aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/llscrolllistctrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llui/llscrolllistctrl.cpp')
-rw-r--r--linden/indra/llui/llscrolllistctrl.cpp353
1 files changed, 251 insertions, 102 deletions
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp
index 7dba55f..7b6c125 100644
--- a/linden/indra/llui/llscrolllistctrl.cpp
+++ b/linden/indra/llui/llscrolllistctrl.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -378,6 +379,22 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
378 TRUE); 379 TRUE);
379} 380}
380 381
382LLScrollListDate::LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible)
383: LLScrollListText(date.asRFC1123(), font, width, font_style, font_alignment, color, use_color, visible),
384 mDate(date)
385{
386}
387
388void LLScrollListDate::setValue(const LLSD& value)
389{
390 mDate = value.asDate();
391 LLScrollListText::setValue(mDate.asRFC1123());
392}
393
394const LLSD LLScrollListDate::getValue() const
395{
396 return mDate;
397}
381 398
382LLScrollListItem::~LLScrollListItem() 399LLScrollListItem::~LLScrollListItem()
383{ 400{
@@ -578,6 +595,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
578 mSearchColumn(0), 595 mSearchColumn(0),
579 mNumDynamicWidthColumns(0), 596 mNumDynamicWidthColumns(0),
580 mTotalStaticColumnWidth(0), 597 mTotalStaticColumnWidth(0),
598 mTotalColumnPadding(0),
581 mSorted(TRUE), 599 mSorted(TRUE),
582 mDirty(FALSE), 600 mDirty(FALSE),
583 mOriginalSelection(-1), 601 mOriginalSelection(-1),
@@ -627,6 +645,28 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
627 mLastSelected = NULL; 645 mLastSelected = NULL;
628} 646}
629 647
648S32 LLScrollListCtrl::getSearchColumn()
649{
650 // search for proper search column
651 if (mSearchColumn < 0)
652 {
653 LLScrollListItem* itemp = getFirstData();
654 if (itemp)
655 {
656 for(S32 column = 0; column < getNumColumns(); column++)
657 {
658 LLScrollListCell* cell = itemp->getColumn(column);
659 if (cell && cell->isText())
660 {
661 mSearchColumn = column;
662 break;
663 }
664 }
665 }
666 }
667 return llclamp(mSearchColumn, 0, getNumColumns());
668}
669
630LLScrollListCtrl::~LLScrollListCtrl() 670LLScrollListCtrl::~LLScrollListCtrl()
631{ 671{
632 std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); 672 std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
@@ -890,8 +930,8 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
890// *TODO: Use bookkeeping to make this an incramental cost with item additions 930// *TODO: Use bookkeeping to make this an incramental cost with item additions
891void LLScrollListCtrl::calcColumnWidths() 931void LLScrollListCtrl::calcColumnWidths()
892{ 932{
893 const S32 HEADING_TEXT_PADDING = 30; 933 const S32 HEADING_TEXT_PADDING = 25;
894 const S32 COLUMN_TEXT_PADDING = 20; 934 const S32 COLUMN_TEXT_PADDING = 10;
895 935
896 mMaxContentWidth = 0; 936 mMaxContentWidth = 0;
897 937
@@ -904,30 +944,27 @@ void LLScrollListCtrl::calcColumnWidths()
904 if (!column) continue; 944 if (!column) continue;
905 945
906 // update column width 946 // update column width
907 S32 new_width = column->mWidth; 947 S32 new_width = column->getWidth();
908 if (column->mRelWidth >= 0) 948 if (column->mRelWidth >= 0)
909 { 949 {
910 new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth()); 950 new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth());
911 } 951 }
912 else if (column->mDynamicWidth) 952 else if (column->mDynamicWidth)
913 { 953 {
914 new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; 954 new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns;
915 } 955 }
916 956
917 if (new_width != column->mWidth) 957 column->setWidth(new_width);
918 {
919 column->mWidth = new_width;
920 }
921 958
922 // update max content width for this column, by looking at all items 959 // update max content width for this column, by looking at all items
923 column->mMaxContentWidth = column->mHeader ? LLFontGL::sSansSerifSmall->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; 960 column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
924 item_list::iterator iter; 961 item_list::iterator iter;
925 for (iter = mItemList.begin(); iter != mItemList.end(); iter++) 962 for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
926 { 963 {
927 LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); 964 LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
928 if (!cellp) continue; 965 if (!cellp) continue;
929 966
930 column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); 967 column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
931 } 968 }
932 969
933 max_item_width += column->mMaxContentWidth; 970 max_item_width += column->mMaxContentWidth;
@@ -971,28 +1008,13 @@ void LLScrollListCtrl::updateColumns()
971{ 1008{
972 calcColumnWidths(); 1009 calcColumnWidths();
973 1010
974 // propagate column widths to individual cells
975 item_list::iterator iter;
976 for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
977 {
978 LLScrollListItem *itemp = *iter;
979 S32 num_cols = itemp->getNumColumns();
980 S32 i = 0;
981 for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
982 {
983 if (i >= (S32)mColumnsIndexed.size()) break;
984
985 cell->setWidth(mColumnsIndexed[i]->mWidth);
986 }
987 }
988
989 // update column headers 1011 // update column headers
990 std::vector<LLScrollListColumn*>::iterator column_ordered_it; 1012 std::vector<LLScrollListColumn*>::iterator column_ordered_it;
991 S32 left = mItemListRect.mLeft; 1013 S32 left = mItemListRect.mLeft;
992 LLColumnHeader* last_header = NULL; 1014 LLColumnHeader* last_header = NULL;
993 for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it) 1015 for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it)
994 { 1016 {
995 if ((*column_ordered_it)->mWidth < 0) 1017 if ((*column_ordered_it)->getWidth() < 0)
996 { 1018 {
997 // skip hidden columns 1019 // skip hidden columns
998 continue; 1020 continue;
@@ -1001,9 +1023,11 @@ void LLScrollListCtrl::updateColumns()
1001 1023
1002 if (column->mHeader) 1024 if (column->mHeader)
1003 { 1025 {
1026 column->mHeader->updateResizeBars();
1027
1004 last_header = column->mHeader; 1028 last_header = column->mHeader;
1005 S32 top = mItemListRect.mTop; 1029 S32 top = mItemListRect.mTop;
1006 S32 right = left + column->mWidth; 1030 S32 right = left + column->getWidth();
1007 1031
1008 if (column->mIndex != (S32)mColumnsIndexed.size()-1) 1032 if (column->mIndex != (S32)mColumnsIndexed.size()-1)
1009 { 1033 {
@@ -1021,14 +1045,30 @@ void LLScrollListCtrl::updateColumns()
1021 } 1045 }
1022 } 1046 }
1023 1047
1024 //FIXME: stretch the entire last column if it is resizable (gestures windows shows truncated text in last column)
1025 // expand last column header we encountered to full list width 1048 // expand last column header we encountered to full list width
1026 if (last_header) 1049 if (last_header && last_header->canResize())
1027 { 1050 {
1028 S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft); 1051 S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft);
1029 last_header->reshape(new_width, last_header->getRect().getHeight()); 1052 last_header->reshape(new_width, last_header->getRect().getHeight());
1030 last_header->setVisible(mDisplayColumnHeaders && new_width > 0); 1053 last_header->setVisible(mDisplayColumnHeaders && new_width > 0);
1054 last_header->getColumn()->setWidth(new_width);
1055 }
1056
1057 // propagate column widths to individual cells
1058 item_list::iterator iter;
1059 for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
1060 {
1061 LLScrollListItem *itemp = *iter;
1062 S32 num_cols = itemp->getNumColumns();
1063 S32 i = 0;
1064 for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
1065 {
1066 if (i >= (S32)mColumnsIndexed.size()) break;
1067
1068 cell->setWidth(mColumnsIndexed[i]->getWidth());
1069 }
1031 } 1070 }
1071
1032} 1072}
1033 1073
1034void LLScrollListCtrl::setDisplayHeading(BOOL display) 1074void LLScrollListCtrl::setDisplayHeading(BOOL display)
@@ -1490,7 +1530,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
1490 { 1530 {
1491 LLScrollListItem* item = *iter; 1531 LLScrollListItem* item = *iter;
1492 // Only select enabled items with matching names 1532 // Only select enabled items with matching names
1493 LLScrollListCell* cellp = item->getColumn(mSearchColumn); 1533 LLScrollListCell* cellp = item->getColumn(getSearchColumn());
1494 BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; 1534 BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
1495 if (select) 1535 if (select)
1496 { 1536 {
@@ -1513,7 +1553,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
1513 LLScrollListItem* item = *iter; 1553 LLScrollListItem* item = *iter;
1514 1554
1515 // Only select enabled items with matching names 1555 // Only select enabled items with matching names
1516 LLScrollListCell* cellp = item->getColumn(mSearchColumn); 1556 LLScrollListCell* cellp = item->getColumn(getSearchColumn());
1517 if (!cellp) 1557 if (!cellp)
1518 { 1558 {
1519 continue; 1559 continue;
@@ -1743,6 +1783,8 @@ void LLScrollListCtrl::drawItems()
1743 1783
1744void LLScrollListCtrl::draw() 1784void LLScrollListCtrl::draw()
1745{ 1785{
1786 LLLocalClipRect clip(getLocalRect());
1787
1746 // if user specifies sort, make sure it is maintained 1788 // if user specifies sort, make sure it is maintained
1747 if (needsSorting() && !isSorted()) 1789 if (needsSorting() && !isSorted())
1748 { 1790 {
@@ -1816,7 +1858,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti
1816 S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; 1858 S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
1817 S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item)); 1859 S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item));
1818 LLRect cell_rect; 1860 LLRect cell_rect;
1819 cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->mWidth, mLineHeight); 1861 cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);
1820 // Convert rect local to screen coordinates 1862 // Convert rect local to screen coordinates
1821 localPointToScreen( 1863 localPointToScreen(
1822 cell_rect.mLeft, cell_rect.mBottom, 1864 cell_rect.mLeft, cell_rect.mBottom,
@@ -2113,7 +2155,7 @@ S32 LLScrollListCtrl::getColumnIndexFromOffset(S32 x)
2113 ordered_columns_t::const_iterator end = mColumnsIndexed.end(); 2155 ordered_columns_t::const_iterator end = mColumnsIndexed.end();
2114 for ( ; iter != end; ++iter) 2156 for ( ; iter != end; ++iter)
2115 { 2157 {
2116 width = (*iter)->mWidth + mColumnPadding; 2158 width = (*iter)->getWidth() + mColumnPadding;
2117 right += width; 2159 right += width;
2118 if (left <= x && x < right ) 2160 if (left <= x && x < right )
2119 { 2161 {
@@ -2140,7 +2182,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index)
2140 { 2182 {
2141 return column_offset; 2183 return column_offset;
2142 } 2184 }
2143 column_offset += (*iter)->mWidth + mColumnPadding; 2185 column_offset += (*iter)->getWidth() + mColumnPadding;
2144 } 2186 }
2145 2187
2146 // when running off the end, return the rightmost pixel 2188 // when running off the end, return the rightmost pixel
@@ -2292,7 +2334,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
2292 { 2334 {
2293 if (getFirstSelected()) 2335 if (getFirstSelected())
2294 { 2336 {
2295 LLScrollListCell* cellp = getFirstSelected()->getColumn(mSearchColumn); 2337 LLScrollListCell* cellp = getFirstSelected()->getColumn(getSearchColumn());
2296 if (cellp) 2338 if (cellp)
2297 { 2339 {
2298 cellp->highlightText(0, 0); 2340 cellp->highlightText(0, 0);
@@ -2379,7 +2421,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
2379 { 2421 {
2380 LLScrollListItem* item = *iter; 2422 LLScrollListItem* item = *iter;
2381 2423
2382 LLScrollListCell* cellp = item->getColumn(mSearchColumn); 2424 LLScrollListCell* cellp = item->getColumn(getSearchColumn());
2383 if (cellp) 2425 if (cellp)
2384 { 2426 {
2385 // Only select enabled items with matching first characters 2427 // Only select enabled items with matching first characters
@@ -2446,7 +2488,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
2446 { 2488 {
2447 if (mLastSelected) 2489 if (mLastSelected)
2448 { 2490 {
2449 LLScrollListCell* cellp = mLastSelected->getColumn(mSearchColumn); 2491 LLScrollListCell* cellp = mLastSelected->getColumn(getSearchColumn());
2450 if (cellp) 2492 if (cellp)
2451 { 2493 {
2452 cellp->highlightText(0, 0); 2494 cellp->highlightText(0, 0);
@@ -2474,7 +2516,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp)
2474 } 2516 }
2475 2517
2476 itemp->setSelected(FALSE); 2518 itemp->setSelected(FALSE);
2477 LLScrollListCell* cellp = itemp->getColumn(mSearchColumn); 2519 LLScrollListCell* cellp = itemp->getColumn(getSearchColumn());
2478 if (cellp) 2520 if (cellp)
2479 { 2521 {
2480 cellp->highlightText(0, 0); 2522 cellp->highlightText(0, 0);
@@ -2501,9 +2543,14 @@ struct SameSortColumn
2501 bool operator()(std::pair<S32, BOOL> sort_column) { return sort_column.first == mColumn; } 2543 bool operator()(std::pair<S32, BOOL> sort_column) { return sort_column.first == mColumn; }
2502}; 2544};
2503 2545
2504BOOL LLScrollListCtrl::setSort(S32 column, BOOL ascending) 2546BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
2505{ 2547{
2506 sort_column_t new_sort_column(column, ascending); 2548 LLScrollListColumn* sort_column = getColumn(column_idx);
2549 if (!sort_column) return FALSE;
2550
2551 sort_column->mSortAscending = ascending;
2552
2553 sort_column_t new_sort_column(column_idx, ascending);
2507 2554
2508 if (mSortColumns.empty()) 2555 if (mSortColumns.empty())
2509 { 2556 {
@@ -2517,7 +2564,7 @@ BOOL LLScrollListCtrl::setSort(S32 column, BOOL ascending)
2517 2564
2518 // remove any existing sort criterion referencing this column 2565 // remove any existing sort criterion referencing this column
2519 // and add the new one 2566 // and add the new one
2520 mSortColumns.erase(remove_if(mSortColumns.begin(), mSortColumns.end(), SameSortColumn(column)), mSortColumns.end()); 2567 mSortColumns.erase(remove_if(mSortColumns.begin(), mSortColumns.end(), SameSortColumn(column_idx)), mSortColumns.end());
2521 mSortColumns.push_back(new_sort_column); 2568 mSortColumns.push_back(new_sort_column);
2522 2569
2523 // did the sort criteria change? 2570 // did the sort criteria change?
@@ -2643,6 +2690,12 @@ void LLScrollListCtrl::scrollToShowSelected()
2643 } 2690 }
2644} 2691}
2645 2692
2693void LLScrollListCtrl::updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width)
2694{
2695 mTotalStaticColumnWidth += llmax(0, new_width) - llmax(0, col->getWidth());
2696}
2697
2698
2646// virtual 2699// virtual
2647LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const 2700LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
2648{ 2701{
@@ -2689,7 +2742,7 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
2689 2742
2690 child_node->createChild("name", TRUE)->setStringValue(column->mName); 2743 child_node->createChild("name", TRUE)->setStringValue(column->mName);
2691 child_node->createChild("label", TRUE)->setStringValue(column->mLabel); 2744 child_node->createChild("label", TRUE)->setStringValue(column->mLabel);
2692 child_node->createChild("width", TRUE)->setIntValue(column->mWidth); 2745 child_node->createChild("width", TRUE)->setIntValue(column->getWidth());
2693 } 2746 }
2694 2747
2695 return node; 2748 return node;
@@ -2813,15 +2866,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
2813 2866
2814 scroll_list->setSearchColumn(search_column); 2867 scroll_list->setSearchColumn(search_column);
2815 2868
2816 if (sort_column >= 0)
2817 {
2818 scroll_list->sortByColumnIndex(sort_column, sort_ascending);
2819 }
2820
2821 LLSD columns; 2869 LLSD columns;
2822 S32 index = 0; 2870 S32 index = 0;
2823 LLXMLNodePtr child; 2871 LLXMLNodePtr child;
2824 S32 total_static = 0;
2825 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) 2872 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
2826 { 2873 {
2827 if (child->hasName("column")) 2874 if (child->hasName("column"))
@@ -2850,8 +2897,6 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
2850 std::string tooltip; 2897 std::string tooltip;
2851 child->getAttributeString("tool_tip", tooltip); 2898 child->getAttributeString("tool_tip", tooltip);
2852 2899
2853 if(!columndynamicwidth) total_static += llmax(0, columnwidth);
2854
2855 F32 columnrelwidth = 0.f; 2900 F32 columnrelwidth = 0.f;
2856 child->getAttributeF32("relwidth", columnrelwidth); 2901 child->getAttributeF32("relwidth", columnrelwidth);
2857 2902
@@ -2872,9 +2917,13 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
2872 index++; 2917 index++;
2873 } 2918 }
2874 } 2919 }
2875 scroll_list->setTotalStaticColumnWidth(total_static);
2876 scroll_list->setColumnHeadings(columns); 2920 scroll_list->setColumnHeadings(columns);
2877 2921
2922 if (sort_column >= 0)
2923 {
2924 scroll_list->sortByColumnIndex(sort_column, sort_ascending);
2925 }
2926
2878 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) 2927 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
2879 { 2928 {
2880 if (child->hasName("row")) 2929 if (child->hasName("row"))
@@ -3019,22 +3068,26 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
3019 if (mColumns.find(name) == mColumns.end()) 3068 if (mColumns.find(name) == mColumns.end())
3020 { 3069 {
3021 // Add column 3070 // Add column
3022 mColumns[name] = LLScrollListColumn(column); 3071 mColumns[name] = LLScrollListColumn(column, this);
3023 LLScrollListColumn* new_column = &mColumns[name]; 3072 LLScrollListColumn* new_column = &mColumns[name];
3024 new_column->mParentCtrl = this; 3073 new_column->mParentCtrl = this;
3025 new_column->mIndex = mColumns.size()-1; 3074 new_column->mIndex = mColumns.size()-1;
3026 3075
3027 // Add button 3076 // Add button
3028 if (new_column->mWidth > 0 || new_column->mRelWidth > 0 || new_column->mDynamicWidth) 3077 if (new_column->getWidth() > 0 || new_column->mRelWidth > 0 || new_column->mDynamicWidth)
3029 { 3078 {
3079 if (getNumColumns() > 0)
3080 {
3081 mTotalColumnPadding += mColumnPadding;
3082 }
3030 if (new_column->mRelWidth >= 0) 3083 if (new_column->mRelWidth >= 0)
3031 { 3084 {
3032 new_column->mWidth = (S32)llround(new_column->mRelWidth*mItemListRect.getWidth()); 3085 new_column->setWidth((S32)llround(new_column->mRelWidth*mItemListRect.getWidth()));
3033 } 3086 }
3034 else if(new_column->mDynamicWidth) 3087 else if(new_column->mDynamicWidth)
3035 { 3088 {
3036 mNumDynamicWidthColumns++; 3089 mNumDynamicWidthColumns++;
3037 new_column->mWidth = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; 3090 new_column->setWidth((mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns);
3038 } 3091 }
3039 S32 top = mItemListRect.mTop; 3092 S32 top = mItemListRect.mTop;
3040 S32 left = mItemListRect.mLeft; 3093 S32 left = mItemListRect.mLeft;
@@ -3043,14 +3096,14 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
3043 for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) 3096 for (itor = mColumns.begin(); itor != mColumns.end(); ++itor)
3044 { 3097 {
3045 if (itor->second.mIndex < new_column->mIndex && 3098 if (itor->second.mIndex < new_column->mIndex &&
3046 itor->second.mWidth > 0) 3099 itor->second.getWidth() > 0)
3047 { 3100 {
3048 left += itor->second.mWidth + mColumnPadding; 3101 left += itor->second.getWidth() + mColumnPadding;
3049 } 3102 }
3050 } 3103 }
3051 } 3104 }
3052 std::string button_name = "btn_" + name; 3105 std::string button_name = "btn_" + name;
3053 S32 right = left+new_column->mWidth; 3106 S32 right = left+new_column->getWidth();
3054 if (new_column->mIndex != (S32)mColumns.size()-1) 3107 if (new_column->mIndex != (S32)mColumns.size()-1)
3055 { 3108 {
3056 right += mColumnPadding; 3109 right += mColumnPadding;
@@ -3145,6 +3198,8 @@ void LLScrollListCtrl::clearColumns()
3145 } 3198 }
3146 mColumns.clear(); 3199 mColumns.clear();
3147 mSortColumns.clear(); 3200 mSortColumns.clear();
3201 mTotalStaticColumnWidth = 0;
3202 mTotalColumnPadding = 0;
3148} 3203}
3149 3204
3150void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label) 3205void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label)
@@ -3244,7 +3299,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
3244 } 3299 }
3245 3300
3246 S32 index = columnp->mIndex; 3301 S32 index = columnp->mIndex;
3247 S32 width = columnp->mWidth; 3302 S32 width = columnp->getWidth();
3248 LLFontGL::HAlign font_alignment = columnp->mFontAlignment; 3303 LLFontGL::HAlign font_alignment = columnp->mFontAlignment;
3249 LLColor4 fcolor = LLColor4::black; 3304 LLColor4 fcolor = LLColor4::black;
3250 3305
@@ -3301,6 +3356,19 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
3301 } 3356 }
3302 new_item->setColumn(index, cell); 3357 new_item->setColumn(index, cell);
3303 } 3358 }
3359 else if (type == "date")
3360 {
3361 LLScrollListDate* cell = new LLScrollListDate(value.asDate(), font, width, font_style, font_alignment);
3362 if (has_color)
3363 {
3364 cell->setColor(color);
3365 }
3366 new_item->setColumn(index, cell);
3367 if (columnp->mHeader && !value.asString().empty())
3368 {
3369 columnp->mHeader->setHasResizableElement(TRUE);
3370 }
3371 }
3304 else 3372 else
3305 { 3373 {
3306 LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment, fcolor, TRUE); 3374 LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment, fcolor, TRUE);
@@ -3325,7 +3393,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
3325 if (new_item->getColumn(column_idx) == NULL) 3393 if (new_item->getColumn(column_idx) == NULL)
3326 { 3394 {
3327 LLScrollListColumn* column_ptr = &column_it->second; 3395 LLScrollListColumn* column_ptr = &column_it->second;
3328 new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL)); 3396 new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL));
3329 } 3397 }
3330 } 3398 }
3331 3399
@@ -3469,6 +3537,7 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS
3469 mButton->setMouseDownCallback(onMouseDown); 3537 mButton->setMouseDownCallback(onMouseDown);
3470 3538
3471 mButton->setCallbackUserData(this); 3539 mButton->setCallbackUserData(this);
3540 mButton->setToolTip(label);
3472 3541
3473 mAscendingText = std::string("[LOW]...[HIGH](Ascending)"); // *TODO: Translate 3542 mAscendingText = std::string("[LOW]...[HIGH](Ascending)"); // *TODO: Translate
3474 mDescendingText = std::string("[HIGH]...[LOW](Descending)"); // *TODO: Translate 3543 mDescendingText = std::string("[HIGH]...[LOW](Descending)"); // *TODO: Translate
@@ -3556,7 +3625,7 @@ void LLColumnHeader::onClick(void* user_data)
3556 3625
3557 LLScrollListCtrl::onClickColumn(column); 3626 LLScrollListCtrl::onClickColumn(column);
3558 3627
3559 // propage new sort order to sort order list 3628 // propagate new sort order to sort order list
3560 headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1); 3629 headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1);
3561} 3630}
3562 3631
@@ -3642,11 +3711,11 @@ void LLColumnHeader::showList()
3642 descending_string = mDescendingText.getString(); 3711 descending_string = mDescendingText.getString();
3643 } 3712 }
3644 3713
3645 S32 text_width = LLFontGL::sSansSerifSmall->getWidth(ascending_string); 3714 S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(ascending_string);
3646 text_width = llmax(text_width, LLFontGL::sSansSerifSmall->getWidth(descending_string)) + 10; 3715 text_width = llmax(text_width, LLFontGL::getFontSansSerifSmall()->getWidth(descending_string)) + 10;
3647 text_width = llmax(text_width, getRect().getWidth() - 30); 3716 text_width = llmax(text_width, getRect().getWidth() - 30);
3648 3717
3649 mList->getColumn(0)->mWidth = text_width; 3718 mList->getColumn(0)->setWidth(text_width);
3650 ((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string); 3719 ((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string);
3651 ((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string); 3720 ((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string);
3652 3721
@@ -3688,7 +3757,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d
3688 llassert(snap_edge == SNAP_RIGHT); 3757 llassert(snap_edge == SNAP_RIGHT);
3689 3758
3690 // use higher snap threshold for column headers 3759 // use higher snap threshold for column headers
3691 threshold = llmin(threshold, 15); 3760 threshold = llmin(threshold, 10);
3692 3761
3693 LLRect snap_rect = getSnapRect(); 3762 LLRect snap_rect = getSnapRect();
3694 3763
@@ -3727,47 +3796,48 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
3727 3796
3728 if (delta_width != 0) 3797 if (delta_width != 0)
3729 { 3798 {
3730 S32 remaining_width = delta_width; 3799 S32 remaining_width = -delta_width;
3731 S32 col; 3800 S32 col;
3732 for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++) 3801 for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++)
3733 { 3802 {
3734 LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); 3803 LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
3735 if (!columnp) break; 3804 if (!columnp) continue;
3736 3805
3737 if (columnp->mHeader && columnp->mHeader->canResize()) 3806 if (columnp->mHeader && columnp->mHeader->canResize())
3738 { 3807 {
3739 // how many pixels in width can this column afford to give up? 3808 // how many pixels in width can this column afford to give up?
3740 S32 resize_buffer_amt = llmax(0, columnp->mWidth - MIN_COLUMN_WIDTH); 3809 S32 resize_buffer_amt = llmax(0, columnp->getWidth() - MIN_COLUMN_WIDTH);
3741 3810
3742 // user shrinking column, need to add width to other columns 3811 // user shrinking column, need to add width to other columns
3743 if (delta_width < 0) 3812 if (delta_width < 0)
3744 { 3813 {
3745 if (!columnp->mDynamicWidth && columnp->mWidth > 0) 3814 if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
3746 { 3815 {
3747 // statically sized column, give all remaining width to this column 3816 // statically sized column, give all remaining width to this column
3748 columnp->mWidth -= remaining_width; 3817 columnp->setWidth(columnp->getWidth() + remaining_width);
3749 if (columnp->mRelWidth > 0.f) 3818 if (columnp->mRelWidth > 0.f)
3750 { 3819 {
3751 columnp->mRelWidth = (F32)columnp->mWidth / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); 3820 columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
3752 } 3821 }
3822 // all padding went to this widget, we're done
3823 break;
3753 } 3824 }
3754 break;
3755 } 3825 }
3756 else 3826 else
3757 { 3827 {
3758 // user growing column, need to take width from other columns 3828 // user growing column, need to take width from other columns
3759 remaining_width -= resize_buffer_amt; 3829 remaining_width += resize_buffer_amt;
3760 3830
3761 if (!columnp->mDynamicWidth && columnp->mWidth > 0) 3831 if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
3762 { 3832 {
3763 columnp->mWidth -= llmin(columnp->mWidth - MIN_COLUMN_WIDTH, delta_width); 3833 columnp->setWidth(columnp->getWidth() - llmin(columnp->getWidth() - MIN_COLUMN_WIDTH, delta_width));
3764 if (columnp->mRelWidth > 0.f) 3834 if (columnp->mRelWidth > 0.f)
3765 { 3835 {
3766 columnp->mRelWidth = (F32)columnp->mWidth / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); 3836 columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
3767 } 3837 }
3768 } 3838 }
3769 3839
3770 if (remaining_width <= 0) 3840 if (remaining_width >= 0)
3771 { 3841 {
3772 // width sucked up from neighboring columns, done 3842 // width sucked up from neighboring columns, done
3773 break; 3843 break;
@@ -3779,14 +3849,14 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
3779 // clamp resize amount to maximum that can be absorbed by other columns 3849 // clamp resize amount to maximum that can be absorbed by other columns
3780 if (delta_width > 0) 3850 if (delta_width > 0)
3781 { 3851 {
3782 delta_width -= llmax(remaining_width, 0); 3852 delta_width += llmin(remaining_width, 0);
3783 } 3853 }
3784 3854
3785 // propagate constrained delta_width to new width for this column 3855 // propagate constrained delta_width to new width for this column
3786 new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding(); 3856 new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding();
3787 3857
3788 // use requested width 3858 // use requested width
3789 mColumn->mWidth = new_width; 3859 mColumn->setWidth(new_width);
3790 3860
3791 // update proportional spacing 3861 // update proportional spacing
3792 if (mColumn->mRelWidth > 0.f) 3862 if (mColumn->mRelWidth > 0.f)
@@ -3804,36 +3874,40 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
3804void LLColumnHeader::setHasResizableElement(BOOL resizable) 3874void LLColumnHeader::setHasResizableElement(BOOL resizable)
3805{ 3875{
3806 // for now, dynamically spaced columns can't be resized 3876 // for now, dynamically spaced columns can't be resized
3807 if (mColumn->mDynamicWidth) return; 3877// if (mColumn->mDynamicWidth) return;
3808 3878
3809 if (resizable != mHasResizableElement) 3879 if (mHasResizableElement != resizable)
3810 { 3880 {
3881 mColumn->mParentCtrl->dirtyColumns();
3811 mHasResizableElement = resizable; 3882 mHasResizableElement = resizable;
3883 }
3884}
3812 3885
3813 S32 num_resizable_columns = 0; 3886void LLColumnHeader::updateResizeBars()
3814 S32 col; 3887{
3815 for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) 3888 S32 num_resizable_columns = 0;
3889 S32 col;
3890 for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
3891 {
3892 LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
3893 if (columnp->mHeader && columnp->mHeader->canResize())
3816 { 3894 {
3817 LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); 3895 num_resizable_columns++;
3818 if (columnp->mHeader && columnp->mHeader->canResize())
3819 {
3820 num_resizable_columns++;
3821 }
3822 } 3896 }
3897 }
3823 3898
3824 S32 num_resizers_enabled = 0; 3899 S32 num_resizers_enabled = 0;
3825 3900
3826 // now enable/disable resize handles on resizable columns if we have at least two 3901 // now enable/disable resize handles on resizable columns if we have at least two
3827 for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) 3902 for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
3903 {
3904 LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
3905 if (!columnp->mHeader) continue;
3906 BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
3907 columnp->mHeader->enableResizeBar(enable);
3908 if (enable)
3828 { 3909 {
3829 LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); 3910 num_resizers_enabled++;
3830 if (!columnp->mHeader) continue;
3831 BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
3832 columnp->mHeader->enableResizeBar(enable);
3833 if (enable)
3834 {
3835 num_resizers_enabled++;
3836 }
3837 } 3911 }
3838 } 3912 }
3839} 3913}
@@ -3841,7 +3915,7 @@ void LLColumnHeader::setHasResizableElement(BOOL resizable)
3841void LLColumnHeader::enableResizeBar(BOOL enable) 3915void LLColumnHeader::enableResizeBar(BOOL enable)
3842{ 3916{
3843 // for now, dynamically spaced columns can't be resized 3917 // for now, dynamically spaced columns can't be resized
3844 if (!mColumn->mDynamicWidth) 3918 //if (!mColumn->mDynamicWidth)
3845 { 3919 {
3846 mResizeBar->setEnabled(enable); 3920 mResizeBar->setEnabled(enable);
3847 } 3921 }
@@ -3851,3 +3925,78 @@ BOOL LLColumnHeader::canResize()
3851{ 3925{
3852 return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth); 3926 return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth);
3853} 3927}
3928
3929void LLScrollListColumn::setWidth(S32 width)
3930{
3931 if (!mDynamicWidth && mRelWidth <= 0.f)
3932 {
3933 mParentCtrl->updateStaticColumnWidth(this, width);
3934 }
3935 mWidth = width;
3936}
3937
3938// Default constructor
3939LLScrollListColumn::LLScrollListColumn() :
3940 mName(),
3941 mSortingColumn(),
3942 mSortAscending(TRUE),
3943 mLabel(),
3944 mWidth(-1),
3945 mRelWidth(-1.0),
3946 mDynamicWidth(FALSE),
3947 mMaxContentWidth(0),
3948 mIndex(-1),
3949 mParentCtrl(NULL),
3950 mHeader(NULL),
3951 mFontAlignment(LLFontGL::LEFT)
3952{ }
3953
3954LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) :
3955 mWidth(0),
3956 mIndex (-1),
3957 mParentCtrl(parent),
3958 mHeader(NULL),
3959 mMaxContentWidth(0),
3960 mDynamicWidth(FALSE),
3961 mRelWidth(-1.f)
3962{
3963 mName = sd.get("name").asString();
3964 mSortingColumn = mName;
3965 if (sd.has("sort"))
3966 {
3967 mSortingColumn = sd.get("sort").asString();
3968 }
3969 mSortAscending = TRUE;
3970 if (sd.has("sort_ascending"))
3971 {
3972 mSortAscending = sd.get("sort_ascending").asBoolean();
3973 }
3974 mLabel = sd.get("label").asString();
3975 if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
3976 {
3977 mRelWidth = (F32)sd.get("relwidth").asReal();
3978 if (mRelWidth < 0) mRelWidth = 0;
3979 if (mRelWidth > 1) mRelWidth = 1;
3980 mDynamicWidth = FALSE;
3981 }
3982 else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE)
3983 {
3984 mDynamicWidth = TRUE;
3985 mRelWidth = -1;
3986 }
3987 else
3988 {
3989
3990 setWidth(sd.get("width").asInteger());
3991 }
3992
3993 if (sd.has("halign"))
3994 {
3995 mFontAlignment = (LLFontGL::HAlign)llclamp(sd.get("halign").asInteger(), (S32)LLFontGL::LEFT, (S32)LLFontGL::HCENTER);
3996 }
3997 else
3998 {
3999 mFontAlignment = LLFontGL::LEFT;
4000 }
4001
4002}