EXT-6726 WIP Added stubs for most of Appearance SP context/gear menus.

Shared code with avatar lists context menus.

Reviewed by Mike Antipov and Nyx at https://codereview.productengine.com/secondlife/r/415/

--HG--
branch : product-engine
master
Vadim Savchuk 2010-05-20 14:54:34 +03:00
parent 8c83a6ca62
commit d634239bac
30 changed files with 694 additions and 115 deletions

View File

@ -268,6 +268,7 @@ set(viewer_SOURCE_FILES
lllandmarkactions.cpp
lllandmarklist.cpp
lllistbrowser.cpp
lllistcontextmenu.cpp
lllistview.cpp
lllocaltextureobject.cpp
lllocationhistory.cpp
@ -786,6 +787,7 @@ set(viewer_HEADER_FILES
lllandmarklist.h
lllightconstants.h
lllistbrowser.h
lllistcontextmenu.h
lllistview.h
lllocaltextureobject.h
lllocationhistory.h

View File

@ -46,6 +46,7 @@
#include "llavatariconctrl.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcachename.h"
#include "lllistcontextmenu.h"
#include "llrecentpeople.h"
#include "lluuid.h"
#include "llvoiceclient.h"

View File

@ -38,6 +38,7 @@
#include "llavatarlistitem.h"
class LLTimer;
class LLListContextMenu;
/**
* Generic list of avatars.
@ -77,7 +78,7 @@ public:
uuid_vec_t& getIDs() { return mIDs; }
bool contains(const LLUUID& id);
void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; }
void setContextMenu(LLListContextMenu* menu) { mContextMenu = menu; }
void setSessionID(const LLUUID& session_id) { mSessionID = session_id; }
const LLUUID& getSessionID() { return mSessionID; }
@ -127,7 +128,7 @@ private:
uuid_vec_t mIDs;
LLUUID mSessionID;
LLAvatarListItem::ContextMenu* mContextMenu;
LLListContextMenu* mContextMenu;
commit_signal_t mRefreshCompleteSignal;
mouse_signal_t mItemDoubleClickSignal;

View File

@ -1,6 +1,6 @@
/**
* @file llavatarlistitem.cpp
* @avatar list item source file
* @brief avatar list item source file
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*

View File

@ -1,6 +1,6 @@
/**
* @file llavatarlistitem.h
* @avatar list item header file
* @brief avatar list item header file
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
@ -67,13 +67,6 @@ public:
IS_OFFLINE,
} EItemState;
class ContextMenu
{
public:
virtual void show(LLView* spawning_view, const uuid_vec_t& selected_uuids, S32 x, S32 y) = 0;
virtual void hide() = 0;
};
/**
* Creates an instance of LLAvatarListItem.
*

View File

@ -35,9 +35,13 @@
#include "llcofwearables.h"
#include "llagentdata.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
#include "lllistcontextmenu.h"
#include "llmenugl.h"
#include "llviewermenu.h"
#include "llwearableitemslist.h"
static LLRegisterPanelClassWrapper<LLCOFAccordionListAdaptor> t_cof_accodion_list_adaptor("accordion_list_adaptor");
@ -49,14 +53,61 @@ const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
//////////////////////////////////////////////////////////////////////////
class CofAttachmentContextMenu : public LLListContextMenu
{
protected:
/*virtual*/ LLContextMenu* createMenu()
{
return createFromFile("menu_cof_attachment.xml");
}
};
//////////////////////////////////////////////////////////////////////////
class CofClothingContextMenu : public LLListContextMenu
{
protected:
/*virtual*/ LLContextMenu* createMenu()
{
return createFromFile("menu_cof_clothing.xml");
}
};
//////////////////////////////////////////////////////////////////////////
class CofBodyPartContextMenu : public LLListContextMenu
{
protected:
/*virtual*/ LLContextMenu* createMenu()
{
return createFromFile("menu_cof_body_part.xml");
}
};
//////////////////////////////////////////////////////////////////////////
LLCOFWearables::LLCOFWearables() : LLPanel(),
mAttachments(NULL),
mClothing(NULL),
mBodyParts(NULL),
mLastSelectedList(NULL)
{
mClothingMenu = new CofClothingContextMenu();
mAttachmentMenu = new CofAttachmentContextMenu();
mBodyPartMenu = new CofBodyPartContextMenu();
};
LLCOFWearables::~LLCOFWearables()
{
delete mClothingMenu;
delete mAttachmentMenu;
delete mBodyPartMenu;
}
// virtual
BOOL LLCOFWearables::postBuild()
@ -65,6 +116,9 @@ BOOL LLCOFWearables::postBuild()
mClothing = getChild<LLFlatListView>("list_clothing");
mBodyParts = getChild<LLFlatListView>("list_body_parts");
mClothing->setRightMouseDownCallback(boost::bind(&LLCOFWearables::onListRightClick, this, _1, _2, _3, mClothingMenu));
mAttachments->setRightMouseDownCallback(boost::bind(&LLCOFWearables::onListRightClick, this, _1, _2, _3, mAttachmentMenu));
mBodyParts->setRightMouseDownCallback(boost::bind(&LLCOFWearables::onListRightClick, this, _1, _2, _3, mBodyPartMenu));
//selection across different list/tabs is not supported
mAttachments->setCommitCallback(boost::bind(&LLCOFWearables::onSelectionChange, this, mAttachments));
@ -304,6 +358,14 @@ LLUUID LLCOFWearables::getSelectedUUID()
return mLastSelectedList->getSelectedUUID();
}
bool LLCOFWearables::getSelectedUUIDs(uuid_vec_t& selected_ids)
{
if (!mLastSelectedList) return false;
mLastSelectedList->getSelectedUUIDs(selected_ids);
return selected_ids.size() != 0;
}
void LLCOFWearables::clear()
{
mAttachments->clear();
@ -311,4 +373,16 @@ void LLCOFWearables::clear()
mBodyParts->clear();
}
void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu)
{
if(menu)
{
uuid_vec_t selected_uuids;
if(getSelectedUUIDs(selected_uuids))
{
menu->show(ctrl, selected_uuids, x, y);
}
}
}
//EOF

