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.cpp102
1 files changed, 73 insertions, 29 deletions
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index 0aa3e17075..cd9c77585a 100644
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
@@ -41,8 +41,6 @@
static LLDefaultChildRegistry::Register<LLMultiSlider> r("multi_slider_bar");
-const F32 FLOAT_THRESHOLD = 0.00001f;
-
S32 LLMultiSlider::mNameCounter = 0;
LLMultiSlider::SliderParams::SliderParams()
@@ -54,6 +52,7 @@ LLMultiSlider::SliderParams::SliderParams()
LLMultiSlider::Params::Params()
: max_sliders("max_sliders", 1),
allow_overlap("allow_overlap", false),
+ overlap_threshold("overlap_threshold", 0),
draw_track("draw_track", true),
use_triangle("use_triangle", false),
track_color("track_color"),
@@ -98,6 +97,15 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
}
+ if (p.overlap_threshold.isProvided())
+ {
+ mOverlapThreshold = p.overlap_threshold;
+ }
+ else
+ {
+ mOverlapThreshold = 0;
+ }
+
for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders.begin();
it != p.sliders.end();
++it)
@@ -143,11 +151,14 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from
// look at the current spot
// and see if anything is there
LLSD::map_iterator mIt = mValue.beginMap();
+ F32 threshold = mOverlapThreshold + (mIncrement / 4); // increment is our distance between points, use to eliminate round error
for(;mIt != mValue.endMap(); mIt++) {
F32 testVal = (F32)mIt->second.asReal() - newValue;
- if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD &&
- mIt->first != name) {
+ if (testVal > -threshold
+ && testVal < threshold
+ && mIt->first != name)
+ {
hit = true;
break;
}
@@ -196,7 +207,11 @@ void LLMultiSlider::setValue(const LLSD& value)
F32 LLMultiSlider::getSliderValue(const std::string& name) const
{
- return (F32)mValue[name].asReal();
+ if (mValue.has(name))
+ {
+ return (F32)mValue[name].asReal();
+ }
+ return 0;
}
void LLMultiSlider::setCurSlider(const std::string& name)
@@ -206,6 +221,24 @@ void LLMultiSlider::setCurSlider(const std::string& name)
}
}
+F32 LLMultiSlider::getSliderValueFromX(S32 xpos) const
+{
+ S32 left_edge = mThumbWidth / 2;
+ S32 right_edge = getRect().getWidth() - (mThumbWidth / 2);
+
+ xpos += mMouseOffset;
+ xpos = llclamp(xpos, left_edge, right_edge);
+
+ F32 t = F32(xpos - left_edge) / (right_edge - left_edge);
+
+ return((t * (mMaxValue - mMinValue)) + mMinValue);
+}
+
+void LLMultiSlider::resetCurSlider()
+{
+ mCurSlider = LLStringUtil::null;
+}
+
const std::string& LLMultiSlider::addSlider()
{
return addSlider(mInitialValue);
@@ -278,11 +311,13 @@ bool LLMultiSlider::findUnusedValue(F32& initVal)
// look at the current spot
// and see if anything is there
+ F32 threshold = mOverlapThreshold + (mIncrement / 4);
LLSD::map_iterator mIt = mValue.beginMap();
for(;mIt != mValue.endMap(); mIt++) {
F32 testVal = (F32)mIt->second.asReal() - initVal;
- if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD) {
+ if(testVal > -threshold && testVal < threshold)
+ {
hit = true;
break;
}
@@ -334,10 +369,15 @@ void LLMultiSlider::deleteSlider(const std::string& name)
void LLMultiSlider::clear()
{
- while(mThumbRects.size() > 0) {
+ while(mThumbRects.size() > 0 && mValue.size() > 0) {
deleteCurSlider();
}
+ if (mThumbRects.size() > 0 || mValue.size() > 0)
+ {
+ LL_WARNS() << "Failed to fully clear Multi slider" << LL_ENDL;
+ }
+
LLF32UICtrl::clear();
}
@@ -345,14 +385,15 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask)
{
if( gFocusMgr.getMouseCapture() == this )
{
- S32 left_edge = mThumbWidth/2;
- S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
-
- x += mMouseOffset;
- x = llclamp( x, left_edge, right_edge );
-
- F32 t = F32(x - left_edge) / (right_edge - left_edge);
- setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue );
+// S32 left_edge = mThumbWidth/2;
+// S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
+//
+// x += mMouseOffset;
+// x = llclamp( x, left_edge, right_edge );
+//
+// F32 t = F32(x - left_edge) / (right_edge - left_edge);
+// setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue );
+ setCurSliderValue(getSliderValueFromX(x));
onCommit();
getWindow()->setCursor(UI_CURSOR_ARROW);
@@ -416,20 +457,23 @@ 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))
+ if (!mCurSlider.empty())
{
- mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x;
- }
- else
- {
- mMouseOffset = 0;
- }
+ // Find the offset of the actual mouse location from the center of the thumb.
+ if (mThumbRects[mCurSlider].pointInRect(x,y))
+ {
+ mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/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 );
- mDragStartThumbRect = mThumbRects[mCurSlider];
+ // Start dragging the thumb
+ // No handler needed for focus lost since this class has no state that depends on it.
+ gFocusMgr.setMouseCapture( this );
+ mDragStartThumbRect = mThumbRects[mCurSlider];
+ }
}
make_ui_sound("UISndClick");
@@ -546,7 +590,7 @@ void LLMultiSlider::draw()
thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
// draw the highlight
- if (hasFocus())
+ if (hasFocus() && !mCurSlider.empty())
{
thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
}
@@ -578,7 +622,7 @@ void LLMultiSlider::draw()
else
{
// draw highlight
- if (hasFocus())
+ if (hasFocus() && !mCurSlider.empty())
{
thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
}