aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:42 -0500
committerJacek Antonelli2008-08-15 23:45:42 -0500
commitce28e056c20bf2723f565bbf464b87781ec248a2 (patch)
treeef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llui
parentSecond Life viewer sources 1.19.1.4b (diff)
downloadmeta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz
Second Life viewer sources 1.20.2
Diffstat (limited to 'linden/indra/llui')
-rw-r--r--linden/indra/llui/llalertdialog.cpp58
-rw-r--r--linden/indra/llui/llalertdialog.h7
-rw-r--r--linden/indra/llui/llbutton.cpp578
-rw-r--r--linden/indra/llui/llbutton.h8
-rw-r--r--linden/indra/llui/llcheckboxctrl.cpp3
-rw-r--r--linden/indra/llui/llcheckboxctrl.h3
-rw-r--r--linden/indra/llui/llcombobox.cpp75
-rw-r--r--linden/indra/llui/llcombobox.h15
-rw-r--r--linden/indra/llui/lldraghandle.cpp26
-rw-r--r--linden/indra/llui/lldraghandle.h6
-rw-r--r--linden/indra/llui/llfloater.cpp265
-rw-r--r--linden/indra/llui/llfloater.h14
-rw-r--r--linden/indra/llui/llfocusmgr.cpp5
-rw-r--r--linden/indra/llui/llfocusmgr.h7
-rw-r--r--linden/indra/llui/llhtmlhelp.h3
-rw-r--r--linden/indra/llui/lliconctrl.cpp59
-rw-r--r--linden/indra/llui/lliconctrl.h6
-rw-r--r--linden/indra/llui/lllineeditor.cpp216
-rw-r--r--linden/indra/llui/lllineeditor.h40
-rw-r--r--linden/indra/llui/llmenugl.cpp279
-rw-r--r--linden/indra/llui/llmenugl.h50
-rw-r--r--linden/indra/llui/llmodaldialog.cpp49
-rw-r--r--linden/indra/llui/llmodaldialog.h2
-rw-r--r--linden/indra/llui/llmultislider.cpp308
-rw-r--r--linden/indra/llui/llmultislider.h4
-rw-r--r--linden/indra/llui/llmultisliderctrl.cpp2
-rw-r--r--linden/indra/llui/llmultisliderctrl.h2
-rw-r--r--linden/indra/llui/llpanel.cpp320
-rw-r--r--linden/indra/llui/llpanel.h40
-rw-r--r--linden/indra/llui/llradiogroup.cpp5
-rw-r--r--linden/indra/llui/llradiogroup.h4
-rw-r--r--linden/indra/llui/llresizebar.cpp15
-rw-r--r--linden/indra/llui/llresizebar.h3
-rw-r--r--linden/indra/llui/llresizehandle.cpp27
-rw-r--r--linden/indra/llui/llresizehandle.h5
-rw-r--r--linden/indra/llui/llresmgr.cpp2
-rw-r--r--linden/indra/llui/llresmgr.h66
-rw-r--r--linden/indra/llui/llrootview.h3
-rw-r--r--linden/indra/llui/llscrollbar.cpp191
-rw-r--r--linden/indra/llui/llscrollbar.h5
-rw-r--r--linden/indra/llui/llscrollcontainer.cpp176
-rw-r--r--linden/indra/llui/llscrollcontainer.h4
-rw-r--r--linden/indra/llui/llscrollingpanellist.cpp9
-rw-r--r--linden/indra/llui/llscrollingpanellist.h2
-rw-r--r--linden/indra/llui/llscrolllistctrl.cpp288
-rw-r--r--linden/indra/llui/llscrolllistctrl.h35
-rw-r--r--linden/indra/llui/llslider.cpp134
-rw-r--r--linden/indra/llui/llslider.h10
-rw-r--r--linden/indra/llui/llsliderctrl.cpp1
-rw-r--r--linden/indra/llui/llsliderctrl.h3
-rw-r--r--linden/indra/llui/llspinctrl.cpp22
-rw-r--r--linden/indra/llui/llspinctrl.h5
-rw-r--r--linden/indra/llui/llstyle.cpp32
-rw-r--r--linden/indra/llui/llstyle.h17
-rw-r--r--linden/indra/llui/lltabcontainer.cpp213
-rw-r--r--linden/indra/llui/lltabcontainer.h10
-rw-r--r--linden/indra/llui/lltextbox.cpp95
-rw-r--r--linden/indra/llui/lltextbox.h3
-rw-r--r--linden/indra/llui/lltexteditor.cpp166
-rw-r--r--linden/indra/llui/lltexteditor.h7
-rw-r--r--linden/indra/llui/llui.cpp175
-rw-r--r--linden/indra/llui/llui.h127
-rw-r--r--linden/indra/llui/lluictrl.cpp22
-rw-r--r--linden/indra/llui/lluictrl.h4
-rw-r--r--linden/indra/llui/lluictrlfactory.cpp301
-rw-r--r--linden/indra/llui/lluictrlfactory.h64
-rw-r--r--linden/indra/llui/llview.cpp215
-rw-r--r--linden/indra/llui/llview.h177
-rw-r--r--linden/indra/llui/llviewborder.cpp81
-rw-r--r--linden/indra/llui/llviewborder.h4
-rw-r--r--linden/indra/llui/llviewquery.cpp5
-rw-r--r--linden/indra/llui/llviewquery.h10
72 files changed, 2311 insertions, 2882 deletions
diff --git a/linden/indra/llui/llalertdialog.cpp b/linden/indra/llui/llalertdialog.cpp
index e60ef42..4ca9dc8 100644
--- a/linden/indra/llui/llalertdialog.cpp
+++ b/linden/indra/llui/llalertdialog.cpp
@@ -186,7 +186,7 @@ bool LLAlertDialog::show()
186 { 186 {
187 mOptionChosen = mDefaultOption; 187 mOptionChosen = mDefaultOption;
188 llinfos << "Alert: " << mLabel << llendl; 188 llinfos << "Alert: " << mLabel << llendl;
189 delete this; 189 close();
190 return false; 190 return false;
191 } 191 }
192 } 192 }
@@ -208,7 +208,7 @@ bool LLAlertDialog::show()
208 case IGNORE_SHOW_AGAIN: 208 case IGNORE_SHOW_AGAIN:
209 break; 209 break;
210 } 210 }
211 delete this; 211 close();
212 return false; 212 return false;
213 } 213 }
214 } 214 }
@@ -231,7 +231,7 @@ bool LLAlertDialog::show()
231 { 231 {
232 gFloaterView->bringToFront(iter->second); 232 gFloaterView->bringToFront(iter->second);
233 mUnique = FALSE; // don't remove entry from map on destruction 233 mUnique = FALSE; // don't remove entry from map on destruction
234 delete this; 234 close();
235 return false; 235 return false;
236 } 236 }
237 sUniqueActiveMap[mLabel] = this; 237 sUniqueActiveMap[mLabel] = this;
@@ -270,7 +270,7 @@ void LLAlertDialog::createDialog(const std::vector<LLString>* optionsp, S32 defa
270 setBackgroundVisible(TRUE); 270 setBackgroundVisible(TRUE);
271 setBackgroundOpaque(TRUE); 271 setBackgroundOpaque(TRUE);
272 272
273 const LLFontGL* font = gResMgr->getRes( font_name ); 273 const LLFontGL* font = LLResMgr::getInstance()->getRes( font_name );
274 const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); 274 const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
275 const S32 EDITOR_HEIGHT = 20; 275 const S32 EDITOR_HEIGHT = 20;
276 276
@@ -399,7 +399,7 @@ void LLAlertDialog::createDialog(const std::vector<LLString>* optionsp, S32 defa
399 399
400bool LLAlertDialog::setCheckBox( const LLString& check_title, const LLString& check_control ) 400bool LLAlertDialog::setCheckBox( const LLString& check_title, const LLString& check_control )
401{ 401{
402 const LLFontGL* font = gResMgr->getRes( font_name ); 402 const LLFontGL* font = LLResMgr::getInstance()->getRes( font_name );
403 const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); 403 const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
404 404
405 // Extend dialog for "check next time" 405 // Extend dialog for "check next time"
@@ -444,8 +444,23 @@ void LLAlertDialog::setVisible( BOOL visible )
444 } 444 }
445} 445}
446 446
447void LLAlertDialog::onClose(bool app_quitting)
448{
449 LLModalDialog::onClose(app_quitting);
450 handleCallbacks();
451}
452
447LLAlertDialog::~LLAlertDialog() 453LLAlertDialog::~LLAlertDialog()
448{ 454{
455 delete[] mButtonData;
456 if (mUnique)
457 {
458 sUniqueActiveMap.erase(mLabel);
459 }
460}
461
462void LLAlertDialog::handleCallbacks()
463{
449 if (mOptionChosen >= 0) 464 if (mOptionChosen >= 0)
450 { 465 {
451 if (mTextCallback && mLineEditor) 466 if (mTextCallback && mLineEditor)
@@ -465,7 +480,7 @@ LLAlertDialog::~LLAlertDialog()
465 sURLLoader->load(mURL); 480 sURLLoader->load(mURL);
466 } 481 }
467 } 482 }
468 483
469 // Only change warn state if we actually warned. 484 // Only change warn state if we actually warned.
470 if (mCheck 485 if (mCheck
471 && sSettings->getWarning(mIgnoreLabel)) 486 && sSettings->getWarning(mIgnoreLabel))
@@ -490,13 +505,7 @@ LLAlertDialog::~LLAlertDialog()
490 } 505 }
491 } 506 }
492 } 507 }
493 delete[] mButtonData;
494 if (mUnique)
495 {
496 sUniqueActiveMap.erase(mLabel);
497 }
498} 508}
499
500BOOL LLAlertDialog::hasTitleBar() const 509BOOL LLAlertDialog::hasTitleBar() const
501{ 510{
502 return (getTitle() != "" && getTitle() != " ") // has title 511 return (getTitle() != "" && getTitle() != " ") // has title
@@ -504,16 +513,11 @@ BOOL LLAlertDialog::hasTitleBar() const
504 || isCloseable(); 513 || isCloseable();
505} 514}
506 515
507BOOL LLAlertDialog::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) 516BOOL LLAlertDialog::handleKeyHere(KEY key, MASK mask )
508{ 517{
509 if( KEY_RETURN == key && mask == MASK_NONE ) 518 if( KEY_RETURN == key && mask == MASK_NONE )
510 { 519 {
511 // Warning: handleKeyHere may result in the default button 520 LLModalDialog::handleKeyHere( key, mask );
512 // being committed, which will destroy this object.
513 // Everything works, but the call stack will pass through
514 // the very end of functions that belong to deleted objects.
515 // Should find a less fragile way to do this.
516 LLModalDialog::handleKeyHere( key, mask , called_from_parent );
517 return TRUE; 521 return TRUE;
518 } 522 }
519 else if (KEY_RIGHT == key) 523 else if (KEY_RIGHT == key)
@@ -538,7 +542,7 @@ BOOL LLAlertDialog::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
538 } 542 }
539 else 543 else
540 { 544 {
541 return LLModalDialog::handleKeyHere( key, mask , called_from_parent ); 545 return LLModalDialog::handleKeyHere( key, mask );
542 } 546 }
543} 547}
544 548
@@ -551,16 +555,14 @@ void LLAlertDialog::draw()
551 mDefaultBtnTimer.stop(); // prevent this block from being run more than once 555 mDefaultBtnTimer.stop(); // prevent this block from being run more than once
552 setDefaultBtn(mButtonData[mDefaultOption].mButton); 556 setDefaultBtn(mButtonData[mDefaultOption].mButton);
553 } 557 }
554 if (getVisible())
555 {
556 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
557 S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
558 558
559 gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0, 559 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
560 shadow_color, shadow_lines); 560 S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
561 561
562 LLModalDialog::draw(); 562 gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0,
563 } 563 shadow_color, shadow_lines);
564
565 LLModalDialog::draw();
564} 566}
565 567
566void LLAlertDialog::setOptionEnabled( S32 option, BOOL enable ) 568void LLAlertDialog::setOptionEnabled( S32 option, BOOL enable )
diff --git a/linden/indra/llui/llalertdialog.h b/linden/indra/llui/llalertdialog.h
index 4978d71..8633164 100644
--- a/linden/indra/llui/llalertdialog.h
+++ b/linden/indra/llui/llalertdialog.h
@@ -68,10 +68,11 @@ public:
68 LLAlertDialog( const LLAlertDialogTemplate* xml_template, const LLString::format_map_t& args, 68 LLAlertDialog( const LLAlertDialogTemplate* xml_template, const LLString::format_map_t& args,
69 alert_callback_t callback = NULL, void *user_data = NULL); 69 alert_callback_t callback = NULL, void *user_data = NULL);
70 70
71 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ); 71 virtual BOOL handleKeyHere(KEY key, MASK mask );
72 72
73 virtual void draw(); 73 virtual void draw();
74 virtual void setVisible( BOOL visible ); 74 virtual void setVisible( BOOL visible );
75 virtual void onClose(bool app_quitting);
75 76
76 bool setCheckBox( const LLString&, const LLString& ); 77 bool setCheckBox( const LLString&, const LLString& );
77 void setOptionEnabled( S32 option, BOOL enable ); 78 void setOptionEnabled( S32 option, BOOL enable );
@@ -126,7 +127,9 @@ private:
126 const LLString& msg, const LLString::format_map_t& args, 127 const LLString& msg, const LLString::format_map_t& args,
127 const LLString& edit_text); 128 const LLString& edit_text);
128 129
129 virtual ~LLAlertDialog(); // No you can't kill it. It can only kill itself. 130 virtual ~LLAlertDialog();
131 void handleCallbacks();
132 // No you can't kill it. It can only kill itself.
130 133
131 // Does it have a readable title label, or minimize or close buttons? 134 // Does it have a readable title label, or minimize or close buttons?
132 BOOL hasTitleBar() const; 135 BOOL hasTitleBar() const;
diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp
index 4af40ff..3ada389 100644
--- a/linden/indra/llui/llbutton.cpp
+++ b/linden/indra/llui/llbutton.cpp
@@ -50,6 +50,8 @@
50#include "llwindow.h" 50#include "llwindow.h"
51#include "llglimmediate.h" 51#include "llglimmediate.h"
52 52
53static LLRegisterWidget<LLButton> r("button");
54
53// globals loaded from settings.xml 55// globals loaded from settings.xml
54S32 LLBUTTON_ORIG_H_PAD = 6; // Pre-zoomable UI 56S32 LLBUTTON_ORIG_H_PAD = 6; // Pre-zoomable UI
55S32 LLBUTTON_H_PAD = 0; 57S32 LLBUTTON_H_PAD = 0;
@@ -222,18 +224,6 @@ LLButton::~LLButton()
222 } 224 }
223} 225}
224 226
225// virtual
226EWidgetType LLButton::getWidgetType() const
227{
228 return WIDGET_TYPE_BUTTON;
229}
230
231// virtual
232LLString LLButton::getWidgetTag() const
233{
234 return LL_BUTTON_TAG;
235}
236
237// HACK: Committing a button is the same as instantly clicking it. 227// HACK: Committing a button is the same as instantly clicking it.
238// virtual 228// virtual
239void LLButton::onCommit() 229void LLButton::onCommit()
@@ -277,10 +267,11 @@ void LLButton::onCommit()
277 267
278 268
279 269
280BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) 270BOOL LLButton::handleUnicodeCharHere(llwchar uni_char)
281{ 271{
282 BOOL handled = FALSE; 272 BOOL handled = FALSE;
283 if( getVisible() && getEnabled() && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' ')) 273 if(' ' == uni_char
274 && !gKeyboard->getKeyRepeated(' '))
284 { 275 {
285 if (mIsToggle) 276 if (mIsToggle)
286 { 277 {
@@ -296,24 +287,21 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent)
296 return handled; 287 return handled;
297} 288}
298 289
299BOOL LLButton::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) 290BOOL LLButton::handleKeyHere(KEY key, MASK mask )
300{ 291{
301 BOOL handled = FALSE; 292 BOOL handled = FALSE;
302 if( getVisible() && getEnabled() && !called_from_parent ) 293 if( mCommitOnReturn && KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
303 { 294 {
304 if( mCommitOnReturn && KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key)) 295 if (mIsToggle)
305 { 296 {
306 if (mIsToggle) 297 toggleState();
307 { 298 }
308 toggleState();
309 }
310 299
311 handled = TRUE; 300 handled = TRUE;
312 301
313 if (mClickedCallback) 302 if (mClickedCallback)
314 { 303 {
315 (*mClickedCallback)( mCallbackUserData ); 304 (*mClickedCallback)( mCallbackUserData );
316 }
317 } 305 }
318 } 306 }
319 return handled; 307 return handled;
@@ -391,8 +379,6 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
391 379
392BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) 380BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
393{ 381{
394 BOOL handled = FALSE;
395
396 LLMouseHandler* other_captor = gFocusMgr.getMouseCapture(); 382 LLMouseHandler* other_captor = gFocusMgr.getMouseCapture();
397 mNeedsHighlight = other_captor == NULL || 383 mNeedsHighlight = other_captor == NULL ||
398 other_captor == this || 384 other_captor == this ||
@@ -409,358 +395,333 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
409 } 395 }
410 396
411 // We only handle the click if the click both started and ended within us 397 // We only handle the click if the click both started and ended within us
412 if( hasMouseCapture() ) 398 getWindow()->setCursor(UI_CURSOR_ARROW);
413 { 399 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
414 handled = TRUE;
415 }
416 else if( getVisible() )
417 {
418 // Opaque
419 handled = TRUE;
420 }
421 400
422 if( handled ) 401 return TRUE;
423 {
424 getWindow()->setCursor(UI_CURSOR_ARROW);
425 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
426 }
427
428 return handled;
429} 402}
430 403
431 404
432// virtual 405// virtual
433void LLButton::draw() 406void LLButton::draw()
434{ 407{
435 if( getVisible() ) 408 BOOL flash = FALSE;
409 if( mFlashing )
436 { 410 {
437 BOOL flash = FALSE; 411 F32 elapsed = mFlashingTimer.getElapsedTimeF32();
438 if( mFlashing ) 412 S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f);
439 { 413 // flash on or off?
440 F32 elapsed = mFlashingTimer.getElapsedTimeF32(); 414 flash = (flash_count % 2 == 0) || flash_count > S32((F32)LLUI::sConfigGroup->getS32("ButtonFlashCount") * 2.f);
441 S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f); 415 }
442 // flash on or off?
443 flash = (flash_count % 2 == 0) || flash_count > (F32)LLUI::sConfigGroup->getS32("ButtonFlashCount");
444 }
445 416
446 BOOL pressed_by_keyboard = FALSE; 417 BOOL pressed_by_keyboard = FALSE;
447 if (hasFocus()) 418 if (hasFocus())
448 { 419 {
449 pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN)); 420 pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN));
450 } 421 }
451 422
452 // Unselected image assignments 423 // Unselected image assignments
453 S32 local_mouse_x; 424 S32 local_mouse_x;
454 S32 local_mouse_y; 425 S32 local_mouse_y;
455 LLCoordWindow cursor_pos_window; 426 LLCoordWindow cursor_pos_window;
456 getWindow()->getCursorPosition(&cursor_pos_window); 427 getWindow()->getCursorPosition(&cursor_pos_window);
457 LLCoordGL cursor_pos_gl; 428 LLCoordGL cursor_pos_gl;
458 getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl); 429 getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
459 cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]); 430 cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
460 cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]); 431 cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
461 screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); 432 screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
462 433
463 BOOL pressed = pressed_by_keyboard 434 BOOL pressed = pressed_by_keyboard
464 || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) 435 || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y))
465 || mToggleState; 436 || mToggleState;
466 437
467 BOOL use_glow_effect = FALSE; 438 BOOL use_glow_effect = FALSE;
468 if ( mNeedsHighlight || flash ) 439 if ( mNeedsHighlight || flash )
440 {
441 if (pressed)
469 { 442 {
470 if (pressed) 443 if (mImageHoverSelected)
471 { 444 {
472 if (mImageHoverSelected) 445 mImagep = mImageHoverSelected;
473 {
474 mImagep = mImageHoverSelected;
475 }
476 else
477 {
478 mImagep = mImageSelected;
479 use_glow_effect = TRUE;
480 }
481 } 446 }
482 else 447 else
483 { 448 {
484 if (mImageHoverUnselected) 449 mImagep = mImageSelected;
485 { 450 use_glow_effect = TRUE;
486 mImagep = mImageHoverUnselected;
487 }
488 else
489 {
490 mImagep = mImageUnselected;
491 use_glow_effect = TRUE;
492 }
493 } 451 }
494 } 452 }
495 else if ( pressed )
496 {
497 mImagep = mImageSelected;
498 }
499 else 453 else
500 { 454 {
501 mImagep = mImageUnselected; 455 if (mImageHoverUnselected)
456 {
457 mImagep = mImageHoverUnselected;
458 }
459 else
460 {
461 mImagep = mImageUnselected;
462 use_glow_effect = TRUE;
463 }
502 } 464 }
465 }
466 else if ( pressed )
467 {
468 mImagep = mImageSelected;
469 }
470 else
471 {
472 mImagep = mImageUnselected;
473 }
503 474
504 // Override if more data is available 475 // Override if more data is available
505 // HACK: Use gray checked state to mean either: 476 // HACK: Use gray checked state to mean either:
506 // enabled and tentative 477 // enabled and tentative
507 // or 478 // or
508 // disabled but checked 479 // disabled but checked
509 if (!mImageDisabledSelected.isNull() && ( (getEnabled() && getTentative()) || (!getEnabled() && pressed ) ) ) 480 if (!mImageDisabledSelected.isNull()
510 { 481 &&
511 mImagep = mImageDisabledSelected; 482 ( (getEnabled() && getTentative())
512 } 483 || (!getEnabled() && pressed ) ) )
513 else if (!mImageDisabled.isNull() && !getEnabled() && !pressed) 484 {
514 { 485 mImagep = mImageDisabledSelected;
515 mImagep = mImageDisabled; 486 }
516 } 487 else if (!mImageDisabled.isNull()
488 && !getEnabled()
489 && !pressed)
490 {
491 mImagep = mImageDisabled;
492 }
517 493
518 if (mNeedsHighlight && !mImagep) 494 if (mNeedsHighlight && !mImagep)
519 { 495 {
520 use_glow_effect = TRUE; 496 use_glow_effect = TRUE;
521 } 497 }
522 498
523 // Figure out appropriate color for the text 499 // Figure out appropriate color for the text
524 LLColor4 label_color; 500 LLColor4 label_color;
525 501
526 // label changes when button state changes, not when pressed 502 // label changes when button state changes, not when pressed
527 if ( getEnabled() ) 503 if ( getEnabled() )
504 {
505 if ( mToggleState )
528 { 506 {
529 if ( mToggleState ) 507 label_color = mSelectedLabelColor;
530 {
531 label_color = mSelectedLabelColor;
532 }
533 else
534 {
535 label_color = mUnselectedLabelColor;
536 }
537 } 508 }
538 else 509 else
539 { 510 {
540 if ( mToggleState ) 511 label_color = mUnselectedLabelColor;
541 {
542 label_color = mDisabledSelectedLabelColor;
543 }
544 else
545 {
546 label_color = mDisabledLabelColor;
547 }
548 } 512 }
549 513 }
550 // Unselected label assignments 514 else
551 LLWString label; 515 {
552 516 if ( mToggleState )
553 if( mToggleState )
554 { 517 {
555 if( getEnabled() || mDisabledSelectedLabel.empty() ) 518 label_color = mDisabledSelectedLabelColor;
556 {
557 label = mSelectedLabel;
558 }
559 else
560 {
561 label = mDisabledSelectedLabel;
562 }
563 } 519 }
564 else 520 else
565 { 521 {
566 if( getEnabled() || mDisabledLabel.empty() ) 522 label_color = mDisabledLabelColor;
567 {
568 label = mUnselectedLabel;
569 }
570 else
571 {
572 label = mDisabledLabel;
573 }
574 } 523 }
575 524 }
576 // draw default button border 525
577 if (getEnabled() && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel 526 // Unselected label assignments
527 LLWString label;
528
529 if( mToggleState )
530 {
531 if( getEnabled() || mDisabledSelectedLabel.empty() )
578 { 532 {
579 drawBorder(LLUI::sColorsGroup->getColor( "ButtonBorderColor" ), BORDER_SIZE); 533 label = mSelectedLabel;
580 } 534 }
581 535 else
582 // overlay with keyboard focus border
583 if (hasFocus())
584 { 536 {
585 F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); 537 label = mDisabledSelectedLabel;
586 drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
587 } 538 }
588 539 }
589 if (use_glow_effect) 540 else
541 {
542 if( getEnabled() || mDisabledLabel.empty() )
590 { 543 {
591 mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f)); 544 label = mUnselectedLabel;
592 } 545 }
593 else 546 else
594 { 547 {
595 mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f)); 548 label = mDisabledLabel;
596 } 549 }
550 }
597 551
598 // Draw button image, if available. 552 // overlay with keyboard focus border
599 // Otherwise draw basic rectangular button. 553 if (hasFocus())
600 if( mImagep.notNull() && !mScaleImage) 554 {
555 F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
556 drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
557 }
558
559 if (use_glow_effect)
560 {
561 mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
562 }
563 else
564 {
565 mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
566 }
567
568 // Draw button image, if available.
569 // Otherwise draw basic rectangular button.
570 if (mImagep.notNull())
571 {
572 if ( mScaleImage)
601 { 573 {
602 mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor ); 574 mImagep->draw(getLocalRect(), getEnabled() ? mImageColor : mDisabledImageColor );
603 if (mCurGlowStrength > 0.01f) 575 if (mCurGlowStrength > 0.01f)
604 { 576 {
605 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); 577 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
606 mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); 578 mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
607 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 579 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
608 } 580 }
609 } 581 }
610 else 582 else
611 if ( mImagep.notNull() && mScaleImage)
612 { 583 {
613 mImagep->draw(0, 0, getRect().getWidth(), getRect().getHeight(), getEnabled() ? mImageColor : mDisabledImageColor ); 584 mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor );
614 if (mCurGlowStrength > 0.01f) 585 if (mCurGlowStrength > 0.01f)
615 { 586 {
616 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); 587 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
617 mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); 588 mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
618 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 589 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
619 } 590 }
620 } 591 }
621 else 592 }
622 { 593 else
623 // no image 594 {
624 llwarns << "No image for button " << getName() << llendl; 595 // no image
625 // draw it in pink so we can find it 596 llwarns << "No image for button " << getName() << llendl;
626 gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE); 597 // draw it in pink so we can find it
627 } 598 gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE);
628 599 }
629 // let overlay image and text play well together
630 S32 text_left = mLeftHPad;
631 S32 text_right = getRect().getWidth() - mRightHPad;
632 S32 text_width = getRect().getWidth() - mLeftHPad - mRightHPad;
633
634 // draw overlay image
635 if (mImageOverlay.notNull())
636 {
637 // get max width and height (discard level 0)
638 S32 overlay_width = mImageOverlay->getWidth();
639 S32 overlay_height = mImageOverlay->getHeight();
640 600
641 F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f); 601 // let overlay image and text play well together
642 overlay_width = llround((F32)overlay_width * scale_factor); 602 S32 text_left = mLeftHPad;
643 overlay_height = llround((F32)overlay_height * scale_factor); 603 S32 text_right = getRect().getWidth() - mRightHPad;
604 S32 text_width = getRect().getWidth() - mLeftHPad - mRightHPad;
644 605
645 S32 center_x = getLocalRect().getCenterX(); 606 // draw overlay image
646 S32 center_y = getLocalRect().getCenterY(); 607 if (mImageOverlay.notNull())
608 {
609 // get max width and height (discard level 0)
610 S32 overlay_width = mImageOverlay->getWidth();
611 S32 overlay_height = mImageOverlay->getHeight();
647 612
648 //FUGLY HACK FOR "DEPRESSED" BUTTONS 613 F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
649 if (pressed) 614 overlay_width = llround((F32)overlay_width * scale_factor);
650 { 615 overlay_height = llround((F32)overlay_height * scale_factor);
651 center_y--;
652 center_x++;
653 }
654 616
655 // fade out overlay images on disabled buttons 617 S32 center_x = getLocalRect().getCenterX();
656 LLColor4 overlay_color = mImageOverlayColor; 618 S32 center_y = getLocalRect().getCenterY();
657 if (!getEnabled())
658 {
659 overlay_color.mV[VALPHA] = 0.5f;
660 }
661 619
662 switch(mImageOverlayAlignment) 620 //FUGLY HACK FOR "DEPRESSED" BUTTONS
663 { 621 if (pressed)
664 case LLFontGL::LEFT: 622 {
665 text_left += overlay_width + 1; 623 center_y--;
666 text_width -= overlay_width + 1; 624 center_x++;
667 mImageOverlay->draw(
668 mLeftHPad,
669 center_y - (overlay_height / 2),
670 overlay_width,
671 overlay_height,
672 overlay_color);
673 break;
674 case LLFontGL::HCENTER:
675 mImageOverlay->draw(
676 center_x - (overlay_width / 2),
677 center_y - (overlay_height / 2),
678 overlay_width,
679 overlay_height,
680 overlay_color);
681 break;
682 case LLFontGL::RIGHT:
683 text_right -= overlay_width + 1;
684 text_width -= overlay_width + 1;
685 mImageOverlay->draw(
686 getRect().getWidth() - mRightHPad - overlay_width,
687 center_y - (overlay_height / 2),
688 overlay_width,
689 overlay_height,
690 overlay_color);
691 break;
692 default:
693 // draw nothing
694 break;
695 }
696 } 625 }
697 626
698 // Draw label 627 // fade out overlay images on disabled buttons
699 if( !label.empty() ) 628 LLColor4 overlay_color = mImageOverlayColor;
629 if (!getEnabled())
700 { 630 {
701 LLWString::trim(label); 631 overlay_color.mV[VALPHA] = 0.5f;
632 }
702 633
703 S32 x; 634 switch(mImageOverlayAlignment)
704 switch( mHAlign ) 635 {
705 { 636 case LLFontGL::LEFT:
706 case LLFontGL::RIGHT: 637 text_left += overlay_width + 1;
707 x = text_right; 638 text_width -= overlay_width + 1;
708 break; 639 mImageOverlay->draw(
709 case LLFontGL::HCENTER: 640 mLeftHPad,
710 x = getRect().getWidth() / 2; 641 center_y - (overlay_height / 2),
711 break; 642 overlay_width,
712 case LLFontGL::LEFT: 643 overlay_height,
713 default: 644 overlay_color);
714 x = text_left; 645 break;
715 break; 646 case LLFontGL::HCENTER:
716 } 647 mImageOverlay->draw(
648 center_x - (overlay_width / 2),
649 center_y - (overlay_height / 2),
650 overlay_width,
651 overlay_height,
652 overlay_color);
653 break;
654 case LLFontGL::RIGHT:
655 text_right -= overlay_width + 1;
656 text_width -= overlay_width + 1;
657 mImageOverlay->draw(
658 getRect().getWidth() - mRightHPad - overlay_width,
659 center_y - (overlay_height / 2),
660 overlay_width,
661 overlay_height,
662 overlay_color);
663 break;
664 default:
665 // draw nothing
666 break;
667 }
668 }
717 669
718 S32 y_offset = 2 + (getRect().getHeight() - 20)/2; 670 // Draw label
719 671 if( !label.empty() )
720 if (pressed) 672 {
721 { 673 LLWString::trim(label);
722 y_offset--;
723 x++;
724 }
725 674
726 mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset), 675 S32 x;
727 label_color, 676 switch( mHAlign )
728 mHAlign, LLFontGL::BOTTOM, 677 {
729 mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL, 678 case LLFontGL::RIGHT:
730 U32_MAX, text_width, 679 x = text_right;
731 NULL, FALSE, FALSE); 680 break;
681 case LLFontGL::HCENTER:
682 x = getRect().getWidth() / 2;
683 break;
684 case LLFontGL::LEFT:
685 default:
686 x = text_left;
687 break;
732 } 688 }
733 689
734 if (sDebugRects 690 S32 y_offset = 2 + (getRect().getHeight() - 20)/2;
735 || (LLView::sEditingUI && this == LLView::sEditingUIView)) 691
692 if (pressed)
736 { 693 {
737 drawDebugRect(); 694 y_offset--;
695 x++;
738 } 696 }
697
698 mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset),
699 label_color,
700 mHAlign, LLFontGL::BOTTOM,
701 mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL,
702 U32_MAX, text_width,
703 NULL, FALSE, FALSE);
739 } 704 }
705
706 if (sDebugRects
707 || (LLView::sEditingUI && this == LLView::sEditingUIView))
708 {
709 drawDebugRect();
710 }
711
740 // reset hover status for next frame 712 // reset hover status for next frame
741 mNeedsHighlight = FALSE; 713 mNeedsHighlight = FALSE;
742} 714}
743 715
744void LLButton::drawBorder(const LLColor4& color, S32 size) 716void LLButton::drawBorder(const LLColor4& color, S32 size)
745{ 717{
746 S32 left = -size;
747 S32 top = getRect().getHeight() + size;
748 S32 right = getRect().getWidth() + size;
749 S32 bottom = -size;
750
751 if (mImagep.isNull())
752 {
753 gl_rect_2d(left, top, right, bottom, color, FALSE);
754 return;
755 }
756
757 if (mScaleImage) 718 if (mScaleImage)
758 { 719 {
759 mImagep->drawSolid(left, bottom, right-left, top-bottom, color); 720 mImagep->drawBorder(getLocalRect(), color, size);
760 } 721 }
761 else 722 else
762 { 723 {
763 mImagep->drawSolid(left, bottom, mImagep->getWidth() + size * 2, mImagep->getHeight() + size * 2, color); 724 mImagep->drawBorder(0, 0, color, size);
764 } 725 }
765} 726}
766 727
@@ -778,9 +739,8 @@ void LLButton::setToggleState(BOOL b)
778{ 739{
779 if( b != mToggleState ) 740 if( b != mToggleState )
780 { 741 {
781 mToggleState = b; 742 setControlValue(b); // will fire LLControlVariable callbacks (if any)
782 LLValueChangedEvent *evt = new LLValueChangedEvent(this, mToggleState); 743 mToggleState = b; // may or may not be redundant
783 fireEvent(evt, "");
784 } 744 }
785} 745}
786 746
@@ -924,7 +884,7 @@ void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alig
924 } 884 }
925 else 885 else
926 { 886 {
927 mImageOverlay = LLUI::getUIImageByName(image_name); 887 mImageOverlay = LLUI::getUIImage(image_name);
928 mImageOverlayAlignment = alignment; 888 mImageOverlayAlignment = alignment;
929 mImageOverlayColor = color; 889 mImageOverlayColor = color;
930 } 890 }
@@ -957,37 +917,37 @@ S32 round_up(S32 grid, S32 value)
957 917
958void LLButton::setImageUnselected(const LLString &image_name) 918void LLButton::setImageUnselected(const LLString &image_name)
959{ 919{
960 setImageUnselected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); 920 setImageUnselected(LLUI::getUIImage(image_name));
961 mImageUnselectedName = image_name; 921 mImageUnselectedName = image_name;
962} 922}
963 923
964void LLButton::setImageSelected(const LLString &image_name) 924void LLButton::setImageSelected(const LLString &image_name)
965{ 925{
966 setImageSelected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); 926 setImageSelected(LLUI::getUIImage(image_name));
967 mImageSelectedName = image_name; 927 mImageSelectedName = image_name;
968} 928}
969 929
970void LLButton::setImageHoverSelected(const LLString &image_name) 930void LLButton::setImageHoverSelected(const LLString &image_name)
971{ 931{
972 setImageHoverSelected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); 932 setImageHoverSelected(LLUI::getUIImage(image_name));
973 mImageHoverSelectedName = image_name; 933 mImageHoverSelectedName = image_name;
974} 934}
975 935
976void LLButton::setImageHoverUnselected(const LLString &image_name) 936void LLButton::setImageHoverUnselected(const LLString &image_name)
977{ 937{
978 setImageHoverUnselected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); 938 setImageHoverUnselected(LLUI::getUIImage(image_name));
979 mImageHoverUnselectedName = image_name; 939 mImageHoverUnselectedName = image_name;
980} 940}
981 941
982void LLButton::setImageDisabled(const LLString &image_name) 942void LLButton::setImageDisabled(const LLString &image_name)
983{ 943{
984 setImageDisabled(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); 944 setImageDisabled(LLUI::getUIImage(image_name));
985 mImageDisabledName = image_name; 945 mImageDisabledName = image_name;
986} 946}
987 947
988void LLButton::setImageDisabledSelected(const LLString &image_name) 948void LLButton::setImageDisabledSelected(const LLString &image_name)
989{ 949{
990 setImageDisabledSelected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); 950 setImageDisabledSelected(LLUI::getUIImage(image_name));
991 mImageDisabledSelectedName = image_name; 951 mImageDisabledSelectedName = image_name;
992} 952}
993 953
@@ -1038,7 +998,7 @@ void clicked_help(void* data)
1038 return; 998 return;
1039 } 999 }
1040 1000
1041 LLUI::sHtmlHelp->show(self->getHelpURL(), ""); 1001 LLUI::sHtmlHelp->show(self->getHelpURL());
1042} 1002}
1043 1003
1044// static 1004// static
diff --git a/linden/indra/llui/llbutton.h b/linden/indra/llui/llbutton.h
index 18f4e07..a101a3c 100644
--- a/linden/indra/llui/llbutton.h
+++ b/linden/indra/llui/llbutton.h
@@ -87,16 +87,15 @@ public:
87 87
88 virtual ~LLButton(); 88 virtual ~LLButton();
89 void init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const LLString& control_name); 89 void init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const LLString& control_name);
90 virtual EWidgetType getWidgetType() const; 90
91 virtual LLString getWidgetTag() const;
92 91
93 void addImageAttributeToXML(LLXMLNodePtr node, const LLString& imageName, 92 void addImageAttributeToXML(LLXMLNodePtr node, const LLString& imageName,
94 const LLUUID& imageID,const LLString& xmlTagName) const; 93 const LLUUID& imageID,const LLString& xmlTagName) const;
95 virtual LLXMLNodePtr getXML(bool save_children = true) const; 94 virtual LLXMLNodePtr getXML(bool save_children = true) const;
96 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 95 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
97 96
98 virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); 97 virtual BOOL handleUnicodeCharHere(llwchar uni_char);
99 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 98 virtual BOOL handleKeyHere(KEY key, MASK mask);
100 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 99 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
101 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); 100 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
102 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 101 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
@@ -104,7 +103,6 @@ public:
104 103
105 virtual void onMouseCaptureLost(); 104 virtual void onMouseCaptureLost();
106 105
107 // HACK: "committing" a button is the same as clicking on it.
108 virtual void onCommit(); 106 virtual void onCommit();
109 107
110 void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; } 108 void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; }
diff --git a/linden/indra/llui/llcheckboxctrl.cpp b/linden/indra/llui/llcheckboxctrl.cpp
index ecb6342..33de4da 100644
--- a/linden/indra/llui/llcheckboxctrl.cpp
+++ b/linden/indra/llui/llcheckboxctrl.cpp
@@ -45,10 +45,11 @@
45#include "llfontgl.h" 45#include "llfontgl.h"
46#include "lltextbox.h" 46#include "lltextbox.h"
47#include "llkeyboard.h" 47#include "llkeyboard.h"
48#include "llviewborder.h"
49 48
50const U32 MAX_STRING_LENGTH = 10; 49const U32 MAX_STRING_LENGTH = 10;
51 50
51static LLRegisterWidget<LLCheckBoxCtrl> r("check_box");
52
52 53
53LLCheckBoxCtrl::LLCheckBoxCtrl(const LLString& name, const LLRect& rect, 54LLCheckBoxCtrl::LLCheckBoxCtrl(const LLString& name, const LLRect& rect,
54 const LLString& label, 55 const LLString& label,
diff --git a/linden/indra/llui/llcheckboxctrl.h b/linden/indra/llui/llcheckboxctrl.h
index 6df0e77..6518272 100644
--- a/linden/indra/llui/llcheckboxctrl.h
+++ b/linden/indra/llui/llcheckboxctrl.h
@@ -75,8 +75,7 @@ public:
75 virtual ~LLCheckBoxCtrl(); 75 virtual ~LLCheckBoxCtrl();
76 76
77 // LLView interface 77 // LLView interface
78 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_CHECKBOX; } 78
79 virtual LLString getWidgetTag() const { return LL_CHECK_BOX_CTRL_TAG; }
80 virtual LLXMLNodePtr getXML(bool save_children = true) const; 79 virtual LLXMLNodePtr getXML(bool save_children = true) const;
81 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 80 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
82 81
diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp
index c486042..0523a11 100644
--- a/linden/indra/llui/llcombobox.cpp
+++ b/linden/indra/llui/llcombobox.cpp
@@ -57,6 +57,8 @@ S32 LLCOMBOBOX_HEIGHT = 0;
57S32 LLCOMBOBOX_WIDTH = 0; 57S32 LLCOMBOBOX_WIDTH = 0;
58S32 MAX_COMBO_WIDTH = 500; 58S32 MAX_COMBO_WIDTH = 500;
59 59
60static LLRegisterWidget<LLComboBox> r1("combo_box");
61
60LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString& label, 62LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString& label,
61 void (*commit_callback)(LLUICtrl*,void*), 63 void (*commit_callback)(LLUICtrl*,void*),
62 void *callback_userdata 64 void *callback_userdata
@@ -74,9 +76,10 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString
74{ 76{
75 // Always use text box 77 // Always use text box
76 // Text label button 78 // Text label button
77 mButton = new LLButton("comboxbox button", 79 mButton = new LLButton(label,
78 LLRect(), label, NULL, LLString::null, 80 LLRect(),
79 NULL, this); 81 LLString::null,
82 NULL, this);
80 mButton->setImageUnselected("square_btn_32x128.tga"); 83 mButton->setImageUnselected("square_btn_32x128.tga");
81 mButton->setImageSelected("square_btn_selected_32x128.tga"); 84 mButton->setImageSelected("square_btn_selected_32x128.tga");
82 mButton->setImageDisabled("square_btn_32x128.tga"); 85 mButton->setImageDisabled("square_btn_32x128.tga");
@@ -99,13 +102,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString
99 mList->setCommitOnKeyboardMovement(FALSE); 102 mList->setCommitOnKeyboardMovement(FALSE);
100 addChild(mList); 103 addChild(mList);
101 104
102 LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0); 105 mArrowImage = LLUI::sImageProvider->getUIImage("combobox_arrow.tga");
103 mBorder = new LLViewBorder( "combo border", border_rect );
104 addChild( mBorder );
105 mBorder->setFollowsAll();
106
107 LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") );
108 mArrowImage = LLUI::sImageProvider->getImageByID(arrow_image_id);
109 mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT); 106 mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT);
110 107
111 updateLayout(); 108 updateLayout();
@@ -447,7 +444,7 @@ void LLComboBox::setButtonVisible(BOOL visible)
447 LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); 444 LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
448 if (visible) 445 if (visible)
449 { 446 {
450 text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); 447 text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton");
451 } 448 }
452 //mTextEntry->setRect(text_entry_rect); 449 //mTextEntry->setRect(text_entry_rect);
453 mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); 450 mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
@@ -456,15 +453,10 @@ void LLComboBox::setButtonVisible(BOOL visible)
456 453
457void LLComboBox::draw() 454void LLComboBox::draw()
458{ 455{
459 if( getVisible() ) 456 mButton->setEnabled(getEnabled() /*&& !mList->isEmpty()*/);
460 {
461 mBorder->setKeyboardFocusHighlight(hasFocus());
462
463 mButton->setEnabled(getEnabled() /*&& !mList->isEmpty()*/);
464 457
465 // Draw children normally 458 // Draw children normally
466 LLUICtrl::draw(); 459 LLUICtrl::draw();
467 }
468} 460}
469 461
470BOOL LLComboBox::setCurrentByIndex( S32 index ) 462BOOL LLComboBox::setCurrentByIndex( S32 index )
@@ -494,14 +486,14 @@ void LLComboBox::updateLayout()
494 if (mAllowTextEntry) 486 if (mAllowTextEntry)
495 { 487 {
496 S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); 488 S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton");
497 mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth(0)) - 2 * shadow_size, 489 mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size,
498 rect.mTop, rect.mRight, rect.mBottom)); 490 rect.mTop, rect.mRight, rect.mBottom));
499 mButton->setTabStop(FALSE); 491 mButton->setTabStop(FALSE);
500 492
501 if (!mTextEntry) 493 if (!mTextEntry)
502 { 494 {
503 LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); 495 LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
504 text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); 496 text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton");
505 // clear label on button 497 // clear label on button
506 LLString cur_label = mButton->getLabelSelected(); 498 LLString cur_label = mButton->getLabelSelected();
507 mTextEntry = new LLLineEditor("combo_text_entry", 499 mTextEntry = new LLLineEditor("combo_text_entry",
@@ -512,11 +504,7 @@ void LLComboBox::updateLayout()
512 onTextCommit, 504 onTextCommit,
513 onTextEntry, 505 onTextEntry,
514 NULL, 506 NULL,
515 this, 507 this);
516 NULL, // prevalidate func
517 LLViewBorder::BEVEL_NONE,
518 LLViewBorder::STYLE_LINE,
519 0); // no border
520 mTextEntry->setSelectAllonFocusReceived(TRUE); 508 mTextEntry->setSelectAllonFocusReceived(TRUE);
521 mTextEntry->setHandleEditKeysDirectly(TRUE); 509 mTextEntry->setHandleEditKeysDirectly(TRUE);
522 mTextEntry->setCommitOnFocusLost(FALSE); 510 mTextEntry->setCommitOnFocusLost(FALSE);
@@ -761,7 +749,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_
761 tool_tip = getToolTip(); 749 tool_tip = getToolTip();
762 if (tool_tip.empty()) 750 if (tool_tip.empty())
763 { 751 {
764 tool_tip = getValue().asString(); 752 tool_tip = getSelectedItemLabel();
765 } 753 }
766 } 754 }
767 755
@@ -780,10 +768,10 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_
780 return TRUE; 768 return TRUE;
781} 769}
782 770
783BOOL LLComboBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 771BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
784{ 772{
785 BOOL result = FALSE; 773 BOOL result = FALSE;
786 if (gFocusMgr.childHasKeyboardFocus(this)) 774 if (hasFocus())
787 { 775 {
788 //give list a chance to pop up and handle key 776 //give list a chance to pop up and handle key
789 LLScrollListItem* last_selected_item = mList->getLastSelectedItem(); 777 LLScrollListItem* last_selected_item = mList->getLastSelectedItem();
@@ -792,7 +780,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
792 // highlight the original selection before potentially selecting a new item 780 // highlight the original selection before potentially selecting a new item
793 mList->highlightNthItem(mList->getItemIndex(last_selected_item)); 781 mList->highlightNthItem(mList->getItemIndex(last_selected_item));
794 } 782 }
795 result = mList->handleKeyHere(key, mask, FALSE); 783 result = mList->handleKeyHere(key, mask);
796 // if selection has changed, pop open list 784 // if selection has changed, pop open list
797 if (mList->getLastSelectedItem() != last_selected_item) 785 if (mList->getLastSelectedItem() != last_selected_item)
798 { 786 {
@@ -802,7 +790,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
802 return result; 790 return result;
803} 791}
804 792
805BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) 793BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char)
806{ 794{
807 BOOL result = FALSE; 795 BOOL result = FALSE;
808 if (gFocusMgr.childHasKeyboardFocus(this)) 796 if (gFocusMgr.childHasKeyboardFocus(this))
@@ -816,7 +804,7 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent
816 // highlight the original selection before potentially selecting a new item 804 // highlight the original selection before potentially selecting a new item
817 mList->highlightNthItem(mList->getItemIndex(last_selected_item)); 805 mList->highlightNthItem(mList->getItemIndex(last_selected_item));
818 } 806 }
819 result = mList->handleUnicodeCharHere(uni_char, called_from_parent); 807 result = mList->handleUnicodeCharHere(uni_char);
820 if (mList->getLastSelectedItem() != last_selected_item) 808 if (mList->getLastSelectedItem() != last_selected_item)
821 { 809 {
822 showList(); 810 showList();
@@ -1095,6 +1083,8 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
1095// LLFlyoutButton 1083// LLFlyoutButton
1096// 1084//
1097 1085
1086static LLRegisterWidget<LLFlyoutButton> r2("flyout_button");
1087
1098const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; 1088const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24;
1099 1089
1100LLFlyoutButton::LLFlyoutButton( 1090LLFlyoutButton::LLFlyoutButton(
@@ -1109,9 +1099,8 @@ LLFlyoutButton::LLFlyoutButton(
1109{ 1099{
1110 // Always use text box 1100 // Always use text box
1111 // Text label button 1101 // Text label button
1112 mActionButton = new LLButton("flyout_button_main", 1102 mActionButton = new LLButton(label,
1113 LLRect(), label, NULL, LLString::null, 1103 LLRect(), LLString::null, NULL, this);
1114 NULL, this);
1115 mActionButton->setScaleImage(TRUE); 1104 mActionButton->setScaleImage(TRUE);
1116 1105
1117 mActionButton->setClickedCallback(onActionButtonClick); 1106 mActionButton->setClickedCallback(onActionButtonClick);
@@ -1120,24 +1109,24 @@ LLFlyoutButton::LLFlyoutButton(
1120 mActionButton->setLabel(label); 1109 mActionButton->setLabel(label);
1121 addChild(mActionButton); 1110 addChild(mActionButton);
1122 1111
1123 mActionButtonImage = LLUI::getUIImageByName("flyout_btn_left.tga"); 1112 mActionButtonImage = LLUI::getUIImage("flyout_btn_left.tga");
1124 mExpanderButtonImage = LLUI::getUIImageByName("flyout_btn_right.tga"); 1113 mExpanderButtonImage = LLUI::getUIImage("flyout_btn_right.tga");
1125 mActionButtonImageSelected = LLUI::getUIImageByName("flyout_btn_left_selected.tga"); 1114 mActionButtonImageSelected = LLUI::getUIImage("flyout_btn_left_selected.tga");
1126 mExpanderButtonImageSelected = LLUI::getUIImageByName("flyout_btn_right_selected.tga"); 1115 mExpanderButtonImageSelected = LLUI::getUIImage("flyout_btn_right_selected.tga");
1116 mActionButtonImageDisabled = LLUI::getUIImage("flyout_btn_left_disabled.tga");
1117 mExpanderButtonImageDisabled = LLUI::getUIImage("flyout_btn_right_disabled.tga");
1127 1118
1128 mActionButton->setImageSelected(mActionButtonImageSelected); 1119 mActionButton->setImageSelected(mActionButtonImageSelected);
1129 mActionButton->setImageUnselected(mActionButtonImage); 1120 mActionButton->setImageUnselected(mActionButtonImage);
1130 mActionButton->setImageDisabled(LLPointer<LLUIImage>(NULL)); 1121 mActionButton->setImageDisabled(mActionButtonImageDisabled);
1131 mActionButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL)); 1122 mActionButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL));
1132 1123
1133 mButton->setImageSelected(mExpanderButtonImageSelected); 1124 mButton->setImageSelected(mExpanderButtonImageSelected);
1134 mButton->setImageUnselected(mExpanderButtonImage); 1125 mButton->setImageUnselected(mExpanderButtonImage);
1135 mButton->setImageDisabled(LLPointer<LLUIImage>(NULL)); 1126 mButton->setImageDisabled(mExpanderButtonImageDisabled);
1136 mButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL)); 1127 mButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL));
1137 mButton->setRightHPad(6); 1128 mButton->setRightHPad(6);
1138 1129
1139 mBorder->setVisible(FALSE);
1140
1141 updateLayout(); 1130 updateLayout();
1142} 1131}
1143 1132
diff --git a/linden/indra/llui/llcombobox.h b/linden/indra/llui/llcombobox.h
index f9ca4d2..b35d078 100644
--- a/linden/indra/llui/llcombobox.h
+++ b/linden/indra/llui/llcombobox.h
@@ -73,8 +73,7 @@ public:
73 virtual ~LLComboBox(); 73 virtual ~LLComboBox();
74 74
75 // LLView interface 75 // LLView interface
76 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_COMBO_BOX; } 76
77 virtual LLString getWidgetTag() const { return LL_COMBO_BOX_TAG; }
78 virtual LLXMLNodePtr getXML(bool save_children = true) const; 77 virtual LLXMLNodePtr getXML(bool save_children = true) const;
79 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 78 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
80 79
@@ -85,8 +84,8 @@ public:
85 virtual void setEnabled(BOOL enabled); 84 virtual void setEnabled(BOOL enabled);
86 85
87 virtual BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); 86 virtual BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect);
88 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 87 virtual BOOL handleKeyHere(KEY key, MASK mask);
89 virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); 88 virtual BOOL handleUnicodeCharHere(llwchar uni_char);
90 89
91 // LLUICtrl interface 90 // LLUICtrl interface
92 virtual void clear(); // select nothing 91 virtual void clear(); // select nothing
@@ -187,9 +186,8 @@ public:
187protected: 186protected:
188 LLButton* mButton; 187 LLButton* mButton;
189 LLScrollListCtrl* mList; 188 LLScrollListCtrl* mList;
190 LLViewBorder* mBorder;
191 EPreferredPosition mListPosition; 189 EPreferredPosition mListPosition;
192 LLPointer<LLImageGL> mArrowImage; 190 LLPointer<LLUIImage> mArrowImage;
193 191
194private: 192private:
195 S32 mButtonPadding; 193 S32 mButtonPadding;
@@ -211,9 +209,6 @@ public:
211 void (*commit_callback)(LLUICtrl*, void*) = NULL, 209 void (*commit_callback)(LLUICtrl*, void*) = NULL,
212 void *callback_userdata = NULL); 210 void *callback_userdata = NULL);
213 211
214 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLYOUT_BUTTON; }
215 virtual LLString getWidgetTag() const { return LL_FLYOUT_BUTTON_TAG; }
216
217 virtual void updateLayout(); 212 virtual void updateLayout();
218 virtual void draw(); 213 virtual void draw();
219 virtual void setEnabled(BOOL enabled); 214 virtual void setEnabled(BOOL enabled);
@@ -230,6 +225,8 @@ protected:
230 LLPointer<LLUIImage> mExpanderButtonImage; 225 LLPointer<LLUIImage> mExpanderButtonImage;
231 LLPointer<LLUIImage> mActionButtonImageSelected; 226 LLPointer<LLUIImage> mActionButtonImageSelected;
232 LLPointer<LLUIImage> mExpanderButtonImageSelected; 227 LLPointer<LLUIImage> mExpanderButtonImageSelected;
228 LLPointer<LLUIImage> mActionButtonImageDisabled;
229 LLPointer<LLUIImage> mExpanderButtonImageDisabled;
233 BOOL mToggleState; 230 BOOL mToggleState;
234}; 231};
235 232
diff --git a/linden/indra/llui/lldraghandle.cpp b/linden/indra/llui/lldraghandle.cpp
index 516afc6..f033371 100644
--- a/linden/indra/llui/lldraghandle.cpp
+++ b/linden/indra/llui/lldraghandle.cpp
@@ -101,16 +101,6 @@ LLDragHandleTop::LLDragHandleTop(const LLString& name, const LLRect &rect, const
101 setTitle( title ); 101 setTitle( title );
102} 102}
103 103
104EWidgetType LLDragHandleTop::getWidgetType() const
105{
106 return WIDGET_TYPE_DRAG_HANDLE_TOP;
107}
108
109LLString LLDragHandleTop::getWidgetTag() const
110{
111 return LL_DRAG_HANDLE_TOP_TAG;
112}
113
114LLDragHandleLeft::LLDragHandleLeft(const LLString& name, const LLRect &rect, const LLString& title) 104LLDragHandleLeft::LLDragHandleLeft(const LLString& name, const LLRect &rect, const LLString& title)
115: LLDragHandle(name, rect, title) 105: LLDragHandle(name, rect, title)
116{ 106{
@@ -118,22 +108,12 @@ LLDragHandleLeft::LLDragHandleLeft(const LLString& name, const LLRect &rect, con
118 setTitle( title ); 108 setTitle( title );
119} 109}
120 110
121EWidgetType LLDragHandleLeft::getWidgetType() const
122{
123 return WIDGET_TYPE_DRAG_HANDLE_LEFT;
124}
125
126LLString LLDragHandleLeft::getWidgetTag() const
127{
128 return LL_DRAG_HANDLE_LEFT_TAG;
129}
130
131void LLDragHandleTop::setTitle(const LLString& title) 111void LLDragHandleTop::setTitle(const LLString& title)
132{ 112{
133 LLString trimmed_title = title; 113 LLString trimmed_title = title;
134 LLString::trim(trimmed_title); 114 LLString::trim(trimmed_title);
135 115
136 const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); 116 const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
137 LLTextBox* titlebox = new LLTextBox( "Drag Handle Title", getRect(), trimmed_title, font ); 117 LLTextBox* titlebox = new LLTextBox( "Drag Handle Title", getRect(), trimmed_title, font );
138 titlebox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); 118 titlebox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
139 titlebox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); 119 titlebox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT);
@@ -262,7 +242,7 @@ void LLDragHandleTop::reshapeTitleBox()
262 { 242 {
263 return; 243 return;
264 } 244 }
265 const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); 245 const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
266 S32 title_width = font->getWidth( getTitleBox()->getText() ) + TITLE_PAD; 246 S32 title_width = font->getWidth( getTitleBox()->getText() ) + TITLE_PAD;
267 if (getMaxTitleWidth() > 0) 247 if (getMaxTitleWidth() > 0)
268 title_width = llmin(title_width, getMaxTitleWidth()); 248 title_width = llmin(title_width, getMaxTitleWidth());
@@ -372,7 +352,7 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
372 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" <<llendl; 352 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" <<llendl;
373 handled = TRUE; 353 handled = TRUE;
374 } 354 }
375 else if( getVisible() ) 355 else
376 { 356 {
377 getWindow()->setCursor(UI_CURSOR_ARROW); 357 getWindow()->setCursor(UI_CURSOR_ARROW);
378 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; 358 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
diff --git a/linden/indra/llui/lldraghandle.h b/linden/indra/llui/lldraghandle.h
index 88e16dc..fc10639 100644
--- a/linden/indra/llui/lldraghandle.h
+++ b/linden/indra/llui/lldraghandle.h
@@ -90,9 +90,6 @@ class LLDragHandleTop
90public: 90public:
91 LLDragHandleTop(const LLString& name, const LLRect& rect, const LLString& title ); 91 LLDragHandleTop(const LLString& name, const LLRect& rect, const LLString& title );
92 92
93 virtual EWidgetType getWidgetType() const;
94 virtual LLString getWidgetTag() const;
95
96 virtual void setTitle( const LLString& title ); 93 virtual void setTitle( const LLString& title );
97 virtual const LLString& getTitle() const; 94 virtual const LLString& getTitle() const;
98 virtual void draw(); 95 virtual void draw();
@@ -110,9 +107,6 @@ class LLDragHandleLeft
110public: 107public:
111 LLDragHandleLeft(const LLString& name, const LLRect& rect, const LLString& title ); 108 LLDragHandleLeft(const LLString& name, const LLRect& rect, const LLString& title );
112 109
113 virtual EWidgetType getWidgetType() const;
114 virtual LLString getWidgetTag() const;
115
116 virtual void setTitle( const LLString& title ); 110 virtual void setTitle( const LLString& title );
117 virtual const LLString& getTitle() const; 111 virtual const LLString& getTitle() const;
118 virtual void draw(); 112 virtual void draw();
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp
index 1e825d3..5142bf4 100644
--- a/linden/indra/llui/llfloater.cpp
+++ b/linden/indra/llui/llfloater.cpp
@@ -50,7 +50,6 @@
50#include "lltextbox.h" 50#include "lltextbox.h"
51#include "llresmgr.h" 51#include "llresmgr.h"
52#include "llui.h" 52#include "llui.h"
53#include "llviewborder.h"
54#include "llwindow.h" 53#include "llwindow.h"
55#include "llstl.h" 54#include "llstl.h"
56#include "llcontrol.h" 55#include "llcontrol.h"
@@ -131,8 +130,9 @@ LLFloaterView* gFloaterView = NULL;
131LLFloater::LLFloater() : 130LLFloater::LLFloater() :
132 //FIXME: we should initialize *all* member variables here 131 //FIXME: we should initialize *all* member variables here
133 mResizable(FALSE), 132 mResizable(FALSE),
134 mDragOnLeft(FALSE) 133 mDragOnLeft(FALSE),
135 134 mMinWidth(0),
135 mMinHeight(0)
136{ 136{
137 // automatically take focus when opened 137 // automatically take focus when opened
138 mAutoFocus = TRUE; 138 mAutoFocus = TRUE;
@@ -656,7 +656,8 @@ void LLFloater::setTitle( const LLString& title )
656 { 656 {
657 return; 657 return;
658 } 658 }
659 mDragHandle->setTitle( title ); 659 if (mDragHandle)
660 mDragHandle->setTitle( title );
660} 661}
661 662
662const LLString& LLFloater::getTitle() const 663const LLString& LLFloater::getTitle() const
@@ -802,24 +803,10 @@ void LLFloater::setMinimized(BOOL minimize)
802 mButtonsEnabled[BUTTON_RESTORE] = TRUE; 803 mButtonsEnabled[BUTTON_RESTORE] = TRUE;
803 } 804 }
804 805
805 mMinimizedHiddenChildren.clear();
806 // hide all children
807 for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
808 {
809 LLView* viewp = *child_it;
810 if (!viewp->getVisible())
811 {
812 mMinimizedHiddenChildren.push_back(viewp->getHandle());
813 }
814 viewp->setVisible(FALSE);
815 }
816
817 // except the special controls
818 if (mDragHandle) 806 if (mDragHandle)
819 { 807 {
820 mDragHandle->setVisible(TRUE); 808 mDragHandle->setVisible(TRUE);
821 } 809 }
822
823 setBorderVisible(TRUE); 810 setBorderVisible(TRUE);
824 811
825 for(handle_set_iter_t dependent_it = mDependents.begin(); 812 for(handle_set_iter_t dependent_it = mDependents.begin();
@@ -843,6 +830,12 @@ void LLFloater::setMinimized(BOOL minimize)
843 // Lose keyboard focus when minimized 830 // Lose keyboard focus when minimized
844 releaseFocus(); 831 releaseFocus();
845 832
833 for (S32 i = 0; i < 4; i++)
834 {
835 if (mResizeBar[i]) mResizeBar[i]->setEnabled(FALSE);
836 if (mResizeHandle[i]) mResizeHandle[i]->setEnabled(FALSE);
837 }
838
846 mMinimized = TRUE; 839 mMinimized = TRUE;
847 840
848 // Reshape *after* setting mMinimized 841 // Reshape *after* setting mMinimized
@@ -867,24 +860,6 @@ void LLFloater::setMinimized(BOOL minimize)
867 mButtonsEnabled[BUTTON_RESTORE] = FALSE; 860 mButtonsEnabled[BUTTON_RESTORE] = FALSE;
868 } 861 }
869 862
870 // show all children
871 for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
872 {
873 LLView* viewp = *child_it;
874 viewp->setVisible(TRUE);
875 }
876
877 std::vector<LLHandle<LLView> >::iterator itor = mMinimizedHiddenChildren.begin();
878 for ( ; itor != mMinimizedHiddenChildren.end(); ++itor)
879 {
880 LLView* viewp = itor->get();
881 if(viewp)
882 {
883 viewp->setVisible(FALSE);
884 }
885 }
886 mMinimizedHiddenChildren.clear();
887
888 // show dependent floater 863 // show dependent floater
889 for(handle_set_iter_t dependent_it = mDependents.begin(); 864 for(handle_set_iter_t dependent_it = mDependents.begin();
890 dependent_it != mDependents.end(); 865 dependent_it != mDependents.end();
@@ -898,6 +873,12 @@ void LLFloater::setMinimized(BOOL minimize)
898 } 873 }
899 } 874 }
900 875
876 for (S32 i = 0; i < 4; i++)
877 {
878 if (mResizeBar[i]) mResizeBar[i]->setEnabled(isResizable());
879 if (mResizeHandle[i]) mResizeHandle[i]->setEnabled(isResizable());
880 }
881
901 mMinimized = FALSE; 882 mMinimized = FALSE;
902 883
903 // Reshape *after* setting mMinimized 884 // Reshape *after* setting mMinimized
@@ -954,7 +935,8 @@ void LLFloater::setIsChrome(BOOL is_chrome)
954 } 935 }
955 936
956 // no titles displayed on "chrome" floaters 937 // no titles displayed on "chrome" floaters
957 mDragHandle->setTitleVisible(!is_chrome); 938 if (mDragHandle)
939 mDragHandle->setTitleVisible(!is_chrome);
958 940
959 LLPanel::setIsChrome(is_chrome); 941 LLPanel::setIsChrome(is_chrome);
960} 942}
@@ -965,7 +947,8 @@ void LLFloater::setForeground(BOOL front)
965 if (front != mForeground) 947 if (front != mForeground)
966 { 948 {
967 mForeground = front; 949 mForeground = front;
968 mDragHandle->setForeground( front ); 950 if (mDragHandle)
951 mDragHandle->setForeground( front );
969 952
970 if (!front) 953 if (!front)
971 { 954 {
@@ -1310,49 +1293,72 @@ void LLFloater::onClickClose( void* userdata )
1310// virtual 1293// virtual
1311void LLFloater::draw() 1294void LLFloater::draw()
1312{ 1295{
1313 if( getVisible() ) 1296 // draw background
1297 if( isBackgroundVisible() )
1314 { 1298 {
1315 // draw background 1299 S32 left = LLPANEL_BORDER_WIDTH;
1316 if( isBackgroundVisible() ) 1300 S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH;
1317 { 1301 S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH;
1318 S32 left = LLPANEL_BORDER_WIDTH; 1302 S32 bottom = LLPANEL_BORDER_WIDTH;
1319 S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH;
1320 S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH;
1321 S32 bottom = LLPANEL_BORDER_WIDTH;
1322 1303
1323 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow"); 1304 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
1324 F32 shadow_offset = (F32)LLUI::sConfigGroup->getS32("DropShadowFloater"); 1305 F32 shadow_offset = (F32)LLUI::sConfigGroup->getS32("DropShadowFloater");
1325 if (!isBackgroundOpaque()) 1306 if (!isBackgroundOpaque())
1326 { 1307 {
1327 shadow_offset *= 0.2f; 1308 shadow_offset *= 0.2f;
1328 shadow_color.mV[VALPHA] *= 0.5f; 1309 shadow_color.mV[VALPHA] *= 0.5f;
1329 } 1310 }
1330 gl_drop_shadow(left, top, right, bottom, 1311 gl_drop_shadow(left, top, right, bottom,
1331 shadow_color, 1312 shadow_color,
1332 llround(shadow_offset)); 1313 llround(shadow_offset));
1333 1314
1334 // No transparent windows in simple UI 1315 // No transparent windows in simple UI
1335 if (isBackgroundOpaque()) 1316 if (isBackgroundOpaque())
1336 { 1317 {
1337 gl_rect_2d( left, top, right, bottom, getBackgroundColor() ); 1318 gl_rect_2d( left, top, right, bottom, getBackgroundColor() );
1338 } 1319 }
1339 else 1320 else
1340 { 1321 {
1341 gl_rect_2d( left, top, right, bottom, getTransparentColor() ); 1322 gl_rect_2d( left, top, right, bottom, getTransparentColor() );
1342 } 1323 }
1343 1324
1344 if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getTitle().empty()) 1325 if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getTitle().empty())
1345 { 1326 {
1346 // draw highlight on title bar to indicate focus. RDW 1327 // draw highlight on title bar to indicate focus. RDW
1347 const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); 1328 const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
1348 LLRect r = getRect(); 1329 LLRect r = getRect();
1349 gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1, 1330 gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1,
1350 LLUI::sColorsGroup->getColor("TitleBarFocusColor"), 0, TRUE); 1331 LLUI::sColorsGroup->getColor("TitleBarFocusColor"), 0, TRUE);
1351 }
1352 } 1332 }
1333 }
1353 1334
1354 LLPanel::updateDefaultBtn(); 1335 LLPanel::updateDefaultBtn();
1355 1336
1337 if( getDefaultButton() )
1338 {
1339 if (hasFocus() && getDefaultButton()->getEnabled())
1340 {
1341 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
1342 // is this button a direct descendent and not a nested widget (e.g. checkbox)?
1343 BOOL focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && focus_ctrl->getParent() == this;
1344 // only enable default button when current focus is not a button
1345 getDefaultButton()->setBorderEnabled(!focus_is_child_button);
1346 }
1347 else
1348 {
1349 getDefaultButton()->setBorderEnabled(FALSE);
1350 }
1351 }
1352 if (isMinimized())
1353 {
1354 for (S32 i = 0; i < BUTTON_COUNT; i++)
1355 {
1356 drawChild(mButtons[i]);
1357 }
1358 drawChild(mDragHandle);
1359 }
1360 else
1361 {
1356 // draw children 1362 // draw children
1357 LLView* focused_child = gFocusMgr.getKeyboardFocus(); 1363 LLView* focused_child = gFocusMgr.getKeyboardFocus();
1358 BOOL focused_child_visible = FALSE; 1364 BOOL focused_child_visible = FALSE;
@@ -1365,36 +1371,35 @@ void LLFloater::draw()
1365 // don't call LLPanel::draw() since we've implemented custom background rendering 1371 // don't call LLPanel::draw() since we've implemented custom background rendering
1366 LLView::draw(); 1372 LLView::draw();
1367 1373
1368 if( isBackgroundVisible() )
1369 {
1370 // add in a border to improve spacialized visual aclarity ;)
1371 // use lines instead of gl_rect_2d so we can round the edges as per james' recommendation
1372 LLUI::setLineWidth(1.5f);
1373 LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? LLUI::sColorsGroup->getColor("FloaterFocusBorderColor") : LLUI::sColorsGroup->getColor("FloaterUnfocusBorderColor");
1374 gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE);
1375 LLUI::setLineWidth(1.f);
1376 }
1377
1378 if (focused_child_visible) 1374 if (focused_child_visible)
1379 { 1375 {
1380 focused_child->setVisible(TRUE); 1376 focused_child->setVisible(TRUE);
1381 } 1377 }
1382 drawChild(focused_child); 1378 drawChild(focused_child);
1379 }
1383 1380
1384 // update tearoff button for torn off floaters 1381 if( isBackgroundVisible() )
1385 // when last host goes away 1382 {
1386 if (mCanTearOff && !getHost()) 1383 // add in a border to improve spacialized visual aclarity ;)
1384 // use lines instead of gl_rect_2d so we can round the edges as per james' recommendation
1385 LLUI::setLineWidth(1.5f);
1386 LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? LLUI::sColorsGroup->getColor("FloaterFocusBorderColor") : LLUI::sColorsGroup->getColor("FloaterUnfocusBorderColor");
1387 gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE);
1388 LLUI::setLineWidth(1.f);
1389 }
1390
1391 // update tearoff button for torn off floaters
1392 // when last host goes away
1393 if (mCanTearOff && !getHost())
1394 {
1395 LLFloater* old_host = mLastHostHandle.get();
1396 if (!old_host)
1387 { 1397 {
1388 LLFloater* old_host = mLastHostHandle.get(); 1398 setCanTearOff(FALSE);
1389 if (!old_host)
1390 {
1391 setCanTearOff(FALSE);
1392 }
1393 } 1399 }
1394 } 1400 }
1395} 1401}
1396 1402
1397
1398void LLFloater::setCanMinimize(BOOL can_minimize) 1403void LLFloater::setCanMinimize(BOOL can_minimize)
1399{ 1404{
1400 // removing minimize/restore button programmatically, 1405 // removing minimize/restore button programmatically,
@@ -1540,7 +1545,13 @@ void LLFloater::updateButtons()
1540 S32 button_count = 0; 1545 S32 button_count = 0;
1541 for (S32 i = 0; i < BUTTON_COUNT; i++) 1546 for (S32 i = 0; i < BUTTON_COUNT; i++)
1542 { 1547 {
1543 if (mButtonsEnabled[i]) 1548 mButtons[i]->setEnabled(mButtonsEnabled[i]);
1549
1550 if (mButtonsEnabled[i]
1551 //*HACK: always render close button for hosted floaters
1552 // so that users don't accidentally hit the button when closing multiple windows
1553 // in the chatterbox
1554 || (i == BUTTON_CLOSE && mButtonScale != 1.f))
1544 { 1555 {
1545 button_count++; 1556 button_count++;
1546 1557
@@ -1564,18 +1575,16 @@ void LLFloater::updateButtons()
1564 1575
1565 mButtons[i]->setRect(btn_rect); 1576 mButtons[i]->setRect(btn_rect);
1566 mButtons[i]->setVisible(TRUE); 1577 mButtons[i]->setVisible(TRUE);
1567 mButtons[i]->setEnabled(TRUE);
1568 // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater 1578 // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater
1569 mButtons[i]->setTabStop(i == BUTTON_RESTORE); 1579 mButtons[i]->setTabStop(i == BUTTON_RESTORE);
1570 } 1580 }
1571 else if (mButtons[i]) 1581 else if (mButtons[i])
1572 { 1582 {
1573 mButtons[i]->setVisible(FALSE); 1583 mButtons[i]->setVisible(FALSE);
1574 mButtons[i]->setEnabled(FALSE);
1575 } 1584 }
1576 } 1585 }
1577 1586 if (mDragHandle)
1578 mDragHandle->setMaxTitleWidth(getRect().getWidth() - (button_count * (LLFLOATER_CLOSE_BOX_SIZE + 1))); 1587 mDragHandle->setMaxTitleWidth(getRect().getWidth() - (button_count * (LLFLOATER_CLOSE_BOX_SIZE + 1)));
1579} 1588}
1580 1589
1581void LLFloater::buildButtons() 1590void LLFloater::buildButtons()
@@ -2076,7 +2085,7 @@ void LLFloaterView::closeAllChildren(bool app_quitting)
2076 2085
2077 // Attempt to close floater. This will cause the "do you want to save" 2086 // Attempt to close floater. This will cause the "do you want to save"
2078 // dialogs to appear. 2087 // dialogs to appear.
2079 if (floaterp->canClose()) 2088 if (floaterp->canClose() && !floaterp->isDead())
2080 { 2089 {
2081 floaterp->close(app_quitting); 2090 floaterp->close(app_quitting);
2082 } 2091 }
@@ -2093,7 +2102,7 @@ BOOL LLFloaterView::allChildrenClosed()
2093 LLView* viewp = *it; 2102 LLView* viewp = *it;
2094 LLFloater* floaterp = (LLFloater*)viewp; 2103 LLFloater* floaterp = (LLFloater*)viewp;
2095 2104
2096 if (floaterp->getVisible() && floaterp->canClose()) 2105 if (floaterp->getVisible() && !floaterp->isDead() && floaterp->canClose())
2097 { 2106 {
2098 return false; 2107 return false;
2099 } 2108 }
@@ -2332,7 +2341,9 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
2332LLMultiFloater::LLMultiFloater() : 2341LLMultiFloater::LLMultiFloater() :
2333 mTabContainer(NULL), 2342 mTabContainer(NULL),
2334 mTabPos(LLTabContainer::TOP), 2343 mTabPos(LLTabContainer::TOP),
2335 mAutoResize(TRUE) 2344 mAutoResize(TRUE),
2345 mOrigMinWidth(0),
2346 mOrigMinHeight(0)
2336{ 2347{
2337 2348
2338} 2349}
@@ -2340,7 +2351,9 @@ LLMultiFloater::LLMultiFloater() :
2340LLMultiFloater::LLMultiFloater(LLTabContainer::TabPosition tab_pos) : 2351LLMultiFloater::LLMultiFloater(LLTabContainer::TabPosition tab_pos) :
2341 mTabContainer(NULL), 2352 mTabContainer(NULL),
2342 mTabPos(tab_pos), 2353 mTabPos(tab_pos),
2343 mAutoResize(TRUE) 2354 mAutoResize(TRUE),
2355 mOrigMinWidth(0),
2356 mOrigMinHeight(0)
2344{ 2357{
2345 2358
2346} 2359}
@@ -2349,7 +2362,9 @@ LLMultiFloater::LLMultiFloater(const LLString &name) :
2349 LLFloater(name), 2362 LLFloater(name),
2350 mTabContainer(NULL), 2363 mTabContainer(NULL),
2351 mTabPos(LLTabContainer::TOP), 2364 mTabPos(LLTabContainer::TOP),
2352 mAutoResize(FALSE) 2365 mAutoResize(FALSE),
2366 mOrigMinWidth(0),
2367 mOrigMinHeight(0)
2353{ 2368{
2354} 2369}
2355 2370
@@ -2361,7 +2376,9 @@ LLMultiFloater::LLMultiFloater(
2361 LLFloater(name, rect, name), 2376 LLFloater(name, rect, name),
2362 mTabContainer(NULL), 2377 mTabContainer(NULL),
2363 mTabPos(LLTabContainer::TOP), 2378 mTabPos(LLTabContainer::TOP),
2364 mAutoResize(auto_resize) 2379 mAutoResize(auto_resize),
2380 mOrigMinWidth(0),
2381 mOrigMinHeight(0)
2365{ 2382{
2366 mTabContainer = new LLTabContainer("Preview Tabs", 2383 mTabContainer = new LLTabContainer("Preview Tabs",
2367 LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0), 2384 LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
@@ -2385,7 +2402,9 @@ LLMultiFloater::LLMultiFloater(
2385 LLFloater(name, rect_control, name), 2402 LLFloater(name, rect_control, name),
2386 mTabContainer(NULL), 2403 mTabContainer(NULL),
2387 mTabPos(tab_pos), 2404 mTabPos(tab_pos),
2388 mAutoResize(auto_resize) 2405 mAutoResize(auto_resize),
2406 mOrigMinWidth(0),
2407 mOrigMinHeight(0)
2389{ 2408{
2390 mTabContainer = new LLTabContainer("Preview Tabs", 2409 mTabContainer = new LLTabContainer("Preview Tabs",
2391 LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0), 2410 LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
@@ -2678,24 +2697,20 @@ void LLMultiFloater::setVisible(BOOL visible)
2678 } 2697 }
2679} 2698}
2680 2699
2681BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 2700BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
2682{ 2701{
2683 if (getEnabled() 2702 if (key == 'W' && mask == MASK_CONTROL)
2684 && mask == MASK_CONTROL)
2685 { 2703 {
2686 if (key == 'W') 2704 LLFloater* floater = getActiveFloater();
2705 // is user closeable and is system closeable
2706 if (floater && floater->canClose() && floater->isCloseable())
2687 { 2707 {
2688 LLFloater* floater = getActiveFloater(); 2708 floater->close();
2689 // is user closeable and is system closeable
2690 if (floater && floater->canClose() && floater->isCloseable())
2691 {
2692 floater->close();
2693 }
2694 return TRUE;
2695 } 2709 }
2710 return TRUE;
2696 } 2711 }
2697 2712
2698 return LLFloater::handleKeyHere(key, mask, called_from_parent); 2713 return LLFloater::handleKeyHere(key, mask);
2699} 2714}
2700 2715
2701LLFloater* LLMultiFloater::getActiveFloater() 2716LLFloater* LLMultiFloater::getActiveFloater()
@@ -2763,15 +2778,18 @@ void LLMultiFloater::setCanResize(BOOL can_resize)
2763 2778
2764BOOL LLMultiFloater::postBuild() 2779BOOL LLMultiFloater::postBuild()
2765{ 2780{
2781 // remember any original xml minimum size
2782 getResizeLimits(&mOrigMinWidth, &mOrigMinHeight);
2783
2766 if (mTabContainer) 2784 if (mTabContainer)
2767 { 2785 {
2768 return TRUE; 2786 return TRUE;
2769 } 2787 }
2770 2788
2771 requires("Preview Tabs", WIDGET_TYPE_TAB_CONTAINER); 2789 requires<LLTabContainer>("Preview Tabs");
2772 if (checkRequirements()) 2790 if (checkRequirements())
2773 { 2791 {
2774 mTabContainer = LLUICtrlFactory::getTabContainerByName(this, "Preview Tabs"); 2792 mTabContainer = getChild<LLTabContainer>("Preview Tabs");
2775 return TRUE; 2793 return TRUE;
2776 } 2794 }
2777 2795
@@ -2780,10 +2798,11 @@ BOOL LLMultiFloater::postBuild()
2780 2798
2781void LLMultiFloater::updateResizeLimits() 2799void LLMultiFloater::updateResizeLimits()
2782{ 2800{
2783 S32 new_min_width = 0; 2801 // initialize minimum size constraint to the original xml values.
2784 S32 new_min_height = 0; 2802 S32 new_min_width = mOrigMinWidth;
2785 S32 tab_idx; 2803 S32 new_min_height = mOrigMinHeight;
2786 for (tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) 2804 // possibly increase minimum size constraint due to children's minimums.
2805 for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
2787 { 2806 {
2788 LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx); 2807 LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
2789 if (floaterp) 2808 if (floaterp)
diff --git a/linden/indra/llui/llfloater.h b/linden/indra/llui/llfloater.h
index f0bbcaf..8068741 100644
--- a/linden/indra/llui/llfloater.h
+++ b/linden/indra/llui/llfloater.h
@@ -50,7 +50,7 @@ class LLMultiFloater;
50const S32 LLFLOATER_VPAD = 6; 50const S32 LLFLOATER_VPAD = 6;
51const S32 LLFLOATER_HPAD = 6; 51const S32 LLFLOATER_HPAD = 6;
52const S32 LLFLOATER_CLOSE_BOX_SIZE = 16; 52const S32 LLFLOATER_CLOSE_BOX_SIZE = 16;
53const S32 LLFLOATER_HEADER_SIZE = 16; 53const S32 LLFLOATER_HEADER_SIZE = 18;
54 54
55const BOOL RESIZE_YES = TRUE; 55const BOOL RESIZE_YES = TRUE;
56const BOOL RESIZE_NO = FALSE; 56const BOOL RESIZE_NO = FALSE;
@@ -122,8 +122,6 @@ public:
122 virtual void initFloater(const LLString& title, BOOL resizable, 122 virtual void initFloater(const LLString& title, BOOL resizable,
123 S32 min_width, S32 min_height, BOOL drag_on_left, 123 S32 min_width, S32 min_height, BOOL drag_on_left,
124 BOOL minimizable, BOOL close_btn); 124 BOOL minimizable, BOOL close_btn);
125 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLOATER; }
126 virtual LLString getWidgetTag() const { return LL_FLOATER_TAG; };
127 125
128 virtual void open(); /* Flawfinder: ignore */ 126 virtual void open(); /* Flawfinder: ignore */
129 127
@@ -187,6 +185,8 @@ public:
187 // Defaults to destroy(). 185 // Defaults to destroy().
188 virtual void onClose(bool app_quitting) { destroy(); } 186 virtual void onClose(bool app_quitting) { destroy(); }
189 187
188 // This cannot be "const" until all derived floater canClose()
189 // methods are const as well. JC
190 virtual BOOL canClose() { return TRUE; } 190 virtual BOOL canClose() { return TRUE; }
191 191
192 virtual void setVisible(BOOL visible); 192 virtual void setVisible(BOOL visible);
@@ -302,9 +302,6 @@ class LLFloaterView : public LLUICtrl
302public: 302public:
303 LLFloaterView( const LLString& name, const LLRect& rect ); 303 LLFloaterView( const LLString& name, const LLRect& rect );
304 304
305 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLOATER_VIEW; }
306 virtual LLString getWidgetTag() const { return LL_FLOATER_VIEW_TAG; }
307
308 /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); 305 /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
309 void reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical); 306 void reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical);
310 307
@@ -373,9 +370,7 @@ public:
373 /*virtual*/ void onClose(bool app_quitting); 370 /*virtual*/ void onClose(bool app_quitting);
374 /*virtual*/ void draw(); 371 /*virtual*/ void draw();
375 /*virtual*/ void setVisible(BOOL visible); 372 /*virtual*/ void setVisible(BOOL visible);
376 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 373 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
377 /*virtual*/ EWidgetType getWidgetType() const { return WIDGET_TYPE_MULTI_FLOATER; }
378 /*virtual*/ LLString getWidgetTag() const { return LL_MULTI_FLOATER_TAG; };
379 374
380 virtual void setCanResize(BOOL can_resize); 375 virtual void setCanResize(BOOL can_resize);
381 virtual void growToFit(S32 content_width, S32 content_height); 376 virtual void growToFit(S32 content_width, S32 content_height);
@@ -418,6 +413,7 @@ protected:
418 413
419 LLTabContainer::TabPosition mTabPos; 414 LLTabContainer::TabPosition mTabPos;
420 BOOL mAutoResize; 415 BOOL mAutoResize;
416 S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
421}; 417};
422 418
423// visibility policy specialized for floaters 419// visibility policy specialized for floaters
diff --git a/linden/indra/llui/llfocusmgr.cpp b/linden/indra/llui/llfocusmgr.cpp
index 0634513..e2d1f46 100644
--- a/linden/indra/llui/llfocusmgr.cpp
+++ b/linden/indra/llui/llfocusmgr.cpp
@@ -46,6 +46,7 @@ LLFocusMgr::LLFocusMgr()
46 mKeyboardFocus( NULL ), 46 mKeyboardFocus( NULL ),
47 mLastKeyboardFocus( NULL ), 47 mLastKeyboardFocus( NULL ),
48 mDefaultKeyboardFocus( NULL ), 48 mDefaultKeyboardFocus( NULL ),
49 mKeystrokesOnly(FALSE),
49 mTopCtrl( NULL ), 50 mTopCtrl( NULL ),
50 mFocusWeight(0.f), 51 mFocusWeight(0.f),
51 mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true 52 mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true
@@ -85,7 +86,7 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
85} 86}
86 87
87 88
88void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock) 89void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystrokes_only)
89{ 90{
90 if (mLockedView && 91 if (mLockedView &&
91 (new_focus == NULL || 92 (new_focus == NULL ||
@@ -98,6 +99,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock)
98 99
99 //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl; 100 //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl;
100 101
102 mKeystrokesOnly = keystrokes_only;
103
101 if( new_focus != mKeyboardFocus ) 104 if( new_focus != mKeyboardFocus )
102 { 105 {
103 mLastKeyboardFocus = mKeyboardFocus; 106 mLastKeyboardFocus = mKeyboardFocus;
diff --git a/linden/indra/llui/llfocusmgr.h b/linden/indra/llui/llfocusmgr.h
index 842c874..49aba93 100644
--- a/linden/indra/llui/llfocusmgr.h
+++ b/linden/indra/llui/llfocusmgr.h
@@ -54,13 +54,17 @@ public:
54 BOOL childHasMouseCapture( const LLView* parent ) const; 54 BOOL childHasMouseCapture( const LLView* parent ) const;
55 55
56 // Keyboard Focus 56 // Keyboard Focus
57 void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE); // new_focus = NULL to release the focus. 57 void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus.
58 LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; } 58 LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; }
59 LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; } 59 LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; }
60 BOOL childHasKeyboardFocus( const LLView* parent ) const; 60 BOOL childHasKeyboardFocus( const LLView* parent ) const;
61 void removeKeyboardFocusWithoutCallback( const LLView* focus ); 61 void removeKeyboardFocusWithoutCallback( const LLView* focus );
62 BOOL getKeystrokesOnly() { return mKeystrokesOnly; }
63 void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; }
64
62 F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); } 65 F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); }
63 F32 getFocusFlashAmt() const; 66 F32 getFocusFlashAmt() const;
67 S32 getFocusFlashWidth() const { return llround(lerp(1.f, 3.f, getFocusFlashAmt())); }
64 LLColor4 getFocusColor() const; 68 LLColor4 getFocusColor() const;
65 void triggerFocusFlash(); 69 void triggerFocusFlash();
66 BOOL getAppHasFocus() const { return mAppHasFocus; } 70 BOOL getAppHasFocus() const { return mAppHasFocus; }
@@ -96,6 +100,7 @@ private:
96 LLUICtrl* mKeyboardFocus; // Keyboard events are preemptively routed to this object 100 LLUICtrl* mKeyboardFocus; // Keyboard events are preemptively routed to this object
97 LLUICtrl* mLastKeyboardFocus; // who last had focus 101 LLUICtrl* mLastKeyboardFocus; // who last had focus
98 LLUICtrl* mDefaultKeyboardFocus; 102 LLUICtrl* mDefaultKeyboardFocus;
103 BOOL mKeystrokesOnly;
99 104
100 // Top View 105 // Top View
101 LLUICtrl* mTopCtrl; 106 LLUICtrl* mTopCtrl;
diff --git a/linden/indra/llui/llhtmlhelp.h b/linden/indra/llui/llhtmlhelp.h
index d4ec9e3..254faa2 100644
--- a/linden/indra/llui/llhtmlhelp.h
+++ b/linden/indra/llui/llhtmlhelp.h
@@ -36,7 +36,8 @@ class LLHtmlHelp
36{ 36{
37public: 37public:
38 virtual ~LLHtmlHelp() {} 38 virtual ~LLHtmlHelp() {}
39 virtual void show(std::string start_url, std::string title) = 0; 39 virtual void show() = 0;
40 virtual void show(std::string help_url) = 0;
40}; 41};
41 42
42#endif // LL_LLFLOATERHTMLHELP_H 43#endif // LL_LLFLOATERHTMLHELP_H
diff --git a/linden/indra/llui/lliconctrl.cpp b/linden/indra/llui/lliconctrl.cpp
index 6a1d77c..f35de85 100644
--- a/linden/indra/llui/lliconctrl.cpp
+++ b/linden/indra/llui/lliconctrl.cpp
@@ -42,14 +42,15 @@
42 42
43const F32 RESOLUTION_BUMP = 1.f; 43const F32 RESOLUTION_BUMP = 1.f;
44 44
45static LLRegisterWidget<LLIconCtrl> r("icon");
46
45LLIconCtrl::LLIconCtrl(const LLString& name, const LLRect &rect, const LLUUID &image_id) 47LLIconCtrl::LLIconCtrl(const LLString& name, const LLRect &rect, const LLUUID &image_id)
46: LLUICtrl(name, 48: LLUICtrl(name,
47 rect, 49 rect,
48 FALSE, // mouse opaque 50 FALSE, // mouse opaque
49 NULL, NULL, 51 NULL, NULL,
50 FOLLOWS_LEFT | FOLLOWS_TOP), 52 FOLLOWS_LEFT | FOLLOWS_TOP),
51 mColor( LLColor4::white ), 53 mColor( LLColor4::white )
52 mImageName("")
53{ 54{
54 setImage( image_id ); 55 setImage( image_id );
55 setTabStop(FALSE); 56 setTabStop(FALSE);
@@ -64,9 +65,7 @@ LLIconCtrl::LLIconCtrl(const LLString& name, const LLRect &rect, const LLString
64 mColor( LLColor4::white ), 65 mColor( LLColor4::white ),
65 mImageName(image_name) 66 mImageName(image_name)
66{ 67{
67 LLUUID image_id; 68 setImage( image_name );
68 image_id.set(LLUI::sAssetsGroup->getString( image_name ));
69 setImage( image_id );
70 setTabStop(FALSE); 69 setTabStop(FALSE);
71} 70}
72 71
@@ -77,32 +76,52 @@ LLIconCtrl::~LLIconCtrl()
77} 76}
78 77
79 78
80void LLIconCtrl::setImage(const LLUUID &image_id) 79void LLIconCtrl::setImage(const LLString& image_name)
81{ 80{
82 mImageID = image_id; 81 //RN: support UUIDs masquerading as strings
82 if (LLUUID::validate(image_name))
83 {
84 mImageID = LLUUID(image_name);
85
86 setImage(mImageID);
87 }
88 else
89 {
90 mImageName = image_name;
91 mImagep = LLUI::sImageProvider->getUIImage(image_name);
92 mImageID.setNull();
93 }
94}
95
96void LLIconCtrl::setImage(const LLUUID& image_id)
97{
98 mImageName.clear();
83 mImagep = LLUI::sImageProvider->getUIImageByID(image_id); 99 mImagep = LLUI::sImageProvider->getUIImageByID(image_id);
100 mImageID = image_id;
84} 101}
85 102
86 103
87void LLIconCtrl::draw() 104void LLIconCtrl::draw()
88{ 105{
89 if( getVisible() ) 106 if( mImagep.notNull() )
90 { 107 {
91 if( mImagep.notNull() ) 108 mImagep->draw(getLocalRect(), mColor );
92 {
93 mImagep->draw(0, 0,
94 getRect().getWidth(), getRect().getHeight(),
95 mColor );
96 }
97
98 LLUICtrl::draw();
99 } 109 }
110
111 LLUICtrl::draw();
100} 112}
101 113
102// virtual 114// virtual
103void LLIconCtrl::setValue(const LLSD& value ) 115void LLIconCtrl::setValue(const LLSD& value )
104{ 116{
105 setImage(value.asUUID()); 117 if (value.isUUID())
118 {
119 setImage(value.asUUID());
120 }
121 else
122 {
123 setImage(value.asString());
124 }
106} 125}
107 126
108// virtual 127// virtual
@@ -135,18 +154,16 @@ LLView* LLIconCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
135 LLRect rect; 154 LLRect rect;
136 createRect(node, rect, parent, LLRect()); 155 createRect(node, rect, parent, LLRect());
137 156
138 LLUUID image_id; 157 LLString image_name;
139 if (node->hasAttribute("image_name")) 158 if (node->hasAttribute("image_name"))
140 { 159 {
141 LLString image_name;
142 node->getAttributeString("image_name", image_name); 160 node->getAttributeString("image_name", image_name);
143 image_id.set(LLUI::sAssetsGroup->getString( image_name ));
144 } 161 }
145 162
146 LLColor4 color(LLColor4::white); 163 LLColor4 color(LLColor4::white);
147 LLUICtrlFactory::getAttributeColor(node,"color", color); 164 LLUICtrlFactory::getAttributeColor(node,"color", color);
148 165
149 LLIconCtrl* icon = new LLIconCtrl(name, rect, image_id); 166 LLIconCtrl* icon = new LLIconCtrl(name, rect, image_name);
150 167
151 icon->setColor(color); 168 icon->setColor(color);
152 169
diff --git a/linden/indra/llui/lliconctrl.h b/linden/indra/llui/lliconctrl.h
index b0c191f..055b504 100644
--- a/linden/indra/llui/lliconctrl.h
+++ b/linden/indra/llui/lliconctrl.h
@@ -51,14 +51,14 @@ public:
51 LLIconCtrl(const LLString& name, const LLRect &rect, const LLUUID &image_id); 51 LLIconCtrl(const LLString& name, const LLRect &rect, const LLUUID &image_id);
52 LLIconCtrl(const LLString& name, const LLRect &rect, const LLString &image_name); 52 LLIconCtrl(const LLString& name, const LLRect &rect, const LLString &image_name);
53 virtual ~LLIconCtrl(); 53 virtual ~LLIconCtrl();
54 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_ICON; }
55 virtual LLString getWidgetTag() const { return LL_ICON_CTRL_TAG; }
56 54
57 // llview overrides 55 // llview overrides
58 virtual void draw(); 56 virtual void draw();
59 57
60 void setImage(const LLUUID &image_id); 58 void setImage(const LLString& image_name);
59 void setImage(const LLUUID& image_name);
61 const LLUUID &getImage() const { return mImageID; } 60 const LLUUID &getImage() const { return mImageID; }
61 LLString getImageName() const { return mImageName; }
62 62
63 // Takes a UUID, wraps get/setImage 63 // Takes a UUID, wraps get/setImage
64 virtual void setValue(const LLSD& value ); 64 virtual void setValue(const LLSD& value );
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp
index 1c96bc4..aeb906c 100644
--- a/linden/indra/llui/lllineeditor.cpp
+++ b/linden/indra/llui/lllineeditor.cpp
@@ -70,7 +70,6 @@ const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
70const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing 70const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing
71const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing 71const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
72const F32 AUTO_SCROLL_TIME = 0.05f; 72const F32 AUTO_SCROLL_TIME = 0.05f;
73const F32 LABEL_HPAD = 5.f;
74 73
75const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f; 74const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f;
76const S32 PREEDIT_MARKER_GAP = 1; 75const S32 PREEDIT_MARKER_GAP = 1;
@@ -81,6 +80,10 @@ const S32 PREEDIT_STANDOUT_GAP = 1;
81const S32 PREEDIT_STANDOUT_POSITION = 2; 80const S32 PREEDIT_STANDOUT_POSITION = 2;
82const S32 PREEDIT_STANDOUT_THICKNESS = 2; 81const S32 PREEDIT_STANDOUT_THICKNESS = 2;
83 82
83static LLRegisterWidget<LLLineEditor> r1("line_editor");
84
85/* static */ LLPointer<LLUIImage> LLLineEditor::sImage;
86
84// 87//
85// Member functions 88// Member functions
86// 89//
@@ -101,8 +104,8 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
101 mMaxLengthBytes(max_length_bytes), 104 mMaxLengthBytes(max_length_bytes),
102 mCursorPos( 0 ), 105 mCursorPos( 0 ),
103 mScrollHPos( 0 ), 106 mScrollHPos( 0 ),
104 mBorderLeft(0), 107 mTextPadLeft(0),
105 mBorderRight(0), 108 mTextPadRight(0),
106 mCommitOnFocusLost( TRUE ), 109 mCommitOnFocusLost( TRUE ),
107 mRevertOnEsc( TRUE ), 110 mRevertOnEsc( TRUE ),
108 mKeystrokeCallback( keystroke_callback ), 111 mKeystrokeCallback( keystroke_callback ),
@@ -128,7 +131,8 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
128 mHandleEditKeysDirectly( FALSE ), 131 mHandleEditKeysDirectly( FALSE ),
129 mSelectAllonFocusReceived( FALSE ), 132 mSelectAllonFocusReceived( FALSE ),
130 mPassDelete(FALSE), 133 mPassDelete(FALSE),
131 mReadOnly(FALSE) 134 mReadOnly(FALSE),
135 mImage( sImage )
132{ 136{
133 llassert( max_length_bytes > 0 ); 137 llassert( max_length_bytes > 0 );
134 138
@@ -151,8 +155,7 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
151 155
152 setFocusLostCallback(focus_lost_callback); 156 setFocusLostCallback(focus_lost_callback);
153 157
154 mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; 158 setTextPadding(0, 0);
155 mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight;
156 159
157 mScrollTimer.reset(); 160 mScrollTimer.reset();
158 161
@@ -166,6 +169,12 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
166 mBorder = new LLViewBorder( "line ed border", border_rect, border_bevel, border_style, mBorderThickness ); 169 mBorder = new LLViewBorder( "line ed border", border_rect, border_bevel, border_style, mBorderThickness );
167 addChild( mBorder ); 170 addChild( mBorder );
168 mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM); 171 mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM);
172
173 if( ! sImage)
174 {
175 sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga");
176 }
177 mImage = sImage;
169} 178}
170 179
171 180
@@ -243,9 +252,9 @@ void LLLineEditor::updateHistory()
243 252
244void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) 253void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
245{ 254{
246 LLUICtrl::reshape(width, height, called_from_parent ); 255 LLUICtrl::reshape(width, height, called_from_parent);
247 256 setTextPadding(mTextPadLeft, mTextPadRight); // For clamping side-effect.
248 mMaxHPixels = getRect().getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; 257 setCursor(mCursorPos); // For clamping side-effect.
249} 258}
250 259
251void LLLineEditor::setEnabled(BOOL enabled) 260void LLLineEditor::setEnabled(BOOL enabled)
@@ -262,12 +271,12 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length)
262 mMaxLengthBytes = max_len; 271 mMaxLengthBytes = max_len;
263} 272}
264 273
265void LLLineEditor::setBorderWidth(S32 left, S32 right) 274void LLLineEditor::setTextPadding(S32 left, S32 right)
266{ 275{
267 mBorderLeft = llclamp(left, 0, getRect().getWidth()); 276 mTextPadLeft = llclamp(left, 0, getRect().getWidth());
268 mBorderRight = llclamp(right, 0, getRect().getWidth()); 277 mTextPadRight = llclamp(right, 0, getRect().getWidth());
269 mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; 278 mMinHPixels = UI_LINEEDITOR_H_PAD + mTextPadLeft;
270 mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight; 279 mMaxHPixels = getRect().getWidth() - mMinHPixels - mTextPadRight;
271} 280}
272 281
273 282
@@ -483,9 +492,10 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
483 492
484BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) 493BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
485{ 494{
486 if (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight)) 495 // Check first whether the "clear search" button wants to deal with this.
496 if(childrenHandleMouseDown(x, y, mask) != NULL)
487 { 497 {
488 return LLUICtrl::handleMouseDown(x, y, mask); 498 return TRUE;
489 } 499 }
490 if (mSelectAllonFocusReceived 500 if (mSelectAllonFocusReceived
491 && gFocusMgr.getKeyboardFocus() != this) 501 && gFocusMgr.getKeyboardFocus() != this)
@@ -563,61 +573,62 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
563BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) 573BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
564{ 574{
565 BOOL handled = FALSE; 575 BOOL handled = FALSE;
566 if (!hasMouseCapture() && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) 576 // Check first whether the "clear search" button wants to deal with this.
577 if(!hasMouseCapture())
567 { 578 {
568 return LLUICtrl::handleHover(x, y, mask); 579 if(childrenHandleHover(x, y, mask) != NULL)
580 {
581 return TRUE;
582 }
569 } 583 }
570 584
571 if( getVisible() ) 585 if( (hasMouseCapture()) && mIsSelecting )
572 { 586 {
573 if( (hasMouseCapture()) && mIsSelecting ) 587 if (x != mLastSelectionX || y != mLastSelectionY)
574 { 588 {
575 if (x != mLastSelectionX || y != mLastSelectionY) 589 mLastSelectionX = x;
590 mLastSelectionY = y;
591 }
592 // Scroll if mouse cursor outside of bounds
593 if (mScrollTimer.hasExpired())
594 {
595 S32 increment = llround(mScrollTimer.getElapsedTimeF32() / AUTO_SCROLL_TIME);
596 mScrollTimer.reset();
597 mScrollTimer.setTimerExpirySec(AUTO_SCROLL_TIME);
598 if( (x < mMinHPixels) && (mScrollHPos > 0 ) )
576 { 599 {
577 mLastSelectionX = x; 600 // Scroll to the left
578 mLastSelectionY = y; 601 mScrollHPos = llclamp(mScrollHPos - increment, 0, mText.length());
579 } 602 }
580 // Scroll if mouse cursor outside of bounds 603 else
581 if (mScrollTimer.hasExpired()) 604 if( (x > mMaxHPixels) && (mCursorPos < (S32)mText.length()) )
582 { 605 {
583 S32 increment = llround(mScrollTimer.getElapsedTimeF32() / AUTO_SCROLL_TIME); 606 // If scrolling one pixel would make a difference...
584 mScrollTimer.reset(); 607 S32 pixels_after_scrolling_one_char = findPixelNearestPos(1);
585 mScrollTimer.setTimerExpirySec(AUTO_SCROLL_TIME); 608 if( pixels_after_scrolling_one_char >= mMaxHPixels )
586 if( (x < mMinHPixels) && (mScrollHPos > 0 ) )
587 {
588 // Scroll to the left
589 mScrollHPos = llclamp(mScrollHPos - increment, 0, mText.length());
590 }
591 else
592 if( (x > mMaxHPixels) && (mCursorPos < (S32)mText.length()) )
593 { 609 {
594 // If scrolling one pixel would make a difference... 610 // ...scroll to the right
595 S32 pixels_after_scrolling_one_char = findPixelNearestPos(1); 611 mScrollHPos = llclamp(mScrollHPos + increment, 0, mText.length());
596 if( pixels_after_scrolling_one_char >= mMaxHPixels )
597 {
598 // ...scroll to the right
599 mScrollHPos = llclamp(mScrollHPos + increment, 0, mText.length());
600 }
601 } 612 }
602 } 613 }
614 }
603 615
604 setCursorAtLocalPos( x ); 616 setCursorAtLocalPos( x );
605 mSelectionEnd = getCursor(); 617 mSelectionEnd = getCursor();
606 618
607 // delay cursor flashing 619 // delay cursor flashing
608 mKeystrokeTimer.reset(); 620 mKeystrokeTimer.reset();
609 621
610 getWindow()->setCursor(UI_CURSOR_IBEAM); 622 getWindow()->setCursor(UI_CURSOR_IBEAM);
611 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; 623 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
612 handled = TRUE; 624 handled = TRUE;
613 } 625 }
614 626
615 if( !handled ) 627 if( !handled )
616 { 628 {
617 getWindow()->setCursor(UI_CURSOR_IBEAM); 629 getWindow()->setCursor(UI_CURSOR_IBEAM);
618 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; 630 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
619 handled = TRUE; 631 handled = TRUE;
620 }
621 } 632 }
622 633
623 return handled; 634 return handled;
@@ -634,9 +645,10 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask)
634 handled = TRUE; 645 handled = TRUE;
635 } 646 }
636 647
637 if (!handled && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) 648 // Check first whether the "clear search" button wants to deal with this.
649 if(!handled && childrenHandleMouseUp(x, y, mask) != NULL)
638 { 650 {
639 return LLUICtrl::handleMouseUp(x, y, mask); 651 return TRUE;
640 } 652 }
641 653
642 if( mIsSelecting ) 654 if( mIsSelecting )
@@ -1223,12 +1235,12 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
1223} 1235}
1224 1236
1225 1237
1226BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) 1238BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
1227{ 1239{
1228 BOOL handled = FALSE; 1240 BOOL handled = FALSE;
1229 BOOL selection_modified = FALSE; 1241 BOOL selection_modified = FALSE;
1230 1242
1231 if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible()) 1243 if ( gFocusMgr.getKeyboardFocus() == this )
1232 { 1244 {
1233 LLLineEditorRollback rollback( this ); 1245 LLLineEditorRollback rollback( this );
1234 1246
@@ -1291,7 +1303,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
1291} 1303}
1292 1304
1293 1305
1294BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) 1306BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
1295{ 1307{
1296 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL 1308 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
1297 { 1309 {
@@ -1381,11 +1393,6 @@ void LLLineEditor::doDelete()
1381 1393
1382void LLLineEditor::draw() 1394void LLLineEditor::draw()
1383{ 1395{
1384 if( !getVisible() )
1385 {
1386 return;
1387 }
1388
1389 S32 text_len = mText.length(); 1396 S32 text_len = mText.length();
1390 1397
1391 LLString saved_text; 1398 LLString saved_text;
@@ -1406,6 +1413,13 @@ void LLLineEditor::draw()
1406 1413
1407 LLColor4 bg_color = mReadOnlyBgColor; 1414 LLColor4 bg_color = mReadOnlyBgColor;
1408 1415
1416#if 0 // for when we're ready for image art.
1417 if( hasFocus())
1418 {
1419 mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
1420 }
1421 mImage->draw(getLocalRect(), mReadOnly ? mReadOnlyBgColor : mWriteableBgColor );
1422#else // the old programmer art.
1409 // drawing solids requires texturing be disabled 1423 // drawing solids requires texturing be disabled
1410 { 1424 {
1411 LLGLSNoTexture no_texture; 1425 LLGLSNoTexture no_texture;
@@ -1423,6 +1437,7 @@ void LLLineEditor::draw()
1423 } 1437 }
1424 gl_rect_2d(background, bg_color); 1438 gl_rect_2d(background, bg_color);
1425 } 1439 }
1440#endif
1426 1441
1427 // draw text 1442 // draw text
1428 1443
@@ -1560,10 +1575,14 @@ void LLLineEditor::draw()
1560 mMaxHPixels - llround(rendered_pixels_right), 1575 mMaxHPixels - llround(rendered_pixels_right),
1561 &rendered_pixels_right); 1576 &rendered_pixels_right);
1562 } 1577 }
1578#if 0 // for when we're ready for image art.
1579 mBorder->setVisible(FALSE); // no more programmatic art.
1580#endif
1563 1581
1564 // If we're editing... 1582 // If we're editing...
1565 if( gFocusMgr.getKeyboardFocus() == this) 1583 if( gFocusMgr.getKeyboardFocus() == this)
1566 { 1584 {
1585 //mBorder->setVisible(TRUE); // ok, programmer art just this once.
1567 // (Flash the cursor every half second) 1586 // (Flash the cursor every half second)
1568 if (gShowTextEditCursor && !mReadOnly) 1587 if (gShowTextEditCursor && !mReadOnly)
1569 { 1588 {
@@ -1616,7 +1635,7 @@ void LLLineEditor::draw()
1616 if (0 == mText.length()) 1635 if (0 == mText.length())
1617 { 1636 {
1618 mGLFont->render(mLabel.getWString(), 0, 1637 mGLFont->render(mLabel.getWString(), 0,
1619 LABEL_HPAD, (F32)text_bottom, 1638 mMinHPixels, (F32)text_bottom,
1620 label_color, 1639 label_color,
1621 LLFontGL::LEFT, LLFontGL::BOTTOM, 1640 LLFontGL::LEFT, LLFontGL::BOTTOM,
1622 LLFontGL::NORMAL, 1641 LLFontGL::NORMAL,
@@ -1757,7 +1776,7 @@ BOOL LLLineEditor::prevalidateFloat(const LLWString &str)
1757 if( 0 < len ) 1776 if( 0 < len )
1758 { 1777 {
1759 // May be a comma or period, depending on the locale 1778 // May be a comma or period, depending on the locale
1760 llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); 1779 llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
1761 1780
1762 S32 i = 0; 1781 S32 i = 0;
1763 1782
@@ -1806,7 +1825,7 @@ BOOL LLLineEditor::postvalidateFloat(const LLString &str)
1806 } 1825 }
1807 1826
1808 // May be a comma or period, depending on the locale 1827 // May be a comma or period, depending on the locale
1809 llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); 1828 llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
1810 1829
1811 for( ; i < len; i++ ) 1830 for( ; i < len; i++ )
1812 { 1831 {
@@ -2244,8 +2263,27 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
2244 return line_editor; 2263 return line_editor;
2245} 2264}
2246 2265
2266//static
2267void LLLineEditor::cleanupClass()
2268{
2269 sImage = NULL;
2270}
2271
2272/* static */
2273LLPointer<LLUIImage> LLLineEditor::parseImage(LLString name, LLXMLNodePtr from, LLPointer<LLUIImage> def)
2274{
2275 LLString xml_name;
2276 if (from->hasAttribute(name)) from->getAttributeString(name, xml_name);
2277 if (xml_name == LLString::null) return def;
2278 LLPointer<LLUIImage> image = LLUI::getUIImage(xml_name);
2279 return image.isNull() ? def : image;
2280}
2281
2247void LLLineEditor::setColorParameters(LLXMLNodePtr node) 2282void LLLineEditor::setColorParameters(LLXMLNodePtr node)
2248{ 2283{
2284 // overrides default image if supplied.
2285 mImage = parseImage("image", node, mImage);
2286
2249 LLColor4 color; 2287 LLColor4 color;
2250 if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) 2288 if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color))
2251 { 2289 {
@@ -2510,6 +2548,9 @@ S32 LLLineEditor::getPreeditFontSize() const
2510} 2548}
2511 2549
2512 2550
2551static LLRegisterWidget<LLSearchEditor> r2("search_editor");
2552
2553
2513LLSearchEditor::LLSearchEditor(const LLString& name, 2554LLSearchEditor::LLSearchEditor(const LLString& name,
2514 const LLRect& rect, 2555 const LLRect& rect,
2515 S32 max_length_bytes, 2556 S32 max_length_bytes,
@@ -2539,7 +2580,7 @@ LLSearchEditor::LLSearchEditor(const LLString& name,
2539 LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0); 2580 LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0);
2540 mClearSearchButton = new LLButton("clear search", 2581 mClearSearchButton = new LLButton("clear search",
2541 clear_btn_rect, 2582 clear_btn_rect,
2542 "closebox.tga", 2583 "icn_clear_lineeditor.tga",
2543 "UIImgBtnCloseInactiveUUID", 2584 "UIImgBtnCloseInactiveUUID",
2544 LLString::null, 2585 LLString::null,
2545 onClearSearch, 2586 onClearSearch,
@@ -2552,9 +2593,42 @@ LLSearchEditor::LLSearchEditor(const LLString& name,
2552 mClearSearchButton->setTabStop(FALSE); 2593 mClearSearchButton->setTabStop(FALSE);
2553 mSearchEdit->addChild(mClearSearchButton); 2594 mSearchEdit->addChild(mClearSearchButton);
2554 2595
2555 mSearchEdit->setBorderWidth(0, btn_width); 2596 mSearchEdit->setTextPadding(0, btn_width);
2597}
2598
2599
2600//virtual
2601void LLSearchEditor::setValue(const LLSD& value )
2602{
2603 mSearchEdit->setValue(value);
2604}
2605
2606//virtual
2607LLSD LLSearchEditor::getValue() const
2608{
2609 return mSearchEdit->getValue();
2556} 2610}
2557 2611
2612//virtual
2613BOOL LLSearchEditor::setTextArg( const LLString& key, const LLStringExplicit& text )
2614{
2615 return mSearchEdit->setTextArg(key, text);
2616}
2617
2618//virtual
2619BOOL LLSearchEditor::setLabelArg( const LLString& key, const LLStringExplicit& text )
2620{
2621 return mSearchEdit->setLabelArg(key, text);
2622}
2623
2624//virtual
2625void LLSearchEditor::clear()
2626{
2627 if (mSearchEdit)
2628 {
2629 mSearchEdit->clear();
2630 }
2631}
2558 2632
2559void LLSearchEditor::draw() 2633void LLSearchEditor::draw()
2560{ 2634{
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h
index ba3c697..bf0dcb5 100644
--- a/linden/indra/llui/lllineeditor.h
+++ b/linden/indra/llui/lllineeditor.h
@@ -78,19 +78,19 @@ public:
78 S32 border_thickness = 1); 78 S32 border_thickness = 1);
79 79
80 virtual ~LLLineEditor(); 80 virtual ~LLLineEditor();
81 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LINE_EDITOR; } 81
82 virtual LLString getWidgetTag() const { return LL_LINE_EDITOR_TAG; };
83 virtual LLXMLNodePtr getXML(bool save_children = true) const; 82 virtual LLXMLNodePtr getXML(bool save_children = true) const;
84 void setColorParameters(LLXMLNodePtr node); 83 void setColorParameters(LLXMLNodePtr node);
85 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 84 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
85 static void cleanupClass();
86 86
87 // mousehandler overrides 87 // mousehandler overrides
88 /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); 88 /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
89 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); 89 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
90 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); 90 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
91 /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); 91 /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask);
92 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ); 92 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
93 /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); 93 /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
94 /*virtual*/ void onMouseCaptureLost(); 94 /*virtual*/ void onMouseCaptureLost();
95 95
96 // LLEditMenuHandler overrides 96 // LLEditMenuHandler overrides
@@ -189,8 +189,8 @@ public:
189 189
190 void setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data)); 190 void setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data));
191 191
192 void setMaxTextLength(S32 max_text_length); 192 void setMaxTextLength(S32 max_text_length);
193 void setBorderWidth(S32 left, S32 right); 193 void setTextPadding(S32 left, S32 right); // Used to specify room for children before or after text.
194 194
195 static BOOL isPartOfWord(llwchar c); 195 static BOOL isPartOfWord(llwchar c);
196 // Prevalidation controls which keystrokes can affect the editor 196 // Prevalidation controls which keystrokes can affect the editor
@@ -212,7 +212,7 @@ public:
212 void updateHistory(); // stores current line in history 212 void updateHistory(); // stores current line in history
213 213
214private: 214private:
215 // private helper classes 215 // private helper methods
216 void removeChar(); 216 void removeChar();
217 void addChar(const llwchar c); 217 void addChar(const llwchar c);
218 void setCursorAtLocalPos(S32 local_mouse_x); 218 void setCursorAtLocalPos(S32 local_mouse_x);
@@ -254,10 +254,10 @@ protected:
254 S32 mCursorPos; // I-beam is just after the mCursorPos-th character. 254 S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
255 S32 mScrollHPos; // Horizontal offset from the start of mText. Used for scrolling. 255 S32 mScrollHPos; // Horizontal offset from the start of mText. Used for scrolling.
256 LLFrameTimer mScrollTimer; 256 LLFrameTimer mScrollTimer;
257 S32 mTextPadLeft; // Used to reserve space before the beginning of the text for children.
258 S32 mTextPadRight; // Used to reserve space after the end of the text for children.
257 S32 mMinHPixels; 259 S32 mMinHPixels;
258 S32 mMaxHPixels; 260 S32 mMaxHPixels;
259 S32 mBorderLeft;
260 S32 mBorderRight;
261 261
262 BOOL mCommitOnFocusLost; 262 BOOL mCommitOnFocusLost;
263 BOOL mRevertOnEsc; 263 BOOL mRevertOnEsc;
@@ -302,6 +302,15 @@ protected:
302 std::vector<S32> mPreeditPositions; 302 std::vector<S32> mPreeditPositions;
303 LLPreeditor::standouts_t mPreeditStandouts; 303 LLPreeditor::standouts_t mPreeditStandouts;
304 304
305private:
306 // Utility on top of LLUI::getUIImage, looks up a named image in a given XML node and returns it if possible
307 // or returns a given default image if anything in the process fails.
308 static LLPointer<LLUIImage> parseImage(LLString name, LLXMLNodePtr from, LLPointer<LLUIImage> def);
309 // Global instance used as default for member instance below.
310 static LLPointer<LLUIImage> sImage;
311 // Instances that by default point to the statics but can be overidden in XML.
312 LLPointer<LLUIImage> mImage;
313
305 // private helper class 314 // private helper class
306 class LLLineEditorRollback 315 class LLLineEditorRollback
307 { 316 {
@@ -359,8 +368,6 @@ public:
359 368
360 /*virtual*/ void draw(); 369 /*virtual*/ void draw();
361 370
362 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SEARCH_EDITOR; }
363 virtual LLString getWidgetTag() const { return LL_SEARCH_EDITOR_TAG; }
364 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 371 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
365 372
366 void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); } 373 void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); }
@@ -368,12 +375,11 @@ public:
368 void setSearchCallback(void (*search_callback)(const LLString& search_string, void* user_data), void* data) { mSearchCallback = search_callback; mCallbackUserData = data; } 375 void setSearchCallback(void (*search_callback)(const LLString& search_string, void* user_data), void* data) { mSearchCallback = search_callback; mCallbackUserData = data; }
369 376
370 // LLUICtrl interface 377 // LLUICtrl interface
371 virtual void setValue(const LLSD& value ) { mSearchEdit->setValue(value); } 378 virtual void setValue(const LLSD& value );
372 virtual LLSD getValue() const { return mSearchEdit->getValue(); } 379 virtual LLSD getValue() const;
373 virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ) { return mSearchEdit->setTextArg( key, text); } 380 virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text );
374 virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ) { return mSearchEdit->setLabelArg(key, text); } 381 virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text );
375 virtual void clear() { if (mSearchEdit) mSearchEdit->clear(); } 382 virtual void clear();
376
377 383
378private: 384private:
379 static void onSearchEdit(LLLineEditor* caller, void* user_data ); 385 static void onSearchEdit(LLLineEditor* caller, void* user_data );
diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp
index cb54476..f2486f1 100644
--- a/linden/indra/llui/llmenugl.cpp
+++ b/linden/indra/llui/llmenugl.cpp
@@ -188,31 +188,6 @@ LLXMLNodePtr LLMenuItemGL::getXML(bool save_children) const
188 return node; 188 return node;
189} 189}
190 190
191BOOL LLMenuItemGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
192{
193 // modified from LLView::handleKey
194 // ignore visibility, as keyboard accelerators should still trigger menu items
195 // even when they are not visible
196 // also, ignore enabled flag for self, as that can change based on menu callbacks
197 BOOL handled = FALSE;
198
199 if( called_from_parent )
200 {
201 // Downward traversal
202 if (getEnabled())
203 {
204 handled = childrenHandleKey( key, mask ) != NULL;
205 }
206 }
207
208 if( !handled )
209 {
210 handled = handleKeyHere( key, mask, called_from_parent );
211 }
212
213 return handled;
214}
215
216BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) 191BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
217{ 192{
218 if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) 193 if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
@@ -400,7 +375,7 @@ void LLMenuItemGL::doIt( void )
400} 375}
401 376
402 377
403BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) 378BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask )
404{ 379{
405 if (getHighlight() && 380 if (getHighlight() &&
406 getMenu()->isOpen()) 381 getMenu()->isOpen())
@@ -436,29 +411,21 @@ BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
436 411
437BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK ) 412BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK )
438{ 413{
439 if (getEnabled()) 414 // switch to mouse navigation mode
440 { 415 LLMenuGL::setKeyboardMode(FALSE);
441 // switch to mouse navigation mode
442 LLMenuGL::setKeyboardMode(FALSE);
443 416
444 doIt(); 417 doIt();
445 make_ui_sound("UISndClickRelease"); 418 make_ui_sound("UISndClickRelease");
446 return TRUE; 419 return TRUE;
447 }
448 return FALSE;
449} 420}
450 421
451BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK ) 422BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK )
452{ 423{
453 if (getEnabled()) 424 // switch to mouse navigation mode
454 { 425 LLMenuGL::setKeyboardMode(FALSE);
455 // switch to mouse navigation mode
456 LLMenuGL::setKeyboardMode(FALSE);
457 426
458 setHighlight(TRUE); 427 setHighlight(TRUE);
459 return TRUE; 428 return TRUE;
460 }
461 return FALSE;
462} 429}
463 430
464 431
@@ -560,9 +527,6 @@ public:
560 527
561 virtual LLString getType() const { return "separator"; } 528 virtual LLString getType() const { return "separator"; }
562 529
563 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_SEPARATOR; }
564 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_SEPARATOR_GL_TAG; }
565
566 // doIt() - do the primary funcationality of the menu item. 530 // doIt() - do the primary funcationality of the menu item.
567 virtual void doIt( void ) {} 531 virtual void doIt( void ) {}
568 532
@@ -641,9 +605,6 @@ class LLMenuItemVerticalSeparatorGL
641public: 605public:
642 LLMenuItemVerticalSeparatorGL( void ); 606 LLMenuItemVerticalSeparatorGL( void );
643 607
644 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_SEPARATOR_VERTICAL; }
645 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_VERTICAL_SEPARATOR_GL_TAG; }
646
647 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; } 608 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }
648}; 609};
649 610
@@ -739,8 +700,6 @@ public:
739 { 700 {
740 setEnabled(FALSE); 701 setEnabled(FALSE);
741 } 702 }
742 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_BLANK; }
743 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_BLANK_GL_TAG; }
744 virtual void doIt( void ) {} 703 virtual void doIt( void ) {}
745 virtual void draw( void ) {} 704 virtual void draw( void ) {}
746}; 705};
@@ -827,57 +786,33 @@ void LLMenuItemCallGL::setEnabledControl(LLString enabled_control, LLView *conte
827 // Register new listener 786 // Register new listener
828 if (!enabled_control.empty()) 787 if (!enabled_control.empty())
829 { 788 {
830 LLControlBase *control = context->findControl(enabled_control); 789 LLControlVariable *control = context->findControl(enabled_control);
831 if (control) 790 if (!control)
832 {
833 LLSD state = control->registerListener(this, "ENABLED");
834 setEnabled(state);
835 }
836 else
837 { 791 {
838 context->addBoolControl(enabled_control, getEnabled()); 792 context->addBoolControl(enabled_control, getEnabled());
839 control = context->findControl(enabled_control); 793 control = context->findControl(enabled_control);
840 control->registerListener(this, "ENABLED"); 794 llassert_always(control);
841 } 795 }
796 control->getSignal()->connect(boost::bind(&LLView::controlListener, _1, getHandle(), std::string("enabled")));
797 setEnabled(control->getValue());
842 } 798 }
843} 799}
844 800
845void LLMenuItemCallGL::setVisibleControl(LLString enabled_control, LLView *context) 801void LLMenuItemCallGL::setVisibleControl(LLString visible_control, LLView *context)
846{ 802{
847 // Register new listener 803 // Register new listener
848 if (!enabled_control.empty()) 804 if (!visible_control.empty())
849 { 805 {
850 LLControlBase *control = context->findControl(enabled_control); 806 LLControlVariable *control = context->findControl(visible_control);
851 if (control) 807 if (!control)
852 { 808 {
853 LLSD state = control->registerListener(this, "VISIBLE"); 809 context->addBoolControl(visible_control, getVisible());
854 setVisible(state); 810 control = context->findControl(visible_control);
811 llassert_always(control);
855 } 812 }
856 else 813 control->getSignal()->connect(boost::bind(&LLView::controlListener, _1, getHandle(), std::string("visible")));
857 { 814 setVisible(control->getValue());
858 context->addBoolControl(enabled_control, getEnabled());
859 control = context->findControl(enabled_control);
860 control->registerListener(this, "VISIBLE");
861 }
862 }
863}
864
865// virtual
866bool LLMenuItemCallGL::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
867{
868 if (userdata.asString() == "ENABLED" && event->desc() == "value_changed")
869 {
870 LLSD state = event->getValue();
871 setEnabled(state);
872 return TRUE;
873 } 815 }
874 if (userdata.asString() == "VISIBLE" && event->desc() == "value_changed")
875 {
876 LLSD state = event->getValue();
877 setVisible(state);
878 return TRUE;
879 }
880 return LLMenuItemGL::handleEvent(event, userdata);
881} 816}
882 817
883// virtual 818// virtual
@@ -1000,44 +935,35 @@ LLMenuItemCheckGL::LLMenuItemCheckGL ( const LLString& name,
1000 setControlName(control_name, context); 935 setControlName(control_name, context);
1001} 936}
1002 937
1003void LLMenuItemCheckGL::setCheckedControl(LLString checked_control, LLView *context) 938//virtual
939void LLMenuItemCheckGL::setValue(const LLSD& value)
1004{ 940{
1005 // Register new listener 941 mChecked = value.asBoolean();
1006 if (!checked_control.empty()) 942 if(mChecked)
1007 { 943 {
1008 LLControlBase *control = context->findControl(checked_control); 944 mDrawBoolLabel = BOOLEAN_TRUE_PREFIX;
1009 if (control) 945 }
1010 { 946 else
1011 LLSD state = control->registerListener(this, "CHECKED"); 947 {
1012 mChecked = state; 948 mDrawBoolLabel.clear();
1013 }
1014 else
1015 {
1016 context->addBoolControl(checked_control, mChecked);
1017 control = context->findControl(checked_control);
1018 control->registerListener(this, "CHECKED");
1019 }
1020 } 949 }
1021} 950}
1022 951
1023// virtual 952void LLMenuItemCheckGL::setCheckedControl(LLString checked_control, LLView *context)
1024bool LLMenuItemCheckGL::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1025{ 953{
1026 if (userdata.asString() == "CHECKED" && event->desc() == "value_changed") 954 // Register new listener
955 if (!checked_control.empty())
1027 { 956 {
1028 LLSD state = event->getValue(); 957 LLControlVariable *control = context->findControl(checked_control);
1029 mChecked = state; 958 if (!control)
1030 if(mChecked)
1031 {
1032 mDrawBoolLabel = BOOLEAN_TRUE_PREFIX;
1033 }
1034 else
1035 { 959 {
1036 mDrawBoolLabel.clear(); 960 context->addBoolControl(checked_control, mChecked);
961 control = context->findControl(checked_control);
962 llassert_always(control);
1037 } 963 }
1038 return TRUE; 964 control->getSignal()->connect(boost::bind(&LLView::controlListener, _1, getHandle(), std::string("value")));
965 mChecked = control->getValue();
1039 } 966 }
1040 return LLMenuItemCallGL::handleEvent(event, userdata);
1041} 967}
1042 968
1043// virtual 969// virtual
@@ -1119,29 +1045,31 @@ LLMenuItemBranchGL::LLMenuItemBranchGL( const LLString& name, const LLString& la
1119} 1045}
1120 1046
1121// virtual 1047// virtual
1122LLView* LLMenuItemBranchGL::getChildByName(const LLString& name, BOOL recurse) const 1048LLView* LLMenuItemBranchGL::getChildView(const LLString& name, BOOL recurse, BOOL create_if_missing) const
1123{ 1049{
1050 // richard: this is redundant with parent, remove
1124 if (mBranch->getName() == name) 1051 if (mBranch->getName() == name)
1125 { 1052 {
1126 return mBranch; 1053 return mBranch;
1127 } 1054 }
1128 // Always recurse on branches 1055 // Always recurse on branches
1129 return mBranch->getChild<LLView>(name, recurse); 1056 LLView* child = mBranch->getChildView(name, recurse, FALSE);
1057 if (!child)
1058 {
1059 child = LLView::getChildView(name, recurse, create_if_missing);
1060 }
1061 return child;
1130} 1062}
1131 1063
1132// virtual 1064// virtual
1133BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask) 1065BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask)
1134{ 1066{
1135 if (getEnabled()) 1067 // switch to mouse navigation mode
1136 { 1068 LLMenuGL::setKeyboardMode(FALSE);
1137 // switch to mouse navigation mode
1138 LLMenuGL::setKeyboardMode(FALSE);
1139 1069
1140 doIt(); 1070 doIt();
1141 make_ui_sound("UISndClickRelease"); 1071 make_ui_sound("UISndClickRelease");
1142 return TRUE; 1072 return TRUE;
1143 }
1144 return FALSE;
1145} 1073}
1146 1074
1147BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask) 1075BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
@@ -1299,7 +1227,7 @@ void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility )
1299 LLMenuItemGL::onVisibilityChange(new_visibility); 1227 LLMenuItemGL::onVisibilityChange(new_visibility);
1300} 1228}
1301 1229
1302BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) 1230BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
1303{ 1231{
1304 if (getMenu()->getVisible() && mBranch->getVisible() && key == KEY_LEFT) 1232 if (getMenu()->getVisible() && mBranch->getVisible() && key == KEY_LEFT)
1305 { 1233 {
@@ -1318,8 +1246,7 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_par
1318 return handled; 1246 return handled;
1319 } 1247 }
1320 1248
1321 if (getEnabled() && 1249 if (getHighlight() &&
1322 getHighlight() &&
1323 getMenu()->isOpen() && 1250 getMenu()->isOpen() &&
1324 key == KEY_RIGHT && !mBranch->getHighlightedItem()) 1251 key == KEY_RIGHT && !mBranch->getHighlightedItem())
1325 { 1252 {
@@ -1333,7 +1260,7 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_par
1333 } 1260 }
1334 } 1261 }
1335 1262
1336 return LLMenuItemGL::handleKeyHere(key, mask, called_from_parent); 1263 return LLMenuItemGL::handleKeyHere(key, mask);
1337} 1264}
1338 1265
1339void LLMenuItemBranchGL::openMenu() 1266void LLMenuItemBranchGL::openMenu()
@@ -1403,9 +1330,6 @@ public:
1403 LLMenuItemBranchDownGL( const LLString& name, const LLString& label, LLMenuGL* branch, 1330 LLMenuItemBranchDownGL( const LLString& name, const LLString& label, LLMenuGL* branch,
1404 KEY key = KEY_NONE, MASK mask = MASK_NONE ); 1331 KEY key = KEY_NONE, MASK mask = MASK_NONE );
1405 1332
1406 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_BRANCH_DOWN; }
1407 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_BRANCH_DOWN_GL_TAG; }
1408
1409 virtual LLString getType() const { return "menu"; } 1333 virtual LLString getType() const { return "menu"; }
1410 1334
1411 // returns the normal width of this control in pixels - this is 1335 // returns the normal width of this control in pixels - this is
@@ -1429,7 +1353,7 @@ public:
1429 virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); 1353 virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
1430 virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); 1354 virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
1431 virtual void draw( void ); 1355 virtual void draw( void );
1432 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 1356 virtual BOOL handleKeyHere(KEY key, MASK mask);
1433 1357
1434 virtual BOOL handleAcceleratorKey(KEY key, MASK mask); 1358 virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
1435}; 1359};
@@ -1566,7 +1490,7 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask)
1566 return handled; 1490 return handled;
1567} 1491}
1568 1492
1569BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 1493BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask)
1570{ 1494{
1571 BOOL menu_open = getBranch()->getVisible(); 1495 BOOL menu_open = getBranch()->getVisible();
1572 // don't do keyboard navigation of top-level menus unless in keyboard mode, or menu expanded 1496 // don't do keyboard navigation of top-level menus unless in keyboard mode, or menu expanded
@@ -1605,7 +1529,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_
1605 // switch to keyboard navigation mode 1529 // switch to keyboard navigation mode
1606 LLMenuGL::setKeyboardMode(TRUE); 1530 LLMenuGL::setKeyboardMode(TRUE);
1607 1531
1608 if (getEnabled() && !isActive()) 1532 if (!isActive())
1609 { 1533 {
1610 doIt(); 1534 doIt();
1611 } 1535 }
@@ -1617,7 +1541,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_
1617 // switch to keyboard navigation mode 1541 // switch to keyboard navigation mode
1618 LLMenuGL::setKeyboardMode(TRUE); 1542 LLMenuGL::setKeyboardMode(TRUE);
1619 1543
1620 if (getEnabled() && !isActive()) 1544 if (!isActive())
1621 { 1545 {
1622 doIt(); 1546 doIt();
1623 } 1547 }
@@ -1690,6 +1614,8 @@ void LLMenuItemBranchDownGL::draw( void )
1690/// Class LLMenuGL 1614/// Class LLMenuGL
1691///============================================================================ 1615///============================================================================
1692 1616
1617static LLRegisterWidget<LLMenuGL> r1("menu");
1618
1693// Default constructor 1619// Default constructor
1694LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLHandle<LLFloater> parent_floater_handle ) 1620LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLHandle<LLFloater> parent_floater_handle )
1695: LLUICtrl( name, LLRect(), FALSE, NULL, NULL ), 1621: LLUICtrl( name, LLRect(), FALSE, NULL, NULL ),
@@ -1946,7 +1872,7 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
1946 { 1872 {
1947 continue; 1873 continue;
1948 } 1874 }
1949 LLControlBase *control = parent->findControl(control_name); 1875 LLControlVariable *control = parent->findControl(control_name);
1950 if (!control) 1876 if (!control)
1951 { 1877 {
1952 parent->addBoolControl(control_name, FALSE); 1878 parent->addBoolControl(control_name, FALSE);
@@ -2685,8 +2611,8 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa
2685 2611
2686 while(1) 2612 while(1)
2687 { 2613 {
2688 // skip separators and disabled items 2614 // skip separators and disabled/invisible items
2689 if ((*next_item_iter)->getEnabled() && (*next_item_iter)->getType() != SEPARATOR_NAME) 2615 if ((*next_item_iter)->getEnabled() && (*next_item_iter)->getVisible() && (*next_item_iter)->getType() != SEPARATOR_NAME)
2690 { 2616 {
2691 if (cur_item) 2617 if (cur_item)
2692 { 2618 {
@@ -2751,8 +2677,8 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa
2751 2677
2752 while(1) 2678 while(1)
2753 { 2679 {
2754 // skip separators and disabled items 2680 // skip separators and disabled/invisible items
2755 if ((*prev_item_iter)->getEnabled() && (*prev_item_iter)->getName() != SEPARATOR_NAME) 2681 if ((*prev_item_iter)->getEnabled() && (*prev_item_iter)->getVisible() && (*prev_item_iter)->getName() != SEPARATOR_NAME)
2756 { 2682 {
2757 (*prev_item_iter)->setHighlight(TRUE); 2683 (*prev_item_iter)->setHighlight(TRUE);
2758 return (*prev_item_iter); 2684 return (*prev_item_iter);
@@ -2801,37 +2727,6 @@ void LLMenuGL::updateParent(LLView* parentp)
2801 } 2727 }
2802} 2728}
2803 2729
2804// LLView functionality
2805BOOL LLMenuGL::handleKey( KEY key, MASK mask, BOOL called_from_parent )
2806{
2807 BOOL handled = FALSE;
2808
2809 // Pass down even if not visible
2810 if( getEnabled() && called_from_parent )
2811 {
2812 for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
2813 {
2814 LLView* viewp = *child_it;
2815 if (viewp->handleKey(key, mask, TRUE))
2816 {
2817 handled = TRUE;
2818 break;
2819 }
2820 }
2821 }
2822
2823 if( !handled )
2824 {
2825 handled = handleKeyHere( key, mask, called_from_parent );
2826 if (handled && LLView::sDebugKeys)
2827 {
2828 llinfos << "Key handled by " << getName() << llendl;
2829 }
2830 }
2831
2832 return handled;
2833}
2834
2835BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask) 2730BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask)
2836{ 2731{
2837 // don't handle if not enabled 2732 // don't handle if not enabled
@@ -2854,7 +2749,7 @@ BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask)
2854 return FALSE; 2749 return FALSE;
2855} 2750}
2856 2751
2857BOOL LLMenuGL::handleUnicodeCharHere( llwchar uni_char, BOOL called_from_parent ) 2752BOOL LLMenuGL::handleUnicodeCharHere( llwchar uni_char )
2858{ 2753{
2859 if (jumpKeysActive()) 2754 if (jumpKeysActive())
2860 { 2755 {
@@ -2980,17 +2875,19 @@ void LLMenuGL::setVisible(BOOL visible)
2980 2875
2981LLMenuGL* LLMenuGL::getChildMenuByName(const LLString& name, BOOL recurse) const 2876LLMenuGL* LLMenuGL::getChildMenuByName(const LLString& name, BOOL recurse) const
2982{ 2877{
2983 LLView* view = getChildByName(name, recurse); 2878 LLView* view = getChildView(name, recurse, FALSE);
2984 if (view) 2879 if (view)
2985 { 2880 {
2986 if (view->getWidgetType() == WIDGET_TYPE_MENU_ITEM_BRANCH) 2881 LLMenuItemBranchGL* branch = dynamic_cast<LLMenuItemBranchGL*>(view);
2882 if (branch)
2987 { 2883 {
2988 LLMenuItemBranchGL *branch = (LLMenuItemBranchGL *)view;
2989 return branch->getBranch(); 2884 return branch->getBranch();
2990 } 2885 }
2991 if (view->getWidgetType() == WIDGET_TYPE_MENU || view->getWidgetType() == WIDGET_TYPE_PIE_MENU) 2886
2887 LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
2888 if (menup)
2992 { 2889 {
2993 return (LLMenuGL*)view; 2890 return menup;
2994 } 2891 }
2995 } 2892 }
2996 llwarns << "Child Menu " << name << " not found in menu " << getName() << llendl; 2893 llwarns << "Child Menu " << name << " not found in menu " << getName() << llendl;
@@ -3070,9 +2967,6 @@ class LLPieMenuBranch : public LLMenuItemGL
3070public: 2967public:
3071 LLPieMenuBranch(const LLString& name, const LLString& label, LLPieMenu* branch); 2968 LLPieMenuBranch(const LLString& name, const LLString& label, LLPieMenu* branch);
3072 2969
3073 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_PIE_MENU_BRANCH; }
3074 virtual LLString getWidgetTag() const { return LL_PIE_MENU_BRANCH_TAG; }
3075
3076 // called to rebuild the draw label 2970 // called to rebuild the draw label
3077 virtual void buildDrawLabel( void ); 2971 virtual void buildDrawLabel( void );
3078 2972
@@ -3842,6 +3736,8 @@ void LLPieMenu::hide(BOOL item_selected)
3842/// Class LLMenuBarGL 3736/// Class LLMenuBarGL
3843///============================================================================ 3737///============================================================================
3844 3738
3739static LLRegisterWidget<LLMenuBarGL> r2("menu_bar");
3740
3845// Default constructor 3741// Default constructor
3846LLMenuBarGL::LLMenuBarGL( const LLString& name ) : LLMenuGL ( name, name ) 3742LLMenuBarGL::LLMenuBarGL( const LLString& name ) : LLMenuGL ( name, name )
3847{ 3743{
@@ -3897,9 +3793,10 @@ LLView* LLMenuBarGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
3897 LLMenuBarGL *menubar = new LLMenuBarGL(name); 3793 LLMenuBarGL *menubar = new LLMenuBarGL(name);
3898 3794
3899 LLHandle<LLFloater> parent_handle; 3795 LLHandle<LLFloater> parent_handle;
3900 if (parent->getWidgetType() == WIDGET_TYPE_FLOATER) 3796 LLFloater* parent_floater = dynamic_cast<LLFloater*>(parent);
3797 if (parent_floater)
3901 { 3798 {
3902 parent_handle = ((LLFloater*)parent)->getHandle(); 3799 parent_handle = parent_floater->getHandle();
3903 } 3800 }
3904 3801
3905 // We need to have the rect early so that it's around when building 3802 // We need to have the rect early so that it's around when building
@@ -3991,7 +3888,7 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask)
3991 return result; 3888 return result;
3992} 3889}
3993 3890
3994BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 3891BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask)
3995{ 3892{
3996 if(key == KEY_ALT && !gKeyboard->getKeyRepeated(key) && LLUI::sConfigGroup->getBOOL("UseAltKeyForMenus")) 3893 if(key == KEY_ALT && !gKeyboard->getKeyRepeated(key) && LLUI::sConfigGroup->getBOOL("UseAltKeyForMenus"))
3997 { 3894 {
@@ -4005,7 +3902,7 @@ BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
4005 // before processing any other key, check to see if ALT key has triggered menu access 3902 // before processing any other key, check to see if ALT key has triggered menu access
4006 checkMenuTrigger(); 3903 checkMenuTrigger();
4007 3904
4008 return LLMenuGL::handleKeyHere(key, mask, called_from_parent); 3905 return LLMenuGL::handleKeyHere(key, mask);
4009} 3906}
4010 3907
4011BOOL LLMenuBarGL::handleJumpKey(KEY key) 3908BOOL LLMenuBarGL::handleJumpKey(KEY key)
@@ -4295,7 +4192,7 @@ BOOL LLMenuHolderGL::hasVisibleMenu() const
4295 for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) 4192 for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
4296 { 4193 {
4297 LLView* viewp = *child_it; 4194 LLView* viewp = *child_it;
4298 if (viewp->getVisible() && viewp->getWidgetType() != WIDGET_TYPE_MENU_BAR) 4195 if (viewp->getVisible() && dynamic_cast<LLMenuBarGL*>(viewp) == NULL)
4299 { 4196 {
4300 return TRUE; 4197 return TRUE;
4301 } 4198 }
@@ -4319,7 +4216,7 @@ BOOL LLMenuHolderGL::hideMenus()
4319 { 4216 {
4320 LLView* viewp = *child_it; 4217 LLView* viewp = *child_it;
4321 // clicks off of menu do not hide menu bar 4218 // clicks off of menu do not hide menu bar
4322 if (viewp->getWidgetType() != WIDGET_TYPE_MENU_BAR && viewp->getVisible()) 4219 if (dynamic_cast<LLMenuBarGL*>(viewp) == NULL && viewp->getVisible())
4323 { 4220 {
4324 viewp->setVisible(FALSE); 4221 viewp->setVisible(FALSE);
4325 } 4222 }
@@ -4429,7 +4326,7 @@ BOOL LLTearOffMenu::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
4429 return mMenu->handleUnicodeChar(uni_char, TRUE); 4326 return mMenu->handleUnicodeChar(uni_char, TRUE);
4430} 4327}
4431 4328
4432BOOL LLTearOffMenu::handleKey(KEY key, MASK mask, BOOL called_from_parent) 4329BOOL LLTearOffMenu::handleKeyHere(KEY key, MASK mask)
4433{ 4330{
4434 if (!mMenu->getHighlightedItem()) 4331 if (!mMenu->getHighlightedItem())
4435 { 4332 {
diff --git a/linden/indra/llui/llmenugl.h b/linden/indra/llui/llmenugl.h
index cd39006..e7b009a 100644
--- a/linden/indra/llui/llmenugl.h
+++ b/linden/indra/llui/llmenugl.h
@@ -91,14 +91,11 @@ public:
91 LLMenuItemGL( const LLString& name, const LLString& label, KEY key = KEY_NONE, MASK = MASK_NONE ); 91 LLMenuItemGL( const LLString& name, const LLString& label, KEY key = KEY_NONE, MASK = MASK_NONE );
92 92
93 virtual void setValue(const LLSD& value) { setLabel(value.asString()); } 93 virtual void setValue(const LLSD& value) { setLabel(value.asString()); }
94 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM; }
95 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_TAG; }
96 94
97 virtual LLXMLNodePtr getXML(bool save_children = true) const; 95 virtual LLXMLNodePtr getXML(bool save_children = true) const;
98 96
99 virtual LLString getType() const { return "item"; } 97 virtual LLString getType() const { return "item"; }
100 98
101 virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
102 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 99 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
103 100
104 virtual BOOL handleAcceleratorKey(KEY key, MASK mask); 101 virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
@@ -165,7 +162,7 @@ public:
165 virtual void setEnabledSubMenus(BOOL enable){}; 162 virtual void setEnabledSubMenus(BOOL enable){};
166 163
167 // LLView Functionality 164 // LLView Functionality
168 virtual BOOL handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ); 165 virtual BOOL handleKeyHere( KEY key, MASK mask );
169 virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); 166 virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
170 virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); 167 virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
171 virtual void draw( void ); 168 virtual void draw( void );
@@ -225,7 +222,7 @@ private:
225// calls a user defined callback. 222// calls a user defined callback.
226//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 223//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
227 224
228class LLMenuItemCallGL : public LLMenuItemGL 225class LLMenuItemCallGL : public LLMenuItemGL, public LLObservable
229{ 226{
230public: 227public:
231 // normal constructor 228 // normal constructor
@@ -267,8 +264,6 @@ public:
267 264
268 virtual LLString getType() const { return "call"; } 265 virtual LLString getType() const { return "call"; }
269 266
270 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_CALL; }
271 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_CALL_GL_TAG; }
272 267
273 void setEnabledControl(LLString enabled_control, LLView *context); 268 void setEnabledControl(LLString enabled_control, LLView *context);
274 void setVisibleControl(LLString enabled_control, LLView *context); 269 void setVisibleControl(LLString enabled_control, LLView *context);
@@ -291,7 +286,6 @@ public:
291 286
292 //virtual void draw(); 287 //virtual void draw();
293 288
294 virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
295 289
296private: 290private:
297 menu_callback mCallback; 291 menu_callback mCallback;
@@ -341,17 +335,13 @@ public:
341 335
342 void setCheckedControl(LLString checked_control, LLView *context); 336 void setCheckedControl(LLString checked_control, LLView *context);
343 337
344 virtual void setValue(const LLSD& value) { mChecked = value.asBoolean(); } 338 virtual void setValue(const LLSD& value);
345 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_CHECK; }
346 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_CHECK_GL_TAG; }
347 339
348 virtual LLString getType() const { return "check"; } 340 virtual LLString getType() const { return "check"; }
349 341
350 // called to rebuild the draw label 342 // called to rebuild the draw label
351 virtual void buildDrawLabel( void ); 343 virtual void buildDrawLabel( void );
352 344
353 virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
354
355private: 345private:
356 check_callback mCheckCallback; 346 check_callback mCheckCallback;
357 BOOL mChecked; 347 BOOL mChecked;
@@ -408,6 +398,8 @@ class LLMenuGL
408// TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united. 398// TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united.
409// I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG 399// I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG
410{ 400{
401 // let branching menu items use my protected traversal methods
402 friend class LLMenuItemBranchGL;
411public: 403public:
412 LLMenuGL( const LLString& name, const LLString& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>()); 404 LLMenuGL( const LLString& name, const LLString& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>());
413 LLMenuGL( const LLString& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>() ); 405 LLMenuGL( const LLString& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>() );
@@ -417,13 +409,9 @@ public:
417 409
418 void parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory); 410 void parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory);
419 411
420 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU; }
421 virtual LLString getWidgetTag() const { return LL_MENU_GL_TAG; }
422 412
423 // LLView Functionality 413 // LLView Functionality
424 virtual BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); 414 virtual BOOL handleUnicodeCharHere( llwchar uni_char );
425 //virtual BOOL handleKeyHere( KEY key, MASK mask, BOOL called_from_parent );
426 virtual BOOL handleUnicodeCharHere( llwchar uni_char, BOOL called_from_parent );
427 virtual BOOL handleHover( S32 x, S32 y, MASK mask ); 415 virtual BOOL handleHover( S32 x, S32 y, MASK mask );
428 virtual void draw( void ); 416 virtual void draw( void );
429 virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color); 417 virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
@@ -579,9 +567,6 @@ public:
579 567
580 virtual LLString getType() const { return "menu"; } 568 virtual LLString getType() const { return "menu"; }
581 569
582 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_BRANCH; }
583 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_BRANCH_GL_TAG; }
584
585 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); 570 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
586 571
587 virtual BOOL handleAcceleratorKey(KEY key, MASK mask); 572 virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
@@ -602,7 +587,7 @@ public:
602 // active. This is used for behavior transfer. 587 // active. This is used for behavior transfer.
603 virtual void setHighlight( BOOL highlight ); 588 virtual void setHighlight( BOOL highlight );
604 589
605 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 590 virtual BOOL handleKeyHere(KEY key, MASK mask);
606 591
607 virtual BOOL isActive() const { return isOpen() && mBranch->getHighlightedItem(); } 592 virtual BOOL isActive() const { return isOpen() && mBranch->getHighlightedItem(); }
608 593
@@ -621,8 +606,7 @@ public:
621 606
622 virtual void openMenu(); 607 virtual void openMenu();
623 608
624protected: 609 virtual LLView* getChildView(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
625 virtual LLView* getChildByName(const LLString& name, BOOL recurse) const;
626 610
627private: 611private:
628 LLMenuGL* mBranch; 612 LLMenuGL* mBranch;
@@ -643,16 +627,12 @@ public:
643 LLPieMenu(const LLString& name); 627 LLPieMenu(const LLString& name);
644 virtual ~LLPieMenu() {} 628 virtual ~LLPieMenu() {}
645 629
646 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_PIE_MENU; }
647 virtual LLString getWidgetTag() const { return LL_PIE_MENU_TAG; }
648
649 void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory); 630 void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory);
650 631
651 // LLView Functionality 632 // LLView Functionality
652 // can't set visibility directly, must call show or hide 633 // can't set visibility directly, must call show or hide
653 virtual void setVisible(BOOL visible); 634 virtual void setVisible(BOOL visible);
654 635
655 //virtual BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
656 virtual BOOL handleHover( S32 x, S32 y, MASK mask ); 636 virtual BOOL handleHover( S32 x, S32 y, MASK mask );
657 virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); 637 virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
658 virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); 638 virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
@@ -672,7 +652,6 @@ public:
672 void show(S32 x, S32 y, BOOL mouse_down); 652 void show(S32 x, S32 y, BOOL mouse_down);
673 void hide(BOOL item_selected); 653 void hide(BOOL item_selected);
674 654
675
676private: 655private:
677 LLMenuItemGL *pieItemFromXY(S32 x, S32 y); 656 LLMenuItemGL *pieItemFromXY(S32 x, S32 y);
678 S32 pieItemIndexFromXY(S32 x, S32 y); 657 S32 pieItemIndexFromXY(S32 x, S32 y);
@@ -708,11 +687,8 @@ public:
708 virtual LLXMLNodePtr getXML(bool save_children = true) const; 687 virtual LLXMLNodePtr getXML(bool save_children = true) const;
709 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 688 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
710 689
711 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_BAR; }
712 virtual LLString getWidgetTag() const { return LL_MENU_BAR_GL_TAG; }
713
714 virtual BOOL handleAcceleratorKey(KEY key, MASK mask); 690 virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
715 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 691 virtual BOOL handleKeyHere(KEY key, MASK mask);
716 virtual BOOL handleJumpKey(KEY key); 692 virtual BOOL handleJumpKey(KEY key);
717 693
718 // rearrange the child rects so they fit the shape of the menu 694 // rearrange the child rects so they fit the shape of the menu
@@ -754,9 +730,6 @@ public:
754 LLMenuHolderGL(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows = FOLLOWS_NONE); 730 LLMenuHolderGL(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows = FOLLOWS_NONE);
755 virtual ~LLMenuHolderGL() {} 731 virtual ~LLMenuHolderGL() {}
756 732
757 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_HOLDER; }
758 virtual LLString getWidgetTag() const { return LL_MENU_HOLDER_GL_TAG; }
759
760 virtual BOOL hideMenus(); 733 virtual BOOL hideMenus();
761 void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); 734 void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
762 void setCanHide(BOOL can_hide) { mCanHide = can_hide; } 735 void setCanHide(BOOL can_hide) { mCanHide = can_hide; }
@@ -794,7 +767,7 @@ public:
794 virtual void onFocusReceived(); 767 virtual void onFocusReceived();
795 virtual void onFocusLost(); 768 virtual void onFocusLost();
796 virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); 769 virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
797 virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); 770 virtual BOOL handleKeyHere(KEY key, MASK mask);
798 virtual void translate(S32 x, S32 y); 771 virtual void translate(S32 x, S32 y);
799 772
800private: 773private:
@@ -816,9 +789,6 @@ class LLMenuItemTearOffGL : public LLMenuItemGL
816public: 789public:
817 LLMenuItemTearOffGL( LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); 790 LLMenuItemTearOffGL( LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>());
818 791
819 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEAROFF_MENU; }
820 virtual LLString getWidgetTag() const { return LL_MENU_ITEM_TEAR_OFF_GL_TAG; }
821
822 virtual LLString getType() const { return "tearoff_menu"; } 792 virtual LLString getType() const { return "tearoff_menu"; }
823 793
824 virtual void doIt(void); 794 virtual void doIt(void);
diff --git a/linden/indra/llui/llmodaldialog.cpp b/linden/indra/llui/llmodaldialog.cpp
index 392c122..160495d 100644
--- a/linden/indra/llui/llmodaldialog.cpp
+++ b/linden/indra/llui/llmodaldialog.cpp
@@ -211,11 +211,9 @@ BOOL LLModalDialog::handleRightMouseDown(S32 x, S32 y, MASK mask)
211} 211}
212 212
213 213
214BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) 214BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask )
215{ 215{
216 childrenHandleKey(key, mask); 216 LLFloater::handleKeyHere(key, mask );
217
218 LLFloater::handleKeyHere(key, mask, called_from_parent );
219 217
220 if (mModal) 218 if (mModal)
221 { 219 {
@@ -246,33 +244,30 @@ void LLModalDialog::onClose(bool app_quitting)
246// virtual 244// virtual
247void LLModalDialog::draw() 245void LLModalDialog::draw()
248{ 246{
249 if (getVisible()) 247 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
250 { 248 S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
251 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow"); 249
252 S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater"); 250 gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0,
251 shadow_color, shadow_lines);
253 252
254 gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0, 253 LLFloater::draw();
255 shadow_color, shadow_lines); 254
255 if (mModal)
256 {
257 // If we've lost focus to a non-child, get it back ASAP.
258 if( gFocusMgr.getTopCtrl() != this )
259 {
260 gFocusMgr.setTopCtrl( this );
261 }
256 262
257 LLFloater::draw(); 263 if( !gFocusMgr.childHasKeyboardFocus( this ) )
264 {
265 setFocus(TRUE);
266 }
258 267
259 if (mModal) 268 if( !gFocusMgr.childHasMouseCapture( this ) )
260 { 269 {
261 // If we've lost focus to a non-child, get it back ASAP. 270 gFocusMgr.setMouseCapture( this );
262 if( gFocusMgr.getTopCtrl() != this )
263 {
264 gFocusMgr.setTopCtrl( this );
265 }
266
267 if( !gFocusMgr.childHasKeyboardFocus( this ) )
268 {
269 setFocus(TRUE);
270 }
271
272 if( !gFocusMgr.childHasMouseCapture( this ) )
273 {
274 gFocusMgr.setMouseCapture( this );
275 }
276 } 271 }
277 } 272 }
278} 273}
diff --git a/linden/indra/llui/llmodaldialog.h b/linden/indra/llui/llmodaldialog.h
index 0199498..77bd9db 100644
--- a/linden/indra/llui/llmodaldialog.h
+++ b/linden/indra/llui/llmodaldialog.h
@@ -60,7 +60,7 @@ public:
60 /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 60 /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
61 /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); 61 /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
62 /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); 62 /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
63 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ); 63 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
64 64
65 /*virtual*/ void onClose(bool app_quitting); 65 /*virtual*/ void onClose(bool app_quitting);
66 66
diff --git a/linden/indra/llui/llmultislider.cpp b/linden/indra/llui/llmultislider.cpp
index d0c9002..dfa36fa 100644
--- a/linden/indra/llui/llmultislider.cpp
+++ b/linden/indra/llui/llmultislider.cpp
@@ -43,6 +43,8 @@
43 43
44#include <sstream> 44#include <sstream>
45 45
46static LLRegisterWidget<LLMultiSlider> r("multi_slider_bar");
47
46const S32 MULTI_THUMB_WIDTH = 8; 48const S32 MULTI_THUMB_WIDTH = 8;
47const S32 MULTI_TRACK_HEIGHT = 6; 49const S32 MULTI_TRACK_HEIGHT = 6;
48const F32 FLOAT_THRESHOLD = 0.00001f; 50const F32 FLOAT_THRESHOLD = 0.00001f;
@@ -98,16 +100,6 @@ LLMultiSlider::LLMultiSlider(
98 setValue(getValue()); 100 setValue(getValue());
99} 101}
100 102
101EWidgetType LLMultiSlider::getWidgetType() const
102{
103 return WIDGET_TYPE_MULTI_SLIDER_BAR;
104}
105
106LLString LLMultiSlider::getWidgetTag() const
107{
108 return LL_MULTI_SLIDER_TAG;
109}
110
111void LLMultiSlider::setSliderValue(const LLString& name, F32 value, BOOL from_event) 103void LLMultiSlider::setSliderValue(const LLString& name, F32 value, BOOL from_event)
112{ 104{
113 // exit if not there 105 // exit if not there
@@ -403,31 +395,28 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
403 return TRUE; 395 return TRUE;
404} 396}
405 397
406BOOL LLMultiSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 398BOOL LLMultiSlider::handleKeyHere(KEY key, MASK mask)
407{ 399{
408 BOOL handled = FALSE; 400 BOOL handled = FALSE;
409 if( getVisible() && getEnabled() && !called_from_parent ) 401 switch(key)
410 { 402 {
411 switch(key) 403 case KEY_UP:
412 { 404 case KEY_DOWN:
413 case KEY_UP: 405 // eat up and down keys to be consistent
414 case KEY_DOWN: 406 handled = TRUE;
415 // eat up and down keys to be consistent 407 break;
416 handled = TRUE; 408 case KEY_LEFT:
417 break; 409 setCurSliderValue(getCurSliderValue() - getIncrement());
418 case KEY_LEFT: 410 onCommit();
419 setCurSliderValue(getCurSliderValue() - getIncrement()); 411 handled = TRUE;
420 onCommit(); 412 break;
421 handled = TRUE; 413 case KEY_RIGHT:
422 break; 414 setCurSliderValue(getCurSliderValue() + getIncrement());
423 case KEY_RIGHT: 415 onCommit();
424 setCurSliderValue(getCurSliderValue() + getIncrement()); 416 handled = TRUE;
425 onCommit(); 417 break;
426 handled = TRUE; 418 default:
427 break; 419 break;
428 default:
429 break;
430 }
431 } 420 }
432 return handled; 421 return handled;
433} 422}
@@ -438,177 +427,142 @@ void LLMultiSlider::draw()
438 427
439 std::map<LLString, LLRect>::iterator mIt; 428 std::map<LLString, LLRect>::iterator mIt;
440 std::map<LLString, LLRect>::iterator curSldrIt; 429 std::map<LLString, LLRect>::iterator curSldrIt;
441 if( getVisible() )
442 {
443 // Draw background and thumb.
444 430
445 // drawing solids requires texturing be disabled 431 // Draw background and thumb.
446 LLGLSNoTexture no_texture;
447 432
448 LLRect rect(mDragStartThumbRect); 433 // drawing solids requires texturing be disabled
434 LLGLSNoTexture no_texture;
449 435
450 F32 opacity = getEnabled() ? 1.f : 0.3f; 436 LLRect rect(mDragStartThumbRect);
451 437
452 // Track 438 F32 opacity = getEnabled() ? 1.f : 0.3f;
453 LLUUID thumb_image_id;
454 thumb_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga"));
455 LLPointer<LLImageGL> thumb_imagep(LLUI::sImageProvider->getUIImageByID(thumb_image_id)->getImage());
456 439
457 S32 height_offset = (getRect().getHeight() - MULTI_TRACK_HEIGHT) / 2; 440 // Track
458 LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset ); 441 LLUIImagePtr thumb_imagep = LLUI::sImageProvider->getUIImage("rounded_square.tga");
459 442
443 S32 height_offset = (getRect().getHeight() - MULTI_TRACK_HEIGHT) / 2;
444 LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset );
460 445
461 if(mDrawTrack)
462 {
463 track_rect.stretch(-1);
464 gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 16, 16, track_rect.getWidth(), track_rect.getHeight(),
465 thumb_imagep, mTrackColor % opacity);
466 }
467 446
468 // if we're supposed to use a drawn triangle 447 if(mDrawTrack)
469 // simple gl call for the triangle 448 {
470 if(mUseTriangle) { 449 track_rect.stretch(-1);
450 thumb_imagep->draw(track_rect, mTrackColor % opacity);
451 }
471 452
472 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { 453 // if we're supposed to use a drawn triangle
454 // simple gl call for the triangle
455 if(mUseTriangle) {
473 456
474 gl_triangle_2d( 457 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) {
475 mIt->second.mLeft - EXTRA_TRIANGLE_WIDTH, 458
476 mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT, 459 gl_triangle_2d(
477 mIt->second.mRight + EXTRA_TRIANGLE_WIDTH, 460 mIt->second.mLeft - EXTRA_TRIANGLE_WIDTH,
478 mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT, 461 mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT,
479 mIt->second.mLeft + mIt->second.getWidth() / 2, 462 mIt->second.mRight + EXTRA_TRIANGLE_WIDTH,
480 mIt->second.mBottom - EXTRA_TRIANGLE_HEIGHT, 463 mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT,
481 mTriangleColor, TRUE); 464 mIt->second.mLeft + mIt->second.getWidth() / 2,
482 } 465 mIt->second.mBottom - EXTRA_TRIANGLE_HEIGHT,
466 mTriangleColor, TRUE);
483 } 467 }
484 else if (!thumb_imagep) 468 }
485 { 469 else if (!thumb_imagep)
486 // draw all the thumbs 470 {
487 curSldrIt = mThumbRects.end(); 471 // draw all the thumbs
488 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { 472 curSldrIt = mThumbRects.end();
473 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) {
474
475 // choose the color
476 curThumbColor = mThumbCenterColor;
477 if(mIt->first == mCurSlider) {
489 478
490 // choose the color 479 curSldrIt = mIt;
491 curThumbColor = mThumbCenterColor; 480 continue;
492 if(mIt->first == mCurSlider) { 481 //curThumbColor = mThumbCenterSelectedColor;
493
494 curSldrIt = mIt;
495 continue;
496 //curThumbColor = mThumbCenterSelectedColor;
497 }
498
499 // the draw command
500 gl_rect_2d(mIt->second, curThumbColor, TRUE);
501 } 482 }
502 483
503 // now draw the current slider 484 // the draw command
504 if(curSldrIt != mThumbRects.end()) { 485 gl_rect_2d(mIt->second, curThumbColor, TRUE);
505 gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor, TRUE); 486 }
506 }
507 487
508 // and draw the drag start 488 // now draw the current slider
509 if (gFocusMgr.getMouseCapture() == this) 489 if(curSldrIt != mThumbRects.end()) {
510 { 490 gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor, TRUE);
511 gl_rect_2d(mDragStartThumbRect, mThumbCenterColor % opacity, FALSE);
512 }
513 } 491 }
514 else if( gFocusMgr.getMouseCapture() == this ) 492
493 // and draw the drag start
494 if (gFocusMgr.getMouseCapture() == this)
515 { 495 {
516 // draw drag start 496 gl_rect_2d(mDragStartThumbRect, mThumbCenterColor % opacity, FALSE);
517 gl_draw_scaled_image_with_border(mDragStartThumbRect.mLeft, 497 }
518 mDragStartThumbRect.mBottom, 16, 16, 498 }
519 mDragStartThumbRect.getWidth(), 499 else if( gFocusMgr.getMouseCapture() == this )
520 mDragStartThumbRect.getHeight(), 500 {
521 thumb_imagep, mThumbCenterColor % 0.3f, TRUE); 501 // draw drag start
522 502 thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor % 0.3f);
523 // draw the highlight 503
524 if (hasFocus()) 504 // draw the highlight
505 if (hasFocus())
506 {
507 thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
508 }
509
510 // draw the thumbs
511 curSldrIt = mThumbRects.end();
512 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++)
513 {
514 // choose the color
515 curThumbColor = mThumbCenterColor;
516 if(mIt->first == mCurSlider)
525 { 517 {
526 F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); 518 // don't draw now, draw last
527 LLRect highlight_rect = mThumbRects[mCurSlider]; 519 curSldrIt = mIt;
528 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); 520 continue;
529 gl_draw_scaled_image_with_border(highlight_rect.mLeft,
530 highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(),
531 highlight_rect.getHeight(),
532 thumb_imagep, gFocusMgr.getFocusColor());
533 } 521 }
522
523 // the draw command
524 thumb_imagep->drawSolid(mIt->second, curThumbColor);
525 }
526
527 // draw cur slider last
528 if(curSldrIt != mThumbRects.end())
529 {
530 thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor);
531 }
532
533 }
534 else
535 {
536 // draw highlight
537 if (hasFocus())
538 {
539 thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
540 }
534 541
535 // draw the thumbs 542 // draw thumbs
536 curSldrIt = mThumbRects.end(); 543 curSldrIt = mThumbRects.end();
537 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { 544 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++)
538 545 {
539 // choose the color
540 curThumbColor = mThumbCenterColor;
541 if(mIt->first == mCurSlider) {
542 // don't draw now, draw last
543 curSldrIt = mIt;
544 continue;
545 }
546
547 // the draw command
548 gl_draw_scaled_image_with_border(
549 mIt->second.mLeft,
550 mIt->second.mBottom, 16, 16,
551 mIt->second.getWidth(),
552 mIt->second.getHeight(), thumb_imagep,
553 curThumbColor, TRUE);
554 }
555 546
556 // draw cur slider last 547 // choose the color
557 if(curSldrIt != mThumbRects.end()) { 548 curThumbColor = mThumbCenterColor;
558 gl_draw_scaled_image_with_border( 549 if(mIt->first == mCurSlider)
559 curSldrIt->second.mLeft, 550 {
560 curSldrIt->second.mBottom, 16, 16, 551 curSldrIt = mIt;
561 curSldrIt->second.getWidth(), 552 continue;
562 curSldrIt->second.getHeight(), thumb_imagep, 553 //curThumbColor = mThumbCenterSelectedColor;
563 mThumbCenterSelectedColor, TRUE); 554 }
564 }
565 555
556 thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity);
566 } 557 }
567 else
568 {
569 // draw highlight
570 if (hasFocus())
571 {
572 F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
573 LLRect highlight_rect = mThumbRects[mCurSlider];
574 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt)));
575 gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(),
576 thumb_imagep, gFocusMgr.getFocusColor());
577 }
578 558
579 // draw thumbs 559 if(curSldrIt != mThumbRects.end())
580 curSldrIt = mThumbRects.end(); 560 {
581 for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { 561 thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor % opacity);
582
583 // choose the color
584 curThumbColor = mThumbCenterColor;
585 if(mIt->first == mCurSlider) {
586 curSldrIt = mIt;
587 continue;
588 //curThumbColor = mThumbCenterSelectedColor;
589 }
590
591 // the draw command
592 gl_draw_scaled_image_with_border(
593 mIt->second.mLeft,
594 mIt->second.mBottom, 16, 16,
595 mIt->second.getWidth(),
596 mIt->second.getHeight(), thumb_imagep,
597 curThumbColor % opacity, TRUE);
598 }
599
600 if(curSldrIt != mThumbRects.end()) {
601 gl_draw_scaled_image_with_border(
602 curSldrIt->second.mLeft,
603 curSldrIt->second.mBottom, 16, 16,
604 curSldrIt->second.getWidth(),
605 curSldrIt->second.getHeight(), thumb_imagep,
606 mThumbCenterSelectedColor % opacity, TRUE);
607 }
608 } 562 }
609
610 LLUICtrl::draw();
611 } 563 }
564
565 LLUICtrl::draw();
612} 566}
613 567
614// virtual 568// virtual
diff --git a/linden/indra/llui/llmultislider.h b/linden/indra/llui/llmultislider.h
index 7cd5061..df6153a 100644
--- a/linden/indra/llui/llmultislider.h
+++ b/linden/indra/llui/llmultislider.h
@@ -55,8 +55,6 @@ public:
55 BOOL use_triangle, 55 BOOL use_triangle,
56 const LLString& control_name = LLString::null ); 56 const LLString& control_name = LLString::null );
57 57
58 virtual EWidgetType getWidgetType() const;
59 virtual LLString getWidgetTag() const;
60 virtual LLXMLNodePtr getXML(bool save_children = true) const; 58 virtual LLXMLNodePtr getXML(bool save_children = true) const;
61 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 59 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
62 60
@@ -94,7 +92,7 @@ public:
94 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 92 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
95 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); 93 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
96 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 94 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
97 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 95 virtual BOOL handleKeyHere(KEY key, MASK mask);
98 virtual void draw(); 96 virtual void draw();
99 97
100protected: 98protected:
diff --git a/linden/indra/llui/llmultisliderctrl.cpp b/linden/indra/llui/llmultisliderctrl.cpp
index 47e21d8..c242d18 100644
--- a/linden/indra/llui/llmultisliderctrl.cpp
+++ b/linden/indra/llui/llmultisliderctrl.cpp
@@ -50,6 +50,8 @@
50#include "llfocusmgr.h" 50#include "llfocusmgr.h"
51#include "llresmgr.h" 51#include "llresmgr.h"
52 52
53static LLRegisterWidget<LLMultiSliderCtrl> r("multi_slider");
54
53const U32 MAX_STRING_LENGTH = 10; 55const U32 MAX_STRING_LENGTH = 10;
54 56
55 57
diff --git a/linden/indra/llui/llmultisliderctrl.h b/linden/indra/llui/llmultisliderctrl.h
index 5e2d13c..6a298c8 100644
--- a/linden/indra/llui/llmultisliderctrl.h
+++ b/linden/indra/llui/llmultisliderctrl.h
@@ -71,8 +71,6 @@ public:
71 const LLString& control_which = LLString::null ); 71 const LLString& control_which = LLString::null );
72 72
73 virtual ~LLMultiSliderCtrl(); 73 virtual ~LLMultiSliderCtrl();
74 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MULTI_SLIDER; }
75 virtual LLString getWidgetTag() const { return LL_MULTI_SLIDER_CTRL_TAG; }
76 virtual LLXMLNodePtr getXML(bool save_children = true) const; 74 virtual LLXMLNodePtr getXML(bool save_children = true) const;
77 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 75 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
78 76
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp
index 567d29e..7db3725 100644
--- a/linden/indra/llui/llpanel.cpp
+++ b/linden/indra/llui/llpanel.cpp
@@ -65,6 +65,8 @@ LLPanel::alert_queue_t LLPanel::sAlertQueue;
65const S32 RESIZE_BAR_OVERLAP = 1; 65const S32 RESIZE_BAR_OVERLAP = 1;
66const S32 RESIZE_BAR_HEIGHT = 3; 66const S32 RESIZE_BAR_HEIGHT = 3;
67 67
68static LLRegisterWidget<LLPanel> r1("panel");
69
68void LLPanel::init() 70void LLPanel::init()
69{ 71{
70 // mRectControl 72 // mRectControl
@@ -126,18 +128,6 @@ LLPanel::~LLPanel()
126} 128}
127 129
128// virtual 130// virtual
129EWidgetType LLPanel::getWidgetType() const
130{
131 return WIDGET_TYPE_PANEL;
132}
133
134// virtual
135LLString LLPanel::getWidgetTag() const
136{
137 return LL_PANEL_TAG;
138}
139
140// virtual
141BOOL LLPanel::isPanel() const 131BOOL LLPanel::isPanel() const
142{ 132{
143 return TRUE; 133 return TRUE;
@@ -227,7 +217,8 @@ void LLPanel::updateDefaultBtn()
227 if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) 217 if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled())
228 { 218 {
229 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); 219 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
230 BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(focus_ctrl)->getCommitOnReturn(); 220 LLButton* buttonp = dynamic_cast<LLButton*>(focus_ctrl);
221 BOOL focus_is_child_button = buttonp && buttonp->getCommitOnReturn();
231 // only enable default button when current focus is not a return-capturing button 222 // only enable default button when current focus is not a return-capturing button
232 mDefaultBtn->setBorderEnabled(!focus_is_child_button); 223 mDefaultBtn->setBorderEnabled(!focus_is_child_button);
233 } 224 }
@@ -259,7 +250,7 @@ void LLPanel::setDefaultBtn(LLButton* btn)
259 250
260void LLPanel::setDefaultBtn(const LLString& id) 251void LLPanel::setDefaultBtn(const LLString& id)
261{ 252{
262 LLButton *button = LLUICtrlFactory::getButtonByName(this, id); 253 LLButton *button = getChild<LLButton>(id);
263 if (button) 254 if (button)
264 { 255 {
265 setDefaultBtn(button); 256 setDefaultBtn(button);
@@ -270,77 +261,6 @@ void LLPanel::setDefaultBtn(const LLString& id)
270 } 261 }
271} 262}
272 263
273BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent)
274{
275 BOOL handled = FALSE;
276 if (getVisible() && getEnabled())
277 {
278 if( (mask == MASK_SHIFT) && (KEY_TAB == key))
279 {
280 //SHIFT-TAB
281 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
282 if (cur_focus && gFocusMgr.childHasKeyboardFocus(this))
283 {
284 LLUICtrl* focus_root = cur_focus;
285 while(cur_focus->getParentUICtrl())
286 {
287 cur_focus = cur_focus->getParentUICtrl();
288 if (cur_focus->isFocusRoot())
289 {
290 // this is the root-most focus root found so far
291 focus_root = cur_focus;
292 }
293 }
294 handled = focus_root->focusPrevItem(FALSE);
295 }
296 else if (!cur_focus && isFocusRoot())
297 {
298 handled = focusLastItem();
299 if (!handled)
300 {
301 setFocus(TRUE);
302 handled = TRUE;
303 }
304 }
305 }
306 else
307 if( (mask == MASK_NONE ) && (KEY_TAB == key))
308 {
309 //TAB
310 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
311 if (cur_focus && gFocusMgr.childHasKeyboardFocus(this))
312 {
313 LLUICtrl* focus_root = cur_focus;
314 while(cur_focus->getParentUICtrl())
315 {
316 cur_focus = cur_focus->getParentUICtrl();
317 if (cur_focus->isFocusRoot())
318 {
319 focus_root = cur_focus;
320 }
321 }
322 handled = focus_root->focusNextItem(FALSE);
323 }
324 else if (!cur_focus && isFocusRoot())
325 {
326 handled = focusFirstItem();
327 if (!handled)
328 {
329 setFocus(TRUE);
330 handled = TRUE;
331 }
332 }
333 }
334 }
335
336 if (!handled)
337 {
338 handled = LLView::handleKey(key, mask, called_from_parent);
339 }
340
341 return handled;
342}
343
344void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group) 264void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group)
345{ 265{
346 mLastTabGroup = tab_group; 266 mLastTabGroup = tab_group;
@@ -355,83 +275,90 @@ void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group)
355 LLView::addCtrlAtEnd(ctrl, tab_group); 275 LLView::addCtrlAtEnd(ctrl, tab_group);
356} 276}
357 277
358BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) 278BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
359{ 279{
360 BOOL handled = FALSE; 280 BOOL handled = FALSE;
361 281
362 if( getVisible() && getEnabled() && 282 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
363 gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent )
364 {
365 // handle user hitting ESC to defocus
366 if (key == KEY_ESCAPE)
367 {
368 gFocusMgr.setKeyboardFocus(NULL);
369 return TRUE;
370 }
371 283
372 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); 284 // handle user hitting ESC to defocus
373 // If we have a default button, click it when 285 if (key == KEY_ESCAPE)
374 // return is pressed, unless current focus is a return-capturing button 286 {
375 // in which case *that* button will handle the return key 287 gFocusMgr.setKeyboardFocus(NULL);
376 if (cur_focus && !(cur_focus->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(cur_focus)->getCommitOnReturn())) 288 return TRUE;
289 }
290 else if( (mask == MASK_SHIFT) && (KEY_TAB == key))
291 {
292 //SHIFT-TAB
293 if (cur_focus)
377 { 294 {
378 // RETURN key means hit default button in this case 295 LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
379 if (key == KEY_RETURN && mask == MASK_NONE 296 if (focus_root)
380 && mDefaultBtn != NULL
381 && mDefaultBtn->getVisible()
382 && mDefaultBtn->getEnabled())
383 { 297 {
384 mDefaultBtn->onCommit(); 298 handled = focus_root->focusPrevItem(FALSE);
385 handled = TRUE;
386 } 299 }
387 } 300 }
388 301 }
389 if (key == KEY_RETURN && mask == MASK_NONE) 302 else if( (mask == MASK_NONE ) && (KEY_TAB == key))
303 {
304 //TAB
305 if (cur_focus)
390 { 306 {
391 // set keyboard focus to self to trigger commitOnFocusLost behavior on current ctrl 307 LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
392 if (cur_focus && cur_focus->acceptsTextInput()) 308 if (focus_root)
393 { 309 {
394 cur_focus->onCommit(); 310 handled = focus_root->focusNextItem(FALSE);
395 handled = TRUE;
396 } 311 }
397 } 312 }
398 } 313 }
399 314
400 return handled; 315 // If we have a default button, click it when
401} 316 // return is pressed, unless current focus is a return-capturing button
402 317 // in which case *that* button will handle the return key
403void LLPanel::requires(LLString name, EWidgetType type) 318 LLButton* focused_button = dynamic_cast<LLButton*>(cur_focus);
404{ 319 if (cur_focus && !(focused_button && focused_button->getCommitOnReturn()))
405 mRequirements[name] = type; 320 {
406} 321 // RETURN key means hit default button in this case
407 322 if (key == KEY_RETURN && mask == MASK_NONE
408BOOL LLPanel::checkRequirements() const 323 && mDefaultBtn != NULL
409{ 324 && mDefaultBtn->getVisible()
410 BOOL retval = TRUE; 325 && mDefaultBtn->getEnabled())
411 LLString message; 326 {
327 mDefaultBtn->onCommit();
328 handled = TRUE;
329 }
330 }
412 331
413 for (requirements_map_t::const_iterator i = mRequirements.begin(); i != mRequirements.end(); ++i) 332 if (key == KEY_RETURN && mask == MASK_NONE)
414 { 333 {
415 if (!this->getCtrlByNameAndType(i->first, i->second)) 334 // set keyboard focus to self to trigger commitOnFocusLost behavior on current ctrl
335 if (cur_focus && cur_focus->acceptsTextInput())
416 { 336 {
417 retval = FALSE; 337 cur_focus->onCommit();
418 message += i->first + " " + LLUICtrlFactory::getWidgetType(i->second) + "\n"; 338 handled = TRUE;
419 } 339 }
420 } 340 }
421 341
422 if (!retval) 342 return handled;
343}
344
345BOOL LLPanel::checkRequirements()
346{
347 if (!mRequirementsError.empty())
423 { 348 {
424 LLString::format_map_t args; 349 LLString::format_map_t args;
425 args["[COMPONENTS]"] = message; 350 args["[COMPONENTS]"] = mRequirementsError;
426 args["[FLOATER]"] = getName(); 351 args["[FLOATER]"] = getName();
427 352
428 llwarns << getName() << " failed requirements check on: \n" 353 llwarns << getName() << " failed requirements check on: \n"
429 << message << llendl; 354 << mRequirementsError << llendl;
430 355
431 alertXml("FailedRequirementsCheck", args); 356 alertXml("FailedRequirementsCheck", args);
357 mRequirementsError.clear();
358 return FALSE;
432 } 359 }
433 360
434 return retval; 361 return TRUE;
435} 362}
436 363
437//static 364//static
@@ -494,30 +421,6 @@ void LLPanel::setBorderVisible(BOOL b)
494 } 421 }
495} 422}
496 423
497LLUICtrl* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) const
498{
499 LLView* view = getChildByName(name, TRUE);
500 if (view && view->isCtrl())
501 {
502 if (type == WIDGET_TYPE_DONTCARE || view->getWidgetType() == type)
503 {
504 return (LLUICtrl*)view;
505 }
506 else
507 {
508 llwarns << "Widget " << name << " has improper type in panel " << getName() << "\n"
509 << "Is: \t\t" << view->getWidgetType() << "\n"
510 << "Should be: \t" << type
511 << llendl;
512 }
513 }
514 else
515 {
516 childNotFound(name);
517 }
518 return NULL;
519}
520
521// virtual 424// virtual
522LLXMLNodePtr LLPanel::getXML(bool save_children) const 425LLXMLNodePtr LLPanel::getXML(bool save_children) const
523{ 426{
@@ -973,7 +876,7 @@ BOOL LLPanel::childSetLabelArg(const LLString& id, const LLString& key, const LL
973 876
974BOOL LLPanel::childSetToolTipArg(const LLString& id, const LLString& key, const LLStringExplicit& text) 877BOOL LLPanel::childSetToolTipArg(const LLString& id, const LLString& key, const LLStringExplicit& text)
975{ 878{
976 LLView* child = getChildByName(id, true); 879 LLView* child = getChildView(id, true, FALSE);
977 if (child) 880 if (child)
978 { 881 {
979 return child->setToolTipArg(key, text); 882 return child->setToolTipArg(key, text);
@@ -1001,7 +904,7 @@ void LLPanel::childSetMaxValue(const LLString& id, LLSD max_value)
1001 904
1002void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible) 905void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible)
1003{ 906{
1004 LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); 907 LLTabContainer* child = getChild<LLTabContainer>(id);
1005 if (child) 908 if (child)
1006 { 909 {
1007 child->selectTabByName(tabname); 910 child->selectTabByName(tabname);
@@ -1010,7 +913,7 @@ void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool vis
1010 913
1011LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const 914LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const
1012{ 915{
1013 LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); 916 LLTabContainer* child = getChild<LLTabContainer>(id);
1014 if (child) 917 if (child)
1015 { 918 {
1016 return child->getCurrentPanel(); 919 return child->getCurrentPanel();
@@ -1020,7 +923,7 @@ LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const
1020 923
1021void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata) 924void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata)
1022{ 925{
1023 LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); 926 LLTabContainer* child = getChild<LLTabContainer>(id);
1024 if (child) 927 if (child)
1025 { 928 {
1026 LLPanel *panel = child->getPanelByName(tabname); 929 LLPanel *panel = child->getPanelByName(tabname);
@@ -1034,7 +937,7 @@ void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabn
1034 937
1035void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data) 938void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data)
1036{ 939{
1037 LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id); 940 LLLineEditor* child = getChild<LLLineEditor>(id);
1038 if (child) 941 if (child)
1039 { 942 {
1040 child->setKeystrokeCallback(keystroke_callback); 943 child->setKeystrokeCallback(keystroke_callback);
@@ -1047,7 +950,7 @@ void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_cal
1047 950
1048void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWString &) ) 951void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWString &) )
1049{ 952{
1050 LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id); 953 LLLineEditor* child = getChild<LLLineEditor>(id);
1051 if (child) 954 if (child)
1052 { 955 {
1053 child->setPrevalidate(func); 956 child->setPrevalidate(func);
@@ -1056,7 +959,7 @@ void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWStri
1056 959
1057void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible) 960void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible)
1058{ 961{
1059 LLTextBox* child = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX); 962 LLTextBox* child = getChild<LLTextBox>(id);
1060 if (child) 963 if (child)
1061 { 964 {
1062 child->setVisible(visible); 965 child->setVisible(visible);
@@ -1066,7 +969,7 @@ void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool
1066 969
1067void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* value) 970void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* value)
1068{ 971{
1069 LLButton* button = (LLButton*)getCtrlByNameAndType(id, WIDGET_TYPE_BUTTON); 972 LLButton* button = getChild<LLButton>(id);
1070 if (button) 973 if (button)
1071 { 974 {
1072 button->setClickedCallback(function, value); 975 button->setClickedCallback(function, value);
@@ -1075,7 +978,7 @@ void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* v
1075 978
1076void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*)) 979void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*))
1077{ 980{
1078 LLTextBox* textbox = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX); 981 LLTextBox* textbox = getChild<LLTextBox>(id);
1079 if (textbox) 982 if (textbox)
1080 { 983 {
1081 textbox->setClickedCallback(function); 984 textbox->setClickedCallback(function);
@@ -1092,13 +995,18 @@ void LLPanel::childSetControlName(const LLString& id, const LLString& control_na
1092} 995}
1093 996
1094//virtual 997//virtual
1095LLView* LLPanel::getChildByName(const LLString& name, BOOL recurse) const 998LLView* LLPanel::getChildView(const LLString& name, BOOL recurse, BOOL create_if_missing) const
1096{ 999{
1097 LLView* view = LLUICtrl::getChildByName(name, recurse); 1000 // just get child, don't try to create a dummy one
1001 LLView* view = LLUICtrl::getChildView(name, recurse, FALSE);
1098 if (!view && !recurse) 1002 if (!view && !recurse)
1099 { 1003 {
1100 childNotFound(name); 1004 childNotFound(name);
1101 } 1005 }
1006 if (!view && create_if_missing)
1007 {
1008 view = createDummyWidget<LLView>(name);
1009 }
1102 return view; 1010 return view;
1103} 1011}
1104 1012
@@ -1191,6 +1099,8 @@ struct LLLayoutStack::LLEmbeddedPanel
1191 F32 mVisibleAmt; 1099 F32 mVisibleAmt;
1192}; 1100};
1193 1101
1102static LLRegisterWidget<LLLayoutStack> r2("layout_stack");
1103
1194LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) : 1104LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) :
1195 mOrientation(orientation), 1105 mOrientation(orientation),
1196 mMinWidth(0), 1106 mMinWidth(0),
@@ -1204,19 +1114,6 @@ LLLayoutStack::~LLLayoutStack()
1204 std::for_each(mPanels.begin(), mPanels.end(), DeletePointer()); 1114 std::for_each(mPanels.begin(), mPanels.end(), DeletePointer());
1205} 1115}
1206 1116
1207// virtual
1208EWidgetType LLLayoutStack::getWidgetType() const
1209{
1210 return WIDGET_TYPE_LAYOUT_STACK;
1211}
1212
1213// virtual
1214LLString LLLayoutStack::getWidgetTag() const
1215{
1216 return LL_LAYOUT_STACK_TAG;
1217}
1218
1219
1220void LLLayoutStack::draw() 1117void LLLayoutStack::draw()
1221{ 1118{
1222 updateLayout(); 1119 updateLayout();
@@ -1304,18 +1201,18 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
1304 LLXMLNodePtr child; 1201 LLXMLNodePtr child;
1305 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) 1202 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
1306 { 1203 {
1204 S32 min_width = 0;
1205 S32 min_height = 0;
1206 BOOL auto_resize = TRUE;
1207
1208 child->getAttributeS32("min_width", min_width);
1209 child->getAttributeS32("min_height", min_height);
1210 child->getAttributeBOOL("auto_resize", auto_resize);
1211
1307 if (child->hasName("layout_panel")) 1212 if (child->hasName("layout_panel"))
1308 { 1213 {
1309 S32 min_width = 0;
1310 S32 min_height = 0;
1311 BOOL auto_resize = TRUE;
1312 BOOL user_resize = TRUE; 1214 BOOL user_resize = TRUE;
1313
1314 child->getAttributeS32("min_width", min_width);
1315 child->getAttributeS32("min_height", min_height);
1316 child->getAttributeBOOL("auto_resize", auto_resize);
1317 child->getAttributeBOOL("user_resize", user_resize); 1215 child->getAttributeBOOL("user_resize", user_resize);
1318
1319 LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory); 1216 LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory);
1320 if (panelp) 1217 if (panelp)
1321 { 1218 {
@@ -1323,6 +1220,26 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
1323 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize); 1220 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
1324 } 1221 }
1325 } 1222 }
1223 else
1224 {
1225 BOOL user_resize = FALSE;
1226 child->getAttributeBOOL("user_resize", user_resize);
1227
1228 LLPanel* panelp = new LLPanel("auto_panel");
1229 LLView* new_child = factory->createWidget(panelp, child);
1230 if (new_child)
1231 {
1232 // put child in new embedded panel
1233 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
1234 // resize panel to contain widget and move widget to be contained in panel
1235 panelp->setRect(new_child->getRect());
1236 new_child->setOrigin(0, 0);
1237 }
1238 else
1239 {
1240 panelp->die();
1241 }
1242 }
1326 } 1243 }
1327 layout_stackp->updateLayout(); 1244 layout_stackp->updateLayout();
1328 1245
@@ -1411,6 +1328,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1411 1328
1412 if (mOrientation == HORIZONTAL) 1329 if (mOrientation == HORIZONTAL)
1413 { 1330 {
1331 // enforce minimize size constraint by default
1332 if (panelp->getRect().getWidth() < (*panel_it)->mMinWidth)
1333 {
1334 panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight());
1335 }
1414 total_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt); 1336 total_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt);
1415 // want n-1 panel gaps for n panels 1337 // want n-1 panel gaps for n panels
1416 if (panel_it != mPanels.begin()) 1338 if (panel_it != mPanels.begin())
@@ -1420,6 +1342,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1420 } 1342 }
1421 else //VERTICAL 1343 else //VERTICAL
1422 { 1344 {
1345 // enforce minimize size constraint by default
1346 if (panelp->getRect().getHeight() < (*panel_it)->mMinHeight)
1347 {
1348 panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight);
1349 }
1423 total_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt); 1350 total_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt);
1424 if (panel_it != mPanels.begin()) 1351 if (panel_it != mPanels.begin())
1425 { 1352 {
@@ -1438,6 +1365,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1438 { 1365 {
1439 continue; 1366 continue;
1440 } 1367 }
1368
1441 // if currently resizing a panel or the panel is flagged as not automatically resizing 1369 // if currently resizing a panel or the panel is flagged as not automatically resizing
1442 // only track total available headroom, but don't use it for automatic resize logic 1370 // only track total available headroom, but don't use it for automatic resize logic
1443 if ((*panel_it)->mResizeBar->hasMouseCapture() 1371 if ((*panel_it)->mResizeBar->hasMouseCapture()
@@ -1469,6 +1397,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1469 } 1397 }
1470 } 1398 }
1471 1399
1400 // calculate how many pixels need to be distributed among layout panels
1472 // positive means panels need to grow, negative means shrink 1401 // positive means panels need to grow, negative means shrink
1473 S32 pixels_to_distribute; 1402 S32 pixels_to_distribute;
1474 if (mOrientation == HORIZONTAL) 1403 if (mOrientation == HORIZONTAL)
@@ -1480,6 +1409,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1480 pixels_to_distribute = getRect().getHeight() - total_height; 1409 pixels_to_distribute = getRect().getHeight() - total_height;
1481 } 1410 }
1482 1411
1412 // now we distribute the pixels...
1483 S32 cur_x = 0; 1413 S32 cur_x = 0;
1484 S32 cur_y = getRect().getHeight(); 1414 S32 cur_y = getRect().getHeight();
1485 1415
@@ -1505,13 +1435,17 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1505 if (pixels_to_distribute < 0) 1435 if (pixels_to_distribute < 0)
1506 { 1436 {
1507 // shrink proportionally to amount over minimum 1437 // shrink proportionally to amount over minimum
1508 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available) : 0; 1438 // so we can do this in one pass
1439 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available)) : 0;
1440 shrink_headroom_available -= (cur_width - (*panel_it)->mMinWidth);
1509 } 1441 }
1510 else 1442 else
1511 { 1443 {
1512 // grow all elements equally 1444 // grow all elements equally
1513 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); 1445 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
1446 num_resizable_panels--;
1514 } 1447 }
1448 pixels_to_distribute -= delta_size;
1515 new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size); 1449 new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size);
1516 } 1450 }
1517 else 1451 else
@@ -1524,12 +1458,16 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1524 if (pixels_to_distribute < 0) 1458 if (pixels_to_distribute < 0)
1525 { 1459 {
1526 // shrink proportionally to amount over minimum 1460 // shrink proportionally to amount over minimum
1527 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available) : 0; 1461 // so we can do this in one pass
1462 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available)) : 0;
1463 shrink_headroom_available -= (cur_height - (*panel_it)->mMinHeight);
1528 } 1464 }
1529 else 1465 else
1530 { 1466 {
1531 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); 1467 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
1468 num_resizable_panels--;
1532 } 1469 }
1470 pixels_to_distribute -= delta_size;
1533 new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size); 1471 new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size);
1534 } 1472 }
1535 else 1473 else
diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h
index e0f48ca..c7627ff 100644
--- a/linden/indra/llui/llpanel.h
+++ b/linden/indra/llui/llpanel.h
@@ -82,13 +82,12 @@ public:
82 /*virtual*/ ~LLPanel(); 82 /*virtual*/ ~LLPanel();
83 83
84 // LLView interface 84 // LLView interface
85 /*virtual*/ EWidgetType getWidgetType() const;
86 /*virtual*/ LLString getWidgetTag() const;
87 /*virtual*/ BOOL isPanel() const; 85 /*virtual*/ BOOL isPanel() const;
88 /*virtual*/ void draw(); 86 /*virtual*/ void draw();
89 /*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); 87 /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
90 /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask, BOOL called_from_parent );
91 /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; 88 /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
89 // Override to set not found list:
90 virtual LLView* getChildView(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
92 91
93 // From LLFocusableElement 92 // From LLFocusableElement
94 /*virtual*/ void setFocus( BOOL b ); 93 /*virtual*/ void setFocus( BOOL b );
@@ -106,8 +105,21 @@ public:
106 BOOL hasBorder() const { return mBorder != NULL; } 105 BOOL hasBorder() const { return mBorder != NULL; }
107 void setBorderVisible( BOOL b ); 106 void setBorderVisible( BOOL b );
108 107
109 void requires(LLString name, EWidgetType type = WIDGET_TYPE_DONTCARE); 108 template <class T> void requires(LLString name)
110 BOOL checkRequirements() const; 109 {
110 // check for widget with matching type and name
111 if (LLView::getChild<T>(name) == NULL)
112 {
113 mRequirementsError += name + "\n";
114 }
115 }
116
117 // requires LLView by default
118 void requires(LLString name)
119 {
120 requires<LLView>(name);
121 }
122 BOOL checkRequirements();
111 123
112 void setBackgroundColor( const LLColor4& color ) { mBgColorOpaque = color; } 124 void setBackgroundColor( const LLColor4& color ) { mBgColorOpaque = color; }
113 const LLColor4& getBackgroundColor() const { return mBgColorOpaque; } 125 const LLColor4& getBackgroundColor() const { return mBgColorOpaque; }
@@ -133,8 +145,6 @@ public:
133 145
134 S32 getLastTabGroup() const { return mLastTabGroup; } 146 S32 getLastTabGroup() const { return mLastTabGroup; }
135 147
136 LLUICtrl* getCtrlByNameAndType(const LLString& name, EWidgetType type) const;
137
138 const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } 148 const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
139 149
140 BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 150 BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
@@ -226,9 +236,6 @@ protected:
226 LLButton* getDefaultButton() { return mDefaultBtn; } 236 LLButton* getDefaultButton() { return mDefaultBtn; }
227 LLCallbackMap::map_t mFactoryMap; 237 LLCallbackMap::map_t mFactoryMap;
228 238
229 // Override to set not found list:
230 virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const;
231
232private: 239private:
233 // common construction logic 240 // common construction logic
234 void init(); 241 void init();
@@ -257,8 +264,7 @@ private:
257 typedef std::map<LLString, LLUIString> ui_string_map_t; 264 typedef std::map<LLString, LLUIString> ui_string_map_t;
258 ui_string_map_t mUIStrings; 265 ui_string_map_t mUIStrings;
259 266
260 typedef std::map<LLString, EWidgetType> requirements_map_t; 267 LLString mRequirementsError;
261 requirements_map_t mRequirements;
262 268
263 typedef std::queue<LLAlertInfo> alert_queue_t; 269 typedef std::queue<LLAlertInfo> alert_queue_t;
264 static alert_queue_t sAlertQueue; 270 static alert_queue_t sAlertQueue;
@@ -281,9 +287,6 @@ public:
281 /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; 287 /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
282 /*virtual*/ void removeCtrl(LLUICtrl* ctrl); 288 /*virtual*/ void removeCtrl(LLUICtrl* ctrl);
283 289
284 virtual EWidgetType getWidgetType() const;
285 virtual LLString getWidgetTag() const;
286
287 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 290 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
288 291
289 S32 getMinWidth() const { return mMinWidth; } 292 S32 getMinWidth() const { return mMinWidth; }
@@ -291,16 +294,17 @@ public:
291 294
292 void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index = S32_MAX); 295 void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index = S32_MAX);
293 void removePanel(LLPanel* panel); 296 void removePanel(LLPanel* panel);
294 void updateLayout(BOOL force_resize = FALSE);
295 297
296private: 298private:
299 struct LLEmbeddedPanel;
300
301 void updateLayout(BOOL force_resize = FALSE);
297 void calcMinExtents(); 302 void calcMinExtents();
298 S32 getDefaultHeight(S32 cur_height); 303 S32 getDefaultHeight(S32 cur_height);
299 S32 getDefaultWidth(S32 cur_width); 304 S32 getDefaultWidth(S32 cur_width);
300 305
301 const eLayoutOrientation mOrientation; 306 const eLayoutOrientation mOrientation;
302 307
303 struct LLEmbeddedPanel;
304 typedef std::vector<LLEmbeddedPanel*> e_panel_list_t; 308 typedef std::vector<LLEmbeddedPanel*> e_panel_list_t;
305 e_panel_list_t mPanels; 309 e_panel_list_t mPanels;
306 LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp) const; 310 LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp) const;
diff --git a/linden/indra/llui/llradiogroup.cpp b/linden/indra/llui/llradiogroup.cpp
index 039fe81..d7373f1 100644
--- a/linden/indra/llui/llradiogroup.cpp
+++ b/linden/indra/llui/llradiogroup.cpp
@@ -42,6 +42,7 @@
42#include "llui.h" 42#include "llui.h"
43#include "llfocusmgr.h" 43#include "llfocusmgr.h"
44 44
45static LLRegisterWidget<LLRadioGroup> r("radio_group");
45 46
46LLRadioGroup::LLRadioGroup(const LLString& name, const LLRect& rect, 47LLRadioGroup::LLRadioGroup(const LLString& name, const LLRect& rect,
47 const LLString& control_name, 48 const LLString& control_name,
@@ -161,11 +162,11 @@ BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event)
161 return TRUE; 162 return TRUE;
162} 163}
163 164
164BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 165BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask)
165{ 166{
166 BOOL handled = FALSE; 167 BOOL handled = FALSE;
167 // do any of the tab buttons have keyboard focus? 168 // do any of the tab buttons have keyboard focus?
168 if (getEnabled() && !called_from_parent && mask == MASK_NONE) 169 if (mask == MASK_NONE)
169 { 170 {
170 switch(key) 171 switch(key)
171 { 172 {
diff --git a/linden/indra/llui/llradiogroup.h b/linden/indra/llui/llradiogroup.h
index 87591a4..e208b79 100644
--- a/linden/indra/llui/llradiogroup.h
+++ b/linden/indra/llui/llradiogroup.h
@@ -82,10 +82,8 @@ public:
82 BOOL border = TRUE); 82 BOOL border = TRUE);
83 83
84 virtual ~LLRadioGroup(); 84 virtual ~LLRadioGroup();
85 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_RADIO_GROUP; }
86 virtual LLString getWidgetTag() const { return LL_RADIO_GROUP_TAG; }
87 85
88 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 86 virtual BOOL handleKeyHere(KEY key, MASK mask);
89 87
90 virtual void setEnabled(BOOL enabled); 88 virtual void setEnabled(BOOL enabled);
91 virtual LLXMLNodePtr getXML(bool save_children = true) const; 89 virtual LLXMLNodePtr getXML(bool save_children = true) const;
diff --git a/linden/indra/llui/llresizebar.cpp b/linden/indra/llui/llresizebar.cpp
index b4933bd..e89bfee 100644
--- a/linden/indra/llui/llresizebar.cpp
+++ b/linden/indra/llui/llresizebar.cpp
@@ -85,16 +85,13 @@ LLResizeBar::LLResizeBar( const LLString& name, LLView* resizing_view, const LLR
85 85
86BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask) 86BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
87{ 87{
88 if( getEnabled() ) 88 // Route future Mouse messages here preemptively. (Release on mouse up.)
89 { 89 // No handler needed for focus lost since this clas has no state that depends on it.
90 // Route future Mouse messages here preemptively. (Release on mouse up.) 90 gFocusMgr.setMouseCapture( this );
91 // No handler needed for focus lost since this clas has no state that depends on it.
92 gFocusMgr.setMouseCapture( this );
93 91
94 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY); 92 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
95 mLastMouseScreenX = mDragLastScreenX; 93 mLastMouseScreenX = mDragLastScreenX;
96 mLastMouseScreenY = mDragLastScreenY; 94 mLastMouseScreenY = mDragLastScreenY;
97 }
98 95
99 return TRUE; 96 return TRUE;
100} 97}
diff --git a/linden/indra/llui/llresizebar.h b/linden/indra/llui/llresizebar.h
index 5446811..d03dafa 100644
--- a/linden/indra/llui/llresizebar.h
+++ b/linden/indra/llui/llresizebar.h
@@ -42,9 +42,6 @@ public:
42 42
43 LLResizeBar(const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side ); 43 LLResizeBar(const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side );
44 44
45 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_RESIZE_BAR; }
46 virtual LLString getWidgetTag() const { return LL_RESIZE_BAR_TAG; }
47
48// virtual void draw(); No appearance 45// virtual void draw(); No appearance
49 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 46 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
50 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 47 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/linden/indra/llui/llresizehandle.cpp b/linden/indra/llui/llresizehandle.cpp
index d3e066b..3aa968f 100644
--- a/linden/indra/llui/llresizehandle.cpp
+++ b/linden/indra/llui/llresizehandle.cpp
@@ -59,8 +59,7 @@ LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 mi
59 59
60 if( RIGHT_BOTTOM == mCorner) 60 if( RIGHT_BOTTOM == mCorner)
61 { 61 {
62 LLUUID image_id(LLUI::sConfigGroup->getString("UIImgResizeBottomRightUUID")); 62 mImage = LLUI::sImageProvider->getUIImage("UIImgResizeBottomRightUUID");
63 mImage = LLUI::sImageProvider->getImageByID(image_id);
64 } 63 }
65 64
66 switch( mCorner ) 65 switch( mCorner )
@@ -78,19 +77,16 @@ LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 mi
78BOOL LLResizeHandle::handleMouseDown(S32 x, S32 y, MASK mask) 77BOOL LLResizeHandle::handleMouseDown(S32 x, S32 y, MASK mask)
79{ 78{
80 BOOL handled = FALSE; 79 BOOL handled = FALSE;
81 if( getVisible() && pointInHandle(x, y) ) 80 if( pointInHandle(x, y) )
82 { 81 {
83 handled = TRUE; 82 handled = TRUE;
84 if( getEnabled() ) 83 // Route future Mouse messages here preemptively. (Release on mouse up.)
85 { 84 // No handler needed for focus lost since this clas has no state that depends on it.
86 // Route future Mouse messages here preemptively. (Release on mouse up.) 85 gFocusMgr.setMouseCapture( this );
87 // No handler needed for focus lost since this clas has no state that depends on it.
88 gFocusMgr.setMouseCapture( this );
89 86
90 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY); 87 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
91 mLastMouseScreenX = mDragLastScreenX; 88 mLastMouseScreenX = mDragLastScreenX;
92 mLastMouseScreenY = mDragLastScreenY; 89 mLastMouseScreenY = mDragLastScreenY;
93 }
94 } 90 }
95 91
96 return handled; 92 return handled;
@@ -107,8 +103,7 @@ BOOL LLResizeHandle::handleMouseUp(S32 x, S32 y, MASK mask)
107 gFocusMgr.setMouseCapture( NULL ); 103 gFocusMgr.setMouseCapture( NULL );
108 handled = TRUE; 104 handled = TRUE;
109 } 105 }
110 else 106 else if( pointInHandle(x, y) )
111 if( getVisible() && pointInHandle(x, y) )
112 { 107 {
113 handled = TRUE; 108 handled = TRUE;
114 } 109 }
@@ -284,7 +279,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
284 } 279 }
285 else // don't have mouse capture 280 else // don't have mouse capture
286 { 281 {
287 if( getVisible() && pointInHandle( x, y ) ) 282 if( pointInHandle( x, y ) )
288 { 283 {
289 handled = TRUE; 284 handled = TRUE;
290 } 285 }
@@ -314,7 +309,7 @@ void LLResizeHandle::draw()
314{ 309{
315 if( mImage.notNull() && getVisible() && (RIGHT_BOTTOM == mCorner) ) 310 if( mImage.notNull() && getVisible() && (RIGHT_BOTTOM == mCorner) )
316 { 311 {
317 gl_draw_image( 0, 0, mImage ); 312 mImage->draw(0, 0);
318 } 313 }
319} 314}
320 315
diff --git a/linden/indra/llui/llresizehandle.h b/linden/indra/llui/llresizehandle.h
index 77ebcb9..5302612 100644
--- a/linden/indra/llui/llresizehandle.h
+++ b/linden/indra/llui/llresizehandle.h
@@ -46,9 +46,6 @@ public:
46 46
47 LLResizeHandle(const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM ); 47 LLResizeHandle(const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM );
48 48
49 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_RESIZE_HANDLE; }
50 virtual LLString getWidgetTag() const { return LL_RESIZE_HANDLE_TAG; }
51
52 virtual void draw(); 49 virtual void draw();
53 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 50 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
54 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 51 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@@ -64,7 +61,7 @@ private:
64 S32 mLastMouseScreenX; 61 S32 mLastMouseScreenX;
65 S32 mLastMouseScreenY; 62 S32 mLastMouseScreenY;
66 LLCoordGL mLastMouseDir; 63 LLCoordGL mLastMouseDir;
67 LLPointer<LLImageGL> mImage; 64 LLPointer<LLUIImage> mImage;
68 S32 mMinWidth; 65 S32 mMinWidth;
69 S32 mMinHeight; 66 S32 mMinHeight;
70 const ECorner mCorner; 67 const ECorner mCorner;
diff --git a/linden/indra/llui/llresmgr.cpp b/linden/indra/llui/llresmgr.cpp
index 83ad440..b5b9174 100644
--- a/linden/indra/llui/llresmgr.cpp
+++ b/linden/indra/llui/llresmgr.cpp
@@ -39,8 +39,6 @@
39#include "llerror.h" 39#include "llerror.h"
40#include "llstring.h" 40#include "llstring.h"
41 41
42// Global singleton
43LLResMgr* gResMgr = NULL;
44 42
45LLResMgr::LLResMgr() 43LLResMgr::LLResMgr()
46{ 44{
diff --git a/linden/indra/llui/llresmgr.h b/linden/indra/llui/llresmgr.h
index 810d386..f9ec115 100644
--- a/linden/indra/llui/llresmgr.h
+++ b/linden/indra/llui/llresmgr.h
@@ -36,6 +36,7 @@
36#include "locale.h" 36#include "locale.h"
37#include "stdtypes.h" 37#include "stdtypes.h"
38#include "llstring.h" 38#include "llstring.h"
39#include "llmemory.h"
39 40
40enum LLLOCALE_ID 41enum LLLOCALE_ID
41{ 42{
@@ -44,67 +45,6 @@ enum LLLOCALE_ID
44 LLLOCALE_COUNT // Number of values in this enum. Keep at end. 45 LLLOCALE_COUNT // Number of values in this enum. Keep at end.
45}; 46};
46 47
47/*
48enum LLSTR_ID
49{
50 LLSTR_HELLO,
51 LLSTR_GOODBYE,
52 LLSTR_CHAT_LABEL,
53 LLSTR_STATUS_LABEL,
54 LLSTR_X,
55 LLSTR_Y,
56 LLSTR_Z,
57 LLSTR_POSITION,
58 LLSTR_SCALE,
59 LLSTR_ROTATION,
60 LLSTR_HAS_PHYSICS,
61 LLSTR_SCRIPT,
62 LLSTR_HELP,
63 LLSTR_REMOVE,
64 LLSTR_CLEAR,
65 LLSTR_APPLY,
66 LLSTR_CANCEL,
67 LLSTR_MATERIAL,
68 LLSTR_FACE,
69 LLSTR_TEXTURE,
70 LLSTR_TEXTURE_SIZE,
71 LLSTR_TEXTURE_OFFSET,
72 LLSTR_TEXTURE_ROTATION,
73 LLSTR_U,
74 LLSTR_V,
75 LLSTR_OWNERSHIP,
76 LLSTR_PUBLIC,
77 LLSTR_PRIVATE,
78 LLSTR_REVERT,
79 LLSTR_INSERT_SAMPLE,
80 LLSTR_SET_TEXTURE,
81 LLSTR_EDIT_SCRIPT,
82 LLSTR_MOUSELOOK_INSTRUCTIONS,
83 LLSTR_EDIT_FACE_INSTRUCTIONS,
84 LLSTR_CLOSE,
85 LLSTR_MOVE,
86 LLSTR_ROTATE,
87 LLSTR_RESIZE,
88 LLSTR_PLACE_BOX,
89 LLSTR_PLACE_PRISM,
90 LLSTR_PLACE_PYRAMID,
91 LLSTR_PLACE_TETRAHEDRON,
92 LLSTR_PLACE_CYLINDER,
93 LLSTR_PLACE_HALF_CYLINDER,
94 LLSTR_PLACE_CONE,
95 LLSTR_PLACE_HALF_CONE,
96 LLSTR_PLACE_SPHERE,
97 LLSTR_PLACE_HALF_SPHERE,
98 LLSTR_PLACE_BIRD,
99 LLSTR_PLACE_SNAKE,
100 LLSTR_PLACE_ROCK,
101 LLSTR_PLACE_TREE,
102 LLSTR_PLACE_GRASS,
103 LLSTR_MODIFY_LAND,
104 LLSTR_COUNT // Number of values in this enum. Keep at end.
105};
106*/
107
108enum LLFONT_ID 48enum LLFONT_ID
109{ 49{
110 LLFONT_OCRA, 50 LLFONT_OCRA,
@@ -117,7 +57,7 @@ enum LLFONT_ID
117 57
118class LLFontGL; 58class LLFontGL;
119 59
120class LLResMgr 60class LLResMgr : public LLSingleton<LLResMgr>
121{ 61{
122public: 62public:
123 LLResMgr(); 63 LLResMgr();
@@ -162,6 +102,4 @@ private:
162 LLString mPrevLocaleString; 102 LLString mPrevLocaleString;
163}; 103};
164 104
165extern LLResMgr* gResMgr;
166
167#endif // LL_RESMGR_ 105#endif // LL_RESMGR_
diff --git a/linden/indra/llui/llrootview.h b/linden/indra/llui/llrootview.h
index 5f130b9..f4c047c 100644
--- a/linden/indra/llui/llrootview.h
+++ b/linden/indra/llui/llrootview.h
@@ -38,9 +38,6 @@ class LLRootView : public LLView
38{ 38{
39public: 39public:
40 LLRootView(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE); 40 LLRootView(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE);
41
42 /*virtual*/ EWidgetType getWidgetType() const { return WIDGET_TYPE_ROOT_VIEW; }
43 /*virtual*/ LLString getWidgetTag() const { return LL_ROOT_VIEW_TAG; }
44}; 41};
45 42
46#endif 43#endif
diff --git a/linden/indra/llui/llscrollbar.cpp b/linden/indra/llui/llscrollbar.cpp
index cf64742..cdabda0 100644
--- a/linden/indra/llui/llscrollbar.cpp
+++ b/linden/indra/llui/llscrollbar.cpp
@@ -414,17 +414,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
414 414
415BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) 415BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks)
416{ 416{
417 BOOL handled = FALSE; 417 changeLine( clicks * mStepSize, TRUE );
418 if( getVisible() && getRect().localPointInRect( x, y ) ) 418 return TRUE;
419 {
420 if( getEnabled() )
421 {
422 changeLine( clicks * mStepSize, TRUE );
423 }
424 handled = TRUE;
425 }
426
427 return handled;
428} 419}
429 420
430BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, 421BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -475,85 +466,68 @@ void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
475 466
476void LLScrollbar::draw() 467void LLScrollbar::draw()
477{ 468{
478 if( getVisible() ) 469 S32 local_mouse_x;
470 S32 local_mouse_y;
471 LLCoordWindow cursor_pos_window;
472 getWindow()->getCursorPosition(&cursor_pos_window);
473 LLCoordGL cursor_pos_gl;
474 getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
475
476 screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
477 BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this;
478 BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));
479 if (hovered)
479 { 480 {
480 S32 local_mouse_x; 481 mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
481 S32 local_mouse_y; 482 }
482 LLCoordWindow cursor_pos_window; 483 else
483 getWindow()->getCursorPosition(&cursor_pos_window); 484 {
484 LLCoordGL cursor_pos_gl; 485 mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
485 getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl); 486 }
486
487 screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
488 BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this;
489 BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));
490 if (hovered)
491 {
492 mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
493 }
494 else
495 {
496 mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
497 }
498 487
499 488
500 // Draw background and thumb. 489 // Draw background and thumb.
501 LLUUID rounded_rect_image_id; 490 LLUIImage* rounded_rect_imagep = LLUI::sImageProvider->getUIImage("rounded_square.tga");
502 rounded_rect_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga"));
503 LLImageGL* rounded_rect_imagep = LLUI::sImageProvider->getImageByID(rounded_rect_image_id);
504 491
505 if (!rounded_rect_imagep) 492 if (!rounded_rect_imagep)
506 { 493 {
507 gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0, 494 gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
508 mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), 495 mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
509 mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), 496 mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(),
510 mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE); 497 mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE);
511 498
512 gl_rect_2d(mThumbRect, mThumbColor, TRUE); 499 gl_rect_2d(mThumbRect, mThumbColor, TRUE);
513 500
514 } 501 }
515 else 502 else
516 { 503 {
517 // Background 504 // Thumb
518 gl_draw_scaled_image_with_border(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0, 505 LLRect outline_rect = mThumbRect;
519 mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, 506 outline_rect.stretch(2);
520 16,
521 16,
522 mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(),
523 mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
524 rounded_rect_imagep,
525 mTrackColor,
526 TRUE);
527
528 // Thumb
529 LLRect outline_rect = mThumbRect;
530 outline_rect.stretch(2);
531
532 if (gFocusMgr.getKeyboardFocus() == this)
533 {
534 gl_draw_scaled_image_with_border(outline_rect.mLeft, outline_rect.mBottom, 16, 16, outline_rect.getWidth(), outline_rect.getHeight(),
535 rounded_rect_imagep, gFocusMgr.getFocusColor() );
536 }
537 507
538 gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), 508 if (gFocusMgr.getKeyboardFocus() == this)
539 rounded_rect_imagep, mThumbColor ); 509 {
540 if (mCurGlowStrength > 0.01f) 510 rounded_rect_imagep->draw(outline_rect, gFocusMgr.getFocusColor());
541 {
542 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
543 gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(),
544 rounded_rect_imagep, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength), TRUE);
545 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
546 }
547 } 511 }
548 512
549 BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax()); 513 rounded_rect_imagep->draw(mThumbRect, mThumbColor);
550 if (mOnScrollEndCallback && was_scrolled_to_bottom) 514 if (mCurGlowStrength > 0.01f)
551 { 515 {
552 mOnScrollEndCallback(mOnScrollEndData); 516 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
517 rounded_rect_imagep->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
518 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
553 } 519 }
554 // Draw children 520
555 LLView::draw();
556 } 521 }
522
523 BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax());
524 if (mOnScrollEndCallback && was_scrolled_to_bottom)
525 {
526 mOnScrollEndCallback(mOnScrollEndData);
527 }
528
529 // Draw children
530 LLView::draw();
557} // end draw 531} // end draw
558 532
559 533
@@ -582,42 +556,39 @@ void LLScrollbar::setValue(const LLSD& value)
582} 556}
583 557
584 558
585BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 559BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask)
586{ 560{
587 BOOL handled = FALSE; 561 BOOL handled = FALSE;
588 562
589 if( getVisible() && getEnabled() && !called_from_parent ) 563 switch( key )
590 { 564 {
591 switch( key ) 565 case KEY_HOME:
592 { 566 changeLine( -mDocPos, TRUE );
593 case KEY_HOME: 567 handled = TRUE;
594 changeLine( -mDocPos, TRUE ); 568 break;
595 handled = TRUE; 569
596 break; 570 case KEY_END:
597 571 changeLine( getDocPosMax() - mDocPos, TRUE );
598 case KEY_END: 572 handled = TRUE;
599 changeLine( getDocPosMax() - mDocPos, TRUE ); 573 break;
600 handled = TRUE; 574
601 break; 575 case KEY_DOWN:
602 576 changeLine( mStepSize, TRUE );
603 case KEY_DOWN: 577 handled = TRUE;
604 changeLine( mStepSize, TRUE ); 578 break;
605 handled = TRUE; 579
606 break; 580 case KEY_UP:
607 581 changeLine( - mStepSize, TRUE );
608 case KEY_UP: 582 handled = TRUE;
609 changeLine( - mStepSize, TRUE ); 583 break;
610 handled = TRUE; 584
611 break; 585 case KEY_PAGE_DOWN:
612 586 pageDown(1);
613 case KEY_PAGE_DOWN: 587 break;
614 pageDown(1); 588
615 break; 589 case KEY_PAGE_UP:
616 590 pageUp(1);
617 case KEY_PAGE_UP: 591 break;
618 pageUp(1);
619 break;
620 }
621 } 592 }
622 593
623 return handled; 594 return handled;
diff --git a/linden/indra/llui/llscrollbar.h b/linden/indra/llui/llscrollbar.h
index b4586c3..52f19d1 100644
--- a/linden/indra/llui/llscrollbar.h
+++ b/linden/indra/llui/llscrollbar.h
@@ -62,11 +62,8 @@ public:
62 62
63 virtual void setValue(const LLSD& value); 63 virtual void setValue(const LLSD& value);
64 64
65 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLLBAR; }
66 virtual LLString getWidgetTag() const { return LL_SCROLLBAR_TAG; }
67
68 // Overrides from LLView 65 // Overrides from LLView
69 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 66 virtual BOOL handleKeyHere(KEY key, MASK mask);
70 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 67 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
71 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); 68 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
72 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 69 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
diff --git a/linden/indra/llui/llscrollcontainer.cpp b/linden/indra/llui/llscrollcontainer.cpp
index 15b59d4..a6c1c6d 100644
--- a/linden/indra/llui/llscrollcontainer.cpp
+++ b/linden/indra/llui/llscrollcontainer.cpp
@@ -61,6 +61,8 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
61/// Class LLScrollableContainerView 61/// Class LLScrollableContainerView
62///---------------------------------------------------------------------------- 62///----------------------------------------------------------------------------
63 63
64static LLRegisterWidget<LLScrollableContainerView> r("scroll_container");
65
64// Default constructor 66// Default constructor
65LLScrollableContainerView::LLScrollableContainerView( const LLString& name, 67LLScrollableContainerView::LLScrollableContainerView( const LLString& name,
66 const LLRect& rect, 68 const LLRect& rect,
@@ -210,63 +212,33 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
210 } 212 }
211} 213}
212 214
213BOOL LLScrollableContainerView::handleKey( KEY key, MASK mask, BOOL called_from_parent ) 215BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
214{ 216{
215 if( getVisible() && getEnabled() ) 217 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
216 { 218 {
217 if( called_from_parent ) 219 if( mScrollbar[i]->handleKeyHere(key, mask) )
218 {
219 // Downward traversal
220
221 // Don't pass keys to scrollbars on downward.
222
223 // Handle 'child' view.
224 if( mScrolledView && mScrolledView->handleKey(key, mask, TRUE) )
225 {
226 return TRUE;
227 }
228 }
229 else
230 { 220 {
231 // Upward traversal 221 return TRUE;
232
233 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
234 {
235 // Note: the scrollbar _is_ actually being called from it's parent. Here
236 // we're delgating LLScrollableContainerView's upward traversal to the scrollbars
237 if( mScrollbar[i]->handleKey(key, mask, TRUE) )
238 {
239 return TRUE;
240 }
241 }
242
243 if (getParent())
244 {
245 return getParent()->handleKey( key, mask, FALSE );
246 }
247 } 222 }
248 } 223 }
249 224
250 return FALSE; 225 return FALSE;
251} 226}
252 227
253BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) 228BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
254{ 229{
255 if( getEnabled() ) 230 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
256 { 231 {
257 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) 232 // Note: tries vertical and then horizontal
258 {
259 // Note: tries vertical and then horizontal
260 233
261 // Pretend the mouse is over the scrollbar 234 // Pretend the mouse is over the scrollbar
262 if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) ) 235 if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) )
263 { 236 {
264 return TRUE; 237 return TRUE;
265 }
266 } 238 }
267 } 239 }
268 240
269 // Opaque 241 // Eat scroll wheel event (to avoid scrolling nested containers?)
270 return TRUE; 242 return TRUE;
271} 243}
272 244
@@ -446,80 +418,78 @@ void LLScrollableContainerView::draw()
446 // clear this flag to be set on next call to handleDragAndDrop 418 // clear this flag to be set on next call to handleDragAndDrop
447 mAutoScrolling = FALSE; 419 mAutoScrolling = FALSE;
448 420
449 if( getVisible() ) 421 // auto-focus when scrollbar active
422 // this allows us to capture user intent (i.e. stop automatically scrolling the view/etc)
423 if (!gFocusMgr.childHasKeyboardFocus(this) &&
424 (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
450 { 425 {
451 // auto-focus when scrollbar active 426 focusFirstItem();
452 // this allows us to capture user intent (i.e. stop automatically scrolling the view/etc) 427 }
453 if (!gFocusMgr.childHasKeyboardFocus(this) &&
454 (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
455 {
456 focusFirstItem();
457 }
458 428
459 // Draw background 429 // Draw background
460 if( mIsOpaque ) 430 if( mIsOpaque )
431 {
432 LLGLSNoTexture no_texture;
433 glColor4fv( mBackgroundColor.mV );
434 gl_rect_2d( mInnerRect );
435 }
436
437 // Draw mScrolledViews and update scroll bars.
438 // get a scissor region ready, and draw the scrolling view. The
439 // scissor region ensures that we don't draw outside of the bounds
440 // of the rectangle.
441 if( mScrolledView )
442 {
443 updateScroll();
444
445 // Draw the scrolled area.
461 { 446 {
462 LLGLSNoTexture no_texture; 447 S32 visible_width = 0;
463 gGL.color4fv( mBackgroundColor.mV ); 448 S32 visible_height = 0;
464 gl_rect_2d( mInnerRect ); 449 BOOL show_v_scrollbar = FALSE;
450 BOOL show_h_scrollbar = FALSE;
451 calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
452
453 LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
454 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
455 visible_width,
456 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
457 ));
458 drawChild(mScrolledView);
465 } 459 }
466 460 }
467 // Draw mScrolledViews and update scroll bars.
468 // get a scissor region ready, and draw the scrolling view. The
469 // scissor region ensures that we don't draw outside of the bounds
470 // of the rectangle.
471 if( mScrolledView )
472 {
473 updateScroll();
474 461
475 // Draw the scrolled area. 462 // Highlight border if a child of this container has keyboard focus
476 { 463 if( mBorder->getVisible() )
477 S32 visible_width = 0; 464 {
478 S32 visible_height = 0; 465 mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
479 BOOL show_v_scrollbar = FALSE; 466 }
480 BOOL show_h_scrollbar = FALSE;
481 calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
482
483 LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
484 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
485 visible_width,
486 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
487 ));
488 drawChild(mScrolledView);
489 }
490 }
491 467
492 // Highlight border if a child of this container has keyboard focus 468 // Draw all children except mScrolledView
493 if( mBorder->getVisible() ) 469 // Note: scrollbars have been adjusted by above drawing code
470 for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
471 child_iter != getChildList()->rend(); ++child_iter)
472 {
473 LLView *viewp = *child_iter;
474 if( sDebugRects )
494 { 475 {
495 mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) ); 476 sDepth++;
496 } 477 }
497 478 if( (viewp != mScrolledView) && viewp->getVisible() )
498 // Draw all children except mScrolledView
499 // Note: scrollbars have been adjusted by above drawing code
500 for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
501 child_iter != getChildList()->rend(); ++child_iter)
502 { 479 {
503 LLView *viewp = *child_iter; 480 drawChild(viewp);
504 if( sDebugRects )
505 {
506 sDepth++;
507 }
508 if( (viewp != mScrolledView) && viewp->getVisible() )
509 {
510 drawChild(viewp);
511 }
512 if( sDebugRects )
513 {
514 sDepth--;
515 }
516 } 481 }
517 482 if( sDebugRects )
518 if (sDebugRects)
519 { 483 {
520 drawDebugRect(); 484 sDepth--;
521 } 485 }
522 } 486 }
487
488 if (sDebugRects)
489 {
490 drawDebugRect();
491 }
492
523} // end draw 493} // end draw
524 494
525void LLScrollableContainerView::updateScroll() 495void LLScrollableContainerView::updateScroll()
diff --git a/linden/indra/llui/llscrollcontainer.h b/linden/indra/llui/llscrollcontainer.h
index 51b1527..b6999e6 100644
--- a/linden/indra/llui/llscrollcontainer.h
+++ b/linden/indra/llui/llscrollcontainer.h
@@ -70,8 +70,6 @@ public:
70 void setScrolledView(LLView* view) { mScrolledView = view; } 70 void setScrolledView(LLView* view) { mScrolledView = view; }
71 71
72 virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); } 72 virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); }
73 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLL_CONTAINER; }
74 virtual LLString getWidgetTag() const { return LL_SCROLLABLE_CONTAINER_VIEW_TAG; }
75 73
76 void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; 74 void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
77 void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; 75 void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
@@ -90,7 +88,7 @@ public:
90 88
91 // LLView functionality 89 // LLView functionality
92 virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); 90 virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
93 virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); 91 virtual BOOL handleKeyHere(KEY key, MASK mask);
94 virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); 92 virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
95 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, 93 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
96 EDragAndDropType cargo_type, 94 EDragAndDropType cargo_type,
diff --git a/linden/indra/llui/llscrollingpanellist.cpp b/linden/indra/llui/llscrollingpanellist.cpp
index 8f85bc8..c9cdf3f 100644
--- a/linden/indra/llui/llscrollingpanellist.cpp
+++ b/linden/indra/llui/llscrollingpanellist.cpp
@@ -34,6 +34,9 @@
34 34
35#include "llscrollingpanellist.h" 35#include "llscrollingpanellist.h"
36 36
37static LLRegisterWidget<LLScrollingPanelList> r("scrolling_panel_list");
38
39
37///////////////////////////////////////////////////////////////////// 40/////////////////////////////////////////////////////////////////////
38// LLScrollingPanelList 41// LLScrollingPanelList
39 42
@@ -129,10 +132,8 @@ void LLScrollingPanelList::updatePanelVisiblilty()
129 132
130void LLScrollingPanelList::draw() 133void LLScrollingPanelList::draw()
131{ 134{
132 if( getVisible() ) 135 updatePanelVisiblilty();
133 { 136
134 updatePanelVisiblilty();
135 }
136 LLUICtrl::draw(); 137 LLUICtrl::draw();
137} 138}
138 139
diff --git a/linden/indra/llui/llscrollingpanellist.h b/linden/indra/llui/llscrollingpanellist.h
index 6fe35cd..7729250 100644
--- a/linden/indra/llui/llscrollingpanellist.h
+++ b/linden/indra/llui/llscrollingpanellist.h
@@ -56,8 +56,6 @@ public:
56 : LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_BOTTOM ) {} 56 : LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_BOTTOM ) {}
57 57
58 virtual void setValue(const LLSD& value) {}; 58 virtual void setValue(const LLSD& value) {};
59 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLLING_PANEL_LIST; }
60 virtual LLString getWidgetTag() const { return LL_SCROLLING_PANEL_LIST_TAG; }
61 59
62 virtual LLXMLNodePtr getXML(bool save_children) const { return LLUICtrl::getXML(); } 60 virtual LLXMLNodePtr getXML(bool save_children) const { return LLUICtrl::getXML(); }
63 61
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp
index 01c37d9..2066819 100644
--- a/linden/indra/llui/llscrolllistctrl.cpp
+++ b/linden/indra/llui/llscrolllistctrl.cpp
@@ -55,10 +55,11 @@
55#include "llkeyboard.h" 55#include "llkeyboard.h"
56#include "llresizebar.h" 56#include "llresizebar.h"
57 57
58const S32 LIST_BORDER_PAD = 0; // white space inside the border and to the left of the scrollbar
59const S32 MIN_COLUMN_WIDTH = 20; 58const S32 MIN_COLUMN_WIDTH = 20;
60const S32 LIST_SNAP_PADDING = 5; 59const S32 LIST_SNAP_PADDING = 5;
61 60
61static LLRegisterWidget<LLScrollListCtrl> r("scroll_list");
62
62// local structures & classes. 63// local structures & classes.
63struct SortScrollListItem 64struct SortScrollListItem
64{ 65{
@@ -68,37 +69,26 @@ struct SortScrollListItem
68 69
69 bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2) 70 bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2)
70 { 71 {
71 if ( mSortOrders.empty() ) return true; 72 if ( mSortOrders.empty() )
72 73 return i1 < i2;
73 const LLScrollListCell *cell1 = NULL;
74 const LLScrollListCell *cell2 = NULL;
75
76 sort_order_t::const_reverse_iterator end_it = mSortOrders.rend();
77 sort_order_t::const_reverse_iterator it;
78 74
79 // sort over all columns in order specified by mSortOrders 75 // sort over all columns in order specified by mSortOrders
80 S32 sort_result = 0; 76 S32 sort_result = 0;
81 for (it = mSortOrders.rbegin(); it != end_it; ++it) 77 for (sort_order_t::const_reverse_iterator it = mSortOrders.rbegin();
78 it != mSortOrders.rend(); ++it)
82 { 79 {
83 S32 col_idx = it->first; 80 S32 col_idx = it->first;
84 BOOL sort_ascending = it->second; 81 BOOL sort_ascending = it->second;
85 82
86 cell1 = i1->getColumn(col_idx); 83 const LLScrollListCell *cell1 = i1->getColumn(col_idx);
87 cell2 = i2->getColumn(col_idx); 84 const LLScrollListCell *cell2 = i2->getColumn(col_idx);
88 // ascending or descending sort for this column? 85 S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column?
89 S32 order = 1;
90 if (!sort_ascending)
91 {
92 order = -1;
93 }
94
95 if (cell1 && cell2) 86 if (cell1 && cell2)
96 { 87 {
97 sort_result = (order * LLString::compareDict(cell1->getValue().asString(), cell2->getValue().asString())); 88 sort_result = order * LLString::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
98 if (sort_result != 0) 89 if (sort_result != 0)
99 { 90 {
100 // we have a sort order! 91 break; // we have a sort order!
101 break;
102 } 92 }
103 } 93 }
104 } 94 }
@@ -114,24 +104,49 @@ struct SortScrollListItem
114// 104//
115// LLScrollListIcon 105// LLScrollListIcon
116// 106//
117LLScrollListIcon::LLScrollListIcon(const LLUUID& icon_id, S32 width) 107LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width)
108 : LLScrollListCell(width),
109 mIcon(icon),
110 mColor(LLColor4::white)
111{
112}
113
114LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width)
118 : LLScrollListCell(width), 115 : LLScrollListCell(width),
119 mColor(LLColor4::white), 116 mColor(LLColor4::white)
120 mImageUUID(icon_id)
121{ 117{
122 // don't use default image specified by LLUUID::null, use no image in that case 118 setValue(value);
123 mIcon = icon_id.isNull() ? NULL : LLUI::sImageProvider->getImageByID(icon_id);
124} 119}
125 120
121
126LLScrollListIcon::~LLScrollListIcon() 122LLScrollListIcon::~LLScrollListIcon()
127{ 123{
128} 124}
129 125
130void LLScrollListIcon::setValue(const LLSD& value) 126void LLScrollListIcon::setValue(const LLSD& value)
131{ 127{
132 mImageUUID = value.asUUID(); 128 if (value.isUUID())
133 // don't use default image specified by LLUUID::null, use no image in that case 129 {
134 mIcon = mImageUUID.isNull() ? NULL : LLUI::sImageProvider->getImageByID(mImageUUID); 130 // don't use default image specified by LLUUID::null, use no image in that case
131 LLUUID image_id = value.asUUID();
132 mIcon = image_id.notNull() ? LLUI::sImageProvider->getUIImageByID(image_id) : LLUIImagePtr(NULL);
133 }
134 else
135 {
136 LLString value_string = value.asString();
137 if (LLUUID::validate(value_string))
138 {
139 setValue(LLUUID(value_string));
140 }
141 else if (!value_string.empty())
142 {
143 mIcon = LLUI::getUIImage(value.asString());
144 }
145 else
146 {
147 mIcon = NULL;
148 }
149 }
135} 150}
136 151
137 152
@@ -143,7 +158,7 @@ void LLScrollListIcon::setColor(const LLColor4& color)
143S32 LLScrollListIcon::getWidth() const 158S32 LLScrollListIcon::getWidth() const
144{ 159{
145 // if no specified fix width, use width of icon 160 // if no specified fix width, use width of icon
146 if (LLScrollListCell::getWidth() == 0) 161 if (LLScrollListCell::getWidth() == 0 && mIcon.notNull())
147 { 162 {
148 return mIcon->getWidth(); 163 return mIcon->getWidth();
149 } 164 }
@@ -151,11 +166,11 @@ S32 LLScrollListIcon::getWidth() const
151} 166}
152 167
153 168
154void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const 169void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const
155{ 170{
156 if (mIcon) 171 if (mIcon)
157 { 172 {
158 gl_draw_image(0, 0, mIcon, mColor); 173 mIcon->draw(0, 0, mColor);
159 } 174 }
160} 175}
161 176
@@ -206,6 +221,13 @@ LLScrollListSeparator::LLScrollListSeparator(S32 width) : LLScrollListCell(width
206{ 221{
207} 222}
208 223
224//virtual
225S32 LLScrollListSeparator::getHeight() const
226{
227 return 5;
228}
229
230
209void LLScrollListSeparator::draw(const LLColor4& color, const LLColor4& highlight_color) const 231void LLScrollListSeparator::draw(const LLColor4& color, const LLColor4& highlight_color) const
210{ 232{
211 //*FIXME: use dynamic item heights and make separators narrow, and inactive 233 //*FIXME: use dynamic item heights and make separators narrow, and inactive
@@ -234,9 +256,34 @@ LLScrollListText::LLScrollListText( const LLString& text, const LLFontGL* font,
234 // initialize rounded rect image 256 // initialize rounded rect image
235 if (!mRoundedRectImage) 257 if (!mRoundedRectImage)
236 { 258 {
237 mRoundedRectImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("rounded_square.tga"))); 259 mRoundedRectImage = LLUI::sImageProvider->getUIImage("rounded_square.tga");
238 } 260 }
239} 261}
262//virtual
263void LLScrollListText::highlightText(S32 offset, S32 num_chars)
264{
265 mHighlightOffset = offset;
266 mHighlightCount = num_chars;
267}
268
269//virtual
270BOOL LLScrollListText::isText() const
271{
272 return TRUE;
273}
274
275//virtual
276BOOL LLScrollListText::getVisible() const
277{
278 return mVisible;
279}
280
281//virtual
282S32 LLScrollListText::getHeight() const
283{
284 return llround(mFont->getLineHeight());
285}
286
240 287
241LLScrollListText::~LLScrollListText() 288LLScrollListText::~LLScrollListText()
242{ 289{
@@ -266,6 +313,13 @@ void LLScrollListText::setValue(const LLSD& text)
266 setText(text.asString()); 313 setText(text.asString());
267} 314}
268 315
316//virtual
317const LLSD LLScrollListText::getValue() const
318{
319 return LLSD(mText.getString());
320}
321
322
269void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const 323void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const
270{ 324{
271 LLColor4 display_color; 325 LLColor4 display_color;
@@ -280,8 +334,6 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
280 334
281 if (mHighlightCount > 0) 335 if (mHighlightCount > 0)
282 { 336 {
283 mRoundedRectImage->bind();
284 gGL.color4fv(highlight_color.mV);
285 S32 left = 0; 337 S32 left = 0;
286 switch(mFontAlignment) 338 switch(mFontAlignment)
287 { 339 {
@@ -295,13 +347,11 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
295 left = (getWidth() - mFont->getWidth(mText.getString())) / 2; 347 left = (getWidth() - mFont->getWidth(mText.getString())) / 2;
296 break; 348 break;
297 } 349 }
298 gl_segmented_rect_2d_tex(left - 2, 350 LLRect highlight_rect(left - 2,
299 llround(mFont->getLineHeight()) + 1, 351 llround(mFont->getLineHeight()) + 1,
300 left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, 352 left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1,
301 1, 353 1);
302 mRoundedRectImage->getWidth(), 354 mRoundedRectImage->draw(highlight_rect, highlight_color);
303 mRoundedRectImage->getHeight(),
304 16);
305 } 355 }
306 356
307 // Try to draw the entire string 357 // Try to draw the entire string
@@ -389,8 +439,6 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const
389{ 439{
390 // draw background rect 440 // draw background rect
391 LLRect bg_rect = rect; 441 LLRect bg_rect = rect;
392 // pad background rectangle to separate it from contents
393 bg_rect.stretch(LIST_BORDER_PAD, 0);
394 { 442 {
395 LLGLSNoTexture no_texture; 443 LLGLSNoTexture no_texture;
396 gGL.color4fv(bg_color.mV); 444 gGL.color4fv(bg_color.mV);
@@ -432,7 +480,7 @@ LLScrollListItemComment::LLScrollListItemComment(const LLString& comment_string,
432: LLScrollListItem(FALSE), 480: LLScrollListItem(FALSE),
433 mColor(color) 481 mColor(color)
434{ 482{
435 addColumn( comment_string, gResMgr->getRes( LLFONT_SANSSERIF_SMALL ) ); 483 addColumn( comment_string, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ) );
436} 484}
437 485
438void LLScrollListItemComment::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) 486void LLScrollListItemComment::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
@@ -541,10 +589,10 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect,
541 mDrewSelected(FALSE) 589 mDrewSelected(FALSE)
542{ 590{
543 mItemListRect.setOriginAndSize( 591 mItemListRect.setOriginAndSize(
544 mBorderThickness + LIST_BORDER_PAD, 592 mBorderThickness,
545 mBorderThickness + LIST_BORDER_PAD, 593 mBorderThickness,
546 getRect().getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), 594 getRect().getWidth() - 2 * mBorderThickness,
547 getRect().getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) ); 595 getRect().getHeight() - 2 * mBorderThickness );
548 596
549 updateLineHeight(); 597 updateLineHeight();
550 598
@@ -738,10 +786,10 @@ void LLScrollListCtrl::updateLayout()
738 // reserve room for column headers, if needed 786 // reserve room for column headers, if needed
739 S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0); 787 S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0);
740 mItemListRect.setOriginAndSize( 788 mItemListRect.setOriginAndSize(
741 mBorderThickness + LIST_BORDER_PAD, 789 mBorderThickness,
742 mBorderThickness + LIST_BORDER_PAD, 790 mBorderThickness,
743 getRect().getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), 791 getRect().getWidth() - 2 * mBorderThickness,
744 getRect().getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); 792 getRect().getHeight() - (2 * mBorderThickness ) - heading_size );
745 793
746 // how many lines of content in a single "page" 794 // how many lines of content in a single "page"
747 mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; 795 mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0;
@@ -749,7 +797,7 @@ void LLScrollListCtrl::updateLayout()
749 if (scrollbar_visible) 797 if (scrollbar_visible)
750 { 798 {
751 // provide space on the right for scrollbar 799 // provide space on the right for scrollbar
752 mItemListRect.mRight = getRect().getWidth() - ( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE; 800 mItemListRect.mRight = getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE;
753 } 801 }
754 802
755 mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); 803 mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0));
@@ -775,7 +823,7 @@ LLRect LLScrollListCtrl::getRequiredRect()
775{ 823{
776 S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0); 824 S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0);
777 S32 height = (mLineHeight * getItemCount()) 825 S32 height = (mLineHeight * getItemCount())
778 + (2 * ( mBorderThickness + LIST_BORDER_PAD )) 826 + (2 * mBorderThickness )
779 + heading_size; 827 + heading_size;
780 S32 width = getRect().getWidth(); 828 S32 width = getRect().getWidth();
781 829
@@ -1357,7 +1405,6 @@ LLScrollListItem* LLScrollListCtrl::addCommentText(const LLString& comment_text,
1357 LLScrollListItem* item = NULL; 1405 LLScrollListItem* item = NULL;
1358 if (getItemCount() < mMaxItemCount) 1406 if (getItemCount() < mMaxItemCount)
1359 { 1407 {
1360 // simple items have their LLSD data set to their label
1361 // always draw comment text with "enabled" color 1408 // always draw comment text with "enabled" color
1362 item = new LLScrollListItemComment( comment_text, mFgUnselectedColor ); 1409 item = new LLScrollListItemComment( comment_text, mFgUnselectedColor );
1363 addItem( item, pos, FALSE ); 1410 addItem( item, pos, FALSE );
@@ -1525,7 +1572,7 @@ LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const LLString& item_text,
1525 if (getItemCount() < mMaxItemCount) 1572 if (getItemCount() < mMaxItemCount)
1526 { 1573 {
1527 item = new LLScrollListItem( enabled, NULL, id ); 1574 item = new LLScrollListItem( enabled, NULL, id );
1528 item->addColumn(item_text, gResMgr->getRes(LLFONT_SANSSERIF_SMALL), column_width); 1575 item->addColumn(item_text, LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF_SMALL), column_width);
1529 addItem( item, pos ); 1576 addItem( item, pos );
1530 } 1577 }
1531 return item; 1578 return item;
@@ -1664,7 +1711,6 @@ void LLScrollListCtrl::drawItems()
1664 fg_color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor); 1711 fg_color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor);
1665 if( item->getSelected() && mCanSelect) 1712 if( item->getSelected() && mCanSelect)
1666 { 1713 {
1667 // Draw background of selected item
1668 bg_color = mBgSelectedColor; 1714 bg_color = mBgSelectedColor;
1669 fg_color = (item->getEnabled() ? mFgSelectedColor : mFgDisabledColor); 1715 fg_color = (item->getEnabled() ? mFgSelectedColor : mFgDisabledColor);
1670 } 1716 }
@@ -1697,43 +1743,40 @@ void LLScrollListCtrl::drawItems()
1697 1743
1698void LLScrollListCtrl::draw() 1744void LLScrollListCtrl::draw()
1699{ 1745{
1700 if( getVisible() ) 1746 // if user specifies sort, make sure it is maintained
1747 if (needsSorting() && !isSorted())
1701 { 1748 {
1702 // if user specifies sort, make sure it is maintained 1749 sortItems();
1703 if (needsSorting() && !isSorted()) 1750 }
1704 {
1705 sortItems();
1706 }
1707
1708 if (mNeedsScroll)
1709 {
1710 scrollToShowSelected();
1711 mNeedsScroll = FALSE;
1712 }
1713 LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0);
1714 // Draw background
1715 if (mBackgroundVisible)
1716 {
1717 LLGLSNoTexture no_texture;
1718 gGL.color4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV );
1719 gl_rect_2d(background);
1720 }
1721 1751
1722 if (mColumnsDirty) 1752 if (mNeedsScroll)
1723 { 1753 {
1724 updateColumns(); 1754 scrollToShowSelected();
1725 mColumnsDirty = FALSE; 1755 mNeedsScroll = FALSE;
1726 } 1756 }
1757 LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0);
1758 // Draw background
1759 if (mBackgroundVisible)
1760 {
1761 LLGLSNoTexture no_texture;
1762 glColor4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV );
1763 gl_rect_2d(background);
1764 }
1727 1765
1728 drawItems(); 1766 if (mColumnsDirty)
1767 {
1768 updateColumns();
1769 mColumnsDirty = FALSE;
1770 }
1729 1771
1730 if (mBorder) 1772 drawItems();
1731 {
1732 mBorder->setKeyboardFocusHighlight(gFocusMgr.getKeyboardFocus() == this);
1733 }
1734 1773
1735 LLUICtrl::draw(); 1774 if (mBorder)
1775 {
1776 mBorder->setKeyboardFocusHighlight(gFocusMgr.getKeyboardFocus() == this);
1736 } 1777 }
1778
1779 LLUICtrl::draw();
1737} 1780}
1738 1781
1739void LLScrollListCtrl::setEnabled(BOOL enabled) 1782void LLScrollListCtrl::setEnabled(BOOL enabled)
@@ -1950,23 +1993,21 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
1950BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) 1993BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
1951{ 1994{
1952 //BOOL handled = FALSE; 1995 //BOOL handled = FALSE;
1953 if(getVisible()) 1996 BOOL handled = handleClick(x, y, mask);
1954 {
1955 BOOL handled = handleClick(x, y, mask);
1956 1997
1957 if (!handled) 1998 if (!handled)
1999 {
2000 // Offer the click to the children, even if we aren't enabled
2001 // so the scroll bars will work.
2002 if (NULL == LLView::childrenHandleDoubleClick(x, y, mask))
1958 { 2003 {
1959 // Offer the click to the children, even if we aren't enabled 2004 if( mCanSelect && mOnDoubleClickCallback )
1960 // so the scroll bars will work.
1961 if (NULL == LLView::childrenHandleDoubleClick(x, y, mask))
1962 { 2005 {
1963 if( mCanSelect && mOnDoubleClickCallback ) 2006 mOnDoubleClickCallback( mCallbackUserData );
1964 {
1965 mOnDoubleClickCallback( mCallbackUserData );
1966 }
1967 } 2007 }
1968 } 2008 }
1969 } 2009 }
2010
1970 return TRUE; 2011 return TRUE;
1971} 2012}
1972 2013
@@ -2146,12 +2187,12 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
2146} 2187}
2147 2188
2148 2189
2149BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent ) 2190BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
2150{ 2191{
2151 BOOL handled = FALSE; 2192 BOOL handled = FALSE;
2152 2193
2153 // not called from parent means we have keyboard focus or a child does 2194 // not called from parent means we have keyboard focus or a child does
2154 if (mCanSelect && !called_from_parent) 2195 if (mCanSelect)
2155 { 2196 {
2156 // Ignore capslock 2197 // Ignore capslock
2157 mask = mask; 2198 mask = mask;
@@ -2234,7 +2275,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
2234 // JC - Special case: Only claim to have handled it 2275 // JC - Special case: Only claim to have handled it
2235 // if we're the special non-commit-on-move 2276 // if we're the special non-commit-on-move
2236 // type. AND we are visible 2277 // type. AND we are visible
2237 if (!mCommitOnKeyboardMovement && mask == MASK_NONE && getVisible()) 2278 if (!mCommitOnKeyboardMovement && mask == MASK_NONE)
2238 { 2279 {
2239 onCommit(); 2280 onCommit();
2240 mSearchString.clear(); 2281 mSearchString.clear();
@@ -2281,7 +2322,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
2281 return handled; 2322 return handled;
2282} 2323}
2283 2324
2284BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) 2325BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
2285{ 2326{
2286 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL 2327 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
2287 { 2328 {
@@ -3207,17 +3248,16 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
3207 LLColor4 color = ((*itor)["color"]); 3248 LLColor4 color = ((*itor)["color"]);
3208 BOOL enabled = !(*itor).has("enabled") || (*itor)["enabled"].asBoolean() == true; 3249 BOOL enabled = !(*itor).has("enabled") || (*itor)["enabled"].asBoolean() == true;
3209 3250
3210 const LLFontGL *font = gResMgr->getRes(fontname); 3251 const LLFontGL *font = LLResMgr::getInstance()->getRes(fontname);
3211 if (!font) 3252 if (!font)
3212 { 3253 {
3213 font = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); 3254 font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
3214 } 3255 }
3215 U8 font_style = LLFontGL::getStyleFromString(fontstyle); 3256 U8 font_style = LLFontGL::getStyleFromString(fontstyle);
3216 3257
3217 if (type == "icon") 3258 if (type == "icon")
3218 { 3259 {
3219 LLUUID image_id = value.asUUID(); 3260 LLScrollListIcon* cell = new LLScrollListIcon(value, width);
3220 LLScrollListIcon* cell = new LLScrollListIcon(value.asUUID(), width);
3221 if (has_color) 3261 if (has_color)
3222 { 3262 {
3223 cell->setColor(color); 3263 cell->setColor(color);
@@ -3270,7 +3310,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
3270 if (new_item->getColumn(column_idx) == NULL) 3310 if (new_item->getColumn(column_idx) == NULL)
3271 { 3311 {
3272 LLScrollListColumn* column_ptr = &column_it->second; 3312 LLScrollListColumn* column_ptr = &column_it->second;
3273 new_item->setColumn(column_idx, new LLScrollListText("", gResMgr->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL)); 3313 new_item->setColumn(column_idx, new LLScrollListText("", LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL));
3274 } 3314 }
3275 } 3315 }
3276 3316
@@ -3290,7 +3330,7 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const LLString& value, EAdd
3290 3330
3291 LLScrollListItem *new_item = new LLScrollListItem(entry_id); 3331 LLScrollListItem *new_item = new LLScrollListItem(entry_id);
3292 3332
3293 const LLFontGL *font = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); 3333 const LLFontGL *font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
3294 3334
3295 new_item->addColumn(value, font, getRect().getWidth()); 3335 new_item->addColumn(value, font, getRect().getWidth());
3296 3336
@@ -3438,29 +3478,25 @@ LLColumnHeader::~LLColumnHeader()
3438 3478
3439void LLColumnHeader::draw() 3479void LLColumnHeader::draw()
3440{ 3480{
3441 if( getVisible() ) 3481 BOOL draw_arrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn;
3442 {
3443 BOOL draw_arrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn;
3444 3482
3445 BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); 3483 BOOL is_ascending = mColumn->mParentCtrl->getSortAscending();
3446 mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent); 3484 mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent);
3447 mArrowImage = mButton->getImageOverlay()->getImage(); 3485 mArrowImage = mButton->getImageOverlay();
3448 3486
3449 //BOOL clip = getRect().mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); 3487 //BOOL clip = getRect().mRight > mColumn->mParentCtrl->getItemListRect().getWidth();
3450 //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE); 3488 //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE);
3451 3489
3452 //LLRect column_header_local_rect(-getRect().mLeft, getRect().getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - getRect().mLeft, 0); 3490 //LLRect column_header_local_rect(-getRect().mLeft, getRect().getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - getRect().mLeft, 0);
3453 //LLUI::setScissorRegionLocal(column_header_local_rect); 3491 //LLUI::setScissorRegionLocal(column_header_local_rect);
3454 3492
3455 // Draw children 3493 // Draw children
3456 LLComboBox::draw(); 3494 LLComboBox::draw();
3457
3458 if (mList->getVisible())
3459 {
3460 // sync sort order with list selection every frame
3461 mColumn->mParentCtrl->sortByColumn(mColumn->mSortingColumn, getCurrentIndex() == 0);
3462 }
3463 3495
3496 if (mList->getVisible())
3497 {
3498 // sync sort order with list selection every frame
3499 mColumn->mParentCtrl->sortByColumn(mColumn->mSortingColumn, getCurrentIndex() == 0);
3464 } 3500 }
3465} 3501}
3466 3502
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h
index 716d18a..8a31154 100644
--- a/linden/indra/llui/llscrolllistctrl.h
+++ b/linden/indra/llui/llscrolllistctrl.h
@@ -90,7 +90,7 @@ public:
90 LLScrollListSeparator(S32 width); 90 LLScrollListSeparator(S32 width);
91 virtual ~LLScrollListSeparator() {}; 91 virtual ~LLScrollListSeparator() {};
92 virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible 92 virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible
93 virtual S32 getHeight() const { return 5; }; 93 virtual S32 getHeight() const;
94 virtual BOOL isText() const { return FALSE; } 94 virtual BOOL isText() const { return FALSE; }
95}; 95};
96 96
@@ -105,14 +105,14 @@ public:
105 105
106 virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; 106 virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
107 virtual S32 getContentWidth() const; 107 virtual S32 getContentWidth() const;
108 virtual S32 getHeight() const { return llround(mFont->getLineHeight()); } 108 virtual S32 getHeight() const;
109 virtual void setValue(const LLSD& value); 109 virtual void setValue(const LLSD& value);
110 virtual const LLSD getValue() const { return LLSD(mText.getString()); } 110 virtual const LLSD getValue() const;
111 virtual BOOL getVisible() const { return mVisible; } 111 virtual BOOL getVisible() const;
112 virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} 112 virtual void highlightText(S32 offset, S32 num_chars);
113 113
114 virtual void setColor(const LLColor4&); 114 virtual void setColor(const LLColor4&);
115 virtual BOOL isText() const { return TRUE; } 115 virtual BOOL isText() const;
116 116
117 void setText(const LLStringExplicit& text); 117 void setText(const LLStringExplicit& text);
118 void setFontStyle(const U8 font_style) { mFontStyle = font_style; } 118 void setFontStyle(const U8 font_style) { mFontStyle = font_style; }
@@ -128,7 +128,7 @@ private:
128 S32 mHighlightCount; 128 S32 mHighlightCount;
129 S32 mHighlightOffset; 129 S32 mHighlightOffset;
130 130
131 LLPointer<LLImageGL> mRoundedRectImage; 131 LLPointer<LLUIImage> mRoundedRectImage;
132 132
133 static U32 sCount; 133 static U32 sCount;
134}; 134};
@@ -139,20 +139,19 @@ private:
139class LLScrollListIcon : public LLScrollListCell 139class LLScrollListIcon : public LLScrollListCell
140{ 140{
141public: 141public:
142 LLScrollListIcon( const LLUUID& icon_id, S32 width = 0); 142 LLScrollListIcon( LLUIImagePtr icon, S32 width = 0);
143 LLScrollListIcon(const LLSD& value, S32 width = 0);
143 /*virtual*/ ~LLScrollListIcon(); 144 /*virtual*/ ~LLScrollListIcon();
144 virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; 145 virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
145 virtual S32 getWidth() const; 146 virtual S32 getWidth() const;
146 virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; } 147 virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; }
147 // used as sort criterion 148 virtual const LLSD getValue() const { return mIcon.isNull() ? LLString::null : mIcon->getName(); }
148 virtual const LLSD getValue() const { return LLSD(mImageUUID); }
149 virtual void setColor(const LLColor4&); 149 virtual void setColor(const LLColor4&);
150 virtual BOOL isText()const { return FALSE; } 150 virtual BOOL isText()const { return FALSE; }
151 virtual void setValue(const LLSD& value); 151 virtual void setValue(const LLSD& value);
152 152
153private: 153private:
154 LLPointer<LLImageGL> mIcon; 154 LLUIImagePtr mIcon;
155 LLUUID mImageUUID;
156 LLColor4 mColor; 155 LLColor4 mColor;
157}; 156};
158 157
@@ -342,8 +341,8 @@ public:
342 void addColumn( const LLString& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE) 341 void addColumn( const LLString& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE)
343 { mColumns.push_back( new LLScrollListText(text, font, width, font_style, font_alignment, LLColor4::black, FALSE, visible) ); } 342 { mColumns.push_back( new LLScrollListText(text, font, width, font_style, font_alignment, LLColor4::black, FALSE, visible) ); }
344 343
345 void addColumn( const LLUUID& icon_id, S32 width = 0 ) 344 void addColumn( LLUIImagePtr icon, S32 width = 0 )
346 { mColumns.push_back( new LLScrollListIcon(icon_id, width) ); } 345 { mColumns.push_back( new LLScrollListIcon(icon, width) ); }
347 346
348 void addColumn( LLCheckBoxCtrl* check, S32 width = 0 ) 347 void addColumn( LLCheckBoxCtrl* check, S32 width = 0 )
349 { mColumns.push_back( new LLScrollListCheck(check,width) ); } 348 { mColumns.push_back( new LLScrollListCheck(check,width) ); }
@@ -404,8 +403,7 @@ public:
404 BOOL draw_border = TRUE); 403 BOOL draw_border = TRUE);
405 404
406 virtual ~LLScrollListCtrl(); 405 virtual ~LLScrollListCtrl();
407 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLL_LIST; } 406
408 virtual LLString getWidgetTag() const { return LL_SCROLL_LIST_CTRL_TAG; }
409 virtual LLXMLNodePtr getXML(bool save_children = true) const; 407 virtual LLXMLNodePtr getXML(bool save_children = true) const;
410 void setScrollListParameters(LLXMLNodePtr node); 408 void setScrollListParameters(LLXMLNodePtr node);
411 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 409 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
@@ -562,8 +560,8 @@ public:
562 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); 560 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
563 /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); 561 /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
564 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); 562 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
565 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 563 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
566 /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); 564 /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
567 /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 565 /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
568 /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); 566 /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect);
569 /*virtual*/ void setEnabled(BOOL enabled); 567 /*virtual*/ void setEnabled(BOOL enabled);
@@ -618,6 +616,7 @@ public:
618 616
619 S32 selectMultiple( LLDynamicArray<LLUUID> ids ); 617 S32 selectMultiple( LLDynamicArray<LLUUID> ids );
620 void sortItems(); 618 void sortItems();
619
621 // manually call this whenever editing list items in place to flag need for resorting 620 // manually call this whenever editing list items in place to flag need for resorting
622 void setSorted(BOOL sorted) { mSorted = sorted; } 621 void setSorted(BOOL sorted) { mSorted = sorted; }
623 void dirtyColumns(); // some operation has potentially affected column layout or ordering 622 void dirtyColumns(); // some operation has potentially affected column layout or ordering
diff --git a/linden/indra/llui/llslider.cpp b/linden/indra/llui/llslider.cpp
index 02841ee..12d794c 100644
--- a/linden/indra/llui/llslider.cpp
+++ b/linden/indra/llui/llslider.cpp
@@ -41,6 +41,10 @@
41#include "llcontrol.h" 41#include "llcontrol.h"
42#include "llimagegl.h" 42#include "llimagegl.h"
43 43
44static LLRegisterWidget<LLSlider> r1("slider_bar");
45static LLRegisterWidget<LLSlider> r2("volume_slider");
46
47
44LLSlider::LLSlider( 48LLSlider::LLSlider(
45 const LLString& name, 49 const LLString& name,
46 const LLRect& rect, 50 const LLRect& rect,
@@ -68,9 +72,9 @@ LLSlider::LLSlider(
68 mMouseDownCallback( NULL ), 72 mMouseDownCallback( NULL ),
69 mMouseUpCallback( NULL ) 73 mMouseUpCallback( NULL )
70{ 74{
71 mThumbImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("icn_slide-thumb_dark.tga"))); 75 mThumbImage = LLUI::sImageProvider->getUIImage("icn_slide-thumb_dark.tga");
72 mTrackImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("icn_slide-groove_dark.tga"))); 76 mTrackImage = LLUI::sImageProvider->getUIImage("icn_slide-groove_dark.tga");
73 mTrackHighlightImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("icn_slide-highlight.tga"))); 77 mTrackHighlightImage = LLUI::sImageProvider->getUIImage("icn_slide-highlight.tga");
74 78
75 // properly handle setting the starting thumb rect 79 // properly handle setting the starting thumb rect
76 // do it this way to handle both the operating-on-settings 80 // do it this way to handle both the operating-on-settings
@@ -217,98 +221,68 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask)
217 return TRUE; 221 return TRUE;
218} 222}
219 223
220BOOL LLSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 224BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
221{ 225{
222 BOOL handled = FALSE; 226 BOOL handled = FALSE;
223 if( getVisible() && getEnabled() && !called_from_parent ) 227 switch(key)
224 { 228 {
225 switch(key) 229 case KEY_UP:
226 { 230 case KEY_DOWN:
227 case KEY_UP: 231 // eat up and down keys to be consistent
228 case KEY_DOWN: 232 handled = TRUE;
229 // eat up and down keys to be consistent 233 break;
230 handled = TRUE; 234 case KEY_LEFT:
231 break; 235 setValueAndCommit(getValueF32() - getIncrement());
232 case KEY_LEFT: 236 handled = TRUE;
233 setValueAndCommit(getValueF32() - getIncrement()); 237 break;
234 handled = TRUE; 238 case KEY_RIGHT:
235 break; 239 setValueAndCommit(getValueF32() + getIncrement());
236 case KEY_RIGHT: 240 handled = TRUE;
237 setValueAndCommit(getValueF32() + getIncrement()); 241 break;
238 handled = TRUE; 242 default:
239 break; 243 break;
240 default:
241 break;
242 }
243 } 244 }
244 return handled; 245 return handled;
245} 246}
246 247
247void LLSlider::draw() 248void LLSlider::draw()
248{ 249{
249 if( getVisible() ) 250 // since thumb image might still be decoding, need thumb to accomodate image size
250 { 251 updateThumbRect();
251 // since thumb image might still be decoding, need thumb to accomodate image size
252 updateThumbRect();
253
254 // Draw background and thumb.
255
256 // drawing solids requires texturing be disabled
257 LLGLSNoTexture no_texture;
258
259 LLRect rect(mDragStartThumbRect);
260
261 F32 opacity = getEnabled() ? 1.f : 0.3f;
262 LLColor4 center_color = (mThumbCenterColor % opacity);
263 LLColor4 track_color = (mTrackColor % opacity);
264
265 // Track
266 LLRect track_rect(mThumbImage->getWidth() / 2,
267 getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2),
268 getRect().getWidth() - mThumbImage->getWidth() / 2,
269 getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) );
270
271 gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 3, 3, track_rect.getWidth(), track_rect.getHeight(),
272 mTrackImage, track_color);
273 gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 3, 3, mThumbRect.mLeft, track_rect.getHeight(),
274 mTrackHighlightImage, track_color);
275 252
253 // Draw background and thumb.
276 254
277 // Thumb 255 // drawing solids requires texturing be disabled
278 if( hasMouseCapture() ) 256 LLGLSNoTexture no_texture;
279 {
280 gl_draw_scaled_image(mDragStartThumbRect.mLeft, mDragStartThumbRect.mBottom, mDragStartThumbRect.getWidth(), mDragStartThumbRect.getHeight(),
281 mThumbImage, mThumbCenterColor % 0.3f);
282 257
283 if (hasFocus()) 258 F32 opacity = getEnabled() ? 1.f : 0.3f;
284 { 259 LLColor4 center_color = (mThumbCenterColor % opacity);
285 F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); 260 LLColor4 track_color = (mTrackColor % opacity);
286 LLRect highlight_rect = mThumbRect;
287 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt)));
288 gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 0, 0, highlight_rect.getWidth(), highlight_rect.getHeight(),
289 mThumbImage, gFocusMgr.getFocusColor(), TRUE);
290 }
291 261
292 gl_draw_scaled_image(mThumbRect.mLeft, mThumbRect.mBottom, mThumbRect.getWidth(), mThumbRect.getHeight(), 262 // Track
293 mThumbImage, mThumbOutlineColor); 263 LLRect track_rect(mThumbImage->getWidth() / 2,
264 getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2),
265 getRect().getWidth() - mThumbImage->getWidth() / 2,
266 getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) );
267 LLRect highlight_rect(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom);
268 mTrackImage->draw(track_rect);
269 mTrackHighlightImage->draw(highlight_rect);
294 270
295 } 271 // Thumb
296 else 272 if( hasMouseCapture() )
297 { 273 {
298 if (hasFocus()) 274 // Show ghost where thumb was before dragging began.
299 { 275 mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor % 0.3f);
300 F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
301 LLRect highlight_rect = mThumbRect;
302 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt)));
303 gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 0, 0, highlight_rect.getWidth(), highlight_rect.getHeight(),
304 mThumbImage, gFocusMgr.getFocusColor(), TRUE);
305 }
306
307 gl_draw_scaled_image(mThumbRect.mLeft, mThumbRect.mBottom, mThumbRect.getWidth(), mThumbRect.getHeight(),
308 mThumbImage, center_color);
309 }
310 LLUICtrl::draw();
311 } 276 }
277 if (hasFocus())
278 {
279 // Draw focus highlighting.
280 mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
281 }
282 // Fill in the thumb.
283 mThumbImage->draw(mThumbRect, hasMouseCapture() ? mThumbOutlineColor : center_color);
284
285 LLUICtrl::draw();
312} 286}
313 287
314// virtual 288// virtual
diff --git a/linden/indra/llui/llslider.h b/linden/indra/llui/llslider.h
index 506a6bd..1c9d5e1 100644
--- a/linden/indra/llui/llslider.h
+++ b/linden/indra/llui/llslider.h
@@ -52,8 +52,6 @@ public:
52 BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG 52 BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG
53 const LLString& control_name = LLString::null ); 53 const LLString& control_name = LLString::null );
54 54
55 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SLIDER_BAR; }
56 virtual LLString getWidgetTag() const { return LL_SLIDER_TAG; }
57 virtual LLXMLNodePtr getXML(bool save_children = true) const; 55 virtual LLXMLNodePtr getXML(bool save_children = true) const;
58 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); 56 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
59 57
@@ -79,7 +77,7 @@ public:
79 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 77 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
80 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); 78 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
81 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 79 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
82 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 80 virtual BOOL handleKeyHere(KEY key, MASK mask);
83 virtual void draw(); 81 virtual void draw();
84 82
85private: 83private:
@@ -96,9 +94,9 @@ private:
96 S32 mMouseOffset; 94 S32 mMouseOffset;
97 LLRect mDragStartThumbRect; 95 LLRect mDragStartThumbRect;
98 96
99 LLImageGL* mThumbImage; 97 LLUIImage* mThumbImage;
100 LLImageGL* mTrackImage; 98 LLUIImage* mTrackImage;
101 LLImageGL* mTrackHighlightImage; 99 LLUIImage* mTrackHighlightImage;
102 100
103 LLRect mThumbRect; 101 LLRect mThumbRect;
104 LLColor4 mTrackColor; 102 LLColor4 mTrackColor;
diff --git a/linden/indra/llui/llsliderctrl.cpp b/linden/indra/llui/llsliderctrl.cpp
index 58ab4ae..d3dc35f 100644
--- a/linden/indra/llui/llsliderctrl.cpp
+++ b/linden/indra/llui/llsliderctrl.cpp
@@ -52,6 +52,7 @@
52 52
53const U32 MAX_STRING_LENGTH = 10; 53const U32 MAX_STRING_LENGTH = 10;
54 54
55static LLRegisterWidget<LLSliderCtrl> r("slider");
55 56
56LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, 57LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect,
57 const LLString& label, 58 const LLString& label,
diff --git a/linden/indra/llui/llsliderctrl.h b/linden/indra/llui/llsliderctrl.h
index 705fa5c..0c8a8b6 100644
--- a/linden/indra/llui/llsliderctrl.h
+++ b/linden/indra/llui/llsliderctrl.h
@@ -63,8 +63,7 @@ public:
63 const LLString& control_which = LLString::null ); 63 const LLString& control_which = LLString::null );
64 64
65 virtual ~LLSliderCtrl() {} // Children all cleaned up by default view destructor. 65 virtual ~LLSliderCtrl() {} // Children all cleaned up by default view destructor.
66 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SLIDER; } 66
67 virtual LLString getWidgetTag() const { return LL_SLIDER_CTRL_TAG; }
68 virtual LLXMLNodePtr getXML(bool save_children = true) const; 67 virtual LLXMLNodePtr getXML(bool save_children = true) const;
69 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 68 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
70 69
diff --git a/linden/indra/llui/llspinctrl.cpp b/linden/indra/llui/llspinctrl.cpp
index 98cdae1..9e85b20 100644
--- a/linden/indra/llui/llspinctrl.cpp
+++ b/linden/indra/llui/llspinctrl.cpp
@@ -52,6 +52,7 @@
52 52
53const U32 MAX_STRING_LENGTH = 32; 53const U32 MAX_STRING_LENGTH = 32;
54 54
55static LLRegisterWidget<LLSpinCtrl> r2("spinner");
55 56
56LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString& label, const LLFontGL* font, 57LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString& label, const LLFontGL* font,
57 void (*commit_callback)(LLUICtrl*, void*), 58 void (*commit_callback)(LLUICtrl*, void*),
@@ -409,26 +410,23 @@ void LLSpinCtrl::draw()
409 410
410BOOL LLSpinCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) 411BOOL LLSpinCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
411{ 412{
412 if( getEnabled() ) 413 if( clicks > 0 )
413 { 414 {
414 if( clicks > 0 ) 415 while( clicks-- )
415 { 416 {
416 while( clicks-- ) 417 LLSpinCtrl::onDownBtn(this);
417 {
418 LLSpinCtrl::onDownBtn(this);
419 }
420 }
421 else
422 while( clicks++ )
423 {
424 LLSpinCtrl::onUpBtn(this);
425 } 418 }
426 } 419 }
420 else
421 while( clicks++ )
422 {
423 LLSpinCtrl::onUpBtn(this);
424 }
427 425
428 return TRUE; 426 return TRUE;
429} 427}
430 428
431BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 429BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask)
432{ 430{
433 if (mEditor->hasFocus()) 431 if (mEditor->hasFocus())
434 { 432 {
diff --git a/linden/indra/llui/llspinctrl.h b/linden/indra/llui/llspinctrl.h
index f1f971e..790e216 100644
--- a/linden/indra/llui/llspinctrl.h
+++ b/linden/indra/llui/llspinctrl.h
@@ -62,8 +62,7 @@ public:
62 S32 label_width = SPINCTRL_DEFAULT_LABEL_WIDTH ); 62 S32 label_width = SPINCTRL_DEFAULT_LABEL_WIDTH );
63 63
64 virtual ~LLSpinCtrl() {} // Children all cleaned up by default view destructor. 64 virtual ~LLSpinCtrl() {} // Children all cleaned up by default view destructor.
65 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SPINNER; } 65
66 virtual LLString getWidgetTag() const { return LL_SPIN_CTRL_TAG; }
67 virtual LLXMLNodePtr getXML(bool save_children = true) const; 66 virtual LLXMLNodePtr getXML(bool save_children = true) const;
68 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); 67 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
69 68
@@ -101,7 +100,7 @@ public:
101 void forceEditorCommit(); // for commit on external button 100 void forceEditorCommit(); // for commit on external button
102 101
103 virtual BOOL handleScrollWheel(S32 x,S32 y,S32 clicks); 102 virtual BOOL handleScrollWheel(S32 x,S32 y,S32 clicks);
104 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 103 virtual BOOL handleKeyHere(KEY key, MASK mask);
105 104
106 virtual void draw(); 105 virtual void draw();
107 106
diff --git a/linden/indra/llui/llstyle.cpp b/linden/indra/llui/llstyle.cpp
index cdf87d3..7c46114 100644
--- a/linden/indra/llui/llstyle.cpp
+++ b/linden/indra/llui/llstyle.cpp
@@ -138,12 +138,34 @@ void LLStyle::setFontName(const LLString& fontname)
138} 138}
139 139
140 140
141void LLStyle::setImage(const LLString& src) 141void LLStyle::setLinkHREF(const LLString& href)
142{ 142{
143 if (src.size() >= UUID_STR_LENGTH - 1) 143 mLink = href;
144 { 144}
145 mImagep = LLUI::sImageProvider->getImageByID(LLUUID(src)); 145
146 } 146BOOL LLStyle::isLink() const
147{
148 return mLink.size();
149}
150
151BOOL LLStyle::isVisible() const
152{
153 return mVisible;
154}
155
156void LLStyle::setVisible(BOOL is_visible)
157{
158 mVisible = is_visible;
159}
160
161LLUIImagePtr LLStyle::getImage() const
162{
163 return mImagep;
164}
165
166void LLStyle::setImage(const LLUUID& src)
167{
168 mImagep = LLUI::sImageProvider->getUIImageByID(src);
147} 169}
148 170
149 171
diff --git a/linden/indra/llui/llstyle.h b/linden/indra/llui/llstyle.h
index d6ae900..6f0099c 100644
--- a/linden/indra/llui/llstyle.h
+++ b/linden/indra/llui/llstyle.h
@@ -35,7 +35,7 @@
35#include "v4color.h" 35#include "v4color.h"
36#include "llresmgr.h" 36#include "llresmgr.h"
37#include "llfont.h" 37#include "llfont.h"
38#include "llimagegl.h" 38#include "llui.h"
39 39
40class LLStyle 40class LLStyle
41{ 41{
@@ -53,19 +53,20 @@ public:
53 virtual const LLColor4& getColor() const { return mColor; } 53 virtual const LLColor4& getColor() const { return mColor; }
54 virtual void setColor(const LLColor4 &color) { mColor = color; } 54 virtual void setColor(const LLColor4 &color) { mColor = color; }
55 55
56 virtual BOOL isVisible() const { return mVisible; } 56 virtual BOOL isVisible() const;
57 virtual void setVisible(BOOL is_visible) { mVisible = is_visible; } 57 virtual void setVisible(BOOL is_visible);
58 58
59 virtual const LLString& getFontString() const { return mFontName; } 59 virtual const LLString& getFontString() const { return mFontName; }
60 virtual void setFontName(const LLString& fontname); 60 virtual void setFontName(const LLString& fontname);
61 virtual LLFONT_ID getFontID() const { return mFontID; } 61 virtual LLFONT_ID getFontID() const { return mFontID; }
62 62
63 virtual const LLString& getLinkHREF() const { return mLink; } 63 virtual const LLString& getLinkHREF() const { return mLink; }
64 virtual void setLinkHREF(const LLString& href) { mLink = href; } 64 virtual void setLinkHREF(const LLString& href);
65 virtual BOOL isLink() const { return mLink.size(); } 65 virtual BOOL isLink() const;
66
67 virtual LLUIImagePtr getImage() const;
68 virtual void setImage(const LLUUID& src);
66 69
67 virtual LLImageGL *getImage() const { return mImagep; }
68 virtual void setImage(const LLString& src);
69 virtual BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); } 70 virtual BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); }
70 virtual void setImageSize(S32 width, S32 height); 71 virtual void setImageSize(S32 width, S32 height);
71 72
@@ -106,7 +107,7 @@ private:
106 LLString mFontName; 107 LLString mFontName;
107 LLFONT_ID mFontID; 108 LLFONT_ID mFontID;
108 LLString mLink; 109 LLString mLink;
109 LLPointer<LLImageGL> mImagep; 110 LLUIImagePtr mImagep;
110 BOOL mIsEmbeddedItem; 111 BOOL mIsEmbeddedItem;
111}; 112};
112 113
diff --git a/linden/indra/llui/lltabcontainer.cpp b/linden/indra/llui/lltabcontainer.cpp
index e632cf1..7f581dc 100644
--- a/linden/indra/llui/lltabcontainer.cpp
+++ b/linden/indra/llui/lltabcontainer.cpp
@@ -64,7 +64,7 @@ const S32 TABCNTRV_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTRV_CLOSE_BTN_SIZ
64const S32 TABCNTRV_ARROW_BTN_SIZE = 16; 64const S32 TABCNTRV_ARROW_BTN_SIZE = 16;
65const S32 TABCNTRV_PAD = 0; 65const S32 TABCNTRV_PAD = 0;
66 66
67 67static LLRegisterWidget<LLTabContainer> r("tab_container");
68 68
69LLTabContainer::LLTabContainer(const LLString& name, const LLRect& rect, TabPosition pos, 69LLTabContainer::LLTabContainer(const LLString& name, const LLRect& rect, TabPosition pos,
70 BOOL bordered, BOOL is_vertical ) 70 BOOL bordered, BOOL is_vertical )
@@ -115,18 +115,6 @@ void LLTabContainer::setValue(const LLSD& value)
115} 115}
116 116
117//virtual 117//virtual
118EWidgetType LLTabContainer::getWidgetType() const
119{
120 return WIDGET_TYPE_TAB_CONTAINER;
121}
122
123//virtual
124LLString LLTabContainer::getWidgetTag() const
125{
126 return LL_TAB_CONTAINER_COMMON_TAG;
127}
128
129//virtual
130void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent) 118void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent)
131{ 119{
132 LLPanel::reshape( width, height, called_from_parent ); 120 LLPanel::reshape( width, height, called_from_parent );
@@ -134,7 +122,7 @@ void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent)
134} 122}
135 123
136//virtual 124//virtual
137LLView* LLTabContainer::getChildByName(const LLString& name, BOOL recurse) const 125LLView* LLTabContainer::getChildView(const LLString& name, BOOL recurse, BOOL create_if_missing) const
138{ 126{
139 tuple_list_t::const_iterator itor; 127 tuple_list_t::const_iterator itor;
140 for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) 128 for (itor = mTabList.begin(); itor != mTabList.end(); ++itor)
@@ -145,19 +133,20 @@ LLView* LLTabContainer::getChildByName(const LLString& name, BOOL recurse) const
145 return panel; 133 return panel;
146 } 134 }
147 } 135 }
136
148 if (recurse) 137 if (recurse)
149 { 138 {
150 for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) 139 for (itor = mTabList.begin(); itor != mTabList.end(); ++itor)
151 { 140 {
152 LLPanel *panel = (*itor)->mTabPanel; 141 LLPanel *panel = (*itor)->mTabPanel;
153 LLView *child = panel->getChild<LLView>(name, recurse); 142 LLView *child = panel->getChildView(name, recurse, FALSE);
154 if (child) 143 if (child)
155 { 144 {
156 return child; 145 return child;
157 } 146 }
158 } 147 }
159 } 148 }
160 return LLView::getChildByName(name, recurse); 149 return LLView::getChildView(name, recurse, create_if_missing);
161} 150}
162 151
163// virtual 152// virtual
@@ -185,124 +174,122 @@ void LLTabContainer::draw()
185 } 174 }
186 175
187 setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f))); 176 setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)));
188 if( getVisible() ) 177
178 BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0);
179 if (!mIsVertical)
189 { 180 {
190 BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0); 181 mJumpPrevArrowBtn->setVisible( has_scroll_arrows );
191 if (!mIsVertical) 182 mJumpNextArrowBtn->setVisible( has_scroll_arrows );
192 { 183 }
193 mJumpPrevArrowBtn->setVisible( has_scroll_arrows ); 184 mPrevArrowBtn->setVisible( has_scroll_arrows );
194 mJumpNextArrowBtn->setVisible( has_scroll_arrows ); 185 mNextArrowBtn->setVisible( has_scroll_arrows );
195 }
196 mPrevArrowBtn->setVisible( has_scroll_arrows );
197 mNextArrowBtn->setVisible( has_scroll_arrows );
198 186
199 S32 left = 0, top = 0; 187 S32 left = 0, top = 0;
200 if (mIsVertical) 188 if (mIsVertical)
201 { 189 {
202 top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0); 190 top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0);
203 top += getScrollPosPixels(); 191 top += getScrollPosPixels();
204 } 192 }
205 else 193 else
206 { 194 {
207 // Set the leftmost position of the tab buttons. 195 // Set the leftmost position of the tab buttons.
208 left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD); 196 left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD);
209 left -= getScrollPosPixels(); 197 left -= getScrollPosPixels();
210 } 198 }
211 199
212 // Hide all the buttons 200 // Hide all the buttons
201 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
202 {
203 LLTabTuple* tuple = *iter;
204 tuple->mButton->setVisible( FALSE );
205 }
206
207 LLPanel::draw();
208
209 // if tabs are hidden, don't draw them and leave them in the invisible state
210 if (!getTabsHidden())
211 {
212 // Show all the buttons
213 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) 213 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
214 { 214 {
215 LLTabTuple* tuple = *iter; 215 LLTabTuple* tuple = *iter;
216 tuple->mButton->setVisible( FALSE ); 216 tuple->mButton->setVisible( TRUE );
217 } 217 }
218 218
219 LLPanel::draw(); 219 // Draw some of the buttons...
220 220 LLRect clip_rect = getLocalRect();
221 // if tabs are hidden, don't draw them and leave them in the invisible state 221 if (has_scroll_arrows)
222 if (!getTabsHidden())
223 { 222 {
224 // Show all the buttons 223 // ...but clip them.
225 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) 224 if (mIsVertical)
226 { 225 {
227 LLTabTuple* tuple = *iter; 226 clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*TABCNTRV_PAD;
228 tuple->mButton->setVisible( TRUE ); 227 clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD;
229 } 228 }
230 229 else
231 // Draw some of the buttons...
232 LLRect clip_rect = getLocalRect();
233 if (has_scroll_arrows)
234 { 230 {
235 // ...but clip them. 231 clip_rect.mLeft = mPrevArrowBtn->getRect().mRight;
236 if (mIsVertical) 232 clip_rect.mRight = mNextArrowBtn->getRect().mLeft;
237 {
238 clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*TABCNTRV_PAD;
239 clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD;
240 }
241 else
242 {
243 clip_rect.mLeft = mPrevArrowBtn->getRect().mRight;
244 clip_rect.mRight = mNextArrowBtn->getRect().mLeft;
245 }
246 } 233 }
247 LLLocalClipRect clip(clip_rect); 234 }
235 LLLocalClipRect clip(clip_rect);
248 236
249 S32 max_scroll_visible = getTabCount() - getMaxScrollPos() + getScrollPos(); 237 S32 max_scroll_visible = getTabCount() - getMaxScrollPos() + getScrollPos();
250 S32 idx = 0; 238 S32 idx = 0;
251 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) 239 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
252 { 240 {
253 LLTabTuple* tuple = *iter; 241 LLTabTuple* tuple = *iter;
254 242
255 tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0, 243 tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0,
256 top ? top - tuple->mButton->getRect().mTop : 0 ); 244 top ? top - tuple->mButton->getRect().mTop : 0 );
257 if (top) top -= BTN_HEIGHT + TABCNTRV_PAD; 245 if (top) top -= BTN_HEIGHT + TABCNTRV_PAD;
258 if (left) left += tuple->mButton->getRect().getWidth(); 246 if (left) left += tuple->mButton->getRect().getWidth();
259 247
260 if (!mIsVertical) 248 if (!mIsVertical)
249 {
250 if( idx < getScrollPos() )
261 { 251 {
262 if( idx < getScrollPos() ) 252 if( tuple->mButton->getFlashing() )
263 {
264 if( tuple->mButton->getFlashing() )
265 {
266 mPrevArrowBtn->setFlashing( TRUE );
267 }
268 }
269 else if( max_scroll_visible < idx )
270 { 253 {
271 if( tuple->mButton->getFlashing() ) 254 mPrevArrowBtn->setFlashing( TRUE );
272 {
273 mNextArrowBtn->setFlashing( TRUE );
274 }
275 } 255 }
276 } 256 }
277 LLUI::pushMatrix(); 257 else if( max_scroll_visible < idx )
278 { 258 {
279 LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); 259 if( tuple->mButton->getFlashing() )
280 tuple->mButton->draw(); 260 {
261 mNextArrowBtn->setFlashing( TRUE );
262 }
281 } 263 }
282 LLUI::popMatrix();
283
284 idx++;
285 } 264 }
286 265 LLUI::pushMatrix();
287
288 if( mIsVertical && has_scroll_arrows )
289 { 266 {
290 // Redraw the arrows so that they appears on top. 267 LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f);
291 gGL.pushMatrix(); 268 tuple->mButton->draw();
292 gGL.translatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f);
293 mPrevArrowBtn->draw();
294 gGL.popMatrix();
295
296 gGL.pushMatrix();
297 gGL.translatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f);
298 mNextArrowBtn->draw();
299 gGL.popMatrix();
300 } 269 }
270 LLUI::popMatrix();
271
272 idx++;
301 } 273 }
302 274
303 mPrevArrowBtn->setFlashing(FALSE); 275
304 mNextArrowBtn->setFlashing(FALSE); 276 if( mIsVertical && has_scroll_arrows )
277 {
278 // Redraw the arrows so that they appears on top.
279 gGL.pushMatrix();
280 gGL.translatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f);
281 mPrevArrowBtn->draw();
282 gGL.popMatrix();
283
284 gGL.pushMatrix();
285 gGL.translatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f);
286 mNextArrowBtn->draw();
287 gGL.popMatrix();
288 }
305 } 289 }
290
291 mPrevArrowBtn->setFlashing(FALSE);
292 mNextArrowBtn->setFlashing(FALSE);
306} 293}
307 294
308 295
@@ -524,12 +511,8 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_
524} 511}
525 512
526// virtual 513// virtual
527BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 514BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask)
528{ 515{
529 if (!getEnabled()) return FALSE;
530
531 if (!gFocusMgr.childHasKeyboardFocus(this)) return FALSE;
532
533 BOOL handled = FALSE; 516 BOOL handled = FALSE;
534 if (key == KEY_LEFT && mask == MASK_ALT) 517 if (key == KEY_LEFT && mask == MASK_ALT)
535 { 518 {
@@ -687,7 +670,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
687 // already a child of mine 670 // already a child of mine
688 return; 671 return;
689 } 672 }
690 const LLFontGL* font = gResMgr->getRes( mIsVertical ? LLFONT_SANSSERIF : LLFONT_SANSSERIF_SMALL ); 673 const LLFontGL* font = LLResMgr::getInstance()->getRes( mIsVertical ? LLFONT_SANSSERIF : LLFONT_SANSSERIF_SMALL );
691 674
692 // Store the original label for possible xml export. 675 // Store the original label for possible xml export.
693 child->setLabel(label); 676 child->setLabel(label);
@@ -1272,7 +1255,7 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
1272 1255
1273 if (!mIsVertical) 1256 if (!mIsVertical)
1274 { 1257 {
1275 const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); 1258 const LLFontGL* fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
1276 // remove current width from total tab strip width 1259 // remove current width from total tab strip width
1277 mTotalTabWidth -= tuple->mButton->getRect().getWidth(); 1260 mTotalTabWidth -= tuple->mButton->getRect().getWidth();
1278 1261
@@ -1353,7 +1336,7 @@ void LLTabContainer::setPanelTitle(S32 index, const LLString& title)
1353 { 1336 {
1354 LLTabTuple* tuple = getTab(index); 1337 LLTabTuple* tuple = getTab(index);
1355 LLButton* tab_button = tuple->mButton; 1338 LLButton* tab_button = tuple->mButton;
1356 const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); 1339 const LLFontGL* fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
1357 mTotalTabWidth -= tab_button->getRect().getWidth(); 1340 mTotalTabWidth -= tab_button->getRect().getWidth();
1358 tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); 1341 tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight());
1359 mTotalTabWidth += tab_button->getRect().getWidth(); 1342 mTotalTabWidth += tab_button->getRect().getWidth();
diff --git a/linden/indra/llui/lltabcontainer.h b/linden/indra/llui/lltabcontainer.h
index 152bd05..16f8be5 100644
--- a/linden/indra/llui/lltabcontainer.h
+++ b/linden/indra/llui/lltabcontainer.h
@@ -62,19 +62,19 @@ public:
62 62
63 // from LLView 63 // from LLView
64 /*virtual*/ void setValue(const LLSD& value); 64 /*virtual*/ void setValue(const LLSD& value);
65 /*virtual*/ EWidgetType getWidgetType() const; 65
66 /*virtual*/ LLString getWidgetTag() const;
67 /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); 66 /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
68 /*virtual*/ void draw(); 67 /*virtual*/ void draw();
69 /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); 68 /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
70 /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); 69 /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
71 /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); 70 /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask );
72 /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect ); 71 /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect );
73 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 72 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
74 /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, 73 /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
75 EDragAndDropType type, void* cargo_data, 74 EDragAndDropType type, void* cargo_data,
76 EAcceptance* accept, LLString& tooltip); 75 EAcceptance* accept, LLString& tooltip);
77 /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; 76 /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
77 /*virtual*/ LLView* getChildView(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
78 78
79 void addTabPanel(LLPanel* child, 79 void addTabPanel(LLPanel* child,
80 const LLString& label, 80 const LLString& label,
@@ -142,10 +142,6 @@ public:
142 142
143 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 143 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
144 144
145protected:
146 /*virtual*/ LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const;
147
148
149private: 145private:
150 // Structure used to map tab buttons to and from tab panels 146 // Structure used to map tab buttons to and from tab panels
151 struct LLTabTuple 147 struct LLTabTuple
diff --git a/linden/indra/llui/lltextbox.cpp b/linden/indra/llui/lltextbox.cpp
index 9ad7849..0f411b8 100644
--- a/linden/indra/llui/lltextbox.cpp
+++ b/linden/indra/llui/lltextbox.cpp
@@ -34,6 +34,8 @@
34#include "lluictrlfactory.h" 34#include "lluictrlfactory.h"
35#include "llfocusmgr.h" 35#include "llfocusmgr.h"
36 36
37static LLRegisterWidget<LLTextBox> r("text");
38
37LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& text, 39LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& text,
38 const LLFontGL* font, BOOL mouse_opaque) 40 const LLFontGL* font, BOOL mouse_opaque)
39: LLUICtrl(name, rect, mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ), 41: LLUICtrl(name, rect, mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ),
@@ -212,7 +214,7 @@ void LLTextBox::setLineLengths()
212 LLString::size_type cur = 0; 214 LLString::size_type cur = 0;
213 LLString::size_type len = mText.getWString().size(); 215 LLString::size_type len = mText.getWString().size();
214 216
215 while (cur < len) 217 while (cur < len)
216 { 218 {
217 LLString::size_type end = mText.getWString().find('\n', cur); 219 LLString::size_type end = mText.getWString().find('\n', cur);
218 LLString::size_type runLen; 220 LLString::size_type runLen;
@@ -323,63 +325,60 @@ BOOL LLTextBox::setTextArg( const LLString& key, const LLStringExplicit& text )
323 325
324void LLTextBox::draw() 326void LLTextBox::draw()
325{ 327{
326 if( getVisible() ) 328 if (mBorderVisible)
327 { 329 {
328 if (mBorderVisible) 330 gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
329 { 331 }
330 gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
331 }
332 332
333 if( mBorderDropShadowVisible ) 333 if( mBorderDropShadowVisible )
334 { 334 {
335 static LLColor4 color_drop_shadow = LLUI::sColorsGroup->getColor("ColorDropShadow"); 335 static LLColor4 color_drop_shadow = LLUI::sColorsGroup->getColor("ColorDropShadow");
336 static S32 drop_shadow_tooltip = LLUI::sConfigGroup->getS32("DropShadowTooltip"); 336 static S32 drop_shadow_tooltip = LLUI::sConfigGroup->getS32("DropShadowTooltip");
337 gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, 337 gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
338 color_drop_shadow, drop_shadow_tooltip); 338 color_drop_shadow, drop_shadow_tooltip);
339 } 339 }
340
341 if (mBackgroundVisible)
342 {
343 LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
344 gl_rect_2d( r, mBackgroundColor );
345 }
346 340
347 S32 text_x = 0; 341 if (mBackgroundVisible)
348 switch( mHAlign ) 342 {
349 { 343 LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
350 case LLFontGL::LEFT: 344 gl_rect_2d( r, mBackgroundColor );
351 text_x = mHPad; 345 }
352 break;
353 case LLFontGL::HCENTER:
354 text_x = getRect().getWidth() / 2;
355 break;
356 case LLFontGL::RIGHT:
357 text_x = getRect().getWidth() - mHPad;
358 break;
359 }
360 346
361 S32 text_y = getRect().getHeight() - mVPad; 347 S32 text_x = 0;
348 switch( mHAlign )
349 {
350 case LLFontGL::LEFT:
351 text_x = mHPad;
352 break;
353 case LLFontGL::HCENTER:
354 text_x = getRect().getWidth() / 2;
355 break;
356 case LLFontGL::RIGHT:
357 text_x = getRect().getWidth() - mHPad;
358 break;
359 }
362 360
363 if ( getEnabled() ) 361 S32 text_y = getRect().getHeight() - mVPad;
362
363 if ( getEnabled() )
364 {
365 if(mHasHover)
364 { 366 {
365 if(mHasHover) 367 drawText( text_x, text_y, mHoverColor );
366 {
367 drawText( text_x, text_y, mHoverColor );
368 }
369 else
370 {
371 drawText( text_x, text_y, mTextColor );
372 }
373 } 368 }
374 else 369 else
375 { 370 {
376 drawText( text_x, text_y, mDisabledColor ); 371 drawText( text_x, text_y, mTextColor );
377 } 372 }
373 }
374 else
375 {
376 drawText( text_x, text_y, mDisabledColor );
377 }
378 378
379 if (sDebugRects) 379 if (sDebugRects)
380 { 380 {
381 drawDebugRect(); 381 drawDebugRect();
382 }
383 } 382 }
384 383
385 mHasHover = FALSE; // This is reset every frame. 384 mHasHover = FALSE; // This is reset every frame.
diff --git a/linden/indra/llui/lltextbox.h b/linden/indra/llui/lltextbox.h
index 7bea722..ffe6f4c 100644
--- a/linden/indra/llui/lltextbox.h
+++ b/linden/indra/llui/lltextbox.h
@@ -57,8 +57,7 @@ public:
57 LLTextBox(const LLString& name_and_label); 57 LLTextBox(const LLString& name_and_label);
58 58
59 virtual ~LLTextBox() {} 59 virtual ~LLTextBox() {}
60 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEXT_BOX; } 60
61 virtual LLString getWidgetTag() const { return LL_TEXT_BOX_TAG; }
62 virtual LLXMLNodePtr getXML(bool save_children = true) const; 61 virtual LLXMLNodePtr getXML(bool save_children = true) const;
63 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); 62 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
64 63
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp
index 545fddb..4ed936f 100644
--- a/linden/indra/llui/lltexteditor.cpp
+++ b/linden/indra/llui/lltexteditor.cpp
@@ -64,6 +64,8 @@
64// 64//
65// Globals 65// Globals
66// 66//
67static LLRegisterWidget<LLTextEditor> r("simple_text_editor");
68
67BOOL gDebugTextEditorTips = FALSE; 69BOOL gDebugTextEditorTips = FALSE;
68 70
69// 71//
@@ -304,10 +306,10 @@ LLTextEditor::LLTextEditor(
304 // Init the scrollbar 306 // Init the scrollbar
305 LLRect scroll_rect; 307 LLRect scroll_rect;
306 scroll_rect.setOriginAndSize( 308 scroll_rect.setOriginAndSize(
307 getRect().getWidth() - UI_TEXTEDITOR_BORDER - SCROLLBAR_SIZE, 309 getRect().getWidth() - SCROLLBAR_SIZE,
308 UI_TEXTEDITOR_BORDER, 310 1,
309 SCROLLBAR_SIZE, 311 SCROLLBAR_SIZE,
310 getRect().getHeight() - 2 * UI_TEXTEDITOR_BORDER ); 312 getRect().getHeight() - 1);
311 S32 lines_in_doc = getLineCount(); 313 S32 lines_in_doc = getLineCount();
312 mScrollbar = new LLScrollbar( "Scrollbar", scroll_rect, 314 mScrollbar = new LLScrollbar( "Scrollbar", scroll_rect,
313 LLScrollbar::VERTICAL, 315 LLScrollbar::VERTICAL,
@@ -1102,14 +1104,7 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rec
1102BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) 1104BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks)
1103{ 1105{
1104 // Pretend the mouse is over the scrollbar 1106 // Pretend the mouse is over the scrollbar
1105 if (getVisible()) 1107 return mScrollbar->handleScrollWheel( 0, 0, clicks );
1106 {
1107 return mScrollbar->handleScrollWheel( 0, 0, clicks );
1108 }
1109 else
1110 {
1111 return FALSE;
1112 }
1113} 1108}
1114 1109
1115BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) 1110BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1197,91 +1192,88 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
1197 BOOL handled = FALSE; 1192 BOOL handled = FALSE;
1198 1193
1199 mHoverSegment = NULL; 1194 mHoverSegment = NULL;
1200 if( getVisible() ) 1195 if(hasMouseCapture() )
1201 { 1196 {
1202 if(hasMouseCapture() ) 1197 if( mIsSelecting )
1203 { 1198 {
1204 if( mIsSelecting ) 1199 if (x != mLastSelectionX || y != mLastSelectionY)
1205 { 1200 {
1206 if (x != mLastSelectionX || y != mLastSelectionY) 1201 mLastSelectionX = x;
1207 { 1202 mLastSelectionY = y;
1208 mLastSelectionX = x; 1203 }
1209 mLastSelectionY = y;
1210 }
1211 1204
1212 if( y > mTextRect.mTop ) 1205 if( y > mTextRect.mTop )
1206 {
1207 mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 );
1208 }
1209 else
1210 if( y < mTextRect.mBottom )
1211 {
1212 mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 );
1213 }
1214
1215 setCursorAtLocalPos( x, y, TRUE );
1216 mSelectionEnd = mCursorPos;
1217
1218 updateScrollFromCursor();
1219 }
1220
1221 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
1222 getWindow()->setCursor(UI_CURSOR_IBEAM);
1223 handled = TRUE;
1224 }
1225
1226 if( !handled )
1227 {
1228 // Pass to children
1229 handled = LLView::childrenHandleHover(x, y, mask) != NULL;
1230 }
1231
1232 if( handled )
1233 {
1234 // Delay cursor flashing
1235 resetKeystrokeTimer();
1236 }
1237
1238 // Opaque
1239 if( !handled && mTakesNonScrollClicks)
1240 {
1241 // Check to see if we're over an HTML-style link
1242 if( !mSegments.empty() )
1243 {
1244 const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
1245 if( cur_segment )
1246 {
1247 if(cur_segment->getStyle().isLink())
1213 { 1248 {
1214 mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); 1249 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl;
1250 getWindow()->setCursor(UI_CURSOR_HAND);
1251 handled = TRUE;
1215 } 1252 }
1216 else 1253 else
1217 if( y < mTextRect.mBottom ) 1254 if(cur_segment->getStyle().getIsEmbeddedItem())
1218 { 1255 {
1219 mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); 1256 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl;
1257 getWindow()->setCursor(UI_CURSOR_HAND);
1258 //getWindow()->setCursor(UI_CURSOR_ARROW);
1259 handled = TRUE;
1220 } 1260 }
1221 1261 mHoverSegment = cur_segment;
1222 setCursorAtLocalPos( x, y, TRUE );
1223 mSelectionEnd = mCursorPos;
1224
1225 updateScrollFromCursor();
1226 } 1262 }
1227
1228 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
1229 getWindow()->setCursor(UI_CURSOR_IBEAM);
1230 handled = TRUE;
1231 } 1263 }
1232 1264
1233 if( !handled ) 1265 if( !handled )
1234 { 1266 {
1235 // Pass to children 1267 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
1236 handled = LLView::childrenHandleHover(x, y, mask) != NULL; 1268 if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE)
1237 }
1238
1239 if( handled )
1240 {
1241 // Delay cursor flashing
1242 resetKeystrokeTimer();
1243 }
1244
1245 // Opaque
1246 if( !handled && mTakesNonScrollClicks)
1247 {
1248 // Check to see if we're over an HTML-style link
1249 if( !mSegments.empty() )
1250 { 1269 {
1251 const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); 1270 getWindow()->setCursor(UI_CURSOR_IBEAM);
1252 if( cur_segment )
1253 {
1254 if(cur_segment->getStyle().isLink())
1255 {
1256 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl;
1257 getWindow()->setCursor(UI_CURSOR_HAND);
1258 handled = TRUE;
1259 }
1260 else
1261 if(cur_segment->getStyle().getIsEmbeddedItem())
1262 {
1263 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl;
1264 getWindow()->setCursor(UI_CURSOR_HAND);
1265 //getWindow()->setCursor(UI_CURSOR_ARROW);
1266 handled = TRUE;
1267 }
1268 mHoverSegment = cur_segment;
1269 }
1270 } 1271 }
1271 1272 else
1272 if( !handled )
1273 { 1273 {
1274 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; 1274 getWindow()->setCursor(UI_CURSOR_ARROW);
1275 if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE)
1276 {
1277 getWindow()->setCursor(UI_CURSOR_IBEAM);
1278 }
1279 else
1280 {
1281 getWindow()->setCursor(UI_CURSOR_ARROW);
1282 }
1283 handled = TRUE;
1284 } 1275 }
1276 handled = TRUE;
1285 } 1277 }
1286 } 1278 }
1287 1279
@@ -2154,14 +2146,14 @@ void LLTextEditor::unindentLineBeforeCloseBrace()
2154} 2146}
2155 2147
2156 2148
2157BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) 2149BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
2158{ 2150{
2159 BOOL handled = FALSE; 2151 BOOL handled = FALSE;
2160 BOOL selection_modified = FALSE; 2152 BOOL selection_modified = FALSE;
2161 BOOL return_key_hit = FALSE; 2153 BOOL return_key_hit = FALSE;
2162 BOOL text_may_have_changed = TRUE; 2154 BOOL text_may_have_changed = TRUE;
2163 2155
2164 if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible()) 2156 if ( gFocusMgr.getKeyboardFocus() == this )
2165 { 2157 {
2166 // Special case for TAB. If want to move to next field, report 2158 // Special case for TAB. If want to move to next field, report
2167 // not handled and let the parent take care of field movement. 2159 // not handled and let the parent take care of field movement.
@@ -2245,7 +2237,7 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
2245} 2237}
2246 2238
2247 2239
2248BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) 2240BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
2249{ 2241{
2250 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL 2242 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
2251 { 2243 {
@@ -2254,7 +2246,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare
2254 2246
2255 BOOL handled = FALSE; 2247 BOOL handled = FALSE;
2256 2248
2257 if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible()) 2249 if ( gFocusMgr.getKeyboardFocus() == this )
2258 { 2250 {
2259 // Handle most keys only if the text editor is writeable. 2251 // Handle most keys only if the text editor is writeable.
2260 if( !mReadOnly ) 2252 if( !mReadOnly )
@@ -2939,8 +2931,8 @@ void LLTextEditor::drawText()
2939 LLStyle style = cur_segment->getStyle(); 2931 LLStyle style = cur_segment->getStyle();
2940 if ( style.isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) 2932 if ( style.isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end))
2941 { 2933 {
2942 LLImageGL *image = style.getImage(); 2934 LLUIImagePtr image = style.getImage();
2943 gl_draw_scaled_image( llround(text_x), llround(text_y)+line_height-style.mImageHeight, style.mImageWidth, style.mImageHeight, image, LLColor4::white ); 2935 image->draw(llround(text_x), llround(text_y)+line_height-style.mImageHeight, style.mImageWidth, style.mImageHeight);
2944 } 2936 }
2945 2937
2946 if (cur_segment == mHoverSegment && style.getIsEmbeddedItem()) 2938 if (cur_segment == mHoverSegment && style.getIsEmbeddedItem())
@@ -2984,7 +2976,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32
2984 2976
2985 if ( style.getFontString()[0] ) 2977 if ( style.getFontString()[0] )
2986 { 2978 {
2987 font = gResMgr->getRes(style.getFontID()); 2979 font = LLResMgr::getInstance()->getRes(style.getFontID());
2988 } 2980 }
2989 2981
2990 U8 font_flags = LLFontGL::NORMAL; 2982 U8 font_flags = LLFontGL::NORMAL;
@@ -3051,10 +3043,6 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32
3051 3043
3052void LLTextEditor::draw() 3044void LLTextEditor::draw()
3053{ 3045{
3054 if( !getVisible() )
3055 {
3056 return;
3057 }
3058 { 3046 {
3059 LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0)); 3047 LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0));
3060 3048
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h
index 7943129..54a34cc 100644
--- a/linden/indra/llui/lltexteditor.h
+++ b/linden/indra/llui/lltexteditor.h
@@ -71,9 +71,6 @@ public:
71 71
72 virtual ~LLTextEditor(); 72 virtual ~LLTextEditor();
73 73
74 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEXT_EDITOR; }
75 virtual LLString getWidgetTag() const { return LL_TEXT_EDITOR_TAG; }
76
77 virtual LLXMLNodePtr getXML(bool save_children = true) const; 74 virtual LLXMLNodePtr getXML(bool save_children = true) const;
78 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); 75 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
79 void setTextEditorParameters(LLXMLNodePtr node); 76 void setTextEditorParameters(LLXMLNodePtr node);
@@ -85,8 +82,8 @@ public:
85 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 82 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
86 virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 83 virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
87 virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); 84 virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask );
88 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ); 85 virtual BOOL handleKeyHere(KEY key, MASK mask );
89 virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); 86 virtual BOOL handleUnicodeCharHere(llwchar uni_char);
90 87
91 virtual BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); 88 virtual BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect);
92 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, 89 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp
index ec8c94e..aafd3af 100644
--- a/linden/indra/llui/llui.cpp
+++ b/linden/indra/llui/llui.cpp
@@ -55,6 +55,7 @@
55//#include "llstartup.h" 55//#include "llstartup.h"
56#include "llui.h" 56#include "llui.h"
57#include "llview.h" 57#include "llview.h"
58#include "lllineeditor.h"
58#include "llwindow.h" 59#include "llwindow.h"
59 60
60#include "llglheaders.h" 61#include "llglheaders.h"
@@ -73,7 +74,6 @@ std::list<LLString> gUntranslated;
73 74
74LLControlGroup* LLUI::sConfigGroup = NULL; 75LLControlGroup* LLUI::sConfigGroup = NULL;
75LLControlGroup* LLUI::sColorsGroup = NULL; 76LLControlGroup* LLUI::sColorsGroup = NULL;
76LLControlGroup* LLUI::sAssetsGroup = NULL;
77LLImageProviderInterface* LLUI::sImageProvider = NULL; 77LLImageProviderInterface* LLUI::sImageProvider = NULL;
78LLUIAudioCallback LLUI::sAudioCallback = NULL; 78LLUIAudioCallback LLUI::sAudioCallback = NULL;
79LLVector2 LLUI::sGLScaleFactor(1.f, 1.f); 79LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
@@ -321,7 +321,7 @@ void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &st
321void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) 321void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
322{ 322{
323 // Work around bug in ATI driver: vertical lines are offset by (-1,-1) 323 // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
324 if( gGLManager.mATIOffsetVerticalLines && (x1 == x2) ) 324 if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
325 { 325 {
326 x1++; 326 x1++;
327 x2++; 327 x2++;
@@ -340,7 +340,7 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
340void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) 340void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
341{ 341{
342 // Work around bug in ATI driver: vertical lines are offset by (-1,-1) 342 // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
343 if( gGLManager.mATIOffsetVerticalLines && (x1 == x2) ) 343 if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
344 { 344 {
345 x1++; 345 x1++;
346 x2++; 346 x2++;
@@ -458,24 +458,30 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma
458 return; 458 return;
459 } 459 }
460 460
461 // scale screen size of borders down 461 // shrink scaling region to be proportional to clipped image region
462 LLRectf clipped_scale_rect = uv_rect; 462 LLRectf scale_rect_uv(
463 clipped_scale_rect.intersectWith(scale_rect); 463 uv_rect.mLeft + (scale_rect.mLeft * uv_rect.getWidth()),
464 uv_rect.mBottom + (scale_rect.mTop * uv_rect.getHeight()),
465 uv_rect.mLeft + (scale_rect.mRight * uv_rect.getWidth()),
466 uv_rect.mBottom + (scale_rect.mBottom * uv_rect.getHeight()));
467
468 S32 image_natural_width = llround((F32)image->getWidth(0) * uv_rect.getWidth());
469 S32 image_natural_height = llround((F32)image->getHeight(0) * uv_rect.getHeight());
464 470
465 LLRect draw_rect(0, height, width, 0); 471 LLRect draw_rect(0, height, width, 0);
466 LLRect draw_scale_rect(llround((F32)image->getWidth() * scale_rect.mLeft), 472 LLRect draw_scale_rect(llround(scale_rect_uv.mLeft * (F32)image->getWidth(0)),
467 llround((F32)image->getHeight() * scale_rect.mTop), 473 llround(scale_rect_uv.mTop * (F32)image->getHeight(0)),
468 llround((F32)image->getWidth() * scale_rect.mRight), 474 llround(scale_rect_uv.mRight * (F32)image->getWidth(0)),
469 llround((F32)image->getHeight() * scale_rect.mBottom)); 475 llround(scale_rect_uv.mBottom * (F32)image->getHeight(0)));
470 // scale fixed region of image up with drawn region 476 // scale fixed region of image to drawn region
471 draw_scale_rect.mRight += width - image->getWidth(); 477 draw_scale_rect.mRight += width - image_natural_width;
472 draw_scale_rect.mTop += height - image->getHeight(); 478 draw_scale_rect.mTop += height - image_natural_height;
473 479
474 S32 border_shrink_width = llmax(0, draw_scale_rect.mLeft - draw_scale_rect.mRight); 480 S32 border_shrink_width = llmax(0, draw_scale_rect.mLeft - draw_scale_rect.mRight);
475 S32 border_shrink_height = llmax(0, draw_scale_rect.mBottom - draw_scale_rect.mTop); 481 S32 border_shrink_height = llmax(0, draw_scale_rect.mBottom - draw_scale_rect.mTop);
476 482
477 F32 shrink_width_ratio = scale_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image->getWidth() * (1.f - scale_rect.getWidth())); 483 F32 shrink_width_ratio = scale_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - scale_rect.getWidth()));
478 F32 shrink_height_ratio = scale_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image->getHeight() * (1.f - scale_rect.getHeight())); 484 F32 shrink_height_ratio = scale_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - scale_rect.getHeight()));
479 485
480 F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); 486 F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
481 draw_scale_rect.mLeft = llround((F32)draw_scale_rect.mLeft * shrink_scale); 487 draw_scale_rect.mLeft = llround((F32)draw_scale_rect.mLeft * shrink_scale);
@@ -515,117 +521,117 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma
515 gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); 521 gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
516 gGL.vertex2i(0, 0); 522 gGL.vertex2i(0, 0);
517 523
518 gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); 524 gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom);
519 gGL.vertex2i(draw_scale_rect.mLeft, 0); 525 gGL.vertex2i(draw_scale_rect.mLeft, 0);
520 526
521 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); 527 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
522 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); 528 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
523 529
524 gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mBottom); 530 gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom);
525 gGL.vertex2i(0, draw_scale_rect.mBottom); 531 gGL.vertex2i(0, draw_scale_rect.mBottom);
526 532
527 // draw bottom middle 533 // draw bottom middle
528 gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); 534 gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom);
529 gGL.vertex2i(draw_scale_rect.mLeft, 0); 535 gGL.vertex2i(draw_scale_rect.mLeft, 0);
530 536
531 gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mBottom); 537 gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom);
532 gGL.vertex2i(draw_scale_rect.mRight, 0); 538 gGL.vertex2i(draw_scale_rect.mRight, 0);
533 539
534 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); 540 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
535 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); 541 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
536 542
537 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); 543 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
538 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); 544 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
539 545
540 // draw bottom right 546 // draw bottom right
541 gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mBottom); 547 gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom);
542 gGL.vertex2i(draw_scale_rect.mRight, 0); 548 gGL.vertex2i(draw_scale_rect.mRight, 0);
543 549
544 gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); 550 gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
545 gGL.vertex2i(width, 0); 551 gGL.vertex2i(width, 0);
546 552
547 gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mBottom); 553 gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom);
548 gGL.vertex2i(width, draw_scale_rect.mBottom); 554 gGL.vertex2i(width, draw_scale_rect.mBottom);
549 555
550 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); 556 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
551 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); 557 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
552 558
553 // draw left 559 // draw left
554 gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mBottom); 560 gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom);
555 gGL.vertex2i(0, draw_scale_rect.mBottom); 561 gGL.vertex2i(0, draw_scale_rect.mBottom);
556 562
557 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); 563 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
558 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); 564 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
559 565
560 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); 566 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
561 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); 567 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
562 568
563 gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mTop); 569 gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop);
564 gGL.vertex2i(0, draw_scale_rect.mTop); 570 gGL.vertex2i(0, draw_scale_rect.mTop);
565 571
566 // draw middle 572 // draw middle
567 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); 573 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom);
568 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); 574 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom);
569 575
570 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); 576 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
571 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); 577 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
572 578
573 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); 579 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
574 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); 580 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
575 581
576 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); 582 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
577 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); 583 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
578 584
579 // draw right 585 // draw right
580 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); 586 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom);
581 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); 587 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom);
582 588
583 gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mBottom); 589 gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom);
584 gGL.vertex2i(width, draw_scale_rect.mBottom); 590 gGL.vertex2i(width, draw_scale_rect.mBottom);
585 591
586 gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mTop); 592 gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop);
587 gGL.vertex2i(width, draw_scale_rect.mTop); 593 gGL.vertex2i(width, draw_scale_rect.mTop);
588 594
589 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); 595 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
590 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); 596 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
591 597
592 // draw top left 598 // draw top left
593 gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mTop); 599 gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop);
594 gGL.vertex2i(0, draw_scale_rect.mTop); 600 gGL.vertex2i(0, draw_scale_rect.mTop);
595 601
596 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); 602 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
597 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); 603 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
598 604
599 gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); 605 gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop);
600 gGL.vertex2i(draw_scale_rect.mLeft, height); 606 gGL.vertex2i(draw_scale_rect.mLeft, height);
601 607
602 gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); 608 gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
603 gGL.vertex2i(0, height); 609 gGL.vertex2i(0, height);
604 610
605 // draw top middle 611 // draw top middle
606 gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); 612 gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop);
607 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); 613 gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop);
608 614
609 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); 615 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
610 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); 616 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
611 617
612 gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mTop); 618 gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop);
613 gGL.vertex2i(draw_scale_rect.mRight, height); 619 gGL.vertex2i(draw_scale_rect.mRight, height);
614 620
615 gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); 621 gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop);
616 gGL.vertex2i(draw_scale_rect.mLeft, height); 622 gGL.vertex2i(draw_scale_rect.mLeft, height);
617 623
618 // draw top right 624 // draw top right
619 gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); 625 gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop);
620 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); 626 gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop);
621 627
622 gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mTop); 628 gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop);
623 gGL.vertex2i(width, draw_scale_rect.mTop); 629 gGL.vertex2i(width, draw_scale_rect.mTop);
624 630
625 gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); 631 gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
626 gGL.vertex2i(width, height); 632 gGL.vertex2i(width, height);
627 633
628 gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mTop); 634 gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop);
629 gGL.vertex2i(draw_scale_rect.mRight, height); 635 gGL.vertex2i(draw_scale_rect.mRight, height);
630 } 636 }
631 gGL.end(); 637 gGL.end();
@@ -1556,20 +1562,14 @@ void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3
1556 gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP); 1562 gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
1557} 1563}
1558 1564
1559class LLShowXUINamesListener: public LLSimpleListener 1565bool handleShowXUINamesChanged(const LLSD& newvalue)
1560{ 1566{
1561 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 1567 LLUI::sShowXUINames = newvalue.asBoolean();
1562 { 1568 return true;
1563 LLUI::sShowXUINames = (BOOL) event->getValue().asBoolean(); 1569}
1564 return true;
1565 }
1566};
1567static LLShowXUINamesListener show_xui_names_listener;
1568
1569 1570
1570void LLUI::initClass(LLControlGroup* config, 1571void LLUI::initClass(LLControlGroup* config,
1571 LLControlGroup* colors, 1572 LLControlGroup* colors,
1572 LLControlGroup* assets,
1573 LLImageProviderInterface* image_provider, 1573 LLImageProviderInterface* image_provider,
1574 LLUIAudioCallback audio_callback, 1574 LLUIAudioCallback audio_callback,
1575 const LLVector2* scale_factor, 1575 const LLVector2* scale_factor,
@@ -1577,7 +1577,6 @@ void LLUI::initClass(LLControlGroup* config,
1577{ 1577{
1578 sConfigGroup = config; 1578 sConfigGroup = config;
1579 sColorsGroup = colors; 1579 sColorsGroup = colors;
1580 sAssetsGroup = assets;
1581 sImageProvider = image_provider; 1580 sImageProvider = image_provider;
1582 sAudioCallback = audio_callback; 1581 sAudioCallback = audio_callback;
1583 sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; 1582 sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
@@ -1585,11 +1584,13 @@ void LLUI::initClass(LLControlGroup* config,
1585 LLFontGL::sShadowColor = colors->getColor("ColorDropShadow"); 1584 LLFontGL::sShadowColor = colors->getColor("ColorDropShadow");
1586 1585
1587 LLUI::sShowXUINames = LLUI::sConfigGroup->getBOOL("ShowXUINames"); 1586 LLUI::sShowXUINames = LLUI::sConfigGroup->getBOOL("ShowXUINames");
1588 LLUI::sConfigGroup->getControl("ShowXUINames")->addListener(&show_xui_names_listener); 1587 LLUI::sConfigGroup->getControl("ShowXUINames")->getSignal()->connect(boost::bind(&handleShowXUINamesChanged, _1));
1589} 1588}
1590 1589
1591void LLUI::cleanupClass() 1590void LLUI::cleanupClass()
1592{ 1591{
1592 sImageProvider->cleanUp();
1593 LLLineEditor::cleanupClass();
1593} 1594}
1594 1595
1595 1596
@@ -1732,28 +1733,15 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
1732 glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom); 1733 glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
1733} 1734}
1734 1735
1735//static
1736LLUUID LLUI::findAssetUUIDByName(const LLString &asset_name)
1737{
1738 if(asset_name == LLString::null) return LLUUID::null;
1739 LLString foundValue = LLUI::sConfigGroup->findString(asset_name);
1740 if(foundValue==LLString::null)
1741 {
1742 foundValue = LLUI::sAssetsGroup->findString(asset_name);
1743 }
1744 if(foundValue == LLString::null){
1745 return LLUUID::null;
1746 }
1747 return LLUUID( foundValue );
1748}
1749
1750//static 1736//static
1751LLUIImage* LLUI::getUIImageByName(const LLString& name) 1737LLUIImage* LLUI::getUIImage(const LLString& name)
1752{ 1738{
1753 return sImageProvider->getUIImageByID(findAssetUUIDByName(name)); 1739 if (!name.empty())
1740 return sImageProvider->getUIImage(name);
1741 else
1742 return NULL;
1754} 1743}
1755 1744
1756
1757// static 1745// static
1758void LLUI::setHtmlHelp(LLHtmlHelp* html_help) 1746void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
1759{ 1747{
@@ -1834,7 +1822,8 @@ LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled)
1834// LLUIImage 1822// LLUIImage
1835// 1823//
1836 1824
1837LLUIImage::LLUIImage(LLPointer<LLImageGL> image) : 1825LLUIImage::LLUIImage(const LLString& name, LLPointer<LLImageGL> image) :
1826 mName(name),
1838 mImage(image), 1827 mImage(image),
1839 mScaleRegion(0.f, 1.f, 1.f, 0.f), 1828 mScaleRegion(0.f, 1.f, 1.f, 0.f),
1840 mClipRegion(0.f, 1.f, 1.f, 0.f), 1829 mClipRegion(0.f, 1.f, 1.f, 0.f),
@@ -1898,24 +1887,32 @@ void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& c
1898 mScaleRegion); 1887 mScaleRegion);
1899} 1888}
1900 1889
1901void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) const 1890void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
1902{ 1891{
1903 gl_draw_scaled_image_with_border( 1892 LLRect border_rect;
1904 x, y, 1893 border_rect.setOriginAndSize(x, y, width, height);
1905 getWidth(), getHeight(), 1894 border_rect.stretch(border_width, border_width);
1906 mImage, 1895 drawSolid(border_rect, color);
1907 color,
1908 TRUE,
1909 mClipRegion,
1910 mScaleRegion);
1911} 1896}
1912 1897
1913S32 LLUIImage::getWidth() const 1898S32 LLUIImage::getWidth() const
1914{ 1899{
1915 return mImage->getWidth(0); 1900 // return clipped dimensions of actual image area
1901 return llround((F32)mImage->getWidth(0) * mClipRegion.getWidth());
1916} 1902}
1917 1903
1918S32 LLUIImage::getHeight() const 1904S32 LLUIImage::getHeight() const
1919{ 1905{
1920 return mImage->getHeight(0); 1906 // return clipped dimensions of actual image area
1907 return llround((F32)mImage->getHeight(0) * mClipRegion.getHeight());
1908}
1909
1910S32 LLUIImage::getTextureWidth() const
1911{
1912 return mImage->getWidth(0);
1913}
1914
1915S32 LLUIImage::getTextureHeight() const
1916{
1917 return mImage->getHeight(0);
1921} 1918}
diff --git a/linden/indra/llui/llui.h b/linden/indra/llui/llui.h
index 9e275a5..0b06913 100644
--- a/linden/indra/llui/llui.h
+++ b/linden/indra/llui/llui.h
@@ -161,7 +161,6 @@ public:
161 // 161 //
162 static void initClass(LLControlGroup* config, 162 static void initClass(LLControlGroup* config,
163 LLControlGroup* colors, 163 LLControlGroup* colors,
164 LLControlGroup* assets,
165 LLImageProviderInterface* image_provider, 164 LLImageProviderInterface* image_provider,
166 LLUIAudioCallback audio_callback = NULL, 165 LLUIAudioCallback audio_callback = NULL,
167 const LLVector2 *scale_factor = NULL, 166 const LLVector2 *scale_factor = NULL,
@@ -179,8 +178,7 @@ public:
179 static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y); 178 static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y);
180 static void setScaleFactor(const LLVector2& scale_factor); 179 static void setScaleFactor(const LLVector2& scale_factor);
181 static void setLineWidth(F32 width); 180 static void setLineWidth(F32 width);
182 static LLUUID findAssetUUIDByName(const LLString& name); 181 static LLUIImage* getUIImage(const LLString& name);
183 static LLUIImage* getUIImageByName(const LLString& name);
184 static LLVector2 getWindowSize(); 182 static LLVector2 getWindowSize();
185 static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y); 183 static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
186 static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y); 184 static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
@@ -193,7 +191,6 @@ public:
193 // 191 //
194 static LLControlGroup* sConfigGroup; 192 static LLControlGroup* sConfigGroup;
195 static LLControlGroup* sColorsGroup; 193 static LLControlGroup* sColorsGroup;
196 static LLControlGroup* sAssetsGroup;
197 static LLImageProviderInterface* sImageProvider; 194 static LLImageProviderInterface* sImageProvider;
198 static LLUIAudioCallback sAudioCallback; 195 static LLUIAudioCallback sAudioCallback;
199 static LLVector2 sGLScaleFactor; 196 static LLVector2 sGLScaleFactor;
@@ -209,101 +206,6 @@ public:
209 206
210}; 207};
211 208
212// UI widgets
213// This MUST match UICtrlNames in lluictrlfactory.cpp
214typedef enum e_widget_type
215{
216 WIDGET_TYPE_VIEW = 0,
217 WIDGET_TYPE_ROOT_VIEW,
218 WIDGET_TYPE_FLOATER_VIEW,
219 WIDGET_TYPE_BUTTON,
220 WIDGET_TYPE_JOYSTICK_TURN,
221 WIDGET_TYPE_JOYSTICK_SLIDE,
222 WIDGET_TYPE_CHECKBOX,
223 WIDGET_TYPE_COLOR_SWATCH,
224 WIDGET_TYPE_COMBO_BOX,
225 WIDGET_TYPE_LINE_EDITOR,
226 WIDGET_TYPE_SEARCH_EDITOR,
227 WIDGET_TYPE_SCROLL_LIST,
228 WIDGET_TYPE_NAME_LIST,
229 WIDGET_TYPE_WEBBROWSER,
230 WIDGET_TYPE_SLIDER, // actually LLSliderCtrl
231 WIDGET_TYPE_SLIDER_BAR, // actually LLSlider
232 WIDGET_TYPE_VOLUME_SLIDER,//actually LLVolumeSliderCtrl
233 WIDGET_TYPE_MULTI_SLIDER, // actually LLMultiSliderCtrl
234 WIDGET_TYPE_MULTI_SLIDER_BAR, // actually LLMultiSlider
235 WIDGET_TYPE_SPINNER,
236 WIDGET_TYPE_TEXT_EDITOR,
237 WIDGET_TYPE_TEXTURE_PICKER,
238 WIDGET_TYPE_TEXT_BOX,
239 WIDGET_TYPE_PAD, // used in XML for positioning, not a real widget
240 WIDGET_TYPE_RADIO_GROUP,
241 WIDGET_TYPE_ICON,
242 WIDGET_TYPE_LANDMARK_PICKER,
243 WIDGET_TYPE_LOCATE, // used in XML for positioning, not a real widget
244 WIDGET_TYPE_VIEW_BORDER, // decorative border
245 WIDGET_TYPE_PANEL,
246 WIDGET_TYPE_MENU,
247 WIDGET_TYPE_PIE_MENU,
248 WIDGET_TYPE_PIE_MENU_BRANCH,
249 WIDGET_TYPE_MENU_ITEM,
250 WIDGET_TYPE_MENU_ITEM_SEPARATOR,
251 WIDGET_TYPE_MENU_SEPARATOR_VERTICAL,
252 WIDGET_TYPE_MENU_ITEM_CALL,
253 WIDGET_TYPE_MENU_ITEM_CHECK,
254 WIDGET_TYPE_MENU_ITEM_BRANCH,
255 WIDGET_TYPE_MENU_ITEM_BRANCH_DOWN,
256 WIDGET_TYPE_MENU_ITEM_BLANK,
257 WIDGET_TYPE_TEAROFF_MENU,
258 WIDGET_TYPE_MENU_BAR,
259 WIDGET_TYPE_TAB_CONTAINER,
260 WIDGET_TYPE_SCROLL_CONTAINER, // LLScrollableContainerView
261 WIDGET_TYPE_SCROLLBAR,
262 WIDGET_TYPE_INVENTORY_PANEL, // LLInventoryPanel
263 WIDGET_TYPE_FLOATER,
264 WIDGET_TYPE_DRAG_HANDLE_TOP,
265 WIDGET_TYPE_DRAG_HANDLE_LEFT,
266 WIDGET_TYPE_RESIZE_HANDLE,
267 WIDGET_TYPE_RESIZE_BAR,
268 WIDGET_TYPE_NAME_EDITOR,
269 WIDGET_TYPE_MULTI_FLOATER,
270 WIDGET_TYPE_MEDIA_REMOTE,
271 WIDGET_TYPE_FOLDER_VIEW,
272 WIDGET_TYPE_FOLDER_ITEM,
273 WIDGET_TYPE_FOLDER,
274 WIDGET_TYPE_STAT_GRAPH,
275 WIDGET_TYPE_STAT_VIEW,
276 WIDGET_TYPE_STAT_BAR,
277 WIDGET_TYPE_DROP_TARGET,
278 WIDGET_TYPE_TEXTURE_BAR,
279 WIDGET_TYPE_TEX_MEM_BAR,
280 WIDGET_TYPE_SNAPSHOT_LIVE_PREVIEW,
281 WIDGET_TYPE_STATUS_BAR,
282 WIDGET_TYPE_PROGRESS_VIEW,
283 WIDGET_TYPE_TALK_VIEW,
284 WIDGET_TYPE_OVERLAY_BAR,
285 WIDGET_TYPE_HUD_VIEW,
286 WIDGET_TYPE_HOVER_VIEW,
287 WIDGET_TYPE_MORPH_VIEW,
288 WIDGET_TYPE_NET_MAP,
289 WIDGET_TYPE_PERMISSIONS_VIEW,
290 WIDGET_TYPE_MENU_HOLDER,
291 WIDGET_TYPE_DEBUG_VIEW,
292 WIDGET_TYPE_SCROLLING_PANEL_LIST,
293 WIDGET_TYPE_AUDIO_STATUS,
294 WIDGET_TYPE_CONTAINER_VIEW,
295 WIDGET_TYPE_CONSOLE,
296 WIDGET_TYPE_FAST_TIMER_VIEW,
297 WIDGET_TYPE_VELOCITY_BAR,
298 WIDGET_TYPE_TEXTURE_VIEW,
299 WIDGET_TYPE_MEMORY_VIEW,
300 WIDGET_TYPE_FRAME_STAT_VIEW,
301 WIDGET_TYPE_LAYOUT_STACK,
302 WIDGET_TYPE_FLYOUT_BUTTON,
303 WIDGET_TYPE_DONTCARE,
304 WIDGET_TYPE_COUNT
305} EWidgetType;
306
307// FactoryPolicy is a static class that controls the creation and lookup of UI elements, 209// FactoryPolicy is a static class that controls the creation and lookup of UI elements,
308// such as floaters. 210// such as floaters.
309// The key parameter is used to provide a unique identifier and/or associated construction 211// The key parameter is used to provide a unique identifier and/or associated construction
@@ -509,7 +411,7 @@ public:
509class LLUIImage : public LLRefCount 411class LLUIImage : public LLRefCount
510{ 412{
511public: 413public:
512 LLUIImage(LLPointer<LLImageGL> image); 414 LLUIImage(const LLString& name, LLPointer<LLImageGL> image);
513 415
514 void setClipRegion(const LLRectf& region); 416 void setClipRegion(const LLRectf& region);
515 void setScaleRegion(const LLRectf& region); 417 void setScaleRegion(const LLRectf& region);
@@ -517,15 +419,29 @@ public:
517 LLPointer<LLImageGL> getImage() { return mImage; } 419 LLPointer<LLImageGL> getImage() { return mImage; }
518 const LLPointer<LLImageGL>& getImage() const { return mImage; } 420 const LLPointer<LLImageGL>& getImage() const { return mImage; }
519 421
520 void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
521 void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const; 422 void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
423 void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
424 void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
425
522 void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const; 426 void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
523 void drawSolid(S32 x, S32 y, const LLColor4& color) const; 427 void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
428 void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, mImage->getWidth(0), mImage->getHeight(0), color); }
429
430 void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
431 void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
432 void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, mImage->getWidth(0), mImage->getHeight(0), color, border_width); }
433
434 const LLString& getName() const { return mName; }
524 435
525 S32 getWidth() const; 436 S32 getWidth() const;
526 S32 getHeight() const; 437 S32 getHeight() const;
527 438
439 // returns dimensions of underlying textures, which might not be equal to ui image portion
440 S32 getTextureWidth() const;
441 S32 getTextureHeight() const;
442
528protected: 443protected:
444 LLString mName;
529 LLRectf mScaleRegion; 445 LLRectf mScaleRegion;
530 LLRectf mClipRegion; 446 LLRectf mClipRegion;
531 LLPointer<LLImageGL> mImage; 447 LLPointer<LLImageGL> mImage;
@@ -533,6 +449,7 @@ protected:
533 BOOL mNoClip; 449 BOOL mNoClip;
534}; 450};
535 451
452typedef LLPointer<LLUIImage> LLUIImagePtr;
536 453
537template <typename T> 454template <typename T>
538class LLTombStone : public LLRefCount 455class LLTombStone : public LLRefCount
@@ -667,6 +584,7 @@ private:
667 LLRootHandle<T> mHandle; 584 LLRootHandle<T> mHandle;
668}; 585};
669 586
587
670//RN: maybe this needs to moved elsewhere? 588//RN: maybe this needs to moved elsewhere?
671class LLImageProviderInterface 589class LLImageProviderInterface
672{ 590{
@@ -674,8 +592,9 @@ public:
674 LLImageProviderInterface() {}; 592 LLImageProviderInterface() {};
675 virtual ~LLImageProviderInterface() {}; 593 virtual ~LLImageProviderInterface() {};
676 594
677 virtual LLUIImage* getUIImageByID(const LLUUID& id, BOOL clamped = TRUE) = 0; 595 virtual LLUIImagePtr getUIImage(const LLString& name) = 0;
678 virtual LLImageGL* getImageByID(const LLUUID& id, BOOL clamped = TRUE) = 0; 596 virtual LLUIImagePtr getUIImageByID(const LLUUID& id) = 0;
597 virtual void cleanUp() = 0;
679}; 598};
680 599
681#endif 600#endif
diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp
index 0e6c155..66504b7 100644
--- a/linden/indra/llui/lluictrl.cpp
+++ b/linden/indra/llui/lluictrl.cpp
@@ -34,7 +34,9 @@
34#include "linden_common.h" 34#include "linden_common.h"
35#include "lluictrl.h" 35#include "lluictrl.h"
36#include "llfocusmgr.h" 36#include "llfocusmgr.h"
37#include "llpanel.h"
37 38
39static LLRegisterWidget<LLUICtrl> r("ui_ctrl");
38 40
39LLFocusableElement::LLFocusableElement() 41LLFocusableElement::LLFocusableElement()
40: mFocusLostCallback(NULL), 42: mFocusLostCallback(NULL),
@@ -473,7 +475,7 @@ BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only)
473 return focusPrev(result); 475 return focusPrev(result);
474} 476}
475 477
476const LLUICtrl* LLUICtrl::findRootMostFocusRoot() const 478LLUICtrl* LLUICtrl::findRootMostFocusRoot() const
477{ 479{
478 const LLUICtrl* focus_root = NULL; 480 const LLUICtrl* focus_root = NULL;
479 const LLUICtrl* next_view = this; 481 const LLUICtrl* next_view = this;
@@ -485,7 +487,9 @@ const LLUICtrl* LLUICtrl::findRootMostFocusRoot() const
485 } 487 }
486 next_view = next_view->getParentUICtrl(); 488 next_view = next_view->getParentUICtrl();
487 } 489 }
488 return focus_root; 490 // since focus_root could be this, need to cast away const to return
491 // a non-const result
492 return const_cast<LLUICtrl*>(focus_root);
489} 493}
490 494
491 495
@@ -538,14 +542,22 @@ LLXMLNodePtr LLUICtrl::getXML(bool save_children) const
538 return node; 542 return node;
539} 543}
540 544
545//static
546LLView* LLUICtrl::fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory)
547{
548 LLUICtrl* ctrl = new LLUICtrl();
549 ctrl->initFromXML(node, parent);
550 return ctrl;
551}
552
553
541// *NOTE: If other classes derive from LLPanel, they will need to be 554// *NOTE: If other classes derive from LLPanel, they will need to be
542// added to this function. 555// added to this function.
543LLPanel* LLUICtrl::getParentPanel() const 556LLPanel* LLUICtrl::getParentPanel() const
544{ 557{
545 LLView* parent = getParent(); 558 LLView* parent = getParent();
546 while (parent 559 LLPanel* parent_panel = dynamic_cast<LLPanel*>(parent);
547 && parent->getWidgetType() != WIDGET_TYPE_PANEL 560 while (!parent_panel)
548 && parent->getWidgetType() != WIDGET_TYPE_FLOATER)
549 { 561 {
550 parent = parent->getParent(); 562 parent = parent->getParent();
551 } 563 }
diff --git a/linden/indra/llui/lluictrl.h b/linden/indra/llui/lluictrl.h
index 0c43297..7bc5eeb 100644
--- a/linden/indra/llui/lluictrl.h
+++ b/linden/indra/llui/lluictrl.h
@@ -141,7 +141,9 @@ public:
141 void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; } 141 void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; }
142 void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; } 142 void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; }
143 143
144 const LLUICtrl* findRootMostFocusRoot() const; 144 static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory);
145
146 LLUICtrl* findRootMostFocusRoot() const;
145 147
146 class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> 148 class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter>
147 { 149 {
diff --git a/linden/indra/llui/lluictrlfactory.cpp b/linden/indra/llui/lluictrlfactory.cpp
index cfee76a..cc8135c 100644
--- a/linden/indra/llui/lluictrlfactory.cpp
+++ b/linden/indra/llui/lluictrlfactory.cpp
@@ -71,100 +71,6 @@
71 71
72const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n"; 72const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n";
73 73
74// *NOTE: If you add a new class derived from LLPanel, add a check for its
75// widget type to LLUICtrl::getParentPanel().
76// *NOTE: This MUST match EWidgetType in llui.h
77//static
78const LLString LLUICtrlFactory::sUICtrlNames[WIDGET_TYPE_COUNT] =
79{
80 LLString("view"), //WIDGET_TYPE_VIEW
81 LLString("root_view"), //WIDGET_TYPE_ROOT_VIEW
82 LLString("floater_view"), //WIDGET_TYPE_FLOATER_VIEW
83 LLString("button"), //WIDGET_TYPE_BUTTON
84 LLString("joystick_turn"), //WIDGET_TYPE_JOYSTICK_TURN
85 LLString("joystick_slide"), //WIDGET_TYPE_JOYSTICK_SLIDE
86 LLString("check_box"), //WIDGET_TYPE_CHECKBOX
87 LLString("color_swatch"), //WIDGET_TYPE_COLOR_SWATCH
88 LLString("combo_box"), //WIDGET_TYPE_COMBO_BOX
89 LLString("line_editor"), //WIDGET_TYPE_LINE_EDITOR
90 LLString("search_editor"), //WIDGET_TYPE_SEARCH_EDITOR
91 LLString("scroll_list"), //WIDGET_TYPE_SCROLL_LIST
92 LLString("name_list"), //WIDGET_TYPE_NAME_LIST
93 LLString("web_browser"), //WIDGET_TYPE_WEBBROWSER
94 LLString("slider"), //WIDGET_TYPE_SLIDER, actually LLSliderCtrl
95 LLString("slider_bar"), //WIDGET_TYPE_SLIDER_BAR, actually LLSlider
96 LLString("volume_slider"), //WIDGET_TYPE_VOLUME_SLIDER, actually LLSlider + "volume" param
97 LLString("multi_slider"), //WIDGET_TYPE_MULTI_SLIDER, actually LLMultiSliderCtrl
98 LLString("multi_slider_bar"), //WIDGET_TYPE_MULTI_SLIDER_BAR, actually LLMultiSlider
99 LLString("spinner"), //WIDGET_TYPE_SPINNER, actually LLSpinCtrl
100 LLString("text_editor"), //WIDGET_TYPE_TEXT_EDITOR
101 LLString("texture_picker"),//WIDGET_TYPE_TEXTURE_PICKER
102 LLString("text"), //WIDGET_TYPE_TEXT_BOX
103 LLString("pad"), //WIDGET_TYPE_PAD
104 LLString("radio_group"), //WIDGET_TYPE_RADIO_GROUP
105 LLString("icon"), //WIDGET_TYPE_ICON
106 LLString("locate"), //WIDGET_TYPE_LOCATE
107 LLString("view_border"), //WIDGET_TYPE_VIEW_BORDER
108 LLString("panel"), //WIDGET_TYPE_PANEL
109 LLString("menu"), //WIDGET_TYPE_MENU
110 LLString("pie_menu"), //WIDGET_TYPE_PIE_MENU
111 LLString("pie_menu_branch"), //WIDGET_TYPE_PIE_MENU_BRANCH
112 LLString("menu_item"), //WIDGET_TYPE_MENU_ITEM
113 LLString("menu_item_separator"), //WIDGET_TYPE_MENU_ITEM_SEPARATOR
114 LLString("menu_separator_vertical"), // WIDGET_TYPE_MENU_SEPARATOR_VERTICAL
115 LLString("menu_item_call"), // WIDGET_TYPE_MENU_ITEM_CALL
116 LLString("menu_item_check"),// WIDGET_TYPE_MENU_ITEM_CHECK
117 LLString("menu_item_branch"), // WIDGET_TYPE_MENU_ITEM_BRANCH
118 LLString("menu_item_branch_down"), //WIDGET_TYPE_MENU_ITEM_BRANCH_DOWN,
119 LLString("menu_item_blank"), //WIDGET_TYPE_MENU_ITEM_BLANK,
120 LLString("tearoff_menu"), //WIDGET_TYPE_TEAROFF_MENU
121 LLString("menu_bar"), //WIDGET_TYPE_MENU_BAR
122 LLString("tab_container"),//WIDGET_TYPE_TAB_CONTAINER
123 LLString("scroll_container"),//WIDGET_TYPE_SCROLL_CONTAINER
124 LLString("scrollbar"), //WIDGET_TYPE_SCROLLBAR
125 LLString("inventory_panel"), //WIDGET_TYPE_INVENTORY_PANEL
126 LLString("floater"), //WIDGET_TYPE_FLOATER
127 LLString("drag_handle_top"), //WIDGET_TYPE_DRAG_HANDLE_TOP
128 LLString("drag_handle_left"), //WIDGET_TYPE_DRAG_HANDLE_LEFT
129 LLString("resize_handle"), //WIDGET_TYPE_RESIZE_HANDLE
130 LLString("resize_bar"), //WIDGET_TYPE_RESIZE_BAR
131 LLString("name_editor"), //WIDGET_TYPE_NAME_EDITOR
132 LLString("multi_floater"), //WIDGET_TYPE_MULTI_FLOATER
133 LLString("media_remote"), //WIDGET_TYPE_MEDIA_REMOTE
134 LLString("folder_view"), //WIDGET_TYPE_FOLDER_VIEW
135 LLString("folder_item"), //WIDGET_TYPE_FOLDER_ITEM
136 LLString("folder"), //WIDGET_TYPE_FOLDER
137 LLString("stat_graph"), //WIDGET_TYPE_STAT_GRAPH
138 LLString("stat_view"), //WIDGET_TYPE_STAT_VIEW
139 LLString("stat_bar"), //WIDGET_TYPE_STAT_BAR
140 LLString("drop_target"), //WIDGET_TYPE_DROP_TARGET
141 LLString("texture_bar"), //WIDGET_TYPE_TEXTURE_BAR
142 LLString("tex_mem_bar"), //WIDGET_TYPE_TEX_MEM_BAR
143 LLString("snapshot_live_preview"), //WIDGET_TYPE_SNAPSHOT_LIVE_PREVIEW
144 LLString("status_bar"), //WIDGET_TYPE_STATUS_BAR
145 LLString("progress_view"), //WIDGET_TYPE_PROGRESS_VIEW
146 LLString("talk_view"), //WIDGET_TYPE_TALK_VIEW
147 LLString("overlay_bar"), //WIDGET_TYPE_OVERLAY_BAR
148 LLString("hud_view"), //WIDGET_TYPE_HUD_VIEW
149 LLString("hover_view"), //WIDGET_TYPE_HOVER_VIEW
150 LLString("morph_view"), //WIDGET_TYPE_MORPH_VIEW
151 LLString("net_map"), //WIDGET_TYPE_NET_MAP
152 LLString("permissions_view"), //WIDGET_TYPE_PERMISSIONS_VIEW
153 LLString("menu_holder"), //WIDGET_TYPE_MENU_HOLDER
154 LLString("debug_view"), //WIDGET_TYPE_DEBUG_VIEW
155 LLString("scrolling_panel_list"), //WIDGET_TYPE_SCROLLING_PANEL_LIST
156 LLString("audio_status"), //WIDGET_TYPE_AUDIO_STATUS
157 LLString("container_view"), //WIDGET_TYPE_CONTAINER_VIEW
158 LLString("console"), //WIDGET_TYPE_CONSOLE
159 LLString("fast_timer_view"), //WIDGET_TYPE_FAST_TIMER_VIEW
160 LLString("velocity_bar"), //WIDGET_TYPE_VELOCITY_BAR
161 LLString("texture_view"), //WIDGET_TYPE_TEXTURE_VIEW
162 LLString("memory_view"), //WIDGET_TYPE_MEMORY_VIEW
163 LLString("frame_stat_view"), //WIDGET_TYPE_FRAME_STAT_VIEW
164 LLString("layout_stack"), //WIDGET_TYPE_LAYOUT_STACK
165 LLString("DONT_CARE"), //WIDGET_TYPE_DONTCARE
166};
167
168const S32 HPAD = 4; 74const S32 HPAD = 4;
169const S32 VPAD = 4; 75const S32 VPAD = 4;
170const S32 FLOATER_H_MARGIN = 15; 76const S32 FLOATER_H_MARGIN = 15;
@@ -179,9 +85,6 @@ public:
179 LLUICtrlLocate() : LLUICtrl("locate", LLRect(0,0,0,0), FALSE, NULL, NULL) { setTabStop(FALSE); } 85 LLUICtrlLocate() : LLUICtrl("locate", LLRect(0,0,0,0), FALSE, NULL, NULL) { setTabStop(FALSE); }
180 virtual void draw() { } 86 virtual void draw() { }
181 87
182 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LOCATE; }
183 virtual LLString getWidgetTag() const { return LL_UI_CTRL_LOCATE_TAG; }
184
185 static LLView *fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) 88 static LLView *fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
186 { 89 {
187 LLString name("pad"); 90 LLString name("pad");
@@ -194,39 +97,14 @@ public:
194 } 97 }
195}; 98};
196 99
100static LLRegisterWidget<LLUICtrlLocate> r1("locate");
101static LLRegisterWidget<LLUICtrlLocate> r2("pad");
102
197//----------------------------------------------------------------------------- 103//-----------------------------------------------------------------------------
198// LLUICtrlFactory() 104// LLUICtrlFactory()
199//----------------------------------------------------------------------------- 105//-----------------------------------------------------------------------------
200LLUICtrlFactory::LLUICtrlFactory() 106LLUICtrlFactory::LLUICtrlFactory()
201{ 107{
202 // Register controls
203 LLUICtrlCreator<LLButton>::registerCreator(LL_BUTTON_TAG, this);
204 LLUICtrlCreator<LLCheckBoxCtrl>::registerCreator(LL_CHECK_BOX_CTRL_TAG, this);
205 LLUICtrlCreator<LLComboBox>::registerCreator(LL_COMBO_BOX_TAG, this);
206 LLUICtrlCreator<LLFlyoutButton>::registerCreator(LL_FLYOUT_BUTTON_TAG, this);
207 LLUICtrlCreator<LLLineEditor>::registerCreator(LL_LINE_EDITOR_TAG, this);
208 LLUICtrlCreator<LLSearchEditor>::registerCreator(LL_SEARCH_EDITOR_TAG, this);
209 LLUICtrlCreator<LLScrollListCtrl>::registerCreator(LL_SCROLL_LIST_CTRL_TAG, this);
210 LLUICtrlCreator<LLSliderCtrl>::registerCreator(LL_SLIDER_CTRL_TAG, this);
211 LLUICtrlCreator<LLSlider>::registerCreator(LL_SLIDER_TAG, this);
212 LLUICtrlCreator<LLSlider>::registerCreator(LL_VOLUME_SLIDER_CTRL_TAG, this);
213 LLUICtrlCreator<LLMultiSliderCtrl>::registerCreator(LL_MULTI_SLIDER_CTRL_TAG, this);
214 LLUICtrlCreator<LLMultiSlider>::registerCreator(LL_MULTI_SLIDER_TAG, this);
215 LLUICtrlCreator<LLSpinCtrl>::registerCreator(LL_SPIN_CTRL_TAG, this);
216 LLUICtrlCreator<LLTextBox>::registerCreator(LL_TEXT_BOX_TAG, this);
217 LLUICtrlCreator<LLRadioGroup>::registerCreator(LL_RADIO_GROUP_TAG, this);
218 LLUICtrlCreator<LLIconCtrl>::registerCreator(LL_ICON_CTRL_TAG, this);
219 LLUICtrlCreator<LLUICtrlLocate>::registerCreator(LL_UI_CTRL_LOCATE_TAG, this);
220 LLUICtrlCreator<LLUICtrlLocate>::registerCreator(LL_PAD_TAG, this);
221 LLUICtrlCreator<LLViewBorder>::registerCreator(LL_VIEW_BORDER_TAG, this);
222 LLUICtrlCreator<LLTabContainer>::registerCreator(LL_TAB_CONTAINER_COMMON_TAG, this);
223 LLUICtrlCreator<LLScrollableContainerView>::registerCreator(LL_SCROLLABLE_CONTAINER_VIEW_TAG, this);
224 LLUICtrlCreator<LLPanel>::registerCreator(LL_PANEL_TAG, this);
225 LLUICtrlCreator<LLMenuGL>::registerCreator(LL_MENU_GL_TAG, this);
226 LLUICtrlCreator<LLMenuBarGL>::registerCreator(LL_MENU_BAR_GL_TAG, this);
227 LLUICtrlCreator<LLScrollingPanelList>::registerCreator(LL_SCROLLING_PANEL_LIST_TAG, this);
228 LLUICtrlCreator<LLLayoutStack>::registerCreator(LL_LAYOUT_STACK_TAG, this);
229
230 setupPaths(); 108 setupPaths();
231} 109}
232 110
@@ -548,43 +426,33 @@ void LLUICtrlFactory::rebuild()
548//----------------------------------------------------------------------------- 426//-----------------------------------------------------------------------------
549//----------------------------------------------------------------------------- 427//-----------------------------------------------------------------------------
550 428
551// static
552EWidgetType LLUICtrlFactory::getWidgetType(const LLString& ctrl_type)
553{
554 U32 ctrl_id;
555 for (ctrl_id = 0; ctrl_id < WIDGET_TYPE_COUNT; ctrl_id++)
556 {
557 if (sUICtrlNames[ctrl_id] == ctrl_type)
558 {
559 break;
560 }
561 }
562 return (EWidgetType) ctrl_id;
563}
564
565LLString LLUICtrlFactory::getWidgetType(EWidgetType ctrl_type)
566{
567 return sUICtrlNames[ctrl_type];
568}
569
570LLView *LLUICtrlFactory::createCtrlWidget(LLPanel *parent, LLXMLNodePtr node) 429LLView *LLUICtrlFactory::createCtrlWidget(LLPanel *parent, LLXMLNodePtr node)
571{ 430{
431 // panel for holding dummy widgets, so they have a parent for layout purposes, etc.
432 // does not manage lifetime of child widgets
433 static LLPanel dummy_panel;
434
572 LLString ctrl_type = node->getName()->mString; 435 LLString ctrl_type = node->getName()->mString;
573 LLString::toLower(ctrl_type); 436 LLString::toLower(ctrl_type);
574 437
575 creator_list_t::const_iterator it = mCreatorFunctions.find(ctrl_type); 438 LLWidgetClassRegistry::factory_func_t func = LLWidgetClassRegistry::getInstance()->getCreatorFunc(ctrl_type);
576 if (it == mCreatorFunctions.end()) 439
440 if (func == NULL)
577 { 441 {
578 llwarns << "Unknown control type " << ctrl_type << llendl; 442 llwarns << "Unknown control type " << ctrl_type << llendl;
579 return NULL; 443 return NULL;
580 } 444 }
581 445
582 LLView *ctrl = (*it->second)(node, parent, this); 446 if (parent == NULL)
447 {
448 parent = &dummy_panel;
449 }
450 LLView *ctrl = func(node, parent, this);
583 451
584 return ctrl; 452 return ctrl;
585} 453}
586 454
587void LLUICtrlFactory::createWidget(LLPanel *parent, LLXMLNodePtr node) 455LLView* LLUICtrlFactory::createWidget(LLPanel *parent, LLXMLNodePtr node)
588{ 456{
589 LLView* view = createCtrlWidget(parent, node); 457 LLView* view = createCtrlWidget(parent, node);
590 458
@@ -595,6 +463,8 @@ void LLUICtrlFactory::createWidget(LLPanel *parent, LLXMLNodePtr node)
595 { 463 {
596 parent->addChild(view, tab_group); 464 parent->addChild(view, tab_group);
597 } 465 }
466
467 return view;
598} 468}
599 469
600//----------------------------------------------------------------------------- 470//-----------------------------------------------------------------------------
@@ -648,138 +518,3 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const LLString& name,
648 return res; 518 return res;
649} 519}
650 520
651//============================================================================
652
653LLButton* LLUICtrlFactory::getButtonByName(const LLPanel* panelp, const LLString& name)
654{
655 return panelp->getChild<LLButton>(name);
656}
657
658LLCheckBoxCtrl* LLUICtrlFactory::getCheckBoxByName(const LLPanel* panelp, const LLString& name)
659{
660 return panelp->getChild<LLCheckBoxCtrl>(name);
661}
662
663LLComboBox* LLUICtrlFactory::getComboBoxByName(const LLPanel* panelp, const LLString& name)
664{
665 return panelp->getChild<LLComboBox>(name);
666}
667
668LLIconCtrl* LLUICtrlFactory::getIconByName(const LLPanel* panelp, const LLString& name)
669{
670 return panelp->getChild<LLIconCtrl>(name);
671}
672
673LLLineEditor* LLUICtrlFactory::getLineEditorByName(const LLPanel* panelp, const LLString& name)
674{
675 return panelp->getChild<LLLineEditor>(name);
676}
677
678LLRadioGroup* LLUICtrlFactory::getRadioGroupByName(const LLPanel* panelp, const LLString& name)
679{
680 return panelp->getChild<LLRadioGroup>(name);
681}
682
683LLScrollListCtrl* LLUICtrlFactory::getScrollListByName(const LLPanel* panelp, const LLString& name)
684{
685 return panelp->getChild<LLScrollListCtrl>(name);
686}
687
688LLSliderCtrl* LLUICtrlFactory::getSliderByName(const LLPanel* panelp, const LLString& name)
689{
690 return panelp->getChild<LLSliderCtrl>(name);
691}
692
693LLSlider* LLUICtrlFactory::getSliderBarByName(const LLPanel* panelp, const LLString& name)
694{
695 return panelp->getChild<LLSlider>(name);
696}
697
698LLSpinCtrl* LLUICtrlFactory::getSpinnerByName(const LLPanel* panelp, const LLString& name)
699{
700 return panelp->getChild<LLSpinCtrl>(name);
701}
702
703LLTextBox* LLUICtrlFactory::getTextBoxByName(const LLPanel* panelp, const LLString& name)
704{
705 return panelp->getChild<LLTextBox>(name);
706}
707
708LLTextEditor* LLUICtrlFactory::getTextEditorByName(const LLPanel* panelp, const LLString& name)
709{
710 return panelp->getChild<LLTextEditor>(name);
711}
712
713LLTabContainer* LLUICtrlFactory::getTabContainerByName(const LLPanel* panelp, const LLString& name)
714{
715 return panelp->getChild<LLTabContainer>(name);
716}
717
718LLScrollableContainerView* LLUICtrlFactory::getScrollableContainerByName(const LLPanel* panelp, const LLString& name)
719{
720 return panelp->getChild<LLScrollableContainerView>(name);
721}
722
723LLPanel* LLUICtrlFactory::getPanelByName(const LLPanel* panelp, const LLString& name)
724{
725 return panelp->getChild<LLPanel>(name);
726}
727
728LLMenuItemCallGL* LLUICtrlFactory::getMenuItemCallByName(const LLPanel* panelp, const LLString& name)
729{
730 return panelp->getChild<LLMenuItemCallGL>(name);
731}
732
733LLScrollingPanelList* LLUICtrlFactory::getScrollingPanelList(const LLPanel* panelp, const LLString& name)
734{
735 return panelp->getChild<LLScrollingPanelList>(name);
736}
737
738LLMultiSliderCtrl* LLUICtrlFactory::getMultiSliderByName(const LLPanel* panelp, const LLString& name)
739{
740 return panelp->getChild<LLMultiSliderCtrl>(name);
741}
742
743LLMultiSlider* LLUICtrlFactory::getMultiSliderBarByName(const LLPanel* panelp, const LLString& name)
744{
745 return panelp->getChild<LLMultiSlider>(name);
746}
747
748
749LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(const LLPanel* panelp, const LLString& name)
750{
751 LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE);
752 if (viewp && viewp->isCtrl())
753 {
754 return ((LLUICtrl*)viewp)->getListInterface();
755 }
756 return NULL;
757}
758
759LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(const LLPanel* panelp, const LLString& name)
760{
761 LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE);
762 if (viewp && viewp->isCtrl())
763 {
764 return ((LLUICtrl*)viewp)->getSelectionInterface();
765 }
766 return NULL;
767}
768
769LLCtrlScrollInterface* LLUICtrlFactory::getScrollInterfaceByName(const LLPanel* panelp, const LLString& name)
770{
771 LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE);
772 if (viewp && viewp->isCtrl())
773 {
774 return ((LLUICtrl*)viewp)->getScrollInterface();
775 }
776 return NULL;
777}
778
779void LLUICtrlFactory::registerCreator(LLString ctrlname, creator_function_t function)
780{
781 LLString::toLower(ctrlname);
782 mCreatorFunctions[ctrlname] = function;
783}
784
785
diff --git a/linden/indra/llui/lluictrlfactory.h b/linden/indra/llui/lluictrlfactory.h
index e6a2cd3..b9325a0 100644
--- a/linden/indra/llui/lluictrlfactory.h
+++ b/linden/indra/llui/lluictrlfactory.h
@@ -41,7 +41,7 @@
41class LLView; 41class LLView;
42class LLPanel; 42class LLPanel;
43 43
44class LLUICtrlFactory 44class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
45{ 45{
46public: 46public:
47 LLUICtrlFactory(); 47 LLUICtrlFactory();
@@ -49,7 +49,7 @@ public:
49 virtual ~LLUICtrlFactory() {} 49 virtual ~LLUICtrlFactory() {}
50 50
51 void setupPaths(); 51 void setupPaths();
52 52
53 void buildFloater(LLFloater* floaterp, const LLString &filename, 53 void buildFloater(LLFloater* floaterp, const LLString &filename,
54 const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); 54 const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE);
55 BOOL buildPanel(LLPanel* panelp, const LLString &filename, 55 BOOL buildPanel(LLPanel* panelp, const LLString &filename,
@@ -65,84 +65,28 @@ public:
65 // Returns 0 on success 65 // Returns 0 on success
66 S32 saveToXML(LLView* viewp, const LLString& filename); 66 S32 saveToXML(LLView* viewp, const LLString& filename);
67 67
68
69 // Rebuilds all currently built panels. 68 // Rebuilds all currently built panels.
70 void rebuild(); 69 void rebuild();
71 70
72 static EWidgetType getWidgetType(const LLString& ctrl_type);
73 static LLString getWidgetType(EWidgetType ctrl_type);
74 static BOOL getAttributeColor(LLXMLNodePtr node, const LLString& name, LLColor4& color); 71 static BOOL getAttributeColor(LLXMLNodePtr node, const LLString& name, LLColor4& color);
75 72
76 // specific typed getters
77 static class LLButton* getButtonByName( const LLPanel* panelp, const LLString& name);
78 static class LLCheckBoxCtrl* getCheckBoxByName( const LLPanel* panelp, const LLString& name);
79 static class LLComboBox* getComboBoxByName( const LLPanel* panelp, const LLString& name);
80 static class LLIconCtrl* getIconByName( const LLPanel* panelp, const LLString& name);
81 static class LLLineEditor* getLineEditorByName( const LLPanel* panelp, const LLString& name);
82 static class LLRadioGroup* getRadioGroupByName( const LLPanel* panelp, const LLString& name);
83 static class LLScrollListCtrl* getScrollListByName( const LLPanel* panelp, const LLString& name);
84 static class LLSliderCtrl* getSliderByName( const LLPanel* panelp, const LLString& name);
85 static class LLSlider* getSliderBarByName( const LLPanel* panelp, const LLString& name);
86 static class LLSpinCtrl* getSpinnerByName( const LLPanel* panelp, const LLString& name);
87 static class LLTextBox* getTextBoxByName( const LLPanel* panelp, const LLString& name);
88 static class LLTextEditor* getTextEditorByName( const LLPanel* panelp, const LLString& name);
89 static class LLTabContainer* getTabContainerByName( const LLPanel* panelp, const LLString& name);
90 static class LLScrollableContainerView* getScrollableContainerByName(const LLPanel* panelp, const LLString& name);
91 static class LLPanel* getPanelByName( const LLPanel* panelp, const LLString& name);
92 static class LLMenuItemCallGL* getMenuItemCallByName( const LLPanel* panelp, const LLString& name);
93 static class LLScrollingPanelList* getScrollingPanelList( const LLPanel* panelp, const LLString& name);
94 static class LLMultiSliderCtrl* getMultiSliderByName( const LLPanel* panelp, const LLString& name);
95 static class LLMultiSlider* getMultiSliderBarByName(const LLPanel* panelp, const LLString& name);
96
97 // interface getters
98 static LLCtrlListInterface* getListInterfaceByName( const LLPanel* panelp, const LLString& name);
99 static LLCtrlSelectionInterface* getSelectionInterfaceByName(const LLPanel* panelp, const LLString& name);
100 static LLCtrlScrollInterface* getScrollInterfaceByName(const LLPanel* panelp, const LLString& name);
101
102 LLPanel* createFactoryPanel(LLString name); 73 LLPanel* createFactoryPanel(LLString name);
103 74
104 virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node); 75 virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node);
105 virtual void createWidget(LLPanel *parent, LLXMLNodePtr node); 76 virtual LLView* createWidget(LLPanel *parent, LLXMLNodePtr node);
106
107 template <class T> T* createDummyWidget(const LLString& name)
108 {
109 return NULL;
110 //static LLPanel dummy_panel;
111 //LLXMLNodePtr new_node_ptr = new LLXMLNode(T::getWidgetTag(), FALSE);
112 //return createWidget(&dummy_panel, new_node_ptr);
113 }
114
115 // Creator library
116 typedef LLView* (*creator_function_t)(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
117 void registerCreator(LLString ctrlname, creator_function_t function);
118 77
119 static bool getLayeredXMLNode(const LLString &filename, LLXMLNodePtr& root); 78 static bool getLayeredXMLNode(const LLString &filename, LLXMLNodePtr& root);
120 79
121protected:
122
123 template<class T>
124 class LLUICtrlCreator
125 {
126 public:
127 static void registerCreator(LLString name, LLUICtrlFactory *factory)
128 {
129 factory->registerCreator(name, T::fromXML);
130 }
131 };
132
133private: 80private:
134 81
135 typedef std::map<LLHandle<LLPanel>, LLString> built_panel_t; 82 typedef std::map<LLHandle<LLPanel>, LLString> built_panel_t;
136 built_panel_t mBuiltPanels; 83 built_panel_t mBuiltPanels;
84
137 typedef std::map<LLHandle<LLFloater>, LLString> built_floater_t; 85 typedef std::map<LLHandle<LLFloater>, LLString> built_floater_t;
138 built_floater_t mBuiltFloaters; 86 built_floater_t mBuiltFloaters;
139 87
140 std::deque<const LLCallbackMap::map_t*> mFactoryStack; 88 std::deque<const LLCallbackMap::map_t*> mFactoryStack;
141 89
142 static const LLString sUICtrlNames[];
143
144 typedef std::map<LLString, creator_function_t> creator_list_t;
145 creator_list_t mCreatorFunctions;
146 static std::vector<LLString> mXUIPaths; 90 static std::vector<LLString> mXUIPaths;
147}; 91};
148 92
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp
index e5415f8..c9828dd 100644
--- a/linden/indra/llui/llview.cpp
+++ b/linden/indra/llui/llview.cpp
@@ -49,7 +49,16 @@
49#include "lluictrl.h" 49#include "lluictrl.h"
50#include "llwindow.h" 50#include "llwindow.h"
51#include "v3color.h" 51#include "v3color.h"
52#include "lluictrlfactory.h"
52 53
54// for ui edit hack
55#include "llbutton.h"
56#include "lllineeditor.h"
57#include "lltexteditor.h"
58#include "lltextbox.h"
59
60//HACK: this allows you to instantiate LLView from xml with "<view/>" which we don't want
61static LLRegisterWidget<LLView> r("view");
53 62
54BOOL LLView::sDebugRects = FALSE; 63BOOL LLView::sDebugRects = FALSE;
55BOOL LLView::sDebugKeys = FALSE; 64BOOL LLView::sDebugKeys = FALSE;
@@ -153,6 +162,8 @@ LLView::~LLView()
153 162
154 std::for_each(mFloaterControls.begin(), mFloaterControls.end(), 163 std::for_each(mFloaterControls.begin(), mFloaterControls.end(),
155 DeletePairedPointer()); 164 DeletePairedPointer());
165 std::for_each(mDummyWidgets.begin(), mDummyWidgets.end(),
166 DeletePairedPointer());
156} 167}
157 168
158// virtual 169// virtual
@@ -716,7 +727,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_scre
716 tool_tip = getShowNamesToolTip(); 727 tool_tip = getShowNamesToolTip();
717 } 728 }
718 729
719 BOOL showNamesTextBox = LLUI::sShowXUINames && (getWidgetType() == WIDGET_TYPE_TEXT_BOX); 730 BOOL showNamesTextBox = LLUI::sShowXUINames && dynamic_cast<LLTextBox*>(this) != NULL;
720 731
721 if( !handled && (blockMouseEvent(x, y) || showNamesTextBox) && !tool_tip.empty()) 732 if( !handled && (blockMouseEvent(x, y) || showNamesTextBox) && !tool_tip.empty())
722 { 733 {
@@ -741,23 +752,21 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
741{ 752{
742 BOOL handled = FALSE; 753 BOOL handled = FALSE;
743 754
744 if( called_from_parent ) 755 if (getVisible() && getEnabled())
745 { 756 {
746 // Downward traversal 757 if( called_from_parent )
747 if (getVisible() && getEnabled())
748 { 758 {
759 // Downward traversal
749 handled = childrenHandleKey( key, mask ) != NULL; 760 handled = childrenHandleKey( key, mask ) != NULL;
750 } 761 }
751 }
752 762
753 // JC: Must pass to disabled views, since they could have 763 if (!handled)
754 // keyboard focus, which requires the escape key to exit.
755 if (!handled && getVisible())
756 {
757 handled = handleKeyHere( key, mask, called_from_parent );
758 if (handled && LLView::sDebugKeys)
759 { 764 {
760 llinfos << "Key handled by " << getName() << llendl; 765 handled = handleKeyHere( key, mask );
766 if (handled && LLView::sDebugKeys)
767 {
768 llinfos << "Key handled by " << getName() << llendl;
769 }
761 } 770 }
762 } 771 }
763 772
@@ -771,7 +780,7 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
771 780
772// Called from handleKey() 781// Called from handleKey()
773// Handles key in this object. Checking parents and children happens in handleKey() 782// Handles key in this object. Checking parents and children happens in handleKey()
774BOOL LLView::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) 783BOOL LLView::handleKeyHere(KEY key, MASK mask)
775{ 784{
776 return FALSE; 785 return FALSE;
777} 786}
@@ -780,25 +789,24 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
780{ 789{
781 BOOL handled = FALSE; 790 BOOL handled = FALSE;
782 791
783 if( called_from_parent ) 792 if (getVisible() && getEnabled())
784 { 793 {
785 // Downward traversal 794 if( called_from_parent )
786 if (getVisible() && getEnabled())
787 { 795 {
796 // Downward traversal
788 handled = childrenHandleUnicodeChar( uni_char ) != NULL; 797 handled = childrenHandleUnicodeChar( uni_char ) != NULL;
789 } 798 }
790 }
791 799
792 if (!handled && getVisible()) 800 if (!handled)
793 {
794 handled = handleUnicodeCharHere(uni_char, called_from_parent);
795 if (handled && LLView::sDebugKeys)
796 { 801 {
797 llinfos << "Unicode key handled by " << getName() << llendl; 802 handled = handleUnicodeCharHere(uni_char);
803 if (handled && LLView::sDebugKeys)
804 {
805 llinfos << "Unicode key handled by " << getName() << llendl;
806 }
798 } 807 }
799 } 808 }
800 809
801
802 if (!handled && !called_from_parent && mParentView) 810 if (!handled && !called_from_parent && mParentView)
803 { 811 {
804 // Upward traversal 812 // Upward traversal
@@ -809,7 +817,7 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
809} 817}
810 818
811 819
812BOOL LLView::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent ) 820BOOL LLView::handleUnicodeCharHere(llwchar uni_char )
813{ 821{
814 return FALSE; 822 return FALSE;
815} 823}
@@ -903,11 +911,14 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
903 if (sEditingUI && handled_view) 911 if (sEditingUI && handled_view)
904 { 912 {
905 // need to find leaf views, big hack 913 // need to find leaf views, big hack
906 EWidgetType type = handled_view->getWidgetType(); 914 LLButton* buttonp = dynamic_cast<LLButton*>(handled_view);
907 if (type == WIDGET_TYPE_BUTTON 915 LLLineEditor* line_editorp = dynamic_cast<LLLineEditor*>(handled_view);
908 || type == WIDGET_TYPE_LINE_EDITOR 916 LLTextEditor* text_editorp = dynamic_cast<LLTextEditor*>(handled_view);
909 || type == WIDGET_TYPE_TEXT_EDITOR 917 LLTextBox* text_boxp = dynamic_cast<LLTextBox*>(handled_view);
910 || type == WIDGET_TYPE_TEXT_BOX) 918 if (buttonp
919 || line_editorp
920 || text_editorp
921 || text_boxp)
911 { 922 {
912 sEditingUIView = handled_view; 923 sEditingUIView = handled_view;
913 } 924 }
@@ -971,8 +982,10 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks)
971 LLView* viewp = *child_it; 982 LLView* viewp = *child_it;
972 S32 local_x = x - viewp->getRect().mLeft; 983 S32 local_x = x - viewp->getRect().mLeft;
973 S32 local_y = y - viewp->getRect().mBottom; 984 S32 local_y = y - viewp->getRect().mBottom;
974 if (viewp->pointInView(local_x, local_y) && 985 if (viewp->pointInView(local_x, local_y)
975 viewp->handleScrollWheel( local_x, local_y, clicks )) 986 && viewp->getVisible()
987 && viewp->getEnabled()
988 && viewp->handleScrollWheel( local_x, local_y, clicks ))
976 { 989 {
977 if (sDebugMouseHandling) 990 if (sDebugMouseHandling)
978 { 991 {
@@ -1528,7 +1541,7 @@ BOOL LLView::hasAncestor(const LLView* parentp) const
1528 1541
1529BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const 1542BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const
1530{ 1543{
1531 LLView *child = getChildByName(childname); 1544 LLView *child = getChildView(childname, TRUE, FALSE);
1532 if (child) 1545 if (child)
1533 { 1546 {
1534 return gFocusMgr.childHasKeyboardFocus(child); 1547 return gFocusMgr.childHasKeyboardFocus(child);
@@ -1543,16 +1556,17 @@ BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const
1543 1556
1544BOOL LLView::hasChild(const LLString& childname, BOOL recurse) const 1557BOOL LLView::hasChild(const LLString& childname, BOOL recurse) const
1545{ 1558{
1546 return getChildByName(childname, recurse) != NULL; 1559 return getChildView(childname, recurse, FALSE) != NULL;
1547} 1560}
1548 1561
1549//----------------------------------------------------------------------------- 1562//-----------------------------------------------------------------------------
1550// getChildByName() 1563// getChildView()
1551//----------------------------------------------------------------------------- 1564//-----------------------------------------------------------------------------
1552LLView* LLView::getChildByName(const LLString& name, BOOL recurse) const 1565LLView* LLView::getChildView(const LLString& name, BOOL recurse, BOOL create_if_missing) const
1553{ 1566{
1554 if(name.empty()) 1567 //richard: should we allow empty names?
1555 return NULL; 1568 //if(name.empty())
1569 // return NULL;
1556 child_list_const_iter_t child_it; 1570 child_list_const_iter_t child_it;
1557 // Look for direct children *first* 1571 // Look for direct children *first*
1558 for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) 1572 for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
@@ -1569,13 +1583,18 @@ LLView* LLView::getChildByName(const LLString& name, BOOL recurse) const
1569 for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) 1583 for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
1570 { 1584 {
1571 LLView* childp = *child_it; 1585 LLView* childp = *child_it;
1572 LLView* viewp = childp->getChildByName(name, recurse); 1586 LLView* viewp = childp->getChildView(name, recurse, FALSE);
1573 if ( viewp ) 1587 if ( viewp )
1574 { 1588 {
1575 return viewp; 1589 return viewp;
1576 } 1590 }
1577 } 1591 }
1578 } 1592 }
1593
1594 if (create_if_missing)
1595 {
1596 return createDummyWidget<LLView>(name);
1597 }
1579 return NULL; 1598 return NULL;
1580} 1599}
1581 1600
@@ -1692,7 +1711,6 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs
1692 if( getRect().mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) 1711 if( getRect().mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight )
1693 { 1712 {
1694 delta_x = constraint.mRight - (getRect().mLeft + KEEP_ONSCREEN_PIXELS); 1713 delta_x = constraint.mRight - (getRect().mLeft + KEEP_ONSCREEN_PIXELS);
1695 delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() );
1696 } 1714 }
1697 1715
1698 if( getRect().mTop > constraint.mTop ) 1716 if( getRect().mTop > constraint.mTop )
@@ -1703,7 +1721,6 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs
1703 if( getRect().mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) 1721 if( getRect().mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom )
1704 { 1722 {
1705 delta_y = constraint.mBottom - (getRect().mTop - KEEP_ONSCREEN_PIXELS); 1723 delta_y = constraint.mBottom - (getRect().mTop - KEEP_ONSCREEN_PIXELS);
1706 delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() );
1707 } 1724 }
1708 } 1725 }
1709 else 1726 else
@@ -1716,6 +1733,7 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs
1716 if( getRect().mRight > constraint.mRight ) 1733 if( getRect().mRight > constraint.mRight )
1717 { 1734 {
1718 delta_x = constraint.mRight - getRect().mRight; 1735 delta_x = constraint.mRight - getRect().mRight;
1736 // compensate for left edge possible going off screen
1719 delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); 1737 delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() );
1720 } 1738 }
1721 1739
@@ -1727,6 +1745,7 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs
1727 if( getRect().mBottom < constraint.mBottom ) 1745 if( getRect().mBottom < constraint.mBottom )
1728 { 1746 {
1729 delta_y = constraint.mBottom - getRect().mBottom; 1747 delta_y = constraint.mBottom - getRect().mBottom;
1748 // compensate for top edge possible going off screen
1730 delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); 1749 delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() );
1731 } 1750 }
1732 } 1751 }
@@ -1832,9 +1851,8 @@ BOOL LLView::localRectToOtherView( const LLRect& local, LLRect* other, LLView* o
1832// virtual 1851// virtual
1833LLXMLNodePtr LLView::getXML(bool save_children) const 1852LLXMLNodePtr LLView::getXML(bool save_children) const
1834{ 1853{
1835 const LLString& type_name = getWidgetTag(); 1854 //FIXME: need to provide actual derived type tag, probably outside this method
1836 1855 LLXMLNodePtr node = new LLXMLNode("view", FALSE);
1837 LLXMLNodePtr node = new LLXMLNode(type_name, FALSE);
1838 1856
1839 node->createChild("name", TRUE)->setStringValue(getName()); 1857 node->createChild("name", TRUE)->setStringValue(getName());
1840 node->createChild("width", TRUE)->setIntValue(getRect().getWidth()); 1858 node->createChild("width", TRUE)->setIntValue(getRect().getWidth());
@@ -1897,6 +1915,14 @@ LLXMLNodePtr LLView::getXML(bool save_children) const
1897 return node; 1915 return node;
1898} 1916}
1899 1917
1918//static
1919LLView* LLView::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
1920{
1921 LLView* viewp = new LLView();
1922 viewp->initFromXML(node, parent);
1923 return viewp;
1924}
1925
1900// static 1926// static
1901void LLView::addColorXML(LLXMLNodePtr node, const LLColor4& color, 1927void LLView::addColorXML(LLXMLNodePtr node, const LLColor4& color,
1902 const LLString& xml_name, const LLString& control_name) 1928 const LLString& xml_name, const LLString& control_name)
@@ -2426,16 +2452,7 @@ LLSimpleListener* LLView::getListenerByName(const LLString& callback_name)
2426 return callback; 2452 return callback;
2427} 2453}
2428 2454
2429void LLView::addListenerToControl(LLEventDispatcher *dispatcher, const LLString& name, LLSD filter, LLSD userdata) 2455LLControlVariable *LLView::findControl(LLString name)
2430{
2431 LLSimpleListener* listener = getListenerByName(name);
2432 if (listener)
2433 {
2434 dispatcher->addListener(listener, filter, userdata);
2435 }
2436}
2437
2438LLControlBase *LLView::findControl(LLString name)
2439{ 2456{
2440 control_map_t::iterator itor = mFloaterControls.find(name); 2457 control_map_t::iterator itor = mFloaterControls.find(name);
2441 if (itor != mFloaterControls.end()) 2458 if (itor != mFloaterControls.end())
@@ -2791,9 +2808,15 @@ LLFontGL::StyleFlags LLView::selectFontStyle(LLXMLNodePtr node)
2791 return gl_font_style; 2808 return gl_font_style;
2792} 2809}
2793 2810
2794void LLView::setControlValue(const LLSD& value) 2811bool LLView::setControlValue(const LLSD& value)
2795{ 2812{
2796 LLUI::sConfigGroup->setValue(getControlName(), value); 2813 LLString ctrlname = getControlName();
2814 if (!ctrlname.empty())
2815 {
2816 LLUI::sConfigGroup->setValue(ctrlname, value);
2817 return true;
2818 }
2819 return false;
2797} 2820}
2798 2821
2799//virtual 2822//virtual
@@ -2804,43 +2827,57 @@ void LLView::setControlName(const LLString& control_name, LLView *context)
2804 context = this; 2827 context = this;
2805 } 2828 }
2806 2829
2807 // Unregister from existing listeners
2808 if (!mControlName.empty()) 2830 if (!mControlName.empty())
2809 { 2831 {
2810 clearDispatchers(); 2832 llwarns << "setControlName called twice on same control!" << llendl;
2833 mControlConnection.disconnect(); // disconnect current signal
2834 mControlName.clear();
2811 } 2835 }
2812 2836
2813 // Register new listener 2837 // Register new listener
2814 if (!control_name.empty()) 2838 if (!control_name.empty())
2815 { 2839 {
2816 LLControlBase *control = context->findControl(control_name); 2840 LLControlVariable *control = context->findControl(control_name);
2817 if (control) 2841 if (control)
2818 { 2842 {
2819 mControlName = control_name; 2843 mControlName = control_name;
2820 LLSD state = control->registerListener(this, "DEFAULT"); 2844 mControlConnection = control->getSignal()->connect(boost::bind(&controlListener, _1, getHandle(), std::string("value")));
2821 setValue(state); 2845 setValue(control->getValue());
2822 } 2846 }
2823 } 2847 }
2824} 2848}
2825 2849
2826// virtual 2850// static
2827bool LLView::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 2851bool LLView::controlListener(const LLSD& newvalue, LLHandle<LLView> handle, std::string type)
2828{ 2852{
2829 if (userdata.asString() == "DEFAULT" && event->desc() == "value_changed") 2853 LLView* view = handle.get();
2854 if (view)
2830 { 2855 {
2831 LLSD state = event->getValue(); 2856 if (type == "value")
2832 setValue(state); 2857 {
2833 return TRUE; 2858 view->setValue(newvalue);
2859 return true;
2860 }
2861 else if (type == "enabled")
2862 {
2863 view->setEnabled(newvalue.asBoolean());
2864 return true;
2865 }
2866 else if (type == "visible")
2867 {
2868 view->setVisible(newvalue.asBoolean());
2869 return true;
2870 }
2834 } 2871 }
2835 return FALSE; 2872 return false;
2836} 2873}
2837 2874
2838void LLView::addBoolControl(LLString name, bool initial_value) 2875void LLView::addBoolControl(LLString name, bool initial_value)
2839{ 2876{
2840 mFloaterControls[name] = new LLControl(name, TYPE_BOOLEAN, initial_value, "Internal floater control"); 2877 mFloaterControls[name] = new LLControlVariable(name, TYPE_BOOLEAN, initial_value, "Internal floater control");
2841} 2878}
2842 2879
2843LLControlBase *LLView::getControl(LLString name) 2880LLControlVariable *LLView::getControl(LLString name)
2844{ 2881{
2845 control_map_t::iterator itor = mFloaterControls.find(name); 2882 control_map_t::iterator itor = mFloaterControls.find(name);
2846 if (itor != mFloaterControls.end()) 2883 if (itor != mFloaterControls.end())
@@ -2860,3 +2897,41 @@ LLSD LLView::getValue() const
2860{ 2897{
2861 return LLSD(); 2898 return LLSD();
2862} 2899}
2900
2901LLView* LLView::createWidget(LLXMLNodePtr xml_node) const
2902{
2903 // forward requests to ui ctrl factory
2904 return LLUICtrlFactory::getInstance()->createCtrlWidget(NULL, xml_node);
2905}
2906
2907//
2908// LLWidgetClassRegistry
2909//
2910
2911LLWidgetClassRegistry::LLWidgetClassRegistry()
2912{
2913}
2914
2915void LLWidgetClassRegistry::registerCtrl(const LLString& tag, LLWidgetClassRegistry::factory_func_t function)
2916{
2917 LLString lower_case_tag = tag;
2918 LLString::toLower(lower_case_tag);
2919
2920 mCreatorFunctions[lower_case_tag] = function;
2921}
2922
2923BOOL LLWidgetClassRegistry::isTagRegistered(const LLString &tag)
2924{
2925 return mCreatorFunctions.find(tag) != mCreatorFunctions.end();
2926}
2927
2928LLWidgetClassRegistry::factory_func_t LLWidgetClassRegistry::getCreatorFunc(const LLString& ctrl_type)
2929{
2930 factory_map_t::const_iterator found_it = mCreatorFunctions.find(ctrl_type);
2931 if (found_it == mCreatorFunctions.end())
2932 {
2933 return NULL;
2934 }
2935 return found_it->second;
2936}
2937
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h
index 51c314a..9a04ed7 100644
--- a/linden/indra/llui/llview.h
+++ b/linden/indra/llui/llview.h
@@ -52,7 +52,6 @@
52#include "stdenums.h" 52#include "stdenums.h"
53#include "lluistring.h" 53#include "lluistring.h"
54 54
55
56const U32 FOLLOWS_NONE = 0x00; 55const U32 FOLLOWS_NONE = 0x00;
57const U32 FOLLOWS_LEFT = 0x01; 56const U32 FOLLOWS_LEFT = 0x01;
58const U32 FOLLOWS_RIGHT = 0x02; 57const U32 FOLLOWS_RIGHT = 0x02;
@@ -65,7 +64,6 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE;
65 64
66const U32 GL_NAME_UI_RESERVED = 2; 65const U32 GL_NAME_UI_RESERVED = 2;
67 66
68
69/* 67/*
70// virtual functions defined in LLView: 68// virtual functions defined in LLView:
71 69
@@ -120,9 +118,7 @@ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,EDragAndDropTy
120 * 118 *
121virtual void draw(); 119virtual void draw();
122 * 120 *
123virtual EWidgetType getWidgetType() const = 0; 121
124 *
125virtual LLString getWidgetTag() const = 0;
126 * 122 *
127virtual LLXMLNodePtr getXML(bool save_children = true) const; 123virtual LLXMLNodePtr getXML(bool save_children = true) const;
128 * 124 *
@@ -132,7 +128,7 @@ virtual void onFocusLost() {}
132 LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox 128 LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox
133virtual void onFocusReceived() {} 129virtual void onFocusReceived() {}
134 LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor 130 LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor
135virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; 131virtual LLView* getChildView(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
136 LLTabContainer, LLPanel, LLMenuGL 132 LLTabContainer, LLPanel, LLMenuGL
137virtual void setControlName(const LLString& control, LLView *context); 133virtual void setControlName(const LLString& control, LLView *context);
138 LLSliderCtrl, LLCheckBoxCtrl 134 LLSliderCtrl, LLCheckBoxCtrl
@@ -144,13 +140,72 @@ virtual void setValue(const LLSD& value);
144 * 140 *
145 141
146protected: 142protected:
147virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 143virtual BOOL handleKeyHere(KEY key, MASK mask);
148 * 144 *
149virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); 145virtual BOOL handleUnicodeCharHere(llwchar uni_char);
150 * 146 *
151*/ 147*/
152 148
153class LLView : public LLMouseHandler, public LLMortician, public LLSimpleListenerObservable 149class LLUICtrlFactory;
150
151// maps xml strings to widget classes
152class LLWidgetClassRegistry : public LLSingleton<LLWidgetClassRegistry>
153{
154 friend class LLSingleton<LLWidgetClassRegistry>;
155public:
156 typedef LLView* (*factory_func_t)(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
157 typedef std::map<LLString, factory_func_t> factory_map_t;
158
159 void registerCtrl(const LLString& xml_tag, factory_func_t function);
160 BOOL isTagRegistered(const LLString& xml_tag);
161 factory_func_t getCreatorFunc(const LLString& xml_tag);
162
163 // get (first) xml tag for a given class
164 template <class T> std::string getTag()
165 {
166 factory_map_t::iterator it;
167 for(it = mCreatorFunctions.begin(); it != mCreatorFunctions.end(); ++it)
168 {
169 if (it->second == T::fromXML)
170 {
171 return it->first;
172 }
173 }
174
175 return "";
176 }
177
178private:
179 LLWidgetClassRegistry();
180 virtual ~LLWidgetClassRegistry() {};
181
182 typedef std::set<LLString> ctrl_name_set_t;
183 ctrl_name_set_t mUICtrlNames;
184
185 // map of xml tags to widget creator functions
186 factory_map_t mCreatorFunctions;
187};
188
189template<class T>
190class LLRegisterWidget
191{
192public:
193 LLRegisterWidget(const std::string& tag)
194 {
195 LLWidgetClassRegistry* registry = LLWidgetClassRegistry::getInstance();
196 if (registry->isTagRegistered(tag))
197 {
198 //error!
199 llerrs << "Widget named " << tag << " already registered!" << llendl;
200 }
201 else
202 {
203 registry->registerCtrl(tag, T::fromXML);
204 }
205 }
206};
207
208class LLView : public LLMouseHandler, public LLMortician
154{ 209{
155 210
156public: 211public:
@@ -294,7 +349,6 @@ public:
294 349
295 LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; } 350 LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; }
296 351
297
298 U32 getFollows() const { return mReshapeFlags; } 352 U32 getFollows() const { return mReshapeFlags; }
299 BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } 353 BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; }
300 BOOL followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; } 354 BOOL followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; }
@@ -355,10 +409,9 @@ public:
355 409
356 virtual void draw(); 410 virtual void draw();
357 411
358 virtual EWidgetType getWidgetType() const = 0;
359 virtual LLString getWidgetTag() const = 0;
360 virtual LLXMLNodePtr getXML(bool save_children = true) const; 412 virtual LLXMLNodePtr getXML(bool save_children = true) const;
361 413 //FIXME: make LLView non-instantiable from XML
414 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
362 virtual void initFromXML(LLXMLNodePtr node, LLView* parent); 415 virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
363 void parseFollowsFlags(LLXMLNodePtr node); 416 void parseFollowsFlags(LLXMLNodePtr node);
364 417
@@ -393,13 +446,13 @@ public:
393 void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata); 446 void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata);
394 447
395 void addBoolControl(LLString name, bool initial_value); 448 void addBoolControl(LLString name, bool initial_value);
396 LLControlBase *getControl(LLString name); 449 LLControlVariable *getControl(LLString name);
397 LLControlBase *findControl(LLString name); 450 LLControlVariable *findControl(LLString name);
398 451
399 void setControlValue(const LLSD& value); 452 bool setControlValue(const LLSD& value);
400 virtual void setControlName(const LLString& control, LLView *context); 453 virtual void setControlName(const LLString& control, LLView *context);
401 virtual LLString getControlName() const { return mControlName; } 454 virtual LLString getControlName() const { return mControlName; }
402 virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); 455// virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
403 virtual void setValue(const LLSD& value); 456 virtual void setValue(const LLSD& value);
404 virtual LLSD getValue() const; 457 virtual LLSD getValue() const;
405 458
@@ -422,17 +475,74 @@ public:
422 /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; 475 /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
423 /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; 476 /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
424 477
425 template <class T> T* getChild(const LLString& name, BOOL recurse = TRUE) const 478 template <class T> T* getChild(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const
426 { 479 {
427 T* result = dynamic_cast<T*>(getChildByName(name, TRUE)); 480 LLView* child = getChildView(name, recurse, FALSE);
428 //if (!result) 481 T* result = dynamic_cast<T*>(child);
429 //{ 482 if (!result)
430 // // create dummy widget instance here 483 {
431 // result = gUICtrlFactory->createDummyWidget<T>(name); 484 // did we find *something* with that name?
432 //} 485 if (child)
486 {
487 llwarns << "Found child named " << name << " but of wrong type" << llendl;
488 }
489 if (create_if_missing)
490 {
491 // create dummy widget instance here
492 result = createDummyWidget<T>(name);
493 }
494 }
433 return result; 495 return result;
434 } 496 }
435 497
498 virtual LLView* getChildView(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
499
500 template <class T> T* createDummyWidget(const LLString& name) const
501 {
502 T* widget = getDummyWidget<T>(name);
503 if (!widget)
504 {
505 // get xml tag name corresponding to requested widget type (e.g. "button")
506 LLString xml_tag = LLWidgetClassRegistry::getInstance()->getTag<T>();
507 if (xml_tag.empty())
508 {
509 llwarns << "No xml tag registered for this class " << llendl;
510 return NULL;
511 }
512 // create dummy xml node (<button name="foo"/>)
513 LLXMLNodePtr new_node_ptr = new LLXMLNode(xml_tag, FALSE);
514 new_node_ptr->createChild("name", TRUE)->setStringValue(name);
515
516 widget = dynamic_cast<T*>(createWidget(new_node_ptr));
517 if (widget)
518 {
519 // need non-const to update private dummy widget cache
520 llwarns << "Making dummy " << xml_tag << " named " << name << " in " << getName() << llendl;
521 const_cast<LLView*>(this)->mDummyWidgets.insert(std::make_pair(name, widget));
522 }
523 else
524 {
525 // dynamic cast will fail if T::fromXML only registered for base class
526 llwarns << "Failed to create dummy widget of requested type " << llendl;
527 return NULL;
528 }
529 }
530 return widget;
531 }
532
533 template <class T> T* getDummyWidget(const LLString& name) const
534 {
535 dummy_widget_map_t::const_iterator found_it = mDummyWidgets.find(name);
536 if (found_it == mDummyWidgets.end())
537 {
538 return NULL;
539 }
540 return dynamic_cast<T*>(found_it->second);
541 }
542
543 LLView* createWidget(LLXMLNodePtr xml_node) const;
544
545
436 // statics 546 // statics
437 static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); 547 static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect());
438 548
@@ -471,8 +581,8 @@ public:
471 581
472 582
473protected: 583protected:
474 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 584 virtual BOOL handleKeyHere(KEY key, MASK mask);
475 virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); 585 virtual BOOL handleUnicodeCharHere(llwchar uni_char);
476 586
477 void drawDebugRect(); 587 void drawDebugRect();
478 void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); 588 void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
@@ -494,10 +604,10 @@ protected:
494 LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); 604 LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
495 LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); 605 LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
496 606
497 typedef std::map<LLString, LLControlBase*> control_map_t; 607 static bool controlListener(const LLSD& newvalue, LLHandle<LLView> handle, std::string type);
498 control_map_t mFloaterControls;
499 608
500 virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; 609 typedef std::map<LLString, LLControlVariable*> control_map_t;
610 control_map_t mFloaterControls;
501 611
502private: 612private:
503 LLView* mParentView; 613 LLView* mParentView;
@@ -538,8 +648,11 @@ private:
538 648
539 LLString mControlName; 649 LLString mControlName;
540 650
651 typedef std::map<LLString, LLView*> dummy_widget_map_t;
652 dummy_widget_map_t mDummyWidgets;
541 653
542// Just debugging stuff? We should try to hide anything that's not. -MG 654 boost::signals::connection mControlConnection;
655
543public: 656public:
544 static BOOL sDebugRects; // Draw debug rects behind everything. 657 static BOOL sDebugRects; // Draw debug rects behind everything.
545 static BOOL sDebugKeys; 658 static BOOL sDebugKeys;
@@ -554,9 +667,6 @@ public:
554 static BOOL sForceReshape; 667 static BOOL sForceReshape;
555}; 668};
556 669
557
558
559
560class LLCompareByTabOrder 670class LLCompareByTabOrder
561{ 671{
562public: 672public:
@@ -568,4 +678,5 @@ private:
568 LLView::child_tab_order_t mTabOrder; 678 LLView::child_tab_order_t mTabOrder;
569}; 679};
570 680
681
571#endif //LL_LLVIEW_H 682#endif //LL_LLVIEW_H
diff --git a/linden/indra/llui/llviewborder.cpp b/linden/indra/llui/llviewborder.cpp
index 6c2d9fa..e8cff7b 100644
--- a/linden/indra/llui/llviewborder.cpp
+++ b/linden/indra/llui/llviewborder.cpp
@@ -33,6 +33,8 @@
33#include "llglimmediate.h" 33#include "llglimmediate.h"
34#include "llfocusmgr.h" 34#include "llfocusmgr.h"
35 35
36static LLRegisterWidget<LLViewBorder> r("view_border");
37
36LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel, EStyle style, S32 width ) 38LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel, EStyle style, S32 width )
37 : 39 :
38 LLView( name, rect, FALSE ), 40 LLView( name, rect, FALSE ),
@@ -66,47 +68,45 @@ void LLViewBorder::setColorsExtended( const LLColor4& shadow_light, const LLColo
66 68
67void LLViewBorder::setTexture( const LLUUID &image_id ) 69void LLViewBorder::setTexture( const LLUUID &image_id )
68{ 70{
69 mTexture = LLUI::sImageProvider->getImageByID(image_id); 71 mTexture = LLUI::sImageProvider->getUIImageByID(image_id);
70} 72}
71 73
72 74
73void LLViewBorder::draw() 75void LLViewBorder::draw()
74{ 76{
75 if( getVisible() ) 77 if( STYLE_LINE == mStyle )
76 { 78 {
77 if( STYLE_LINE == mStyle ) 79 if( 0 == mBorderWidth )
80 {
81 // no visible border
82 }
83 else
84 if( 1 == mBorderWidth )
85 {
86 drawOnePixelLines();
87 }
88 else
89 if( 2 == mBorderWidth )
78 { 90 {
79 if( 0 == mBorderWidth ) 91 drawTwoPixelLines();
80 {
81 // no visible border
82 }
83 else
84 if( 1 == mBorderWidth )
85 {
86 drawOnePixelLines();
87 }
88 else
89 if( 2 == mBorderWidth )
90 {
91 drawTwoPixelLines();
92 }
93 else
94 {
95 llassert( FALSE ); // not implemented
96 }
97 } 92 }
98 else 93 else
99 if( STYLE_TEXTURE == mStyle )
100 { 94 {
101 if( mTexture ) 95 llassert( FALSE ); // not implemented
102 {
103 drawTextures();
104 }
105 } 96 }
97 }
98 else
99 if( STYLE_TEXTURE == mStyle )
100 {
101 if( mTexture )
102 {
103 drawTextures();
104 }
105 }
106
107 // draw the children
108 LLView::draw();
106 109
107 // draw the children
108 LLView::draw();
109 }
110} 110}
111 111
112void LLViewBorder::drawOnePixelLines() 112void LLViewBorder::drawOnePixelLines()
@@ -134,11 +134,10 @@ void LLViewBorder::drawOnePixelLines()
134 134
135 if( mHasKeyboardFocus ) 135 if( mHasKeyboardFocus )
136 { 136 {
137 F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
138 top_color = gFocusMgr.getFocusColor(); 137 top_color = gFocusMgr.getFocusColor();
139 bottom_color = top_color; 138 bottom_color = top_color;
140 139
141 LLUI::setLineWidth(lerp(1.f, 3.f, lerp_amt)); 140 LLUI::setLineWidth(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt()));
142 } 141 }
143 142
144 S32 left = 0; 143 S32 left = 0;
@@ -225,20 +224,20 @@ void LLViewBorder::drawTwoPixelLines()
225 224
226void LLViewBorder::drawTextures() 225void LLViewBorder::drawTextures()
227{ 226{
228 LLGLSUIDefault gls_ui; 227 //LLGLSUIDefault gls_ui;
229 228
230 llassert( FALSE ); // TODO: finish implementing 229 //llassert( FALSE ); // TODO: finish implementing
231 230
232 gGL.color4fv(UI_VERTEX_COLOR.mV); 231 //gGL.color4fv(UI_VERTEX_COLOR.mV);
233 232
234 mTexture->bind(); 233 //mTexture->bind();
235 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); 234 //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
236 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); 235 //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
237 236
238 drawTextureTrapezoid( 0.f, mBorderWidth, getRect().getWidth(), 0, 0 ); 237 //drawTextureTrapezoid( 0.f, mBorderWidth, getRect().getWidth(), 0, 0 );
239 drawTextureTrapezoid( 90.f, mBorderWidth, getRect().getHeight(), (F32)getRect().getWidth(),0 ); 238 //drawTextureTrapezoid( 90.f, mBorderWidth, getRect().getHeight(), (F32)getRect().getWidth(),0 );
240 drawTextureTrapezoid( 180.f, mBorderWidth, getRect().getWidth(), (F32)getRect().getWidth(),(F32)getRect().getHeight() ); 239 //drawTextureTrapezoid( 180.f, mBorderWidth, getRect().getWidth(), (F32)getRect().getWidth(),(F32)getRect().getHeight() );
241 drawTextureTrapezoid( 270.f, mBorderWidth, getRect().getHeight(), 0, (F32)getRect().getHeight() ); 240 //drawTextureTrapezoid( 270.f, mBorderWidth, getRect().getHeight(), 0, (F32)getRect().getHeight() );
242} 241}
243 242
244 243
diff --git a/linden/indra/llui/llviewborder.h b/linden/indra/llui/llviewborder.h
index 4e5dfee..eacb2b5 100644
--- a/linden/indra/llui/llviewborder.h
+++ b/linden/indra/llui/llviewborder.h
@@ -44,8 +44,6 @@ public:
44 LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel = BEVEL_OUT, EStyle style = STYLE_LINE, S32 width = 1 ); 44 LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel = BEVEL_OUT, EStyle style = STYLE_LINE, S32 width = 1 );
45 45
46 virtual void setValue(const LLSD& val) { setRect(LLRect(val)); } 46 virtual void setValue(const LLSD& val) { setRect(LLRect(val)); }
47 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_VIEW_BORDER; }
48 virtual LLString getWidgetTag() const { return LL_VIEW_BORDER_TAG; }
49 47
50 virtual BOOL isCtrl() const { return FALSE; } 48 virtual BOOL isCtrl() const { return FALSE; }
51 49
@@ -85,7 +83,7 @@ private:
85 LLColor4 mShadowDark; 83 LLColor4 mShadowDark;
86 LLColor4 mBackgroundColor; 84 LLColor4 mBackgroundColor;
87 S32 mBorderWidth; 85 S32 mBorderWidth;
88 LLPointer<LLImageGL> mTexture; 86 LLUIImagePtr mTexture;
89 BOOL mHasKeyboardFocus; 87 BOOL mHasKeyboardFocus;
90}; 88};
91 89
diff --git a/linden/indra/llui/llviewquery.cpp b/linden/indra/llui/llviewquery.cpp
index 5c58ad6..b84fba5 100644
--- a/linden/indra/llui/llviewquery.cpp
+++ b/linden/indra/llui/llviewquery.cpp
@@ -66,11 +66,6 @@ filterResult_t LLCtrlFilter::operator() (const LLView* const view, const viewLis
66 return filterResult_t(view->isCtrl(),TRUE); 66 return filterResult_t(view->isCtrl(),TRUE);
67} 67}
68 68
69filterResult_t LLWidgetTypeFilter::operator() (const LLView* const view, const viewList_t & children) const
70{
71 return filterResult_t(view->getWidgetType() == mType, TRUE);
72}
73
74// 69//
75// LLViewQuery 70// LLViewQuery
76// 71//
diff --git a/linden/indra/llui/llviewquery.h b/linden/indra/llui/llviewquery.h
index 7e947cd..c76ed25 100644
--- a/linden/indra/llui/llviewquery.h
+++ b/linden/indra/llui/llviewquery.h
@@ -87,14 +87,14 @@ class LLCtrlFilter : public LLQueryFilter, public LLSingleton<LLCtrlFilter>
87 /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; 87 /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
88}; 88};
89 89
90template <class T>
90class LLWidgetTypeFilter : public LLQueryFilter 91class LLWidgetTypeFilter : public LLQueryFilter
91{ 92{
92public: 93 /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const
93 LLWidgetTypeFilter(EWidgetType type) : mType(type) {}; 94 {
94private: 95 return filterResult_t(dynamic_cast<const T*>(view) != NULL, TRUE);
95 /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; 96 }
96 97
97 EWidgetType mType;
98}; 98};
99 99
100// Algorithm for flattening 100// Algorithm for flattening