123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865 |
- /**
- * @file llsliderctrl.cpp
- * @brief LLSliderCtrl base class
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * 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
- *
- * 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
- *
- * 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.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llsliderctrl.h"
- #include "llcontrol.h"
- #include "llgl.h"
- #include "llimagegl.h"
- #include "llkeyboard.h"
- #include "lllineeditor.h"
- #include "lllocale.h"
- #include "lltextbox.h"
- #include "llwindow.h"
- constexpr U32 MAX_SLIDER_STR_LEN = 10;
- static const std::string LL_SLIDER_CTRL_TAG = "slider";
- static LLRegisterWidget<LLSliderCtrl> r23(LL_SLIDER_CTRL_TAG);
- ///////////////////////////////////////////////////////////////////////////////
- // LLSlider class (actuak slider sub-element of LLSliderCtrl).
- ///////////////////////////////////////////////////////////////////////////////
- LLSlider::LLSlider(const std::string& name, const LLRect& rect,
- void (*on_commit_callback)(LLUICtrl*, void*),
- void* callback_userdata,
- F32 initial_value, F32 min_value, F32 max_value,
- F32 increment, const char* 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),
- mMouseDownCallback(NULL),
- mMouseUpCallback(NULL),
- mMouseHoverCallback(NULL)
- {
- mThumbImage = LLUI::getUIImage("icn_slide-thumb_dark.tga");
- mTrackImage = LLUI::getUIImage("icn_slide-groove_dark.tga");
- mTrackHighlightImage = LLUI::getUIImage("icn_slide-highlight.tga");
- // 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(getValueF32());
- updateThumbRect();
- mDragStartThumbRect = mThumbRect;
- }
- //virtual
- 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);
- value += mMinValue;
- if (!from_event && mValue != value)
- {
- setControlValue(value);
- }
- mValue = value;
- updateThumbRect();
- }
- void LLSlider::updateThumbRect()
- {
- F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue);
- S32 thumb_width = mThumbImage->getWidth();
- S32 thumb_height = mThumbImage->getHeight();
- 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;
- }
- void LLSlider::setValueAndCommit(F32 value)
- {
- F32 old_value = mValue;
- setValue(value);
- if (value != old_value)
- {
- onCommit();
- }
- }
- //virtual
- bool LLSlider::handleHover(S32 x, S32 y, MASK mask)
- {
- if (hasMouseCapture())
- {
- if (mMouseHoverCallback)
- {
- mMouseHoverCallback(this, mCallbackUserData);
- }
- 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);
- F32 t = F32(x - left_edge) / (right_edge - left_edge);
- setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue);
- gWindowp->setCursor(UI_CURSOR_ARROW);
- LL_DEBUGS("UserInput") << "hover handled by " << getName()
- << " (active)" << LL_ENDL;
- }
- else
- {
- gWindowp->setCursor(UI_CURSOR_ARROW);
- LL_DEBUGS("UserInput") << "hover handled by " << getName()
- << " (inactive)" << LL_ENDL;
- }
- return true;
- }
- //virtual
- bool LLSlider::handleMouseUp(S32 x, S32 y, MASK mask)
- {
- if (hasMouseCapture())
- {
- gFocusMgr.setMouseCapture(NULL);
- if (mMouseUpCallback)
- {
- mMouseUpCallback(this, mCallbackUserData);
- }
- make_ui_sound("UISndClickRelease");
- }
- return true;
- }
- //virtual
- 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
- {
- setValueAndCommit(mInitialValue);
- }
- else
- {
- // 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;
- }
- 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 = mThumbRect;
- }
- make_ui_sound("UISndClick");
- return true;
- }
- //virtual
- bool LLSlider::handleKeyHere(KEY key, MASK mask)
- {
- switch (key)
- {
- case KEY_UP:
- case KEY_DOWN:
- // Eat up and down keys to be consistent
- return true;
- case KEY_LEFT:
- setValueAndCommit(getValueF32() - getIncrement());
- return true;
- case KEY_RIGHT:
- setValueAndCommit(getValueF32() + getIncrement());
- return true;
- default:
- break;
- }
- return false;
- }
- //virtual
- void LLSlider::draw()
- {
- // Since thumb image might still be decoding, need thumb to accomodate
- // image size
- updateThumbRect();
- // Draw background and thumb.
- // Drawing solids requires texturing be disabled
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- F32 opacity = getEnabled() ? 1.f : 0.3f;
- LLColor4 center_color = LLUI::sSliderThumbCenterColor % opacity;
- // Track
- S32 half_width = mThumbImage->getWidth() / 2;
- S32 half_height = mTrackImage->getHeight() / 2;
- LLRect track_rect(half_width, getLocalRect().getCenterY() + half_height,
- getRect().getWidth() - half_width,
- getLocalRect().getCenterY() - half_height);
- LLRect highlight_rect(track_rect.mLeft, track_rect.mTop,
- mThumbRect.getCenterX(), track_rect.mBottom);
- mTrackImage->draw(track_rect);
- mTrackHighlightImage->draw(highlight_rect);
- // Thumb
- if (hasMouseCapture())
- {
- // Show ghost where thumb was before dragging began.
- mThumbImage->draw(mDragStartThumbRect,
- LLUI::sSliderThumbCenterColor % 0.3f);
- }
- if (hasFocus())
- {
- // Draw focus highlighting.
- mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor(),
- gFocusMgr.getFocusFlashWidth());
- }
- // Fill in the thumb.
- mThumbImage->draw(mThumbRect, hasMouseCapture() ?
- LLUI::sSliderThumbOutlineColor : center_color);
- LLUICtrl::draw();
- }
- LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
- const std::string& label, const LLFontGL* font,
- S32 label_width, S32 text_left, bool show_text,
- bool can_edit_text,
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_user_data, F32 initial_value,
- F32 min_value, F32 max_value, F32 increment,
- const char* control_name)
- : LLUICtrl(name, rect, true, commit_callback, callback_user_data),
- mFont(font),
- mShowText(show_text),
- mCanEditText(can_edit_text),
- mPrecision(3),
- mLabelBox(NULL),
- mLabelWidth(label_width),
- mValue(initial_value),
- mEditor(NULL),
- mTextBox(NULL),
- mTextEnabledColor(LLUI::sLabelTextColor),
- mTextDisabledColor(LLUI::sLabelDisabledColor),
- mSliderMouseUpCallback(NULL),
- mSliderMouseDownCallback(NULL)
- {
- S32 top = getRect().getHeight();
- S32 bottom = 0;
- S32 left = 0;
- // Label
- if (!label.empty())
- {
- if (label_width == 0)
- {
- label_width = font->getWidth(label);
- }
- LLRect label_rect(left, top, label_width, bottom);
- mLabelBox = new LLTextBox("SliderCtrl Label", label_rect, label, font);
- addChild(mLabelBox);
- }
- S32 slider_right = getRect().getWidth();
- if (show_text)
- {
- slider_right = text_left - SLIDERCTRL_SPACING;
- }
- S32 slider_left = label_width ? label_width + SLIDERCTRL_SPACING : 0;
- LLRect slider_rect(slider_left, top, slider_right, bottom);
- mSlider = new LLSlider(LL_SLIDER_CTRL_TAG, slider_rect,
- LLSliderCtrl::onSliderCommit, this, initial_value,
- min_value, max_value, increment, control_name);
- addChild(mSlider);
- if (show_text)
- {
- LLRect text_rect(text_left, top, getRect().getWidth(), bottom);
- if (can_edit_text)
- {
- mEditor = new LLLineEditor("SliderCtrl Editor", text_rect,
- LLStringUtil::null, font,
- MAX_SLIDER_STR_LEN,
- &LLSliderCtrl::onEditorCommit,
- NULL, NULL, this,
- &LLLineEditor::prevalidateFloat);
- mEditor->setFollowsLeft();
- mEditor->setFollowsBottom();
- mEditor->setFocusReceivedCallback(&LLSliderCtrl::onEditorGainFocus,
- this);
- mEditor->setIgnoreTab(true);
- #if 0 // Do not do this, as selecting the entire text is single clicking
- // in some cases and double clicking in others
- mEditor->setSelectAllonFocusReceived(true);
- #endif
- addChild(mEditor);
- }
- else
- {
- mTextBox = new LLTextBox("SliderCtrl Text", text_rect,
- LLStringUtil::null, font);
- mTextBox->setFollowsLeft();
- mTextBox->setFollowsBottom();
- addChild(mTextBox);
- }
- }
- updateText();
- }
- //virtual
- LLSliderCtrl::~LLSliderCtrl()
- {
- // Children all cleaned up by default view destructor.
- }
- //static
- void LLSliderCtrl::onEditorGainFocus(LLFocusableElement* caller,
- void* userdata)
- {
- LLSliderCtrl* self = (LLSliderCtrl*)userdata;
- llassert(caller == self->mEditor);
- self->onFocusReceived();
- }
- //virtual
- void LLSliderCtrl::setValue(F32 v, bool from_event)
- {
- mSlider->setValue(v, from_event);
- mValue = mSlider->getValueF32();
- updateText();
- }
- void LLSliderCtrl::setLabel(const std::string& label)
- {
- if (mLabelBox)
- {
- mLabelBox->setText(label);
- }
- }
- //virtual
- bool LLSliderCtrl::setLabelArg(const std::string& key,
- const std::string& text)
- {
- bool res = false;
- if (mLabelBox)
- {
- res = mLabelBox->setTextArg(key, text);
- if (res && mLabelWidth == 0)
- {
- S32 label_width = mFont->getWidth(mLabelBox->getText());
- LLRect rect = mLabelBox->getRect();
- S32 prev_right = rect.mRight;
- rect.mRight = rect.mLeft + label_width;
- mLabelBox->setRect(rect);
- S32 delta = rect.mRight - prev_right;
- rect = mSlider->getRect();
- S32 left = rect.mLeft + delta;
- left = llclamp(left, 0, rect.mRight - SLIDERCTRL_SPACING);
- rect.mLeft = left;
- mSlider->setRect(rect);
- }
- }
- return res;
- }
- //virtual
- void LLSliderCtrl::clear()
- {
- setValue(0.f);
- if (mEditor)
- {
- mEditor->setText(LLStringUtil::null);
- }
- if (mTextBox)
- {
- mTextBox->setText(LLStringUtil::null);
- }
- }
- void LLSliderCtrl::setOffLimit(const std::string& off_text, F32 off_value)
- {
- mDisplayOff = off_text.size() > 0;
- mOffText = off_text;
- mOffValue = off_value;
- if (mTextBox && !mEditor)
- {
- updateText();
- }
- }
- void LLSliderCtrl::updateText()
- {
- if (mEditor || mTextBox)
- {
- LLLocale locale(LLLocale::USER_LOCALE);
- // Do not display very small negative values as -0.000
- F32 displayed_value = floorf(getValueF32() *
- powf(10.f, mPrecision) + 0.5f) /
- powf(10.f, mPrecision);
- std::string format = llformat("%%.%df", mPrecision);
- std::string text = llformat(format.c_str(), displayed_value);
- if (mEditor)
- {
- mEditor->setText(text);
- }
- else if (mDisplayOff && displayed_value == mOffValue)
- {
- mTextBox->setText(mOffText);
- }
- else
- {
- mTextBox->setText(text);
- }
- }
- }
- void LLSliderCtrl::updateSliderRect()
- {
- S32 left = 0;
- S32 right = getRect().getWidth();
- S32 top = getRect().getHeight();
- S32 bottom = 0;
- if (mEditor)
- {
- LLRect editor_rect = mEditor->getRect();
- S32 editor_width = editor_rect.getWidth();
- editor_rect.mRight = right;
- editor_rect.mLeft = right - editor_width;
- mEditor->setRect(editor_rect);
- right -= editor_width + SLIDERCTRL_SPACING;
- }
- if (mTextBox)
- {
- right -= mTextBox->getRect().getWidth() + SLIDERCTRL_SPACING;
- }
- if (mLabelBox)
- {
- left += mLabelBox->getRect().getWidth() + SLIDERCTRL_SPACING;
- }
- mSlider->setRect(LLRect(left, top, right, bottom));
- }
- //static
- void LLSliderCtrl::onEditorCommit(LLUICtrl* caller, void *userdata)
- {
- LLSliderCtrl* self = (LLSliderCtrl*) userdata;
- llassert(caller == self->mEditor);
- bool success = false;
- F32 val = self->mValue;
- F32 saved_val = self->mValue;
- std::string text = self->mEditor->getText();
- if (LLLineEditor::postvalidateFloat(text))
- {
- LLLocale locale(LLLocale::USER_LOCALE);
- val = (F32) atof(text.c_str());
- if (self->mSlider->getMinValue() <= val &&
- val <= self->mSlider->getMaxValue())
- {
- if (self->mValidateCallback)
- {
- // Set the value temporarily so that the callback can retrieve
- // it:
- self->setValue(val);
- if (self->mValidateCallback(self, self->mCallbackUserData))
- {
- success = true;
- }
- }
- else
- {
- self->setValue(val);
- success = true;
- }
- }
- }
- if (success)
- {
- self->onCommit();
- }
- else
- {
- if (self->getValueF32() != saved_val)
- {
- self->setValue(saved_val);
- }
- self->reportInvalidData();
- }
- self->updateText();
- }
- //static
- void LLSliderCtrl::onSliderCommit(LLUICtrl* caller, void *userdata)
- {
- LLSliderCtrl* self = (LLSliderCtrl*)userdata;
- llassert(caller == self->mSlider);
- bool success = false;
- F32 saved_val = self->mValue;
- F32 new_val = self->mSlider->getValueF32();
- if (self->mValidateCallback)
- {
- // set the value temporarily so that the callback can retrieve it:
- self->mValue = new_val;
- if (self->mValidateCallback(self, self->mCallbackUserData))
- {
- success = true;
- }
- }
- else
- {
- self->mValue = new_val;
- success = true;
- }
- if (success)
- {
- self->onCommit();
- }
- else
- {
- if (self->mValue != saved_val)
- {
- self->setValue(saved_val);
- }
- self->reportInvalidData();
- }
- self->updateText();
- }
- //virtual
- void LLSliderCtrl::setEnabled(bool b)
- {
- LLView::setEnabled(b);
- if (mLabelBox)
- {
- mLabelBox->setColor(b ? mTextEnabledColor : mTextDisabledColor);
- }
- mSlider->setEnabled(b);
- if (mEditor)
- {
- mEditor->setEnabled(b);
- }
- if (mTextBox)
- {
- mTextBox->setColor(b ? mTextEnabledColor : mTextDisabledColor);
- }
- }
- //virtual
- void LLSliderCtrl::setTentative(bool b)
- {
- if (mEditor)
- {
- mEditor->setTentative(b);
- }
- LLUICtrl::setTentative(b);
- }
- //virtual
- void LLSliderCtrl::onCommit()
- {
- setTentative(false);
- if (mEditor)
- {
- mEditor->setTentative(false);
- }
- LLUICtrl::onCommit();
- }
- //virtual
- void LLSliderCtrl::setRect(const LLRect& rect)
- {
- LLUICtrl::setRect(rect);
- updateSliderRect();
- }
- //virtual
- void LLSliderCtrl::reshape(S32 width, S32 height, bool called_from_parent)
- {
- LLUICtrl::reshape(width, height, called_from_parent);
- updateSliderRect();
- }
- //virtual
- void LLSliderCtrl::setPrecision(S32 precision)
- {
- if (precision < 0 || precision > 10)
- {
- llerrs << "LLSliderCtrl::setPrecision - precision out of range"
- << llendl;
- return;
- }
- mPrecision = precision;
- updateText();
- }
- void LLSliderCtrl::setSliderMouseDownCallback(void (*cb)(LLUICtrl*, void*))
- {
- mSliderMouseDownCallback = cb;
- mSlider->setMouseDownCallback(LLSliderCtrl::onSliderMouseDown);
- }
- //static
- void LLSliderCtrl::onSliderMouseDown(LLUICtrl* caller, void* userdata)
- {
- LLSliderCtrl* self = (LLSliderCtrl*) userdata;
- if (self->mSliderMouseDownCallback)
- {
- self->mSliderMouseDownCallback(self, self->mCallbackUserData);
- }
- }
- void LLSliderCtrl::setSliderMouseUpCallback(void (*cb)(LLUICtrl*, void*))
- {
- mSliderMouseUpCallback = cb;
- mSlider->setMouseUpCallback(LLSliderCtrl::onSliderMouseUp);
- }
- //static
- void LLSliderCtrl::onSliderMouseUp(LLUICtrl* caller, void* userdata)
- {
- LLSliderCtrl* self = (LLSliderCtrl*) userdata;
- if (self->mSliderMouseUpCallback)
- {
- self->mSliderMouseUpCallback(self, self->mCallbackUserData);
- }
- }
- //virtual
- void LLSliderCtrl::onTabInto()
- {
- if (mEditor)
- {
- mEditor->onTabInto();
- }
- }
- void LLSliderCtrl::reportInvalidData()
- {
- make_ui_sound("UISndBadKeystroke");
- }
- //virtual
- void LLSliderCtrl::setControlName(const char* control_name, LLView* context)
- {
- LLView::setControlName(control_name, context);
- mSlider->setControlName(control_name, context);
- }
- //virtual
- const std::string& LLSliderCtrl::getTag() const
- {
- return LL_SLIDER_CTRL_TAG;
- }
- //virtual
- LLXMLNodePtr LLSliderCtrl::getXML(bool save_children) const
- {
- LLXMLNodePtr node = LLUICtrl::getXML();
- node->setName(LL_SLIDER_CTRL_TAG);
- node->createChild("show_text", true)->setBoolValue(mShowText);
- node->createChild("can_edit_text", true)->setBoolValue(mCanEditText);
- node->createChild("decimal_digits", true)->setIntValue(mPrecision);
- if (mLabelBox)
- {
- node->createChild("label", true)->setStringValue(mLabelBox->getText());
- }
- // TomY TODO: Do we really want to export the transient state of the slider?
- node->createChild("value", true)->setFloatValue(mValue);
- if (mSlider)
- {
- node->createChild("initial_val", true)->setFloatValue(mSlider->getInitialValue());
- node->createChild("min_val", true)->setFloatValue(mSlider->getMinValue());
- node->createChild("max_val", true)->setFloatValue(mSlider->getMaxValue());
- node->createChild("increment", true)->setFloatValue(mSlider->getIncrement());
- }
- addColorXML(node, mTextEnabledColor, "text_enabled_color", "LabelTextColor");
- addColorXML(node, mTextDisabledColor, "text_disabled_color", "LabelDisabledColor");
- return node;
- }
- //static
- LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView* parent,
- LLUICtrlFactory*)
- {
- std::string name = LL_SLIDER_CTRL_TAG;
- node->getAttributeString("name", name);
- std::string label;
- node->getAttributeString("label", label);
- LLRect rect;
- createRect(node, rect, parent, LLRect());
- LLFontGL* font = LLView::selectFont(node);
- // *HACK: Font might not be specified.
- if (!font)
- {
- font = LLFontGL::getFontSansSerifSmall();
- }
- S32 label_width = 0;
- node->getAttributeS32("label_width", label_width);
- bool show_text = true;
- node->getAttributeBool("show_text", show_text);
- bool can_edit_text = false;
- node->getAttributeBool("can_edit_text", can_edit_text);
- 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);
- U32 precision = 3;
- node->getAttributeU32("decimal_digits", precision);
- S32 text_left = 0;
- if (show_text)
- {
- // Calculate the size of the text box (log max_value is number of
- // digits - 1 so plus 1)
- if (max_value)
- {
- text_left = font->getWidth("0") *
- ((S32)log10f(max_value) + precision + 1);
- }
- if (increment < 1.f)
- {
- // (mostly) take account of decimal point in value
- text_left += font->getWidth(".");
- }
- if (min_value < 0.f || max_value < 0.f)
- {
- // (mostly) take account of minus sign
- text_left += font->getWidth("-");
- }
- // Padding to make things look nicer
- text_left += 8;
- }
- if (label.empty())
- {
- label.assign(node->getTextContents());
- }
- LLUICtrlCallback callback = NULL;
- LLSliderCtrl* slider =
- new LLSliderCtrl(name, rect, label, font, label_width,
- rect.getWidth() - text_left, show_text, can_edit_text,
- callback, NULL, initial_value, min_value,
- max_value, increment);
- slider->setPrecision(precision);
- slider->initFromXML(node, parent);
- slider->updateText();
- return slider;
- }
|