llcolorswatch.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 // File include
00035 #include "llcolorswatch.h"
00036 
00037 // Linden library includes
00038 #include "v4color.h"
00039 
00040 // Project includes
00041 #include "llui.h"
00042 #include "llglimmediate.h"
00043 #include "lluiconstants.h"
00044 #include "llviewerwindow.h"
00045 #include "llviewercontrol.h"
00046 #include "llbutton.h"
00047 #include "lltextbox.h"
00048 #include "llfloatercolorpicker.h"
00049 #include "llviewborder.h"
00050 #include "llviewerimagelist.h"
00051 #include "llfocusmgr.h"
00052 
00053 static LLRegisterWidget<LLColorSwatchCtrl> r("color_swatch");
00054 
00055 LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const LLColor4& color,
00056                 void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
00057                 void* userdata )
00058 :       LLUICtrl(name, rect, TRUE, commit_callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
00059         mValid( TRUE ),
00060         mColor( color ),
00061         mBorderColor( gColors.getColor("DefaultHighlightLight") ),
00062         mCanApplyImmediately(FALSE),
00063         mOnCancelCallback(NULL),
00064         mOnSelectCallback(NULL)
00065 {
00066         mCaption = new LLTextBox( name,
00067                 LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
00068                 name,
00069                 LLFontGL::sSansSerifSmall );
00070         mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
00071         addChild( mCaption );
00072 
00073         // Scalable UI made this off-by-one, I don't know why. JC
00074         LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0);
00075         border_rect.mBottom += BTN_HEIGHT_SMALL;
00076         mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN);
00077         addChild(mBorder);
00078 
00079         mAlphaGradientImage = LLUI::getUIImage("color_swatch_alpha.tga");
00080 }
00081 
00082 LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLColor4& color,
00083                 void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
00084                 void* userdata )
00085 :       LLUICtrl(name, rect, TRUE, commit_callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
00086         mValid( TRUE ),
00087         mColor( color ),
00088         mBorderColor( gColors.getColor("DefaultHighlightLight") ),
00089         mCanApplyImmediately(FALSE),
00090         mOnCancelCallback(NULL),
00091         mOnSelectCallback(NULL)
00092 {
00093         mCaption = new LLTextBox( label,
00094                 LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
00095                 label,
00096                 LLFontGL::sSansSerifSmall );
00097         mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
00098         addChild( mCaption );
00099 
00100         // Scalable UI made this off-by-one, I don't know why. JC
00101         LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0);
00102         border_rect.mBottom += BTN_HEIGHT_SMALL;
00103         mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN);
00104         addChild(mBorder);
00105 
00106         mAlphaGradientImage = LLUI::getUIImage("color_swatch_alpha.tga");
00107 }
00108 
00109 LLColorSwatchCtrl::~LLColorSwatchCtrl ()
00110 {
00111         // parent dialog is destroyed so we are too and we need to cancel selection
00112         LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
00113         if (pickerp)
00114         {
00115                 pickerp->cancelSelection();
00116                 pickerp->close();
00117         }
00118         mAlphaGradientImage = NULL;
00119 }
00120 
00121 BOOL LLColorSwatchCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
00122 {
00123         return handleMouseDown(x, y, mask);
00124 }
00125 
00126 BOOL LLColorSwatchCtrl::handleHover(S32 x, S32 y, MASK mask)
00127 {
00128         getWindow()->setCursor(UI_CURSOR_HAND);
00129         return TRUE;
00130 }
00131 
00132 BOOL LLColorSwatchCtrl::handleUnicodeCharHere(llwchar uni_char)
00133 {
00134         if( ' ' == uni_char )
00135         {
00136                 showPicker(TRUE);
00137         }
00138         return LLUICtrl::handleUnicodeCharHere(uni_char);
00139 }
00140 
00141 // forces color of this swatch and any associated floater to the input value, if currently invalid
00142 void LLColorSwatchCtrl::setOriginal(const LLColor4& color)
00143 {
00144         mColor = color;
00145         LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
00146         if (pickerp)
00147         {
00148                 pickerp->setOrigRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]);
00149         }
00150 }
00151 
00152 void LLColorSwatchCtrl::set(const LLColor4& color, BOOL update_picker, BOOL from_event)
00153 {
00154         mColor = color; 
00155         LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
00156         if (pickerp && update_picker)
00157         {
00158                 pickerp->setCurRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]);
00159         }
00160         if (!from_event)
00161         {
00162                 setControlValue(mColor.getValue());
00163         }
00164 }
00165 
00166 void LLColorSwatchCtrl::setLabel(const std::string& label)
00167 {
00168         mCaption->setText(label);
00169 }
00170 
00171 BOOL LLColorSwatchCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
00172 {
00173         // Route future Mouse messages here preemptively.  (Release on mouse up.)
00174         // No handler is needed for capture lost since this object has no state that depends on it.
00175         gViewerWindow->setMouseCapture( this );
00176 
00177         return TRUE;
00178 }
00179 
00180 
00181 BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
00182 {
00183         // We only handle the click if the click both started and ended within us
00184         if( hasMouseCapture() )
00185         {
00186                 // Release the mouse
00187                 gViewerWindow->setMouseCapture( NULL );
00188 
00189                 // If mouseup in the widget, it's been clicked
00190                 if ( pointInView(x, y) )
00191                 {
00192                         llassert(getEnabled());
00193                         llassert(getVisible());
00194 
00195                         showPicker(FALSE);
00196                 }
00197         }
00198 
00199         return TRUE;
00200 }
00201 
00202 
00203 // assumes GL state is set for 2D
00204 void LLColorSwatchCtrl::draw()
00205 {
00206         mBorder->setKeyboardFocusHighlight(hasFocus());
00207         // Draw border
00208         LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
00209         gl_rect_2d( border, mBorderColor, FALSE );
00210 
00211         LLRect interior = border;
00212         interior.stretch( -1 );
00213 
00214         // Check state
00215         if ( mValid )
00216         {
00217                 // Draw the color swatch
00218                 gl_rect_2d_checkerboard( interior );
00219                 gl_rect_2d(interior, mColor, TRUE);
00220                 LLColor4 opaque_color = mColor;
00221                 opaque_color.mV[VALPHA] = 1.f;
00222                 gGL.color4fv(opaque_color.mV);
00223                 if (mAlphaGradientImage.notNull())
00224                 {
00225                         gGL.pushMatrix();
00226                         {
00227                                 mAlphaGradientImage->draw(interior, mColor);
00228                         }
00229                         gGL.popMatrix();
00230                 }
00231         }
00232         else
00233         {
00234                 // Draw grey and an X
00235                 gl_rect_2d(interior, LLColor4::grey, TRUE);
00236 
00237                 gl_draw_x(interior, LLColor4::black);
00238         }
00239 
00240         LLUICtrl::draw();
00241 }
00242 
00243 void LLColorSwatchCtrl::setEnabled( BOOL enabled )
00244 {
00245         mCaption->setEnabled( enabled );
00246         LLView::setEnabled( enabled );
00247 
00248         if (!enabled)
00249         {
00250                 LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
00251                 if (pickerp)
00252                 {
00253                         pickerp->cancelSelection();
00254                         pickerp->close();
00255                 }
00256         }
00257 }
00258 
00259 
00260 void LLColorSwatchCtrl::setValue(const LLSD& value)
00261 {
00262         set(LLColor4(value), TRUE, TRUE);
00263 }
00264 
00266 // called (infrequently) when the color changes so the subject of the swatch can be updated.
00267 void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
00268 {
00269         LLColorSwatchCtrl* subject = ( LLColorSwatchCtrl* )data;
00270         if ( subject )
00271         {
00272                 LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)subject->mPickerHandle.get();
00273                 if (pickerp)
00274                 {
00275                         // move color across from selector to internal widget storage
00276                         LLColor4 updatedColor ( pickerp->getCurR (), 
00277                                                                         pickerp->getCurG (), 
00278                                                                         pickerp->getCurB (), 
00279                                                                         subject->mColor.mV[VALPHA] ); // keep current alpha
00280                         subject->mColor = updatedColor;
00281                         subject->setControlValue(updatedColor.getValue());
00282 
00283                         if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)
00284                         {
00285                                 subject->mOnCancelCallback(subject, subject->mCallbackUserData);
00286                         }
00287                         else if (pick_op == COLOR_SELECT && subject->mOnSelectCallback)
00288                         {
00289                                 subject->mOnSelectCallback(subject, subject->mCallbackUserData);
00290                         }
00291                         else
00292                         {
00293                                 // just commit change
00294                                 subject->onCommit ();
00295                         }
00296                 }
00297         }
00298 }
00299 
00300 void LLColorSwatchCtrl::setValid(BOOL valid )
00301 {
00302         mValid = valid;
00303 
00304         LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
00305         if (pickerp)
00306         {
00307                 pickerp->setActive(valid);
00308         }
00309 }
00310 
00311 void LLColorSwatchCtrl::showPicker(BOOL take_focus)
00312 {
00313         LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
00314         if (!pickerp)
00315         {
00316                 pickerp = new LLFloaterColorPicker(this, mCanApplyImmediately);
00317                 gFloaterView->getParentFloater(this)->addDependentFloater(pickerp);
00318                 mPickerHandle = pickerp->getHandle();
00319         }
00320 
00321         // initialize picker with current color
00322         pickerp->initUI ( mColor.mV [ VRED ], mColor.mV [ VGREEN ], mColor.mV [ VBLUE ] );
00323 
00324         // display it
00325         pickerp->showUI ();
00326 
00327         if (take_focus)
00328         {
00329                 pickerp->setFocus(TRUE);
00330         }
00331 }
00332 
00333 // virtual
00334 LLXMLNodePtr LLColorSwatchCtrl::getXML(bool save_children) const
00335 {
00336         LLXMLNodePtr node = LLUICtrl::getXML();
00337 
00338         node->createChild("color", TRUE)->setFloatValue(4, mColor.mV);
00339 
00340         node->createChild("border_color", TRUE)->setFloatValue(4, mBorderColor.mV);
00341 
00342         if (mCaption)
00343         {
00344                 node->createChild("label", TRUE)->setStringValue(mCaption->getText());
00345         }
00346 
00347         node->createChild("can_apply_immediately", TRUE)->setBoolValue(mCanApplyImmediately);
00348 
00349         return node;
00350 }
00351 
00352 LLView* LLColorSwatchCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
00353 {
00354         LLString name("colorswatch");
00355         node->getAttributeString("name", name);
00356 
00357         LLString label;
00358         node->getAttributeString("label", label);
00359 
00360         LLColor4 color(1.f, 1.f, 1.f, 1.f);
00361         node->getAttributeColor("initial_color", color);
00362 
00363         LLRect rect;
00364         createRect(node, rect, parent, LLRect());
00365 
00366         BOOL can_apply_immediately = FALSE;
00367         node->getAttributeBOOL("can_apply_immediately", can_apply_immediately);
00368 
00369         LLUICtrlCallback callback = NULL;
00370 
00371         if (label.empty())
00372         {
00373                 label.assign(node->getValue());
00374         }
00375 
00376         LLColorSwatchCtrl* color_swatch = new LLColorSwatchCtrl(
00377                 name, 
00378                 rect,
00379                 label,
00380                 color,
00381                 callback,
00382                 NULL );
00383 
00384         color_swatch->setCanApplyImmediately(can_apply_immediately);
00385         color_swatch->initFromXML(node, parent);
00386 
00387         return color_swatch;
00388 }

Generated on Fri May 16 08:33:16 2008 for SecondLife by  doxygen 1.5.5