llslider.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llslider.h"
00035 #include "llui.h"
00036 
00037 #include "llgl.h"
00038 #include "llwindow.h"
00039 #include "llfocusmgr.h"
00040 #include "llkeyboard.h"                 // for the MASK constants
00041 #include "llcontrol.h"
00042 #include "llimagegl.h"
00043 
00044 static LLRegisterWidget<LLSlider> r1("slider_bar");
00045 static LLRegisterWidget<LLSlider> r2("volume_slider");
00046 
00047 
00048 LLSlider::LLSlider( 
00049         const LLString& name,
00050         const LLRect& rect,
00051         void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
00052         void* callback_userdata,
00053         F32 initial_value,
00054         F32 min_value,
00055         F32 max_value,
00056         F32 increment,
00057         BOOL volume,
00058         const LLString& control_name)
00059         :
00060         LLUICtrl( name, rect, TRUE,     on_commit_callback, callback_userdata, 
00061                 FOLLOWS_LEFT | FOLLOWS_TOP),
00062         mValue( initial_value ),
00063         mInitialValue( initial_value ),
00064         mMinValue( min_value ),
00065         mMaxValue( max_value ),
00066         mIncrement( increment ),
00067         mVolumeSlider( volume ),
00068         mMouseOffset( 0 ),
00069         mTrackColor(            LLUI::sColorsGroup->getColor( "SliderTrackColor" ) ),
00070         mThumbOutlineColor(     LLUI::sColorsGroup->getColor( "SliderThumbOutlineColor" ) ),
00071         mThumbCenterColor(      LLUI::sColorsGroup->getColor( "SliderThumbCenterColor" ) ),
00072         mMouseDownCallback( NULL ),
00073         mMouseUpCallback( NULL )
00074 {
00075         mThumbImage = LLUI::sImageProvider->getUIImage("icn_slide-thumb_dark.tga");
00076         mTrackImage = LLUI::sImageProvider->getUIImage("icn_slide-groove_dark.tga");
00077         mTrackHighlightImage = LLUI::sImageProvider->getUIImage("icn_slide-highlight.tga");
00078 
00079         // properly handle setting the starting thumb rect
00080         // do it this way to handle both the operating-on-settings
00081         // and standalone ways of using this
00082         setControlName(control_name, NULL);
00083         setValue(getValueF32());
00084 
00085         updateThumbRect();
00086         mDragStartThumbRect = mThumbRect;
00087 }
00088 
00089 
00090 void LLSlider::setValue(F32 value, BOOL from_event)
00091 {
00092         value = llclamp( value, mMinValue, mMaxValue );
00093 
00094         // Round to nearest increment (bias towards rounding down)
00095         value -= mMinValue;
00096         value += mIncrement/2.0001f;
00097         value -= fmod(value, mIncrement);
00098         value += mMinValue;
00099 
00100         if (!from_event && mValue != value)
00101         {
00102                 setControlValue(value);
00103         }
00104 
00105         mValue = value;
00106         updateThumbRect();
00107 }
00108 
00109 void LLSlider::updateThumbRect()
00110 {
00111         F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue);
00112 
00113         S32 thumb_width = mThumbImage->getWidth();
00114         S32 thumb_height = mThumbImage->getHeight();
00115         S32 left_edge = (thumb_width / 2);
00116         S32 right_edge = getRect().getWidth() - (thumb_width / 2);
00117 
00118         S32 x = left_edge + S32( t * (right_edge - left_edge) );
00119         mThumbRect.mLeft = x - (thumb_width / 2);
00120         mThumbRect.mRight = mThumbRect.mLeft + thumb_width;
00121         mThumbRect.mBottom = getLocalRect().getCenterY() - (thumb_height / 2);
00122         mThumbRect.mTop = mThumbRect.mBottom + thumb_height;
00123 }
00124 
00125 
00126 void LLSlider::setValueAndCommit(F32 value)
00127 {
00128         F32 old_value = mValue;
00129         setValue(value);
00130 
00131         if (mValue != old_value)
00132         {
00133                 onCommit();
00134         }
00135 }
00136 
00137 
00138 BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask)
00139 {
00140         if( hasMouseCapture() )
00141         {
00142                 S32 thumb_half_width = mThumbImage->getWidth()/2;
00143                 S32 left_edge = thumb_half_width;
00144                 S32 right_edge = getRect().getWidth() - (thumb_half_width);
00145 
00146                 x += mMouseOffset;
00147                 x = llclamp( x, left_edge, right_edge );
00148 
00149                 F32 t = F32(x - left_edge) / (right_edge - left_edge);
00150                 setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue );
00151 
00152                 getWindow()->setCursor(UI_CURSOR_ARROW);
00153                 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;               
00154         }
00155         else
00156         {
00157                 getWindow()->setCursor(UI_CURSOR_ARROW);
00158                 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;             
00159         }
00160         return TRUE;
00161 }
00162 
00163 BOOL LLSlider::handleMouseUp(S32 x, S32 y, MASK mask)
00164 {
00165         BOOL handled = FALSE;
00166 
00167         if( hasMouseCapture() )
00168         {
00169                 gFocusMgr.setMouseCapture( NULL );
00170 
00171                 if( mMouseUpCallback )
00172                 {
00173                         mMouseUpCallback( this, mCallbackUserData );
00174                 }
00175                 handled = TRUE;
00176                 make_ui_sound("UISndClickRelease");
00177         }
00178         else
00179         {
00180                 handled = TRUE;
00181         }
00182 
00183         return handled;
00184 }
00185 
00186 BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask)
00187 {
00188         // only do sticky-focus on non-chrome widgets
00189         if (!getIsChrome())
00190         {
00191                 setFocus(TRUE);
00192         }
00193         if( mMouseDownCallback )
00194         {
00195                 mMouseDownCallback( this, mCallbackUserData );
00196         }
00197 
00198         if (MASK_CONTROL & mask) // if CTRL is modifying
00199         {
00200                 setValueAndCommit(mInitialValue);
00201         }
00202         else
00203         {
00204                 // Find the offset of the actual mouse location from the center of the thumb.
00205                 if (mThumbRect.pointInRect(x,y))
00206                 {
00207                         mMouseOffset = (mThumbRect.mLeft + mThumbImage->getWidth()/2) - x;
00208                 }
00209                 else
00210                 {
00211                         mMouseOffset = 0;
00212                 }
00213 
00214                 // Start dragging the thumb
00215                 // No handler needed for focus lost since this class has no state that depends on it.
00216                 gFocusMgr.setMouseCapture( this );  
00217                 mDragStartThumbRect = mThumbRect;                               
00218         }
00219         make_ui_sound("UISndClick");
00220 
00221         return TRUE;
00222 }
00223 
00224 BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
00225 {
00226         BOOL handled = FALSE;
00227         switch(key)
00228         {
00229         case KEY_UP:
00230         case KEY_DOWN:
00231                 // eat up and down keys to be consistent
00232                 handled = TRUE;
00233                 break;
00234         case KEY_LEFT:
00235                 setValueAndCommit(getValueF32() - getIncrement());
00236                 handled = TRUE;
00237                 break;
00238         case KEY_RIGHT:
00239                 setValueAndCommit(getValueF32() + getIncrement());
00240                 handled = TRUE;
00241                 break;
00242         default:
00243                 break;
00244         }
00245         return handled;
00246 }
00247 
00248 void LLSlider::draw()
00249 {
00250         // since thumb image might still be decoding, need thumb to accomodate image size
00251         updateThumbRect();
00252 
00253         // Draw background and thumb.
00254 
00255         // drawing solids requires texturing be disabled
00256         LLGLSNoTexture no_texture;
00257 
00258         F32 opacity = getEnabled() ? 1.f : 0.3f;
00259         LLColor4 center_color = (mThumbCenterColor % opacity);
00260         LLColor4 track_color = (mTrackColor % opacity);
00261 
00262         // Track
00263         LLRect track_rect(mThumbImage->getWidth() / 2, 
00264                                                 getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2), 
00265                                                 getRect().getWidth() - mThumbImage->getWidth() / 2, 
00266                                                 getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) );
00267         LLRect highlight_rect(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom);
00268         mTrackImage->draw(track_rect);
00269         mTrackHighlightImage->draw(highlight_rect);
00270 
00271         // Thumb
00272         if( hasMouseCapture() )
00273         {
00274                 // Show ghost where thumb was before dragging began.
00275                 mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor % 0.3f);
00276         }
00277         if (hasFocus())
00278         {
00279                 // Draw focus highlighting.
00280                 mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
00281         }
00282         // Fill in the thumb.
00283         mThumbImage->draw(mThumbRect, hasMouseCapture() ? mThumbOutlineColor : center_color);
00284 
00285         LLUICtrl::draw();
00286 }
00287 
00288 // virtual
00289 LLXMLNodePtr LLSlider::getXML(bool save_children) const
00290 {
00291         LLXMLNodePtr node = LLUICtrl::getXML();
00292 
00293         node->createChild("initial_val", TRUE)->setFloatValue(getInitialValue());
00294         node->createChild("min_val", TRUE)->setFloatValue(getMinValue());
00295         node->createChild("max_val", TRUE)->setFloatValue(getMaxValue());
00296         node->createChild("increment", TRUE)->setFloatValue(getIncrement());
00297         node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider);
00298 
00299         return node;
00300 }
00301 
00302 
00303 //static
00304 LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory)
00305 {
00306         LLString name("slider_bar");
00307         node->getAttributeString("name", name);
00308 
00309         LLRect rect;
00310         createRect(node, rect, parent, LLRect());
00311 
00312         F32 initial_value = 0.f;
00313         node->getAttributeF32("initial_val", initial_value);
00314 
00315         F32 min_value = 0.f;
00316         node->getAttributeF32("min_val", min_value);
00317 
00318         F32 max_value = 1.f; 
00319         node->getAttributeF32("max_val", max_value);
00320 
00321         F32 increment = 0.1f;
00322         node->getAttributeF32("increment", increment);
00323 
00324         BOOL volume = node->hasName("volume_slider") ? TRUE : FALSE;
00325         node->getAttributeBOOL("volume", volume);
00326 
00327         LLSlider* slider = new LLSlider(name,
00328                                                         rect,
00329                                                         NULL,
00330                                                         NULL,
00331                                                         initial_value,
00332                                                         min_value,
00333                                                         max_value,
00334                                                         increment,
00335                                                         volume);
00336 
00337         slider->initFromXML(node, parent);
00338 
00339         return slider;
00340 }

Generated on Fri May 16 08:32:58 2008 for SecondLife by  doxygen 1.5.5