diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 3d7afdb1a7..2d63816113 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2514,6 +2514,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (selected_item) { handleRightMouseDown(selected_item->getRect().getCenterX(), selected_item->getRect().getCenterY(), MASK_NONE); + handled = TRUE; } break; } @@ -2523,11 +2524,139 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) } } // TODO: multiple: shift-up, shift-down, shift-home, shift-end, select all + // Let's just do this! + else if (mask == MASK_CONTROL) + { + switch (key) + { + case 'A': + if (canSelectAll()) + { + selectAll(); + handled = TRUE; + } + break; + default: + break; + } + } + else if (mask == MASK_SHIFT) + { + switch (key) + { + case KEY_UP: + if (mAllowKeyboardMovement || hasFocus()) + { + auto selected_items = getAllSelected(); + auto last = selected_items.back(); + + if (mLastSelected == last && selected_items.size() > 1) + { + deselectItem(last); + mLastSelected = getAllSelected().back(); // Use updated selection + } + else + { + auto items = getAllData(); + auto first = std::find(items.begin(), items.end(), selected_items.front()); + if (first != items.end() && first > items.begin()) + { + selectItem(*(--first), FALSE); + } + } + + handled = TRUE; + } + + break; + case KEY_DOWN: + if (mAllowKeyboardMovement || hasFocus()) + { + auto selected_items = getAllSelected(); + auto first = selected_items.front(); + + if (mLastSelected == first && selected_items.size() > 1) + { + deselectItem(first); + mLastSelected = getAllSelected().front(); // Use updated selection + } + else + { + auto items = getAllData(); + auto last = std::find(items.begin(), items.end(), selected_items.back()); + if (last != items.end() && last < items.end() - 1) + { + selectItem(*(++last), FALSE); + } + } + + handled = TRUE; + } + break; + case KEY_HOME: + if (mAllowKeyboardMovement || hasFocus()) + { + auto items = getAllData(); + auto first = std::find(items.begin(), items.end(), getAllSelected().front()); + for (auto it = items.begin(); it != items.end(); ++it) + { + if (it <= first) + { + selectItem(*it, FALSE); + } + else + { + deselectItem(*it); + } + } + + handled = TRUE; + } + break; + case KEY_END: + if (mAllowKeyboardMovement || hasFocus()) + { + auto items = getAllData(); + auto last = std::find(items.begin(), items.end(), getAllSelected().back()); + for (auto it = items.begin(); it != items.end(); ++it) + { + if (it >= last) + { + selectItem(*it, FALSE); + } + else + { + deselectItem(*it); + } + } + + handled = TRUE; + } + break; + default: + break; + } + } + // } return handled; } +// Needed for keyboard selection in radar +void LLScrollListCtrl::setLastSelectedItem(const LLUUID& id) +{ + for (auto item : getAllSelected()) + { + if (item->getUUID() == id) + { + mLastSelected = item; + break; + } + } +} +// + BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) { if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 40eaa4e9d4..aa176e318b 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -275,6 +275,7 @@ public: std::vector getAllSelected() const; S32 getNumSelected() const; LLScrollListItem* getLastSelectedItem() const { return mLastSelected; } + void setLastSelectedItem(const LLUUID& id); // Needed for keyboard selection in radar // iterate over all items LLScrollListItem* getFirstData() const; diff --git a/indra/newview/fspanelradar.cpp b/indra/newview/fspanelradar.cpp index c20c1278d9..8334d58e28 100644 --- a/indra/newview/fspanelradar.cpp +++ b/indra/newview/fspanelradar.cpp @@ -326,6 +326,11 @@ void FSPanelRadar::updateList(const std::vector& entries, const LLSD& stat static const std::string typingColumnIcon = getString("TypingColumnIcon"); // Store current selection and scroll position + LLUUID last_selected_id; + if (mRadarList->getLastSelectedItem()) + { + last_selected_id = mRadarList->getLastSelectedItem()->getUUID(); + } std::vector selected_items = mRadarList->getAllSelected(); uuid_vec_t selected_ids; for (std::vector::iterator it = selected_items.begin(); it != selected_items.end(); ++it) @@ -458,6 +463,10 @@ void FSPanelRadar::updateList(const std::vector& entries, const LLSD& stat if (!selected_ids.empty()) { mRadarList->selectMultiple(selected_ids); + if (last_selected_id.notNull()) + { + mRadarList->setLastSelectedItem(last_selected_id); + } } updateButtons();