diff options
Diffstat (limited to 'indra/newview/llcolorswatch.cpp')
-rw-r--r-- | indra/newview/llcolorswatch.cpp | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp new file mode 100644 index 0000000000..4dade7f683 --- /dev/null +++ b/indra/newview/llcolorswatch.cpp @@ -0,0 +1,386 @@ +/** + * @file llcolorswatch.cpp + * @brief LLColorSwatch class implementation + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +// File include +#include "llcolorswatch.h" + +// Linden library includes +#include "v4color.h" + +// Project includes +#include "llui.h" +#include "lluiconstants.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" +#include "llbutton.h" +#include "lltextbox.h" +#include "llfloatercolorpicker.h" +#include "llviewborder.h" +#include "llviewerimagelist.h" +#include "llfocusmgr.h" + +LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const LLColor4& color, + void (*commit_callback)(LLUICtrl* ctrl, void* userdata), + void* userdata ) +: LLUICtrl(name, rect, TRUE, commit_callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP), + mValid( TRUE ), + mColor( color ), + mBorderColor( gColors.getColor("DefaultHighlightLight") ), + mCanApplyImmediately(FALSE), + mOnCancelCallback(NULL), + mOnSelectCallback(NULL) +{ + mCaption = new LLTextBox( name, + LLRect( 0, BTN_HEIGHT_SMALL, mRect.getWidth(), 0 ), + LLString::null, + LLFontGL::sSansSerifSmall ); + mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); + addChild( mCaption ); + + // Scalable UI made this off-by-one, I don't know why. JC + LLRect border_rect(0, mRect.getHeight()-1, mRect.getWidth()-1, 0); + border_rect.mBottom += BTN_HEIGHT_SMALL; + mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN); + addChild(mBorder); + + mAlphaGradientImage = gImageList.getImageFromUUID(LLUUID(gViewerArt.getString("color_swatch_alpha.tga")), + MIPMAP_FALSE, TRUE, GL_ALPHA8, GL_ALPHA); +} + +LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLColor4& color, + void (*commit_callback)(LLUICtrl* ctrl, void* userdata), + void* userdata ) +: LLUICtrl(name, rect, TRUE, commit_callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP), + mValid( TRUE ), + mColor( color ), + mBorderColor( gColors.getColor("DefaultHighlightLight") ), + mCanApplyImmediately(FALSE), + mOnCancelCallback(NULL), + mOnSelectCallback(NULL) +{ + mCaption = new LLTextBox( label, + LLRect( 0, BTN_HEIGHT_SMALL, mRect.getWidth(), 0 ), + LLString::null, + LLFontGL::sSansSerifSmall ); + mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); + addChild( mCaption ); + + // Scalable UI made this off-by-one, I don't know why. JC + LLRect border_rect(0, mRect.getHeight()-1, mRect.getWidth()-1, 0); + border_rect.mBottom += BTN_HEIGHT_SMALL; + mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN); + addChild(mBorder); + + mAlphaGradientImage = gImageList.getImageFromUUID(LLUUID(gViewerArt.getString("color_swatch_alpha.tga")), + MIPMAP_FALSE, TRUE, GL_ALPHA8, GL_ALPHA); +} + +LLColorSwatchCtrl::~LLColorSwatchCtrl () +{ + // parent dialog is destroyed so we are too and we need to cancel selection + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + if (pickerp) + { + pickerp->cancelSelection(); + pickerp->close(); + } + mAlphaGradientImage = NULL; +} + +BOOL LLColorSwatchCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + return handleMouseDown(x, y, mask); +} + +BOOL LLColorSwatchCtrl::handleHover(S32 x, S32 y, MASK mask) +{ + getWindow()->setCursor(UI_CURSOR_HAND); + return TRUE; +} + +BOOL LLColorSwatchCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) +{ + if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char ) + { + showPicker(TRUE); + } + return LLUICtrl::handleUnicodeCharHere(uni_char, called_from_parent); +} + +// forces color of this swatch and any associated floater to the input value, if currently invalid +void LLColorSwatchCtrl::setOriginal(const LLColor4& color) +{ + mColor = color; + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + if (pickerp) + { + pickerp->setOrigRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]); + } +} + +void LLColorSwatchCtrl::set(const LLColor4& color, BOOL update_picker, BOOL from_event) +{ + mColor = color; + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + if (pickerp && update_picker) + { + pickerp->setCurRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]); + } + if (!from_event) + { + setControlValue(mColor.getValue()); + } +} + +void LLColorSwatchCtrl::setLabel(const std::string& label) +{ + mCaption->setText(label); +} + +BOOL LLColorSwatchCtrl::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // Route future Mouse messages here preemptively. (Release on mouse up.) + // No handler is needed for capture lost since this object has no state that depends on it. + gViewerWindow->setMouseCapture( this, NULL ); + + return TRUE; +} + + +BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask) +{ + // We only handle the click if the click both started and ended within us + if( gViewerWindow->hasMouseCapture( this ) ) + { + // Release the mouse + gViewerWindow->setMouseCapture( NULL, NULL ); + + // If mouseup in the widget, it's been clicked + if ( pointInView(x, y) ) + { + llassert(mEnabled); + llassert(getVisible()); + + showPicker(FALSE); + } + } + + return TRUE; +} + + +// assumes GL state is set for 2D +void LLColorSwatchCtrl::draw() +{ + if( getVisible() ) + { + mBorder->setKeyboardFocusHighlight(hasFocus()); + // Draw border + LLRect border( 0, mRect.getHeight(), mRect.getWidth(), BTN_HEIGHT_SMALL ); + gl_rect_2d( border, mBorderColor, FALSE ); + + LLRect interior = border; + interior.stretch( -1 ); + + // Check state + if ( mValid ) + { + LLGLSTexture gls_texture; + + // Draw the color swatch + gl_rect_2d_checkerboard( interior ); + gl_rect_2d(interior, mColor, TRUE); + LLColor4 opaque_color = mColor; + opaque_color.mV[VALPHA] = 1.f; + glColor4fv(opaque_color.mV); + if (mAlphaGradientImage.notNull()) + { + glPushMatrix(); + { + glTranslatef((F32)interior.mLeft, (F32)interior.mBottom, 0.f); + LLViewerImage::bindTexture(mAlphaGradientImage); + gl_rect_2d_simple_tex(interior.getWidth(), interior.getHeight()); + } + glPopMatrix(); + } + } + else + { + // Draw grey and an X + gl_rect_2d(interior, LLColor4::grey, TRUE); + + gl_draw_x(interior, LLColor4::black); + } + + LLUICtrl::draw(); + } +} + +void LLColorSwatchCtrl::setEnabled( BOOL enabled ) +{ + mCaption->setEnabled( enabled ); + LLUICtrl::setEnabled( enabled ); + + if (!enabled) + { + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + if (pickerp) + { + pickerp->cancelSelection(); + pickerp->close(); + } + } +} + + +////////////////////////////////////////////////////////////////////////////// +// called when parent filters down a visibility changed message +void LLColorSwatchCtrl::onVisibilityChange ( BOOL curVisibilityIn ) +{ + // visibility changed - moved away to different tab for instance - cancel selection + //if ( ! curVisibilityIn) + //{ + // LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + // if (pickerp) + // { + // pickerp->cancelSelection(); + // } + //} +} + +void LLColorSwatchCtrl::setValue(const LLSD& value) +{ + set(LLColor4(value), TRUE, TRUE); +} + +////////////////////////////////////////////////////////////////////////////// +// called (infrequently) when the color changes so the subject of the swatch can be updated. +void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) +{ + LLColorSwatchCtrl* subject = ( LLColorSwatchCtrl* )data; + if ( subject ) + { + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(subject->mPickerHandle); + if (pickerp) + { + // move color across from selector to internal widget storage + LLColor4 updatedColor ( pickerp->getCurR (), + pickerp->getCurG (), + pickerp->getCurB (), + subject->mColor.mV[VALPHA] ); // keep current alpha + subject->mColor = updatedColor; + subject->setControlValue(updatedColor.getValue()); + + if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback) + { + subject->mOnCancelCallback(subject, subject->mCallbackUserData); + } + else if (pick_op == COLOR_SELECT && subject->mOnSelectCallback) + { + subject->mOnSelectCallback(subject, subject->mCallbackUserData); + } + else + { + // just commit change + subject->onCommit (); + } + } + }; +} + +void LLColorSwatchCtrl::setValid(BOOL valid ) +{ + mValid = valid; + + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + if (pickerp) + { + pickerp->setActive(valid); + } +} + +void LLColorSwatchCtrl::showPicker(BOOL take_focus) +{ + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + if (!pickerp) + { + pickerp = new LLFloaterColorPicker(this, mCanApplyImmediately); + gFloaterView->getParentFloater(this)->addDependentFloater(pickerp); + mPickerHandle = pickerp->getHandle(); + } + + // initialize picker singleton with current color + pickerp->initUI ( mColor.mV [ VRED ], mColor.mV [ VGREEN ], mColor.mV [ VBLUE ] ); + + // display it + pickerp->showUI (); + + if (take_focus) + { + pickerp->setFocus(TRUE); + } +} + +// virtual +LLXMLNodePtr LLColorSwatchCtrl::getXML(bool save_children) const +{ + LLXMLNodePtr node = LLUICtrl::getXML(); + + node->createChild("color", TRUE)->setFloatValue(4, mColor.mV); + + node->createChild("border_color", TRUE)->setFloatValue(4, mBorderColor.mV); + + if (mCaption) + { + node->createChild("label", TRUE)->setStringValue(mCaption->getText()); + } + + node->createChild("can_apply_immediately", TRUE)->setBoolValue(mCanApplyImmediately); + + return node; +} + +LLView* LLColorSwatchCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +{ + LLString name("colorswatch"); + node->getAttributeString("name", name); + + LLString label; + node->getAttributeString("label", label); + + LLColor4 color(1.f, 1.f, 1.f, 1.f); + node->getAttributeColor("initial_color", color); + + LLRect rect; + createRect(node, rect, parent, LLRect()); + + BOOL can_apply_immediately = FALSE; + node->getAttributeBOOL("can_apply_immediately", can_apply_immediately); + + LLUICtrlCallback callback = NULL; + + if (label.empty()) + { + label.assign(node->getValue()); + } + + LLColorSwatchCtrl* color_swatch = new LLColorSwatchCtrl( + name, + rect, + label, + color, + callback, + NULL ); + + color_swatch->setCanApplyImmediately(can_apply_immediately); + color_swatch->initFromXML(node, parent); + + return color_swatch; +} |