diff options
Diffstat (limited to 'indra/llui/llmultislider.cpp')
-rw-r--r-- | indra/llui/llmultislider.cpp | 347 |
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); } |