View File

@ -40,6 +40,7 @@
#include "llappearancemgr.h"
#include "llinventorymodel.h"
class LLListContextMenu;
class LLPanelClothingListItem;
class LLPanelBodyPartsListItem;
class LLPanelDeletableWearableListItem;
@ -115,11 +116,12 @@ public:
LLCOFWearables();
virtual ~LLCOFWearables() {};
virtual ~LLCOFWearables();
/*virtual*/ BOOL postBuild();
LLUUID getSelectedUUID();
bool getSelectedUUIDs(uuid_vec_t& selected_ids);
void refresh();
void clear();
@ -138,6 +140,8 @@ protected:
LLPanelBodyPartsListItem* buildBodypartListItem(LLViewerInventoryItem* item);
LLPanelDeletableWearableListItem* buildAttachemntListItem(LLViewerInventoryItem* item);
void onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu);
LLFlatListView* mAttachments;
LLFlatListView* mClothing;
LLFlatListView* mBodyParts;
@ -146,6 +150,9 @@ protected:
LLCOFCallbacks mCOFCallbacks;
LLListContextMenu* mClothingMenu;
LLListContextMenu* mAttachmentMenu;
LLListContextMenu* mBodyPartMenu;
};

View File

@ -0,0 +1,125 @@
/**
* @file lllistcontextmenu.cpp
* @brief Base class of misc lists' context menus
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "lllistcontextmenu.h"
// libs
#include "llmenugl.h" // for LLContextMenu
// newview
#include "llviewermenu.h" // for LLViewerMenuHolderGL
LLListContextMenu::LLListContextMenu()
: mMenu(NULL)
{
}
LLListContextMenu::~LLListContextMenu()
{
// do not forget delete LLContextMenu* mMenu.
// It can have registered Enable callbacks which are called from the LLMenuHolderGL::draw()
// via selected item (menu_item_call) by calling LLMenuItemCallGL::buildDrawLabel.
// we can have a crash via using callbacks of deleted instance of ContextMenu. EXT-4725
// menu holder deletes its menus on viewer exit, so we have no way to determine if instance
// of mMenu has already been deleted except of using LLHandle. EXT-4762.
if (!mMenuHandle.isDead())
{
mMenu->die();
mMenu = NULL;
}
}
void LLListContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
{
if (mMenu)
{
//preventing parent (menu holder) from deleting already "dead" context menus on exit
LLView* parent = mMenu->getParent();
if (parent)
{
parent->removeChild(mMenu);
}
delete mMenu;
mMenu = NULL;
mUUIDs.clear();
}
if ( uuids.empty() )
{
return;
}
mUUIDs.resize(uuids.size());
std::copy(uuids.begin(), uuids.end(), mUUIDs.begin());
mMenu = createMenu();
if (!mMenu)
{
llwarns << "Context menu creation failed" << llendl;
return;
}
mMenuHandle = mMenu->getHandle();
mMenu->show(x, y);
LLMenuGL::showPopup(spawning_view, mMenu, x, y);
}
void LLListContextMenu::hide()
{
if(mMenu)
{
mMenu->hide();
}
}
// static
void LLListContextMenu::handleMultiple(functor_t functor, const uuid_vec_t& ids)
{
uuid_vec_t::const_iterator it;
for (it = ids.begin(); it != ids.end(); ++it)
{
functor(*it);
}
}
// static
LLContextMenu* LLListContextMenu::createFromFile(const std::string& filename)
{
return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
filename, LLContextMenu::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
}
// EOF

View File

@ -0,0 +1,84 @@
/**
* @file lllistcontextmenu.h
* @brief Base class of misc lists' context menus
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLLISTCONTEXTMENU_H
#define LL_LLLISTCONTEXTMENU_H
#include "llhandle.h"
#include "lluuid.h"
#include "llview.h"
class LLView;
class LLContextMenu;
/**
* Context menu for single or multiple list items.
*
* Derived classes must implement contextMenu().
*
* Typical usage:
* <code>
* my_context_menu->show(parent_view, selected_list_items_ids, x, y);
* </code>
*/
class LLListContextMenu
{
public:
LLListContextMenu();
virtual ~LLListContextMenu();
/**
* Show the menu at specified coordinates.
*
* @param spawning_view View to spawn at.
* @param uuids An array of list items ids.
* @param x Horizontal coordinate in the spawn_view's coordinate frame.
* @param y Vertical coordinate in the spawn_view's coordinate frame.
*/
virtual void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
virtual void hide();
protected:
typedef boost::function<void (const LLUUID& id)> functor_t;
virtual LLContextMenu* createMenu() = 0;
static LLContextMenu* createFromFile(const std::string& filename);
static void handleMultiple(functor_t functor, const uuid_vec_t& ids);
uuid_vec_t mUUIDs;
LLContextMenu* mMenu;
LLHandle<LLView> mMenuHandle;
};
#endif // LL_LLLISTCONTEXTMENU_H

