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
This commit is contained in:
Liru Færs
2019-10-07 23:46:09 -04:00
parent 33ef6cc3f7
commit 8f3b10875e
8 changed files with 127 additions and 77 deletions

View File

@@ -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

33
indra/llui/lfidbearer.cpp Normal file
View File

@@ -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<LLMenuGL*> 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);
}

45
indra/llui/lfidbearer.h Normal file
View File

@@ -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<typename T> static T* getActive() { return static_cast<T*>(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<LLMenuGL*> sMenus; // Menus that recur, such as general avatars or groups menus
static LFIDBearer* sActive;
};

View File

@@ -59,8 +59,6 @@
static LLRegisterWidget<LLScrollListCtrl> r("scroll_list");
std::vector<LLMenuGL*> LLScrollListCtrl::sMenus = {}; // List menus that recur, such as general avatars or groups menus
// local structures & classes.
struct SortScrollListItem
{
@@ -314,7 +312,7 @@ std::vector<LLScrollListItem*> 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;
}

View File

@@ -32,6 +32,7 @@
#include <vector>
#include <deque>
#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<void (void)> 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<LLScrollListItem*> 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<LLMenuGL*> sMenus; // List menus that recur, such as general avatars or groups menus
LLView *mCommentTextView;
LLWString mSearchString;

View File

@@ -378,7 +378,7 @@ namespace
{
bool handleEvent(LLPointer<LLEvent> 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<LLEvent> event, const LLSD& userdata)
{
teleport_to(get_focused_list_id_selected());
teleport_to(LFIDBearer::getActiveSelectedID());
return true;
}
};

View File

@@ -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<typename T> T* get_focused()
return t;
}
S32 get_focused_list_num_selected()
{
if (auto list = get_focused<LLScrollListCtrl>())
return list->getNumSelected();
return 0;
}
const LLUUID get_focused_list_id_selected()
{
if (auto list = get_focused<LLScrollListCtrl>())
return list->getStringUUIDSelectedItem();
return LLUUID::null;
}
const uuid_vec_t get_focused_list_ids_selected()
{
if (auto list = get_focused<LLScrollListCtrl>())
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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> event, const LLSD& userdata)
{
auto list = get_focused<LLScrollListCtrl>();
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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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<LLEvent> 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;
}
};

View File

@@ -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: