diff options
author | Jacek Antonelli | 2008-08-15 23:45:27 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:27 -0500 |
commit | a8a62201ba762e98dff92cf49033e577fc34d8d4 (patch) | |
tree | 11f8513c5cdc222f2fac0c93eb724c089803c200 /linden/indra/llui/llcombobox.cpp | |
parent | Second Life viewer sources 1.18.6.4-RC (diff) | |
download | meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.zip meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.gz meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.bz2 meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.xz |
Second Life viewer sources 1.19.0.0
Diffstat (limited to 'linden/indra/llui/llcombobox.cpp')
-rw-r--r-- | linden/indra/llui/llcombobox.cpp | 514 |
1 files changed, 325 insertions, 189 deletions
diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index cfdcf58..22b5033 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -55,17 +55,16 @@ | |||
55 | // Globals | 55 | // Globals |
56 | S32 LLCOMBOBOX_HEIGHT = 0; | 56 | S32 LLCOMBOBOX_HEIGHT = 0; |
57 | S32 LLCOMBOBOX_WIDTH = 0; | 57 | S32 LLCOMBOBOX_WIDTH = 0; |
58 | 58 | S32 MAX_COMBO_WIDTH = 500; | |
59 | |||
59 | LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString& label, | 60 | LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString& label, |
60 | void (*commit_callback)(LLUICtrl*,void*), | 61 | void (*commit_callback)(LLUICtrl*,void*), |
61 | void *callback_userdata | 62 | void *callback_userdata |
62 | ) | 63 | ) |
63 | : LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata, | 64 | : LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata, |
64 | FOLLOWS_LEFT | FOLLOWS_TOP), | 65 | FOLLOWS_LEFT | FOLLOWS_TOP), |
65 | mDrawArrow(TRUE), | ||
66 | mTextEntry(NULL), | 66 | mTextEntry(NULL), |
67 | mArrowImage(NULL), | 67 | mArrowImage(NULL), |
68 | mArrowImageWidth(8), | ||
69 | mAllowTextEntry(FALSE), | 68 | mAllowTextEntry(FALSE), |
70 | mMaxChars(20), | 69 | mMaxChars(20), |
71 | mTextEntryTentative(TRUE), | 70 | mTextEntryTentative(TRUE), |
@@ -73,55 +72,43 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
73 | mPrearrangeCallback( NULL ), | 72 | mPrearrangeCallback( NULL ), |
74 | mTextEntryCallback( NULL ) | 73 | mTextEntryCallback( NULL ) |
75 | { | 74 | { |
76 | // For now, all comboboxes don't take keyboard focus when clicked. | ||
77 | // This might change if it is part of a modal dialog. | ||
78 | // mKeyboardFocusOnClick = FALSE; | ||
79 | |||
80 | // Revert to standard behavior. When this control's parent is hidden, it needs to | ||
81 | // hide this ctrl--which won't just happen automatically since when LLComboBox is | ||
82 | // showing its list, it's also set to TopCtrl. When keyboard focus is cleared all | ||
83 | // controls (including this one) know that they are no longer editing. | ||
84 | mKeyboardFocusOnClick = TRUE; | ||
85 | |||
86 | LLRect r; | ||
87 | r.setOriginAndSize(0, 0, rect.getWidth(), rect.getHeight()); | ||
88 | |||
89 | // Always use text box | 75 | // Always use text box |
90 | // Text label button | 76 | // Text label button |
91 | mButton = new LLSquareButton("comboxbox button", | 77 | mButton = new LLButton("comboxbox button", |
92 | r, label, NULL, LLString::null, | 78 | LLRect(), label, NULL, LLString::null, |
93 | NULL, this); | 79 | NULL, this); |
80 | mButton->setImageUnselected("square_btn_32x128.tga"); | ||
81 | mButton->setImageSelected("square_btn_selected_32x128.tga"); | ||
82 | mButton->setImageDisabled("square_btn_32x128.tga"); | ||
83 | mButton->setImageDisabledSelected("square_btn_selected_32x128.tga"); | ||
84 | mButton->setScaleImage(TRUE); | ||
85 | |||
94 | mButton->setMouseDownCallback(onButtonDown); | 86 | mButton->setMouseDownCallback(onButtonDown); |
95 | mButton->setFont(LLFontGL::sSansSerifSmall); | 87 | mButton->setFont(LLFontGL::sSansSerifSmall); |
96 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); | 88 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); |
97 | mButton->setHAlign( LLFontGL::LEFT ); | 89 | mButton->setHAlign( LLFontGL::LEFT ); |
98 | 90 | mButton->setRightHPad(2); | |
99 | const S32 ARROW_WIDTH = 16; | ||
100 | mButton->setRightHPad( ARROW_WIDTH ); | ||
101 | addChild(mButton); | 91 | addChild(mButton); |
102 | 92 | ||
103 | // Default size, will be set by arrange() call in button callback. | ||
104 | S32 list_width = mRect.getWidth() + SCROLLBAR_SIZE; | ||
105 | r.setOriginAndSize(0, 16, list_width, 220); | ||
106 | |||
107 | // disallow multiple selection | 93 | // disallow multiple selection |
108 | mList = new LLScrollListCtrl( | 94 | mList = new LLScrollListCtrl( |
109 | "ComboBox", r, | 95 | "ComboBox", LLRect(), |
110 | &LLComboBox::onItemSelected, this, FALSE); | 96 | &LLComboBox::onItemSelected, this, FALSE); |
111 | mList->setVisible(FALSE); | 97 | mList->setVisible(FALSE); |
112 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); | 98 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); |
113 | mList->setCommitOnKeyboardMovement(FALSE); | 99 | mList->setCommitOnKeyboardMovement(FALSE); |
114 | mList->setFocusChangedCallback(onListFocusChanged); | ||
115 | addChild(mList); | 100 | addChild(mList); |
116 | 101 | ||
117 | LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | 102 | LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); |
118 | mBorder = new LLViewBorder( "combo border", border_rect ); | 103 | mBorder = new LLViewBorder( "combo border", border_rect ); |
119 | addChild( mBorder ); | 104 | addChild( mBorder ); |
120 | mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM); | 105 | mBorder->setFollowsAll(); |
121 | 106 | ||
122 | LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") ); | 107 | LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") ); |
123 | mArrowImage = LLUI::sImageProvider->getUIImageByID(arrow_image_id); | 108 | mArrowImage = LLUI::sImageProvider->getImageByID(arrow_image_id); |
124 | mArrowImageWidth = llmax(8,mArrowImage->getWidth(0)); // In case image hasn't loaded yet | 109 | mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT); |
110 | |||
111 | updateLayout(); | ||
125 | } | 112 | } |
126 | 113 | ||
127 | 114 | ||
@@ -155,7 +142,7 @@ LLXMLNodePtr LLComboBox::getXML(bool save_children) const | |||
155 | LLSD value = item->getValue(); | 142 | LLSD value = item->getValue(); |
156 | item_node->createChild("value", TRUE)->setStringValue(value.asString()); | 143 | item_node->createChild("value", TRUE)->setStringValue(value.asString()); |
157 | item_node->createChild("enabled", TRUE)->setBoolValue(item->getEnabled()); | 144 | item_node->createChild("enabled", TRUE)->setBoolValue(item->getEnabled()); |
158 | item_node->setStringValue(cell->getText()); | 145 | item_node->setStringValue(cell->getValue().asString()); |
159 | } | 146 | } |
160 | } | 147 | } |
161 | 148 | ||
@@ -272,34 +259,46 @@ void LLComboBox::resetDirty() | |||
272 | 259 | ||
273 | 260 | ||
274 | // add item "name" to menu | 261 | // add item "name" to menu |
275 | void LLComboBox::add(const LLString& name, EAddPosition pos, BOOL enabled) | 262 | LLScrollListItem* LLComboBox::add(const LLString& name, EAddPosition pos, BOOL enabled) |
276 | { | 263 | { |
277 | mList->addSimpleItem(name, pos, enabled); | 264 | LLScrollListItem* item = mList->addSimpleElement(name, pos); |
265 | item->setEnabled(enabled); | ||
278 | mList->selectFirstItem(); | 266 | mList->selectFirstItem(); |
267 | return item; | ||
279 | } | 268 | } |
280 | 269 | ||
281 | // add item "name" with a unique id to menu | 270 | // add item "name" with a unique id to menu |
282 | void LLComboBox::add(const LLString& name, const LLUUID& id, EAddPosition pos, BOOL enabled ) | 271 | LLScrollListItem* LLComboBox::add(const LLString& name, const LLUUID& id, EAddPosition pos, BOOL enabled ) |
283 | { | 272 | { |
284 | mList->addSimpleItem(name, LLSD(id), pos, enabled); | 273 | LLScrollListItem* item = mList->addSimpleElement(name, pos, id); |
274 | item->setEnabled(enabled); | ||
285 | mList->selectFirstItem(); | 275 | mList->selectFirstItem(); |
276 | return item; | ||
286 | } | 277 | } |
287 | 278 | ||
288 | // add item "name" with attached userdata | 279 | // add item "name" with attached userdata |
289 | void LLComboBox::add(const LLString& name, void* userdata, EAddPosition pos, BOOL enabled ) | 280 | LLScrollListItem* LLComboBox::add(const LLString& name, void* userdata, EAddPosition pos, BOOL enabled ) |
290 | { | 281 | { |
291 | LLScrollListItem* item = mList->addSimpleItem(name, pos, enabled); | 282 | LLScrollListItem* item = mList->addSimpleElement(name, pos); |
283 | item->setEnabled(enabled); | ||
292 | item->setUserdata( userdata ); | 284 | item->setUserdata( userdata ); |
293 | mList->selectFirstItem(); | 285 | mList->selectFirstItem(); |
286 | return item; | ||
294 | } | 287 | } |
295 | 288 | ||
296 | // add item "name" with attached generic data | 289 | // add item "name" with attached generic data |
297 | void LLComboBox::add(const LLString& name, LLSD value, EAddPosition pos, BOOL enabled ) | 290 | LLScrollListItem* LLComboBox::add(const LLString& name, LLSD value, EAddPosition pos, BOOL enabled ) |
298 | { | 291 | { |
299 | mList->addSimpleItem(name, value, pos, enabled); | 292 | LLScrollListItem* item = mList->addSimpleElement(name, pos, value); |
293 | item->setEnabled(enabled); | ||
300 | mList->selectFirstItem(); | 294 | mList->selectFirstItem(); |
295 | return item; | ||
301 | } | 296 | } |
302 | 297 | ||
298 | LLScrollListItem* LLComboBox::addSeparator(EAddPosition pos) | ||
299 | { | ||
300 | return mList->addSeparator(pos); | ||
301 | } | ||
303 | 302 | ||
304 | void LLComboBox::sortByName() | 303 | void LLComboBox::sortByName() |
305 | { | 304 | { |
@@ -311,7 +310,7 @@ void LLComboBox::sortByName() | |||
311 | // Returns TRUE if the item was found. | 310 | // Returns TRUE if the item was found. |
312 | BOOL LLComboBox::setSimple(const LLStringExplicit& name) | 311 | BOOL LLComboBox::setSimple(const LLStringExplicit& name) |
313 | { | 312 | { |
314 | BOOL found = mList->selectSimpleItem(name, FALSE); | 313 | BOOL found = mList->selectItemByLabel(name, FALSE); |
315 | 314 | ||
316 | if (found) | 315 | if (found) |
317 | { | 316 | { |
@@ -330,14 +329,14 @@ void LLComboBox::setValue(const LLSD& value) | |||
330 | LLScrollListItem* item = mList->getFirstSelected(); | 329 | LLScrollListItem* item = mList->getFirstSelected(); |
331 | if (item) | 330 | if (item) |
332 | { | 331 | { |
333 | setLabel( mList->getSimpleSelectedItem() ); | 332 | setLabel( mList->getSelectedItemLabel() ); |
334 | } | 333 | } |
335 | } | 334 | } |
336 | } | 335 | } |
337 | 336 | ||
338 | const LLString& LLComboBox::getSimple() const | 337 | const LLString LLComboBox::getSimple() const |
339 | { | 338 | { |
340 | const LLString& res = mList->getSimpleSelectedItem(); | 339 | const LLString res = mList->getSelectedItemLabel(); |
341 | if (res.empty() && mAllowTextEntry) | 340 | if (res.empty() && mAllowTextEntry) |
342 | { | 341 | { |
343 | return mTextEntry->getText(); | 342 | return mTextEntry->getText(); |
@@ -348,9 +347,9 @@ const LLString& LLComboBox::getSimple() const | |||
348 | } | 347 | } |
349 | } | 348 | } |
350 | 349 | ||
351 | const LLString& LLComboBox::getSimpleSelectedItem(S32 column) const | 350 | const LLString LLComboBox::getSelectedItemLabel(S32 column) const |
352 | { | 351 | { |
353 | return mList->getSimpleSelectedItem(column); | 352 | return mList->getSelectedItemLabel(column); |
354 | } | 353 | } |
355 | 354 | ||
356 | // virtual | 355 | // virtual |
@@ -373,10 +372,10 @@ LLSD LLComboBox::getValue() const | |||
373 | 372 | ||
374 | void LLComboBox::setLabel(const LLStringExplicit& name) | 373 | void LLComboBox::setLabel(const LLStringExplicit& name) |
375 | { | 374 | { |
376 | if ( mAllowTextEntry ) | 375 | if ( mTextEntry ) |
377 | { | 376 | { |
378 | mTextEntry->setText(name); | 377 | mTextEntry->setText(name); |
379 | if (mList->selectSimpleItem(name, FALSE)) | 378 | if (mList->selectItemByLabel(name, FALSE)) |
380 | { | 379 | { |
381 | mTextEntry->setTentative(FALSE); | 380 | mTextEntry->setTentative(FALSE); |
382 | } | 381 | } |
@@ -385,7 +384,8 @@ void LLComboBox::setLabel(const LLStringExplicit& name) | |||
385 | mTextEntry->setTentative(mTextEntryTentative); | 384 | mTextEntry->setTentative(mTextEntryTentative); |
386 | } | 385 | } |
387 | } | 386 | } |
388 | else | 387 | |
388 | if (!mAllowTextEntry) | ||
389 | { | 389 | { |
390 | mButton->setLabelUnselected(name); | 390 | mButton->setLabelUnselected(name); |
391 | mButton->setLabelSelected(name); | 391 | mButton->setLabelSelected(name); |
@@ -397,7 +397,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name) | |||
397 | 397 | ||
398 | BOOL LLComboBox::remove(const LLString& name) | 398 | BOOL LLComboBox::remove(const LLString& name) |
399 | { | 399 | { |
400 | BOOL found = mList->selectSimpleItem(name); | 400 | BOOL found = mList->selectItemByLabel(name); |
401 | 401 | ||
402 | if (found) | 402 | if (found) |
403 | { | 403 | { |
@@ -433,16 +433,21 @@ void LLComboBox::onFocusLost() | |||
433 | LLUICtrl::onFocusLost(); | 433 | LLUICtrl::onFocusLost(); |
434 | } | 434 | } |
435 | 435 | ||
436 | void LLComboBox::onLostTop() | ||
437 | { | ||
438 | hideList(); | ||
439 | } | ||
440 | |||
441 | |||
436 | void LLComboBox::setButtonVisible(BOOL visible) | 442 | void LLComboBox::setButtonVisible(BOOL visible) |
437 | { | 443 | { |
438 | mButton->setVisible(visible); | 444 | mButton->setVisible(visible); |
439 | mDrawArrow = visible; | ||
440 | if (mTextEntry) | 445 | if (mTextEntry) |
441 | { | 446 | { |
442 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | 447 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); |
443 | if (visible) | 448 | if (visible) |
444 | { | 449 | { |
445 | text_entry_rect.mRight -= mArrowImageWidth + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); | 450 | text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); |
446 | } | 451 | } |
447 | //mTextEntry->setRect(text_entry_rect); | 452 | //mTextEntry->setRect(text_entry_rect); |
448 | mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); | 453 | mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); |
@@ -457,22 +462,8 @@ void LLComboBox::draw() | |||
457 | 462 | ||
458 | mButton->setEnabled(mEnabled /*&& !mList->isEmpty()*/); | 463 | mButton->setEnabled(mEnabled /*&& !mList->isEmpty()*/); |
459 | 464 | ||
460 | // Draw children | 465 | // Draw children normally |
461 | LLUICtrl::draw(); | 466 | LLUICtrl::draw(); |
462 | |||
463 | if (mDrawArrow) | ||
464 | { | ||
465 | // Paste the graphic on the right edge | ||
466 | if (!mArrowImage.isNull()) | ||
467 | { | ||
468 | S32 arrow_height = llmin(mRect.getHeight(), mArrowImage->getHeight()); | ||
469 | S32 arrow_width = llround((F32)mArrowImage->getWidth() * ((F32)arrow_height / (F32)mArrowImage->getHeight())); | ||
470 | |||
471 | S32 left = mRect.getWidth() - mArrowImage->getWidth() - LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
472 | |||
473 | gl_draw_scaled_image( left, 0, arrow_width, arrow_height, mArrowImage, LLColor4::white); | ||
474 | } | ||
475 | } | ||
476 | } | 467 | } |
477 | } | 468 | } |
478 | 469 | ||
@@ -481,7 +472,7 @@ BOOL LLComboBox::setCurrentByIndex( S32 index ) | |||
481 | BOOL found = mList->selectNthItem( index ); | 472 | BOOL found = mList->selectNthItem( index ); |
482 | if (found) | 473 | if (found) |
483 | { | 474 | { |
484 | setLabel(mList->getSimpleSelectedItem()); | 475 | setLabel(mList->getSelectedItemLabel()); |
485 | } | 476 | } |
486 | return found; | 477 | return found; |
487 | } | 478 | } |
@@ -497,6 +488,67 @@ S32 LLComboBox::getCurrentIndex() const | |||
497 | } | 488 | } |
498 | 489 | ||
499 | 490 | ||
491 | void LLComboBox::updateLayout() | ||
492 | { | ||
493 | LLRect rect = getLocalRect(); | ||
494 | if (mAllowTextEntry) | ||
495 | { | ||
496 | S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
497 | mButton->setRect(LLRect( mRect.getWidth() - llmax(8,mArrowImage->getWidth(0)) - 2 * shadow_size, | ||
498 | rect.mTop, rect.mRight, rect.mBottom)); | ||
499 | mButton->setTabStop(FALSE); | ||
500 | |||
501 | if (!mTextEntry) | ||
502 | { | ||
503 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | ||
504 | text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
505 | // clear label on button | ||
506 | LLString cur_label = mButton->getLabelSelected(); | ||
507 | mTextEntry = new LLLineEditor("combo_text_entry", | ||
508 | text_entry_rect, | ||
509 | "", | ||
510 | LLFontGL::sSansSerifSmall, | ||
511 | mMaxChars, | ||
512 | onTextCommit, | ||
513 | onTextEntry, | ||
514 | NULL, | ||
515 | this, | ||
516 | NULL, // prevalidate func | ||
517 | LLViewBorder::BEVEL_NONE, | ||
518 | LLViewBorder::STYLE_LINE, | ||
519 | 0); // no border | ||
520 | mTextEntry->setSelectAllonFocusReceived(TRUE); | ||
521 | mTextEntry->setHandleEditKeysDirectly(TRUE); | ||
522 | mTextEntry->setCommitOnFocusLost(FALSE); | ||
523 | mTextEntry->setText(cur_label); | ||
524 | mTextEntry->setIgnoreTab(TRUE); | ||
525 | mTextEntry->setFollowsAll(); | ||
526 | addChild(mTextEntry); | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | mTextEntry->setVisible(TRUE); | ||
531 | mTextEntry->setMaxTextLength(mMaxChars); | ||
532 | } | ||
533 | |||
534 | // clear label on button | ||
535 | setLabel(LLString::null); | ||
536 | |||
537 | mButton->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP | FOLLOWS_RIGHT); | ||
538 | } | ||
539 | else if (!mAllowTextEntry) | ||
540 | { | ||
541 | mButton->setRect(rect); | ||
542 | mButton->setTabStop(TRUE); | ||
543 | |||
544 | if (mTextEntry) | ||
545 | { | ||
546 | mTextEntry->setVisible(FALSE); | ||
547 | } | ||
548 | mButton->setFollowsAll(); | ||
549 | } | ||
550 | } | ||
551 | |||
500 | void* LLComboBox::getCurrentUserdata() | 552 | void* LLComboBox::getCurrentUserdata() |
501 | { | 553 | { |
502 | LLScrollListItem* item = mList->getFirstSelected(); | 554 | LLScrollListItem* item = mList->getFirstSelected(); |
@@ -514,7 +566,7 @@ void LLComboBox::showList() | |||
514 | LLCoordWindow window_size; | 566 | LLCoordWindow window_size; |
515 | getWindow()->getSize(&window_size); | 567 | getWindow()->getSize(&window_size); |
516 | //HACK: shouldn't have to know about scale here | 568 | //HACK: shouldn't have to know about scale here |
517 | mList->arrange( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); | 569 | mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); |
518 | 570 | ||
519 | // Make sure that we can see the whole list | 571 | // Make sure that we can see the whole list |
520 | LLRect root_view_local; | 572 | LLRect root_view_local; |
@@ -523,7 +575,9 @@ void LLComboBox::showList() | |||
523 | 575 | ||
524 | LLRect rect = mList->getRect(); | 576 | LLRect rect = mList->getRect(); |
525 | 577 | ||
526 | S32 list_width = mRect.getWidth() + SCROLLBAR_SIZE; | 578 | S32 min_width = mRect.getWidth(); |
579 | S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); | ||
580 | S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); | ||
527 | 581 | ||
528 | if (mListPosition == BELOW) | 582 | if (mListPosition == BELOW) |
529 | { | 583 | { |
@@ -583,12 +637,6 @@ void LLComboBox::showList() | |||
583 | mList->translate(0, -y); | 637 | mList->translate(0, -y); |
584 | } | 638 | } |
585 | 639 | ||
586 | // pass mouse capture on to list if button is depressed | ||
587 | if (mButton->hasMouseCapture()) | ||
588 | { | ||
589 | gFocusMgr.setMouseCapture(mList); | ||
590 | } | ||
591 | |||
592 | // NB: this call will trigger the focuslost callback which will hide the list, so do it first | 640 | // NB: this call will trigger the focuslost callback which will hide the list, so do it first |
593 | // before finally showing the list | 641 | // before finally showing the list |
594 | 642 | ||
@@ -604,24 +652,29 @@ void LLComboBox::showList() | |||
604 | mButton->setToggleState(TRUE); | 652 | mButton->setToggleState(TRUE); |
605 | mList->setVisible(TRUE); | 653 | mList->setVisible(TRUE); |
606 | 654 | ||
607 | gFocusMgr.setTopCtrl(mList); | 655 | setUseBoundingRect(TRUE); |
656 | gFocusMgr.setTopCtrl(this); | ||
608 | } | 657 | } |
609 | 658 | ||
610 | void LLComboBox::hideList() | 659 | void LLComboBox::hideList() |
611 | { | 660 | { |
661 | //*HACK: store the original value explicitly somewhere, not just in label | ||
662 | LLString orig_selection = mAllowTextEntry ? mTextEntry->getText() : mButton->getLabelSelected(); | ||
663 | |||
664 | // assert selection in list | ||
665 | mList->selectItemByLabel(orig_selection, FALSE); | ||
666 | |||
612 | mButton->setToggleState(FALSE); | 667 | mButton->setToggleState(FALSE); |
613 | mList->setVisible(FALSE); | 668 | mList->setVisible(FALSE); |
614 | mList->highlightNthItem(-1); | 669 | mList->highlightNthItem(-1); |
615 | 670 | ||
616 | if( gFocusMgr.getTopCtrl() == mList ) | 671 | setUseBoundingRect(FALSE); |
672 | if( gFocusMgr.getTopCtrl() == this ) | ||
617 | { | 673 | { |
618 | gFocusMgr.setTopCtrl(NULL); | 674 | gFocusMgr.setTopCtrl(NULL); |
619 | } | 675 | } |
620 | |||
621 | //mList->setFocus(FALSE); | ||
622 | } | 676 | } |
623 | 677 | ||
624 | |||
625 | //------------------------------------------------------------------ | 678 | //------------------------------------------------------------------ |
626 | // static functions | 679 | // static functions |
627 | //------------------------------------------------------------------ | 680 | //------------------------------------------------------------------ |
@@ -650,21 +703,20 @@ void LLComboBox::onButtonDown(void *userdata) | |||
650 | self->showList(); | 703 | self->showList(); |
651 | } | 704 | } |
652 | 705 | ||
653 | if (self->mKeyboardFocusOnClick && !self->hasFocus()) | 706 | self->setFocus( TRUE ); |
707 | |||
708 | // pass mouse capture on to list if button is depressed | ||
709 | if (self->mButton->hasMouseCapture()) | ||
654 | { | 710 | { |
655 | self->setFocus( TRUE ); | 711 | gFocusMgr.setMouseCapture(self->mList); |
656 | } | 712 | } |
657 | } | 713 | } |
658 | else | 714 | else |
659 | { | 715 | { |
660 | // hide and release keyboard focus | ||
661 | self->hideList(); | 716 | self->hideList(); |
662 | |||
663 | self->onCommit(); | ||
664 | } | 717 | } |
665 | } | ||
666 | |||
667 | 718 | ||
719 | } | ||
668 | 720 | ||
669 | // static | 721 | // static |
670 | void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) | 722 | void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) |
@@ -672,7 +724,7 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) | |||
672 | // Note: item is the LLScrollListCtrl | 724 | // Note: item is the LLScrollListCtrl |
673 | LLComboBox *self = (LLComboBox *) userdata; | 725 | LLComboBox *self = (LLComboBox *) userdata; |
674 | 726 | ||
675 | const LLString& name = self->mList->getSimpleSelectedItem(); | 727 | const LLString name = self->mList->getSelectedItemLabel(); |
676 | 728 | ||
677 | S32 cur_id = self->getCurrentIndex(); | 729 | S32 cur_id = self->getCurrentIndex(); |
678 | if (cur_id != -1) | 730 | if (cur_id != -1) |
@@ -681,40 +733,24 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) | |||
681 | 733 | ||
682 | if (self->mAllowTextEntry) | 734 | if (self->mAllowTextEntry) |
683 | { | 735 | { |
684 | gFocusMgr.setKeyboardFocus(self->mTextEntry, NULL); | 736 | gFocusMgr.setKeyboardFocus(self->mTextEntry); |
685 | self->mTextEntry->selectAll(); | 737 | self->mTextEntry->selectAll(); |
686 | } | 738 | } |
687 | } | 739 | } |
688 | else | 740 | else |
689 | { | 741 | { |
690 | // invalid selection, just restore existing value | 742 | // invalid selection, just restore existing value |
691 | self->mList->selectSimpleItem(self->mButton->getLabelSelected()); | 743 | LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); |
744 | |||
745 | self->mList->selectItemByLabel(orig_selection); | ||
692 | } | 746 | } |
693 | self->onCommit(); | 747 | self->onCommit(); |
694 | 748 | ||
695 | self->hideList(); | 749 | self->hideList(); |
696 | } | 750 | } |
697 | 751 | ||
698 | // static | ||
699 | void LLComboBox::onListFocusChanged(LLUICtrl* list, void* user_data) | ||
700 | { | ||
701 | LLComboBox *self = (LLComboBox *) list->getParent(); | ||
702 | // user not manipulating list or clicking on drop down button | ||
703 | if (!self->mList->hasFocus() && !self->mButton->hasMouseCapture()) | ||
704 | { | ||
705 | //*HACK: store the original value explicitly somewhere, not just in label | ||
706 | LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); | ||
707 | |||
708 | self->hideList(); | ||
709 | |||
710 | // reassert original selection | ||
711 | self->mList->selectSimpleItem(orig_selection, FALSE); | ||
712 | } | ||
713 | } | ||
714 | |||
715 | BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) | 752 | BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) |
716 | { | 753 | { |
717 | |||
718 | LLString tool_tip; | 754 | LLString tool_tip; |
719 | 755 | ||
720 | if (LLUI::sShowXUINames) | 756 | if (LLUI::sShowXUINames) |
@@ -726,23 +762,19 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_ | |||
726 | tool_tip = mToolTipMsg; | 762 | tool_tip = mToolTipMsg; |
727 | } | 763 | } |
728 | 764 | ||
729 | if( getVisible() && pointInView( x, y ) ) | 765 | if( !tool_tip.empty() ) |
730 | { | 766 | { |
731 | if( !tool_tip.empty() ) | 767 | msg = tool_tip; |
732 | { | 768 | |
733 | msg = tool_tip; | 769 | // Convert rect local to screen coordinates |
734 | 770 | localPointToScreen( | |
735 | // Convert rect local to screen coordinates | 771 | 0, 0, |
736 | localPointToScreen( | 772 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); |
737 | 0, 0, | 773 | localPointToScreen( |
738 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); | 774 | mRect.getWidth(), mRect.getHeight(), |
739 | localPointToScreen( | 775 | &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); |
740 | mRect.getWidth(), mRect.getHeight(), | ||
741 | &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); | ||
742 | } | ||
743 | return TRUE; | ||
744 | } | 776 | } |
745 | return FALSE; | 777 | return TRUE; |
746 | } | 778 | } |
747 | 779 | ||
748 | BOOL LLComboBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | 780 | BOOL LLComboBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) |
@@ -793,63 +825,11 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent | |||
793 | 825 | ||
794 | void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative) | 826 | void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative) |
795 | { | 827 | { |
796 | LLRect rect( 0, mRect.getHeight(), mRect.getWidth(), 0); | ||
797 | if (allow && !mAllowTextEntry) | ||
798 | { | ||
799 | S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
800 | mButton->setRect(LLRect( mRect.getWidth() - mArrowImageWidth - 2 * shadow_size, | ||
801 | rect.mTop, rect.mRight, rect.mBottom)); | ||
802 | mButton->setTabStop(FALSE); | ||
803 | |||
804 | // clear label on button | ||
805 | LLString cur_label = mButton->getLabelSelected(); | ||
806 | setLabel(LLString::null); | ||
807 | if (!mTextEntry) | ||
808 | { | ||
809 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | ||
810 | text_entry_rect.mRight -= mArrowImageWidth + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
811 | mTextEntry = new LLLineEditor("combo_text_entry", | ||
812 | text_entry_rect, | ||
813 | "", | ||
814 | LLFontGL::sSansSerifSmall, | ||
815 | max_chars, | ||
816 | onTextCommit, | ||
817 | onTextEntry, | ||
818 | NULL, | ||
819 | this, | ||
820 | NULL, // prevalidate func | ||
821 | LLViewBorder::BEVEL_NONE, | ||
822 | LLViewBorder::STYLE_LINE, | ||
823 | 0); // no border | ||
824 | mTextEntry->setSelectAllonFocusReceived(TRUE); | ||
825 | mTextEntry->setHandleEditKeysDirectly(TRUE); | ||
826 | mTextEntry->setCommitOnFocusLost(FALSE); | ||
827 | mTextEntry->setText(cur_label); | ||
828 | mTextEntry->setIgnoreTab(TRUE); | ||
829 | mTextEntry->setFollowsAll(); | ||
830 | addChild(mTextEntry); | ||
831 | mMaxChars = max_chars; | ||
832 | } | ||
833 | else | ||
834 | { | ||
835 | mTextEntry->setVisible(TRUE); | ||
836 | } | ||
837 | |||
838 | mButton->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP | FOLLOWS_RIGHT); | ||
839 | } | ||
840 | else if (!allow && mAllowTextEntry) | ||
841 | { | ||
842 | mButton->setRect(rect); | ||
843 | mButton->setTabStop(TRUE); | ||
844 | |||
845 | if (mTextEntry) | ||
846 | { | ||
847 | mTextEntry->setVisible(FALSE); | ||
848 | } | ||
849 | mButton->setFollowsAll(); | ||
850 | } | ||
851 | mAllowTextEntry = allow; | 828 | mAllowTextEntry = allow; |
852 | mTextEntryTentative = set_tentative; | 829 | mTextEntryTentative = set_tentative; |
830 | mMaxChars = max_chars; | ||
831 | |||
832 | updateLayout(); | ||
853 | } | 833 | } |
854 | 834 | ||
855 | void LLComboBox::setTextEntry(const LLStringExplicit& text) | 835 | void LLComboBox::setTextEntry(const LLStringExplicit& text) |
@@ -875,7 +855,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data) | |||
875 | if (key == KEY_BACKSPACE || | 855 | if (key == KEY_BACKSPACE || |
876 | key == KEY_DELETE) | 856 | key == KEY_DELETE) |
877 | { | 857 | { |
878 | if (self->mList->selectSimpleItem(line_editor->getText(), FALSE)) | 858 | if (self->mList->selectItemByLabel(line_editor->getText(), FALSE)) |
879 | { | 859 | { |
880 | line_editor->setTentative(FALSE); | 860 | line_editor->setTentative(FALSE); |
881 | } | 861 | } |
@@ -955,11 +935,11 @@ void LLComboBox::updateSelection() | |||
955 | } | 935 | } |
956 | } | 936 | } |
957 | 937 | ||
958 | if (mList->selectSimpleItem(full_string, FALSE)) | 938 | if (mList->selectItemByLabel(full_string, FALSE)) |
959 | { | 939 | { |
960 | mTextEntry->setTentative(FALSE); | 940 | mTextEntry->setTentative(FALSE); |
961 | } | 941 | } |
962 | else if (!mList->selectSimpleItemByPrefix(left_wstring, FALSE)) | 942 | else if (!mList->selectItemByPrefix(left_wstring, FALSE)) |
963 | { | 943 | { |
964 | mList->deselectAllItems(); | 944 | mList->deselectAllItems(); |
965 | mTextEntry->setText(wstring_to_utf8str(user_wstring)); | 945 | mTextEntry->setText(wstring_to_utf8str(user_wstring)); |
@@ -967,7 +947,7 @@ void LLComboBox::updateSelection() | |||
967 | } | 947 | } |
968 | else | 948 | else |
969 | { | 949 | { |
970 | LLWString selected_item = utf8str_to_wstring(mList->getSimpleSelectedItem()); | 950 | LLWString selected_item = utf8str_to_wstring(mList->getSelectedItemLabel()); |
971 | LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size()); | 951 | LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size()); |
972 | mTextEntry->setText(wstring_to_utf8str(wtext)); | 952 | mTextEntry->setText(wstring_to_utf8str(wtext)); |
973 | mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size()); | 953 | mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size()); |
@@ -993,6 +973,10 @@ void LLComboBox::setFocus(BOOL b) | |||
993 | if (b) | 973 | if (b) |
994 | { | 974 | { |
995 | mList->clearSearchString(); | 975 | mList->clearSearchString(); |
976 | if (mList->getVisible()) | ||
977 | { | ||
978 | mList->setFocus(TRUE); | ||
979 | } | ||
996 | } | 980 | } |
997 | } | 981 | } |
998 | 982 | ||
@@ -1048,7 +1032,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id) | |||
1048 | 1032 | ||
1049 | if (found) | 1033 | if (found) |
1050 | { | 1034 | { |
1051 | setLabel(mList->getSimpleSelectedItem()); | 1035 | setLabel(mList->getSelectedItemLabel()); |
1052 | } | 1036 | } |
1053 | 1037 | ||
1054 | return found; | 1038 | return found; |
@@ -1063,14 +1047,14 @@ BOOL LLComboBox::setSelectedByValue(LLSD value, BOOL selected) | |||
1063 | BOOL found = mList->setSelectedByValue(value, selected); | 1047 | BOOL found = mList->setSelectedByValue(value, selected); |
1064 | if (found) | 1048 | if (found) |
1065 | { | 1049 | { |
1066 | setLabel(mList->getSimpleSelectedItem()); | 1050 | setLabel(mList->getSelectedItemLabel()); |
1067 | } | 1051 | } |
1068 | return found; | 1052 | return found; |
1069 | } | 1053 | } |
1070 | 1054 | ||
1071 | LLSD LLComboBox::getSimpleSelectedValue() | 1055 | LLSD LLComboBox::getSelectedValue() |
1072 | { | 1056 | { |
1073 | return mList->getSimpleSelectedValue(); | 1057 | return mList->getSelectedValue(); |
1074 | } | 1058 | } |
1075 | 1059 | ||
1076 | BOOL LLComboBox::isSelected(LLSD value) | 1060 | BOOL LLComboBox::isSelected(LLSD value) |
@@ -1097,3 +1081,155 @@ BOOL LLComboBox::operateOnAll(EOperation op) | |||
1097 | } | 1081 | } |
1098 | return FALSE; | 1082 | return FALSE; |
1099 | } | 1083 | } |
1084 | |||
1085 | |||
1086 | |||
1087 | // | ||
1088 | // LLFlyoutButton | ||
1089 | // | ||
1090 | |||
1091 | const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; | ||
1092 | |||
1093 | LLFlyoutButton::LLFlyoutButton( | ||
1094 | const LLString& name, | ||
1095 | const LLRect &rect, | ||
1096 | const LLString& label, | ||
1097 | void (*commit_callback)(LLUICtrl*, void*) , | ||
1098 | void *callback_userdata) | ||
1099 | : LLComboBox(name, rect, LLString::null, commit_callback, callback_userdata), | ||
1100 | mToggleState(FALSE), | ||
1101 | mActionButton(NULL) | ||
1102 | { | ||
1103 | // Always use text box | ||
1104 | // Text label button | ||
1105 | mActionButton = new LLButton("flyout_button_main", | ||
1106 | LLRect(), label, NULL, LLString::null, | ||
1107 | NULL, this); | ||
1108 | mActionButton->setScaleImage(TRUE); | ||
1109 | |||
1110 | mActionButton->setClickedCallback(onActionButtonClick); | ||
1111 | mActionButton->setFollowsAll(); | ||
1112 | mActionButton->setHAlign( LLFontGL::HCENTER ); | ||
1113 | mActionButton->setLabel(label); | ||
1114 | addChild(mActionButton); | ||
1115 | |||
1116 | mActionButtonImage = LLUI::getUIImageByName("flyout_btn_left.tga"); | ||
1117 | mExpanderButtonImage = LLUI::getUIImageByName("flyout_btn_right.tga"); | ||
1118 | mActionButtonImageSelected = LLUI::getUIImageByName("flyout_btn_left_selected.tga"); | ||
1119 | mExpanderButtonImageSelected = LLUI::getUIImageByName("flyout_btn_right_selected.tga"); | ||
1120 | |||
1121 | mActionButton->setImageSelected(mActionButtonImageSelected); | ||
1122 | mActionButton->setImageUnselected(mActionButtonImage); | ||
1123 | mActionButton->setImageDisabled(LLPointer<LLUIImage>(NULL)); | ||
1124 | mActionButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL)); | ||
1125 | |||
1126 | mButton->setImageSelected(mExpanderButtonImageSelected); | ||
1127 | mButton->setImageUnselected(mExpanderButtonImage); | ||
1128 | mButton->setImageDisabled(LLPointer<LLUIImage>(NULL)); | ||
1129 | mButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL)); | ||
1130 | mButton->setRightHPad(6); | ||
1131 | |||
1132 | mBorder->setVisible(FALSE); | ||
1133 | |||
1134 | updateLayout(); | ||
1135 | } | ||
1136 | |||
1137 | //static | ||
1138 | LLView* LLFlyoutButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | ||
1139 | { | ||
1140 | LLString name = "flyout_button"; | ||
1141 | node->getAttributeString("name", name); | ||
1142 | |||
1143 | LLString label(""); | ||
1144 | node->getAttributeString("label", label); | ||
1145 | |||
1146 | LLRect rect; | ||
1147 | createRect(node, rect, parent, LLRect()); | ||
1148 | |||
1149 | LLUICtrlCallback callback = NULL; | ||
1150 | |||
1151 | LLFlyoutButton* flyout_button = new LLFlyoutButton(name, | ||
1152 | rect, | ||
1153 | label, | ||
1154 | callback, | ||
1155 | NULL); | ||
1156 | |||
1157 | LLString list_position; | ||
1158 | node->getAttributeString("list_position", list_position); | ||
1159 | if (list_position == "below") | ||
1160 | { | ||
1161 | flyout_button->mListPosition = BELOW; | ||
1162 | } | ||
1163 | else if (list_position == "above") | ||
1164 | { | ||
1165 | flyout_button->mListPosition = ABOVE; | ||
1166 | } | ||
1167 | |||
1168 | |||
1169 | flyout_button->initFromXML(node, parent); | ||
1170 | |||
1171 | LLXMLNodePtr child; | ||
1172 | for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) | ||
1173 | { | ||
1174 | if (child->hasName("flyout_button_item")) | ||
1175 | { | ||
1176 | LLString label = child->getTextContents(); | ||
1177 | |||
1178 | LLString value = label; | ||
1179 | child->getAttributeString("value", value); | ||
1180 | |||
1181 | flyout_button->add(label, LLSD(value) ); | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | flyout_button->updateLayout(); | ||
1186 | |||
1187 | return flyout_button; | ||
1188 | } | ||
1189 | |||
1190 | void LLFlyoutButton::updateLayout() | ||
1191 | { | ||
1192 | LLComboBox::updateLayout(); | ||
1193 | |||
1194 | mButton->setOrigin(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); | ||
1195 | mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); | ||
1196 | mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); | ||
1197 | mButton->setTabStop(FALSE); | ||
1198 | mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); | ||
1199 | |||
1200 | mActionButton->setOrigin(0, 0); | ||
1201 | mActionButton->reshape(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); | ||
1202 | } | ||
1203 | |||
1204 | //static | ||
1205 | void LLFlyoutButton::onActionButtonClick(void *user_data) | ||
1206 | { | ||
1207 | LLFlyoutButton* buttonp = (LLFlyoutButton*)user_data; | ||
1208 | // remember last list selection? | ||
1209 | buttonp->mList->deselect(); | ||
1210 | buttonp->onCommit(); | ||
1211 | } | ||
1212 | |||
1213 | void LLFlyoutButton::draw() | ||
1214 | { | ||
1215 | mActionButton->setToggleState(mToggleState); | ||
1216 | mButton->setToggleState(mToggleState); | ||
1217 | |||
1218 | //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or | ||
1219 | // the label reflects the last selected item, for now we have to manually remove the label | ||
1220 | mButton->setLabel(LLString::null); | ||
1221 | LLComboBox::draw(); | ||
1222 | } | ||
1223 | |||
1224 | void LLFlyoutButton::setEnabled(BOOL enabled) | ||
1225 | { | ||
1226 | mActionButton->setEnabled(enabled); | ||
1227 | LLComboBox::setEnabled(enabled); | ||
1228 | } | ||
1229 | |||
1230 | |||
1231 | void LLFlyoutButton::setToggleState(BOOL state) | ||
1232 | { | ||
1233 | mToggleState = state; | ||
1234 | } | ||
1235 | |||