View File

@ -41,8 +41,26 @@
#include "llappearancemgr.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "lllistcontextmenu.h"
#include "lltransutil.h"
#include "llviewermenu.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llwearableitemslist.h"
//////////////////////////////////////////////////////////////////////////
class OutfitContextMenu : public LLListContextMenu
{
protected:
/* virtual */ LLContextMenu* createMenu()
{
return createFromFile("menu_outfit_tab.xml");
}
};
//////////////////////////////////////////////////////////////////////////
static LLRegisterPanelClassWrapper<LLOutfitsList> t_outfits_list("outfits_list");
LLOutfitsList::LLOutfitsList()
@ -55,10 +73,14 @@ LLOutfitsList::LLOutfitsList()
gInventory.addObserver(mCategoriesObserver);
gInventory.addObserver(this);
mOutfitMenu = new OutfitContextMenu();
}
LLOutfitsList::~LLOutfitsList()
{
delete mOutfitMenu;
if (gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
@ -140,6 +162,8 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode();
LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL);
tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this,
_1, _2, _3, cat_id));
tab->setName(name);
tab->setTitle(name);
@ -447,4 +471,19 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring)
}
}
void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
{
LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
if(mOutfitMenu && tab && tab->getHeaderVisible() && cat_id.notNull())
{
S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight();
if(y >= header_bottom)
{
uuid_vec_t selected_uuids;
selected_uuids.push_back(cat_id);
mOutfitMenu->show(ctrl, selected_uuids, x, y);
}
}
}
// EOF

