summaryrefslogtreecommitdiff
path: root/indra/llui/llmultislider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llmultislider.cpp')
-rw-r--r--indra/llui/llmultislider.cpp347
1 files changed, 170 insertions, 177 deletions
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index c5c0e1c8b1..1f6fa12969 100644
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
@@ -2,30 +2,25 @@
* @file llmultisldr.cpp
* @brief LLMultiSlider base class
*
- * $LicenseInfo:firstyear=2007&license=viewergpl$
- *
- * Copyright (c) 2007-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* 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://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * 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://secondlife.com/developers/opensource/flossexception
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -39,68 +34,96 @@
#include "llfocusmgr.h"
#include "llkeyboard.h" // for the MASK constants
#include "llcontrol.h"
-#include "llimagegl.h"
+#include "lluictrlfactory.h"
#include <sstream>
-static LLRegisterWidget<LLMultiSlider> r("multi_slider_bar");
+static LLDefaultChildRegistry::Register<LLMultiSlider> r("multi_slider_bar");
-const S32 MULTI_THUMB_WIDTH = 8;
-const S32 MULTI_TRACK_HEIGHT = 6;
const F32 FLOAT_THRESHOLD = 0.00001f;
-const S32 EXTRA_TRIANGLE_WIDTH = 2;
-const S32 EXTRA_TRIANGLE_HEIGHT = -2;
S32 LLMultiSlider::mNameCounter = 0;
-LLMultiSlider::LLMultiSlider(
- const LLString& name,
- const LLRect& rect,
- void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_userdata,
- F32 initial_value,
- F32 min_value,
- F32 max_value,
- F32 increment,
- S32 max_sliders,
- BOOL allow_overlap,
- BOOL draw_track,
- BOOL use_triangle,
- const LLString& control_name)
- :
- LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata,
- FOLLOWS_LEFT | FOLLOWS_TOP),
-
- mInitialValue( initial_value ),
- mMinValue( min_value ),
- mMaxValue( max_value ),
- mIncrement( increment ),
- mMaxNumSliders(max_sliders),
- mAllowOverlap(allow_overlap),
- mDrawTrack(draw_track),
- mUseTriangle(use_triangle),
+LLMultiSlider::SliderParams::SliderParams()
+: name("name"),
+ value("value", 0.f)
+{
+}
+
+LLMultiSlider::Params::Params()
+: max_sliders("max_sliders", 1),
+ allow_overlap("allow_overlap", false),
+ draw_track("draw_track", true),
+ use_triangle("use_triangle", false),
+ track_color("track_color"),
+ thumb_disabled_color("thumb_disabled_color"),
+ thumb_outline_color("thumb_outline_color"),
+ thumb_center_color("thumb_center_color"),
+ thumb_center_selected_color("thumb_center_selected_color"),
+ triangle_color("triangle_color"),
+ mouse_down_callback("mouse_down_callback"),
+ mouse_up_callback("mouse_up_callback"),
+ thumb_width("thumb_width"),
+ sliders("slider")
+{
+ name = "multi_slider_bar";
+ mouse_opaque(true);
+ follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+}
+
+LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
+: LLF32UICtrl(p),
mMouseOffset( 0 ),
- mDragStartThumbRect( 0, getRect().getHeight(), MULTI_THUMB_WIDTH, 0 ),
- mTrackColor( LLUI::sColorsGroup->getColor( "MultiSliderTrackColor" ) ),
- mThumbOutlineColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbOutlineColor" ) ),
- mThumbCenterColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbCenterColor" ) ),
- mThumbCenterSelectedColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbCenterSelectedColor" ) ),
- mDisabledThumbColor(LLUI::sColorsGroup->getColor( "MultiSliderDisabledThumbColor" ) ),
- mTriangleColor(LLUI::sColorsGroup->getColor( "MultiSliderTriangleColor" ) ),
- mMouseDownCallback( NULL ),
- mMouseUpCallback( NULL )
+ mDragStartThumbRect( 0, getRect().getHeight(), p.thumb_width, 0 ),
+ mMaxNumSliders(p.max_sliders),
+ mAllowOverlap(p.allow_overlap),
+ mDrawTrack(p.draw_track),
+ mUseTriangle(p.use_triangle),
+ mTrackColor(p.track_color()),
+ mThumbOutlineColor(p.thumb_outline_color()),
+ mThumbCenterColor(p.thumb_center_color()),
+ mThumbCenterSelectedColor(p.thumb_center_selected_color()),
+ mDisabledThumbColor(p.thumb_disabled_color()),
+ mTriangleColor(p.triangle_color()),
+ mThumbWidth(p.thumb_width),
+ mMouseDownSignal(NULL),
+ mMouseUpSignal(NULL)
{
mValue.emptyMap();
- mCurSlider = LLString::null;
+ mCurSlider = LLStringUtil::null;
+
+ if (p.mouse_down_callback.isProvided())
+ {
+ setMouseDownCallback(initCommitCallback(p.mouse_down_callback));
+ }
+ if (p.mouse_up_callback.isProvided())
+ {
+ setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
+ }
+
+ for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders().begin();
+ it != p.sliders().end();
+ ++it)
+ {
+ if (it->name.isProvided())
+ {
+ addSlider(it->value, it->name);
+ }
+ else
+ {
+ addSlider(it->value);
+ }
+ }
+}
- // properly handle setting the starting thumb rect
- // do it this way to handle both the operating-on-settings
- // and standalone ways of using this
- setControlName(control_name, NULL);
- setValue(getValue());
+LLMultiSlider::~LLMultiSlider()
+{
+ delete mMouseDownSignal;
+ delete mMouseUpSignal;
}
-void LLMultiSlider::setSliderValue(const LLString& name, F32 value, BOOL from_event)
+
+void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from_event)
{
// exit if not there
if(!mValue.has(name)) {
@@ -151,12 +174,12 @@ void LLMultiSlider::setSliderValue(const LLString& name, F32 value, BOOL from_ev
F32 t = (newValue - mMinValue) / (mMaxValue - mMinValue);
- S32 left_edge = MULTI_THUMB_WIDTH/2;
- S32 right_edge = getRect().getWidth() - (MULTI_THUMB_WIDTH/2);
+ S32 left_edge = mThumbWidth/2;
+ S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
S32 x = left_edge + S32( t * (right_edge - left_edge) );
- mThumbRects[name].mLeft = x - (MULTI_THUMB_WIDTH/2);
- mThumbRects[name].mRight = x + (MULTI_THUMB_WIDTH/2);
+ mThumbRects[name].mLeft = x - (mThumbWidth/2);
+ mThumbRects[name].mRight = x + (mThumbWidth/2);
}
void LLMultiSlider::setValue(const LLSD& value)
@@ -174,30 +197,30 @@ void LLMultiSlider::setValue(const LLSD& value)
}
}
-F32 LLMultiSlider::getSliderValue(const LLString& name) const
+F32 LLMultiSlider::getSliderValue(const std::string& name) const
{
return (F32)mValue[name].asReal();
}
-void LLMultiSlider::setCurSlider(const LLString& name)
+void LLMultiSlider::setCurSlider(const std::string& name)
{
if(mValue.has(name)) {
mCurSlider = name;
}
}
-const LLString& LLMultiSlider::addSlider()
+const std::string& LLMultiSlider::addSlider()
{
return addSlider(mInitialValue);
}
-const LLString& LLMultiSlider::addSlider(F32 val)
+const std::string& LLMultiSlider::addSlider(F32 val)
{
std::stringstream newName;
F32 initVal = val;
if(mValue.size() >= mMaxNumSliders) {
- return LLString::null;
+ return LLStringUtil::null;
}
// create a new name
@@ -206,11 +229,11 @@ const LLString& LLMultiSlider::addSlider(F32 val)
bool foundOne = findUnusedValue(initVal);
if(!foundOne) {
- return LLString::null;
+ return LLStringUtil::null;
}
// add a new thumb rect
- mThumbRects[newName.str()] = LLRect( 0, getRect().getHeight(), MULTI_THUMB_WIDTH, 0 );
+ mThumbRects[newName.str()] = LLRect( 0, getRect().getHeight(), mThumbWidth, 0 );
// add the value and set the current slider to this one
mValue.insert(newName.str(), initVal);
@@ -222,6 +245,30 @@ const LLString& LLMultiSlider::addSlider(F32 val)
return mCurSlider;
}
+void LLMultiSlider::addSlider(F32 val, const std::string& name)
+{
+ F32 initVal = val;
+
+ if(mValue.size() >= mMaxNumSliders) {
+ return;
+ }
+
+ bool foundOne = findUnusedValue(initVal);
+ if(!foundOne) {
+ return;
+ }
+
+ // add a new thumb rect
+ mThumbRects[name] = LLRect( 0, getRect().getHeight(), mThumbWidth, 0 );
+
+ // add the value and set the current slider to this one
+ mValue.insert(name, initVal);
+ mCurSlider = name;
+
+ // move the slider
+ setSliderValue(mCurSlider, initVal, TRUE);
+}
+
bool LLMultiSlider::findUnusedValue(F32& initVal)
{
bool firstTry = true;
@@ -269,7 +316,7 @@ bool LLMultiSlider::findUnusedValue(F32& initVal)
}
-void LLMultiSlider::deleteSlider(const LLString& name)
+void LLMultiSlider::deleteSlider(const std::string& name)
{
// can't delete last slider
if(mValue.size() <= 0) {
@@ -282,7 +329,7 @@ void LLMultiSlider::deleteSlider(const LLString& name)
// set to the last created
if(mValue.size() > 0) {
- std::map<LLString, LLRect>::iterator mIt = mThumbRects.end();
+ std::map<std::string, LLRect>::iterator mIt = mThumbRects.end();
mIt--;
mCurSlider = mIt->first;
}
@@ -294,15 +341,15 @@ void LLMultiSlider::clear()
deleteCurSlider();
}
- LLUICtrl::clear();
+ LLF32UICtrl::clear();
}
BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask)
{
if( gFocusMgr.getMouseCapture() == this )
{
- S32 left_edge = MULTI_THUMB_WIDTH/2;
- S32 right_edge = getRect().getWidth() - (MULTI_THUMB_WIDTH/2);
+ S32 left_edge = mThumbWidth/2;
+ S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
x += mMouseOffset;
x = llclamp( x, left_edge, right_edge );
@@ -330,10 +377,9 @@ BOOL LLMultiSlider::handleMouseUp(S32 x, S32 y, MASK mask)
{
gFocusMgr.setMouseCapture( NULL );
- if( mMouseUpCallback )
- {
- mMouseUpCallback( this, mCallbackUserData );
- }
+ if (mMouseUpSignal)
+ (*mMouseUpSignal)( this, LLSD() );
+
handled = TRUE;
make_ui_sound("UISndClickRelease");
}
@@ -352,10 +398,8 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
}
- if( mMouseDownCallback )
- {
- mMouseDownCallback( this, mCallbackUserData );
- }
+ if (mMouseDownSignal)
+ (*mMouseDownSignal)( this, LLSD() );
if (MASK_CONTROL & mask) // if CTRL is modifying
{
@@ -365,7 +409,7 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
else
{
// scroll through thumbs to see if we have a new one selected and select that one
- std::map<LLString, LLRect>::iterator mIt = mThumbRects.begin();
+ std::map<std::string, LLRect>::iterator mIt = mThumbRects.begin();
for(; mIt != mThumbRects.end(); mIt++) {
// check if inside. If so, set current slider and continue
@@ -378,7 +422,7 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
// Find the offset of the actual mouse location from the center of the thumb.
if (mThumbRects[mCurSlider].pointInRect(x,y))
{
- mMouseOffset = (mThumbRects[mCurSlider].mLeft + MULTI_THUMB_WIDTH/2) - x;
+ mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x;
}
else
{
@@ -423,31 +467,34 @@ BOOL LLMultiSlider::handleKeyHere(KEY key, MASK mask)
void LLMultiSlider::draw()
{
+ static LLUICachedControl<S32> extra_triangle_height ("UIExtraTriangleHeight", 0);
+ static LLUICachedControl<S32> extra_triangle_width ("UIExtraTriangleWidth", 0);
LLColor4 curThumbColor;
- std::map<LLString, LLRect>::iterator mIt;
- std::map<LLString, LLRect>::iterator curSldrIt;
+ std::map<std::string, LLRect>::iterator mIt;
+ std::map<std::string, LLRect>::iterator curSldrIt;
// Draw background and thumb.
// drawing solids requires texturing be disabled
- LLGLSNoTexture no_texture;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLRect rect(mDragStartThumbRect);
F32 opacity = getEnabled() ? 1.f : 0.3f;
// Track
- LLUIImagePtr thumb_imagep = LLUI::sImageProvider->getUIImage("rounded_square.tga");
+ LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square");
- S32 height_offset = (getRect().getHeight() - MULTI_TRACK_HEIGHT) / 2;
+ static LLUICachedControl<S32> multi_track_height ("UIMultiTrackHeight", 0);
+ S32 height_offset = (getRect().getHeight() - multi_track_height) / 2;
LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset );
if(mDrawTrack)
{
track_rect.stretch(-1);
- thumb_imagep->draw(track_rect, mTrackColor % opacity);
+ thumb_imagep->draw(track_rect, mTrackColor.get() % opacity);
}
// if we're supposed to use a drawn triangle
@@ -457,13 +504,13 @@ void LLMultiSlider::draw()
for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) {
gl_triangle_2d(
- mIt->second.mLeft - EXTRA_TRIANGLE_WIDTH,
- mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT,
- mIt->second.mRight + EXTRA_TRIANGLE_WIDTH,
- mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT,
+ mIt->second.mLeft - extra_triangle_width,
+ mIt->second.mTop + extra_triangle_height,
+ mIt->second.mRight + extra_triangle_width,
+ mIt->second.mTop + extra_triangle_height,
mIt->second.mLeft + mIt->second.getWidth() / 2,
- mIt->second.mBottom - EXTRA_TRIANGLE_HEIGHT,
- mTriangleColor, TRUE);
+ mIt->second.mBottom - extra_triangle_height,
+ mTriangleColor.get(), TRUE);
}
}
else if (!thumb_imagep)
@@ -473,7 +520,7 @@ void LLMultiSlider::draw()
for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) {
// choose the color
- curThumbColor = mThumbCenterColor;
+ curThumbColor = mThumbCenterColor.get();
if(mIt->first == mCurSlider) {
curSldrIt = mIt;
@@ -487,19 +534,19 @@ void LLMultiSlider::draw()
// now draw the current slider
if(curSldrIt != mThumbRects.end()) {
- gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor, TRUE);
+ gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor.get(), TRUE);
}
// and draw the drag start
if (gFocusMgr.getMouseCapture() == this)
{
- gl_rect_2d(mDragStartThumbRect, mThumbCenterColor % opacity, FALSE);
+ gl_rect_2d(mDragStartThumbRect, mThumbCenterColor.get() % opacity, FALSE);
}
}
else if( gFocusMgr.getMouseCapture() == this )
{
// draw drag start
- thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor % 0.3f);
+ thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
// draw the highlight
if (hasFocus())
@@ -512,7 +559,7 @@ void LLMultiSlider::draw()
for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++)
{
// choose the color
- curThumbColor = mThumbCenterColor;
+ curThumbColor = mThumbCenterColor.get();
if(mIt->first == mCurSlider)
{
// don't draw now, draw last
@@ -527,7 +574,7 @@ void LLMultiSlider::draw()
// draw cur slider last
if(curSldrIt != mThumbRects.end())
{
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor);
+ thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
}
}
@@ -545,7 +592,7 @@ void LLMultiSlider::draw()
{
// choose the color
- curThumbColor = mThumbCenterColor;
+ curThumbColor = mThumbCenterColor.get();
if(mIt->first == mCurSlider)
{
curSldrIt = mIt;
@@ -558,74 +605,20 @@ void LLMultiSlider::draw()
if(curSldrIt != mThumbRects.end())
{
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor % opacity);
+ thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
}
}
- LLUICtrl::draw();
+ LLF32UICtrl::draw();
}
-
-// virtual
-LLXMLNodePtr LLMultiSlider::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("initial_val", TRUE)->setFloatValue(getInitialValue());
- node->createChild("min_val", TRUE)->setFloatValue(getMinValue());
- node->createChild("max_val", TRUE)->setFloatValue(getMaxValue());
- node->createChild("increment", TRUE)->setFloatValue(getIncrement());
-
- return node;
+boost::signals2::connection LLMultiSlider::setMouseDownCallback( const commit_signal_t::slot_type& cb )
+{
+ if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t();
+ return mMouseDownSignal->connect(cb);
}
-
-//static
-LLView* LLMultiSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- LLString name("multi_slider_bar");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- F32 initial_value = 0.f;
- node->getAttributeF32("initial_val", initial_value);
-
- F32 min_value = 0.f;
- node->getAttributeF32("min_val", min_value);
-
- F32 max_value = 1.f;
- node->getAttributeF32("max_val", max_value);
-
- F32 increment = 0.1f;
- node->getAttributeF32("increment", increment);
-
- S32 max_sliders = 1;
- node->getAttributeS32("max_sliders", max_sliders);
-
- BOOL allow_overlap = FALSE;
- node->getAttributeBOOL("allow_overlap", allow_overlap);
-
- BOOL draw_track = TRUE;
- node->getAttributeBOOL("draw_track", draw_track);
-
- BOOL use_triangle = FALSE;
- node->getAttributeBOOL("use_triangle", use_triangle);
-
- LLMultiSlider* multiSlider = new LLMultiSlider(name,
- rect,
- NULL,
- NULL,
- initial_value,
- min_value,
- max_value,
- increment,
- max_sliders,
- allow_overlap,
- draw_track,
- use_triangle);
-
- multiSlider->initFromXML(node, parent);
-
- return multiSlider;
+boost::signals2::connection LLMultiSlider::setMouseUpCallback( const commit_signal_t::slot_type& cb )
+{
+ if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t();
+ return mMouseUpSignal->connect(cb);
}