diff options
author | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
commit | b2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch) | |
tree | 3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/llui/llcombobox.cpp | |
parent | Second Life viewer sources 1.14.0.1 (diff) | |
download | meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.zip meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.gz meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.bz2 meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.xz |
Second Life viewer sources 1.15.0.2
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llui/llcombobox.cpp | 292 |
1 files changed, 107 insertions, 185 deletions
diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index 7c3755a..983dd43 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp | |||
@@ -4,6 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | 5 | * Copyright (c) 2001-2007, Linden Research, Inc. |
6 | * | 6 | * |
7 | * Second Life Viewer Source Code | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | 8 | * The source code in this file ("Source Code") is provided by Linden Lab |
8 | * to you under the terms of the GNU General Public License, version 2.0 | 9 | * to you under the terms of the GNU General Public License, version 2.0 |
9 | * ("GPL"), unless you have obtained a separate licensing agreement | 10 | * ("GPL"), unless you have obtained a separate licensing agreement |
@@ -59,7 +60,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
59 | ) | 60 | ) |
60 | : LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata, | 61 | : LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata, |
61 | FOLLOWS_LEFT | FOLLOWS_TOP), | 62 | FOLLOWS_LEFT | FOLLOWS_TOP), |
62 | mDrawButton(TRUE), | 63 | mDrawArrow(TRUE), |
63 | mTextEntry(NULL), | 64 | mTextEntry(NULL), |
64 | mArrowImage(NULL), | 65 | mArrowImage(NULL), |
65 | mArrowImageWidth(8), | 66 | mArrowImageWidth(8), |
@@ -67,8 +68,8 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
67 | mMaxChars(20), | 68 | mMaxChars(20), |
68 | mTextEntryTentative(TRUE), | 69 | mTextEntryTentative(TRUE), |
69 | mPrearrangeCallback( NULL ), | 70 | mPrearrangeCallback( NULL ), |
70 | mTextEntryCallback( NULL ), | 71 | mListPosition(BELOW), |
71 | mListWidth(list_width) | 72 | mTextEntryCallback( NULL ) |
72 | { | 73 | { |
73 | // For now, all comboboxes don't take keyboard focus when clicked. | 74 | // For now, all comboboxes don't take keyboard focus when clicked. |
74 | // This might change if it is part of a modal dialog. | 75 | // This might change if it is part of a modal dialog. |
@@ -76,7 +77,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
76 | 77 | ||
77 | // Revert to standard behavior. When this control's parent is hidden, it needs to | 78 | // Revert to standard behavior. When this control's parent is hidden, it needs to |
78 | // hide this ctrl--which won't just happen automatically since when LLComboBox is | 79 | // hide this ctrl--which won't just happen automatically since when LLComboBox is |
79 | // showing its list, it's also set to TopView. When keyboard focus is cleared all | 80 | // showing its list, it's also set to TopCtrl. When keyboard focus is cleared all |
80 | // controls (including this one) know that they are no longer editing. | 81 | // controls (including this one) know that they are no longer editing. |
81 | mKeyboardFocusOnClick = TRUE; | 82 | mKeyboardFocusOnClick = TRUE; |
82 | 83 | ||
@@ -87,7 +88,8 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
87 | // Text label button | 88 | // Text label button |
88 | mButton = new LLSquareButton("comboxbox button", | 89 | mButton = new LLSquareButton("comboxbox button", |
89 | r, label, NULL, LLString::null, | 90 | r, label, NULL, LLString::null, |
90 | &LLComboBox::onButtonClick, this); | 91 | NULL, this); |
92 | mButton->setMouseDownCallback(onButtonDown); | ||
91 | mButton->setFont(LLFontGL::sSansSerifSmall); | 93 | mButton->setFont(LLFontGL::sSansSerifSmall); |
92 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); | 94 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); |
93 | mButton->setHAlign( LLFontGL::LEFT ); | 95 | mButton->setHAlign( LLFontGL::LEFT ); |
@@ -110,6 +112,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
110 | mList->setVisible(FALSE); | 112 | mList->setVisible(FALSE); |
111 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); | 113 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); |
112 | mList->setCommitOnKeyboardMovement(FALSE); | 114 | mList->setCommitOnKeyboardMovement(FALSE); |
115 | mList->setFocusChangedCallback(onListFocusChanged); | ||
113 | addChild(mList); | 116 | addChild(mList); |
114 | 117 | ||
115 | LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | 118 | LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); |
@@ -119,7 +122,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
119 | 122 | ||
120 | LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") ); | 123 | LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") ); |
121 | mArrowImage = LLUI::sImageProvider->getUIImageByID(arrow_image_id); | 124 | mArrowImage = LLUI::sImageProvider->getUIImageByID(arrow_image_id); |
122 | mArrowImageWidth = llmax(8,mArrowImage->getWidth()); // In case image hasn't loaded yet | 125 | mArrowImageWidth = llmax(8,mArrowImage->getWidth(0)); // In case image hasn't loaded yet |
123 | } | 126 | } |
124 | 127 | ||
125 | 128 | ||
@@ -219,115 +222,10 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * | |||
219 | 222 | ||
220 | void LLComboBox::setEnabled(BOOL enabled) | 223 | void LLComboBox::setEnabled(BOOL enabled) |
221 | { | 224 | { |
222 | LLUICtrl::setEnabled(enabled); | 225 | LLView::setEnabled(enabled); |
223 | mButton->setEnabled(enabled); | 226 | mButton->setEnabled(enabled); |
224 | } | 227 | } |
225 | 228 | ||
226 | // *HACK: these are all hacks to support the fact that the combobox | ||
227 | // has mouse capture so we can hide the list when we don't handle the | ||
228 | // mouse up event | ||
229 | BOOL LLComboBox::handleHover(S32 x, S32 y, MASK mask) | ||
230 | { | ||
231 | if (mList->getVisible()) | ||
232 | { | ||
233 | S32 local_x, local_y; | ||
234 | LLView::localPointToOtherView(x, y, &local_x, &local_y, mList); | ||
235 | if (mList->pointInView(local_x, local_y)) | ||
236 | { | ||
237 | return mList->handleHover(local_x, local_y, mask); | ||
238 | } | ||
239 | } | ||
240 | return LLUICtrl::handleHover(x, y, mask); | ||
241 | } | ||
242 | |||
243 | BOOL LLComboBox::handleMouseDown(S32 x, S32 y, MASK mask) | ||
244 | { | ||
245 | if (mList->getVisible()) | ||
246 | { | ||
247 | S32 local_x, local_y; | ||
248 | LLView::localPointToOtherView(x, y, &local_x, &local_y, mList); | ||
249 | if (mList->pointInView(local_x, local_y)) | ||
250 | { | ||
251 | return mList->handleMouseDown(local_x, local_y, mask); | ||
252 | } | ||
253 | } | ||
254 | BOOL has_focus_now = hasFocus(); | ||
255 | BOOL handled = LLUICtrl::handleMouseDown(x, y, mask); | ||
256 | if (handled && !has_focus_now) | ||
257 | { | ||
258 | onFocusReceived(); | ||
259 | } | ||
260 | |||
261 | return handled; | ||
262 | } | ||
263 | |||
264 | BOOL LLComboBox::handleRightMouseDown(S32 x, S32 y, MASK mask) | ||
265 | { | ||
266 | if (mList->getVisible()) | ||
267 | { | ||
268 | S32 local_x, local_y; | ||
269 | LLView::localPointToOtherView(x, y, &local_x, &local_y, mList); | ||
270 | if (mList->pointInView(local_x, local_y)) | ||
271 | { | ||
272 | return mList->handleRightMouseDown(local_x, local_y, mask); | ||
273 | } | ||
274 | } | ||
275 | return LLUICtrl::handleRightMouseDown(x, y, mask); | ||
276 | } | ||
277 | |||
278 | BOOL LLComboBox::handleRightMouseUp(S32 x, S32 y, MASK mask) | ||
279 | { | ||
280 | if (mList->getVisible()) | ||
281 | { | ||
282 | S32 local_x, local_y; | ||
283 | LLView::localPointToOtherView(x, y, &local_x, &local_y, mList); | ||
284 | if (mList->pointInView(local_x, local_y)) | ||
285 | { | ||
286 | return mList->handleRightMouseUp(local_x, local_y, mask); | ||
287 | } | ||
288 | } | ||
289 | return LLUICtrl::handleRightMouseUp(x, y, mask); | ||
290 | } | ||
291 | |||
292 | BOOL LLComboBox::handleDoubleClick(S32 x, S32 y, MASK mask) | ||
293 | { | ||
294 | if (mList->getVisible()) | ||
295 | { | ||
296 | S32 local_x, local_y; | ||
297 | LLView::localPointToOtherView(x, y, &local_x, &local_y, mList); | ||
298 | if (mList->pointInView(local_x, local_y)) | ||
299 | { | ||
300 | return mList->handleDoubleClick(local_x, local_y, mask); | ||
301 | } | ||
302 | } | ||
303 | return LLUICtrl::handleDoubleClick(x, y, mask); | ||
304 | } | ||
305 | |||
306 | BOOL LLComboBox::handleMouseUp(S32 x, S32 y, MASK mask) | ||
307 | { | ||
308 | BOOL handled = childrenHandleMouseUp(x, y, mask) != NULL; | ||
309 | |||
310 | if (!handled && mList->getVisible()) | ||
311 | { | ||
312 | S32 local_x, local_y; | ||
313 | LLView::localPointToOtherView(x, y, &local_x, &local_y, mList); | ||
314 | if (mList->pointInView(local_x, local_y)) | ||
315 | { | ||
316 | handled = mList->handleMouseUp(local_x, local_y, mask); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | if( !handled && gFocusMgr.getMouseCapture() == this ) | ||
321 | { | ||
322 | // Mouse events that we didn't handle cause the list to be hidden. | ||
323 | // Eat mouse event, regardless of where on the screen it happens. | ||
324 | hideList(); | ||
325 | handled = TRUE; | ||
326 | } | ||
327 | |||
328 | return handled; | ||
329 | } | ||
330 | |||
331 | void LLComboBox::clear() | 229 | void LLComboBox::clear() |
332 | { | 230 | { |
333 | if (mTextEntry) | 231 | if (mTextEntry) |
@@ -512,12 +410,13 @@ void LLComboBox::onFocusLost() | |||
512 | { | 410 | { |
513 | mTextEntry->selectAll(); | 411 | mTextEntry->selectAll(); |
514 | } | 412 | } |
413 | LLUICtrl::onFocusLost(); | ||
515 | } | 414 | } |
516 | 415 | ||
517 | void LLComboBox::setButtonVisible(BOOL visible) | 416 | void LLComboBox::setButtonVisible(BOOL visible) |
518 | { | 417 | { |
519 | mButton->setVisible(visible); | 418 | mButton->setVisible(visible); |
520 | mDrawButton = visible; | 419 | mDrawArrow = visible; |
521 | if (mTextEntry) | 420 | if (mTextEntry) |
522 | { | 421 | { |
523 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | 422 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); |
@@ -541,15 +440,17 @@ void LLComboBox::draw() | |||
541 | // Draw children | 440 | // Draw children |
542 | LLUICtrl::draw(); | 441 | LLUICtrl::draw(); |
543 | 442 | ||
544 | if (mDrawButton) | 443 | if (mDrawArrow) |
545 | { | 444 | { |
546 | // Paste the graphic on the right edge | 445 | // Paste the graphic on the right edge |
547 | if (!mArrowImage.isNull()) | 446 | if (!mArrowImage.isNull()) |
548 | { | 447 | { |
549 | S32 left = mRect.getWidth() - mArrowImageWidth - LLUI::sConfigGroup->getS32("DropShadowButton"); | 448 | S32 arrow_height = llmin(mRect.getHeight(), mArrowImage->getHeight()); |
449 | S32 arrow_width = llround((F32)mArrowImage->getWidth() * ((F32)arrow_height / (F32)mArrowImage->getHeight())); | ||
450 | |||
451 | S32 left = mRect.getWidth() - mArrowImage->getWidth() - LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
550 | 452 | ||
551 | gl_draw_image( left, 0, mArrowImage, | 453 | gl_draw_scaled_image( left, 0, arrow_width, arrow_height, mArrowImage, LLColor4::white); |
552 | LLColor4::white); | ||
553 | } | 454 | } |
554 | } | 455 | } |
555 | } | 456 | } |
@@ -595,18 +496,61 @@ void LLComboBox::showList() | |||
595 | //HACK: shouldn't have to know about scale here | 496 | //HACK: shouldn't have to know about scale here |
596 | mList->arrange( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); | 497 | mList->arrange( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); |
597 | 498 | ||
598 | // Move rect so it hangs off the bottom of this view | 499 | // Make sure that we can see the whole list |
500 | LLRect root_view_local; | ||
501 | LLView* root_view = getRootView(); | ||
502 | root_view->localRectToOtherView(root_view->getLocalRect(), &root_view_local, this); | ||
503 | |||
599 | LLRect rect = mList->getRect(); | 504 | LLRect rect = mList->getRect(); |
600 | 505 | ||
601 | rect.setLeftTopAndSize(0, 0, rect.getWidth(), rect.getHeight() ); | 506 | if (mListPosition == BELOW) |
602 | mList->setRect(rect); | 507 | { |
508 | if (rect.getHeight() <= -root_view_local.mBottom) | ||
509 | { | ||
510 | // Move rect so it hangs off the bottom of this view | ||
511 | rect.setLeftTopAndSize(0, 0, rect.getWidth(), rect.getHeight() ); | ||
512 | } | ||
513 | else | ||
514 | { | ||
515 | // stack on top or bottom, depending on which has more room | ||
516 | if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) | ||
517 | { | ||
518 | // Move rect so it hangs off the bottom of this view | ||
519 | rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight())); | ||
520 | } | ||
521 | else | ||
522 | { | ||
523 | // move rect so it stacks on top of this view (clipped to size of screen) | ||
524 | rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); | ||
525 | } | ||
526 | } | ||
527 | } | ||
528 | else // ABOVE | ||
529 | { | ||
530 | if (rect.getHeight() <= root_view_local.mTop - mRect.getHeight()) | ||
531 | { | ||
532 | // move rect so it stacks on top of this view (clipped to size of screen) | ||
533 | rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); | ||
534 | } | ||
535 | else | ||
536 | { | ||
537 | // stack on top or bottom, depending on which has more room | ||
538 | if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) | ||
539 | { | ||
540 | // Move rect so it hangs off the bottom of this view | ||
541 | rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight())); | ||
542 | } | ||
543 | else | ||
544 | { | ||
545 | // move rect so it stacks on top of this view (clipped to size of screen) | ||
546 | rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); | ||
547 | } | ||
548 | } | ||
603 | 549 | ||
604 | // Make sure that we can see the whole list | 550 | } |
605 | LLRect floater_area_screen; | 551 | mList->setOrigin(rect.mLeft, rect.mBottom); |
606 | LLRect floater_area_local; | 552 | mList->reshape(rect.getWidth(), rect.getHeight()); |
607 | gFloaterView->getParent()->localRectToScreen( gFloaterView->getRect(), &floater_area_screen ); | 553 | mList->translateIntoRect(root_view_local, FALSE); |
608 | screenRectToLocal( floater_area_screen, &floater_area_local ); | ||
609 | mList->translateIntoRect( floater_area_local, FALSE ); | ||
610 | 554 | ||
611 | // Make sure we didn't go off bottom of screen | 555 | // Make sure we didn't go off bottom of screen |
612 | S32 x, y; | 556 | S32 x, y; |
@@ -617,7 +561,12 @@ void LLComboBox::showList() | |||
617 | mList->translate(0, -y); | 561 | mList->translate(0, -y); |
618 | } | 562 | } |
619 | 563 | ||
620 | gFocusMgr.setMouseCapture( this, LLComboBox::onMouseCaptureLost ); | 564 | // pass mouse capture on to list if button is depressed |
565 | if (mButton->hasMouseCapture()) | ||
566 | { | ||
567 | gFocusMgr.setMouseCapture(mList); | ||
568 | } | ||
569 | |||
621 | // NB: this call will trigger the focuslost callback which will hide the list, so do it first | 570 | // NB: this call will trigger the focuslost callback which will hide the list, so do it first |
622 | // before finally showing the list | 571 | // before finally showing the list |
623 | 572 | ||
@@ -627,14 +576,13 @@ void LLComboBox::showList() | |||
627 | // so that the callback is not immediately triggered on setFocus() | 576 | // so that the callback is not immediately triggered on setFocus() |
628 | mList->selectFirstItem(); | 577 | mList->selectFirstItem(); |
629 | } | 578 | } |
630 | gFocusMgr.setKeyboardFocus(mList, onListFocusLost); | 579 | mList->setFocus(TRUE); |
631 | 580 | ||
632 | // Show the list and push the button down | 581 | // Show the list and push the button down |
633 | mButton->setToggleState(TRUE); | 582 | mButton->setToggleState(TRUE); |
634 | mList->setVisible(TRUE); | 583 | mList->setVisible(TRUE); |
635 | 584 | ||
636 | gFocusMgr.setTopView(mList, LLComboBox::onTopViewLost ); | 585 | gFocusMgr.setTopCtrl(mList); |
637 | |||
638 | } | 586 | } |
639 | 587 | ||
640 | void LLComboBox::hideList() | 588 | void LLComboBox::hideList() |
@@ -643,37 +591,21 @@ void LLComboBox::hideList() | |||
643 | mList->setVisible(FALSE); | 591 | mList->setVisible(FALSE); |
644 | mList->highlightNthItem(-1); | 592 | mList->highlightNthItem(-1); |
645 | 593 | ||
646 | if( gFocusMgr.getTopView() == mList ) | 594 | if( gFocusMgr.getTopCtrl() == mList ) |
647 | { | ||
648 | gFocusMgr.setTopView(NULL, NULL); | ||
649 | } | ||
650 | |||
651 | if( gFocusMgr.getMouseCapture() == this ) | ||
652 | { | 595 | { |
653 | gFocusMgr.setMouseCapture( NULL, NULL ); | 596 | gFocusMgr.setTopCtrl(NULL); |
654 | } | 597 | } |
655 | 598 | ||
656 | if( gFocusMgr.getKeyboardFocus() == mList ) | 599 | //mList->setFocus(FALSE); |
657 | { | ||
658 | if (mAllowTextEntry) | ||
659 | { | ||
660 | mTextEntry->setFocus(TRUE); | ||
661 | } | ||
662 | else | ||
663 | { | ||
664 | setFocus(TRUE); | ||
665 | } | ||
666 | } | ||
667 | } | 600 | } |
668 | 601 | ||
669 | 602 | ||
670 | |||
671 | //------------------------------------------------------------------ | 603 | //------------------------------------------------------------------ |
672 | // static functions | 604 | // static functions |
673 | //------------------------------------------------------------------ | 605 | //------------------------------------------------------------------ |
674 | 606 | ||
675 | // static | 607 | // static |
676 | void LLComboBox::onButtonClick(void *userdata) | 608 | void LLComboBox::onButtonDown(void *userdata) |
677 | { | 609 | { |
678 | LLComboBox *self = (LLComboBox *)userdata; | 610 | LLComboBox *self = (LLComboBox *)userdata; |
679 | 611 | ||
@@ -720,50 +652,47 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) | |||
720 | 652 | ||
721 | const LLString& name = self->mList->getSimpleSelectedItem(); | 653 | const LLString& name = self->mList->getSimpleSelectedItem(); |
722 | 654 | ||
723 | self->hideList(); | ||
724 | |||
725 | S32 cur_id = self->getCurrentIndex(); | 655 | S32 cur_id = self->getCurrentIndex(); |
726 | if (cur_id != -1) | 656 | if (cur_id != -1) |
727 | { | 657 | { |
728 | self->setLabel(self->mList->getSimpleSelectedItem()); | 658 | self->setLabel(name); |
729 | 659 | ||
730 | if (self->mAllowTextEntry) | 660 | if (self->mAllowTextEntry) |
731 | { | 661 | { |
732 | self->mTextEntry->setText(name); | ||
733 | self->mTextEntry->setTentative(FALSE); | ||
734 | gFocusMgr.setKeyboardFocus(self->mTextEntry, NULL); | 662 | gFocusMgr.setKeyboardFocus(self->mTextEntry, NULL); |
735 | self->mTextEntry->selectAll(); | 663 | self->mTextEntry->selectAll(); |
736 | } | 664 | } |
737 | else | 665 | } |
738 | { | 666 | else |
739 | self->mButton->setLabelUnselected( name ); | 667 | { |
740 | self->mButton->setLabelSelected( name ); | 668 | // invalid selection, just restore existing value |
741 | self->mButton->setDisabledLabel( name ); | 669 | self->mList->selectSimpleItem(self->mButton->getLabelSelected()); |
742 | self->mButton->setDisabledSelectedLabel( name ); | ||
743 | } | ||
744 | } | 670 | } |
745 | self->onCommit(); | 671 | self->onCommit(); |
746 | } | ||
747 | 672 | ||
748 | // static | ||
749 | void LLComboBox::onTopViewLost(LLView* old_focus) | ||
750 | { | ||
751 | LLComboBox *self = (LLComboBox *) old_focus->getParent(); | ||
752 | self->hideList(); | 673 | self->hideList(); |
753 | } | 674 | } |
754 | 675 | ||
755 | |||
756 | // static | 676 | // static |
757 | void LLComboBox::onMouseCaptureLost(LLMouseHandler*) | 677 | void LLComboBox::onListFocusChanged(LLUICtrl* list, void* user_data) |
758 | { | 678 | { |
759 | // Can't hide the list here. If the list scrolls off the screen, | 679 | LLComboBox *self = (LLComboBox *) list->getParent(); |
760 | // and you click in the arrow buttons of the scroll bar, they must capture | 680 | // user not manipulating list or clicking on drop down button |
761 | // the mouse to handle scrolling-while-mouse-down. | 681 | if (!self->mList->hasFocus() && !self->mButton->hasMouseCapture()) |
682 | { | ||
683 | //*HACK: store the original value explicitly somewhere, not just in label | ||
684 | LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); | ||
685 | |||
686 | self->hideList(); | ||
687 | |||
688 | // reassert original selection | ||
689 | self->mList->selectSimpleItem(orig_selection, FALSE); | ||
690 | } | ||
762 | } | 691 | } |
763 | 692 | ||
764 | BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) | 693 | BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) |
765 | { | 694 | { |
766 | 695 | ||
767 | LLString tool_tip; | 696 | LLString tool_tip; |
768 | 697 | ||
769 | if (LLUI::sShowXUINames) | 698 | if (LLUI::sShowXUINames) |
@@ -875,6 +804,7 @@ void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative | |||
875 | mTextEntry->setCommitOnFocusLost(FALSE); | 804 | mTextEntry->setCommitOnFocusLost(FALSE); |
876 | mTextEntry->setText(cur_label); | 805 | mTextEntry->setText(cur_label); |
877 | mTextEntry->setIgnoreTab(TRUE); | 806 | mTextEntry->setIgnoreTab(TRUE); |
807 | mTextEntry->setFollowsAll(); | ||
878 | addChild(mTextEntry); | 808 | addChild(mTextEntry); |
879 | mMaxChars = max_chars; | 809 | mMaxChars = max_chars; |
880 | } | 810 | } |
@@ -882,6 +812,8 @@ void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative | |||
882 | { | 812 | { |
883 | mTextEntry->setVisible(TRUE); | 813 | mTextEntry->setVisible(TRUE); |
884 | } | 814 | } |
815 | |||
816 | mButton->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP | FOLLOWS_RIGHT); | ||
885 | } | 817 | } |
886 | else if (!allow && mAllowTextEntry) | 818 | else if (!allow && mAllowTextEntry) |
887 | { | 819 | { |
@@ -892,6 +824,7 @@ void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative | |||
892 | { | 824 | { |
893 | mTextEntry->setVisible(FALSE); | 825 | mTextEntry->setVisible(FALSE); |
894 | } | 826 | } |
827 | mButton->setFollowsAll(); | ||
895 | } | 828 | } |
896 | mAllowTextEntry = allow; | 829 | mAllowTextEntry = allow; |
897 | mTextEntryTentative = set_tentative; | 830 | mTextEntryTentative = set_tentative; |
@@ -927,6 +860,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data) | |||
927 | else | 860 | else |
928 | { | 861 | { |
929 | line_editor->setTentative(self->mTextEntryTentative); | 862 | line_editor->setTentative(self->mTextEntryTentative); |
863 | self->mList->deselectAllItems(); | ||
930 | } | 864 | } |
931 | return; | 865 | return; |
932 | } | 866 | } |
@@ -1141,15 +1075,3 @@ BOOL LLComboBox::operateOnAll(EOperation op) | |||
1141 | } | 1075 | } |
1142 | return FALSE; | 1076 | return FALSE; |
1143 | } | 1077 | } |
1144 | |||
1145 | //static | ||
1146 | void LLComboBox::onListFocusLost(LLUICtrl* old_focus) | ||
1147 | { | ||
1148 | // if focus is going to nothing (user hit ESC), take it back | ||
1149 | LLComboBox* combo = (LLComboBox*)old_focus->getParent(); | ||
1150 | combo->hideList(); | ||
1151 | if (gFocusMgr.getKeyboardFocus() == NULL) | ||
1152 | { | ||
1153 | combo->focusFirstItem(); | ||
1154 | } | ||
1155 | } | ||