diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llbutton.cpp | 12 | ||||
-rw-r--r-- | indra/llui/llcombobox.cpp | 10 | ||||
-rw-r--r-- | indra/llui/llcombobox.h | 1 | ||||
-rw-r--r-- | indra/llui/llctrlselectioninterface.h | 1 | ||||
-rw-r--r-- | indra/llui/llfloater.cpp | 22 | ||||
-rw-r--r-- | indra/llui/llpanel.cpp | 34 | ||||
-rw-r--r-- | indra/llui/llpanel.h | 1 | ||||
-rw-r--r-- | indra/llui/llradiogroup.h | 1 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.cpp | 205 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.h | 16 | ||||
-rw-r--r-- | indra/llui/llview.cpp | 35 |
11 files changed, 189 insertions, 149 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 6c27ccc037..435e1d1701 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -956,37 +956,37 @@ S32 round_up(S32 grid, S32 value) void LLButton::setImageUnselected(const LLString &image_name) { - setImageUnselected(LLUI::getUIImageByName(image_name)); + setImageUnselected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); mImageUnselectedName = image_name; } void LLButton::setImageSelected(const LLString &image_name) { - setImageSelected(LLUI::getUIImageByName(image_name)); + setImageSelected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); mImageSelectedName = image_name; } void LLButton::setImageHoverSelected(const LLString &image_name) { - setImageHoverSelected(LLUI::getUIImageByName(image_name)); + setImageHoverSelected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); mImageHoverSelectedName = image_name; } void LLButton::setImageHoverUnselected(const LLString &image_name) { - setImageHoverUnselected(LLUI::getUIImageByName(image_name)); + setImageHoverUnselected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); mImageHoverUnselectedName = image_name; } void LLButton::setImageDisabled(const LLString &image_name) { - setImageDisabled(LLUI::getUIImageByName(image_name)); + setImageDisabled(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); mImageDisabledName = image_name; } void LLButton::setImageDisabledSelected(const LLString &image_name) { - setImageDisabledSelected(LLUI::getUIImageByName(image_name)); + setImageDisabledSelected(image_name.empty() ? NULL : LLUI::getUIImageByName(image_name)); mImageDisabledSelectedName = image_name; } diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 250ca523d2..ca02305f32 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -642,12 +642,16 @@ void LLComboBox::showList() mList->setFocus(TRUE); + // register ourselves as a "top" control + // effectively putting us into a special draw layer + // and not affecting the bounding rectangle calculation + gFocusMgr.setTopCtrl(this); + // Show the list and push the button down mButton->setToggleState(TRUE); mList->setVisible(TRUE); setUseBoundingRect(TRUE); - gFocusMgr.setTopCtrl(this); } void LLComboBox::hideList() @@ -1081,6 +1085,10 @@ BOOL LLComboBox::operateOnAll(EOperation op) return FALSE; } +BOOL LLComboBox::selectItemRange( S32 first, S32 last ) +{ + return mList->selectItemRange(first, last); +} // diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 13c2455d61..0d6c3aef2e 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -156,6 +156,7 @@ public: virtual BOOL getCanSelect() const { return TRUE; } virtual BOOL selectFirstItem() { return setCurrentByIndex(0); } virtual BOOL selectNthItem( S32 index ) { return setCurrentByIndex(index); } + virtual BOOL selectItemRange( S32 first, S32 last ); virtual S32 getFirstSelectedIndex() const { return getCurrentIndex(); } virtual BOOL setCurrentByID( const LLUUID& id ); virtual LLUUID getCurrentID() const; // LLUUID::null if no items in menu diff --git a/indra/llui/llctrlselectioninterface.h b/indra/llui/llctrlselectioninterface.h index e43e20a4c0..eb89a0833d 100644 --- a/indra/llui/llctrlselectioninterface.h +++ b/indra/llui/llctrlselectioninterface.h @@ -58,6 +58,7 @@ public: virtual BOOL selectFirstItem() = 0; virtual BOOL selectNthItem( S32 index ) = 0; + virtual BOOL selectItemRange( S32 first, S32 last ) = 0; virtual S32 getFirstSelectedIndex() const = 0; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 5c1f8429d1..68719bea40 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1343,21 +1343,7 @@ void LLFloater::draw() } } - if( getDefaultButton() ) - { - if (gFocusMgr.childHasKeyboardFocus( this ) && getDefaultButton()->getEnabled()) - { - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); - // is this button a direct descendent and not a nested widget (e.g. checkbox)? - BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && focus_ctrl->getParent() == this; - // only enable default button when current focus is not a button - getDefaultButton()->setBorderEnabled(!focus_is_child_button); - } - else - { - getDefaultButton()->setBorderEnabled(FALSE); - } - } + LLPanel::updateDefaultBtn(); // draw children LLView* focused_child = gFocusMgr.getKeyboardFocus(); @@ -1368,6 +1354,7 @@ void LLFloater::draw() focused_child->setVisible(FALSE); } + // don't call LLPanel::draw() since we've implemented custom background rendering LLView::draw(); if( isBackgroundVisible() ) @@ -2568,6 +2555,11 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, { mTabContainer->selectTabPanel(floaterp); } + else + { + // reassert visible tab (hiding new floater if necessary) + mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex()); + } floaterp->setHost(this); if (isMinimized()) diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 6554a25dcf..4c16683704 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -211,6 +211,11 @@ void LLPanel::draw() } } + updateDefaultBtn(); +} + +void LLPanel::updateDefaultBtn() +{ if( mDefaultBtn) { if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) @@ -353,6 +358,13 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) if( getVisible() && getEnabled() && gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent ) { + // handle user hitting ESC to defocus + if (key == KEY_ESCAPE) + { + gFocusMgr.setKeyboardFocus(NULL); + return TRUE; + } + LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); // If we have a default button, click it when // return is pressed, unless current focus is a return-capturing button @@ -1298,6 +1310,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor } } } + layout_stackp->updateLayout(); return layout_stackp; } @@ -1408,10 +1421,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize) { // panels that are not fully visible do not count towards shrink headroom if ((*panel_it)->mVisibleAmt < 1.f) + { continue; + } // if currently resizing a panel or the panel is flagged as not automatically resizing // only track total available headroom, but don't use it for automatic resize logic - if ((*panel_it)->mResizeBar->hasMouseCapture() || (!(*panel_it)->mAutoResize && !force_resize)) + if ((*panel_it)->mResizeBar->hasMouseCapture() + || (!(*panel_it)->mAutoResize + && !force_resize)) { if (mOrientation == HORIZONTAL) { @@ -1464,7 +1481,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize) S32 delta_size = 0; // if panel can automatically resize (not animating, and resize flag set)... - if ((*panel_it)->mVisibleAmt == 1.f && (force_resize || (*panel_it)->mAutoResize) && !(*panel_it)->mResizeBar->hasMouseCapture()) + if ((*panel_it)->mVisibleAmt == 1.f + && (force_resize || (*panel_it)->mAutoResize) + && !(*panel_it)->mResizeBar->hasMouseCapture()) { if (mOrientation == HORIZONTAL) { @@ -1472,7 +1491,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) if (pixels_to_distribute < 0) { // shrink proportionally to amount over minimum - delta_size = llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available); + delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available) : 0; } else { @@ -1491,7 +1510,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) if (pixels_to_distribute < 0) { // shrink proportionally to amount over minimum - delta_size = llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available); + delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available) : 0; } else { @@ -1583,9 +1602,10 @@ void LLLayoutStack::updateLayout(BOOL force_resize) } // not enough room to fit existing contents - if (!force_resize - && ((cur_y != -mPanelSpacing) - || (cur_x != getRect().getWidth() + mPanelSpacing))) + if (force_resize == FALSE + // layout did not complete by reaching target position + && ((mOrientation == VERTICAL && cur_y != -mPanelSpacing) + || (mOrientation == HORIZONTAL && cur_x != getRect().getWidth() + mPanelSpacing))) { // do another layout pass with all stacked elements contributing // even those that don't usually resize diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 2fdf95df58..6c2df683e4 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -119,6 +119,7 @@ public: BOOL isBackgroundOpaque() const { return mBgOpaque; } void setDefaultBtn(LLButton* btn = NULL); void setDefaultBtn(const LLString& id); + void updateDefaultBtn(); void setLabel(const LLStringExplicit& label) { mLabel = label; } LLString getLabel() const { return mLabel; } diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index d35bd741d7..3e01e8223c 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -121,6 +121,7 @@ public: /*virtual*/ BOOL getCanSelect() const { return TRUE; } /*virtual*/ BOOL selectFirstItem() { return setSelectedIndex(0); } /*virtual*/ BOOL selectNthItem( S32 index ) { return setSelectedIndex(index); } + /*virtual*/ BOOL selectItemRange( S32 first, S32 last ) { return setSelectedIndex(first); } /*virtual*/ S32 getFirstSelectedIndex() const { return getSelectedIndex(); } /*virtual*/ BOOL setCurrentByID( const LLUUID& id ); /*virtual*/ LLUUID getCurrentID() const; // LLUUID::null if no items in menu diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 94053980e6..4227a34777 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -220,22 +220,14 @@ LLScrollListText::LLScrollListText( const LLString& text, const LLFontGL* font, : LLScrollListCell(width), mText( text ), mFont( font ), + mColor(color), + mUseColor(use_color), mFontStyle( font_style ), mFontAlignment( font_alignment ), mVisible( visible ), mHighlightCount( 0 ), mHighlightOffset( 0 ) { - if (use_color) - { - mColor = new LLColor4(); - mColor->setVec(color); - } - else - { - mColor = NULL; - } - sCount++; // initialize rounded rect image @@ -248,7 +240,6 @@ LLScrollListText::LLScrollListText( const LLString& text, const LLFontGL* font, LLScrollListText::~LLScrollListText() { sCount--; - delete mColor; } S32 LLScrollListText::getContentWidth() const @@ -259,11 +250,8 @@ S32 LLScrollListText::getContentWidth() const void LLScrollListText::setColor(const LLColor4& color) { - if (!mColor) - { - mColor = new LLColor4(); - } - *mColor = color; + mColor = color; + mUseColor = TRUE; } void LLScrollListText::setText(const LLStringExplicit& text) @@ -279,14 +267,14 @@ void LLScrollListText::setValue(const LLSD& text) void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const { - const LLColor4* display_color; - if (mColor) + LLColor4 display_color; + if (mUseColor) { display_color = mColor; } else { - display_color = &color; + display_color = color; } if (mHighlightCount > 0) @@ -333,7 +321,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col } mFont->render(mText.getWString(), 0, start_x, 2.f, - *display_color, + display_color, mFontAlignment, LLFontGL::BOTTOM, mFontStyle, @@ -524,6 +512,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, mNeedsScroll(FALSE), mCanSelect(TRUE), mDisplayColumnHeaders(FALSE), + mColumnsDirty(FALSE), mMaxItemCount(INT_MAX), mMaxContentWidth(0), mBackgroundVisible( TRUE ), @@ -636,7 +625,6 @@ void LLScrollListCtrl::clearRows() mScrollLines = 0; mLastSelected = NULL; - calcMaxContentWidth(NULL); updateLayout(); mDirty = FALSE; } @@ -768,7 +756,7 @@ void LLScrollListCtrl::updateLayout() mScrollbar->setDocSize( getItemCount() ); mScrollbar->setVisible(scrollbar_visible); - updateColumns(); + dirtyColumns(); } // Attempt to size the control to show all items. @@ -846,7 +834,6 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r } updateLineHeightInsert(item); - calcMaxContentWidth(item); updateLayout(); } @@ -854,17 +841,14 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r return not_too_big; } -void LLScrollListCtrl::calcMaxContentWidth(LLScrollListItem* added_item) +void LLScrollListCtrl::calcColumnWidths() { const S32 HEADING_TEXT_PADDING = 30; const S32 COLUMN_TEXT_PADDING = 20; - if (added_item == NULL) - { - mMaxContentWidth = 0; - } + mMaxContentWidth = 0; - S32 item_content_width = 0; + S32 max_item_width = 0; ordered_columns_t::iterator column_itor; for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) @@ -872,31 +856,37 @@ void LLScrollListCtrl::calcMaxContentWidth(LLScrollListItem* added_item) LLScrollListColumn* column = *column_itor; if (!column) continue; - if (!added_item) + // update column width + S32 new_width = column->mWidth; + if (column->mRelWidth >= 0) { - // update on all items - column->mMaxContentWidth = column->mHeader ? LLFontGL::sSansSerifSmall->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) - { - LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); - if (!cellp) continue; + new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth()); + } + else if (column->mDynamicWidth) + { + new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; + } - column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); - } + if (new_width != column->mWidth) + { + column->mWidth = new_width; } - else + + // update max content width for this column, by looking at all items + column->mMaxContentWidth = column->mHeader ? LLFontGL::sSansSerifSmall->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { - LLScrollListCell* cellp = added_item->getColumn(column->mIndex); + LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); if (!cellp) continue; column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); } - item_content_width += column->mMaxContentWidth; + max_item_width += column->mMaxContentWidth; } - mMaxContentWidth = llmax(mMaxContentWidth, item_content_width); + mMaxContentWidth = max_item_width; } const S32 SCROLL_LIST_ROW_PAD = 2; @@ -932,29 +922,9 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) void LLScrollListCtrl::updateColumns() { - mColumnsIndexed.resize(mColumns.size()); - - std::map<LLString, LLScrollListColumn>::iterator column_itor; - for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) - { - LLScrollListColumn *column = &column_itor->second; - S32 new_width = column->mWidth; - if (column->mRelWidth >= 0) - { - new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth()); - } - else if (column->mDynamicWidth) - { - new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; - } - - if (new_width != column->mWidth) - { - column->mWidth = new_width; - } - mColumnsIndexed[column_itor->second.mIndex] = column; - } + calcColumnWidths(); + // propagate column widths to individual cells item_list::iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -969,7 +939,7 @@ void LLScrollListCtrl::updateColumns() } } - // update headers + // update column headers std::vector<LLScrollListColumn*>::iterator column_ordered_it; S32 left = mItemListRect.mLeft; LLColumnHeader* last_header = NULL; @@ -1004,6 +974,7 @@ void LLScrollListCtrl::updateColumns() } } + //FIXME: stretch the entire last column if it is resizable (gestures windows shows truncated text in last column) // expand last column header we encountered to full list width if (last_header) { @@ -1061,28 +1032,42 @@ BOOL LLScrollListCtrl::selectFirstItem() return success; } - +// Deselects all other items +// virtual BOOL LLScrollListCtrl::selectNthItem( S32 target_index ) { - if (mItemList.empty()) return FALSE; + return selectItemRange(target_index, target_index); +} - // Deselects all other items - BOOL success = FALSE; - S32 index = 0; +// virtual +BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) +{ + if (mItemList.empty()) + { + return FALSE; + } - target_index = llclamp(target_index, 0, (S32)mItemList.size() - 1); + S32 listlen = (S32)mItemList.size(); + first_index = llclamp(first_index, 0, listlen-1); + + if (last_index < 0) + last_index = listlen-1; + else + last_index = llclamp(last_index, first_index, listlen-1); - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + BOOL success = FALSE; + S32 index = 0; + for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem *itemp = *iter; - if( target_index == index ) + if( index >= first_index && index <= last_index ) { if( itemp->getEnabled() ) { - selectItem(itemp); + selectItem(itemp, FALSE); success = TRUE; - mOriginalSelection = target_index; + if (!success) + mOriginalSelection = first_index; } } else @@ -1131,7 +1116,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) void LLScrollListCtrl::deleteSingleItem(S32 target_index) { - if (target_index >= (S32)mItemList.size()) + if (target_index < 0 || target_index >= (S32)mItemList.size()) { return; } @@ -1144,7 +1129,7 @@ void LLScrollListCtrl::deleteSingleItem(S32 target_index) } delete itemp; mItemList.erase(mItemList.begin() + target_index); - calcMaxContentWidth(NULL); + dirtyColumns(); } //FIXME: refactor item deletion @@ -1169,7 +1154,7 @@ void LLScrollListCtrl::deleteItems(const LLSD& sd) } } - calcMaxContentWidth(NULL); + dirtyColumns(); } void LLScrollListCtrl::deleteSelectedItems() @@ -1189,7 +1174,7 @@ void LLScrollListCtrl::deleteSelectedItems() } } mLastSelected = NULL; - calcMaxContentWidth(NULL); + dirtyColumns(); } void LLScrollListCtrl::highlightNthItem(S32 target_index) @@ -1243,7 +1228,7 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const return -1; } -S32 LLScrollListCtrl::getItemIndex( LLUUID& target_id ) const +S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const { S32 index = 0; item_list::const_iterator iter; @@ -1730,6 +1715,12 @@ void LLScrollListCtrl::draw() gl_rect_2d(background); } + if (mColumnsDirty) + { + updateColumns(); + mColumnsDirty = FALSE; + } + drawItems(); if (mBorder) @@ -1996,9 +1987,8 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) gFocusMgr.setMouseCapture(this); mNeedsScroll = TRUE; } - // otherwise we already have this item selected - // so propagate state of cell to rest of selected column - else + + // propagate state of cell to rest of selected column { // propagate value of this cell to other selected items // and commit the respective widgets @@ -2534,6 +2524,23 @@ void LLScrollListCtrl::sortItems() setSorted(TRUE); } +void LLScrollListCtrl::dirtyColumns() +{ + mColumnsDirty = TRUE; + + // need to keep mColumnsIndexed up to date + // just in case someone indexes into it immediately + mColumnsIndexed.resize(mColumns.size()); + + std::map<LLString, LLScrollListColumn>::iterator column_itor; + for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) + { + LLScrollListColumn *column = &column_itor->second; + mColumnsIndexed[column_itor->second.mIndex] = column; + } +} + + S32 LLScrollListCtrl::getScrollPos() const { return mScrollbar->getDocPos(); @@ -2724,6 +2731,12 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac S32 search_column = 0; node->getAttributeS32("search_column", search_column); + S32 sort_column = -1; + node->getAttributeS32("sort_column", sort_column); + + BOOL sort_ascending = TRUE; + node->getAttributeBOOL("sort_ascending", sort_ascending); + LLUICtrlCallback callback = NULL; LLScrollListCtrl* scroll_list = new LLScrollListCtrl( @@ -2748,6 +2761,11 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac scroll_list->setSearchColumn(search_column); + if (sort_column >= 0) + { + scroll_list->sortByColumn(sort_column, sort_ascending); + } + LLSD columns; S32 index = 0; LLXMLNodePtr child; @@ -3010,7 +3028,7 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) } } - updateColumns(); + dirtyColumns(); } // static @@ -3241,13 +3259,14 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p col_index++; } - S32 num_columns = mColumns.size(); - for (S32 column = 0; column < num_columns; ++column) + // add dummy cells for missing columns + for (column_map_t::iterator column_it = mColumns.begin(); column_it != mColumns.end(); ++column_it) { - if (new_item->getColumn(column) == NULL) + S32 column_idx = column_it->second.mIndex; + if (new_item->getColumn(column_idx) == NULL) { - LLScrollListColumn* column_ptr = mColumnsIndexed[column]; - new_item->setColumn(column, new LLScrollListText("", gResMgr->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL)); + LLScrollListColumn* column_ptr = &column_it->second; + new_item->setColumn(column_idx, new LLScrollListText("", gResMgr->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL)); } } @@ -3649,7 +3668,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d void LLColumnHeader::userSetShape(const LLRect& new_rect) { S32 new_width = new_rect.getWidth(); - S32 delta_width = new_width - getRect().getWidth(); + S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); if (delta_width != 0) { @@ -3721,6 +3740,8 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect) } // tell scroll list to layout columns again + // do immediate update to get proper feedback to resize handle + // which needs to know how far the resize actually went mColumn->mParentCtrl->updateColumns(); } } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index d889512ee6..6edb2939dd 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -120,7 +120,8 @@ public: private: LLUIString mText; const LLFontGL* mFont; - LLColor4* mColor; + LLColor4 mColor; + U8 mUseColor; U8 mFontStyle; LLFontGL::HAlign mFontAlignment; BOOL mVisible; @@ -467,6 +468,7 @@ public: BOOL handleClick(S32 x, S32 y, MASK mask); BOOL selectFirstItem(); BOOL selectNthItem( S32 index ); + BOOL selectItemRange( S32 first, S32 last ); BOOL selectItemAt(S32 x, S32 y, MASK mask); void deleteSingleItem( S32 index ); @@ -486,7 +488,7 @@ public: virtual BOOL getCanSelect() const { return mCanSelect; } S32 getItemIndex( LLScrollListItem* item ) const; - S32 getItemIndex( LLUUID& item_id ) const; + S32 getItemIndex( const LLUUID& item_id ) const; LLScrollListItem* addCommentText( const LLString& comment_text, EAddPosition pos = ADD_BOTTOM); LLScrollListItem* addSeparator(EAddPosition pos); @@ -587,7 +589,7 @@ public: static void onClickColumn(void *userdata); void updateColumns(); - void calcMaxContentWidth(LLScrollListItem* changed_item); + void calcColumnWidths(); S32 getMaxContentWidth() { return mMaxContentWidth; } void setDisplayHeading(BOOL display); @@ -616,6 +618,9 @@ public: S32 selectMultiple( LLDynamicArray<LLUUID> ids ); void sortItems(); + // manually call this whenever editing list items in place to flag need for resorting + void setSorted(BOOL sorted) { mSorted = sorted; } + void dirtyColumns(); // some operation has potentially affected column layout or ordering protected: // "Full" interface: use this when you're creating a list that has one or more of the following: @@ -649,7 +654,6 @@ private: void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE); void deselectItem(LLScrollListItem* itemp); void commitIfChanged(); - void setSorted(BOOL sorted) { mSorted = sorted; } BOOL setSort(S32 column, BOOL ascending); @@ -670,6 +674,7 @@ private: BOOL mNeedsScroll; BOOL mCanSelect; BOOL mDisplayColumnHeaders; + BOOL mColumnsDirty; item_list mItemList; @@ -710,7 +715,8 @@ private: BOOL mSorted; - std::map<LLString, LLScrollListColumn> mColumns; + typedef std::map<LLString, LLScrollListColumn> column_map_t; + column_map_t mColumns; BOOL mDirty; S32 mOriginalSelection; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 1014f17898..56e24085ac 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -760,18 +760,10 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) } } - if( !handled && !called_from_parent) + if( !handled && !called_from_parent && mParentView) { - if (mIsFocusRoot) - { - // stop processing at focus root - handled = FALSE; - } - else if (mParentView) - { - // Upward traversal - handled = mParentView->handleKey( key, mask, FALSE ); - } + // Upward traversal + handled = mParentView->handleKey( key, mask, FALSE ); } return handled; } @@ -806,18 +798,10 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) } - if (!handled && !called_from_parent) + if (!handled && !called_from_parent && mParentView) { - if (mIsFocusRoot) - { - // stop processing at focus root - handled = FALSE; - } - else if(mParentView) - { - // Upward traversal - handled = mParentView->handleUnicodeChar(uni_char, FALSE); - } + // Upward traversal + handled = mParentView->handleUnicodeChar(uni_char, FALSE); } return handled; @@ -1448,7 +1432,12 @@ void LLView::updateBoundingRect() for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* childp = *child_it; - if (!childp->getVisible()) continue; + // ignore invisible and "top" children when calculating bounding rect + // such as combobox popups + if (!childp->getVisible() || childp == gFocusMgr.getTopCtrl()) + { + continue; + } LLRect child_bounding_rect = childp->getBoundingRect(); |