diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/llui/llmultisliderctrl.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2 meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz |
Second Life viewer sources 1.19.1.0
Diffstat (limited to 'linden/indra/llui/llmultisliderctrl.cpp')
-rw-r--r-- | linden/indra/llui/llmultisliderctrl.cpp | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/linden/indra/llui/llmultisliderctrl.cpp b/linden/indra/llui/llmultisliderctrl.cpp new file mode 100644 index 0000000..0d23dd7 --- /dev/null +++ b/linden/indra/llui/llmultisliderctrl.cpp | |||
@@ -0,0 +1,634 @@ | |||
1 | /** | ||
2 | * @file llmultisliderctrl.cpp | ||
3 | * @brief LLMultiSliderCtrl base class | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | #include "linden_common.h" | ||
33 | |||
34 | #include "llmultisliderctrl.h" | ||
35 | |||
36 | #include "audioengine.h" | ||
37 | #include "sound_ids.h" | ||
38 | |||
39 | #include "llmath.h" | ||
40 | #include "llfontgl.h" | ||
41 | #include "llgl.h" | ||
42 | #include "llkeyboard.h" | ||
43 | #include "lllineeditor.h" | ||
44 | #include "llmultislider.h" | ||
45 | #include "llstring.h" | ||
46 | #include "lltextbox.h" | ||
47 | #include "llui.h" | ||
48 | #include "lluiconstants.h" | ||
49 | #include "llcontrol.h" | ||
50 | #include "llfocusmgr.h" | ||
51 | #include "llresmgr.h" | ||
52 | |||
53 | const U32 MAX_STRING_LENGTH = 10; | ||
54 | |||
55 | |||
56 | LLMultiSliderCtrl::LLMultiSliderCtrl(const LLString& name, const LLRect& rect, | ||
57 | const LLString& label, | ||
58 | const LLFontGL* font, | ||
59 | S32 label_width, | ||
60 | S32 text_left, | ||
61 | BOOL show_text, | ||
62 | BOOL can_edit_text, | ||
63 | void (*commit_callback)(LLUICtrl*, void*), | ||
64 | void* callback_user_data, | ||
65 | F32 initial_value, F32 min_value, F32 max_value, F32 increment, | ||
66 | S32 max_sliders, BOOL allow_overlap, | ||
67 | BOOL draw_track, | ||
68 | BOOL use_triangle, | ||
69 | const LLString& control_which) | ||
70 | : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data ), | ||
71 | mFont(font), | ||
72 | mShowText( show_text ), | ||
73 | mCanEditText( can_edit_text ), | ||
74 | mPrecision( 3 ), | ||
75 | mLabelBox( NULL ), | ||
76 | mLabelWidth( label_width ), | ||
77 | |||
78 | mEditor( NULL ), | ||
79 | mTextBox( NULL ), | ||
80 | mTextEnabledColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ), | ||
81 | mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ), | ||
82 | mSliderMouseUpCallback( NULL ), | ||
83 | mSliderMouseDownCallback( NULL ) | ||
84 | { | ||
85 | S32 top = getRect().getHeight(); | ||
86 | S32 bottom = 0; | ||
87 | S32 left = 0; | ||
88 | |||
89 | // Label | ||
90 | if( !label.empty() ) | ||
91 | { | ||
92 | if (label_width == 0) | ||
93 | { | ||
94 | label_width = font->getWidth(label); | ||
95 | } | ||
96 | LLRect label_rect( left, top, label_width, bottom ); | ||
97 | mLabelBox = new LLTextBox( "MultiSliderCtrl Label", label_rect, label.c_str(), font ); | ||
98 | addChild(mLabelBox); | ||
99 | } | ||
100 | |||
101 | S32 slider_right = getRect().getWidth(); | ||
102 | if( show_text ) | ||
103 | { | ||
104 | slider_right = text_left - MULTI_SLIDERCTRL_SPACING; | ||
105 | } | ||
106 | |||
107 | S32 slider_left = label_width ? label_width + MULTI_SLIDERCTRL_SPACING : 0; | ||
108 | LLRect slider_rect( slider_left, top, slider_right, bottom ); | ||
109 | mMultiSlider = new LLMultiSlider( | ||
110 | "multi_slider", | ||
111 | slider_rect, | ||
112 | LLMultiSliderCtrl::onSliderCommit, this, | ||
113 | initial_value, min_value, max_value, increment, | ||
114 | max_sliders, allow_overlap, draw_track, | ||
115 | use_triangle, | ||
116 | control_which ); | ||
117 | addChild( mMultiSlider ); | ||
118 | mCurValue = mMultiSlider->getCurSliderValue(); | ||
119 | |||
120 | if( show_text ) | ||
121 | { | ||
122 | LLRect text_rect( text_left, top, getRect().getWidth(), bottom ); | ||
123 | if( can_edit_text ) | ||
124 | { | ||
125 | mEditor = new LLLineEditor( "MultiSliderCtrl Editor", text_rect, | ||
126 | "", font, | ||
127 | MAX_STRING_LENGTH, | ||
128 | &LLMultiSliderCtrl::onEditorCommit, NULL, NULL, this, | ||
129 | &LLLineEditor::prevalidateFloat ); | ||
130 | mEditor->setFollowsLeft(); | ||
131 | mEditor->setFollowsBottom(); | ||
132 | mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus ); | ||
133 | mEditor->setIgnoreTab(TRUE); | ||
134 | // don't do this, as selecting the entire text is single clicking in some cases | ||
135 | // and double clicking in others | ||
136 | //mEditor->setSelectAllonFocusReceived(TRUE); | ||
137 | addChild(mEditor); | ||
138 | } | ||
139 | else | ||
140 | { | ||
141 | mTextBox = new LLTextBox( "MultiSliderCtrl Text", text_rect, "", font); | ||
142 | mTextBox->setFollowsLeft(); | ||
143 | mTextBox->setFollowsBottom(); | ||
144 | addChild(mTextBox); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | updateText(); | ||
149 | } | ||
150 | |||
151 | LLMultiSliderCtrl::~LLMultiSliderCtrl() | ||
152 | { | ||
153 | // Children all cleaned up by default view destructor. | ||
154 | } | ||
155 | |||
156 | // static | ||
157 | void LLMultiSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata ) | ||
158 | { | ||
159 | LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; | ||
160 | llassert( caller == self->mEditor ); | ||
161 | |||
162 | self->onFocusReceived(); | ||
163 | } | ||
164 | |||
165 | |||
166 | void LLMultiSliderCtrl::setValue(const LLSD& value) | ||
167 | { | ||
168 | mMultiSlider->setValue(value); | ||
169 | mCurValue = mMultiSlider->getCurSliderValue(); | ||
170 | updateText(); | ||
171 | } | ||
172 | |||
173 | void LLMultiSliderCtrl::setSliderValue(const LLString& name, F32 v, BOOL from_event) | ||
174 | { | ||
175 | mMultiSlider->setSliderValue(name, v, from_event ); | ||
176 | mCurValue = mMultiSlider->getCurSliderValue(); | ||
177 | updateText(); | ||
178 | } | ||
179 | |||
180 | void LLMultiSliderCtrl::setCurSlider(const LLString& name) | ||
181 | { | ||
182 | mMultiSlider->setCurSlider(name); | ||
183 | mCurValue = mMultiSlider->getCurSliderValue(); | ||
184 | } | ||
185 | |||
186 | BOOL LLMultiSliderCtrl::setLabelArg( const LLString& key, const LLString& text ) | ||
187 | { | ||
188 | BOOL res = FALSE; | ||
189 | if (mLabelBox) | ||
190 | { | ||
191 | res = mLabelBox->setTextArg(key, text); | ||
192 | if (res && mLabelWidth == 0) | ||
193 | { | ||
194 | S32 label_width = mFont->getWidth(mLabelBox->getText()); | ||
195 | LLRect rect = mLabelBox->getRect(); | ||
196 | S32 prev_right = rect.mRight; | ||
197 | rect.mRight = rect.mLeft + label_width; | ||
198 | mLabelBox->setRect(rect); | ||
199 | |||
200 | S32 delta = rect.mRight - prev_right; | ||
201 | rect = mMultiSlider->getRect(); | ||
202 | S32 left = rect.mLeft + delta; | ||
203 | left = llclamp(left, 0, rect.mRight-MULTI_SLIDERCTRL_SPACING); | ||
204 | rect.mLeft = left; | ||
205 | mMultiSlider->setRect(rect); | ||
206 | } | ||
207 | } | ||
208 | return res; | ||
209 | } | ||
210 | |||
211 | const LLString& LLMultiSliderCtrl::addSlider() | ||
212 | { | ||
213 | const LLString& name = mMultiSlider->addSlider(); | ||
214 | |||
215 | // if it returns null, pass it on | ||
216 | if(name == LLString::null) { | ||
217 | return LLString::null; | ||
218 | } | ||
219 | |||
220 | // otherwise, update stuff | ||
221 | mCurValue = mMultiSlider->getCurSliderValue(); | ||
222 | updateText(); | ||
223 | return name; | ||
224 | } | ||
225 | |||
226 | const LLString& LLMultiSliderCtrl::addSlider(F32 val) | ||
227 | { | ||
228 | const LLString& name = mMultiSlider->addSlider(val); | ||
229 | |||
230 | // if it returns null, pass it on | ||
231 | if(name == LLString::null) { | ||
232 | return LLString::null; | ||
233 | } | ||
234 | |||
235 | // otherwise, update stuff | ||
236 | mCurValue = mMultiSlider->getCurSliderValue(); | ||
237 | updateText(); | ||
238 | return name; | ||
239 | } | ||
240 | |||
241 | void LLMultiSliderCtrl::deleteSlider(const LLString& name) | ||
242 | { | ||
243 | mMultiSlider->deleteSlider(name); | ||
244 | mCurValue = mMultiSlider->getCurSliderValue(); | ||
245 | updateText(); | ||
246 | } | ||
247 | |||
248 | |||
249 | void LLMultiSliderCtrl::clear() | ||
250 | { | ||
251 | setCurSliderValue(0.0f); | ||
252 | if( mEditor ) | ||
253 | { | ||
254 | mEditor->setText(LLString("")); | ||
255 | } | ||
256 | if( mTextBox ) | ||
257 | { | ||
258 | mTextBox->setText(LLString("")); | ||
259 | } | ||
260 | |||
261 | // get rid of sliders | ||
262 | mMultiSlider->clear(); | ||
263 | |||
264 | } | ||
265 | |||
266 | BOOL LLMultiSliderCtrl::isMouseHeldDown() | ||
267 | { | ||
268 | return gFocusMgr.getMouseCapture() == mMultiSlider; | ||
269 | } | ||
270 | |||
271 | void LLMultiSliderCtrl::updateText() | ||
272 | { | ||
273 | if( mEditor || mTextBox ) | ||
274 | { | ||
275 | LLLocale locale(LLLocale::USER_LOCALE); | ||
276 | |||
277 | // Don't display very small negative values as -0.000 | ||
278 | F32 displayed_value = (F32)(floor(getCurSliderValue() * pow(10.0, (F64)mPrecision) + 0.5) / pow(10.0, (F64)mPrecision)); | ||
279 | |||
280 | LLString format = llformat("%%.%df", mPrecision); | ||
281 | LLString text = llformat(format.c_str(), displayed_value); | ||
282 | if( mEditor ) | ||
283 | { | ||
284 | mEditor->setText( text ); | ||
285 | } | ||
286 | else | ||
287 | { | ||
288 | mTextBox->setText( text ); | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | |||
293 | // static | ||
294 | void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata ) | ||
295 | { | ||
296 | LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; | ||
297 | llassert( caller == self->mEditor ); | ||
298 | |||
299 | BOOL success = FALSE; | ||
300 | F32 val = self->mCurValue; | ||
301 | F32 saved_val = self->mCurValue; | ||
302 | |||
303 | LLString text = self->mEditor->getText(); | ||
304 | if( LLLineEditor::postvalidateFloat( text ) ) | ||
305 | { | ||
306 | LLLocale locale(LLLocale::USER_LOCALE); | ||
307 | val = (F32) atof( text.c_str() ); | ||
308 | if( self->mMultiSlider->getMinValue() <= val && val <= self->mMultiSlider->getMaxValue() ) | ||
309 | { | ||
310 | if( self->mValidateCallback ) | ||
311 | { | ||
312 | self->setCurSliderValue( val ); // set the value temporarily so that the callback can retrieve it. | ||
313 | if( self->mValidateCallback( self, self->mCallbackUserData ) ) | ||
314 | { | ||
315 | success = TRUE; | ||
316 | } | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | self->setCurSliderValue( val ); | ||
321 | success = TRUE; | ||
322 | } | ||
323 | } | ||
324 | } | ||
325 | |||
326 | if( success ) | ||
327 | { | ||
328 | self->onCommit(); | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | if( self->getCurSliderValue() != saved_val ) | ||
333 | { | ||
334 | self->setCurSliderValue( saved_val ); | ||
335 | } | ||
336 | self->reportInvalidData(); | ||
337 | } | ||
338 | self->updateText(); | ||
339 | } | ||
340 | |||
341 | // static | ||
342 | void LLMultiSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata ) | ||
343 | { | ||
344 | LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; | ||
345 | //llassert( caller == self->mSlider ); | ||
346 | |||
347 | BOOL success = FALSE; | ||
348 | F32 saved_val = self->mCurValue; | ||
349 | F32 new_val = self->mMultiSlider->getCurSliderValue(); | ||
350 | |||
351 | if( self->mValidateCallback ) | ||
352 | { | ||
353 | self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it. | ||
354 | if( self->mValidateCallback( self, self->mCallbackUserData ) ) | ||
355 | { | ||
356 | success = TRUE; | ||
357 | } | ||
358 | } | ||
359 | else | ||
360 | { | ||
361 | self->mCurValue = new_val; | ||
362 | success = TRUE; | ||
363 | } | ||
364 | |||
365 | if( success ) | ||
366 | { | ||
367 | self->onCommit(); | ||
368 | } | ||
369 | else | ||
370 | { | ||
371 | if( self->mCurValue != saved_val ) | ||
372 | { | ||
373 | self->setCurSliderValue( saved_val ); | ||
374 | } | ||
375 | self->reportInvalidData(); | ||
376 | } | ||
377 | self->updateText(); | ||
378 | } | ||
379 | |||
380 | void LLMultiSliderCtrl::setEnabled(BOOL b) | ||
381 | { | ||
382 | LLUICtrl::setEnabled( b ); | ||
383 | |||
384 | if( mLabelBox ) | ||
385 | { | ||
386 | mLabelBox->setColor( b ? mTextEnabledColor : mTextDisabledColor ); | ||
387 | } | ||
388 | |||
389 | mMultiSlider->setEnabled( b ); | ||
390 | |||
391 | if( mEditor ) | ||
392 | { | ||
393 | mEditor->setEnabled( b ); | ||
394 | } | ||
395 | |||
396 | if( mTextBox ) | ||
397 | { | ||
398 | mTextBox->setColor( b ? mTextEnabledColor : mTextDisabledColor ); | ||
399 | } | ||
400 | } | ||
401 | |||
402 | |||
403 | void LLMultiSliderCtrl::setTentative(BOOL b) | ||
404 | { | ||
405 | if( mEditor ) | ||
406 | { | ||
407 | mEditor->setTentative(b); | ||
408 | } | ||
409 | LLUICtrl::setTentative(b); | ||
410 | } | ||
411 | |||
412 | |||
413 | void LLMultiSliderCtrl::onCommit() | ||
414 | { | ||
415 | setTentative(FALSE); | ||
416 | |||
417 | if( mEditor ) | ||
418 | { | ||
419 | mEditor->setTentative(FALSE); | ||
420 | } | ||
421 | |||
422 | LLUICtrl::onCommit(); | ||
423 | } | ||
424 | |||
425 | |||
426 | void LLMultiSliderCtrl::setPrecision(S32 precision) | ||
427 | { | ||
428 | if (precision < 0 || precision > 10) | ||
429 | { | ||
430 | llerrs << "LLMultiSliderCtrl::setPrecision - precision out of range" << llendl; | ||
431 | return; | ||
432 | } | ||
433 | |||
434 | mPrecision = precision; | ||
435 | updateText(); | ||
436 | } | ||
437 | |||
438 | void LLMultiSliderCtrl::setSliderMouseDownCallback( void (*slider_mousedown_callback)(LLUICtrl* caller, void* userdata) ) | ||
439 | { | ||
440 | mSliderMouseDownCallback = slider_mousedown_callback; | ||
441 | mMultiSlider->setMouseDownCallback( LLMultiSliderCtrl::onSliderMouseDown ); | ||
442 | } | ||
443 | |||
444 | // static | ||
445 | void LLMultiSliderCtrl::onSliderMouseDown(LLUICtrl* caller, void* userdata) | ||
446 | { | ||
447 | LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; | ||
448 | if( self->mSliderMouseDownCallback ) | ||
449 | { | ||
450 | self->mSliderMouseDownCallback( self, self->mCallbackUserData ); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | |||
455 | void LLMultiSliderCtrl::setSliderMouseUpCallback( void (*slider_mouseup_callback)(LLUICtrl* caller, void* userdata) ) | ||
456 | { | ||
457 | mSliderMouseUpCallback = slider_mouseup_callback; | ||
458 | mMultiSlider->setMouseUpCallback( LLMultiSliderCtrl::onSliderMouseUp ); | ||
459 | } | ||
460 | |||
461 | // static | ||
462 | void LLMultiSliderCtrl::onSliderMouseUp(LLUICtrl* caller, void* userdata) | ||
463 | { | ||
464 | LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; | ||
465 | if( self->mSliderMouseUpCallback ) | ||
466 | { | ||
467 | self->mSliderMouseUpCallback( self, self->mCallbackUserData ); | ||
468 | } | ||
469 | } | ||
470 | |||
471 | void LLMultiSliderCtrl::onTabInto() | ||
472 | { | ||
473 | if( mEditor ) | ||
474 | { | ||
475 | mEditor->onTabInto(); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | void LLMultiSliderCtrl::reportInvalidData() | ||
480 | { | ||
481 | make_ui_sound("UISndBadKeystroke"); | ||
482 | } | ||
483 | |||
484 | //virtual | ||
485 | LLString LLMultiSliderCtrl::getControlName() const | ||
486 | { | ||
487 | return mMultiSlider->getControlName(); | ||
488 | } | ||
489 | |||
490 | // virtual | ||
491 | void LLMultiSliderCtrl::setControlName(const LLString& control_name, LLView* context) | ||
492 | { | ||
493 | mMultiSlider->setControlName(control_name, context); | ||
494 | } | ||
495 | |||
496 | // virtual | ||
497 | LLXMLNodePtr LLMultiSliderCtrl::getXML(bool save_children) const | ||
498 | { | ||
499 | LLXMLNodePtr node = LLUICtrl::getXML(); | ||
500 | |||
501 | node->createChild("show_text", TRUE)->setBoolValue(mShowText); | ||
502 | |||
503 | node->createChild("can_edit_text", TRUE)->setBoolValue(mCanEditText); | ||
504 | |||
505 | node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision); | ||
506 | |||
507 | if (mLabelBox) | ||
508 | { | ||
509 | node->createChild("label", TRUE)->setStringValue(mLabelBox->getText()); | ||
510 | } | ||
511 | |||
512 | // TomY TODO: Do we really want to export the transient state of the slider? | ||
513 | node->createChild("value", TRUE)->setFloatValue(mCurValue); | ||
514 | |||
515 | if (mMultiSlider) | ||
516 | { | ||
517 | node->createChild("initial_val", TRUE)->setFloatValue(mMultiSlider->getInitialValue()); | ||
518 | node->createChild("min_val", TRUE)->setFloatValue(mMultiSlider->getMinValue()); | ||
519 | node->createChild("max_val", TRUE)->setFloatValue(mMultiSlider->getMaxValue()); | ||
520 | node->createChild("increment", TRUE)->setFloatValue(mMultiSlider->getIncrement()); | ||
521 | } | ||
522 | addColorXML(node, mTextEnabledColor, "text_enabled_color", "LabelTextColor"); | ||
523 | addColorXML(node, mTextDisabledColor, "text_disabled_color", "LabelDisabledColor"); | ||
524 | |||
525 | return node; | ||
526 | } | ||
527 | |||
528 | LLView* LLMultiSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | ||
529 | { | ||
530 | LLString name("multi_slider"); | ||
531 | node->getAttributeString("name", name); | ||
532 | |||
533 | LLString label; | ||
534 | node->getAttributeString("label", label); | ||
535 | |||
536 | LLRect rect; | ||
537 | createRect(node, rect, parent, LLRect()); | ||
538 | |||
539 | LLFontGL* font = LLView::selectFont(node); | ||
540 | |||
541 | // HACK: Font might not be specified. | ||
542 | if (!font) | ||
543 | { | ||
544 | font = LLFontGL::sSansSerifSmall; | ||
545 | } | ||
546 | |||
547 | S32 label_width = 0; | ||
548 | node->getAttributeS32("label_width", label_width); | ||
549 | |||
550 | BOOL show_text = TRUE; | ||
551 | node->getAttributeBOOL("show_text", show_text); | ||
552 | |||
553 | BOOL can_edit_text = FALSE; | ||
554 | node->getAttributeBOOL("can_edit_text", can_edit_text); | ||
555 | |||
556 | BOOL allow_overlap = FALSE; | ||
557 | node->getAttributeBOOL("allow_overlap", allow_overlap); | ||
558 | |||
559 | BOOL draw_track = TRUE; | ||
560 | node->getAttributeBOOL("draw_track", draw_track); | ||
561 | |||
562 | BOOL use_triangle = FALSE; | ||
563 | node->getAttributeBOOL("use_triangle", use_triangle); | ||
564 | |||
565 | F32 initial_value = 0.f; | ||
566 | node->getAttributeF32("initial_val", initial_value); | ||
567 | |||
568 | F32 min_value = 0.f; | ||
569 | node->getAttributeF32("min_val", min_value); | ||
570 | |||
571 | F32 max_value = 1.f; | ||
572 | node->getAttributeF32("max_val", max_value); | ||
573 | |||
574 | F32 increment = 0.1f; | ||
575 | node->getAttributeF32("increment", increment); | ||
576 | |||
577 | U32 precision = 3; | ||
578 | node->getAttributeU32("decimal_digits", precision); | ||
579 | |||
580 | S32 max_sliders = 1; | ||
581 | node->getAttributeS32("max_sliders", max_sliders); | ||
582 | |||
583 | |||
584 | S32 text_left = 0; | ||
585 | if (show_text) | ||
586 | { | ||
587 | // calculate the size of the text box (log max_value is number of digits - 1 so plus 1) | ||
588 | if ( max_value ) | ||
589 | text_left = font->getWidth("0") * ( static_cast < S32 > ( log10 ( max_value ) ) + precision + 1 ); | ||
590 | |||
591 | if ( increment < 1.0f ) | ||
592 | text_left += font->getWidth("."); // (mostly) take account of decimal point in value | ||
593 | |||
594 | if ( min_value < 0.0f || max_value < 0.0f ) | ||
595 | text_left += font->getWidth("-"); // (mostly) take account of minus sign | ||
596 | |||
597 | // padding to make things look nicer | ||
598 | text_left += 8; | ||
599 | } | ||
600 | |||
601 | LLUICtrlCallback callback = NULL; | ||
602 | |||
603 | if (label.empty()) | ||
604 | { | ||
605 | label.assign(node->getTextContents()); | ||
606 | } | ||
607 | |||
608 | LLMultiSliderCtrl* slider = new LLMultiSliderCtrl(name, | ||
609 | rect, | ||
610 | label, | ||
611 | font, | ||
612 | label_width, | ||
613 | rect.getWidth() - text_left, | ||
614 | show_text, | ||
615 | can_edit_text, | ||
616 | callback, | ||
617 | NULL, | ||
618 | initial_value, | ||
619 | min_value, | ||
620 | max_value, | ||
621 | increment, | ||
622 | max_sliders, | ||
623 | allow_overlap, | ||
624 | draw_track, | ||
625 | use_triangle); | ||
626 | |||
627 | slider->setPrecision(precision); | ||
628 | |||
629 | slider->initFromXML(node, parent); | ||
630 | |||
631 | slider->updateText(); | ||
632 | |||
633 | return slider; | ||
634 | } | ||