View File

@ -41,6 +41,7 @@
class LLAccordionCtrl;
class LLAccordionCtrlTab;
class LLWearableItemsList;
class LLListContextMenu;
/**
* @class LLOutfitsList
@ -105,6 +106,8 @@ private:
*/
void applyFilter(const std::string& new_filter_substring);
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
LLInventoryCategoriesObserver* mCategoriesObserver;
LLAccordionCtrl* mAccordion;
@ -118,6 +121,8 @@ private:
typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t;
typedef outfits_map_t::value_type outfits_map_value_t;
outfits_map_t mOutfitsMap;
LLListContextMenu* mOutfitMenu;
};
#endif //LL_LLOUTFITSLIST_H

View File

@ -212,6 +212,7 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()
mCOFWearables(NULL),
mInventoryItemsPanel(NULL),
mCOFObserver(NULL),
mGearMenu(NULL),
mCOFDragAndDropObserver(NULL),
mInitialized(false)
{
@ -254,6 +255,8 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);
childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL);
childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL);
childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list");
mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
@ -692,4 +695,31 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch
return false;
}
void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
{
if(!mGearMenu)
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Gear.OnClick", boost::bind(&LLPanelOutfitEdit::onGearMenuItemClick, this, _2));
mGearMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
"menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
mGearMenu->buildDrawLabels();
mGearMenu->updateParent(LLMenuGL::sMenuContainer);
}
S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight();
LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);
}
void LLPanelOutfitEdit::onGearMenuItemClick(const LLSD& data)
{
std::string param = data.asString();
if("add" == param)
{
// TODO
}
}
// EOF

View File

@ -58,6 +58,7 @@ class LLScrollListCtrl;
class LLToggleableMenu;
class LLFilterEditor;
class LLFilteredWearableListManager;
class LLMenuGL;
class LLPanelOutfitEdit : public LLPanel
{
@ -126,6 +127,8 @@ public:
private:
void onGearButtonClick(LLUICtrl* clicked_button);
void onGearMenuItemClick(const LLSD& data);
LLTextBox* mCurrentOutfitName;
@ -149,6 +152,7 @@ private:
std::vector<LLLookItemType> mLookItemTypes;
LLCOFWearables* mCOFWearables;
LLMenuGL* mGearMenu;
bool mInitialized;
};

View File

@ -383,11 +383,8 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
, _7 // EAcceptance* accept
));
mCommitCallbackRegistrar.add("panel_outfits_inventory_gear_default.Custom.Action",
boost::bind(&LLPanelOutfitsInventory::onCustomAction, this, _2));
mEnableCallbackRegistrar.add("panel_outfits_inventory_gear_default.Enable",
boost::bind(&LLPanelOutfitsInventory::isActionEnabled, this, _2));
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("panel_outfits_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_outfit_gear.xml",
gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
}
void LLPanelOutfitsInventory::updateListCommands()

View File

