00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include <sstream>
00035 #include <iomanip>
00036
00037 #include "llfloatercolorpicker.h"
00038
00039 #include "llfontgl.h"
00040 #include "llsys.h"
00041 #include "llgl.h"
00042 #include "v3dmath.h"
00043 #include "lldir.h"
00044 #include "llui.h"
00045 #include "lllineeditor.h"
00046 #include "v4coloru.h"
00047 #include "llbutton.h"
00048 #include "llviewercontrol.h"
00049 #include "viewer.h"
00050 #include "llvieweruictrlfactory.h"
00051 #include "llviewerwindow.h"
00052 #include "llgl.h"
00053 #include "llmemory.h"
00054 #include "llimage.h"
00055 #include "llmousehandler.h"
00056 #include "llimagegl.h"
00057 #include "llglheaders.h"
00058 #include "llcheckboxctrl.h"
00059 #include "llworld.h"
00060 #include "lltextbox.h"
00061 #include "lluiconstants.h"
00062 #include "llfocusmgr.h"
00063 #include "lltoolmgr.h"
00064 #include "lltoolpipette.h"
00065 #include "lldraghandle.h"
00066
00067 const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
00068 const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
00069 const F32 CONTEXT_FADE_TIME = 0.08f;
00070
00072
00073
00074
00076
00078
00079 LLFloaterColorPicker::
00080 LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate )
00081 : LLFloater ("Color Picker Floater"),
00082 mComponents ( 3 ),
00083 mMouseDownInLumRegion ( FALSE ),
00084 mMouseDownInHueRegion ( FALSE ),
00085 mMouseDownInSwatch ( FALSE ),
00086
00087 mRGBViewerImageLeft ( 140 ),
00088 mRGBViewerImageTop ( 356 ),
00089 mRGBViewerImageWidth ( 256 ),
00090 mRGBViewerImageHeight ( 256 ),
00091 mLumRegionLeft ( mRGBViewerImageLeft + mRGBViewerImageWidth + 16 ),
00092 mLumRegionTop ( mRGBViewerImageTop ),
00093 mLumRegionWidth ( 16 ),
00094 mLumRegionHeight ( mRGBViewerImageHeight ),
00095 mLumMarkerSize ( 6 ),
00096
00097 mSwatchRegionLeft ( 12 ),
00098 mSwatchRegionTop ( 190 ),
00099 mSwatchRegionWidth ( 116 ),
00100 mSwatchRegionHeight ( 60 ),
00101 mSwatchView ( NULL ),
00102
00103 numPaletteColumns ( 16 ),
00104 numPaletteRows ( 2 ),
00105 highlightEntry ( -1 ),
00106 mPaletteRegionLeft ( 11 ),
00107 mPaletteRegionTop ( 100 - 8 ),
00108 mPaletteRegionWidth ( mLumRegionLeft + mLumRegionWidth - 10 ),
00109 mPaletteRegionHeight ( 40 ),
00110 mSwatch ( swatch ),
00111 mActive ( TRUE ),
00112 mCanApplyImmediately ( show_apply_immediate ),
00113 mContextConeOpacity ( 0.f )
00114 {
00115
00116 createUI ();
00117
00118 if (!mCanApplyImmediately)
00119 {
00120 mApplyImmediateCheck->setEnabled(FALSE);
00121 mApplyImmediateCheck->set(FALSE);
00122 }
00123 }
00124
00126
00127 LLFloaterColorPicker::
00128 ~LLFloaterColorPicker()
00129 {
00130
00131 destroyUI ();
00132 }
00133
00135
00136 void
00137 LLFloaterColorPicker::
00138 createUI ()
00139 {
00140
00141 gUICtrlFactory->buildFloater ( this, "floater_color_picker.xml" );
00142 setVisible ( FALSE );
00143
00144
00145
00146 LLPointer<LLImageRaw> raw = new LLImageRaw ( mRGBViewerImageWidth, mRGBViewerImageHeight, mComponents );
00147 U8* bits = raw->getData();
00148 S32 linesize = mRGBViewerImageWidth * mComponents;
00149 for ( S32 y = 0; y < mRGBViewerImageHeight; ++y )
00150 {
00151 for ( S32 x = 0; x < linesize; x += mComponents )
00152 {
00153 F32 rVal, gVal, bVal;
00154
00155 hslToRgb ( (F32)x / (F32) ( linesize - 1 ),
00156 (F32)y / (F32) ( mRGBViewerImageHeight - 1 ),
00157 0.5f,
00158 rVal,
00159 gVal,
00160 bVal );
00161
00162 * ( bits + x + y * linesize + 0 ) = ( U8 )( rVal * 255.0f );
00163 * ( bits + x + y * linesize + 1 ) = ( U8 )( gVal * 255.0f );
00164 * ( bits + x + y * linesize + 2 ) = ( U8 )( bVal * 255.0f );
00165 }
00166 }
00167 mRGBImage = new LLImageGL ( (LLImageRaw*)raw, FALSE );
00168 mRGBImage->bind();
00169 mRGBImage->setClamp(TRUE, TRUE);
00170
00171
00172 for ( S32 each = 0; each < numPaletteColumns * numPaletteRows; ++each )
00173 {
00174 std::ostringstream codec;
00175 codec << "ColorPaletteEntry" << std::setfill ( '0' ) << std::setw ( 2 ) << each + 1;
00176
00177
00178 const std::string s ( codec.str () );
00179 mPalette.push_back ( new LLColor4 ( gSavedSettings.getColor4 ( s ) ) );
00180 }
00181 }
00182
00184
00185 void
00186 LLFloaterColorPicker::
00187 showUI ()
00188 {
00189 setVisible ( TRUE );
00190 setFocus ( TRUE );
00191 open();
00192
00193
00194 if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
00195 {
00196 LLColorSwatchCtrl* swatch = getSwatch ();
00197
00198 setVisible ( FALSE );
00199
00200
00201 if ( swatch )
00202 {
00203 LLColor4 curCol = swatch->get ();
00204 send_agent_pause();
00205 gViewerWindow->getWindow ()->dialog_color_picker ( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
00206 send_agent_resume();
00207
00208 setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
00209 setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
00210
00211 LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE );
00212 }
00213
00214 close();
00215 }
00216 }
00217
00219
00220 BOOL
00221 LLFloaterColorPicker::
00222 postBuild()
00223 {
00224 mCancelBtn = LLViewerUICtrlFactory::getButtonByName( this, "cancel_btn" );
00225 mCancelBtn->setClickedCallback ( onClickCancel );
00226 mCancelBtn->setCallbackUserData ( this );
00227
00228 mSelectBtn = LLViewerUICtrlFactory::getButtonByName( this, "select_btn");
00229 mSelectBtn->setClickedCallback ( onClickSelect );
00230 mSelectBtn->setCallbackUserData ( this );
00231 mSelectBtn->setFocus ( TRUE );
00232
00233 mPipetteBtn = LLViewerUICtrlFactory::getButtonByName ( this, "color_pipette" );
00234
00235 mPipetteBtn->setImages("eye_button_inactive.tga", "eye_button_active.tga");
00236
00237 mPipetteBtn->setClickedCallback( onClickPipette );
00238 mPipetteBtn->setCallbackUserData ( this );
00239
00240 mApplyImmediateCheck = LLViewerUICtrlFactory::getCheckBoxByName( this, "apply_immediate");
00241 mApplyImmediateCheck->set(gSavedSettings.getBOOL("ApplyColorImmediately"));
00242 mApplyImmediateCheck->setCommitCallback(onImmediateCheck);
00243 mApplyImmediateCheck->setCallbackUserData(this);
00244
00245 childSetCommitCallback("rspin", onTextCommit, (void*)this );
00246 childSetCommitCallback("gspin", onTextCommit, (void*)this );
00247 childSetCommitCallback("bspin", onTextCommit, (void*)this );
00248 childSetCommitCallback("hspin", onTextCommit, (void*)this );
00249 childSetCommitCallback("sspin", onTextCommit, (void*)this );
00250 childSetCommitCallback("lspin", onTextCommit, (void*)this );
00251
00252 return TRUE;
00253 }
00254
00256
00257 void
00258 LLFloaterColorPicker::
00259 initUI ( F32 rValIn, F32 gValIn, F32 bValIn )
00260 {
00261
00262 enableTextCallbacks ( TRUE );
00263
00264
00265 rValIn = llclamp ( rValIn, 0.0f, 1.0f );
00266 gValIn = llclamp ( gValIn, 0.0f, 1.0f );
00267 bValIn = llclamp ( bValIn, 0.0f, 1.0f );
00268
00269
00270 setOrigRgb ( rValIn, gValIn, bValIn );
00271
00272
00273 setCurRgb ( rValIn, gValIn, bValIn );
00274
00275
00276 updateTextEntry ();
00277 }
00278
00280
00281 void
00282 LLFloaterColorPicker::
00283 destroyUI ()
00284 {
00285
00286 stopUsingPipette();
00287
00288
00289 std::vector < LLColor4* >::iterator iter = mPalette.begin ();
00290 while ( iter != mPalette.end () )
00291 {
00292 delete ( *iter );
00293 ++iter;
00294 }
00295
00296 if ( mSwatchView )
00297 {
00298 this->removeChild ( mSwatchView );
00299 delete mSwatchView;
00300 mSwatchView = NULL;
00301 }
00302 }
00303
00304
00306
00307 F32
00308 LLFloaterColorPicker::
00309 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
00310 {
00311 if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
00312 if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
00313 if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn );
00314 if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In );
00315 if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f );
00316 return ( val1In );
00317 }
00318
00320
00321 void
00322 LLFloaterColorPicker::
00323 hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut )
00324 {
00325 if ( sValIn < 0.00001f )
00326 {
00327 rValOut = lValIn;
00328 gValOut = lValIn;
00329 bValOut = lValIn;
00330 }
00331 else
00332 {
00333 F32 interVal1;
00334 F32 interVal2;
00335
00336 if ( lValIn < 0.5f )
00337 interVal2 = lValIn * ( 1.0f + sValIn );
00338 else
00339 interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn );
00340
00341 interVal1 = 2.0f * lValIn - interVal2;
00342
00343 rValOut = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) );
00344 gValOut = hueToRgb ( interVal1, interVal2, hValIn );
00345 bValOut = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) );
00346 }
00347 }
00348
00350
00351 void
00352 LLFloaterColorPicker::
00353 setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn )
00354 {
00355 origR = origRIn;
00356 origG = origGIn;
00357 origB = origBIn;
00358 }
00359
00361
00362 void
00363 LLFloaterColorPicker::
00364 getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut )
00365 {
00366 origROut = origR;
00367 origGOut = origG;
00368 origBOut = origB;
00369 }
00370
00372
00373 void
00374 LLFloaterColorPicker::
00375 setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn )
00376 {
00377
00378 curR = curRIn;
00379 curG = curGIn;
00380 curB = curBIn;
00381
00382
00383 LLColor3(curRIn, curGIn, curBIn).calcHSL(&curH, &curS, &curL);
00384
00385
00386
00387
00388 enableTextCallbacks( FALSE );
00389 updateTextEntry();
00390 enableTextCallbacks( TRUE );
00391 }
00392
00394
00395 void
00396 LLFloaterColorPicker::
00397 getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut )
00398 {
00399 curROut = curR;
00400 curGOut = curG;
00401 curBOut = curB;
00402 }
00403
00405
00406 void
00407 LLFloaterColorPicker::
00408 setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn )
00409 {
00410
00411 curH = curHIn;
00412 curS = curSIn;
00413 curL = curLIn;
00414
00415
00416 hslToRgb ( curH, curS, curL, curR, curG, curB );
00417 }
00418
00420
00421 void
00422 LLFloaterColorPicker::
00423 getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut )
00424 {
00425 curHOut = curH;
00426 curSOut = curS;
00427 curLOut = curL;
00428 }
00429
00431
00432 void
00433 LLFloaterColorPicker::
00434 onClickCancel ( void* data )
00435 {
00436 if (data)
00437 {
00438 LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data;
00439
00440 if ( self )
00441 {
00442 self->cancelSelection ();
00443 self->close();
00444 }
00445 }
00446 }
00447
00449
00450 void
00451 LLFloaterColorPicker::
00452 onClickSelect ( void* data )
00453 {
00454 if (data)
00455 {
00456 LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data;
00457
00458 if ( self )
00459 {
00460
00461 LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_SELECT );
00462 self->close();
00463 }
00464 }
00465 }
00466
00467 void LLFloaterColorPicker::onClickPipette( void* data )
00468 {
00469 LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data;
00470
00471 if ( self && gToolMgr)
00472 {
00473 BOOL pipette_active = self->mPipetteBtn->getToggleState();
00474 pipette_active = !pipette_active;
00475 if (pipette_active)
00476 {
00477 gToolPipette->setSelectCallback(onColorSelect, self);
00478 gToolMgr->setTransientTool(gToolPipette);
00479 }
00480 else
00481 {
00482 gToolMgr->clearTransientTool();
00483 }
00484 }
00485 }
00486
00488
00489 void
00490 LLFloaterColorPicker::
00491 onTextCommit ( LLUICtrl* ctrl, void* data )
00492 {
00493 if ( data )
00494 {
00495 LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data;
00496 if ( self )
00497 {
00498 self->onTextEntryChanged ( ctrl );
00499 }
00500 }
00501 }
00502
00503 void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data)
00504 {
00505 LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data;
00506 if (self)
00507 {
00508 gSavedSettings.setBOOL("ApplyColorImmediately", self->mApplyImmediateCheck->get());
00509
00510 if (self->mApplyImmediateCheck->get())
00511 {
00512 LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
00513 }
00514 }
00515 }
00516
00517 void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te, void *data )
00518 {
00519 LLFloaterColorPicker* self = (LLFloaterColorPicker*)data;
00520 if (self)
00521 {
00522 self->setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]);
00523 if (self->mApplyImmediateCheck->get())
00524 {
00525 LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
00526 }
00527 }
00528 }
00529
00530 void LLFloaterColorPicker::onMouseCaptureLost()
00531 {
00532 setMouseDownInHueRegion(FALSE);
00533 setMouseDownInLumRegion(FALSE);
00534 }
00535
00537
00538 void LLFloaterColorPicker::draw()
00539 {
00540 LLRect swatch_rect;
00541 mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this);
00542
00543 LLRect local_rect = getLocalRect();
00544 if (gFocusMgr.childHasKeyboardFocus(this) && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
00545 {
00546 LLGLSNoTexture no_texture;
00547 LLGLEnable(GL_CULL_FACE);
00548 glBegin(GL_QUADS);
00549 {
00550 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00551 glVertex2i(swatch_rect.mLeft, swatch_rect.mTop);
00552 glVertex2i(swatch_rect.mRight, swatch_rect.mTop);
00553 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00554 glVertex2i(local_rect.mRight, local_rect.mTop);
00555 glVertex2i(local_rect.mLeft, local_rect.mTop);
00556
00557 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00558 glVertex2i(local_rect.mLeft, local_rect.mTop);
00559 glVertex2i(local_rect.mLeft, local_rect.mBottom);
00560 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00561 glVertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
00562 glVertex2i(swatch_rect.mLeft, swatch_rect.mTop);
00563
00564 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00565 glVertex2i(local_rect.mRight, local_rect.mBottom);
00566 glVertex2i(local_rect.mRight, local_rect.mTop);
00567 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00568 glVertex2i(swatch_rect.mRight, swatch_rect.mTop);
00569 glVertex2i(swatch_rect.mRight, swatch_rect.mBottom);
00570
00571 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00572 glVertex2i(local_rect.mLeft, local_rect.mBottom);
00573 glVertex2i(local_rect.mRight, local_rect.mBottom);
00574 glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00575 glVertex2i(swatch_rect.mRight, swatch_rect.mBottom);
00576 glVertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
00577 }
00578 glEnd();
00579 }
00580
00581 if (gFocusMgr.childHasMouseCapture(mDragHandle))
00582 {
00583 mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
00584 }
00585 else
00586 {
00587 mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
00588 }
00589
00590 mPipetteBtn->setEnabled(gToolMgr != NULL);
00591 mPipetteBtn->setToggleState(gToolMgr && gToolMgr->getCurrentTool() == gToolPipette);
00592 mApplyImmediateCheck->setEnabled(mActive && mCanApplyImmediately);
00593 mSelectBtn->setEnabled(mActive);
00594
00595
00596 LLFloater::draw ();
00597
00598
00599 gl_draw_image ( mRGBViewerImageLeft, mRGBViewerImageTop - mRGBViewerImageHeight, mRGBImage, LLColor4::white );
00600
00601
00602 S32 xPos = ( S32 ) ( ( F32 )mRGBViewerImageWidth * getCurH () ) - 8;
00603 S32 yPos = ( S32 ) ( ( F32 )mRGBViewerImageHeight * getCurS () ) - 8;
00604 gl_line_2d ( mRGBViewerImageLeft + xPos,
00605 mRGBViewerImageTop - mRGBViewerImageHeight + yPos + 8,
00606 mRGBViewerImageLeft + xPos + 16,
00607 mRGBViewerImageTop - mRGBViewerImageHeight + yPos + 8,
00608 LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ) );
00609
00610 gl_line_2d ( mRGBViewerImageLeft + xPos + 8,
00611 mRGBViewerImageTop - mRGBViewerImageHeight + yPos,
00612 mRGBViewerImageLeft + xPos + 8,
00613 mRGBViewerImageTop - mRGBViewerImageHeight + yPos + 16,
00614 LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ) );
00615
00616
00617 gl_rect_2d ( mRGBViewerImageLeft,
00618 mRGBViewerImageTop - mRGBViewerImageHeight,
00619 mRGBViewerImageLeft + mRGBViewerImageWidth,
00620 mRGBViewerImageTop,
00621 LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ),
00622 FALSE );
00623
00624
00625 for ( S32 y = 0; y < mLumRegionHeight; ++y )
00626 {
00627 F32 rValSlider, gValSlider, bValSlider;
00628 hslToRgb ( getCurH (), getCurS (), ( F32 )y / ( F32 )mLumRegionHeight, rValSlider, gValSlider, bValSlider );
00629
00630 gl_rect_2d( mLumRegionLeft,
00631 mLumRegionTop - mLumRegionHeight + y,
00632 mLumRegionLeft + mLumRegionWidth,
00633 mLumRegionTop - mLumRegionHeight + y - 1,
00634 LLColor4 ( rValSlider, gValSlider, bValSlider, 1.0f ) );
00635 }
00636
00637
00638
00639 S32 startX = mLumRegionLeft + mLumRegionWidth;
00640 S32 startY = mLumRegionTop - mLumRegionHeight + ( S32 ) ( mLumRegionHeight * getCurL () );
00641 gl_triangle_2d ( startX, startY,
00642 startX + mLumMarkerSize, startY - mLumMarkerSize,
00643 startX + mLumMarkerSize, startY + mLumMarkerSize,
00644 LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ), TRUE );
00645
00646
00647 gl_rect_2d ( mLumRegionLeft,
00648 mLumRegionTop - mLumRegionHeight,
00649 mLumRegionLeft + mLumRegionWidth,
00650 mLumRegionTop,
00651 LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ),
00652 FALSE );
00653
00654
00655 gl_rect_2d ( mSwatchRegionLeft,
00656 mSwatchRegionTop - mSwatchRegionHeight,
00657 mSwatchRegionLeft + mSwatchRegionWidth,
00658 mSwatchRegionTop,
00659 LLColor4 ( getCurR (), getCurG (), getCurB (), 1.0f ),
00660 TRUE );
00661
00662
00663 gl_rect_2d ( mSwatchRegionLeft,
00664 mSwatchRegionTop - mSwatchRegionHeight,
00665 mSwatchRegionLeft + mSwatchRegionWidth,
00666 mSwatchRegionTop,
00667 LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ),
00668 FALSE );
00669
00670
00671 drawPalette ();
00672 }
00673
00675
00676 LLColor4&
00677 LLFloaterColorPicker::
00678 getComplimentaryColor ( LLColor4& backgroundColor )
00679 {
00680
00681 F32 hVal, sVal, lVal;
00682 backgroundColor.calcHSL(&hVal, &sVal, &lVal);
00683 hVal *= 360.f;
00684 sVal *= 100.f;
00685 lVal *= 100.f;
00686
00687
00688 if ( lVal < 0.5f )
00689 {
00690 return LLColor4::white;
00691 }
00692
00693 return LLColor4::black;
00694 }
00695
00697
00698 void
00699 LLFloaterColorPicker::
00700 drawPalette ()
00701 {
00702 S32 curEntry = 0;
00703
00704 for ( S32 y = 0; y < numPaletteRows; ++y )
00705 {
00706 for ( S32 x = 0; x < numPaletteColumns; ++x )
00707 {
00708
00709 S32 x1 = mPaletteRegionLeft + ( mPaletteRegionWidth * x ) / numPaletteColumns;
00710 S32 y1 = mPaletteRegionTop - ( mPaletteRegionHeight * y ) / numPaletteRows;
00711 S32 x2 = ( mPaletteRegionLeft + ( mPaletteRegionWidth * ( x + 1 ) ) / numPaletteColumns );
00712 S32 y2 = ( mPaletteRegionTop - ( mPaletteRegionHeight * ( y + 1 ) ) / numPaletteRows );
00713
00714
00715 if ( mPalette [ curEntry ] )
00716 {
00717 gl_rect_2d ( x1 + 2, y1 - 2, x2 - 2, y2 + 2, *mPalette [ curEntry++ ], TRUE );
00718 gl_rect_2d ( x1 + 1, y1 - 1, x2 - 1, y2 + 1, LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ), FALSE );
00719 }
00720 }
00721 }
00722
00723
00724 if ( highlightEntry >= 0 )
00725 {
00726
00727 S32 entryColumn = highlightEntry % numPaletteColumns;
00728 S32 entryRow = highlightEntry / numPaletteColumns;
00729
00730
00731 S32 x1 = mPaletteRegionLeft + ( mPaletteRegionWidth * entryColumn ) / numPaletteColumns;
00732 S32 y1 = mPaletteRegionTop - ( mPaletteRegionHeight * entryRow ) / numPaletteRows;
00733 S32 x2 = ( mPaletteRegionLeft + ( mPaletteRegionWidth * ( entryColumn + 1 ) ) / numPaletteColumns );
00734 S32 y2 = ( mPaletteRegionTop - ( mPaletteRegionHeight * ( entryRow + 1 ) ) / numPaletteRows );
00735
00736
00737 S32 xCenter = x1 + ( x2 - x1 ) / 2;
00738 S32 yCenter = y1 - ( y1 - y2 ) / 2;
00739
00740
00741 LLColor4 hlColor ( getComplimentaryColor ( *mPalette [ highlightEntry ] ) );
00742
00743
00744 gl_line_2d ( xCenter - 4, yCenter - 4, xCenter + 4, yCenter + 4, hlColor );
00745 gl_line_2d ( xCenter + 4, yCenter - 4, xCenter - 4, yCenter + 4, hlColor );
00746 }
00747 }
00748
00750
00751 void
00752 LLFloaterColorPicker::
00753 updateTextEntry ()
00754 {
00755
00756 childSetValue("rspin", ( getCurR () * 255.0f ) );
00757 childSetValue("gspin", ( getCurG () * 255.0f ) );
00758 childSetValue("bspin", ( getCurB () * 255.0f ) );
00759 childSetValue("hspin", ( getCurH () * 360.0f ) );
00760 childSetValue("sspin", ( getCurS () * 100.0f ) );
00761 childSetValue("lspin", ( getCurL () * 100.0f ) );
00762 }
00763
00765
00766 void
00767 LLFloaterColorPicker::
00768 enableTextCallbacks ( BOOL stateIn )
00769 {
00770 if ( stateIn )
00771 {
00772 childSetCommitCallback("rspin", onTextCommit, (void*)this );
00773 childSetCommitCallback("gspin", onTextCommit, (void*)this );
00774 childSetCommitCallback("bspin", onTextCommit, (void*)this );
00775 childSetCommitCallback("hspin", onTextCommit, (void*)this );
00776 childSetCommitCallback("sspin", onTextCommit, (void*)this );
00777 childSetCommitCallback("lspin", onTextCommit, (void*)this );
00778 }
00779 else
00780 {
00781 childSetCommitCallback("rspin", 0, (void*)this );
00782 childSetCommitCallback("gspin", 0, (void*)this );
00783 childSetCommitCallback("bspin", 0, (void*)this );
00784 childSetCommitCallback("hspin", 0, (void*)this );
00785 childSetCommitCallback("sspin", 0, (void*)this );
00786 childSetCommitCallback("lspin", 0, (void*)this );
00787 }
00788 }
00789
00790
00792
00793 void
00794 LLFloaterColorPicker::
00795 onTextEntryChanged ( LLUICtrl* ctrl )
00796 {
00797
00798 LLString name = ctrl->getName();
00799 if ( ( name == "rspin" ) || ( name == "gspin" ) || ( name == "bspin" ) )
00800 {
00801
00802 F32 rVal, gVal, bVal;
00803 getCurRgb ( rVal, gVal, bVal );
00804
00805
00806 if ( name == "rspin" )
00807 {
00808 rVal = (F32)ctrl->getValue().asReal() / 255.0f;
00809 }
00810 else
00811 if ( name == "gspin" )
00812 {
00813 gVal = (F32)ctrl->getValue().asReal() / 255.0f;
00814 }
00815 else
00816 if ( name == "bspin" )
00817 {
00818 bVal = (F32)ctrl->getValue().asReal() / 255.0f;
00819 }
00820
00821
00822 setCurRgb ( rVal, gVal, bVal );
00823
00824
00825 enableTextCallbacks ( FALSE );
00826 updateTextEntry ();
00827 enableTextCallbacks ( TRUE );
00828 }
00829 else
00830
00831 if ( ( name == "hspin" ) || ( name == "sspin" ) || ( name == "lspin" ) )
00832 {
00833
00834 F32 hVal, sVal, lVal;
00835 getCurHsl ( hVal, sVal, lVal );
00836
00837
00838 if ( name == "hspin" )
00839 hVal = (F32)ctrl->getValue().asReal() / 360.0f;
00840 else
00841 if ( name == "sspin" )
00842 sVal = (F32)ctrl->getValue().asReal() / 100.0f;
00843 else
00844 if ( name == "lspin" )
00845 lVal = (F32)ctrl->getValue().asReal() / 100.0f;
00846
00847
00848 setCurHsl ( hVal, sVal, lVal );
00849
00850
00851 enableTextCallbacks ( FALSE );
00852 updateTextEntry ();
00853 enableTextCallbacks ( TRUE );
00854 }
00855
00856 if (mApplyImmediateCheck->get())
00857 {
00858 LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
00859 }
00860 }
00861
00863
00864 BOOL
00865 LLFloaterColorPicker::
00866 updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn )
00867 {
00868 if ( xPosIn >= mRGBViewerImageLeft &&
00869 xPosIn <= mRGBViewerImageLeft + mRGBViewerImageWidth &&
00870 yPosIn <= mRGBViewerImageTop &&
00871 yPosIn >= mRGBViewerImageTop - mRGBViewerImageHeight )
00872 {
00873
00874 setCurHsl ( ( ( F32 )xPosIn - ( F32 )mRGBViewerImageLeft ) / ( F32 )mRGBViewerImageWidth,
00875 ( ( F32 )yPosIn - ( ( F32 )mRGBViewerImageTop - ( F32 )mRGBViewerImageHeight ) ) / ( F32 )mRGBViewerImageHeight,
00876 getCurL () );
00877
00878
00879 return TRUE;
00880 }
00881 else
00882 if ( xPosIn >= mLumRegionLeft &&
00883 xPosIn <= mLumRegionLeft + mLumRegionWidth &&
00884 yPosIn <= mLumRegionTop &&
00885 yPosIn >= mLumRegionTop - mLumRegionHeight )
00886 {
00887
00888
00889 setCurHsl ( getCurH (),
00890 getCurS (),
00891 ( ( F32 )yPosIn - ( ( F32 )mRGBViewerImageTop - ( F32 )mRGBViewerImageHeight ) ) / ( F32 )mRGBViewerImageHeight );
00892
00893
00894 return TRUE;
00895 }
00896
00897 return FALSE;
00898 }
00899
00901
00902 BOOL
00903 LLFloaterColorPicker::
00904 handleMouseDown ( S32 x, S32 y, MASK mask )
00905 {
00906
00907 if ( mForeground )
00908 {
00909
00910 gFloaterView->bringToFront(this);
00911
00912
00913 LLRect rgbAreaRect ( mRGBViewerImageLeft,
00914 mRGBViewerImageTop,
00915 mRGBViewerImageLeft + mRGBViewerImageWidth,
00916 mRGBViewerImageTop - mRGBViewerImageHeight );
00917
00918 if ( rgbAreaRect.pointInRect ( x, y ) )
00919 {
00920 gViewerWindow->setMouseCapture(this);
00921
00922 setMouseDownInHueRegion ( TRUE );
00923
00924
00925 updateRgbHslFromPoint ( x, y );
00926
00927
00928 return TRUE;
00929 }
00930
00931
00932 LLRect lumAreaRect ( mLumRegionLeft,
00933 mLumRegionTop,
00934 mLumRegionLeft + mLumRegionWidth + mLumMarkerSize,
00935 mLumRegionTop - mLumRegionHeight );
00936
00937 if ( lumAreaRect.pointInRect ( x, y ) )
00938 {
00939 gViewerWindow->setMouseCapture(this);
00940
00941 setMouseDownInLumRegion ( TRUE );
00942
00943
00944 return TRUE;
00945 }
00946
00947
00948 LLRect swatchRect ( mSwatchRegionLeft,
00949 mSwatchRegionTop,
00950 mSwatchRegionLeft + mSwatchRegionWidth,
00951 mSwatchRegionTop - mSwatchRegionHeight );
00952
00953 setMouseDownInSwatch( FALSE );
00954 if ( swatchRect.pointInRect ( x, y ) )
00955 {
00956 setMouseDownInSwatch( TRUE );
00957
00958
00959 return TRUE;
00960 }
00961
00962
00963 LLRect paletteRect ( mPaletteRegionLeft,
00964 mPaletteRegionTop,
00965 mPaletteRegionLeft + mPaletteRegionWidth,
00966 mPaletteRegionTop - mPaletteRegionHeight );
00967
00968 if ( paletteRect.pointInRect ( x, y ) )
00969 {
00970
00971 if (gFocusMgr.childHasKeyboardFocus(this))
00972 {
00973 mSelectBtn->setFocus(TRUE);
00974 }
00975
00976
00977 S32 c = ( ( x - mPaletteRegionLeft ) * numPaletteColumns ) / mPaletteRegionWidth;
00978 S32 r = ( ( y - ( mPaletteRegionTop - mPaletteRegionHeight ) ) * numPaletteRows ) / mPaletteRegionHeight;
00979
00980 U32 index = ( numPaletteRows - r - 1 ) * numPaletteColumns + c;
00981
00982 if ( index <= mPalette.size () )
00983 {
00984 LLColor4 selected = *mPalette [ index ];
00985
00986 setCurRgb ( selected [ 0 ], selected [ 1 ], selected [ 2 ] );
00987
00988 if (mApplyImmediateCheck->get())
00989 {
00990 LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
00991 }
00992
00993
00994 enableTextCallbacks ( FALSE );
00995 updateTextEntry ();
00996 enableTextCallbacks ( TRUE );
00997 }
00998
00999 return TRUE;
01000 }
01001 }
01002
01003 return LLFloater::handleMouseDown ( x, y, mask );
01004 }
01005
01007
01008 BOOL
01009 LLFloaterColorPicker::
01010 handleHover ( S32 x, S32 y, MASK mask )
01011 {
01012
01013 if ( isFrontmost () )
01014 {
01015
01016 if ( getMouseDownInHueRegion() || getMouseDownInLumRegion())
01017 {
01018 S32 clamped_x, clamped_y;
01019 if (getMouseDownInHueRegion())
01020 {
01021 clamped_x = llclamp(x, mRGBViewerImageLeft, mRGBViewerImageLeft + mRGBViewerImageWidth);
01022 clamped_y = llclamp(y, mRGBViewerImageTop - mRGBViewerImageHeight, mRGBViewerImageTop);
01023 }
01024 else
01025 {
01026 clamped_x = llclamp(x, mLumRegionLeft, mLumRegionLeft + mLumRegionWidth);
01027 clamped_y = llclamp(y, mLumRegionTop - mLumRegionHeight, mLumRegionTop);
01028 }
01029
01030
01031 if ( updateRgbHslFromPoint ( clamped_x, clamped_y ) )
01032 {
01033
01034 updateTextEntry ();
01035
01036
01039
01040
01041
01042
01043 }
01044 }
01045
01046 highlightEntry = -1;
01047
01048 if ( mMouseDownInSwatch )
01049 {
01050 getWindow()->setCursor ( UI_CURSOR_ARROWDRAG );
01051
01052
01053 LLRect paletteRect ( mPaletteRegionLeft,
01054 mPaletteRegionTop,
01055 mPaletteRegionLeft + mPaletteRegionWidth,
01056 mPaletteRegionTop - mPaletteRegionHeight );
01057
01058 if ( paletteRect.pointInRect ( x, y ) )
01059 {
01060
01061 S32 xOffset = ( ( x - mPaletteRegionLeft ) * numPaletteColumns ) / mPaletteRegionWidth;
01062 S32 yOffset = ( ( mPaletteRegionTop - y - 1 ) * numPaletteRows ) / mPaletteRegionHeight;
01063
01064
01065 highlightEntry = xOffset + yOffset * numPaletteColumns;
01066 }
01067
01068 return TRUE;
01069 }
01070 }
01071
01072
01073 return LLFloater::handleHover ( x, y, mask );
01074 }
01075
01076 void LLFloaterColorPicker::onClose(bool app_quitting)
01077 {
01078
01079
01080
01081 LLFloater::onClose(app_quitting);
01082 }
01083
01085
01086 BOOL
01087 LLFloaterColorPicker::
01088 handleMouseUp ( S32 x, S32 y, MASK mask )
01089 {
01090 getWindow()->setCursor ( UI_CURSOR_ARROW );
01091
01092 if (getMouseDownInHueRegion() || getMouseDownInLumRegion())
01093 {
01094 if (mApplyImmediateCheck->get())
01095 {
01096 LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
01097 }
01098 }
01099
01100
01101 LLRect paletteRect ( mPaletteRegionLeft,
01102 mPaletteRegionTop,
01103 mPaletteRegionLeft + mPaletteRegionWidth,
01104 mPaletteRegionTop - mPaletteRegionHeight );
01105
01106 if ( paletteRect.pointInRect ( x, y ) )
01107 {
01108 if ( mMouseDownInSwatch )
01109 {
01110 S32 curEntry = 0;
01111 for ( S32 row = 0; row < numPaletteRows; ++row )
01112 {
01113 for ( S32 column = 0; column < numPaletteColumns; ++column )
01114 {
01115 S32 left = mPaletteRegionLeft + ( mPaletteRegionWidth * column ) / numPaletteColumns;
01116 S32 top = mPaletteRegionTop - ( mPaletteRegionHeight * row ) / numPaletteRows;
01117 S32 right = ( mPaletteRegionLeft + ( mPaletteRegionWidth * ( column + 1 ) ) / numPaletteColumns );
01118 S32 bottom = ( mPaletteRegionTop - ( mPaletteRegionHeight * ( row + 1 ) ) / numPaletteRows );
01119
01120
01121 LLRect dropRect ( left, top, right, bottom );
01122
01123 if ( dropRect.pointInRect ( x, y ) )
01124 {
01125 if ( mPalette [ curEntry ] )
01126 {
01127 delete mPalette [ curEntry ];
01128
01129 mPalette [ curEntry ] = new LLColor4 ( getCurR (), getCurG (), getCurB (), 1.0f );
01130
01131
01132 std::ostringstream codec;
01133 codec << "ColorPaletteEntry" << std::setfill ( '0' ) << std::setw ( 2 ) << curEntry + 1;
01134 const std::string s ( codec.str () );
01135 gSavedSettings.setColor4( s, *mPalette [ curEntry ] );
01136 }
01137 }
01138
01139 ++curEntry;
01140 }
01141 }
01142 }
01143 }
01144
01145
01146 setMouseDownInHueRegion ( FALSE );
01147 setMouseDownInLumRegion ( FALSE );
01148
01149
01150 mMouseDownInSwatch = false;
01151
01152 if (hasMouseCapture())
01153 {
01154 gViewerWindow->setMouseCapture(NULL);
01155 }
01156
01157
01158 return LLFloater::handleMouseUp ( x, y, mask );
01159 }
01160
01162
01163 void
01164 LLFloaterColorPicker::
01165 cancelSelection ()
01166 {
01167
01168 setCurRgb ( getOrigR (), getOrigG (), getOrigB () );
01169
01170
01171 enableTextCallbacks ( FALSE );
01172
01173
01174 LLColorSwatchCtrl::onColorChanged( getSwatch(), LLColorSwatchCtrl::COLOR_CANCEL );
01175
01176
01177 this->setVisible ( FALSE );
01178 }
01179
01180 void LLFloaterColorPicker::setMouseDownInHueRegion ( BOOL mouse_down_in_region )
01181 {
01182 mMouseDownInHueRegion = mouse_down_in_region;
01183 if (mouse_down_in_region)
01184 {
01185 if (gFocusMgr.childHasKeyboardFocus(this))
01186 {
01187
01188 mSelectBtn->setFocus(TRUE);
01189 }
01190 }
01191 }
01192
01193 void LLFloaterColorPicker::setMouseDownInLumRegion ( BOOL mouse_down_in_region )
01194 {
01195 mMouseDownInLumRegion = mouse_down_in_region;
01196 if (mouse_down_in_region)
01197 {
01198 if (gFocusMgr.childHasKeyboardFocus(this))
01199 {
01200
01201 mSelectBtn->setFocus(TRUE);
01202 }
01203 }
01204 }
01205
01206 void LLFloaterColorPicker::setMouseDownInSwatch (BOOL mouse_down_in_swatch)
01207 {
01208 mMouseDownInSwatch = mouse_down_in_swatch;
01209 if (mouse_down_in_swatch)
01210 {
01211 if (gFocusMgr.childHasKeyboardFocus(this))
01212 {
01213
01214 mSelectBtn->setFocus(TRUE);
01215 }
01216 }
01217 }
01218
01219 void LLFloaterColorPicker::setActive(BOOL active)
01220 {
01221
01222 if (!active && mPipetteBtn->getToggleState())
01223 {
01224 stopUsingPipette();
01225 }
01226 mActive = active;
01227 }
01228
01229 void LLFloaterColorPicker::stopUsingPipette()
01230 {
01231 if (gToolMgr && gToolMgr->getCurrentTool() == gToolPipette)
01232 {
01233 gToolMgr->clearTransientTool();
01234 }
01235 }