guiColorPicker.cpp
Engine/source/gui/controls/guiColorPicker.cpp
Common colors we use
colorAlpha (0.0f, 0.0f, 0.0f, 0.0f)
colorAlphaW (1.0f, 1.0f, 1.0f, 0.0f)
colorBlack (.0,.0,.0)
colorWhite (1., 1., 1.)
colorWhiteBlend (1., 1., 1.,.75)
Public Variables
Public Functions
ConsoleDocClass(GuiColorPickerCtrl , "@brief Editor GUI used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> picking <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classlinearcolorf/">LinearColorF</a> from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">palette.\n\n</a>" "@note Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
DefineEngineMethod(GuiColorPickerCtrl , getSelectorPos , Point2I , () , "Gets the current position of the selector" )
DefineEngineMethod(GuiColorPickerCtrl , setSelectorColor , void , (LinearColorF color) , "Sets the current position of the selector based on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">color.n</a>" "@param color Color <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.n</a>" )
DefineEngineMethod(GuiColorPickerCtrl , setSelectorPos , void , (Point2I newPos) , "Sets the current position of the selector" )
DefineEngineMethod(GuiColorPickerCtrl , updateColor , void , () , "Forces update of pick color" )
ImplementEnumType(GuiColorPickMode , "\n\n" "@ingroup GuiUtil" "@internal" )
Detailed Description
Common colors we use
LinearColorF colorAlpha (0.0f, 0.0f, 0.0f, 0.0f)
LinearColorF colorAlphaW (1.0f, 1.0f, 1.0f, 0.0f)
LinearColorF colorBlack (.0,.0,.0)
LinearColorF colorWhite (1., 1., 1.)
LinearColorF colorWhiteBlend (1., 1., 1.,.75)
Public Variables
EndImplementEnumType
Public Functions
ConsoleDocClass(GuiColorPickerCtrl , "@brief Editor GUI used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> picking <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classlinearcolorf/">LinearColorF</a> from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">palette.\n\n</a>" "@note Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
DefineEngineMethod(GuiColorPickerCtrl , getSelectorPos , Point2I , () , "Gets the current position of the selector" )
DefineEngineMethod(GuiColorPickerCtrl , setSelectorColor , void , (LinearColorF color) , "Sets the current position of the selector based on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">color.n</a>" "@param color Color <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.n</a>" )
DefineEngineMethod(GuiColorPickerCtrl , setSelectorPos , void , (Point2I newPos) , "Sets the current position of the selector" )
DefineEngineMethod(GuiColorPickerCtrl , updateColor , void , () , "Forces update of pick color" )
IMPLEMENT_CONOBJECT(GuiColorPickerCtrl )
ImplementEnumType(GuiColorPickMode , "\n\n" "@ingroup GuiUtil" "@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 "console/engineAPI.h" 27#include "gui/core/guiCanvas.h" 28#include "gui/buttons/guiButtonCtrl.h" 29#include "gui/core/guiDefaultControlRender.h" 30#include "gui/controls/guiColorPicker.h" 31#include "gfx/primBuilder.h" 32#include "gfx/gfxDrawUtil.h" 33 34/// @name Common colors we use 35/// @{ 36LinearColorF colorWhite(1.,1.,1.); 37LinearColorF colorWhiteBlend(1.,1.,1.,.75); 38LinearColorF colorBlack(.0,.0,.0); 39LinearColorF colorAlpha(0.0f, 0.0f, 0.0f, 0.0f); 40LinearColorF colorAlphaW(1.0f, 1.0f, 1.0f, 0.0f); 41 42ColorI GuiColorPickerCtrl::mColorRange[7] = { 43 ColorI(255,0,0), // Red 44 ColorI(255,0,255), // Pink 45 ColorI(0,0,255), // Blue 46 ColorI(0,255,255), // Light blue 47 ColorI(0,255,0), // Green 48 ColorI(255,255,0), // Yellow 49 ColorI(255,0,0), // Red 50}; 51/// @} 52 53IMPLEMENT_CONOBJECT(GuiColorPickerCtrl); 54 55ConsoleDocClass( GuiColorPickerCtrl, 56 "@brief Editor GUI used for picking a LinearColorF from a palette.\n\n" 57 "@note Editor use only.\n\n" 58 "@internal" 59); 60 61GuiColorPickerCtrl::GuiColorPickerCtrl() 62{ 63 setExtent(140, 30); 64 mDisplayMode = pPallet; 65 mBaseColor = LinearColorF(1.,.0,1.); 66 mPickColor = LinearColorF(.0,.0,.0); 67 mSelectorPos = Point2I(0,0); 68 mMouseDown = mMouseOver = false; 69 mActive = true; 70 mPositionChanged = false; 71 mSelectorGap = 1; 72 mActionOnMove = false; 73 mShowReticle = true; 74 mSelectColor = false; 75 mSetColor = mSetColor.BLACK; 76 mBitmap = NULL; 77} 78 79GuiColorPickerCtrl::~GuiColorPickerCtrl() 80{ 81 if (mBitmap) 82 { 83 delete mBitmap; 84 mBitmap = NULL; 85 } 86} 87 88ImplementEnumType( GuiColorPickMode, 89 "\n\n" 90 "@ingroup GuiUtil" 91 "@internal" ) 92 { GuiColorPickerCtrl::pPallet, "Pallete" }, 93 { GuiColorPickerCtrl::pHorizColorRange, "HorizColor"}, 94 { GuiColorPickerCtrl::pVertColorRange, "VertColor" }, 95 { GuiColorPickerCtrl::pHorizColorBrightnessRange, "HorizBrightnessColor" }, 96 { GuiColorPickerCtrl::pVertColorBrightnessRange, "VertBrightnessColor" }, 97 { GuiColorPickerCtrl::pBlendColorRange, "BlendColor" }, 98 { GuiColorPickerCtrl::pHorizAlphaRange, "HorizAlpha" }, 99 { GuiColorPickerCtrl::pVertAlphaRange, "VertAlpha" }, 100 { GuiColorPickerCtrl::pDropperBackground, "Dropper" }, 101EndImplementEnumType; 102 103void GuiColorPickerCtrl::initPersistFields() 104{ 105 addGroup("ColorPicker"); 106 addField("baseColor", TypeColorF, Offset(mBaseColor, GuiColorPickerCtrl)); 107 addField("pickColor", TypeColorF, Offset(mPickColor, GuiColorPickerCtrl)); 108 addField("selectorGap", TypeS32, Offset(mSelectorGap, GuiColorPickerCtrl)); 109 addField("displayMode", TYPEID< PickMode >(), Offset(mDisplayMode, GuiColorPickerCtrl) ); 110 addField("actionOnMove", TypeBool,Offset(mActionOnMove, GuiColorPickerCtrl)); 111 addField("showReticle", TypeBool, Offset(mShowReticle, GuiColorPickerCtrl)); 112 endGroup("ColorPicker"); 113 114 Parent::initPersistFields(); 115} 116 117// Function to draw a box which can have 4 different colors in each corner blended together 118void GuiColorPickerCtrl::drawBlendBox(RectI &bounds, LinearColorF &c1, LinearColorF &c2, LinearColorF &c3, LinearColorF &c4) 119{ 120 GFX->setStateBlock(mStateBlock); 121 122 S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x; 123 S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y; 124 125 LinearColorF col[4]; 126 col[0] = c1; 127 col[1] = c2; 128 col[2] = c3; 129 col[3] = c4; 130 131 //A couple of checks to determine if color blend 132 if (c1 == colorWhite && c3 == colorAlpha && c4 == colorBlack) 133 { 134 //Color 135 PrimBuild::begin(GFXTriangleStrip, 4); 136 137 PrimBuild::color(col[1]); 138 PrimBuild::vertex2i(l, t); 139 140 PrimBuild::color(col[1]); 141 PrimBuild::vertex2i(r, t); 142 143 PrimBuild::color(col[1]); 144 PrimBuild::vertex2i(l, b); 145 146 PrimBuild::color(col[1]); 147 PrimBuild::vertex2i(r, b); 148 149 PrimBuild::end(); 150 151 //White 152 PrimBuild::begin(GFXTriangleStrip, 4); 153 154 PrimBuild::color(col[0]); 155 PrimBuild::vertex2i(l, t); 156 157 PrimBuild::color(colorAlphaW); 158 PrimBuild::vertex2i(r, t); 159 160 PrimBuild::color(col[0]); 161 PrimBuild::vertex2i(l, b); 162 163 PrimBuild::color(colorAlphaW); 164 PrimBuild::vertex2i(r, b); 165 166 PrimBuild::end(); 167 168 //Black 169 PrimBuild::begin(GFXTriangleStrip, 4); 170 171 PrimBuild::color(col[2]); 172 PrimBuild::vertex2i(l, t); 173 PrimBuild::color(col[2]); 174 PrimBuild::vertex2i(r, t); 175 176 PrimBuild::color(col[3]); 177 PrimBuild::vertex2i(l, b); 178 179 PrimBuild::color(col[3]); 180 PrimBuild::vertex2i(r, b); 181 182 PrimBuild::end(); 183 } 184 else 185 { 186 PrimBuild::begin(GFXTriangleStrip, 4); 187 188 PrimBuild::color(col[0]); 189 PrimBuild::vertex2i(l, t); 190 191 PrimBuild::color(col[1]); 192 PrimBuild::vertex2i(r, t); 193 194 PrimBuild::color(col[3]); 195 PrimBuild::vertex2i(l, b); 196 197 PrimBuild::color(col[2]); 198 PrimBuild::vertex2i(r, b); 199 200 PrimBuild::end(); 201 } 202} 203 204//-------------------------------------------------------------------------- 205/// Function to draw a set of boxes blending throughout an array of colors 206void GuiColorPickerCtrl::drawBlendRangeBox(RectI &bounds, bool vertical, U8 numColors, ColorI *colors) 207{ 208 209 GFX->setStateBlock(mStateBlock); 210 211 S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x + 4; 212 S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y + 4; 213 214 // Calculate increment value 215 S32 x_inc = int(mFloor((r - l) / F32(numColors - 1))); 216 S32 y_inc = int(mFloor((b - t) / F32(numColors - 1))); 217 218 ColorI *col = new ColorI[numColors]; 219 dMemcpy(col, colors, numColors * sizeof(ColorI)); 220 for (U16 i = 0; i < numColors - 1; i++) 221 col[i] = colors[i]; 222 223 for (U16 i = 0; i < numColors - 1; i++) 224 { 225 // This is not efficent, but then again it doesn't really need to be. -pw 226 PrimBuild::begin(GFXTriangleStrip, 4); 227 228 if (!vertical) // Horizontal (+x) 229 { 230 // First color 231 PrimBuild::color(col[i]); 232 PrimBuild::vertex2i(l, t); 233 PrimBuild::color(col[i + 1]); 234 PrimBuild::vertex2i(l + x_inc, t); 235 236 // Second color 237 PrimBuild::color(col[i]); 238 PrimBuild::vertex2i(l, b); 239 PrimBuild::color(col[i + 1]); 240 PrimBuild::vertex2i(l + x_inc, b); 241 l += x_inc; 242 } 243 else // Vertical (+y) 244 { 245 // First color 246 PrimBuild::color(col[i]); 247 PrimBuild::vertex2i(l, t); 248 PrimBuild::color(col[i + 1]); 249 PrimBuild::vertex2i(l, t + y_inc); 250 251 // Second color 252 PrimBuild::color(col[i]); 253 PrimBuild::vertex2i(r, t); 254 PrimBuild::color(col[i + 1]); 255 PrimBuild::vertex2i(r, t + y_inc); 256 t += y_inc; 257 } 258 PrimBuild::end(); 259 } 260 261 SAFE_DELETE_ARRAY(col); 262} 263 264void GuiColorPickerCtrl::drawSelector(RectI &bounds, Point2I &selectorPos, SelectorMode mode) 265{ 266 if( !mShowReticle ) 267 return; 268 269 U16 sMax = mSelectorGap*2; 270 const ColorI color = colorWhiteBlend.toColorI(); 271 switch (mode) 272 { 273 case sVertical: 274 // Now draw the vertical selector Up -> Pos 275 if (selectorPos.y != bounds.point.y+1) 276 GFX->getDrawUtil()->drawLine(selectorPos.x, bounds.point.y, selectorPos.x, selectorPos.y-sMax-1, color); 277 // Down -> Pos 278 if (selectorPos.y != bounds.point.y+bounds.extent.y) 279 GFX->getDrawUtil()->drawLine(selectorPos.x, selectorPos.y + sMax, selectorPos.x, bounds.point.y + bounds.extent.y, color); 280 break; 281 case sHorizontal: 282 // Now draw the horizontal selector Left -> Pos 283 if (selectorPos.x != bounds.point.x) 284 GFX->getDrawUtil()->drawLine(bounds.point.x, selectorPos.y-1, selectorPos.x-sMax, selectorPos.y-1, color); 285 // Right -> Pos 286 if (selectorPos.x != bounds.point.x) 287 GFX->getDrawUtil()->drawLine(bounds.point.x+mSelectorPos.x+sMax, selectorPos.y-1, bounds.point.x + bounds.extent.x, selectorPos.y-1, color); 288 break; 289 } 290} 291 292//-------------------------------------------------------------------------- 293/// Function to invoke calls to draw the picker box and selector 294void GuiColorPickerCtrl::renderColorBox(RectI &bounds) 295{ 296 RectI pickerBounds; 297 pickerBounds.point.x = bounds.point.x+1; 298 pickerBounds.point.y = bounds.point.y+1; 299 pickerBounds.extent.x = bounds.extent.x-1; 300 pickerBounds.extent.y = bounds.extent.y-1; 301 302 if (mProfile->mBorder) 303 GFX->getDrawUtil()->drawRect(bounds, mProfile->mBorderColor); 304 305 Point2I selectorPos = Point2I(bounds.point.x+mSelectorPos.x+1, bounds.point.y+mSelectorPos.y+1); 306 307 // Draw color box differently depending on mode 308 RectI blendRect; 309 switch (mDisplayMode) 310 { 311 case pHorizColorRange: 312 drawBlendRangeBox( pickerBounds, false, 7, mColorRange); 313 drawSelector( pickerBounds, selectorPos, sVertical ); 314 break; 315 case pVertColorRange: 316 drawBlendRangeBox( pickerBounds, true, 7, mColorRange); 317 drawSelector( pickerBounds, selectorPos, sHorizontal ); 318 break; 319 case pHorizColorBrightnessRange: 320 blendRect = pickerBounds; 321 blendRect.point.y++; 322 blendRect.extent.y -= 2; 323 drawBlendRangeBox( pickerBounds, false, 7, mColorRange); 324 // This is being drawn slightly offset from the larger rect so as to insure 255 and 0 325 // can both be selected for every color. 326 drawBlendBox( blendRect, colorAlpha, colorAlpha, colorBlack, colorBlack ); 327 blendRect.point.y += blendRect.extent.y - 1; 328 blendRect.extent.y = 2; 329 GFX->getDrawUtil()->drawRect( blendRect, colorBlack.toColorI()); 330 drawSelector( pickerBounds, selectorPos, sHorizontal ); 331 drawSelector( pickerBounds, selectorPos, sVertical ); 332 break; 333 case pVertColorBrightnessRange: 334 drawBlendRangeBox( pickerBounds, true, 7, mColorRange); 335 drawBlendBox( pickerBounds, colorAlpha, colorBlack, colorBlack, colorAlpha ); 336 drawSelector( pickerBounds, selectorPos, sHorizontal ); 337 drawSelector( pickerBounds, selectorPos, sVertical ); 338 break; 339 case pHorizAlphaRange: 340 drawBlendBox( pickerBounds, colorBlack, colorWhite, colorWhite, colorBlack ); 341 drawSelector( pickerBounds, selectorPos, sVertical ); 342 break; 343 case pVertAlphaRange: 344 drawBlendBox( pickerBounds, colorBlack, colorBlack, colorWhite, colorWhite ); 345 drawSelector( pickerBounds, selectorPos, sHorizontal ); 346 break; 347 case pBlendColorRange: 348 drawBlendBox( pickerBounds, colorWhite, mBaseColor, colorAlpha, colorBlack ); 349 drawSelector( pickerBounds, selectorPos, sHorizontal ); 350 drawSelector( pickerBounds, selectorPos, sVertical ); 351 break; 352 case pDropperBackground: 353 break; 354 case pPallet: 355 default: 356 GFX->getDrawUtil()->drawRectFill( pickerBounds, mBaseColor.toColorI()); 357 break; 358 } 359} 360 361void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) 362{ 363 if (mStateBlock.isNull()) 364 { 365 GFXStateBlockDesc desc; 366 desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); 367 desc.setZReadWrite(false); 368 desc.zWriteEnable = false; 369 desc.setCullMode(GFXCullNone); 370 mStateBlock = GFX->createStateBlock(desc); 371 } 372 373 RectI boundsRect(offset, getExtent()); 374 renderColorBox(boundsRect); 375 376 if (mPositionChanged || mBitmap == NULL) 377 { 378 bool nullBitmap = false; 379 380 if (mPositionChanged == false && mBitmap == NULL) 381 nullBitmap = true; 382 383 mPositionChanged = false; 384 Point2I extent = getRoot()->getExtent(); 385 386 // If we are anything but a pallete, change the pick color 387 if (mDisplayMode != pPallet) 388 { 389 Point2I resolution = getRoot()->getExtent(); 390 391 U32 buf_x = offset.x + mSelectorPos.x + 1; 392 U32 buf_y = resolution.y - (extent.y - (offset.y + mSelectorPos.y + 1)); 393 394 GFXTexHandle bb(resolution.x, resolution.y, GFXFormatR8G8B8A8_SRGB, &GFXRenderTargetSRGBProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__)); 395 396 Point2I tmpPt(buf_x, buf_y); 397 398 GFXTarget *targ = GFX->getActiveRenderTarget(); 399 targ->resolveTo(bb); 400 401 if (mBitmap) 402 { 403 delete mBitmap; 404 mBitmap = NULL; 405 } 406 407 mBitmap = new GBitmap(bb.getWidth(), bb.getHeight(),false,GFXFormatR8G8B8A8); 408 409 bb.copyToBmp(mBitmap); 410 411 if (!nullBitmap) 412 { 413 if (mSelectColor) 414 { 415 Point2I pos = findColor(mSetColor, offset, resolution, *mBitmap); 416 mSetColor = mSetColor.BLACK; 417 mSelectColor = false; 418 setSelectorPos(pos); 419 } 420 else 421 { 422 ColorI tmp; 423 mBitmap->getColor(buf_x, buf_y, tmp); 424 425 mPickColor = (LinearColorF)tmp; 426 427 // Now do onAction() if we are allowed 428 if (mActionOnMove) 429 onAction(); 430 } 431 } 432 } 433 } 434 435 //render the children 436 renderChildControls(offset, updateRect); 437} 438 439void GuiColorPickerCtrl::setSelectorPos(const LinearColorF & color) 440{ 441 if (mBitmap && !mPositionChanged) 442 { 443 Point2I resolution = getRoot() ? getRoot()->getExtent() : Point2I(1024, 768); 444 RectI rect(getGlobalBounds()); 445 Point2I pos = findColor(color, rect.point, resolution, *mBitmap); 446 mSetColor = mSetColor.BLACK; 447 mSelectColor = false; 448 449 setSelectorPos(pos); 450 } 451 else 452 { 453 mSetColor = color; 454 mSelectColor = true; 455 mPositionChanged = true; 456 } 457} 458 459Point2I GuiColorPickerCtrl::findColor(const LinearColorF & color, const Point2I& offset, const Point2I& resolution, GBitmap& bmp) 460{ 461 RectI rect; 462 Point2I ext = getExtent(); 463 if (mDisplayMode != pDropperBackground) 464 { 465 ext.x -= 3; 466 ext.y -= 2; 467 rect = RectI(Point2I(1, 1), ext); 468 } 469 else 470 { 471 rect = RectI(Point2I(0, 0), ext); 472 } 473 474 Point2I closestPos(-1, -1); 475 476 /* Debugging 477 char filename[256]; 478 dSprintf( filename, 256, "%s.%s", "colorPickerTest", "png" ); 479 480 // Open up the file on disk. 481 FileStream fs; 482 if ( !fs.open( filename, Torque::FS::File::Write ) ) 483 Con::errorf( "GuiObjectView::saveAsImage() - Failed to open output file '%s'!", filename ); 484 else 485 { 486 // Write it and close. 487 bmp.writeBitmap( "png", fs ); 488 489 fs.close(); 490 } 491 */ 492 493 ColorI tmp; 494 U32 buf_x; 495 U32 buf_y; 496 LinearColorF curColor; 497 F32 val(10000.0f); 498 F32 closestVal(10000.0f); 499 bool closestSet = false; 500 501 for (S32 x = rect.point.x; x <= rect.extent.x; x++) 502 { 503 for (S32 y = rect.point.y; y <= rect.extent.y; y++) 504 { 505 buf_x = offset.x + x + 1; 506 buf_y = (resolution.y - (offset.y + y + 1)); 507 buf_y = resolution.y - buf_y; 508 509 //Get the color at that position 510 bmp.getColor(buf_x, buf_y, tmp); 511 curColor = (LinearColorF)tmp; 512 513 //Evaluate how close the color is to our desired color 514 val = mFabs(color.red - curColor.red) + mFabs(color.green - curColor.green) + mFabs(color.blue - curColor.blue); 515 516 if (!closestSet) 517 { 518 closestVal = val; 519 closestPos.set(x, y); 520 closestSet = true; 521 } 522 else if (val < closestVal) 523 { 524 closestVal = val; 525 closestPos.set(x, y); 526 } 527 } 528 } 529 530 return closestPos; 531} 532 533void GuiColorPickerCtrl::setSelectorPos(const Point2I &pos) 534{ 535 Point2I extent = getExtent(); 536 RectI rect; 537 if (mDisplayMode != pDropperBackground) 538 { 539 extent.x -= 3; 540 extent.y -= 2; 541 rect = RectI(Point2I(1,1), extent); 542 } 543 else 544 { 545 rect = RectI(Point2I(0,0), extent); 546 } 547 548 if (rect.pointInRect(pos)) 549 { 550 mSelectorPos = pos; 551 mPositionChanged = true; 552 // We now need to update 553 setUpdate(); 554 } 555 556 else 557 { 558 if ((pos.x > rect.point.x) && (pos.x < (rect.point.x + rect.extent.x))) 559 mSelectorPos.x = pos.x; 560 else if (pos.x <= rect.point.x) 561 mSelectorPos.x = rect.point.x; 562 else if (pos.x >= (rect.point.x + rect.extent.x)) 563 mSelectorPos.x = rect.point.x + rect.extent.x - 1; 564 565 if ((pos.y > rect.point.y) && (pos.y < (rect.point.y + rect.extent.y))) 566 mSelectorPos.y = pos.y; 567 else if (pos.y <= rect.point.y) 568 mSelectorPos.y = rect.point.y; 569 else if (pos.y >= (rect.point.y + rect.extent.y)) 570 mSelectorPos.y = rect.point.y + rect.extent.y - 1; 571 572 mPositionChanged = true; 573 setUpdate(); 574 } 575} 576 577void GuiColorPickerCtrl::onMouseDown(const GuiEvent &event) 578{ 579 if (!mActive) 580 return; 581 582 if (mDisplayMode == pDropperBackground) 583 return; 584 585 mouseLock(this); 586 587 if (mProfile->mCanKeyFocus) 588 setFirstResponder(); 589 590 if (mActive && (mDisplayMode != pDropperBackground)) 591 onAction(); 592 593 // Update the picker cross position 594 if (mDisplayMode != pPallet) 595 setSelectorPos(globalToLocalCoord(event.mousePoint)); 596 597 mMouseDown = true; 598} 599 600//-------------------------------------------------------------------------- 601void GuiColorPickerCtrl::onMouseDragged(const GuiEvent &event) 602{ 603 if ((mActive && mMouseDown) || (mActive && (mDisplayMode == pDropperBackground))) 604 { 605 // Update the picker cross position 606 if (mDisplayMode != pPallet) 607 setSelectorPos(globalToLocalCoord(event.mousePoint)); 608 } 609 610 if( !mActionOnMove ) 611 execAltConsoleCallback(); 612} 613 614void GuiColorPickerCtrl::onMouseMove(const GuiEvent &event) 615{ 616 // Only for dropper mode 617 if (mActive && (mDisplayMode == pDropperBackground)) 618 setSelectorPos(globalToLocalCoord(event.mousePoint)); 619} 620 621void GuiColorPickerCtrl::onMouseEnter(const GuiEvent &event) 622{ 623 mMouseOver = true; 624} 625 626void GuiColorPickerCtrl::onMouseLeave(const GuiEvent &) 627{ 628 // Reset state 629 mMouseOver = false; 630} 631 632void GuiColorPickerCtrl::onMouseUp(const GuiEvent &) 633{ 634 //if we released the mouse within this control, perform the action 635 if (mActive && mMouseDown && (mDisplayMode != pDropperBackground)) 636 mMouseDown = false; 637 638 if (mActive && (mDisplayMode == pDropperBackground)) 639 { 640 // In a dropper, the alt command executes the mouse up action (to signal stopping) 641 execAltConsoleCallback(); 642 } 643 644 mouseUnlock(); 645} 646 647const char *GuiColorPickerCtrl::getScriptValue() 648{ 649 static char temp[256]; 650 LinearColorF color = getValue(); 651 dSprintf( temp, 256, "%f %f %f %f", color.red, color.green, color.blue, color.alpha ); 652 return temp; 653} 654 655void GuiColorPickerCtrl::setScriptValue(const char *value) 656{ 657 LinearColorF newValue; 658 dSscanf(value, "%f %f %f %f", &newValue.red, &newValue.green, &newValue.blue, &newValue.alpha); 659 setValue(newValue); 660} 661 662DefineEngineMethod(GuiColorPickerCtrl, getSelectorPos, Point2I, (), , "Gets the current position of the selector") 663{ 664 return object->getSelectorPos(); 665} 666 667DefineEngineMethod(GuiColorPickerCtrl, setSelectorPos, void, (Point2I newPos), , "Sets the current position of the selector") 668{ 669 object->setSelectorPos(newPos); 670} 671 672DefineEngineMethod(GuiColorPickerCtrl, updateColor, void, (), , "Forces update of pick color") 673{ 674 object->updateColor(); 675} 676 677DefineEngineMethod(GuiColorPickerCtrl, setSelectorColor, void, (LinearColorF color), , 678 "Sets the current position of the selector based on a color.n" 679 "@param color Color to look for.n") 680{ 681 object->setSelectorPos(color); 682} 683