diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llcheckboxctrl.cpp | 2 | ||||
-rw-r--r-- | indra/llui/llcombobox.cpp | 32 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.cpp | 115 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.h | 14 | ||||
-rw-r--r-- | indra/llui/llsliderctrl.cpp | 2 | ||||
-rw-r--r-- | indra/llui/llspinctrl.cpp | 24 |
6 files changed, 125 insertions, 64 deletions
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index fde27132e6..215f6d40ed 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -156,7 +156,7 @@ void LLCheckBoxCtrl::onCommit() void LLCheckBoxCtrl::setEnabled(BOOL b) { - LLUICtrl::setEnabled(b); + LLView::setEnabled(b); mButton->setEnabled(b); } diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index f13e0d54b9..f548045474 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -102,7 +102,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") ); mArrowImage = LLUI::sImageProvider->getUIImageByID(arrow_image_id); - mArrowImageWidth = llmax(8,mArrowImage->getWidth()); // In case image hasn't loaded yet + mArrowImageWidth = llmax(8,mArrowImage->getWidth(0)); // In case image hasn't loaded yet } @@ -202,7 +202,7 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * void LLComboBox::setEnabled(BOOL enabled) { - LLUICtrl::setEnabled(enabled); + LLView::setEnabled(enabled); mButton->setEnabled(enabled); } @@ -477,14 +477,15 @@ void LLComboBox::showList() mList->arrange( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); // Make sure that we can see the whole list - LLRect floater_area_local; - gFloaterView->localRectToOtherView(gFloaterView->getLocalSnapRect(), &floater_area_local, this); + LLRect root_view_local; + LLView* root_view = getRootView(); + root_view->localRectToOtherView(root_view->getLocalRect(), &root_view_local, this); LLRect rect = mList->getRect(); if (mListPosition == BELOW) { - if (rect.getHeight() <= -floater_area_local.mBottom) + if (rect.getHeight() <= -root_view_local.mBottom) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, rect.getWidth(), rect.getHeight() ); @@ -492,44 +493,44 @@ void LLComboBox::showList() else { // stack on top or bottom, depending on which has more room - if (-floater_area_local.mBottom > floater_area_local.mTop - mRect.getHeight()) + if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) { // Move rect so it hangs off the bottom of this view - rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-floater_area_local.mBottom, rect.getHeight())); + rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight())); } else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(floater_area_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); } } } else // ABOVE { - if (rect.getHeight() <= floater_area_local.mTop - mRect.getHeight()) + if (rect.getHeight() <= root_view_local.mTop - mRect.getHeight()) { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(floater_area_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); } else { // stack on top or bottom, depending on which has more room - if (-floater_area_local.mBottom > floater_area_local.mTop - mRect.getHeight()) + if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) { // Move rect so it hangs off the bottom of this view - rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-floater_area_local.mBottom, rect.getHeight())); + rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight())); } else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(floater_area_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); } } } mList->setOrigin(rect.mLeft, rect.mBottom); mList->reshape(rect.getWidth(), rect.getHeight()); - mList->translateIntoRect(floater_area_local, FALSE); + mList->translateIntoRect(root_view_local, FALSE); // Make sure we didn't go off bottom of screen S32 x, y; @@ -656,7 +657,8 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) void LLComboBox::onListFocusChanged(LLUICtrl* list, void* user_data) { LLComboBox *self = (LLComboBox *) list->getParent(); - if (!list->hasFocus()) + // user not manipulating list or clicking on drop down button + if (!self->mList->hasFocus() && !self->mButton->hasMouseCapture()) { //*HACK: store the original value explicitly somewhere, not just in label LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f442855aca..146052538a 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -405,6 +405,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), mSortColumn(-1), + mSorted(TRUE), mSortAscending(TRUE) { mItemListRect.setOriginAndSize( @@ -623,22 +624,28 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos ) { case ADD_TOP: mItemList.push_front(item); + setSorted(FALSE); break; case ADD_SORTED: - mSortColumn = 0; - mSortAscending = TRUE; + if (mSortColumn == -1) + { + mSortColumn = 0; + mSortAscending = TRUE; + } mItemList.push_back(item); std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending)); break; case ADD_BOTTOM: mItemList.push_back(item); + setSorted(FALSE); break; default: llassert(0); mItemList.push_back(item); + setSorted(FALSE); break; } @@ -1094,7 +1101,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection) } } - if ((mCommitOnSelectionChange || mCommitOnKeyboardMovement)) + if (mCommitOnKeyboardMovement) { onCommit(); } @@ -1685,8 +1692,7 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask) } // always commit when mouse operation is completed inside list - // this only needs to be done for lists that don't commit on selection change - if (!mCommitOnSelectionChange && pointInView(x,y)) + if (mItemListRect.pointInRect(x,y)) { mSelectionChanged = FALSE; onCommit(); @@ -2090,6 +2096,16 @@ void LLScrollListCtrl::commitIfChanged() } } +void LLScrollListCtrl::setSorted(BOOL sorted) +{ + mSorted = sorted; +} + +BOOL LLScrollListCtrl::isSorted() +{ + return mSorted; +} + // Called by scrollbar //static void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata ) @@ -2102,10 +2118,11 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void // First column is column 0 void LLScrollListCtrl::sortByColumn(U32 column, BOOL ascending) { - if (mSortColumn != column) + if (!mSorted || mSortColumn != column) { mSortColumn = column; std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending)); + setSorted(TRUE); } // just reverse the list if changing sort order @@ -2358,6 +2375,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac LLString sortname(columnname); child->getAttributeString("sort", sortname); + + BOOL sort_ascending = TRUE; + child->getAttributeBOOL("sort_ascending", sort_ascending); LLString imagename; child->getAttributeString("image", imagename); @@ -2379,6 +2399,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac columns[index]["name"] = columnname; columns[index]["sort"] = sortname; + columns[index]["sort_ascending"] = sort_ascending; columns[index]["image"] = imagename; columns[index]["label"] = labelname; columns[index]["width"] = columnwidth; @@ -2543,6 +2564,13 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) { mDefaultColumn = 0; } + // if no column name provided, just use ordinal as name + if (name.empty()) + { + std::ostringstream new_name; + new_name << mColumnsIndexed.size(); + name = new_name.str(); + } if (mColumns.find(name) == mColumns.end()) { // Add column @@ -2621,6 +2649,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata) U32 column_index = info->mIndex; LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; + bool ascending = column->mSortAscending; if (column->mSortingColumn != column->mName) { if (parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end()) @@ -2630,7 +2659,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata) } } - bool ascending = true; if (column_index == parent->mSortColumn) { ascending = !parent->mSortAscending; @@ -2715,6 +2743,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p // Add any columns we don't already have LLSD columns = value["columns"]; LLSD::array_const_iterator itor; + S32 col_index = 0 ; for (itor = columns.beginArray(); itor != columns.endArray(); ++itor) { LLString column = (*itor)["column"].asString(); @@ -2723,21 +2752,39 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p { mDefaultColumn = 0; } - std::map<LLString, LLScrollListColumn>::iterator column_itor = mColumns.find(column); - if (column_itor == mColumns.end()) + + LLScrollListColumn* columnp = NULL; + + // empty columns strings index by ordinal + if (column.empty()) + { + std::ostringstream new_name; + new_name << col_index; + column = new_name.str(); + } + + std::map<LLString, LLScrollListColumn>::iterator column_itor; + column_itor = mColumns.find(column); + if (column_itor != mColumns.end()) + { + columnp = &column_itor->second; + } + + // create new column on demand + if (!columnp) { LLSD new_column; new_column["name"] = column; new_column["label"] = column; - new_column["width"] = 0; + new_column["width"] = (*itor)["width"]; addColumn(new_column); - column_itor = mColumns.find(column); + columnp = &mColumns.find(column)->second; new_item->setNumColumns(mColumns.size()); } - S32 index = column_itor->second.mIndex; - S32 width = column_itor->second.mWidth; - LLFontGL::HAlign font_alignment = column_itor->second.mFontAlignment; + S32 index = columnp->mIndex; + S32 width = columnp->mWidth; + LLFontGL::HAlign font_alignment = columnp->mFontAlignment; LLSD value = (*itor)["value"]; LLString fontname = (*itor)["font"].asString(); @@ -2770,11 +2817,13 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p else { new_item->setColumn(index, new LLScrollListText(value.asString(), font, width, font_style, font_alignment)); - if (column_itor->second.mHeader && !value.asString().empty()) + if (columnp->mHeader && !value.asString().empty()) { - column_itor->second.mHeader->setHasResizableElement(TRUE); + columnp->mHeader->setHasResizableElement(TRUE); } } + + col_index++; } S32 num_columns = mColumns.size(); @@ -2917,32 +2966,6 @@ LLColumnHeader::LLColumnHeader(const LLString& label, const LLRect &rect, LLScro mAscendingText = "[LOW]...[HIGH](Ascending)"; mDescendingText = "[HIGH]...[LOW](Descending)"; - LLSD row; - row["columns"][0]["column"] = "label"; - row["columns"][0]["value"] = mAscendingText.getString(); - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - row["columns"][0]["width"] = 80; - - row["columns"][1]["column"] = "arrow"; - row["columns"][1]["type"] = "icon"; - row["columns"][1]["value"] = LLUI::sAssetsGroup->getString("up_arrow.tga"); - row["columns"][1]["width"] = 20; - - mList->addElement(row); - - row["columns"][0]["column"] = "label"; - row["columns"][0]["type"] = "text"; - row["columns"][0]["value"] = mDescendingText.getString(); - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - row["columns"][0]["width"] = 80; - - row["columns"][1]["column"] = "arrow"; - row["columns"][1]["type"] = "icon"; - row["columns"][1]["value"] = LLUI::sAssetsGroup->getString("down_arrow.tga"); - row["columns"][1]["width"] = 20; - - mList->addElement(row); - mList->reshape(llmax(mList->getRect().getWidth(), 110, mRect.getWidth()), mList->getRect().getHeight()); // resize handles on left and right @@ -2964,7 +2987,7 @@ void LLColumnHeader::draw() { if( getVisible() ) { - mDrawArrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn; + mDrawArrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn; BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); mArrowImage = is_ascending ? LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("up_arrow.tga"))) @@ -3311,7 +3334,11 @@ void LLColumnHeader::setHasResizableElement(BOOL resizable) void LLColumnHeader::enableResizeBar(BOOL enable) { - mResizeBar->setEnabled(enable); + // for now, dynamically spaced columns can't be resized + if (!mColumn->mDynamicWidth) + { + mResizeBar->setEnabled(enable); + } } BOOL LLColumnHeader::canResize() diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 7a0a32c87e..de9b58bd1e 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -142,6 +142,7 @@ public: LLScrollListColumn() : mName(""), mSortingColumn(""), + mSortAscending(TRUE), mLabel(""), mWidth(-1), mRelWidth(-1.0), @@ -156,6 +157,7 @@ public: LLScrollListColumn(LLString name, LLString label, S32 width, F32 relwidth) : mName(name), mSortingColumn(name), + mSortAscending(TRUE), mLabel(label), mWidth(width), mRelWidth(relwidth), @@ -176,6 +178,11 @@ public: { mSortingColumn = sd.get("sort").asString(); } + mSortAscending = TRUE; + if (sd.has("sort_ascending")) + { + mSortAscending = sd.get("sort_ascending").asBoolean(); + } mLabel = sd.get("label").asString(); if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0) { @@ -210,6 +217,7 @@ public: LLString mName; LLString mSortingColumn; + BOOL mSortAscending; LLString mLabel; S32 mWidth; F32 mRelWidth; @@ -381,8 +389,10 @@ public: // Returns FALSE if not found. BOOL setSelectedByValue(LLSD value, BOOL selected); - virtual BOOL isSelected(LLSD value); + BOOL isSorted(); + virtual BOOL isSelected(LLSD value); + BOOL selectFirstItem(); BOOL selectNthItem( S32 index ); BOOL selectItemAt(S32 x, S32 y, MASK mask); @@ -552,6 +562,7 @@ protected: void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE); void deselectItem(LLScrollListItem* itemp); void commitIfChanged(); + void setSorted(BOOL sorted); protected: S32 mCurIndex; // For get[First/Next]Data @@ -615,6 +626,7 @@ protected: S32 mSortColumn; BOOL mSortAscending; + BOOL mSorted; std::map<LLString, LLScrollListColumn> mColumns; std::vector<LLScrollListColumn*> mColumnsIndexed; diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index b3c49e81f1..8b5cd4690e 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -300,7 +300,7 @@ void LLSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata ) void LLSliderCtrl::setEnabled(BOOL b) { - LLUICtrl::setEnabled( b ); + LLView::setEnabled( b ); if( mLabelBox ) { diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index fbd8335e6c..34363eb506 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -123,6 +123,23 @@ LLSpinCtrl::~LLSpinCtrl() } +F32 clamp_precision(F32 value, S32 decimal_precision) +{ + // pow() isn't perfect + + F64 clamped_value = value; + for (S32 i = 0; i < decimal_precision; i++) + clamped_value *= 10.0; + + clamped_value = llround((F32)clamped_value); + + for (S32 i = 0; i < decimal_precision; i++) + clamped_value /= 10.0; + + return (F32)clamped_value; +} + + // static void LLSpinCtrl::onUpBtn( void *userdata ) { @@ -131,6 +148,7 @@ void LLSpinCtrl::onUpBtn( void *userdata ) { // use getValue()/setValue() to force reload from/to control F32 val = (F32)self->getValue().asReal() + self->mIncrement; + val = clamp_precision(val, self->mPrecision); val = llmin( val, self->mMaxValue ); if( self->mValidateCallback ) @@ -163,6 +181,7 @@ void LLSpinCtrl::onDownBtn( void *userdata ) if( self->getEnabled() ) { F32 val = (F32)self->getValue().asReal() - self->mIncrement; + val = clamp_precision(val, self->mPrecision); val = llmax( val, self->mMinValue ); if( self->mValidateCallback ) @@ -224,12 +243,13 @@ void LLSpinCtrl::clear() } + void LLSpinCtrl::updateEditor() { LLLocale locale(LLLocale::USER_LOCALE); // Don't display very small negative values as -0.000 - F32 displayed_value = (F32)floor(getValue().asReal() * pow(10.0, (F64)mPrecision) + 0.5) / (F32)pow(10.0, (F64)mPrecision); + F32 displayed_value = clamp_precision((F32)getValue().asReal(), mPrecision); // if( S32( displayed_value * pow( 10, mPrecision ) ) == 0 ) // { @@ -301,7 +321,7 @@ void LLSpinCtrl::setFocus(BOOL b) void LLSpinCtrl::setEnabled(BOOL b) { - LLUICtrl::setEnabled( b ); + LLView::setEnabled( b ); mEditor->setEnabled( b ); } |