@ -42,6 +42,7 @@
#include "llagent.h"
#include "llagentdata.h" // for gAgentID
#include "llavataractions.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llviewermenu.h" // for gMenuHolder
namespace LLPanelPeopleMenus
@ -49,64 +50,6 @@ namespace LLPanelPeopleMenus
NearbyMenu gNearbyMenu;
//== ContextMenu ==============================================================
ContextMenu::ContextMenu()
: mMenu(NULL)
{
}
ContextMenu::~ContextMenu()
{
// do not forget delete LLContextMenu* mMenu.
// It can have registered Enable callbacks which are called from the LLMenuHolderGL::draw()
// via selected item (menu_item_call) by calling LLMenuItemCallGL::buildDrawLabel.
// we can have a crash via using callbacks of deleted instance of ContextMenu. EXT-4725
// menu holder deletes its menus on viewer exit, so we have no way to determine if instance
// of mMenu has already been deleted except of using LLHandle. EXT-4762.
if (!mMenuHandle.isDead())
{
mMenu->die();
mMenu = NULL;
}
}
void ContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
{
if (mMenu)
{
//preventing parent (menu holder) from deleting already "dead" context menus on exit
LLView* parent = mMenu->getParent();
if (parent)
{
parent->removeChild(mMenu);
}
delete mMenu;
mMenu = NULL;
mUUIDs.clear();
}
if ( uuids.empty() )
return;
mUUIDs.resize(uuids.size());
std::copy(uuids.begin(), uuids.end(), mUUIDs.begin());
mMenu = createMenu();
mMenuHandle = mMenu->getHandle();
mMenu->show(x, y);
LLMenuGL::showPopup(spawning_view, mMenu, x, y);
}
void ContextMenu::hide()
{
if(mMenu)
{
mMenu->hide();
}
}
//== NearbyMenu ===============================================================
LLContextMenu* NearbyMenu::createMenu()
@ -135,8 +78,7 @@ LLContextMenu* NearbyMenu::createMenu()
enable_registrar.add("Avatar.CheckItem", boost::bind(&NearbyMenu::checkContextMenuItem, this, _2));
// create the context menu from the XUI
return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_people_nearby.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
return createFromFile("menu_people_nearby.xml");
}
else
{
@ -151,9 +93,7 @@ LLContextMenu* NearbyMenu::createMenu()
enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2));
// create the context menu from the XUI
return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
("menu_people_nearby_multiselect.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
return createFromFile("menu_people_nearby_multiselect.xml");
}
}

View File

