Files
SingularityViewer/indra/newview/llcolorswatch.cpp

411 lines
11 KiB
C++

/**
* @file llcolorswatch.cpp
* @brief LLColorSwatch class implementation
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
// File include
#include "llcolorswatch.h"
// Linden library includes
#include "v4color.h"
#include "llwindow.h" // setCursor()
// Project includes
#include "llui.h"
#include "llrender.h"
#include "lluiconstants.h"
#include "llviewercontrol.h"
#include "llbutton.h"
#include "lltextbox.h"
#include "llfloatercolorpicker.h"
#include "llviewborder.h"
#include "llviewertexturelist.h"
#include "llfocusmgr.h"
static LLRegisterWidget<LLColorSwatchCtrl> r("color_swatch");
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, getRect().getWidth(), 0 ),
name,
LLFontGL::getFontSansSerifSmall() );
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, getRect().getHeight()-1, getRect().getWidth()-1, 0);
border_rect.mBottom += BTN_HEIGHT_SMALL;
mBorder = new LLViewBorder(std::string("border"), border_rect, LLViewBorder::BEVEL_IN);
addChild(mBorder);
mAlphaGradientImage = LLUI::getUIImage("color_swatch_alpha.tga");
}
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, getRect().getWidth(), 0 ),
label,
LLFontGL::getFontSansSerifSmall() );
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, getRect().getHeight()-1, getRect().getWidth()-1, 0);
border_rect.mBottom += BTN_HEIGHT_SMALL;
mBorder = new LLViewBorder(std::string("border"), border_rect, LLViewBorder::BEVEL_IN);
addChild(mBorder);
mAlphaGradientImage = LLUI::getUIImage("color_swatch_alpha.tga");
}
LLColorSwatchCtrl::~LLColorSwatchCtrl ()
{
// parent dialog is destroyed so we are too and we need to cancel selection
LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
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)
{
if( ' ' == uni_char )
{
showPicker(TRUE);
}
return LLUICtrl::handleUnicodeCharHere(uni_char);
}
// 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*)mPickerHandle.get();
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*)mPickerHandle.get();
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.
gFocusMgr.setMouseCapture( this );
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( hasMouseCapture() )
{
// Release the mouse
gFocusMgr.setMouseCapture( NULL );
// If mouseup in the widget, it's been clicked
if ( pointInView(x, y) )
{
llassert(getEnabled());
llassert(getVisible());
// Focus the widget now in order to return the focus
// after the color picker is closed.
setFocus(TRUE);
showPicker(FALSE);
}
}
return TRUE;
}
// assumes GL state is set for 2D
void LLColorSwatchCtrl::draw()
{
mBorder->setKeyboardFocusHighlight(hasFocus());
// Draw border
LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
gl_rect_2d( border, mBorderColor, FALSE );
LLRect interior = border;
interior.stretch( -1 );
// Check state
if ( mValid )
{
// Draw the color swatch
gl_rect_2d_checkerboard( getScreenRect(), interior );
gl_rect_2d(interior, mColor, TRUE);
LLColor4 opaque_color = mColor;
opaque_color.mV[VALPHA] = 1.f;
gGL.color4fv(opaque_color.mV);
if (mAlphaGradientImage.notNull())
{
gGL.pushMatrix();
{
mAlphaGradientImage->draw(interior, mColor);
}
gGL.popMatrix();
}
}
else
{
if (!mFallbackImageName.empty())
{
LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName);
if( fallback_image->getComponents() == 4 )
{
gl_rect_2d_checkerboard( getScreenRect(), interior );
}
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), fallback_image);
fallback_image->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
}
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 );
LLView::setEnabled( enabled );
if (!enabled)
{
LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
if (pickerp)
{
pickerp->cancelSelection();
pickerp->close();
}
}
}
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*)subject->mPickerHandle.get();
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*)mPickerHandle.get();
if (pickerp)
{
pickerp->setActive(valid);
}
}
void LLColorSwatchCtrl::showPicker(BOOL take_focus)
{
LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
if (!pickerp)
{
pickerp = new LLFloaterColorPicker(this, mCanApplyImmediately);
LLFloater* parent = gFloaterView->getParentFloater(this);
if (parent)
{
parent->addDependentFloater(pickerp);
}
mPickerHandle = pickerp->getHandle();
}
// initialize picker 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->setName(LL_COLOR_SWATCH_CTRL_TAG);
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)
{
std::string name("colorswatch");
node->getAttributeString("name", name);
std::string 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;
}