summaryrefslogtreecommitdiff
path: root/indra/llui/llscrolllistctrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llscrolllistctrl.cpp')
-rw-r--r--indra/llui/llscrolllistctrl.cpp183
1 files changed, 148 insertions, 35 deletions
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index a6e4f3a2af..be85f1cb6a 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -115,6 +115,13 @@ struct SortScrollListItem
// LLScrollListCtrl
//---------------------------------------------------------------------------
+void LLScrollListCtrl::SelectionTypeNames::declareValues()
+{
+ declare("row", LLScrollListCtrl::ROW);
+ declare("cell", LLScrollListCtrl::CELL);
+ declare("header", LLScrollListCtrl::HEADER);
+}
+
LLScrollListCtrl::Contents::Contents()
: columns("column"),
rows("row")
@@ -128,8 +135,10 @@ LLScrollListCtrl::Params::Params()
has_border("draw_border"),
draw_heading("draw_heading"),
search_column("search_column", 0),
+ selection_type("selection_type", ROW),
sort_column("sort_column", -1),
sort_ascending("sort_ascending", true),
+ can_sort("can_sort", true),
mouse_wheel_opaque("mouse_wheel_opaque", false),
commit_on_keyboard_movement("commit_on_keyboard_movement", true),
commit_on_selection_change("commit_on_selection_change", false),
@@ -165,8 +174,10 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
mCommitOnSelectionChange(p.commit_on_selection_change),
mSelectionChanged(false),
+ mSelectionType(p.selection_type),
mNeedsScroll(false),
mCanSelect(true),
+ mCanSort(p.can_sort),
mColumnsDirty(false),
mMaxItemCount(INT_MAX),
mBorderThickness( 2 ),
@@ -840,7 +851,15 @@ BOOL LLScrollListCtrl::selectFirstItem()
{
if (!itemp->getSelected())
{
- selectItem(itemp);
+ switch (mSelectionType)
+ {
+ case CELL:
+ selectItem(itemp, 0);
+ break;
+ case HEADER:
+ case ROW:
+ selectItem(itemp, -1);
+ }
}
success = TRUE;
mOriginalSelection = 0;
@@ -899,7 +918,8 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index )
{
if( itemp->getEnabled() )
{
- selectItem(itemp, FALSE);
+ // TODO: support range selection for cells
+ selectItem(itemp, -1, FALSE);
success = TRUE;
}
}
@@ -1025,10 +1045,14 @@ void LLScrollListCtrl::clearHighlightedItems()
void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index)
{
- if (mHighlightedItem != target_index)
- {
- mHighlightedItem = target_index;
- }
+ if (mHighlightedItem != target_index)
+ {
+ if (mHighlightedItem >= 0 && mHighlightedItem < mItemList.size())
+ {
+ mItemList[mHighlightedItem]->setHoverCell(-1);
+ }
+ mHighlightedItem = target_index;
+ }
}
S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
@@ -1043,7 +1067,8 @@ S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
{
if (item->getEnabled() && (item->getUUID() == (*iditr)))
{
- selectItem(item,FALSE);
+ // TODO: support multiple selection for cells
+ selectItem(item, -1, FALSE);
++count;
break;
}
@@ -1116,7 +1141,7 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection)
{
if (prev_item)
{
- selectItem(prev_item, !extend_selection);
+ selectItem(prev_item, cur_item->getSelectedCell(), !extend_selection);
}
else
{
@@ -1160,7 +1185,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection)
{
if (next_item)
{
- selectItem(next_item, !extend_selection);
+ selectItem(next_item, cur_item->getSelectedCell(), !extend_selection);
}
else
{
@@ -1231,7 +1256,7 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen
bool found = NULL != item;
if(found)
{
- selectItem(item);
+ selectItem(item, -1);
}
if (mCommitOnSelectionChange)
@@ -1299,7 +1324,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
if (select)
{
- selectItem(item);
+ selectItem(item, -1);
found = TRUE;
break;
}
@@ -1339,7 +1364,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
// find offset of matching text (might have leading whitespace)
S32 offset = item_label.find(target_trimmed);
cellp->highlightText(offset, target_trimmed.size());
- selectItem(item);
+ selectItem(item, -1);
found = TRUE;
break;
}
@@ -1421,7 +1446,7 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected)
{
if (selected)
{
- selectItem(item);
+ selectItem(item, -1);
}
else
{
@@ -1501,7 +1526,7 @@ void LLScrollListCtrl::drawItems()
S32 max_columns = 0;
- LLColor4 highlight_color = LLColor4::white;
+ LLColor4 highlight_color = LLColor4::white; // ex: text inside cells
static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout(), 0.4f, 0.f);
@@ -1527,7 +1552,8 @@ void LLScrollListCtrl::drawItems()
max_columns = llmax(max_columns, item->getNumColumns());
LLColor4 fg_color;
- LLColor4 bg_color(LLColor4::transparent);
+ LLColor4 hover_color(LLColor4::transparent);
+ LLColor4 select_color(LLColor4::transparent);
if( mScrollLines <= line && line < mScrollLines + num_page_lines )
{
@@ -1536,44 +1562,44 @@ void LLScrollListCtrl::drawItems()
{
if(item->getHighlighted()) // if it's highlighted, average the colors
{
- bg_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
+ select_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
}
else // otherwise just select-highlight it
{
- bg_color = mBgSelectedColor.get();
+ select_color = mBgSelectedColor.get();
}
fg_color = (item->getEnabled() ? mFgSelectedColor.get() : mFgDisabledColor.get());
}
- else if (mHighlightedItem == line && mCanSelect)
+ if (mHighlightedItem == line && mCanSelect)
{
if(item->getHighlighted()) // if it's highlighted, average the colors
{
- bg_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
+ hover_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
}
else // otherwise just hover-highlight it
{
- bg_color = mHoveredColor.get();
+ hover_color = mHoveredColor.get();
}
}
else if (item->getHighlighted())
{
- bg_color = mHighlightedColor.get();
+ hover_color = mHighlightedColor.get();
}
else
{
if (mDrawStripes && (line % 2 == 0) && (max_columns > 1))
{
- bg_color = mBgStripeColor.get();
+ hover_color = mBgStripeColor.get();
}
}
if (!item->getEnabled())
{
- bg_color = mBgReadOnlyColor.get();
+ hover_color = mBgReadOnlyColor.get();
}
- item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding);
+ item->draw(item_rect, fg_color % alpha, hover_color% alpha, select_color% alpha, highlight_color % alpha, mColumnPadding);
cur_y -= mLineHeight;
}
@@ -1725,7 +1751,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
{
if (mLastSelected == NULL)
{
- selectItem(hit_item);
+ selectItem(hit_item, getColumnIndexFromOffset(x));
}
else
{
@@ -1749,7 +1775,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
LLScrollListItem *item = *itor;
if (item == hit_item || item == lastSelected)
{
- selectItem(item, FALSE);
+ selectItem(item, getColumnIndexFromOffset(x), FALSE);
selecting = !selecting;
if (hit_item == lastSelected)
{
@@ -1759,7 +1785,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
}
if (selecting)
{
- selectItem(item, FALSE);
+ selectItem(item, getColumnIndexFromOffset(x), FALSE);
}
}
}
@@ -1774,7 +1800,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
{
if(!(mMaxSelectable > 0 && getAllSelected().size() >= mMaxSelectable))
{
- selectItem(hit_item, FALSE);
+ selectItem(hit_item, getColumnIndexFromOffset(x), FALSE);
}
else
{
@@ -1788,12 +1814,12 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
else
{
deselectAllItems(TRUE);
- selectItem(hit_item);
+ selectItem(hit_item, getColumnIndexFromOffset(x));
}
}
else
{
- selectItem(hit_item);
+ selectItem(hit_item, getColumnIndexFromOffset(x));
}
selection_changed = mSelectionChanged;
@@ -2161,8 +2187,29 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
{
LLScrollListItem* item = hitItem(x, y);
if (item)
- {
- mouseOverHighlightNthItem(getItemIndex(item));
+ {
+ mouseOverHighlightNthItem(getItemIndex(item));
+ switch (mSelectionType)
+ {
+ case CELL:
+ item->setHoverCell(getColumnIndexFromOffset(x));
+ break;
+ case HEADER:
+ {
+ S32 cell = getColumnIndexFromOffset(x);
+ if (cell > 0)
+ {
+ item->setHoverCell(cell);
+ }
+ else
+ {
+ item->setHoverCell(-1);
+ }
+ break;
+ }
+ case ROW:
+ break;
+ }
}
else
{
@@ -2210,6 +2257,58 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
handled = TRUE;
}
break;
+ case KEY_LEFT:
+ if (mAllowKeyboardMovement || hasFocus())
+ {
+ // TODO: support multi-select
+ LLScrollListItem *item = getFirstSelected();
+ if (item)
+ {
+ S32 cell = item->getSelectedCell();
+ switch (mSelectionType)
+ {
+ case CELL:
+ if (cell < mColumns.size()) cell++;
+ break;
+ case HEADER:
+ if (cell == -1) cell = 1;
+ else if (cell > 1 && cell < mColumns.size()) cell++; // skip header
+ break;
+ case ROW:
+ cell = -1;
+ break;
+ }
+ item->setSelectedCell(cell);
+ handled = TRUE;
+ }
+ }
+ break;
+ case KEY_RIGHT:
+ if (mAllowKeyboardMovement || hasFocus())
+ {
+ // TODO: support multi-select
+ LLScrollListItem *item = getFirstSelected();
+ if (item)
+ {
+ S32 cell = item->getSelectedCell();
+ switch (mSelectionType)
+ {
+ case CELL:
+ if (cell >= 0) cell--;
+ break;
+ case HEADER:
+ if (cell > 1) cell--;
+ else if (cell == 1) cell = -1; // skip header
+ break;
+ case ROW:
+ cell = -1;
+ break;
+ }
+ item->setSelectedCell(cell);
+ handled = TRUE;
+ }
+ }
+ break;
case KEY_PAGE_UP:
if (mAllowKeyboardMovement || hasFocus())
{
@@ -2378,7 +2477,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char)
{
- selectItem(item);
+ selectItem(item, -1);
mNeedsScroll = true;
cellp->highlightText(0, 1);
mSearchTimer.reset();
@@ -2430,7 +2529,7 @@ BOOL LLScrollListCtrl::isRepeatedChars(const LLWString& string) const
return TRUE;
}
-void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_item)
+void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, BOOL select_single_item)
{
if (!itemp) return;
@@ -2449,6 +2548,18 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
deselectAllItems(TRUE);
}
itemp->setSelected(TRUE);
+ switch (mSelectionType)
+ {
+ case CELL:
+ itemp->setSelectedCell(cell);
+ break;
+ case HEADER:
+ itemp->setSelectedCell(cell <= 0 ? -1 : cell);
+ break;
+ case ROW:
+ itemp->setSelectedCell(-1);
+ break;
+ }
mLastSelected = itemp;
mSelectionChanged = true;
}
@@ -2709,7 +2820,7 @@ void LLScrollListCtrl::selectAll()
LLScrollListItem *itemp = *iter;
if( itemp->getEnabled() )
{
- selectItem(itemp, FALSE);
+ selectItem(itemp, -1, FALSE);
}
}
@@ -2838,6 +2949,8 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
LLScrollListCtrl *parent = info->mParentCtrl;
if (!parent) return;
+ if (!parent->mCanSort) return;
+
S32 column_index = info->mIndex;
LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex];