summaryrefslogtreecommitdiff
path: root/indra/newview/llcolorswatch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llcolorswatch.cpp')
-rw-r--r--indra/newview/llcolorswatch.cpp386
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;
+}