diff options
author | Jacek Antonelli | 2008-08-15 23:45:29 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:29 -0500 |
commit | 7bdb4845afdd157f95281293803567090e3f992a (patch) | |
tree | fbcada1c227d7407f9f37ccba360bfe6326d9c5e /linden/indra/llui | |
parent | Second Life viewer sources 1.19.0.0 (diff) | |
download | meta-impy-7bdb4845afdd157f95281293803567090e3f992a.zip meta-impy-7bdb4845afdd157f95281293803567090e3f992a.tar.gz meta-impy-7bdb4845afdd157f95281293803567090e3f992a.tar.bz2 meta-impy-7bdb4845afdd157f95281293803567090e3f992a.tar.xz |
Second Life viewer sources 1.19.0.2
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llui/llcombobox.cpp | 6 | ||||
-rw-r--r-- | linden/indra/llui/llcombobox.h | 1 | ||||
-rw-r--r-- | linden/indra/llui/llctrlselectioninterface.h | 1 | ||||
-rw-r--r-- | linden/indra/llui/llfloater.cpp | 5 | ||||
-rw-r--r-- | linden/indra/llui/llpanel.cpp | 29 | ||||
-rw-r--r-- | linden/indra/llui/llradiogroup.h | 1 | ||||
-rw-r--r-- | linden/indra/llui/llscrolllistctrl.cpp | 175 | ||||
-rw-r--r-- | linden/indra/llui/llscrolllistctrl.h | 14 | ||||
-rw-r--r-- | linden/indra/llui/llview.cpp | 35 |
9 files changed, 161 insertions, 106 deletions
diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index 22b5033..96092b4 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp | |||
@@ -648,12 +648,16 @@ void LLComboBox::showList() | |||
648 | } | 648 | } |
649 | mList->setFocus(TRUE); | 649 | mList->setFocus(TRUE); |
650 | 650 | ||
651 | // register ourselves as a "top" control | ||
652 | // effectively putting us into a special draw layer | ||
653 | // and not affecting the bounding rectangle calculation | ||
654 | gFocusMgr.setTopCtrl(this); | ||
655 | |||
651 | // Show the list and push the button down | 656 | // Show the list and push the button down |
652 | mButton->setToggleState(TRUE); | 657 | mButton->setToggleState(TRUE); |
653 | mList->setVisible(TRUE); | 658 | mList->setVisible(TRUE); |
654 | 659 | ||
655 | setUseBoundingRect(TRUE); | 660 | setUseBoundingRect(TRUE); |
656 | gFocusMgr.setTopCtrl(this); | ||
657 | } | 661 | } |
658 | 662 | ||
659 | void LLComboBox::hideList() | 663 | void LLComboBox::hideList() |
diff --git a/linden/indra/llui/llcombobox.h b/linden/indra/llui/llcombobox.h index 2a70db2..7511449 100644 --- a/linden/indra/llui/llcombobox.h +++ b/linden/indra/llui/llcombobox.h | |||
@@ -156,6 +156,7 @@ public: | |||
156 | virtual BOOL getCanSelect() const { return TRUE; } | 156 | virtual BOOL getCanSelect() const { return TRUE; } |
157 | virtual BOOL selectFirstItem() { return setCurrentByIndex(0); } | 157 | virtual BOOL selectFirstItem() { return setCurrentByIndex(0); } |
158 | virtual BOOL selectNthItem( S32 index ) { return setCurrentByIndex(index); } | 158 | virtual BOOL selectNthItem( S32 index ) { return setCurrentByIndex(index); } |
159 | virtual BOOL selectItemRange( S32 first, S32 last ) { return setCurrentByIndex(first); } | ||
159 | virtual S32 getFirstSelectedIndex() const { return getCurrentIndex(); } | 160 | virtual S32 getFirstSelectedIndex() const { return getCurrentIndex(); } |
160 | virtual BOOL setCurrentByID( const LLUUID& id ); | 161 | virtual BOOL setCurrentByID( const LLUUID& id ); |
161 | virtual LLUUID getCurrentID(); // LLUUID::null if no items in menu | 162 | virtual LLUUID getCurrentID(); // LLUUID::null if no items in menu |
diff --git a/linden/indra/llui/llctrlselectioninterface.h b/linden/indra/llui/llctrlselectioninterface.h index 121d971..b4d3fc0 100644 --- a/linden/indra/llui/llctrlselectioninterface.h +++ b/linden/indra/llui/llctrlselectioninterface.h | |||
@@ -58,6 +58,7 @@ public: | |||
58 | 58 | ||
59 | virtual BOOL selectFirstItem() = 0; | 59 | virtual BOOL selectFirstItem() = 0; |
60 | virtual BOOL selectNthItem( S32 index ) = 0; | 60 | virtual BOOL selectNthItem( S32 index ) = 0; |
61 | virtual BOOL selectItemRange( S32 first, S32 last ) = 0; | ||
61 | 62 | ||
62 | virtual S32 getFirstSelectedIndex() const = 0; | 63 | virtual S32 getFirstSelectedIndex() const = 0; |
63 | 64 | ||
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index 1500f9f..496b67f 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp | |||
@@ -2735,6 +2735,11 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, | |||
2735 | { | 2735 | { |
2736 | mTabContainer->selectTabPanel(floaterp); | 2736 | mTabContainer->selectTabPanel(floaterp); |
2737 | } | 2737 | } |
2738 | else | ||
2739 | { | ||
2740 | // reassert visible tab (hiding new floater if necessary) | ||
2741 | mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex()); | ||
2742 | } | ||
2738 | 2743 | ||
2739 | floaterp->setHost(this); | 2744 | floaterp->setHost(this); |
2740 | if (mMinimized) | 2745 | if (mMinimized) |
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index af8aa21..7430e50 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp | |||
@@ -356,6 +356,13 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) | |||
356 | if( getVisible() && getEnabled() && | 356 | if( getVisible() && getEnabled() && |
357 | gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent ) | 357 | gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent ) |
358 | { | 358 | { |
359 | // handle user hitting ESC to defocus | ||
360 | if (key == KEY_ESCAPE) | ||
361 | { | ||
362 | gFocusMgr.setKeyboardFocus(NULL); | ||
363 | return TRUE; | ||
364 | } | ||
365 | |||
359 | LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); | 366 | LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); |
360 | // If we have a default button, click it when | 367 | // If we have a default button, click it when |
361 | // return is pressed, unless current focus is a return-capturing button | 368 | // return is pressed, unless current focus is a return-capturing button |
@@ -1322,6 +1329,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor | |||
1322 | } | 1329 | } |
1323 | } | 1330 | } |
1324 | } | 1331 | } |
1332 | layout_stackp->updateLayout(); | ||
1325 | 1333 | ||
1326 | return layout_stackp; | 1334 | return layout_stackp; |
1327 | } | 1335 | } |
@@ -1442,10 +1450,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1442 | { | 1450 | { |
1443 | // panels that are not fully visible do not count towards shrink headroom | 1451 | // panels that are not fully visible do not count towards shrink headroom |
1444 | if ((*panel_it)->mVisibleAmt < 1.f) | 1452 | if ((*panel_it)->mVisibleAmt < 1.f) |
1453 | { | ||
1445 | continue; | 1454 | continue; |
1455 | } | ||
1446 | // if currently resizing a panel or the panel is flagged as not automatically resizing | 1456 | // if currently resizing a panel or the panel is flagged as not automatically resizing |
1447 | // only track total available headroom, but don't use it for automatic resize logic | 1457 | // only track total available headroom, but don't use it for automatic resize logic |
1448 | if ((*panel_it)->mResizeBar->hasMouseCapture() || (!(*panel_it)->mAutoResize && !force_resize)) | 1458 | if ((*panel_it)->mResizeBar->hasMouseCapture() |
1459 | || (!(*panel_it)->mAutoResize | ||
1460 | && !force_resize)) | ||
1449 | { | 1461 | { |
1450 | if (mOrientation == HORIZONTAL) | 1462 | if (mOrientation == HORIZONTAL) |
1451 | { | 1463 | { |
@@ -1498,7 +1510,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1498 | S32 delta_size = 0; | 1510 | S32 delta_size = 0; |
1499 | 1511 | ||
1500 | // if panel can automatically resize (not animating, and resize flag set)... | 1512 | // if panel can automatically resize (not animating, and resize flag set)... |
1501 | if ((*panel_it)->mVisibleAmt == 1.f && (force_resize || (*panel_it)->mAutoResize) && !(*panel_it)->mResizeBar->hasMouseCapture()) | 1513 | if ((*panel_it)->mVisibleAmt == 1.f |
1514 | && (force_resize || (*panel_it)->mAutoResize) | ||
1515 | && !(*panel_it)->mResizeBar->hasMouseCapture()) | ||
1502 | { | 1516 | { |
1503 | if (mOrientation == HORIZONTAL) | 1517 | if (mOrientation == HORIZONTAL) |
1504 | { | 1518 | { |
@@ -1506,7 +1520,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1506 | if (pixels_to_distribute < 0) | 1520 | if (pixels_to_distribute < 0) |
1507 | { | 1521 | { |
1508 | // shrink proportionally to amount over minimum | 1522 | // shrink proportionally to amount over minimum |
1509 | delta_size = llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available); | 1523 | delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available) : 0; |
1510 | } | 1524 | } |
1511 | else | 1525 | else |
1512 | { | 1526 | { |
@@ -1525,7 +1539,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1525 | if (pixels_to_distribute < 0) | 1539 | if (pixels_to_distribute < 0) |
1526 | { | 1540 | { |
1527 | // shrink proportionally to amount over minimum | 1541 | // shrink proportionally to amount over minimum |
1528 | delta_size = llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available); | 1542 | delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available) : 0; |
1529 | } | 1543 | } |
1530 | else | 1544 | else |
1531 | { | 1545 | { |
@@ -1617,9 +1631,10 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1617 | } | 1631 | } |
1618 | 1632 | ||
1619 | // not enough room to fit existing contents | 1633 | // not enough room to fit existing contents |
1620 | if (!force_resize | 1634 | if (force_resize == FALSE |
1621 | && ((cur_y != -mPanelSpacing) | 1635 | // layout did not complete by reaching target position |
1622 | || (cur_x != mRect.getWidth() + mPanelSpacing))) | 1636 | && ((mOrientation == VERTICAL && cur_y != -mPanelSpacing) |
1637 | || (mOrientation == HORIZONTAL && cur_x != mRect.getWidth() + mPanelSpacing))) | ||
1623 | { | 1638 | { |
1624 | // do another layout pass with all stacked elements contributing | 1639 | // do another layout pass with all stacked elements contributing |
1625 | // even those that don't usually resize | 1640 | // even those that don't usually resize |
diff --git a/linden/indra/llui/llradiogroup.h b/linden/indra/llui/llradiogroup.h index e0a4168..aed8de2 100644 --- a/linden/indra/llui/llradiogroup.h +++ b/linden/indra/llui/llradiogroup.h | |||
@@ -118,6 +118,7 @@ public: | |||
118 | /*virtual*/ BOOL getCanSelect() const { return TRUE; } | 118 | /*virtual*/ BOOL getCanSelect() const { return TRUE; } |
119 | /*virtual*/ BOOL selectFirstItem() { return setSelectedIndex(0); } | 119 | /*virtual*/ BOOL selectFirstItem() { return setSelectedIndex(0); } |
120 | /*virtual*/ BOOL selectNthItem( S32 index ) { return setSelectedIndex(index); } | 120 | /*virtual*/ BOOL selectNthItem( S32 index ) { return setSelectedIndex(index); } |
121 | /*virtual*/ BOOL selectItemRange( S32 first, S32 last ) { return setSelectedIndex(first); } | ||
121 | /*virtual*/ S32 getFirstSelectedIndex() const { return getSelectedIndex(); } | 122 | /*virtual*/ S32 getFirstSelectedIndex() const { return getSelectedIndex(); } |
122 | /*virtual*/ BOOL setCurrentByID( const LLUUID& id ); | 123 | /*virtual*/ BOOL setCurrentByID( const LLUUID& id ); |
123 | /*virtual*/ LLUUID getCurrentID(); // LLUUID::null if no items in menu | 124 | /*virtual*/ LLUUID getCurrentID(); // LLUUID::null if no items in menu |
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index d65ebd2..36a7b00 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp | |||
@@ -518,6 +518,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, | |||
518 | mNeedsScroll(FALSE), | 518 | mNeedsScroll(FALSE), |
519 | mCanSelect(TRUE), | 519 | mCanSelect(TRUE), |
520 | mDisplayColumnHeaders(FALSE), | 520 | mDisplayColumnHeaders(FALSE), |
521 | mColumnsDirty(FALSE), | ||
521 | mMaxItemCount(INT_MAX), | 522 | mMaxItemCount(INT_MAX), |
522 | mMaxContentWidth(0), | 523 | mMaxContentWidth(0), |
523 | mBackgroundVisible( TRUE ), | 524 | mBackgroundVisible( TRUE ), |
@@ -630,7 +631,6 @@ void LLScrollListCtrl::clearRows() | |||
630 | 631 | ||
631 | mScrollLines = 0; | 632 | mScrollLines = 0; |
632 | mLastSelected = NULL; | 633 | mLastSelected = NULL; |
633 | calcMaxContentWidth(NULL); | ||
634 | updateLayout(); | 634 | updateLayout(); |
635 | mDirty = FALSE; | 635 | mDirty = FALSE; |
636 | } | 636 | } |
@@ -762,7 +762,7 @@ void LLScrollListCtrl::updateLayout() | |||
762 | mScrollbar->setDocSize( getItemCount() ); | 762 | mScrollbar->setDocSize( getItemCount() ); |
763 | mScrollbar->setVisible(scrollbar_visible); | 763 | mScrollbar->setVisible(scrollbar_visible); |
764 | 764 | ||
765 | updateColumns(); | 765 | dirtyColumns(); |
766 | } | 766 | } |
767 | 767 | ||
768 | // Attempt to size the control to show all items. | 768 | // Attempt to size the control to show all items. |
@@ -840,7 +840,6 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r | |||
840 | } | 840 | } |
841 | 841 | ||
842 | updateLineHeightInsert(item); | 842 | updateLineHeightInsert(item); |
843 | calcMaxContentWidth(item); | ||
844 | 843 | ||
845 | updateLayout(); | 844 | updateLayout(); |
846 | } | 845 | } |
@@ -848,17 +847,14 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r | |||
848 | return not_too_big; | 847 | return not_too_big; |
849 | } | 848 | } |
850 | 849 | ||
851 | void LLScrollListCtrl::calcMaxContentWidth(LLScrollListItem* added_item) | 850 | void LLScrollListCtrl::calcColumnWidths() |
852 | { | 851 | { |
853 | const S32 HEADING_TEXT_PADDING = 30; | 852 | const S32 HEADING_TEXT_PADDING = 30; |
854 | const S32 COLUMN_TEXT_PADDING = 20; | 853 | const S32 COLUMN_TEXT_PADDING = 20; |
855 | 854 | ||
856 | if (added_item == NULL) | 855 | mMaxContentWidth = 0; |
857 | { | ||
858 | mMaxContentWidth = 0; | ||
859 | } | ||
860 | 856 | ||
861 | S32 item_content_width = 0; | 857 | S32 max_item_width = 0; |
862 | 858 | ||
863 | ordered_columns_t::iterator column_itor; | 859 | ordered_columns_t::iterator column_itor; |
864 | for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) | 860 | for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) |
@@ -866,31 +862,37 @@ void LLScrollListCtrl::calcMaxContentWidth(LLScrollListItem* added_item) | |||
866 | LLScrollListColumn* column = *column_itor; | 862 | LLScrollListColumn* column = *column_itor; |
867 | if (!column) continue; | 863 | if (!column) continue; |
868 | 864 | ||
869 | if (!added_item) | 865 | // update column width |
866 | S32 new_width = column->mWidth; | ||
867 | if (column->mRelWidth >= 0) | ||
870 | { | 868 | { |
871 | // update on all items | 869 | new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth()); |
872 | column->mMaxContentWidth = column->mHeader ? LLFontGL::sSansSerifSmall->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; | 870 | } |
873 | item_list::iterator iter; | 871 | else if (column->mDynamicWidth) |
874 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) | 872 | { |
875 | { | 873 | new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; |
876 | LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); | 874 | } |
877 | if (!cellp) continue; | ||
878 | 875 | ||
879 | column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); | 876 | if (new_width != column->mWidth) |
880 | } | 877 | { |
878 | column->mWidth = new_width; | ||
881 | } | 879 | } |
882 | else | 880 | |
881 | // update max content width for this column, by looking at all items | ||
882 | column->mMaxContentWidth = column->mHeader ? LLFontGL::sSansSerifSmall->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; | ||
883 | item_list::iterator iter; | ||
884 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) | ||
883 | { | 885 | { |
884 | LLScrollListCell* cellp = added_item->getColumn(column->mIndex); | 886 | LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); |
885 | if (!cellp) continue; | 887 | if (!cellp) continue; |
886 | 888 | ||
887 | column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); | 889 | column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); |
888 | } | 890 | } |
889 | 891 | ||
890 | item_content_width += column->mMaxContentWidth; | 892 | max_item_width += column->mMaxContentWidth; |
891 | } | 893 | } |
892 | 894 | ||
893 | mMaxContentWidth = llmax(mMaxContentWidth, item_content_width); | 895 | mMaxContentWidth = max_item_width; |
894 | } | 896 | } |
895 | 897 | ||
896 | const S32 SCROLL_LIST_ROW_PAD = 2; | 898 | const S32 SCROLL_LIST_ROW_PAD = 2; |
@@ -926,29 +928,9 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) | |||
926 | 928 | ||
927 | void LLScrollListCtrl::updateColumns() | 929 | void LLScrollListCtrl::updateColumns() |
928 | { | 930 | { |
929 | mColumnsIndexed.resize(mColumns.size()); | 931 | calcColumnWidths(); |
930 | |||
931 | std::map<LLString, LLScrollListColumn>::iterator column_itor; | ||
932 | for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) | ||
933 | { | ||
934 | LLScrollListColumn *column = &column_itor->second; | ||
935 | S32 new_width = column->mWidth; | ||
936 | if (column->mRelWidth >= 0) | ||
937 | { | ||
938 | new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth()); | ||
939 | } | ||
940 | else if (column->mDynamicWidth) | ||
941 | { | ||
942 | new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; | ||
943 | } | ||
944 | |||
945 | if (new_width != column->mWidth) | ||
946 | { | ||
947 | column->mWidth = new_width; | ||
948 | } | ||
949 | mColumnsIndexed[column_itor->second.mIndex] = column; | ||
950 | } | ||
951 | 932 | ||
933 | // propagate column widths to individual cells | ||
952 | item_list::iterator iter; | 934 | item_list::iterator iter; |
953 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) | 935 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) |
954 | { | 936 | { |
@@ -963,7 +945,7 @@ void LLScrollListCtrl::updateColumns() | |||
963 | } | 945 | } |
964 | } | 946 | } |
965 | 947 | ||
966 | // update headers | 948 | // update column headers |
967 | std::vector<LLScrollListColumn*>::iterator column_ordered_it; | 949 | std::vector<LLScrollListColumn*>::iterator column_ordered_it; |
968 | S32 left = mItemListRect.mLeft; | 950 | S32 left = mItemListRect.mLeft; |
969 | LLColumnHeader* last_header = NULL; | 951 | LLColumnHeader* last_header = NULL; |
@@ -998,6 +980,7 @@ void LLScrollListCtrl::updateColumns() | |||
998 | } | 980 | } |
999 | } | 981 | } |
1000 | 982 | ||
983 | //FIXME: stretch the entire last column if it is resizable (gestures windows shows truncated text in last column) | ||
1001 | // expand last column header we encountered to full list width | 984 | // expand last column header we encountered to full list width |
1002 | if (last_header) | 985 | if (last_header) |
1003 | { | 986 | { |
@@ -1055,28 +1038,42 @@ BOOL LLScrollListCtrl::selectFirstItem() | |||
1055 | return success; | 1038 | return success; |
1056 | } | 1039 | } |
1057 | 1040 | ||
1058 | 1041 | // Deselects all other items | |
1042 | // virtual | ||
1059 | BOOL LLScrollListCtrl::selectNthItem( S32 target_index ) | 1043 | BOOL LLScrollListCtrl::selectNthItem( S32 target_index ) |
1060 | { | 1044 | { |
1061 | if (mItemList.empty()) return FALSE; | 1045 | return selectItemRange(target_index, target_index); |
1046 | } | ||
1062 | 1047 | ||
1063 | // Deselects all other items | 1048 | // virtual |
1064 | BOOL success = FALSE; | 1049 | BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) |
1065 | S32 index = 0; | 1050 | { |
1051 | if (mItemList.empty()) | ||
1052 | { | ||
1053 | return FALSE; | ||
1054 | } | ||
1066 | 1055 | ||
1067 | target_index = llclamp(target_index, 0, (S32)mItemList.size() - 1); | 1056 | S32 listlen = (S32)mItemList.size(); |
1057 | first_index = llclamp(first_index, 0, listlen-1); | ||
1058 | |||
1059 | if (last_index < 0) | ||
1060 | last_index = listlen-1; | ||
1061 | else | ||
1062 | last_index = llclamp(last_index, first_index, listlen-1); | ||
1068 | 1063 | ||
1069 | item_list::iterator iter; | 1064 | BOOL success = FALSE; |
1070 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) | 1065 | S32 index = 0; |
1066 | for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++) | ||
1071 | { | 1067 | { |
1072 | LLScrollListItem *itemp = *iter; | 1068 | LLScrollListItem *itemp = *iter; |
1073 | if( target_index == index ) | 1069 | if( index >= first_index && index <= last_index ) |
1074 | { | 1070 | { |
1075 | if( itemp->getEnabled() ) | 1071 | if( itemp->getEnabled() ) |
1076 | { | 1072 | { |
1077 | selectItem(itemp); | 1073 | selectItem(itemp); |
1078 | success = TRUE; | 1074 | success = TRUE; |
1079 | mOriginalSelection = target_index; | 1075 | if (!success) |
1076 | mOriginalSelection = first_index; | ||
1080 | } | 1077 | } |
1081 | } | 1078 | } |
1082 | else | 1079 | else |
@@ -1125,7 +1122,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) | |||
1125 | 1122 | ||
1126 | void LLScrollListCtrl::deleteSingleItem(S32 target_index) | 1123 | void LLScrollListCtrl::deleteSingleItem(S32 target_index) |
1127 | { | 1124 | { |
1128 | if (target_index >= (S32)mItemList.size()) | 1125 | if (target_index < 0 || target_index >= (S32)mItemList.size()) |
1129 | { | 1126 | { |
1130 | return; | 1127 | return; |
1131 | } | 1128 | } |
@@ -1138,7 +1135,7 @@ void LLScrollListCtrl::deleteSingleItem(S32 target_index) | |||
1138 | } | 1135 | } |
1139 | delete itemp; | 1136 | delete itemp; |
1140 | mItemList.erase(mItemList.begin() + target_index); | 1137 | mItemList.erase(mItemList.begin() + target_index); |
1141 | calcMaxContentWidth(NULL); | 1138 | dirtyColumns(); |
1142 | } | 1139 | } |
1143 | 1140 | ||
1144 | //FIXME: refactor item deletion | 1141 | //FIXME: refactor item deletion |
@@ -1163,7 +1160,7 @@ void LLScrollListCtrl::deleteItems(const LLSD& sd) | |||
1163 | } | 1160 | } |
1164 | } | 1161 | } |
1165 | 1162 | ||
1166 | calcMaxContentWidth(NULL); | 1163 | dirtyColumns(); |
1167 | } | 1164 | } |
1168 | 1165 | ||
1169 | void LLScrollListCtrl::deleteSelectedItems() | 1166 | void LLScrollListCtrl::deleteSelectedItems() |
@@ -1183,7 +1180,7 @@ void LLScrollListCtrl::deleteSelectedItems() | |||
1183 | } | 1180 | } |
1184 | } | 1181 | } |
1185 | mLastSelected = NULL; | 1182 | mLastSelected = NULL; |
1186 | calcMaxContentWidth(NULL); | 1183 | dirtyColumns(); |
1187 | } | 1184 | } |
1188 | 1185 | ||
1189 | void LLScrollListCtrl::highlightNthItem(S32 target_index) | 1186 | void LLScrollListCtrl::highlightNthItem(S32 target_index) |
@@ -1237,7 +1234,7 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) | |||
1237 | return -1; | 1234 | return -1; |
1238 | } | 1235 | } |
1239 | 1236 | ||
1240 | S32 LLScrollListCtrl::getItemIndex( LLUUID& target_id ) | 1237 | S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) |
1241 | { | 1238 | { |
1242 | S32 index = 0; | 1239 | S32 index = 0; |
1243 | item_list::iterator iter; | 1240 | item_list::iterator iter; |
@@ -1722,6 +1719,12 @@ void LLScrollListCtrl::draw() | |||
1722 | gl_rect_2d(background); | 1719 | gl_rect_2d(background); |
1723 | } | 1720 | } |
1724 | 1721 | ||
1722 | if (mColumnsDirty) | ||
1723 | { | ||
1724 | updateColumns(); | ||
1725 | mColumnsDirty = FALSE; | ||
1726 | } | ||
1727 | |||
1725 | drawItems(); | 1728 | drawItems(); |
1726 | 1729 | ||
1727 | if (mBorder) | 1730 | if (mBorder) |
@@ -1989,9 +1992,8 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) | |||
1989 | gFocusMgr.setMouseCapture(this); | 1992 | gFocusMgr.setMouseCapture(this); |
1990 | mNeedsScroll = TRUE; | 1993 | mNeedsScroll = TRUE; |
1991 | } | 1994 | } |
1992 | // otherwise we already have this item selected | 1995 | |
1993 | // so propagate state of cell to rest of selected column | 1996 | // propagate state of cell to rest of selected column |
1994 | else | ||
1995 | { | 1997 | { |
1996 | // propagate value of this cell to other selected items | 1998 | // propagate value of this cell to other selected items |
1997 | // and commit the respective widgets | 1999 | // and commit the respective widgets |
@@ -2537,6 +2539,23 @@ void LLScrollListCtrl::sortItems() | |||
2537 | setSorted(TRUE); | 2539 | setSorted(TRUE); |
2538 | } | 2540 | } |
2539 | 2541 | ||
2542 | void LLScrollListCtrl::dirtyColumns() | ||
2543 | { | ||
2544 | mColumnsDirty = TRUE; | ||
2545 | |||
2546 | // need to keep mColumnsIndexed up to date | ||
2547 | // just in case someone indexes into it immediately | ||
2548 | mColumnsIndexed.resize(mColumns.size()); | ||
2549 | |||
2550 | std::map<LLString, LLScrollListColumn>::iterator column_itor; | ||
2551 | for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) | ||
2552 | { | ||
2553 | LLScrollListColumn *column = &column_itor->second; | ||
2554 | mColumnsIndexed[column_itor->second.mIndex] = column; | ||
2555 | } | ||
2556 | } | ||
2557 | |||
2558 | |||
2540 | S32 LLScrollListCtrl::getScrollPos() | 2559 | S32 LLScrollListCtrl::getScrollPos() |
2541 | { | 2560 | { |
2542 | return mScrollbar->getDocPos(); | 2561 | return mScrollbar->getDocPos(); |
@@ -2727,6 +2746,12 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2727 | S32 search_column = 0; | 2746 | S32 search_column = 0; |
2728 | node->getAttributeS32("search_column", search_column); | 2747 | node->getAttributeS32("search_column", search_column); |
2729 | 2748 | ||
2749 | S32 sort_column = -1; | ||
2750 | node->getAttributeS32("sort_column", sort_column); | ||
2751 | |||
2752 | BOOL sort_ascending = TRUE; | ||
2753 | node->getAttributeBOOL("sort_ascending", sort_ascending); | ||
2754 | |||
2730 | LLUICtrlCallback callback = NULL; | 2755 | LLUICtrlCallback callback = NULL; |
2731 | 2756 | ||
2732 | LLScrollListCtrl* scroll_list = new LLScrollListCtrl( | 2757 | LLScrollListCtrl* scroll_list = new LLScrollListCtrl( |
@@ -2751,6 +2776,11 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2751 | 2776 | ||
2752 | scroll_list->setSearchColumn(search_column); | 2777 | scroll_list->setSearchColumn(search_column); |
2753 | 2778 | ||
2779 | if (sort_column >= 0) | ||
2780 | { | ||
2781 | scroll_list->sortByColumn(sort_column, sort_ascending); | ||
2782 | } | ||
2783 | |||
2754 | LLSD columns; | 2784 | LLSD columns; |
2755 | S32 index = 0; | 2785 | S32 index = 0; |
2756 | LLXMLNodePtr child; | 2786 | LLXMLNodePtr child; |
@@ -3026,7 +3056,7 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) | |||
3026 | } | 3056 | } |
3027 | } | 3057 | } |
3028 | 3058 | ||
3029 | updateColumns(); | 3059 | dirtyColumns(); |
3030 | } | 3060 | } |
3031 | 3061 | ||
3032 | // static | 3062 | // static |
@@ -3257,13 +3287,14 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
3257 | col_index++; | 3287 | col_index++; |
3258 | } | 3288 | } |
3259 | 3289 | ||
3260 | S32 num_columns = mColumns.size(); | 3290 | // add dummy cells for missing columns |
3261 | for (S32 column = 0; column < num_columns; ++column) | 3291 | for (column_map_t::iterator column_it = mColumns.begin(); column_it != mColumns.end(); ++column_it) |
3262 | { | 3292 | { |
3263 | if (new_item->getColumn(column) == NULL) | 3293 | S32 column_idx = column_it->second.mIndex; |
3294 | if (new_item->getColumn(column_idx) == NULL) | ||
3264 | { | 3295 | { |
3265 | LLScrollListColumn* column_ptr = mColumnsIndexed[column]; | 3296 | LLScrollListColumn* column_ptr = &column_it->second; |
3266 | new_item->setColumn(column, new LLScrollListText("", gResMgr->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL)); | 3297 | new_item->setColumn(column_idx, new LLScrollListText("", gResMgr->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL)); |
3267 | } | 3298 | } |
3268 | } | 3299 | } |
3269 | 3300 | ||
@@ -3665,7 +3696,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d | |||
3665 | void LLColumnHeader::userSetShape(const LLRect& new_rect) | 3696 | void LLColumnHeader::userSetShape(const LLRect& new_rect) |
3666 | { | 3697 | { |
3667 | S32 new_width = new_rect.getWidth(); | 3698 | S32 new_width = new_rect.getWidth(); |
3668 | S32 delta_width = new_width - (mRect.getWidth() + mColumn->mParentCtrl->getColumnPadding()); | 3699 | S32 delta_width = new_width - (mRect.getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); |
3669 | 3700 | ||
3670 | if (delta_width != 0) | 3701 | if (delta_width != 0) |
3671 | { | 3702 | { |
@@ -3737,6 +3768,8 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect) | |||
3737 | } | 3768 | } |
3738 | 3769 | ||
3739 | // tell scroll list to layout columns again | 3770 | // tell scroll list to layout columns again |
3771 | // do immediate update to get proper feedback to resize handle | ||
3772 | // which needs to know how far the resize actually went | ||
3740 | mColumn->mParentCtrl->updateColumns(); | 3773 | mColumn->mParentCtrl->updateColumns(); |
3741 | } | 3774 | } |
3742 | } | 3775 | } |
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index ada4f9b..71ba63d 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h | |||
@@ -97,6 +97,7 @@ public: | |||
97 | virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; | 97 | virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; |
98 | virtual S32 getContentWidth() const; | 98 | virtual S32 getContentWidth() const; |
99 | virtual S32 getHeight() const { return llround(mFont->getLineHeight()); } | 99 | virtual S32 getHeight() const { return llround(mFont->getLineHeight()); } |
100 | virtual void setValue(LLSD value) { setText(value.asString()); } | ||
100 | virtual const LLSD getValue() const { return LLSD(mText.getString()); } | 101 | virtual const LLSD getValue() const { return LLSD(mText.getString()); } |
101 | virtual BOOL getVisible() const { return mVisible; } | 102 | virtual BOOL getVisible() const { return mVisible; } |
102 | virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} | 103 | virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} |
@@ -440,6 +441,7 @@ public: | |||
440 | BOOL handleClick(S32 x, S32 y, MASK mask); | 441 | BOOL handleClick(S32 x, S32 y, MASK mask); |
441 | BOOL selectFirstItem(); | 442 | BOOL selectFirstItem(); |
442 | BOOL selectNthItem( S32 index ); | 443 | BOOL selectNthItem( S32 index ); |
444 | BOOL selectItemRange( S32 first, S32 last ); | ||
443 | BOOL selectItemAt(S32 x, S32 y, MASK mask); | 445 | BOOL selectItemAt(S32 x, S32 y, MASK mask); |
444 | 446 | ||
445 | void deleteSingleItem( S32 index ); | 447 | void deleteSingleItem( S32 index ); |
@@ -459,7 +461,7 @@ public: | |||
459 | virtual BOOL getCanSelect() const { return mCanSelect; } | 461 | virtual BOOL getCanSelect() const { return mCanSelect; } |
460 | 462 | ||
461 | S32 getItemIndex( LLScrollListItem* item ); | 463 | S32 getItemIndex( LLScrollListItem* item ); |
462 | S32 getItemIndex( LLUUID& item_id ); | 464 | S32 getItemIndex( const LLUUID& item_id ); |
463 | 465 | ||
464 | LLScrollListItem* addCommentText( const LLString& comment_text, EAddPosition pos = ADD_BOTTOM); | 466 | LLScrollListItem* addCommentText( const LLString& comment_text, EAddPosition pos = ADD_BOTTOM); |
465 | LLScrollListItem* addSeparator(EAddPosition pos); | 467 | LLScrollListItem* addSeparator(EAddPosition pos); |
@@ -561,7 +563,7 @@ public: | |||
561 | static void onClickColumn(void *userdata); | 563 | static void onClickColumn(void *userdata); |
562 | 564 | ||
563 | void updateColumns(); | 565 | void updateColumns(); |
564 | void calcMaxContentWidth(LLScrollListItem* changed_item); | 566 | void calcColumnWidths(); |
565 | S32 getMaxContentWidth() { return mMaxContentWidth; } | 567 | S32 getMaxContentWidth() { return mMaxContentWidth; } |
566 | 568 | ||
567 | void setDisplayHeading(BOOL display); | 569 | void setDisplayHeading(BOOL display); |
@@ -596,6 +598,9 @@ public: | |||
596 | 598 | ||
597 | S32 selectMultiple( LLDynamicArray<LLUUID> ids ); | 599 | S32 selectMultiple( LLDynamicArray<LLUUID> ids ); |
598 | void sortItems(); | 600 | void sortItems(); |
601 | // manually call this whenever editing list items in place to flag need for resorting | ||
602 | void setSorted(BOOL sorted); | ||
603 | void dirtyColumns(); // some operation has potentially affected column layout or ordering | ||
599 | 604 | ||
600 | protected: | 605 | protected: |
601 | // "Full" interface: use this when you're creating a list that has one or more of the following: | 606 | // "Full" interface: use this when you're creating a list that has one or more of the following: |
@@ -624,7 +629,6 @@ protected: | |||
624 | void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE); | 629 | void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE); |
625 | void deselectItem(LLScrollListItem* itemp); | 630 | void deselectItem(LLScrollListItem* itemp); |
626 | void commitIfChanged(); | 631 | void commitIfChanged(); |
627 | void setSorted(BOOL sorted); | ||
628 | BOOL setSort(S32 column, BOOL ascending); | 632 | BOOL setSort(S32 column, BOOL ascending); |
629 | 633 | ||
630 | protected: | 634 | protected: |
@@ -645,6 +649,7 @@ protected: | |||
645 | BOOL mNeedsScroll; | 649 | BOOL mNeedsScroll; |
646 | BOOL mCanSelect; | 650 | BOOL mCanSelect; |
647 | BOOL mDisplayColumnHeaders; | 651 | BOOL mDisplayColumnHeaders; |
652 | BOOL mColumnsDirty; | ||
648 | 653 | ||
649 | typedef std::deque<LLScrollListItem *> item_list; | 654 | typedef std::deque<LLScrollListItem *> item_list; |
650 | item_list mItemList; | 655 | item_list mItemList; |
@@ -686,7 +691,8 @@ protected: | |||
686 | 691 | ||
687 | BOOL mSorted; | 692 | BOOL mSorted; |
688 | 693 | ||
689 | std::map<LLString, LLScrollListColumn> mColumns; | 694 | typedef std::map<LLString, LLScrollListColumn> column_map_t; |
695 | column_map_t mColumns; | ||
690 | 696 | ||
691 | BOOL mDirty; | 697 | BOOL mDirty; |
692 | S32 mOriginalSelection; | 698 | S32 mOriginalSelection; |
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index 04d33a6..39398b0 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp | |||
@@ -973,18 +973,10 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) | |||
973 | } | 973 | } |
974 | } | 974 | } |
975 | 975 | ||
976 | if( !handled && !called_from_parent) | 976 | if( !handled && !called_from_parent && mParentView) |
977 | { | 977 | { |
978 | if (mIsFocusRoot) | 978 | // Upward traversal |
979 | { | 979 | handled = mParentView->handleKey( key, mask, FALSE ); |
980 | // stop processing at focus root | ||
981 | handled = FALSE; | ||
982 | } | ||
983 | else if (mParentView) | ||
984 | { | ||
985 | // Upward traversal | ||
986 | handled = mParentView->handleKey( key, mask, FALSE ); | ||
987 | } | ||
988 | } | 980 | } |
989 | return handled; | 981 | return handled; |
990 | } | 982 | } |
@@ -1019,18 +1011,10 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) | |||
1019 | } | 1011 | } |
1020 | 1012 | ||
1021 | 1013 | ||
1022 | if (!handled && !called_from_parent) | 1014 | if (!handled && !called_from_parent && mParentView) |
1023 | { | 1015 | { |
1024 | if (mIsFocusRoot) | 1016 | // Upward traversal |
1025 | { | 1017 | handled = mParentView->handleUnicodeChar(uni_char, FALSE); |
1026 | // stop processing at focus root | ||
1027 | handled = FALSE; | ||
1028 | } | ||
1029 | else if(mParentView) | ||
1030 | { | ||
1031 | // Upward traversal | ||
1032 | handled = mParentView->handleUnicodeChar(uni_char, FALSE); | ||
1033 | } | ||
1034 | } | 1018 | } |
1035 | 1019 | ||
1036 | return handled; | 1020 | return handled; |
@@ -1666,7 +1650,12 @@ void LLView::updateBoundingRect() | |||
1666 | for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | 1650 | for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) |
1667 | { | 1651 | { |
1668 | LLView* childp = *child_it; | 1652 | LLView* childp = *child_it; |
1669 | if (!childp->getVisible()) continue; | 1653 | // ignore invisible and "top" children when calculating bounding rect |
1654 | // such as combobox popups | ||
1655 | if (!childp->getVisible() || childp == gFocusMgr.getTopCtrl()) | ||
1656 | { | ||
1657 | continue; | ||
1658 | } | ||
1670 | 1659 | ||
1671 | LLRect child_bounding_rect = childp->getBoundingRect(); | 1660 | LLRect child_bounding_rect = childp->getBoundingRect(); |
1672 | 1661 | ||