guiGradientCtrl.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  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. if ( mPointer.isNull() )
  84. mPointer.set( "core/art/gui/images/arrowbtn_d", &GFXDefaultGUIProfile, avar("%s() - mGrid (line %d)", __FUNCTION__, __LINE__) );
  85. char* altCommand = Con::getReturnBuffer(512);
  86. dSprintf( altCommand, 512, "%s(%i.color, \"%i.setColor\");", mColorFunction, getId(), getId() );
  87. setField( "altCommand", altCommand );
  88. return true;
  89. }
  90. void GuiGradientSwatchCtrl::onRender( Point2I offset, const RectI &updateRect )
  91. {
  92. bool highlight = mMouseOver;
  93. ColorI backColor = mSwatchColor;
  94. ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA;
  95. RectI renderRect( offset, getExtent() );
  96. if ( !highlight )
  97. renderRect.inset( 1, 1 );
  98. GFXDrawUtil *drawer = GFX->getDrawUtil();
  99. drawer->clearBitmapModulation();
  100. // Draw background transparency grid texture...
  101. if ( mGrid.isValid() )
  102. drawer->drawBitmapStretch( mGrid, renderRect );
  103. // Draw swatch color as fill...
  104. drawer->drawRectFill( renderRect, mSwatchColor );
  105. // Draw any borders...
  106. drawer->drawRect( renderRect, borderColor );
  107. }
  108. void GuiGradientSwatchCtrl::onMouseDown(const GuiEvent &event)
  109. {
  110. if (! mActive)
  111. return;
  112. if (mProfile->mCanKeyFocus)
  113. setFirstResponder();
  114. //capture current bounds and mouse down position
  115. mOrigBounds = getBounds();
  116. mMouseDownPosition = event.mousePoint;
  117. if(mUseMouseEvents)
  118. onMouseDown_callback();
  119. //lock the mouse
  120. mouseLock();
  121. mDepressed = true;
  122. // If we have a double click then execute the alt command.
  123. if ( event.mouseClickCount == 2 )
  124. {
  125. onDoubleClick_callback();
  126. execAltConsoleCallback();
  127. }
  128. setUpdate();
  129. }
  130. void GuiGradientSwatchCtrl::onMouseDragged(const GuiEvent &event)
  131. {
  132. //gradientCtrl owns the y, x here however is regulated by the extent currently
  133. //dirty, please fix
  134. GuiGradientCtrl* parent = dynamic_cast<GuiGradientCtrl*>(getParent());
  135. if( !parent )
  136. return;
  137. //use bounds and delta to move the ctrl
  138. Point2I newPosition = mMouseDownPosition;
  139. Point2I deltaMousePosition = event.mousePoint - mMouseDownPosition;
  140. newPosition.x = mOrigBounds.point.x + deltaMousePosition.x;
  141. // default position but it needs to be standard; currently using this cops out a static y value
  142. newPosition.y = mOrigBounds.point.y;
  143. if( newPosition.x + parent->mSwatchFactor >= parent->mBlendRangeBox.point.x &&
  144. newPosition.x + parent->mSwatchFactor <= parent->mBlendRangeBox.extent.x )
  145. {
  146. setPosition(newPosition);
  147. if( parent )
  148. parent->sortColorRange();
  149. }
  150. }
  151. void GuiGradientSwatchCtrl::onRightMouseDown(const GuiEvent &event)
  152. {
  153. GuiGradientCtrl* parent = dynamic_cast<GuiGradientCtrl*>(getParent());
  154. if( parent )
  155. parent->removeColorRange( this );
  156. }
  157. //-----------------------------------------------------------------------------
  158. // GuiGradientCtrl
  159. static S32 QSORT_CALLBACK _numIncreasing( const void* a, const void* b )
  160. {
  161. GuiGradientCtrl::ColorRange *crA = (GuiGradientCtrl::ColorRange *) (a);
  162. GuiGradientCtrl::ColorRange *crB = (GuiGradientCtrl::ColorRange *) (b);
  163. S32 posA = crA->swatch->getPosition().x;
  164. S32 posB = crB->swatch->getPosition().x;
  165. return ( (posA < posB) ? -1 : ((posA > posB) ? 1 : 0) );
  166. }
  167. ImplementEnumType( GuiGradientPickMode,
  168. "\n\n"
  169. "@ingroup GuiCore"
  170. "@internal")
  171. { GuiGradientCtrl::pHorizColorRange, "HorizColor"},
  172. { GuiGradientCtrl::pHorizAlphaRange, "HorizAlpha"},
  173. EndImplementEnumType;
  174. IMPLEMENT_CONOBJECT(GuiGradientCtrl);
  175. ConsoleDocClass( GuiGradientCtrl,
  176. "@brief Visual representation of color box used with the GuiColorPickerCtrl\n\n"
  177. "Editor use only.\n\n"
  178. "@internal"
  179. );
  180. GuiGradientCtrl::GuiGradientCtrl()
  181. {
  182. setExtent(140, 30);
  183. mDisplayMode = pHorizColorRange;
  184. mSaveDisplayMode = pHorizColorRange;
  185. mBaseColor = ColorF(1.,.0,1.);
  186. mPickColor = ColorF(.0,.0,.0);
  187. mMouseDown = mMouseOver = false;
  188. mActive = true;
  189. mPositionChanged = false;
  190. mActionOnMove = false;
  191. mShowReticle = true;
  192. colorWhiteBlend = ColorF(1.,1.,1.,.75);
  193. mSwatchFactor = 7;
  194. }
  195. //--------------------------------------------------------------------------
  196. void GuiGradientCtrl::initPersistFields()
  197. {
  198. addGroup("ColorPicker");
  199. addField("baseColor", TypeColorF, Offset(mBaseColor, GuiGradientCtrl));
  200. addField("pickColor", TypeColorF, Offset(mPickColor, GuiGradientCtrl));
  201. addField("displayMode", TYPEID< PickMode >(), Offset(mDisplayMode, GuiGradientCtrl) );
  202. addField("actionOnMove", TypeBool,Offset(mActionOnMove, GuiGradientCtrl));
  203. addField("showReticle", TypeBool, Offset(mShowReticle, GuiGradientCtrl));
  204. addField("swatchFactor", TypeS32, Offset(mSwatchFactor, GuiGradientCtrl));
  205. endGroup("ColorPicker");
  206. Parent::initPersistFields();
  207. }
  208. bool GuiGradientCtrl::onAdd()
  209. {
  210. Parent::onAdd();
  211. S32 l = getBounds().point.x + mSwatchFactor, r = getBounds().point.x + getBounds().extent.x - mSwatchFactor;
  212. S32 t = getBounds().point.y, b = getBounds().point.y + getBounds().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( GFXTriangleFan, 4 );
  281. PrimBuild::color( colorRange.first().swatch->getColor() );
  282. PrimBuild::vertex2i( l, t );
  283. PrimBuild::vertex2i( l, b );
  284. PrimBuild::color( colorRange.first().swatch->getColor() );
  285. PrimBuild::vertex2i( r, b );
  286. PrimBuild::vertex2i( r, t );
  287. PrimBuild::end();
  288. }
  289. else
  290. {
  291. PrimBuild::begin( GFXTriangleFan, 4 );
  292. PrimBuild::color( colorRange.first().swatch->getColor() );
  293. PrimBuild::vertex2i( l, t );
  294. PrimBuild::vertex2i( l, b );
  295. PrimBuild::color( colorRange.first().swatch->getColor() );
  296. PrimBuild::vertex2i( l + colorRange.first().swatch->getPosition().x, b );
  297. PrimBuild::vertex2i( l + colorRange.first().swatch->getPosition().x, t );
  298. PrimBuild::end();
  299. for( U16 i = 0;i < colorRange.size() - 1; i++ )
  300. {
  301. PrimBuild::begin( GFXTriangleFan, 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::vertex2i( l + colorRange[i].swatch->getPosition().x, b );
  308. // First color
  309. PrimBuild::color( colorRange[i+1].swatch->getColor() );
  310. PrimBuild::vertex2i( l + colorRange[i+1].swatch->getPosition().x, b );
  311. PrimBuild::vertex2i( l + colorRange[i+1].swatch->getPosition().x, t );
  312. }
  313. PrimBuild::end();
  314. }
  315. PrimBuild::begin( GFXTriangleFan, 4 );
  316. PrimBuild::color( colorRange.last().swatch->getColor() );
  317. PrimBuild::vertex2i( l + colorRange.last().swatch->getPosition().x, t );
  318. PrimBuild::vertex2i( l + colorRange.last().swatch->getPosition().x, b );
  319. PrimBuild::color( colorRange.last().swatch->getColor() );
  320. PrimBuild::vertex2i( r, b );
  321. PrimBuild::vertex2i( r, t );
  322. PrimBuild::end();
  323. }
  324. }
  325. void GuiGradientCtrl::onMouseDown(const GuiEvent &event)
  326. {
  327. if (!mActive)
  328. return;
  329. mouseLock(this);
  330. if (mProfile->mCanKeyFocus)
  331. setFirstResponder();
  332. if (mActive)
  333. onAction();
  334. Point2I extent = getRoot()->getExtent();
  335. Point2I resolution = getRoot()->getExtent();
  336. GFXTexHandle bb( resolution.x,
  337. resolution.y,
  338. GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) );
  339. Point2I tmpPt( event.mousePoint.x, event.mousePoint.y );
  340. GFXTarget *targ = GFX->getActiveRenderTarget();
  341. targ->resolveTo( bb );
  342. GBitmap bmp( bb.getWidth(), bb.getHeight() );
  343. bb.copyToBmp( &bmp );
  344. ColorI tmp;
  345. bmp.getColor( event.mousePoint.x, event.mousePoint.y, tmp );
  346. addColorRange( globalToLocalCoord(event.mousePoint), ColorF(tmp) );
  347. mMouseDown = true;
  348. }
  349. void GuiGradientCtrl::onMouseUp(const GuiEvent &)
  350. {
  351. //if we released the mouse within this control, perform the action
  352. if (mActive && mMouseDown )
  353. mMouseDown = false;
  354. mouseUnlock();
  355. }
  356. void GuiGradientCtrl::onMouseEnter(const GuiEvent &event)
  357. {
  358. mMouseOver = true;
  359. }
  360. void GuiGradientCtrl::onMouseLeave(const GuiEvent &)
  361. {
  362. // Reset state
  363. mMouseOver = false;
  364. }
  365. void GuiGradientCtrl::setupDefaultRange()
  366. {
  367. S32 l = mBlendRangeBox.point.x - mSwatchFactor;
  368. S32 r = mBlendRangeBox.extent.x - mSwatchFactor;
  369. //setup alpha range (white/black only)
  370. ColorRange crW;
  371. crW.pos = l;
  372. crW.color = ColorI(255,255,255);
  373. crW.swatch = NULL;
  374. mAlphaRange.push_back( crW );
  375. ColorRange crB;
  376. crB.pos = r;
  377. crB.color = ColorI(0,0,0);
  378. crB.swatch = NULL;
  379. mAlphaRange.push_back( crB );
  380. //setup color range (only 1 color necessary)
  381. ColorRange crD;
  382. crD.pos = l;
  383. crD.color = ColorI(255,0,0);
  384. crD.swatch = NULL;
  385. mColorRange.push_back( crD );
  386. }
  387. void GuiGradientCtrl::reInitSwatches( GuiGradientCtrl::PickMode )
  388. {
  389. //liable to crash in the guiEditor, needs fix
  390. for( S32 i = 0;i < mColorRange.size(); i++ )
  391. {
  392. if(mColorRange[i].swatch != NULL)
  393. {
  394. mColorRange[i].pos = mColorRange[i].swatch->getPosition().x;
  395. mColorRange[i].color = mColorRange[i].swatch->getColor();
  396. mColorRange[i].swatch->deleteObject();
  397. mColorRange[i].swatch = NULL;
  398. }
  399. }
  400. for( S32 i = 0;i < mAlphaRange.size(); i++ )
  401. {
  402. if(mAlphaRange[i].swatch != NULL)
  403. {
  404. mAlphaRange[i].pos = mAlphaRange[i].swatch->getPosition().x;
  405. mAlphaRange[i].color = mAlphaRange[i].swatch->getColor();
  406. mAlphaRange[i].swatch->deleteObject();
  407. mAlphaRange[i].swatch = NULL;
  408. }
  409. }
  410. S32 b = mBlendRangeBox.extent.y - mSwatchFactor;
  411. if( mDisplayMode == pHorizColorRange )
  412. {
  413. for( S32 i = 0;i < mColorRange.size(); i++ )
  414. {
  415. mColorRange[i].swatch = new GuiGradientSwatchCtrl();
  416. mColorRange[i].swatch->registerObject();
  417. addObject(mColorRange[i].swatch);
  418. mColorRange[i].swatch->setPosition( Point2I( mColorRange[i].pos, b ) );// needs to be adjusted
  419. mColorRange[i].swatch->setColor(ColorF(mColorRange[i].color));
  420. }
  421. }
  422. else if( mDisplayMode == pHorizAlphaRange )
  423. {
  424. for( S32 i = 0;i < mAlphaRange.size(); i++ )
  425. {
  426. mAlphaRange[i].swatch = new GuiGradientSwatchCtrl();
  427. mAlphaRange[i].swatch->registerObject();
  428. addObject(mAlphaRange[i].swatch);
  429. mAlphaRange[i].swatch->setPosition( Point2I( mAlphaRange[i].pos, b ) );// needs to be adjusted
  430. mAlphaRange[i].swatch->setColor(ColorF(mAlphaRange[i].color));
  431. }
  432. }
  433. }
  434. void GuiGradientCtrl::addColorRange( Point2I pos, ColorF color )
  435. {
  436. if( pos.x + mSwatchFactor < mBlendRangeBox.point.x &&
  437. pos.x + mSwatchFactor > mBlendRangeBox.extent.x )
  438. {
  439. return;
  440. }
  441. ColorRange range;
  442. range.pos = pos.x - mSwatchFactor;
  443. range.color = color;
  444. S32 b = mBlendRangeBox.extent.y - mSwatchFactor;
  445. range.swatch = new GuiGradientSwatchCtrl();
  446. range.swatch->registerObject();
  447. addObject( range.swatch );
  448. range.swatch->setPosition( pos.x - mSwatchFactor, b );//swatch factor and default location is going to have to be placed
  449. range.swatch->setColor( color );
  450. if( mDisplayMode == pHorizColorRange )
  451. {
  452. mColorRange.push_back( range );
  453. S32 size = mColorRange.size();
  454. if( size > 0 )
  455. dQsort( mColorRange.address(), size, sizeof(ColorRange), _numIncreasing);
  456. }
  457. else if( mDisplayMode == pHorizAlphaRange )
  458. {
  459. mAlphaRange.push_back( range );
  460. S32 size = mAlphaRange.size();
  461. if( size > 0 )
  462. dQsort( mAlphaRange.address(), size, sizeof(ColorRange), _numIncreasing);
  463. }
  464. }
  465. void GuiGradientCtrl::removeColorRange( GuiGradientSwatchCtrl* swatch )
  466. {
  467. if( mDisplayMode == pHorizColorRange )
  468. {
  469. if( mColorRange.size() <= 1 )
  470. return;
  471. for( S32 i = 0;i < mColorRange.size(); i++ )
  472. {
  473. if( mColorRange[i].swatch == swatch )
  474. {
  475. mColorRange.erase( U32(i) );
  476. swatch->safeDeleteObject();
  477. break;
  478. }
  479. }
  480. }
  481. else if( mDisplayMode == pHorizAlphaRange )
  482. {
  483. if( mAlphaRange.size() <= 1 )
  484. return;
  485. for( S32 i = 0;i < mAlphaRange.size(); i++ )
  486. {
  487. if( mAlphaRange[i].swatch == swatch )
  488. {
  489. mAlphaRange.erase( U32(i) );
  490. swatch->safeDeleteObject();
  491. break;
  492. }
  493. }
  494. }
  495. }
  496. void GuiGradientCtrl::sortColorRange()
  497. {
  498. if( mDisplayMode == pHorizColorRange )
  499. dQsort( mColorRange.address(), mColorRange.size(), sizeof(ColorRange), _numIncreasing);
  500. else if( mDisplayMode == pHorizAlphaRange )
  501. dQsort( mAlphaRange.address(), mAlphaRange.size(), sizeof(ColorRange), _numIncreasing);
  502. }
  503. ConsoleMethod(GuiGradientCtrl, getColorCount, S32, 2, 2, "Get color count")
  504. {
  505. if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  506. return object->mColorRange.size();
  507. else if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  508. return object->mColorRange.size();
  509. return 0;
  510. }
  511. ConsoleMethod(GuiGradientCtrl, getColor, const char*, 3, 3, "Get color value")
  512. {
  513. S32 idx = dAtoi(argv[2]);
  514. if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  515. {
  516. if ( idx >= 0 && idx < object->mColorRange.size() )
  517. {
  518. char* rColor = Con::getReturnBuffer(256);
  519. rColor[0] = 0;
  520. dSprintf(rColor, 256, "%f %f %f %f",
  521. object->mColorRange[idx].swatch->getColor().red,
  522. object->mColorRange[idx].swatch->getColor().green,
  523. object->mColorRange[idx].swatch->getColor().blue,
  524. object->mColorRange[idx].swatch->getColor().alpha);
  525. return rColor;
  526. }
  527. }
  528. else if( object->getDisplayMode() == GuiGradientCtrl::pHorizColorRange )
  529. {
  530. if ( idx >= 0 && idx < object->mAlphaRange.size() )
  531. {
  532. char* rColor = Con::getReturnBuffer(256);
  533. rColor[0] = 0;
  534. dSprintf(rColor, 256, "%f %f %f %f",
  535. object->mAlphaRange[idx].swatch->getColor().red,
  536. object->mAlphaRange[idx].swatch->getColor().green,
  537. object->mAlphaRange[idx].swatch->getColor().blue,
  538. object->mAlphaRange[idx].swatch->getColor().alpha);
  539. return rColor;
  540. }
  541. }
  542. return "1 1 1 1";
  543. }