guiGradientCtrl.cpp 19 KB

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