From 8f3b10875ebe09cebb28c703851bda8cb4ae42d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Liru=20F=C3=A6rs?= Date: Mon, 7 Oct 2019 23:46:09 -0400 Subject: [PATCH] Introduce LFIDBearer, a Class for menu bearing UI that offers IDs to menus Move menu code from scroll list into there Separate out interface for getting IDs No longer bother with the focus manager, for menus where not necessary, this ensures that if focus suddenly changes, it won't break menu UX flow. Clean up all the static functions by using new static class functions --- indra/llui/CMakeLists.txt | 2 + indra/llui/lfidbearer.cpp | 33 +++++++++ indra/llui/lfidbearer.h | 45 ++++++++++++ indra/llui/llscrolllistctrl.cpp | 9 +-- indra/llui/llscrolllistctrl.h | 11 ++- indra/newview/llfloateravatarlist.cpp | 4 +- indra/newview/llviewermenu.cpp | 98 +++++++++++---------------- indra/newview/llviewermenu.h | 2 - 8 files changed, 127 insertions(+), 77 deletions(-) create mode 100644 indra/llui/lfidbearer.cpp create mode 100644 indra/llui/lfidbearer.h diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index b00081882..11b8c800e 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( ) set(llui_SOURCE_FILES + lfidbearer.cpp llaccordionctrl.cpp llaccordionctrltab.cpp llalertdialog.cpp @@ -101,6 +102,7 @@ set(llui_HEADER_FILES CMakeLists.txt ailist.h + lfidbearer.h llaccordionctrl.h llaccordionctrltab.h llalertdialog.h diff --git a/indra/llui/lfidbearer.cpp b/indra/llui/lfidbearer.cpp new file mode 100644 index 000000000..cc7a3f988 --- /dev/null +++ b/indra/llui/lfidbearer.cpp @@ -0,0 +1,33 @@ +/* Copyright (C) 2019 Liru Færs + * + * LFIDBearer is a class that holds an ID or IDs that menus can use + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA */ + +#include "linden_common.h" +#include "lfidbearer.h" +#include "llmenugl.h" + +std::vector LFIDBearer::sMenus = {}; +LFIDBearer* LFIDBearer::sActive = nullptr; + +void LFIDBearer::showMenu(LLView* self, LLMenuGL* menu, S32 x, S32 y) +{ + sActive = this; // Menu listeners rely on this + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(self, menu, x, y); +} diff --git a/indra/llui/lfidbearer.h b/indra/llui/lfidbearer.h new file mode 100644 index 000000000..8b4c7684d --- /dev/null +++ b/indra/llui/lfidbearer.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2019 Liru Færs + * + * LFIDBearer is a class that holds an ID or IDs that menus can use + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA */ + +#pragma once + +#include "lluuid.h" + +class LLMenuGL; +class LLView; + +struct LFIDBearer +{ + virtual ~LFIDBearer() { if (sActive == this) sActive = nullptr; } + virtual LLUUID getStringUUIDSelectedItem() const = 0; + virtual uuid_vec_t getSelectedIDs() const = 0; + virtual S32 getNumSelected() const = 0; + + template static T* getActive() { return static_cast(sActive); } + static LLUUID getActiveSelectedID() { return sActive->getStringUUIDSelectedItem(); } + static uuid_vec_t getActiveSelectedIDs() { return sActive->getSelectedIDs(); } + static S32 getActiveNumSelected() { return sActive->getNumSelected(); } + + void showMenu(LLView* self, LLMenuGL* menu, S32 x, S32 y); + static void addCommonMenu(LLMenuGL* menu) { sMenus.push_back(menu); } + +protected: + static std::vector sMenus; // Menus that recur, such as general avatars or groups menus + static LFIDBearer* sActive; +}; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 2aa1b17ec..d1a187d0c 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -59,8 +59,6 @@ static LLRegisterWidget r("scroll_list"); -std::vector LLScrollListCtrl::sMenus = {}; // List menus that recur, such as general avatars or groups menus - // local structures & classes. struct SortScrollListItem { @@ -314,7 +312,7 @@ std::vector LLScrollListCtrl::getAllSelected() const return ret; } -uuid_vec_t LLScrollListCtrl::getSelectedIDs() +uuid_vec_t LLScrollListCtrl::getSelectedIDs() const { uuid_vec_t ids; if (!getCanSelect()) return ids; @@ -1813,10 +1811,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) if (col->mHeader && col->mHeader->getRect().pointInRect(x,y)) // Right clicking a column header shouldn't bring up a menu return FALSE; } - gFocusMgr.setKeyboardFocus(this); // Menu listeners rely on this - mPopupMenu->buildDrawLabels(); - mPopupMenu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, mPopupMenu, x, y); + showMenu(this, mPopupMenu, x, y); return TRUE; } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index e52f41ee9..c09af350a 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -32,6 +32,7 @@ #include #include +#include "lfidbearer.h" #include "lluictrl.h" #include "llctrlselectioninterface.h" #include "llfontgl.h" @@ -48,6 +49,7 @@ class LLMenuGL; class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, public LLCtrlListInterface, public LLCtrlScrollInterface +, public LFIDBearer { public: typedef boost::function callback_t; @@ -194,13 +196,13 @@ public: // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which // has an associated, unique UUID, and only one of which can be selected at a time. LLScrollListItem* addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); - LLUUID getStringUUIDSelectedItem() const; + LLUUID getStringUUIDSelectedItem() const override final; LLScrollListItem* getFirstSelected() const; virtual S32 getFirstSelectedIndex() const; std::vector getAllSelected() const; - uuid_vec_t getSelectedIDs(); //Helper. Much like getAllSelected, but just provides a LLUUID vec - S32 getNumSelected() const; + uuid_vec_t getSelectedIDs() const override final; //Helper. Much like getAllSelected, but just provides a LLUUID vec + S32 getNumSelected() const override final; LLScrollListItem* getLastSelectedItem() const { return mLastSelected; } // iterate over all items @@ -255,7 +257,6 @@ public: // support right-click context menus for avatar/group lists void setContextMenu(LLMenuGL* menu) { mPopupMenu = menu; } void setContextMenu(S32 index) { mPopupMenu = sMenus[index]; } - static void addCommonMenu(LLMenuGL* menu) { sMenus.push_back(menu); } // Overridden from LLView /*virtual*/ void draw(); @@ -468,8 +469,6 @@ private: class LLViewBorder* mBorder; LLMenuGL *mPopupMenu; - static std::vector sMenus; // List menus that recur, such as general avatars or groups menus - LLView *mCommentTextView; LLWString mSearchString; diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 51122e51b..9d6264f3c 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -378,7 +378,7 @@ namespace { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLFloaterAvatarList::setFocusAvatar(get_focused_list_id_selected()); + LLFloaterAvatarList::setFocusAvatar(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -405,7 +405,7 @@ namespace { bool handleEvent(LLPointer event, const LLSD& userdata) { - teleport_to(get_focused_list_id_selected()); + teleport_to(LFIDBearer::getActiveSelectedID()); return true; } }; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 291f0b17b..8f3e64f19 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -34,6 +34,7 @@ #include "llviewermenu.h" // linden library includes +#include "lfidbearer.h" #include "llanimationstates.h" // For ANIM_AGENT_AWAY #include "llavatarnamecache.h" // IDEVO #include "llinventorypanel.h" @@ -763,8 +764,8 @@ void init_menus() gMenuHolder->addChild(gLoginMenuBarView); // Singu Note: Initialize common ScrollListMenus here - LLScrollListCtrl::addCommonMenu(LLUICtrlFactory::getInstance()->buildMenu("menu_avs_list.xml", gMenuHolder)); // 0 - //LLScrollListCtrl::addCommonMenu(LLUICtrlFactory::getInstance()->buildMenu("menu_groups_list.xml")); // 1 // Singu TODO + LFIDBearer::addCommonMenu(LLUICtrlFactory::getInstance()->buildMenu("menu_avs_list.xml", gMenuHolder)); // 0 + //LFIDBearer::addCommonMenu(LLUICtrlFactory::getInstance()->buildMenu("menu_groups_list.xml")); // 1 // Singu TODO LLView* ins = gMenuBarView->getChildView("insert_world", true, false); ins->setVisible(false); @@ -9051,27 +9052,6 @@ template T* get_focused() return t; } -S32 get_focused_list_num_selected() -{ - if (auto list = get_focused()) - return list->getNumSelected(); - return 0; -} - -const LLUUID get_focused_list_id_selected() -{ - if (auto list = get_focused()) - return list->getStringUUIDSelectedItem(); - return LLUUID::null; -} - -const uuid_vec_t get_focused_list_ids_selected() -{ - if (auto list = get_focused()) - return list->getSelectedIDs(); - return uuid_vec_t(); -} - const LLWString get_slurl_for(const LLUUID& id, bool group) { std::string str("secondlife:///app/"); @@ -9088,7 +9068,7 @@ class ListEnableAnySelected : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(get_focused_list_num_selected()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(LFIDBearer::getActiveNumSelected()); return true; } }; @@ -9097,7 +9077,7 @@ class ListEnableMultipleSelected : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(get_focused_list_num_selected() > 1); + gMenuHolder->findControl(userdata["control"].asString())->setValue(LFIDBearer::getActiveNumSelected() > 1); return true; } }; @@ -9106,7 +9086,7 @@ class ListEnableSingleSelected : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(get_focused_list_num_selected() == 1); + gMenuHolder->findControl(userdata["control"].asString())->setValue(LFIDBearer::getActiveNumSelected() == 1); return true; } }; @@ -9115,8 +9095,6 @@ class ListEnableCall : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - auto list = get_focused(); - if (!list) return false; gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::canCall()); return true; } @@ -9126,7 +9104,7 @@ class ListEnableIsFriend : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::isFriend(get_focused_list_id_selected())); + gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::isFriend(LFIDBearer::getActiveSelectedID())); return true; } }; @@ -9135,7 +9113,7 @@ class ListEnableIsNotFriend : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(!LLAvatarActions::isFriend(get_focused_list_id_selected())); + gMenuHolder->findControl(userdata["control"].asString())->setValue(!LLAvatarActions::isFriend(LFIDBearer::getActiveSelectedID())); return true; } }; @@ -9144,7 +9122,7 @@ class ListEnableMute : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); + const uuid_vec_t& ids = LFIDBearer::getActiveSelectedIDs(); bool can_block = true; for (uuid_vec_t::const_iterator it = ids.begin(); can_block && it != ids.end(); ++it) can_block = LLAvatarActions::canBlock(*it); @@ -9157,7 +9135,7 @@ class ListEnableOfferTeleport : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::canOfferTeleport(get_focused_list_ids_selected())); + gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::canOfferTeleport(LFIDBearer::getActiveSelectedIDs())); return true; } }; @@ -9166,7 +9144,7 @@ class ListVisibleWebProfile : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(get_focused_list_num_selected() && !(gSavedSettings.getBOOL("UseWebProfiles") || gSavedSettings.getString("WebProfileURL").empty())); + gMenuHolder->findControl(userdata["control"].asString())->setValue(LFIDBearer::getActiveNumSelected() && !(gSavedSettings.getBOOL("UseWebProfiles") || gSavedSettings.getString("WebProfileURL").empty())); return true; } }; @@ -9176,7 +9154,7 @@ class ListBanFromGroup : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - ban_from_group(get_focused_list_ids_selected()); + ban_from_group(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9185,7 +9163,7 @@ class ListCopySLURL : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - copy_profile_uri(get_focused_list_id_selected(), false); + copy_profile_uri(LFIDBearer::getActiveSelectedID(), false); return true; } }; @@ -9194,7 +9172,7 @@ class ListCopyUUIDs : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::copyUUIDs(get_focused_list_ids_selected()); + LLAvatarActions::copyUUIDs(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9203,7 +9181,7 @@ class ListInviteToGroup : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::inviteToGroup(get_focused_list_ids_selected()); + LLAvatarActions::inviteToGroup(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9212,7 +9190,7 @@ class ListOfferTeleport : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::offerTeleport(get_focused_list_ids_selected()); + LLAvatarActions::offerTeleport(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9221,7 +9199,7 @@ class ListPay : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::pay(get_focused_list_id_selected()); + LLAvatarActions::pay(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9230,7 +9208,7 @@ class ListRemoveFriend : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::removeFriendDialog(get_focused_list_id_selected()); + LLAvatarActions::removeFriendDialog(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9239,7 +9217,7 @@ class ListRequestFriendship : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::requestFriendshipDialog(get_focused_list_id_selected()); + LLAvatarActions::requestFriendshipDialog(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9248,7 +9226,7 @@ class ListRequestTeleport : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::teleportRequest(get_focused_list_id_selected()); + LLAvatarActions::teleportRequest(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9257,7 +9235,7 @@ class ListShare : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::share(get_focused_list_id_selected()); + LLAvatarActions::share(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9272,7 +9250,7 @@ class ListShowLog : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - for (const LLUUID& id : get_focused_list_ids_selected()) + for (const LLUUID& id : LFIDBearer::getActiveSelectedIDs()) show_log_browser(id); return true; } @@ -9282,7 +9260,7 @@ class ListShowProfile : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::showProfiles(get_focused_list_ids_selected()); + LLAvatarActions::showProfiles(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9291,7 +9269,7 @@ class ListShowWebProfile : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::showProfiles(get_focused_list_ids_selected(), true); + LLAvatarActions::showProfiles(LFIDBearer::getActiveSelectedIDs(), true); return true; } }; @@ -9300,7 +9278,7 @@ class ListStartAdhocCall : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::startAdhocCall(get_focused_list_ids_selected()); + LLAvatarActions::startAdhocCall(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9309,7 +9287,7 @@ class ListStartCall : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::startCall(get_focused_list_id_selected()); + LLAvatarActions::startCall(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9318,7 +9296,7 @@ class ListStartConference : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::startConference(get_focused_list_ids_selected()); + LLAvatarActions::startConference(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9327,7 +9305,7 @@ class ListStartIM : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAvatarActions::startIM(get_focused_list_id_selected()); + LLAvatarActions::startIM(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9336,7 +9314,7 @@ class ListAbuseReport : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLFloaterReporter::showFromObject(get_focused_list_id_selected()); + LLFloaterReporter::showFromObject(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9364,7 +9342,7 @@ class ListIsNearby : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gMenuHolder->findControl(userdata["control"].asString())->setValue(is_nearby(get_focused_list_id_selected())); + gMenuHolder->findControl(userdata["control"].asString())->setValue(is_nearby(LFIDBearer::getActiveSelectedID())); return true; } }; @@ -9374,7 +9352,7 @@ class ListTrack : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - track_av(get_focused_list_id_selected()); + track_av(LFIDBearer::getActiveSelectedID()); return true; } }; @@ -9388,7 +9366,7 @@ class ListEject : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - confirm_eject(get_focused_list_ids_selected()); + confirm_eject(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9402,7 +9380,7 @@ class ListFreeze : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - confirm_freeze(get_focused_list_ids_selected()); + confirm_freeze(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9441,7 +9419,7 @@ class ListEstateBan : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - confirm_estate_ban(get_focused_list_ids_selected()); + confirm_estate_ban(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9454,7 +9432,7 @@ class ListEstateEject : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - confirm_estate_kick(get_focused_list_ids_selected()); + confirm_estate_kick(LFIDBearer::getActiveSelectedIDs()); return true; } }; @@ -9463,9 +9441,9 @@ class ListToggleMute : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) - LLAvatarActions::toggleBlock(*it); + const uuid_vec_t& ids = LFIDBearer::getActiveSelectedIDs(); + for (const auto& id : ids) + LLAvatarActions::toggleBlock(id); return true; } }; diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index b3f2cda7b..29d46def8 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -142,8 +142,6 @@ bool handle_go_to(); // Export to XML or Collada void handle_export_selected( void * ); -const LLUUID get_focused_list_id_selected(); - class LLViewerMenuHolderGL : public LLMenuHolderGL { public: