llfloatercolorpicker.cpp

Go to the documentation of this file.
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 // Class LLFloaterColorPicker
00074 //
00076 
00078 // default ctor
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           // *TODO: Specify this in XML
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           // *TODO: Specify this in XML
00097           mSwatchRegionLeft             ( 12 ),
00098           mSwatchRegionTop              ( 190 ),
00099           mSwatchRegionWidth    ( 116 ),
00100           mSwatchRegionHeight   ( 60 ),
00101           mSwatchView                   ( NULL ),
00102           // *TODO: Specify this in XML
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         // create user interface for this picker
00116         createUI ();
00117 
00118         if (!mCanApplyImmediately)
00119         {
00120                 mApplyImmediateCheck->setEnabled(FALSE);
00121                 mApplyImmediateCheck->set(FALSE);
00122         }
00123 }
00124 
00126 // dtor
00127 LLFloaterColorPicker::
00128 ~LLFloaterColorPicker()
00129 {
00130         // destroy the UI we created
00131         destroyUI ();
00132 }
00133 
00135 //
00136 void
00137 LLFloaterColorPicker::
00138 createUI ()
00139 {
00140         // build the majority of the gui using the factory builder
00141         gUICtrlFactory->buildFloater ( this, "floater_color_picker.xml" );
00142         setVisible ( FALSE );
00143 
00144         // create RGB type area (not really RGB but it's got R,G & B in it.,..
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         // create palette
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                 // argh!
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();         /*Flawfinder: ignore*/
00192 
00193         // HACK: if system color picker is required - close the SL one we made and use default system dialog
00194         if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
00195         {
00196                 LLColorSwatchCtrl* swatch = getSwatch ();
00197 
00198                 setVisible ( FALSE );
00199 
00200                 // code that will get switched in for default system color picker
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 // called after the dialog is rendered
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         // start catching lose-focus events from entry widgets
00262         enableTextCallbacks ( TRUE );
00263 
00264         // under some circumstances, we get rogue values that can be calmed by clamping...
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         // store initial value in case cancel or revert is selected
00270         setOrigRgb ( rValIn, gValIn, bValIn );
00271 
00272         // starting point for current value to
00273         setCurRgb ( rValIn, gValIn, bValIn );
00274 
00275         // unpdate text entry fields
00276         updateTextEntry ();
00277 }
00278 
00280 //
00281 void
00282 LLFloaterColorPicker::
00283 destroyUI ()
00284 {
00285         // shut down pipette tool if active
00286         stopUsingPipette();
00287 
00288         // delete palette we created
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 // mutator for original RGB value
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 // accessor for original RGB value
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 // mutator for current RGB value
00373 void
00374 LLFloaterColorPicker::
00375 setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn )
00376 {
00377         // save current RGB
00378         curR = curRIn;
00379         curG = curGIn;
00380         curB = curBIn;
00381 
00382         // update corresponding HSL values and
00383         LLColor3(curRIn, curGIn, curBIn).calcHSL(&curH, &curS, &curL);
00384 
00385         // color changed so update text fields (fixes SL-16968)
00386     // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
00387     // CP: this was required when I first wrote the code but this may not be necessary anymore - leaving it there just in case
00388     enableTextCallbacks( FALSE );
00389     updateTextEntry();
00390     enableTextCallbacks( TRUE );
00391 }
00392 
00394 // accessor for current RGB value
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 // mutator for current HSL value
00406 void
00407 LLFloaterColorPicker::
00408 setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn )
00409 {
00410         // save current HSL
00411         curH = curHIn;
00412         curS = curSIn;
00413         curL = curLIn;
00414 
00415         // update corresponding RGB values and
00416         hslToRgb ( curH, curS, curL, curR, curG, curB );
00417 }
00418 
00420 // accessor for current HSL value
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 // called when 'cancel' clicked
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 // called when 'select' clicked
00450 void
00451 LLFloaterColorPicker::
00452 onClickSelect ( void* data )
00453 {
00454         if (data)
00455         {
00456                 LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data;
00457 
00458                 if ( self )
00459                 {
00460                         // apply to selection
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 // called when 'text is committed' - i,e. focus moves from a text field
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         // draw context cone connecting color picker with color swatch in parent floater
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         // base floater stuff
00596         LLFloater::draw ();
00597 
00598         // draw image for RGB area (not really RGB but you'll see what I mean...
00599         gl_draw_image ( mRGBViewerImageLeft, mRGBViewerImageTop - mRGBViewerImageHeight, mRGBImage, LLColor4::white );
00600 
00601         // update 'cursor' into RGB Section
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         // create rgb area outline
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         // draw luminance slider
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         // draw luninance marker
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         // draw luminance slider outline
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         // draw selected color swatch
00655         gl_rect_2d ( mSwatchRegionLeft,
00656                                  mSwatchRegionTop - mSwatchRegionHeight,
00657                                  mSwatchRegionLeft + mSwatchRegionWidth,
00658                                  mSwatchRegionTop,
00659                                  LLColor4 ( getCurR (), getCurG (), getCurB (), 1.0f ),
00660                                  TRUE );
00661 
00662         // draw selected color swatch outline
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         // color palette code is a little more involved so break it out into its' own method
00671         drawPalette ();
00672 }
00673 
00675 // find a complimentary color to the one passed in that can be used to highlight
00676 LLColor4&
00677 LLFloaterColorPicker::
00678 getComplimentaryColor ( LLColor4& backgroundColor )
00679 {
00680         // going to base calculation on luminance
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         // fairly simple heuristic for now...!
00688         if ( lVal < 0.5f )
00689         {
00690                 return LLColor4::white;
00691         }
00692 
00693         return LLColor4::black;
00694 }
00695 
00697 // draw color palette
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                         // calculate position
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                         // draw palette entry color
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         // if there is something to highlight (mouse down in swatch & hovering over palette)
00724         if ( highlightEntry >= 0 )
00725         {
00726                 // extract row/column from palette index
00727                 S32 entryColumn = highlightEntry % numPaletteColumns;
00728                 S32 entryRow = highlightEntry / numPaletteColumns;
00729 
00730                 // calculate position of this entry
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                 // center position of entry
00737                 S32 xCenter = x1 + ( x2 - x1 ) / 2;
00738                 S32 yCenter = y1 - ( y1 - y2 ) / 2;
00739 
00740                 // find a color that works well as a highlight color
00741                 LLColor4 hlColor ( getComplimentaryColor ( *mPalette [ highlightEntry ] ) );
00742 
00743                 // mark a cross for entry that is being hovered
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 // update text entry values for RGB/HSL (can't be done in ::draw () since this overwrites input
00751 void
00752 LLFloaterColorPicker::
00753 updateTextEntry ()
00754 {
00755         // set values in spinners
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 // turns on or off text entry commit call backs
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         // value in RGB boxes changed
00798         LLString name = ctrl->getName();
00799         if ( ( name == "rspin" ) || ( name == "gspin" ) || ( name == "bspin" ) )
00800         {
00801                 // get current RGB
00802                 F32 rVal, gVal, bVal;
00803                 getCurRgb ( rVal, gVal, bVal );
00804 
00805                 // update component value with new value from text
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                 // update current RGB (and implicitly HSL)
00822                 setCurRgb ( rVal, gVal, bVal );
00823 
00824                 // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
00825                 enableTextCallbacks ( FALSE );
00826                 updateTextEntry ();
00827                 enableTextCallbacks ( TRUE );
00828         }
00829         else
00830         // value in HSL boxes changed
00831         if ( ( name == "hspin" ) || ( name == "sspin" ) || ( name == "lspin" ) )
00832         {
00833                 // get current HSL
00834                 F32 hVal, sVal, lVal;
00835                 getCurHsl ( hVal, sVal, lVal );
00836 
00837                 // update component value with new value from text
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                 // update current HSL (and implicitly RGB)
00848                 setCurHsl ( hVal, sVal, lVal );
00849 
00850                 // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
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                 // update HSL (and therefore RGB) based on new H & S and current L
00874                 setCurHsl ( ( ( F32 )xPosIn - ( F32 )mRGBViewerImageLeft ) / ( F32 )mRGBViewerImageWidth,
00875                                         ( ( F32 )yPosIn - ( ( F32 )mRGBViewerImageTop - ( F32 )mRGBViewerImageHeight ) ) / ( F32 )mRGBViewerImageHeight,
00876                                         getCurL () );
00877 
00878                 // indicate a value changed
00879                 return TRUE;
00880         }
00881         else
00882         if ( xPosIn >= mLumRegionLeft &&
00883                  xPosIn <= mLumRegionLeft + mLumRegionWidth &&
00884                  yPosIn <= mLumRegionTop &&
00885                  yPosIn >= mLumRegionTop - mLumRegionHeight )
00886         {
00887 
00888                 // update HSL (and therefore RGB) based on current HS and new L
00889                  setCurHsl ( getCurH (),
00890                                          getCurS (),
00891                                         ( ( F32 )yPosIn - ( ( F32 )mRGBViewerImageTop - ( F32 )mRGBViewerImageHeight ) ) / ( F32 )mRGBViewerImageHeight );
00892 
00893                 // indicate a value changed
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         // if this window is in the foreground
00907         if ( mForeground )
00908         {
00909                 // make it the frontmost
00910                 gFloaterView->bringToFront(this);
00911 
00912                 // rect containing RGB area
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                         // mouse button down
00922                         setMouseDownInHueRegion ( TRUE );
00923 
00924                         // update all values based on initial click
00925                         updateRgbHslFromPoint ( x, y );
00926 
00927                         // required by base class
00928                         return TRUE;
00929                 }
00930 
00931                 // rect containing RGB area
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                         // mouse button down
00941                         setMouseDownInLumRegion ( TRUE );
00942 
00943                         // required by base class
00944                         return TRUE;
00945                 }
00946 
00947                 // rect containing swatch area
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                         // required - dont drag windows here.
00959                         return TRUE;
00960                 }
00961 
00962                 // rect containing palette area
00963                 LLRect paletteRect ( mPaletteRegionLeft,
00964                                                          mPaletteRegionTop,
00965                                                          mPaletteRegionLeft + mPaletteRegionWidth,
00966                                                          mPaletteRegionTop - mPaletteRegionHeight );
00967 
00968                 if ( paletteRect.pointInRect ( x, y ) )
00969                 {
00970                         // release keyboard focus so we can change text values
00971                         if (gFocusMgr.childHasKeyboardFocus(this))
00972                         {
00973                                 mSelectBtn->setFocus(TRUE);
00974                         }
00975 
00976                         // calculate which palette index we selected
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                                 // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
00994                                 enableTextCallbacks ( FALSE );
00995                                 updateTextEntry ();
00996                                 enableTextCallbacks ( TRUE );
00997                         }
00998 
00999                         return TRUE;
01000                 }
01001         }
01002         // dispatch to base class for the rest of things
01003         return LLFloater::handleMouseDown ( x, y, mask );
01004 }
01005 
01007 //
01008 BOOL
01009 LLFloaterColorPicker::
01010 handleHover ( S32 x, S32 y, MASK mask )
01011 {
01012         // if we're the front most window
01013         if ( isFrontmost () )
01014         {
01015                 // mouse was pressed within region
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                         // update the stored RGB/HSL values using the mouse position - returns TRUE if RGB was updated
01031                         if ( updateRgbHslFromPoint ( clamped_x, clamped_y ) )
01032                         {
01033                                 // update text entry fields
01034                                 updateTextEntry ();
01035 
01036                                 // RN: apparently changing color when dragging generates too much traffic and results in sporadic updates
01039                                 //if (mApplyImmediateCheck->get())
01040                                 //{
01041                                 //      LLColorSwatchCtrl::onColorChanged ( getSwatch () );
01042                                 //}
01043                         }
01044                 }
01045 
01046                 highlightEntry = -1;
01047 
01048                 if ( mMouseDownInSwatch )
01049                 {
01050                         getWindow()->setCursor ( UI_CURSOR_ARROWDRAG );
01051 
01052                         // if cursor if over a palette entry
01053                         LLRect paletteRect ( mPaletteRegionLeft,
01054                                                                 mPaletteRegionTop,
01055                                                                 mPaletteRegionLeft + mPaletteRegionWidth,
01056                                                                 mPaletteRegionTop - mPaletteRegionHeight );
01057 
01058                         if ( paletteRect.pointInRect ( x, y ) )
01059                         {
01060                                 // find row/column in palette
01061                                 S32 xOffset = ( ( x - mPaletteRegionLeft ) * numPaletteColumns ) / mPaletteRegionWidth;
01062                                 S32 yOffset = ( ( mPaletteRegionTop - y - 1 ) * numPaletteRows ) / mPaletteRegionHeight;
01063 
01064                                 // calculate the entry 0..n-1 to highlight and set variable to next draw() picks it up
01065                                 highlightEntry = xOffset + yOffset * numPaletteColumns;
01066                         }
01067 
01068                         return TRUE;
01069                 }
01070         }
01071 
01072         // dispatch to base class for the rest of things
01073         return LLFloater::handleHover ( x, y, mask );
01074 }
01075 
01076 void LLFloaterColorPicker::onClose(bool app_quitting)
01077 {
01078         //RN: this is consistent with texture picker in that closing the window leaves the current selection
01079         // to change this to "close to cancel", uncomment the following line
01080         //cancelSelection();
01081         LLFloater::onClose(app_quitting);
01082 }
01083 
01085 // reverts state once mouse button is released
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         // rect containing palette area
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                                         // rect is flipped vertically when testing here
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                                                         // save off color
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         // mouse button not down anymore
01146         setMouseDownInHueRegion ( FALSE );
01147         setMouseDownInLumRegion ( FALSE );
01148 
01149         // mouse button not down in color swatch anymore
01150         mMouseDownInSwatch = false;
01151 
01152         if (hasMouseCapture())
01153         {
01154                 gViewerWindow->setMouseCapture(NULL);
01155         }
01156 
01157         // dispatch to base class for the rest of things
01158         return LLFloater::handleMouseUp ( x, y, mask );
01159 }
01160 
01162 // cancel current color selection, revert to original and close picker
01163 void
01164 LLFloaterColorPicker::
01165 cancelSelection ()
01166 {
01167         // restore the previous colour selection
01168         setCurRgb ( getOrigR (), getOrigG (), getOrigB () );
01169 
01170         //      we're going away and when we do and the entry widgets lose focus, they do bad things so turn them off
01171         enableTextCallbacks ( FALSE );
01172 
01173         // update in world item with original color via current swatch
01174         LLColorSwatchCtrl::onColorChanged( getSwatch(), LLColorSwatchCtrl::COLOR_CANCEL );
01175 
01176         // hide picker dialog
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                         // get focus out of spinners so that they can update freely
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                         // get focus out of spinners so that they can update freely
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                         // get focus out of spinners so that they can update freely
01214                         mSelectBtn->setFocus(TRUE);
01215                 }
01216         }
01217 }
01218 
01219 void LLFloaterColorPicker::setActive(BOOL active) 
01220 { 
01221         // shut down pipette tool if active
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 }

Generated on Thu Jul 1 06:08:32 2010 for Second Life Viewer by  doxygen 1.4.7