Torque3D Documentation / _generateds / guiGradientCtrl.cpp

guiGradientCtrl.cpp

Engine/source/gui/controls/guiGradientCtrl.cpp

More...

Public Variables

Public Functions

ConsoleDocClass(GuiGradientCtrl , "@brief Visual representation of color box used with the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiColorPickerCtrl\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
ConsoleDocClass(GuiGradientSwatchCtrl , "@brief Swatch selector that appears inside the <a href="/coding/class/classguigradientctrl/">GuiGradientCtrl</a> object. These objects are automatically created by GuiGradientCtrl. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Currently only appears <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be editor <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">specific\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiSwatchButtonCtrl\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiGradientCtrl\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiCore\n</a>" "@internal" )
DefineEngineMethod(GuiGradientCtrl , getColor , LinearColorF , (S32 idx) , "Get color <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>" )
DefineEngineMethod(GuiGradientCtrl , getColorCount , S32 , () , "Get color <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1ad43c3812e6d13e0518d9f8b8f463ffcf">count</a>" )
IMPLEMENT_CALLBACK(GuiGradientSwatchCtrl , onDoubleClick , void , () , () , "@brief Called whenever the left mouse button performs <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> double click <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">control.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// The left mouse button has performed <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> double click on the control, causing the callback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occur.\n</a>" "GuiGradientSwatchCtrl::onDoubleClick(%this)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "//Code <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> run when the callback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occurs\n</a>" " }\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControl\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiSwatchButtonCtrl\n\n</a>" " @internal" )
IMPLEMENT_CALLBACK(GuiGradientSwatchCtrl , onMouseDown , void , () , () , "@brief Called whenever the left mouse button has entered the down state <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">control.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// The left mouse button is down on the control, causing the callback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occur.\n</a>" "<a href="/coding/class/classguigradientswatchctrl/#classguigradientswatchctrl_1ae08816218663d948aa0dfee90aa26547">GuiGradientSwatchCtrl::onMouseDown</a>(%this)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "//Code <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> run when the callback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occurs\n</a>" " }\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControl\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiSwatchButtonCtrl\n\n</a>" " @internal" )
ImplementEnumType(GuiGradientPickMode , "\n\n" "@ingroup GuiCore" "@internal" )

Detailed Description

Public Variables

 EndImplementEnumType 

Public Functions

_numIncreasing(const void * a, const void * b)

ConsoleDocClass(GuiGradientCtrl , "@brief Visual representation of color box used with the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiColorPickerCtrl\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )

ConsoleDocClass(GuiGradientSwatchCtrl , "@brief Swatch selector that appears inside the <a href="/coding/class/classguigradientctrl/">GuiGradientCtrl</a> object. These objects are automatically created by GuiGradientCtrl. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Currently only appears <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be editor <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">specific\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiSwatchButtonCtrl\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiGradientCtrl\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiCore\n</a>" "@internal" )

DefineEngineMethod(GuiGradientCtrl , getColor , LinearColorF , (S32 idx) , "Get color <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>" )

DefineEngineMethod(GuiGradientCtrl , getColorCount , S32 , () , "Get color <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1ad43c3812e6d13e0518d9f8b8f463ffcf">count</a>" )

IMPLEMENT_CALLBACK(GuiGradientSwatchCtrl , onDoubleClick , void , () , () , "@brief Called whenever the left mouse button performs <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> double click <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">control.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// The left mouse button has performed <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> double click on the control, causing the callback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occur.\n</a>" "GuiGradientSwatchCtrl::onDoubleClick(%this)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "//Code <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> run when the callback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occurs\n</a>" " }\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControl\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiSwatchButtonCtrl\n\n</a>" " @internal" )

IMPLEMENT_CALLBACK(GuiGradientSwatchCtrl , onMouseDown , void , () , () , "@brief Called whenever the left mouse button has entered the down state <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">control.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// The left mouse button is down on the control, causing the callback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occur.\n</a>" "<a href="/coding/class/classguigradientswatchctrl/#classguigradientswatchctrl_1ae08816218663d948aa0dfee90aa26547">GuiGradientSwatchCtrl::onMouseDown</a>(%this)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "//Code <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> run when the callback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">occurs\n</a>" " }\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControl\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiSwatchButtonCtrl\n\n</a>" " @internal" )

IMPLEMENT_CONOBJECT(GuiGradientCtrl )

IMPLEMENT_CONOBJECT(GuiGradientSwatchCtrl )

ImplementEnumType(GuiGradientPickMode , "\n\n" "@ingroup GuiCore" "@internal" )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23#include "console/console.h"
 24#include "gfx/gfxDevice.h"
 25#include "console/consoleTypes.h"
 26#include "gui/core/guiCanvas.h"
 27#include "gui/buttons/guiButtonCtrl.h"
 28#include "gui/core/guiDefaultControlRender.h"
 29#include "gui/controls/guiGradientCtrl.h"
 30#include "gui/controls/guiColorPicker.h"
 31#include "gfx/primBuilder.h"
 32#include "gfx/gfxDrawUtil.h"
 33#include "console/engineAPI.h"
 34
 35//-----------------------------------------------------------------------------
 36// GuiGradientSwatchCtrl
 37
 38IMPLEMENT_CONOBJECT(GuiGradientSwatchCtrl);
 39
 40ConsoleDocClass( GuiGradientSwatchCtrl,
 41   "@brief Swatch selector that appears inside the GuiGradientCtrl object. These objects are automatically created by GuiGradientCtrl. \n\n"
 42   "Currently only appears to be editor specific\n\n"
 43   "@see GuiSwatchButtonCtrl\n"
 44   "@see GuiGradientCtrl\n\n"
 45   "@ingroup GuiCore\n"
 46   "@internal"
 47);
 48
 49IMPLEMENT_CALLBACK( GuiGradientSwatchCtrl, onMouseDown, void, (),(),
 50   "@brief Called whenever the left mouse button has entered the down state while in this control.\n\n"
 51   "@tsexample\n"
 52   "// The left mouse button is down on the control, causing the callback to occur.\n"
 53   "GuiGradientSwatchCtrl::onMouseDown(%this)\n"
 54   "  {\n"
 55   "     // Code to run when the callback occurs\n"
 56   "  }\n"
 57   "@endtsexample\n\n"
 58   "@see GuiControl\n"
 59   "@see GuiSwatchButtonCtrl\n\n"
 60   "@internal"
 61);
 62
 63IMPLEMENT_CALLBACK( GuiGradientSwatchCtrl, onDoubleClick, void, (),(),
 64   "@brief Called whenever the left mouse button performs a double click while in this control.\n\n"
 65   "@tsexample\n"
 66   "// The left mouse button has performed a double click on the control, causing the callback to occur.\n"
 67   "GuiGradientSwatchCtrl::onDoubleClick(%this)\n"
 68   "  {\n"
 69   "     // Code to run when the callback occurs\n"
 70   "  }\n"
 71   "@endtsexample\n\n"
 72   "@see GuiControl\n"
 73   "@see GuiSwatchButtonCtrl\n\n"
 74   "@internal"
 75);
 76
 77
 78GuiGradientSwatchCtrl::GuiGradientSwatchCtrl()
 79{
 80   setPosition(0, 0);
 81   setExtent(14, 14);
 82   mMouseDownPosition = Point2I(0, 0);
 83   mSwatchColor = ColorI( 1, 1, 1, 1 );
 84   mColorFunction = StringTable->insert("getColorF");
 85   setDataField( StringTable->insert("Profile"), NULL, "GuiInspectorSwatchButtonProfile" );
 86}
 87
 88bool GuiGradientSwatchCtrl::onWake()
 89{
 90   if ( !Parent::onWake() )
 91      return false;
 92   
 93   static const U32 bufSize = 512;
 94   char* altCommand = Con::getReturnBuffer(bufSize);
 95   dSprintf( altCommand, bufSize, "%s(%i.color, \"%i.setColor\");", mColorFunction, getId(), getId() );
 96   setField( "altCommand", altCommand );
 97
 98   return true;
 99}
100
101void GuiGradientSwatchCtrl::onRender( Point2I offset, const RectI &updateRect )
102{
103   bool highlight = mMouseOver;
104
105   ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA;
106   RectI renderRect( offset, getExtent() );
107
108   if ( !highlight )
109      renderRect.inset( 1, 1 );      
110
111   GFXDrawUtil *drawer = GFX->getDrawUtil();
112   drawer->clearBitmapModulation();
113   
114   // Draw background transparency grid texture...
115   if ( mGrid.isValid() )
116      drawer->drawBitmapStretch( mGrid, renderRect );
117
118   // Draw swatch color as fill...
119   drawer->drawRectFill( renderRect, mSwatchColor.toColorI());
120
121   // Draw any borders...
122   drawer->drawRect( renderRect, borderColor );
123}
124
125void GuiGradientSwatchCtrl::onMouseDown(const GuiEvent &event)
126{
127   if (! mActive)
128      return;
129
130   if (mProfile->mCanKeyFocus)
131      setFirstResponder();
132   
133   //capture current bounds and mouse down position
134   mOrigBounds = getBounds();
135   mMouseDownPosition = event.mousePoint;
136
137   if(mUseMouseEvents)
138      onMouseDown_callback();
139
140   //lock the mouse
141   mouseLock();
142   mDepressed = true;
143
144   // If we have a double click then execute the alt command.
145   if ( event.mouseClickCount == 2 )
146   {
147      onDoubleClick_callback();
148
149      execAltConsoleCallback();
150   }
151
152   setUpdate();
153}
154
155void GuiGradientSwatchCtrl::onMouseDragged(const GuiEvent &event)
156{
157   //gradientCtrl owns the y, x here however is regulated by the extent currently
158   //dirty, please fix
159   GuiGradientCtrl* parent = dynamic_cast<GuiGradientCtrl*>(getParent());
160   if( !parent )
161      return;
162   
163   //use bounds and delta to move the ctrl
164   Point2I newPosition = mMouseDownPosition;
165   Point2I deltaMousePosition = event.mousePoint - mMouseDownPosition;
166   
167   newPosition.x = mOrigBounds.point.x + deltaMousePosition.x;
168
169   // default position but it needs to be standard; currently using this cops out a static y value
170   newPosition.y = mOrigBounds.point.y; 
171
172   if( newPosition.x + parent->mSwatchFactor >= parent->mBlendRangeBox.point.x &&
173      newPosition.x + parent->mSwatchFactor <= parent->mBlendRangeBox.extent.x )
174   {
175      setPosition(newPosition);
176      if( parent )
177         parent->sortColorRange();
178   }
179}
180
181void GuiGradientSwatchCtrl::onRightMouseDown(const GuiEvent &event)
182{
183   GuiGradientCtrl* parent = dynamic_cast<GuiGradientCtrl*>(getParent());
184   if( parent )
185      parent->removeColorRange( this );
186}
187
188//-----------------------------------------------------------------------------
189// GuiGradientCtrl
190
191static S32 QSORT_CALLBACK _numIncreasing( const void* a, const void* b )
192{
193   GuiGradientCtrl::ColorRange *crA = (GuiGradientCtrl::ColorRange *) (a);
194   GuiGradientCtrl::ColorRange *crB = (GuiGradientCtrl::ColorRange *) (b);
195   S32 posA = crA->swatch->getPosition().x;
196   S32 posB = crB->swatch->getPosition().x;
197   return ( (posA < posB) ? -1 : ((posA > posB) ? 1 : 0) );
198}
199
200ImplementEnumType( GuiGradientPickMode,
201   "\n\n"
202   "@ingroup GuiCore"
203   "@internal")
204   { GuiGradientCtrl::pHorizColorRange,   "HorizColor"},
205   { GuiGradientCtrl::pHorizAlphaRange,   "HorizAlpha"},
206EndImplementEnumType;
207
208IMPLEMENT_CONOBJECT(GuiGradientCtrl);
209
210ConsoleDocClass( GuiGradientCtrl,
211   "@brief Visual representation of color box used with the GuiColorPickerCtrl\n\n"
212   "Editor use only.\n\n"
213   "@internal"
214);
215
216
217GuiGradientCtrl::GuiGradientCtrl()
218{
219   setExtent(140, 30);
220   mDisplayMode = pHorizColorRange;
221   mSaveDisplayMode = pHorizColorRange;
222   mBaseColor = LinearColorF(1.,.0,1.);
223   mPickColor = LinearColorF(.0,.0,.0);
224   mMouseDown = mMouseOver = false;
225   mActive = true;
226   mPositionChanged = false;
227   mActionOnMove = false;
228   mShowReticle = true;
229   colorWhiteBlend = LinearColorF(1.,1.,1.,.75);
230   mSwatchFactor = 7;
231}
232
233//--------------------------------------------------------------------------
234void GuiGradientCtrl::initPersistFields()
235{
236   addGroup("ColorPicker");
237   addField("baseColor", TypeColorF, Offset(mBaseColor, GuiGradientCtrl));
238   addField("pickColor", TypeColorF, Offset(mPickColor, GuiGradientCtrl));
239   addField("displayMode", TYPEID< PickMode >(), Offset(mDisplayMode, GuiGradientCtrl) );
240   addField("actionOnMove", TypeBool,Offset(mActionOnMove, GuiGradientCtrl));
241   addField("showReticle", TypeBool, Offset(mShowReticle, GuiGradientCtrl));
242   addField("swatchFactor", TypeS32, Offset(mSwatchFactor, GuiGradientCtrl));
243   endGroup("ColorPicker");
244
245   Parent::initPersistFields();
246}
247
248bool GuiGradientCtrl::onAdd()
249{
250   Parent::onAdd();
251
252   RectI bounds = getBounds();
253   S32 l = bounds.point.x + mSwatchFactor, r = bounds.point.x + bounds.extent.x - mSwatchFactor;
254   S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - mSwatchFactor;
255   mBlendRangeBox = RectI( Point2I(l, t), Point2I(r, b) );
256   
257   setupDefaultRange();
258   reInitSwatches( mDisplayMode );
259   return true;
260}
261
262void GuiGradientCtrl::inspectPreApply()
263{
264   mSaveDisplayMode = mDisplayMode;
265}
266
267void GuiGradientCtrl::inspectPostApply()
268{
269   if((mSaveDisplayMode != mDisplayMode) )
270      reInitSwatches( mDisplayMode );
271
272   // Apply any transformations set in the editor
273   Parent::inspectPostApply();
274}
275
276void GuiGradientCtrl::onRender(Point2I offset, const RectI& updateRect)
277{
278   if (mStateBlock.isNull())
279   {
280      GFXStateBlockDesc desc;
281      desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
282      desc.setZReadWrite(false);
283      desc.zWriteEnable = false;
284      desc.setCullMode(GFXCullNone);
285      mStateBlock = GFX->createStateBlock( desc );
286   }
287
288   RectI boundsRect(offset, getExtent()); 
289   renderColorBox(boundsRect);
290
291   if (mPositionChanged) 
292   {
293      mPositionChanged = false;
294
295      // Now do onAction() if we are allowed
296      if (mActionOnMove) 
297         onAction();  
298   }
299   
300   //render the children
301   renderChildControls( offset, updateRect);
302}
303
304/// Function to invoke calls to draw the picker box and swatch controls
305void GuiGradientCtrl::renderColorBox(RectI &bounds)
306{   
307   // Draw color box differently depending on mode
308   if( mDisplayMode == pHorizColorRange )
309   {
310      drawBlendRangeBox( bounds, false, mColorRange);
311   }
312   else if( mDisplayMode == pHorizAlphaRange )
313   {
314      drawBlendRangeBox( bounds, false, mAlphaRange);
315   }
316}
317
318/// Function to draw a set of boxes blending throughout an array of colors
319void GuiGradientCtrl::drawBlendRangeBox(RectI &bounds, bool vertical, Vector<ColorRange> colorRange)
320{
321   GFX->setStateBlock(mStateBlock);
322
323   // Create new global dimensions
324   S32 l = bounds.point.x + mSwatchFactor, r = bounds.point.x + bounds.extent.x - mSwatchFactor;
325   S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - mSwatchFactor;
326
327   // Draw border using new global dimensions
328   if (mProfile->mBorder)
329      GFX->getDrawUtil()->drawRect(RectI(Point2I(l, t), Point2I(r, b)), mProfile->mBorderColor);
330
331   // Update local dimensions
332   mBlendRangeBox.point = globalToLocalCoord(Point2I(l, t));
333   mBlendRangeBox.extent = globalToLocalCoord(Point2I(r, b));
334
335   if (colorRange.size() == 1) // Only one color to draw
336   {
337      PrimBuild::begin(GFXTriangleStrip, 4);
338
339      PrimBuild::color(colorRange.first().swatch->getColor());
340      PrimBuild::vertex2i(l, t);
341      PrimBuild::vertex2i(r, t);
342
343      PrimBuild::color(colorRange.first().swatch->getColor());
344      PrimBuild::vertex2i(l, b);
345      PrimBuild::vertex2i(r, b);
346
347      PrimBuild::end();
348   }
349   else
350   {
351      PrimBuild::begin(GFXTriangleStrip, 4);
352
353      PrimBuild::color(colorRange.first().swatch->getColor());
354      PrimBuild::vertex2i(l, t);
355      PrimBuild::vertex2i(l + colorRange.first().swatch->getPosition().x, t);
356
357      PrimBuild::color(colorRange.first().swatch->getColor());
358      PrimBuild::vertex2i(l, b);
359      PrimBuild::vertex2i(l + colorRange.first().swatch->getPosition().x, b);
360
361      PrimBuild::end();
362
363      for (U16 i = 0; i < colorRange.size() - 1; i++)
364      {
365         PrimBuild::begin(GFXTriangleStrip, 4);
366         if (!vertical)  // Horizontal (+x)
367         {
368            // First color
369            PrimBuild::color(colorRange[i].swatch->getColor());
370            PrimBuild::vertex2i(l + colorRange[i].swatch->getPosition().x, t);
371            PrimBuild::color(colorRange[i + 1].swatch->getColor());
372            PrimBuild::vertex2i(l + colorRange[i + 1].swatch->getPosition().x, t);
373
374            // First color
375            PrimBuild::color(colorRange[i].swatch->getColor());
376            PrimBuild::vertex2i(l + colorRange[i].swatch->getPosition().x, b);
377            PrimBuild::color(colorRange[i + 1].swatch->getColor());
378            PrimBuild::vertex2i(l + colorRange[i + 1].swatch->getPosition().x, b);
379         }
380         PrimBuild::end();
381      }
382
383      PrimBuild::begin(GFXTriangleStrip, 4);
384
385      PrimBuild::color(colorRange.last().swatch->getColor());
386      PrimBuild::vertex2i(l + colorRange.last().swatch->getPosition().x, t);
387      PrimBuild::vertex2i(r, t);
388
389      PrimBuild::color(colorRange.last().swatch->getColor());
390      PrimBuild::vertex2i(l + colorRange.last().swatch->getPosition().x, b);
391      PrimBuild::vertex2i(r, b);
392
393      PrimBuild::end();
394   }
395}
396
397void GuiGradientCtrl::onMouseDown(const GuiEvent &event)
398{
399   if (!mActive)
400      return;
401   
402   mouseLock(this);
403   
404   if (mProfile->mCanKeyFocus)
405      setFirstResponder();
406   
407   if (mActive) 
408      onAction();
409
410   Point2I extent = getRoot()->getExtent();
411   Point2I resolution = getRoot()->getExtent();
412   GFXTexHandle bb( resolution.x, 
413                    resolution.y, 
414                    GFXFormatR8G8B8A8, &GFXRenderTargetSRGBProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) );
415   
416   Point2I tmpPt( event.mousePoint.x, event.mousePoint.y );
417   GFXTarget *targ = GFX->getActiveRenderTarget();
418   targ->resolveTo( bb );
419   GBitmap bmp( bb.getWidth(), bb.getHeight() );
420   bb.copyToBmp( &bmp );
421   ColorI tmp;
422   bmp.getColor( event.mousePoint.x, event.mousePoint.y, tmp );
423   
424   addColorRange( globalToLocalCoord(event.mousePoint), LinearColorF(tmp) );
425   
426   mMouseDown = true;
427}
428
429void GuiGradientCtrl::onMouseUp(const GuiEvent &)
430{
431   //if we released the mouse within this control, perform the action
432   if (mActive && mMouseDown ) 
433      mMouseDown = false;
434   
435   mouseUnlock();
436}
437
438void GuiGradientCtrl::onMouseEnter(const GuiEvent &event)
439{
440   mMouseOver = true;
441}
442
443void GuiGradientCtrl::onMouseLeave(const GuiEvent &)
444{
445   // Reset state
446   mMouseOver = false;
447}
448
449void GuiGradientCtrl::setupDefaultRange()
450{
451   S32 l = mBlendRangeBox.point.x - mSwatchFactor;
452   S32 r = mBlendRangeBox.extent.x - mSwatchFactor;
453   
454   //setup alpha range (white/black only)
455   ColorRange crW;
456   crW.pos = l;
457   crW.color = ColorI(255,255,255);
458   crW.swatch = NULL;
459   mAlphaRange.push_back( crW );
460
461   ColorRange crB;
462   crB.pos = r;
463   crB.color = ColorI(0,0,0);
464   crB.swatch = NULL;
465   mAlphaRange.push_back( crB );
466
467   //setup color range (only 1 color necessary)
468   ColorRange crD;
469   crD.pos = l;
470   crD.color = ColorI(255,0,0);
471   crD.swatch = NULL;
472   mColorRange.push_back( crD );
473}
474
475void GuiGradientCtrl::reInitSwatches( GuiGradientCtrl::PickMode )
476{
477   //liable to crash in the guiEditor, needs fix
478   for( S32 i = 0;i < mColorRange.size(); i++ ) 
479   {
480      if(mColorRange[i].swatch != NULL)
481      {
482         mColorRange[i].pos = mColorRange[i].swatch->getPosition().x;
483         mColorRange[i].color = mColorRange[i].swatch->getColor();
484         mColorRange[i].swatch->deleteObject();
485         mColorRange[i].swatch = NULL;
486      }
487   }
488   
489   for( S32 i = 0;i < mAlphaRange.size(); i++ ) 
490   {
491      if(mAlphaRange[i].swatch != NULL)
492      {
493         mAlphaRange[i].pos = mAlphaRange[i].swatch->getPosition().x;
494         mAlphaRange[i].color = mAlphaRange[i].swatch->getColor();
495         mAlphaRange[i].swatch->deleteObject();
496         mAlphaRange[i].swatch = NULL;
497      }
498   }
499   
500   S32 b = mBlendRangeBox.extent.y - mSwatchFactor;
501
502   if( mDisplayMode == pHorizColorRange )
503   {
504      for( S32 i = 0;i < mColorRange.size(); i++ ) 
505      {
506         mColorRange[i].swatch = new GuiGradientSwatchCtrl();
507         mColorRange[i].swatch->registerObject();
508         addObject(mColorRange[i].swatch);
509         mColorRange[i].swatch->setPosition( Point2I( mColorRange[i].pos, b ) );// needs to be adjusted
510         mColorRange[i].swatch->setColor(LinearColorF(mColorRange[i].color));
511      }
512   }
513
514   else if( mDisplayMode == pHorizAlphaRange )
515   {
516      for( S32 i = 0;i < mAlphaRange.size(); i++ ) 
517      {
518         mAlphaRange[i].swatch = new GuiGradientSwatchCtrl();
519         mAlphaRange[i].swatch->registerObject();
520         addObject(mAlphaRange[i].swatch);
521         mAlphaRange[i].swatch->setPosition( Point2I( mAlphaRange[i].pos, b ) );// needs to be adjusted
522         mAlphaRange[i].swatch->setColor(LinearColorF(mAlphaRange[i].color));
523      }
524   }
525}
526
527void GuiGradientCtrl::addColorRange(Point2I pos, const LinearColorF& color)
528{
529   if( pos.x + mSwatchFactor < mBlendRangeBox.point.x &&
530      pos.x + mSwatchFactor > mBlendRangeBox.extent.x )
531   {
532      return;
533   }
534
535   ColorRange range;
536   range.pos = pos.x - mSwatchFactor;
537   range.color = color;
538   
539   S32 b = mBlendRangeBox.extent.y - mSwatchFactor;
540
541   range.swatch = new GuiGradientSwatchCtrl();
542   range.swatch->registerObject();
543   addObject( range.swatch );
544   range.swatch->setPosition( pos.x - mSwatchFactor, b );//swatch factor and default location is going to have to be placed
545   range.swatch->setColor( color );
546   
547   if( mDisplayMode == pHorizColorRange )
548   {
549      mColorRange.push_back( range );
550      S32 size = mColorRange.size();
551      if( size > 0 )
552         dQsort( mColorRange.address(), size, sizeof(ColorRange), _numIncreasing);
553   }
554   else if( mDisplayMode == pHorizAlphaRange )
555   {
556      mAlphaRange.push_back( range );
557      S32 size = mAlphaRange.size();
558      if( size > 0 )
559         dQsort( mAlphaRange.address(), size, sizeof(ColorRange), _numIncreasing);
560   }
561}
562
563void GuiGradientCtrl::removeColorRange( GuiGradientSwatchCtrl* swatch )
564{
565   if( mDisplayMode == pHorizColorRange )
566   {
567      if( mColorRange.size() <= 1 )
568         return;
569
570      for( S32 i = 0;i < mColorRange.size(); i++ ) 
571      {
572         if( mColorRange[i].swatch == swatch )
573         {
574            mColorRange.erase( U32(i) );
575            swatch->safeDeleteObject();
576            break;
577         }
578      }
579   }
580   else if( mDisplayMode == pHorizAlphaRange )
581   {
582      if( mAlphaRange.size() <= 1 )
583         return;
584
585      for( S32 i = 0;i < mAlphaRange.size(); i++ ) 
586      {
587         if( mAlphaRange[i].swatch == swatch )
588         {
589            mAlphaRange.erase( U32(i) );
590            swatch->safeDeleteObject();
591            break;   
592         }
593      }
594   }
595}
596
597void GuiGradientCtrl::sortColorRange()
598{
599   if( mDisplayMode == pHorizColorRange )
600      dQsort( mColorRange.address(), mColorRange.size(), sizeof(ColorRange), _numIncreasing);
601   else if( mDisplayMode == pHorizAlphaRange )
602      dQsort( mAlphaRange.address(), mAlphaRange.size(), sizeof(ColorRange), _numIncreasing);
603}
604
605DefineEngineMethod(GuiGradientCtrl, getColorCount, S32, (), , "Get color count")
606{
607   if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
608      return object->mColorRange.size();
609   else if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
610      return object->mColorRange.size();
611   
612   return 0;
613}
614
615DefineEngineMethod(GuiGradientCtrl, getColor, LinearColorF, (S32 idx), , "Get color value")
616{
617
618   if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
619   {
620      if ( idx >= 0 && idx < object->mColorRange.size() )
621      {
622
623         return object->mColorRange[idx].swatch->getColor();
624      }
625   }
626   else if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
627   {
628      if ( idx >= 0 && idx < object->mAlphaRange.size() )
629      {
630
631         return object->mAlphaRange[idx].swatch->getColor();
632      }
633   }
634
635   return LinearColorF::ONE;
636}
637