guiGradientCtrl.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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. addGroup("ColorPicker");
  197. addField("baseColor", TypeColorF, Offset(mBaseColor, GuiGradientCtrl));
  198. addField("pickColor", TypeColorF, Offset(mPickColor, GuiGradientCtrl));
  199. addField("displayMode", TYPEID< PickMode >(), Offset(mDisplayMode, GuiGradientCtrl) );
  200. addField("actionOnMove", TypeBool,Offset(mActionOnMove, GuiGradientCtrl));
  201. addField("showReticle", TypeBool, Offset(mShowReticle, GuiGradientCtrl));
  202. addField("swatchFactor", TypeS32, Offset(mSwatchFactor, GuiGradientCtrl));
  203. endGroup("ColorPicker");
  204. Parent::initPersistFields();
  205. }
  206. bool GuiGradientCtrl::onAdd()
  207. {
  208. Parent::onAdd();
  209. RectI bounds = getBounds();
  210. S32 l = bounds.point.x + mSwatchFactor, r = bounds.point.x + bounds.extent.x - mSwatchFactor;
  211. S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - mSwatchFactor;
  212. mBlendRangeBox = RectI( Point2I(l, t), Point2I(r, b) );
  213. setupDefaultRange();
  214. reInitSwatches( mDisplayMode );
  215. return true;
  216. }
  217. void GuiGradientCtrl::inspectPreApply()
  218. {
  219. mSaveDisplayMode = mDisplayMode;
  220. }
  221. void GuiGradientCtrl::inspectPostApply()
  222. {
  223. if((mSaveDisplayMode != mDisplayMode) )
  224. reInitSwatches( mDisplayMode );
  225. // Apply any transformations set in the editor
  226. Parent::inspectPostApply();
  227. }
  228. void GuiGradientCtrl::onRender(Point2I offset, const RectI& updateRect)
  229. {
  230. if (mStateBlock.isNull())
  231. {
  232. GFXStateBlockDesc desc;
  233. desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
  234. desc.setZReadWrite(false);
  235. desc.zWriteEnable = false;
  236. desc.setCullMode(GFXCullNone);
  237. mStateBlock = GFX->createStateBlock( desc );
  238. }
  239. RectI boundsRect(offset, getExtent());
  240. renderColorBox(boundsRect);
  241. if (mPositionChanged)
  242. {
  243. mPositionChanged = false;
  244. // Now do onAction() if we are allowed
  245. if (mActionOnMove)
  246. onAction();
  247. }
  248. //render the children
  249. renderChildControls( offset, updateRect);
  250. }
  251. /// Function to invoke calls to draw the picker box and swatch controls
  252. void GuiGradientCtrl::renderColorBox(RectI &bounds)
  253. {
  254. // Draw color box differently depending on mode
  255. if( mDisplayMode == pHorizColorRange )
  256. {
  257. drawBlendRangeBox( bounds, false, mColorRange);
  258. }
  259. else if( mDisplayMode == pHorizAlphaRange )
  260. {
  261. drawBlendRangeBox( bounds, false, mAlphaRange);
  262. }
  263. }
  264. /// Function to draw a set of boxes blending throughout an array of colors
  265. void GuiGradientCtrl::drawBlendRangeBox(RectI &bounds, bool vertical, Vector<ColorRange> colorRange)
  266. {
  267. GFX->setStateBlock(mStateBlock);
  268. // Create new global dimensions
  269. S32 l = bounds.point.x + mSwatchFactor, r = bounds.point.x + bounds.extent.x - mSwatchFactor;
  270. S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - mSwatchFactor;
  271. // Draw border using new global dimensions
  272. if (mProfile->mBorder)
  273. GFX->getDrawUtil()->drawRect(RectI(Point2I(l, t), Point2I(r, b)), mProfile->mBorderColor);
  274. // Update local dimensions
  275. mBlendRangeBox.point = globalToLocalCoord(Point2I(l, t));
  276. mBlendRangeBox.extent = globalToLocalCoord(Point2I(r, b));
  277. if (colorRange.size() == 1) // Only one color to draw
  278. {
  279. PrimBuild::begin(GFXTriangleStrip, 4);
  280. PrimBuild::color(colorRange.first().swatch->getColor());
  281. PrimBuild::vertex2i(l, t);
  282. PrimBuild::vertex2i(r, t);
  283. PrimBuild::color(colorRange.first().swatch->getColor());
  284. PrimBuild::vertex2i(l, b);
  285. PrimBuild::vertex2i(r, b);
  286. PrimBuild::end();
  287. }
  288. else
  289. {
  290. PrimBuild::begin(GFXTriangleStrip, 4);
  291. PrimBuild::color(colorRange.first().swatch->getColor());
  292. PrimBuild::vertex2i(l, t);
  293. PrimBuild::vertex2i(l + colorRange.first().swatch->getPosition().x, t);
  294. PrimBuild::color(colorRange.first().swatch->getColor());
  295. PrimBuild::vertex2i(l, b);
  296. PrimBuild::vertex2i(l + colorRange.first().swatch->getPosition().x, b);
  297. PrimBuild::end();
  298. for (U16 i = 0; i < colorRange.size() - 1; i++)
  299. {
  300. PrimBuild::begin(GFXTriangleStrip, 4);
  301. if (!vertical) // Horizontal (+x)
  302. {
  303. // First color
  304. PrimBuild::color(colorRange[i].swatch->getColor());
  305. PrimBuild::vertex2i(l + colorRange[i].swatch->getPosition().x, t);
  306. PrimBuild::color(colorRange[i + 1].swatch->getColor());
  307. PrimBuild::vertex2i(l + colorRange[i + 1].swatch->getPosition().x, t);
  308. // First color
  309. PrimBuild::color(colorRange[i].swatch->getColor());
  310. PrimBuild::vertex2i(l + colorRange[i].swatch->getPosition().x, b);
  311. PrimBuild::color(colorRange[i + 1].swatch->getColor());
  312. PrimBuild::vertex2i(l + colorRange[i + 1].swatch->getPosition().x, b);
  313. }
  314. PrimBuild::end();
  315. }
  316. PrimBuild::begin(GFXTriangleStrip, 4);
  317. PrimBuild::color(colorRange.last().swatch->getColor());
  318. PrimBuild::vertex2i(l + colorRange.last().swatch->getPosition().x, t);
  319. PrimBuild::vertex2i(r, t);
  320. PrimBuild::color(colorRange.last().swatch->getColor());
  321. PrimBuild::vertex2i(l + colorRange.last().swatch->getPosition().x, b);
  322. PrimBuild::vertex2i(r, b);
  323. PrimBuild::end();
  324. }
  325. }
  326. void GuiGradientCtrl::onMouseDown(const GuiEvent &event)
  327. {
  328. if (!mActive)
  329. return;
  330. mouseLock(this);
  331. if (mProfile->mCanKeyFocus)
  332. setFirstResponder();
  333. if (mActive)
  334. onAction();
  335. Point2I extent = getRoot()->getExtent();
  336. Point2I resolution = getRoot()->getExtent();
  337. GFXTexHandle bb( resolution.x,
  338. resolution.y,
  339. GFXFormatR8G8B8A8, &GFXRenderTargetSRGBProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) );
  340. Point2I tmpPt( event.mousePoint.x, event.mousePoint.y );
  341. GFXTarget *targ = GFX->getActiveRenderTarget();
  342. targ->resolveTo( bb );
  343. GBitmap bmp( bb.getWidth(), bb.getHeight() );
  344. bb.copyToBmp( &bmp );
  345. ColorI tmp;
  346. bmp.getColor( event.mousePoint.x, event.mousePoint.y, tmp );
  347. addColorRange( globalToLocalCoord(event.mousePoint), LinearColorF(tmp) );
  348. mMouseDown = true;
  349. }
  350. void GuiGradientCtrl::onMouseUp(const GuiEvent &)
  351. {
  352. //if we released the mouse within this control, perform the action
  353. if (mActive && mMouseDown )
  354. mMouseDown = false;
  355. mouseUnlock();
  356. }
  357. void GuiGradientCtrl::onMouseEnter(const GuiEvent &event)
  358. {
  359. mMouseOver = true;
  360. }
  361. void GuiGradientCtrl::onMouseLeave(const GuiEvent &)
  362. {
  363. // Reset state
  364. mMouseOver = false;
  365. }
  366. void GuiGradientCtrl::setupDefaultRange()
  367. {
  368. S32 l = mBlendRangeBox.point.x - mSwatchFactor;
  369. S32 r = mBlendRangeBox.extent.x - mSwatchFactor;
  370. //setup alpha range (white/black only)
  371. ColorRange crW;
  372. crW.pos = l;
  373. crW.color = ColorI(255,255,255);
  374. crW.swatch = NULL;
  375. mAlphaRange.push_back( crW );
  376. ColorRange crB;
  377. crB.pos = r;
  378. crB.color = ColorI(0,0,0);
  379. crB.swatch = NULL;
  380. mAlphaRange.push_back( crB );
  381. //setup color range (only 1 color necessary)
  382. ColorRange crD;
  383. crD.pos = l;
  384. crD.color = ColorI(255,0,0);
  385. crD.swatch = NULL;
  386. mColorRange.push_back( crD );
  387. }
  388. void GuiGradientCtrl::reInitSwatches( GuiGradientCtrl::PickMode )
  389. {
  390. //liable to crash in the guiEditor, needs fix
  391. for( S32 i = 0;i < mColorRange.size(); i++ )
  392. {
  393. if(mColorRange[i].swatch != NULL)
  394. {
  395. mColorRange[i].pos = mColorRange[i].swatch->getPosition().x;
  396. mColorRange[i].color = mColorRange[i].swatch->getColor();
  397. mColorRange[i].swatch->deleteObject();
  398. mColorRange[i].swatch = NULL;
  399. }
  400. }
  401. for( S32 i = 0;i < mAlphaRange.size(); i++ )
  402. {
  403. if(mAlphaRange[i].swatch != NULL)
  404. {
  405. mAlphaRange[i].pos = mAlphaRange[i].swatch->getPosition().x;
  406. mAlphaRange[i].color = mAlphaRange[i].swatch->getColor();
  407. mAlphaRange[i].swatch->deleteObject();
  408. mAlphaRange[i].swatch = NULL;
  409. }
  410. }
  411. S32 b = mBlendRangeBox.extent.y - mSwatchFactor;
  412. if( mDisplayMode == pHorizColorRange )
  413. {
  414. for( S32 i = 0;i < mColorRange.size(); i++ )
  415. {
  416. mColorRange[i].swatch = new GuiGradientSwatchCtrl();
  417. mColorRange[i].swatch->registerObject();
  418. addObject(mColorRange[i].swatch);
  419. mColorRange[i].swatch->setPosition( Point2I( mColorRange[i].pos, b ) );// needs to be adjusted
  420. mColorRange[i].swatch->setColor(LinearColorF(mColorRange[i].color));
  421. }
  422. }
  423. else if( mDisplayMode == pHorizAlphaRange )
  424. {
  425. for( S32 i = 0;i < mAlphaRange.size(); i++ )
  426. {
  427. mAlphaRange[i].swatch = new GuiGradientSwatchCtrl();
  428. mAlphaRange[i].swatch->registerObject();
  429. addObject(mAlphaRange[i].swatch);
  430. mAlphaRange[i].swatch->setPosition( Point2I( mAlphaRange[i].pos, b ) );// needs to be adjusted
  431. mAlphaRange[i].swatch->setColor(LinearColorF(mAlphaRange[i].color));
  432. }
  433. }
  434. }
  435. void GuiGradientCtrl::addColorRange(Point2I pos, const LinearColorF& color)
  436. {
  437. if( pos.x + mSwatchFactor < mBlendRangeBox.point.x &&
  438. pos.x + mSwatchFactor > mBlendRangeBox.extent.x )
  439. {
  440. return;
  441. }
  442. ColorRange range;
  443. range.pos = pos.x - mSwatchFactor;
  444. range.color = color;
  445. S32 b = mBlendRangeBox.extent.y - mSwatchFactor;
  446. range.swatch = new GuiGradientSwatchCtrl();
  447. range.swatch->registerObject();
  448. addObject( range.swatch );
  449. range.swatch->setPosition( pos.x - mSwatchFactor, b );//swatch factor and default location is going to have to be placed
  450. range.swatch->setColor( color );
  451. if( mDisplayMode == pHorizColorRange )
  452. {
  453. mColorRange.push_back( range );
  454. S32 size = mColorRange.size();
  455. if( size > 0 )
  456. dQsort( mColorRange.address(), size, sizeof(ColorRange), _numIncreasing);
  457. }
  458. else if( mDisplayMode == pHorizAlphaRange )
  459. {
  460. mAlphaRange.push_back( range );
  461. S32 size = mAlphaRange.size();
  462. if( size > 0 )
  463. dQsort( mAlphaRange.address(), size, sizeof(ColorRange), _numIncreasing);
  464. }
  465. }
  466. void GuiGradientCtrl::removeColorRange( GuiGradientSwatchCtrl* swatch )
  467. {
  468. if( mDisplayMode == pHorizColorRange )
  469. {
  470. if( mColorRange.size() <= 1 )
  471. return;
  472. for( S32 i = 0;i < mColorRange.size(); i++ )
  473. {
  474. if( mColorRange[i].swatch == swatch )
  475. {
  476. mColorRange.erase( U32(i) );
  477. swatch->safeDeleteObject();
  478. break;
  479. }
  480. }
  481. }
  482. else if( mDisplayMode == pHorizAlphaRange )
  483. {
  484. if( mAlphaRange.size() <= 1 )
  485. return;
  486. for( S32 i = 0;i < mAlphaRange.size(); i++ )
  487. {
  488. if( mAlphaRange[i].swatch == swatch )
  489. {
  490. mAlphaRange.erase( U32(i) );
  491. swatch->safeDeleteObject();
  492. break;
  493. }
  494. }
  495. }
  496. }
  497. void GuiGradientCtrl::sortColorRange()
  498. {
  499. if( mDisplayMode == pHorizColorRange )
  500. dQsort( mColorRange.address(), mColorRange.size(), sizeof(ColorRange), _numIncreasing);
  501. else if( mDisplayMode == pHorizAlphaRange )
  502. dQsort( mAlphaRange.address(), mAlphaRange.size(), sizeof(ColorRange), _numIncreasing);
  503. }
  504. DefineEngineMethod(GuiGradientCtrl, getColorCount, S32, (), , "Get color count")
  505. {
  506. if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  507. return object->mColorRange.size();
  508. else if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  509. return object->mColorRange.size();
  510. return 0;
  511. }
  512. DefineEngineMethod(GuiGradientCtrl, getColor, LinearColorF, (S32 idx), , "Get color value")
  513. {
  514. if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  515. {
  516. if ( idx >= 0 && idx < object->mColorRange.size() )
  517. {
  518. return object->mColorRange[idx].swatch->getColor();
  519. }
  520. }
  521. else if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  522. {
  523. if ( idx >= 0 && idx < object->mAlphaRange.size() )
  524. {
  525. return object->mAlphaRange[idx].swatch->getColor();
  526. }
  527. }
  528. return LinearColorF::ONE;
  529. }