diff options
Diffstat (limited to 'indra/llui/llslider.cpp')
-rw-r--r-- | indra/llui/llslider.cpp | 253 |
1 files changed, 182 insertions, 71 deletions
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp index 66ed0d4e88..013950a5ad 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -2,31 +2,25 @@ * @file llslider.cpp * @brief LLSlider base class * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&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://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * 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 + * 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. * - * 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. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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 + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,18 +34,24 @@ #include "llfocusmgr.h" #include "llkeyboard.h" // for the MASK constants #include "llcontrol.h" -#include "llimagegl.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLSlider> r1("slider_bar"); +static LLDefaultChildRegistry::Register<LLSlider> r1("slider_bar"); +//FIXME: make this into an unregistered template so that code constructed sliders don't +// have ambigious template lookup problem LLSlider::Params::Params() -: track_color("track_color"), +: orientation ("orientation", std::string ("horizontal")), + track_color("track_color"), thumb_outline_color("thumb_outline_color"), thumb_center_color("thumb_center_color"), thumb_image("thumb_image"), - track_image("track_image"), - track_highlight_image("track_highlight_image"), + thumb_image_pressed("thumb_image_pressed"), + thumb_image_disabled("thumb_image_disabled"), + track_image_horizontal("track_image_horizontal"), + track_image_vertical("track_image_vertical"), + track_highlight_horizontal_image("track_highlight_horizontal_image"), + track_highlight_vertical_image("track_highlight_vertical_image"), mouse_down_callback("mouse_down_callback"), mouse_up_callback("mouse_up_callback") { @@ -61,12 +61,19 @@ LLSlider::Params::Params() LLSlider::LLSlider(const LLSlider::Params& p) : LLF32UICtrl(p), mMouseOffset( 0 ), + mOrientation ((p.orientation() == "horizontal") ? HORIZONTAL : VERTICAL), mTrackColor(p.track_color()), mThumbOutlineColor(p.thumb_outline_color()), mThumbCenterColor(p.thumb_center_color()), mThumbImage(p.thumb_image), - mTrackImage(p.track_image), - mTrackHighlightImage(p.track_highlight_image) + mThumbImagePressed(p.thumb_image_pressed), + mThumbImageDisabled(p.thumb_image_disabled), + mTrackImageHorizontal(p.track_image_horizontal), + mTrackImageVertical(p.track_image_vertical), + mTrackHighlightHorizontalImage(p.track_highlight_horizontal_image), + mTrackHighlightVerticalImage(p.track_highlight_vertical_image), + mMouseDownSignal(NULL), + mMouseUpSignal(NULL) { mViewModel->setValue(p.initial_value); updateThumbRect(); @@ -75,9 +82,19 @@ LLSlider::LLSlider(const LLSlider::Params& p) setValue(getValueF32()); if (p.mouse_down_callback.isProvided()) - initCommitCallback(p.mouse_down_callback, mMouseDownSignal); + { + setMouseDownCallback(initCommitCallback(p.mouse_down_callback)); + } if (p.mouse_up_callback.isProvided()) - initCommitCallback(p.mouse_up_callback, mMouseUpSignal); + { + setMouseUpCallback(initCommitCallback(p.mouse_up_callback)); + } +} + +LLSlider::~LLSlider() +{ + delete mMouseDownSignal; + delete mMouseUpSignal; } void LLSlider::setValue(F32 value, BOOL from_event) @@ -106,14 +123,29 @@ void LLSlider::updateThumbRect() S32 thumb_width = mThumbImage ? mThumbImage->getWidth() : DEFAULT_THUMB_SIZE; S32 thumb_height = mThumbImage ? mThumbImage->getHeight() : DEFAULT_THUMB_SIZE; - S32 left_edge = (thumb_width / 2); - S32 right_edge = getRect().getWidth() - (thumb_width / 2); - - S32 x = left_edge + S32( t * (right_edge - left_edge) ); - mThumbRect.mLeft = x - (thumb_width / 2); - mThumbRect.mRight = mThumbRect.mLeft + thumb_width; - mThumbRect.mBottom = getLocalRect().getCenterY() - (thumb_height / 2); - mThumbRect.mTop = mThumbRect.mBottom + thumb_height; + + if ( mOrientation == HORIZONTAL ) + { + S32 left_edge = (thumb_width / 2); + S32 right_edge = getRect().getWidth() - (thumb_width / 2); + + S32 x = left_edge + S32( t * (right_edge - left_edge) ); + mThumbRect.mLeft = x - (thumb_width / 2); + mThumbRect.mRight = mThumbRect.mLeft + thumb_width; + mThumbRect.mBottom = getLocalRect().getCenterY() - (thumb_height / 2); + mThumbRect.mTop = mThumbRect.mBottom + thumb_height; + } + else + { + S32 top_edge = (thumb_height / 2); + S32 bottom_edge = getRect().getHeight() - (thumb_height / 2); + + S32 y = top_edge + S32( t * (bottom_edge - top_edge) ); + mThumbRect.mLeft = getLocalRect().getCenterX() - (thumb_width / 2); + mThumbRect.mRight = mThumbRect.mLeft + thumb_width; + mThumbRect.mBottom = y - (thumb_height / 2); + mThumbRect.mTop = mThumbRect.mBottom + thumb_height; + } } @@ -133,18 +165,32 @@ BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask) { if( hasMouseCapture() ) { - S32 thumb_half_width = mThumbImage->getWidth()/2; - S32 left_edge = thumb_half_width; - S32 right_edge = getRect().getWidth() - (thumb_half_width); + if ( mOrientation == HORIZONTAL ) + { + S32 thumb_half_width = mThumbImage->getWidth()/2; + S32 left_edge = thumb_half_width; + S32 right_edge = getRect().getWidth() - (thumb_half_width); + + x += mMouseOffset; + x = llclamp( x, left_edge, right_edge ); - x += mMouseOffset; - x = llclamp( x, left_edge, right_edge ); + F32 t = F32(x - left_edge) / (right_edge - left_edge); + setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue ); + } + else // mOrientation == VERTICAL + { + S32 thumb_half_height = mThumbImage->getHeight()/2; + S32 top_edge = thumb_half_height; + S32 bottom_edge = getRect().getHeight() - (thumb_half_height); - F32 t = F32(x - left_edge) / (right_edge - left_edge); - setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue ); + y += mMouseOffset; + y = llclamp(y, top_edge, bottom_edge); + F32 t = F32(y - top_edge) / (bottom_edge - top_edge); + setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue ); + } getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; } else { @@ -162,7 +208,8 @@ BOOL LLSlider::handleMouseUp(S32 x, S32 y, MASK mask) { gFocusMgr.setMouseCapture( NULL ); - mMouseUpSignal( this, getValueF32() ); + if (mMouseUpSignal) + (*mMouseUpSignal)( this, getValueF32() ); handled = TRUE; make_ui_sound("UISndClickRelease"); @@ -182,7 +229,8 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask) { setFocus(TRUE); } - mMouseDownSignal( this, getValueF32() ); + if (mMouseDownSignal) + (*mMouseDownSignal)( this, getValueF32() ); if (MASK_CONTROL & mask) // if CTRL is modifying { @@ -193,7 +241,9 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask) // Find the offset of the actual mouse location from the center of the thumb. if (mThumbRect.pointInRect(x,y)) { - mMouseOffset = (mThumbRect.mLeft + mThumbImage->getWidth()/2) - x; + mMouseOffset = (mOrientation == HORIZONTAL) + ? (mThumbRect.mLeft + mThumbImage->getWidth()/2) - x + : (mThumbRect.mBottom + mThumbImage->getHeight()/2) - y; } else { @@ -215,15 +265,12 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask) BOOL handled = FALSE; switch(key) { - case KEY_UP: case KEY_DOWN: - // eat up and down keys to be consistent - handled = TRUE; - break; case KEY_LEFT: setValueAndCommit(getValueF32() - getIncrement()); handled = TRUE; break; + case KEY_UP: case KEY_RIGHT: setValueAndCommit(getValueF32() + getIncrement()); handled = TRUE; @@ -234,8 +281,21 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask) return handled; } +BOOL LLSlider::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + if ( mOrientation == VERTICAL ) + { + F32 new_val = getValueF32() - clicks * getIncrement(); + setValueAndCommit(new_val); + return TRUE; + } + return LLF32UICtrl::handleScrollWheel(x,y,clicks); +} + void LLSlider::draw() { + F32 alpha = getDrawContext().mAlpha; + // since thumb image might still be decoding, need thumb to accomodate image size updateThumbRect(); @@ -244,32 +304,83 @@ void LLSlider::draw() // drawing solids requires texturing be disabled gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - F32 opacity = getEnabled() ? 1.f : 0.3f; - LLColor4 center_color = (mThumbCenterColor.get() % opacity); - LLColor4 track_color = (mTrackColor.get() % opacity); - // Track - LLRect track_rect(mThumbImage->getWidth() / 2, - getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2), - getRect().getWidth() - mThumbImage->getWidth() / 2, - getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) ); - LLRect highlight_rect(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom); - mTrackImage->draw(track_rect); - mTrackHighlightImage->draw(highlight_rect); + LLPointer<LLUIImage>& trackImage = ( mOrientation == HORIZONTAL ) + ? mTrackImageHorizontal + : mTrackImageVertical; - // Thumb - if( hasMouseCapture() ) + LLPointer<LLUIImage>& trackHighlightImage = ( mOrientation == HORIZONTAL ) + ? mTrackHighlightHorizontalImage + : mTrackHighlightVerticalImage; + + LLRect track_rect; + LLRect highlight_rect; + + if ( mOrientation == HORIZONTAL ) { - // Show ghost where thumb was before dragging began. - mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f); + track_rect.set(mThumbImage->getWidth() / 2, + getLocalRect().getCenterY() + (trackImage->getHeight() / 2), + getRect().getWidth() - mThumbImage->getWidth() / 2, + getLocalRect().getCenterY() - (trackImage->getHeight() / 2) ); + highlight_rect.set(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom); + } + else + { + track_rect.set(getLocalRect().getCenterX() - (trackImage->getWidth() / 2), + getRect().getHeight(), + getLocalRect().getCenterX() + (trackImage->getWidth() / 2), + 0); + highlight_rect.set(track_rect.mLeft, track_rect.mTop, track_rect.mRight, track_rect.mBottom); } + + trackImage->draw(track_rect, LLColor4::white % alpha); + trackHighlightImage->draw(highlight_rect, LLColor4::white % alpha); + + // Thumb if (hasFocus()) { // Draw focus highlighting. - mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); + mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor() % alpha, gFocusMgr.getFocusFlashWidth()); } - // Fill in the thumb. - mThumbImage->draw(mThumbRect, hasMouseCapture() ? mThumbOutlineColor.get() : center_color); + if( hasMouseCapture() ) // currently clicking on slider + { + // Show ghost where thumb was before dragging began. + if (mThumbImage.notNull()) + { + mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor.get() % (0.3f * alpha)); + } + if (mThumbImagePressed.notNull()) + { + mThumbImagePressed->draw(mThumbRect, mThumbOutlineColor % alpha); + } + } + else if (!isInEnabledChain()) + { + if (mThumbImageDisabled.notNull()) + { + mThumbImageDisabled->draw(mThumbRect, mThumbCenterColor % alpha); + } + } + else + { + if (mThumbImage.notNull()) + { + mThumbImage->draw(mThumbRect, mThumbCenterColor % alpha); + } + } + LLUICtrl::draw(); } + +boost::signals2::connection LLSlider::setMouseDownCallback( const commit_signal_t::slot_type& cb ) +{ + if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t(); + return mMouseDownSignal->connect(cb); +} + +boost::signals2::connection LLSlider::setMouseUpCallback( const commit_signal_t::slot_type& cb ) +{ + if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t(); + return mMouseUpSignal->connect(cb); +} |