@ -33,42 +33,15 @@
#ifndef LL_LLPANELPEOPLEMENUS_H
#define LL_LLPANELPEOPLEMENUS_H
#include "llavatarlistitem.h"
#include "lllistcontextmenu.h"
namespace LLPanelPeopleMenus
{
/**
* Base context menu.
*/
class ContextMenu : public LLAvatarListItem::ContextMenu
{
public:
ContextMenu();
virtual ~ContextMenu();
/**
* Show the menu at specified coordinates.
*
* @param uuids - an array of avatar or group ids
*/
/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
virtual void hide();
protected:
virtual LLContextMenu* createMenu() = 0;
uuid_vec_t mUUIDs;
LLContextMenu* mMenu;
LLHandle<LLView> mMenuHandle;
};
/**
* Menu used in the nearby people list.
*/
class NearbyMenu : public ContextMenu
class NearbyMenu : public LLListContextMenu
{
public:
/*virtual*/ LLContextMenu* createMenu();

View File

@ -47,6 +47,7 @@ class LLFlatListView;
class LLTeleportHistoryPanel : public LLPanelPlacesTab
{
public:
// *TODO: derive from LLListContextMenu?
class ContextMenu
{
public:

View File

@ -648,8 +648,7 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
enable_registrar.add("ParticipantList.CheckItem", boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem, this, _2));
// create the context menu from the XUI
LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
LLContextMenu* main_menu = createFromFile("menu_participant_list.xml");
// Don't show sort options for P2P chat
bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
@ -666,10 +665,10 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
{
LLPanelPeopleMenus::ContextMenu::show(spawning_view, uuids, x, y);
if (uuids.size() == 0) return;
LLListContextMenu::show(spawning_view, uuids, x, y);
const LLUUID& speaker_id = mUUIDs.front();
BOOL is_muted = isMuted(speaker_id);

View File

@ -32,8 +32,8 @@
#include "llviewerprecompiledheaders.h"
#include "llevent.h"
#include "llpanelpeoplemenus.h"
#include "llavatarlist.h" // for LLAvatarItemRecentSpeakerComparator
#include "lllistcontextmenu.h"
class LLSpeakerMgr;
class LLAvatarList;
@ -148,7 +148,7 @@ class LLParticipantList
/**
* Menu used in the participant list.
*/
class LLParticipantListMenu : public LLPanelPeopleMenus::ContextMenu
class LLParticipantListMenu : public LLListContextMenu
{
public:
LLParticipantListMenu(LLParticipantList& parent):mParent(parent){};

View File

@ -35,8 +35,10 @@
#include "lliconctrl.h"
#include "llagentwearables.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llmenugl.h" // for LLContextMenu
#include "lltransutil.h"
class LLFindOutfitItems : public LLInventoryCollectFunctor
@ -377,12 +379,17 @@ static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;
static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
LLWearableItemsList::Params::Params()
: use_internal_context_menu("use_internal_context_menu", true)
{}
LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
: LLInventoryItemsList(p)
{
setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
if (p.use_internal_context_menu)
{
setRightMouseDownCallback(boost::bind(&LLWearableItemsList::onRightClick, this, _2, _3));
}
}
// virtual
@ -406,4 +413,27 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)
refreshList(item_array);
}
void LLWearableItemsList::onRightClick(S32 x, S32 y)
{
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
if (selected_uuids.empty())
{
return;
}
ContextMenu::instance().show(this, selected_uuids, x, y);
}
//////////////////////////////////////////////////////////////////////////
/// ContextMenu
//////////////////////////////////////////////////////////////////////////
// virtual
LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
{
return createFromFile("menu_wearable_list_item.xml");
}
// EOF

View File

@ -32,11 +32,14 @@
#ifndef LL_LLWEARABLEITEMSLIST_H
#define LL_LLWEARABLEITEMSLIST_H
// libs
#include "llpanel.h"
#include "llsingleton.h"
// newview
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
#include "lllistcontextmenu.h"
#include "llwearabletype.h"
/**
@ -274,8 +277,23 @@ private:
class LLWearableItemsList : public LLInventoryItemsList
{
public:
/**
* Context menu.
*
* This menu is likely to be used from outside
* (e.g. for items selected across multiple wearable lists),
* so making it a singleton.
*/
class ContextMenu : public LLListContextMenu, public LLSingleton<ContextMenu>
{
protected:
/* virtual */ LLContextMenu* createMenu();
};
struct Params : public LLInitParam::Block<Params, LLInventoryItemsList::Params>
{
Optional<bool> use_internal_context_menu;
Params();
};
@ -286,6 +304,8 @@ public:
protected:
friend class LLUICtrlFactory;
LLWearableItemsList(const LLWearableItemsList::Params& p);
void onRightClick(S32 x, S32 y);
};
#endif //LL_LLWEARABLEITEMSLIST_H

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
name="COF Attachment">
<menu_item_call
label="Detach"
layout="topleft"
name="detach">
<on_click
function="Attachment.Detach"
parameter="detach"/>
</menu_item_call>
<context_menu
label="Attach to"
layout="topleft"
name="attach_to" />
<context_menu
label="Attach to HUD"
layout="topleft"
name="attach_to_hud" />
</context_menu>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
name="COF Body">
<menu_item_call
label="Replace"
layout="topleft"
name="replace">
<on_click
function="BodyPart.Replace"/>
</menu_item_call>
<menu_item_call
label="Edit"
layout="topleft"
name="edit">
<on_click
function="BodyPart.Edit"/>
<on_enable
function="BodyPart.OnEnable"
parameter="edit" />
</menu_item_call>
</context_menu>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
name="COF Clothing">
<menu_item_call
label="Take Off"
layout="topleft"
name="take_off">
<on_click
function="Clothing.TakeOff" />
</menu_item_call>
<menu_item_call
label="Move Up a Layer"
layout="topleft"
name="move_up">
<on_click
function="Clothing.MoveUp" />
<on_enable
function="Clothing.OnEnable"
parameter="move_up" />
</menu_item_call>
<menu_item_call
label="Move Down a Layer"
layout="topleft"
name="move_down">
<on_click
function="Clothing.MoveDown" />
<on_enable
function="Clothing.OnEnable"
parameter="move_down" />
</menu_item_call>
<menu_item_call
label="Edit"
layout="topleft"
name="edit">
<on_click
function="Clothing.Edit" />
<on_enable
function="Clothing.OnEnable"
parameter="edit" />
</menu_item_call>
</context_menu>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<menu
layout="topleft"
name="Gear COF">
<menu_item_call
label="Add To Outfit"
layout="topleft"
name="add">
<on_click
function="Gear.OnClick"
parameter="add"/>
<on_enable
function="Gear.OnEnable"
parameter="add" />
</menu_item_call>
</menu>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<menu
layout="topleft"
name="Gear Outfit">
<menu_item_call
label="Wear - Replace Current Outfit"
layout="topleft"
name="wear">
<on_click
function="Gear.OnClick"
parameter="wear"/>
<on_enable
function="Gear.OnEnable"
parameter="wear" />
</menu_item_call>
<menu_item_call
label="Take Off - Remove Current Outfit"
layout="topleft"
name="take_off">
<on_click
function="Gear.OnClick"
parameter="take_off"/>
<on_enable
function="Gear.OnEnable"
parameter="take_off" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
label="Rename"
layout="topleft"
name="rename">
<on_click
function="Gear.OnClick"
parameter="rename"/>
<on_enable
function="Gear.OnEnable"
parameter="rename" />
</menu_item_call>
<menu_item_call
label="Delete Outfit"
layout="topleft"
name="delete_outfit">
<on_click
function="Gear.OnClick"
parameter="delete_outfit"/>
<on_enable
function="Gear.OnEnable"
parameter="delete_outfit" />
</menu_item_call>
</menu>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
name="Outfit">
<menu_item_call
label="Wear - Replace Current Outfit"
layout="topleft"
name="wear_replace">
<on_click
function="Outfit.WearReplace" />
</menu_item_call>
<menu_item_call
label="Wear - Add to Current Outfit"
layout="topleft"
name="wear_add">
<on_click
function="Outfit.WearAdd" />
</menu_item_call>
<menu_item_call
label="Take Off - Remove Current Outfit"
layout="topleft"
name="take_off">
<on_click
function="Outfit.TakeOff" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
label="Rename"
layout="topleft"
name="rename">
<on_click
function="Outfit.Rename" />
</menu_item_call>
<menu_item_call
label="Delete Outfit"
layout="topleft"
name="delete">
<on_click
function="Outfit.Delete" />
</menu_item_call>
</context_menu>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
name="Outfit Wearable Context Menu">
<menu_item_call
label="Wear"
layout="topleft"
name="wear">
<on_click
function="Wearable.Wear" />
</menu_item_call>
<menu_item_call
label="Detach"
layout="topleft"
name="detach">
<on_click
function="Attachment.Detach" />
</menu_item_call>
<!-- *TODO: implement the submenus
<menu
label="Attach to"
layout="topleft"
name="attach_to" />
<menu
label="Attach to HUD"
layout="topleft"
name="attach_to_hud" />
-->
<menu_item_call
label="Object Profile"
layout="topleft"
name="object_profile">
<on_click
function="Attachment.Profile" />
</menu_item_call>
<menu_item_call
label="Take Off"
layout="topleft"
name="take_off">
<on_click
function="Clothing.TakeOff"
parameter="take_off"/>
</menu_item_call>
<menu_item_call
label="Edit"
layout="topleft"
name="edit">
<on_click
function="Wearable.Edit"
parameter="edit"/>
</menu_item_call>
<menu_item_call
label="Show Original"
layout="topleft"
name="show_original">
<on_click
function="Wearable.ShowOriginal" />
</menu_item_call>
</context_menu>

View File

@ -15,6 +15,7 @@
allow_select="true"
follows="all"
keep_one_selected="true"
multi_select="true"
name="wearable_items_list"
translate="false"
/>

View File

@ -29,6 +29,7 @@
height="10"
layout="topleft"
left="0"
multi_select="true"
name="list_attachments"
top="0"
width="311" />
@ -63,6 +64,7 @@
height="10"
layout="topleft"
left="0"
multi_select="true"
name="list_clothing"
top_pad="0"
width="311" />
@ -98,6 +100,7 @@
height="10"
layout="topleft"
left="0"
multi_select="true"
name="list_body_parts"
top_pad="0"
width="311" />