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: