diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/llui/llslider.cpp |
Print done when done.
Diffstat (limited to 'indra/llui/llslider.cpp')
-rw-r--r-- | indra/llui/llslider.cpp | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp new file mode 100644 index 0000000000..2a1c2f7845 --- /dev/null +++ b/indra/llui/llslider.cpp @@ -0,0 +1,352 @@ +/** + * @file llslider.cpp + * @brief LLSlider base class + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llslider.h" +#include "llui.h" + +#include "llgl.h" +#include "llwindow.h" +#include "llfocusmgr.h" +#include "llkeyboard.h" // for the MASK constants +#include "llcontrol.h" +#include "llimagegl.h" + +const S32 THUMB_WIDTH = 8; +const S32 TRACK_HEIGHT = 6; + +LLSlider::LLSlider( + 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, + const LLString& control_name) + : + LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata, + FOLLOWS_LEFT | FOLLOWS_TOP), + mValue( initial_value ), + mInitialValue( initial_value ), + mMinValue( min_value ), + mMaxValue( max_value ), + mIncrement( increment ), + mMouseOffset( 0 ), + mDragStartThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ), + mThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ), + mTrackColor( LLUI::sColorsGroup->getColor( "SliderTrackColor" ) ), + mThumbOutlineColor( LLUI::sColorsGroup->getColor( "SliderThumbOutlineColor" ) ), + mThumbCenterColor( LLUI::sColorsGroup->getColor( "SliderThumbCenterColor" ) ), + mDisabledThumbColor(LLUI::sColorsGroup->getColor( "SliderDisabledThumbColor" ) ), + mMouseDownCallback( NULL ), + mMouseUpCallback( NULL ) +{ + // prperly 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(getValueF32()); +} + +EWidgetType LLSlider::getWidgetType() const +{ + return WIDGET_TYPE_SLIDER_BAR; +} + +LLString LLSlider::getWidgetTag() const +{ + return LL_SLIDER_TAG; +} + +void LLSlider::setValue(F32 value, BOOL from_event) +{ + value = llclamp( value, mMinValue, mMaxValue ); + + // Round to nearest increment (bias towards rounding down) + value -= mMinValue; + value += mIncrement/2.0001f; + value -= fmod(value, mIncrement); + mValue = mMinValue + value; + + if (!from_event) + { + setControlValue(mValue); + } + + F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue); + + S32 left_edge = THUMB_WIDTH/2; + S32 right_edge = mRect.getWidth() - (THUMB_WIDTH/2); + + S32 x = left_edge + S32( t * (right_edge - left_edge) ); + mThumbRect.mLeft = x - (THUMB_WIDTH/2); + mThumbRect.mRight = x + (THUMB_WIDTH/2); +} + +F32 LLSlider::getValueF32() const +{ + return mValue; +} + +BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask) +{ + if( gFocusMgr.getMouseCapture() == this ) + { + S32 left_edge = THUMB_WIDTH/2; + S32 right_edge = mRect.getWidth() - (THUMB_WIDTH/2); + + x += mMouseOffset; + x = llclamp( x, left_edge, right_edge ); + + F32 t = F32(x - left_edge) / (right_edge - left_edge); + setValue(t * (mMaxValue - mMinValue) + mMinValue ); + onCommit(); + + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; + } + else + { + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; + } + return TRUE; +} + +BOOL LLSlider::handleMouseUp(S32 x, S32 y, MASK mask) +{ + BOOL handled = FALSE; + + if( gFocusMgr.getMouseCapture() == this ) + { + gFocusMgr.setMouseCapture( NULL, NULL ); + + if( mMouseUpCallback ) + { + mMouseUpCallback( this, mCallbackUserData ); + } + handled = TRUE; + make_ui_sound("UISndClickRelease"); + } + else + { + handled = TRUE; + } + + return handled; +} + +BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // only do sticky-focus on non-chrome widgets + if (!getIsChrome()) + { + setFocus(TRUE); + } + if( mMouseDownCallback ) + { + mMouseDownCallback( this, mCallbackUserData ); + } + + if (MASK_CONTROL & mask) // if CTRL is modifying + { + setValue(mInitialValue); + onCommit(); + } + else + { + // Find the offset of the actual mouse location from the center of the thumb. + if (mThumbRect.pointInRect(x,y)) + { + mMouseOffset = (mThumbRect.mLeft + THUMB_WIDTH/2) - x; + } + else + { + mMouseOffset = 0; + } + + // Start dragging the thumb + // No handler needed for focus lost since this class has no state that depends on it. + gFocusMgr.setMouseCapture( this, NULL ); + mDragStartThumbRect = mThumbRect; + } + make_ui_sound("UISndClick"); + + return TRUE; +} + +BOOL LLSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) +{ + BOOL handled = FALSE; + if( getVisible() && mEnabled && !called_from_parent ) + { + switch(key) + { + case KEY_UP: + case KEY_DOWN: + // eat up and down keys to be consistent + handled = TRUE; + break; + case KEY_LEFT: + setValue(getValueF32() - getIncrement()); + onCommit(); + handled = TRUE; + break; + case KEY_RIGHT: + setValue(getValueF32() + getIncrement()); + onCommit(); + handled = TRUE; + break; + default: + break; + } + } + return handled; +} + +void LLSlider::draw() +{ + if( getVisible() ) + { + // Draw background and thumb. + + // drawing solids requires texturing be disabled + LLGLSNoTexture no_texture; + + LLRect rect(mDragStartThumbRect); + + F32 opacity = mEnabled ? 1.f : 0.3f; + + // Track + + LLUUID thumb_image_id; + thumb_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga")); + LLImageGL* thumb_imagep = LLUI::sImageProvider->getUIImageByID(thumb_image_id); + + S32 height_offset = (mRect.getHeight() - TRACK_HEIGHT) / 2; + LLRect track_rect(0, mRect.getHeight() - height_offset, mRect.getWidth(), height_offset ); + + track_rect.stretch(-1); + gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 16, 16, track_rect.getWidth(), track_rect.getHeight(), + thumb_imagep, mTrackColor % opacity); + //gl_rect_2d( track_rect, mThumbOutlineColor % opacity ); + + if (!thumb_imagep) + { + gl_rect_2d(mThumbRect, mThumbCenterColor, TRUE); + if (gFocusMgr.getMouseCapture() == this) + { + gl_rect_2d(mDragStartThumbRect, mThumbCenterColor % opacity, FALSE); + } + } + else if( gFocusMgr.getMouseCapture() == this ) + { + gl_draw_scaled_image_with_border(mDragStartThumbRect.mLeft, mDragStartThumbRect.mBottom, 16, 16, mDragStartThumbRect.getWidth(), mDragStartThumbRect.getHeight(), + thumb_imagep, mThumbCenterColor % 0.3f, TRUE); + + if (hasFocus()) + { + F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); + LLRect highlight_rect = mThumbRect; + highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); + gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(), + thumb_imagep, gFocusMgr.getFocusColor()); + } + + + gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), + thumb_imagep, mThumbOutlineColor, TRUE); + + //// Start Thumb + //gl_rect_2d( mDragStartThumbRect, mThumbOutlineColor % 0.3f ); + //rect.stretch(-1); + //gl_rect_2d( rect, mThumbCenterColor % 0.3f ); + + //// Thumb + //gl_rect_2d( mThumbRect, mThumbOutlineColor ); + } + else + { + if (hasFocus()) + { + F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); + LLRect highlight_rect = mThumbRect; + highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); + gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(), + thumb_imagep, gFocusMgr.getFocusColor()); + } + + gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), + thumb_imagep, mThumbCenterColor % opacity, TRUE); + //rect = mThumbRect; + + //gl_rect_2d( mThumbRect, mThumbOutlineColor % opacity ); + // + //rect.stretch(-1); + + //// Thumb + //gl_rect_2d( rect, mThumbCenterColor % opacity ); + + } + + LLUICtrl::draw(); + } +} + +// virtual +LLXMLNodePtr LLSlider::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; +} + + +//static +LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +{ + LLString name("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); + + + LLSlider* slider = new LLSlider(name, + rect, + NULL, + NULL, + initial_value, + min_value, + max_value, + increment); + + slider->initFromXML(node, parent); + + return slider; +} |