From 6589c200199e1fe0d0bf5f610d990ae197108981 Mon Sep 17 00:00:00 2001 From: Paul Guslisty Date: Thu, 7 Oct 2010 13:46:50 +0300 Subject: STORM-263 FIXED Cog button in lower-left of sidebar panel does not close popup menu on second click - In all places of sidebar panel where gear menu button is used changed type of gear menu buttons from LLButton to LLMenuButton - Added setMenuPosition and setMenu to the LLMenuButton interface as public methods - In all sidebar panels where LLButton was replaced with LLMenuButton the algorithm of replacing is simple and the same for all sidebar panels. In general the algorithm is: 1. set gearMenu to the menuButton using LLMenuButton::setMenu 2. set mouse down callback for the menuButton 3. in callback for mouse down set the menu position where it should be shown using LLMenuButton::setMenuPosition --- indra/llui/llmenubutton.cpp | 32 +++++- indra/llui/llmenubutton.h | 11 ++- indra/newview/lloutfitslist.cpp | 23 ++++- indra/newview/llpanellandmarks.cpp | 12 +++ indra/newview/llpanelmaininventory.cpp | 13 ++- indra/newview/llpanelmaininventory.h | 2 + indra/newview/llpaneloutfitedit.cpp | 27 +++-- indra/newview/llpaneloutfitedit.h | 5 +- indra/newview/llpanelpeople.cpp | 110 ++++++++++++--------- indra/newview/llpanelpeople.h | 11 ++- indra/newview/llpanelteleporthistory.cpp | 30 +++--- indra/newview/llpanelteleporthistory.h | 2 + indra/newview/llpanelwearing.cpp | 24 ++++- .../skins/default/xui/en/panel_landmarks.xml | 2 +- .../skins/default/xui/en/panel_main_inventory.xml | 2 +- .../skins/default/xui/en/panel_outfit_edit.xml | 4 +- .../skins/default/xui/en/panel_outfits_list.xml | 2 +- .../skins/default/xui/en/panel_outfits_wearing.xml | 2 +- .../newview/skins/default/xui/en/panel_people.xml | 9 +- .../default/xui/en/panel_teleport_history.xml | 2 +- 20 files changed, 227 insertions(+), 98 deletions(-) (limited to 'indra') diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index 3df05f4d3f..0930eb95dd 100644 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -57,6 +57,8 @@ LLMenuButton::LLMenuButton(const LLMenuButton::Params& p) llwarns << "Error loading menu_button menu" << llendl; } } + + setMenuPosition(); } void LLMenuButton::toggleMenu() @@ -70,12 +72,34 @@ void LLMenuButton::toggleMenu() } else { - LLRect rect = getRect(); - //mMenu->needsArrange(); //so it recalculates the visible elements - LLMenuGL::showPopup(getParent(), mMenu, rect.mLeft, rect.mBottom); + //mMenu->needsArrange(); //so it recalculates the visible elements + LLMenuGL::showPopup(getParent(), mMenu, mX, mY); } } +void LLMenuButton::setMenuPosition(EMenuPosition position /*ON_BOTTOM_LEFT*/) +{ + if (!mMenu) + return; + + LLRect rect = getRect(); + + switch (position) + { + case ON_TOP_LEFT: + { + mX = rect.mLeft; + mY = rect.mTop + mMenu->getRect().getHeight(); + break; + } + case ON_BOTTOM_LEFT: + { + mX = rect.mLeft; + mY = rect.mBottom; + break; + } + } +} void LLMenuButton::hideMenu() { @@ -109,6 +133,8 @@ BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask) setFocus(TRUE); } + LLUICtrl::handleMouseDown(x, y, mask); + toggleMenu(); if (getSoundFlags() & MOUSE_DOWN) diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h index 81ca0e047c..273af2413e 100644 --- a/indra/llui/llmenubutton.h +++ b/indra/llui/llmenubutton.h @@ -42,14 +42,22 @@ public: Optional menu_filename; Params(); - }; + }; + + enum EMenuPosition + { + ON_TOP_LEFT, + ON_BOTTOM_LEFT + }; void toggleMenu(); + void setMenuPosition(EMenuPosition position = ON_BOTTOM_LEFT); /*virtual*/ void draw(); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); void hideMenu(); LLMenuGL* getMenu() { return mMenu; } + void setMenu(LLMenuGL* menu) { mMenu = menu; } protected: friend class LLUICtrlFactory; @@ -58,6 +66,7 @@ protected: private: LLMenuGL* mMenu; bool mMenuVisibleLastFrame; + S32 mX, mY; }; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index c0f7fa4abf..bd9536d931 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -38,6 +38,7 @@ #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "lllistcontextmenu.h" +#include "llmenubutton.h" #include "llnotificationsutil.h" #include "lloutfitobserver.h" #include "llsidetray.h" @@ -99,10 +100,8 @@ public: updateItemsVisibility(); mMenu->buildDrawLabels(); + mMenu->arrangeAndClear(); mMenu->updateParent(LLMenuGL::sMenuContainer); - S32 menu_x = 0; - S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight(); - LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y); } void updateItemsVisibility() @@ -115,6 +114,8 @@ public: mMenu->arrangeAndClear(); // update menu height } + LLMenuGL* getMenu() { return mMenu; } + private: const LLUUID& getSelectedOutfitID() { @@ -353,6 +354,15 @@ BOOL LLOutfitsList::postBuild() mAccordion = getChild("outfits_accordion"); mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR); + LLMenuButton* menu_gear_btn = getChild("options_gear_btn"); + + // LLMenuButton::handleMouseDownCallback calls signal LLUICtrl::mouse_signal_t, not LLButton::commit_signal_t. + // That's why to set signal LLUICtrl::mouse_signal_t we need to upcast to LLUICtrl. Using static_cast instead + // of getChild(...) for performance. + static_cast(menu_gear_btn)->setMouseDownCallback(boost::bind(&LLOutfitsList::showGearMenu, this, _1)); + + menu_gear_btn->setMenu(mGearMenu->getMenu()); + return TRUE; } @@ -695,7 +705,14 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata) void LLOutfitsList::showGearMenu(LLView* spawning_view) { if (!mGearMenu) return; + mGearMenu->show(spawning_view); + + LLMenuButton* btn = dynamic_cast(spawning_view); + if (btn) + { + btn->setMenuPosition(LLMenuButton::ON_TOP_LEFT); + } } void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 24bf67a000..0e74cce37f 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -47,6 +47,7 @@ #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" #include "lllandmarkactions.h" +#include "llmenubutton.h" #include "llplacesinventorybridge.h" #include "llplacesinventorypanel.h" #include "llsidetray.h" @@ -707,6 +708,8 @@ void LLLandmarksPanel::initListCommandsHandlers() mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME)); + + getChild("options_gear_btn")->setMouseDownCallback(boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); } @@ -751,6 +754,15 @@ void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_ menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); LLView* spawning_view = getChild (spawning_view_name); + + LLMenuButton* btn = dynamic_cast (spawning_view); + if (btn) + { + btn->setMenu(menu); + btn->setMenuPosition(LLMenuButton::ON_TOP_LEFT); + return; + } + S32 menu_x, menu_y; //show menu in co-ordinates of panel spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 27e054af34..59d58321a9 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -192,6 +192,8 @@ BOOL LLPanelMainInventory::postBuild() mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2)); } + mGearMenuButton = getChild("options_gear_btn"); + initListCommandsHandlers(); // *TODO:Get the cost info from the server @@ -900,10 +902,14 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data) void LLPanelMainInventory::initListCommandsHandlers() { - childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this)); childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this)); childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this)); + // LLMenuButton::handleMouseDownCallback calls signal LLUICtrl::mouse_signal_t, not LLButton::commit_signal_t. + // That's why to set signal LLUICtrl::mouse_signal_t we need to upcast to LLUICtrl. Using static_cast instead + // of getChild(...) for performance. + static_cast(mGearMenuButton)->setMouseDownCallback(boost::bind(&LLPanelMainInventory::onGearButtonClick, this)); + mTrashButton = getChild("trash_btn"); mTrashButton->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this , _4 // BOOL drop @@ -914,6 +920,7 @@ void LLPanelMainInventory::initListCommandsHandlers() mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mGearMenuButton->setMenu(mMenuGearDefault); mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); // Update the trash button when selected item(s) get worn or taken off. @@ -929,7 +936,9 @@ void LLPanelMainInventory::updateListCommands() void LLPanelMainInventory::onGearButtonClick() { - showActionMenu(mMenuGearDefault,"options_gear_btn"); + mMenuGearDefault->buildDrawLabels(); + mMenuGearDefault->updateParent(LLMenuGL::sMenuContainer); + mGearMenuButton->setMenuPosition(LLMenuButton::ON_TOP_LEFT); } void LLPanelMainInventory::onAddButtonClick() diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index fb31206870..8853ba9248 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -31,6 +31,7 @@ #include "llpanel.h" #include "llinventoryobserver.h" #include "lldndbutton.h" +#include "llmenubutton.h" #include "llfolderview.h" @@ -144,6 +145,7 @@ private: LLDragAndDropButton* mTrashButton; LLMenuGL* mMenuGearDefault; LLMenuGL* mMenuAdd; + LLMenuButton* mGearMenuButton; bool mNeedUploadCost; // List Commands // diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 54b0805a6c..c625ba5a11 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -403,7 +403,9 @@ LLPanelOutfitEdit::LLPanelOutfitEdit() mAddWearablesPanel(NULL), mFolderViewFilterCmbBox(NULL), mListViewFilterCmbBox(NULL), - mPlusBtn(NULL) + mPlusBtn(NULL), + mWearablesGearMenuBtn(NULL), + mGearMenuBtn(NULL) { mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(FALSE); @@ -478,13 +480,20 @@ BOOL LLPanelOutfitEdit::postBuild() childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL); childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL); childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL); - childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); - childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL); childSetCommitCallback("shop_btn_2", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL); setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChange, this, _2)); + mWearablesGearMenuBtn = getChild("wearables_gear_menu_btn"); + mGearMenuBtn = getChild("gear_menu_btn"); + + // LLMenuButton::handleMouseDownCallback calls signal LLUICtrl::mouse_signal_t, not LLButton::commit_signal_t. + // That's why to set signal LLUICtrl::mouse_signal_t we need to upcast to LLUICtrl. Using static_cast instead + // of getChild(...) for performance. + static_cast(mWearablesGearMenuBtn)->setMouseDownCallback(boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1)); + static_cast(mGearMenuBtn)->setMouseDownCallback(boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1)); + mCOFWearables = getChild("cof_wearables_list"); mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::filterWearablesBySelectedItem, this)); @@ -1259,32 +1268,36 @@ void LLPanelOutfitEdit::resetAccordionState() void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) { LLMenuGL* menu = NULL; + LLMenuButton* btn = NULL; if (mAddWearablesPanel->getVisible()) { if (!mAddWearablesGearMenu) { mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel); + mWearablesGearMenuBtn->setMenu(mAddWearablesGearMenu); } menu = mAddWearablesGearMenu; + btn = mWearablesGearMenuBtn; } else { if (!mGearMenu) { mGearMenu = LLPanelOutfitEditGearMenu::create(); + mGearMenuBtn->setMenu(mGearMenu); } menu = mGearMenu; + btn = mGearMenuBtn; } - if (!menu) return; + if (!menu || !btn) return; - menu->arrangeAndClear(); // update menu height - S32 menu_y = menu->getRect().getHeight() + clicked_button->getRect().getHeight(); menu->buildDrawLabels(); - LLMenuGL::showPopup(clicked_button, menu, 0, menu_y); + menu->arrangeAndClear(); + btn->setMenuPosition(LLMenuButton::ON_TOP_LEFT); } void LLPanelOutfitEdit::onAddMoreButtonClicked() diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 2dca986e33..07edbdb9ba 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -38,6 +38,7 @@ #include "llinventory.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" +#include "llmenubutton.h" #include "llwearableitemslist.h" class LLButton; @@ -238,8 +239,8 @@ private: LLMenuGL* mAddWearablesGearMenu; bool mInitialized; std::auto_ptr mSaveComboBtn; - - + LLMenuButton* mWearablesGearMenuBtn; + LLMenuButton* mGearMenuBtn; }; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index d096b17145..8d387f3e85 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -463,7 +463,11 @@ LLPanelPeople::LLPanelPeople() mAllFriendList(NULL), mNearbyList(NULL), mRecentList(NULL), - mGroupList(NULL) + mGroupList(NULL), + mNearbyGearButton(NULL), + mFriendsGearButton(NULL), + mGroupsGearButton(NULL), + mRecentGearButton(NULL) { mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this)); mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this)); @@ -599,11 +603,6 @@ BOOL LLPanelPeople::postBuild() buttonSetAction("teleport_btn", boost::bind(&LLPanelPeople::onTeleportButtonClicked, this)); buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this)); - getChild(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked, this)); - getChild(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this)); - getChild(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked, this)); - getChild(GROUP_TAB_NAME)->childSetAction("groups_viewsort_btn",boost::bind(&LLPanelPeople::onGroupsViewSortButtonClicked, this)); - // Must go after setting commit callback and initializing all pointers to children. mTabContainer->selectTabByName(NEARBY_TAB_NAME); @@ -623,24 +622,49 @@ BOOL LLPanelPeople::postBuild() enable_registrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2)); enable_registrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2)); + mNearbyGearButton = getChild("nearby_view_sort_btn"); + mFriendsGearButton = getChild("friends_viewsort_btn"); + mGroupsGearButton = getChild("groups_viewsort_btn"); + mRecentGearButton = getChild("recent_viewsort_btn"); + + // LLMenuButton::handleMouseDownCallback calls signal LLUICtrl::mouse_signal_t, not LLButton::commit_signal_t. + // That's why to set signal LLUICtrl::mouse_signal_t we need to upcast to LLUICtrl. Using static_cast instead + // of getChild(...) for performance. + static_cast(mNearbyGearButton)->setMouseDownCallback(boost::bind(&LLPanelPeople::onViewSortButtonClicked, this)); + static_cast(mFriendsGearButton)->setMouseDownCallback(boost::bind(&LLPanelPeople::onViewSortButtonClicked, this)); + static_cast(mGroupsGearButton)->setMouseDownCallback(boost::bind(&LLPanelPeople::onViewSortButtonClicked, this)); + static_cast(mRecentGearButton)->setMouseDownCallback(boost::bind(&LLPanelPeople::onViewSortButtonClicked, this)); + LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGroupPlusMenuHandle = plus_menu->getHandle(); LLMenuGL* nearby_view_sort = LLUICtrlFactory::getInstance()->createFromFile("menu_people_nearby_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if(nearby_view_sort) + { mNearbyViewSortMenuHandle = nearby_view_sort->getHandle(); + mNearbyGearButton->setMenu(nearby_view_sort); + } LLMenuGL* friend_view_sort = LLUICtrlFactory::getInstance()->createFromFile("menu_people_friends_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if(friend_view_sort) + { mFriendsViewSortMenuHandle = friend_view_sort->getHandle(); + mFriendsGearButton->setMenu(friend_view_sort); + } LLMenuGL* group_view_sort = LLUICtrlFactory::getInstance()->createFromFile("menu_people_groups_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if(group_view_sort) + { mGroupsViewSortMenuHandle = group_view_sort->getHandle(); + mGroupsGearButton->setMenu(group_view_sort); + } LLMenuGL* recent_view_sort = LLUICtrlFactory::getInstance()->createFromFile("menu_people_recent_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if(recent_view_sort) + { mRecentViewSortMenuHandle = recent_view_sort->getHandle(); + mRecentGearButton->setMenu(recent_view_sort); + } LLVoiceClient::getInstance()->addObserver(this); @@ -907,20 +931,9 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const void LLPanelPeople::showGroupMenu(LLMenuGL* menu) { // Shows the menu at the top of the button bar. - - // Calculate its coordinates. - // (assumes that groups panel is the current tab) - LLPanel* bottom_panel = mTabContainer->getCurrentPanel()->getChild("bottom_panel"); - LLPanel* parent_panel = mTabContainer->getCurrentPanel(); menu->arrangeAndClear(); - S32 menu_height = menu->getRect().getHeight(); - S32 menu_x = -2; // *HACK: compensates HPAD in showPopup() - S32 menu_y = bottom_panel->getRect().mTop + menu_height; - - // Actually show the menu. menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(parent_panel, menu, menu_x, menu_y); } void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save) @@ -1347,36 +1360,39 @@ void LLPanelPeople::onMoreButtonClicked() // *TODO: not implemented yet } -void LLPanelPeople::onFriendsViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mFriendsViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); -} - -void LLPanelPeople::onGroupsViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mGroupsViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); -} - -void LLPanelPeople::onRecentViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mRecentViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); -} - -void LLPanelPeople::onNearbyViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mNearbyViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); +void LLPanelPeople::onViewSortButtonClicked() +{ + std::string current_panel = getActiveTabName(); + + LLMenuGL* menu = NULL; + LLMenuButton* btn = NULL; + + if (current_panel == NEARBY_TAB_NAME) + { + menu = dynamic_cast(mNearbyViewSortMenuHandle.get()); + btn = mNearbyGearButton; + } + else if (current_panel == FRIENDS_TAB_NAME) + { + menu = dynamic_cast(mFriendsViewSortMenuHandle.get()); + btn = mFriendsGearButton; + } + else if (current_panel == GROUP_TAB_NAME) + { + menu = dynamic_cast(mGroupsViewSortMenuHandle.get()); + btn = mGroupsGearButton; + } + else if (current_panel == RECENT_TAB_NAME) + { + menu = dynamic_cast(mRecentViewSortMenuHandle.get()); + btn = mRecentGearButton; + } + + if (menu && btn) + { + showGroupMenu(menu); + btn->setMenuPosition(LLMenuButton::ON_TOP_LEFT); + } } void LLPanelPeople::onOpen(const LLSD& key) diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index d0913ee756..3109feef0c 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -30,6 +30,7 @@ #include #include "llcallingcard.h" // for avatar tracker +#include "llmenubutton.h" #include "llvoiceclient.h" class LLFilterEditor; @@ -100,10 +101,7 @@ private: void onShareButtonClicked(); void onMoreButtonClicked(); void onActivateButtonClicked(); - void onRecentViewSortButtonClicked(); - void onNearbyViewSortButtonClicked(); - void onFriendsViewSortButtonClicked(); - void onGroupsViewSortButtonClicked(); + void onViewSortButtonClicked(); void onAvatarListDoubleClicked(LLUICtrl* ctrl); void onAvatarListCommitted(LLAvatarList* list); void onGroupPlusButtonClicked(); @@ -157,6 +155,11 @@ private: Updater* mNearbyListUpdater; Updater* mRecentListUpdater; + LLMenuButton* mNearbyGearButton; + LLMenuButton* mFriendsGearButton; + LLMenuButton* mGroupsGearButton; + LLMenuButton* mRecentGearButton; + std::string mFilterSubString; std::string mFilterSubStringOrig; }; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index a7cbf52290..216b7e2fa9 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -375,7 +375,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() mHistoryAccordion(NULL), mAccordionTabMenu(NULL), mLastSelectedFlatlList(NULL), - mLastSelectedItemIndex(-1) + mLastSelectedItemIndex(-1), + mMenuGearButton(NULL) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml"); } @@ -439,8 +440,6 @@ BOOL LLTeleportHistoryPanel::postBuild() } } - getChild("bottom_panel")->childSetAction("gear_btn",boost::bind(&LLTeleportHistoryPanel::onGearButtonClicked, this)); - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("TeleportHistory.ExpandAllFolders", boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders, this)); @@ -448,9 +447,19 @@ BOOL LLTeleportHistoryPanel::postBuild() registrar.add("TeleportHistory.ClearTeleportHistory", boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory, this)); mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); - LLMenuGL* gear_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mMenuGearButton = getChild("gear_btn"); + + LLMenuGL* gear_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());; if(gear_menu) + { mGearMenuHandle = gear_menu->getHandle(); + mMenuGearButton->setMenu(gear_menu); + } + + // LLMenuButton::handleMouseDownCallback calls signal LLUICtrl::mouse_signal_t, not LLButton::commit_signal_t. + // That's why to set signal LLUICtrl::mouse_signal_t we need to upcast to LLUICtrl. Using static_cast instead + // of getChild(...) for performance. + static_cast(mMenuGearButton)->setMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onGearButtonClicked, this)); return TRUE; } @@ -991,19 +1000,12 @@ void LLTeleportHistoryPanel::onGearButtonClicked() if (!menu) return; - // Shows the menu at the top of the button bar. - - // Calculate its coordinates. - LLPanel* bottom_panel = getChild("bottom_panel"); menu->arrangeAndClear(); - S32 menu_height = menu->getRect().getHeight(); - S32 menu_x = -2; // *HACK: compensates HPAD in showPopup() - S32 menu_y = bottom_panel->getRect().mTop + menu_height; - - // Actually show the menu. menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, menu, menu_x, menu_y); + + // Shows the menu at the top of the button bar. + mMenuGearButton->setMenuPosition(LLMenuButton::ON_TOP_LEFT); } bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index b5a025b39b..04809383f2 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -33,6 +33,7 @@ #include "llpanelplacestab.h" #include "llteleporthistory.h" #include "llmenugl.h" +#include "llmenubutton.h" class LLTeleportHistoryStorage; class LLAccordionCtrl; @@ -118,6 +119,7 @@ private: ContextMenu mContextMenu; LLContextMenu* mAccordionTabMenu; LLHandle mGearMenuHandle; + LLMenuButton* mMenuGearButton; }; diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 860470cd73..1b46294c52 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -32,6 +32,7 @@ #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" +#include "llmenubutton.h" #include "llsidetray.h" #include "llviewermenu.h" #include "llwearableitemslist.h" @@ -67,13 +68,13 @@ public: { if (!mMenu) return; + mMenu->arrangeAndClear(); mMenu->buildDrawLabels(); mMenu->updateParent(LLMenuGL::sMenuContainer); - S32 menu_x = 0; - S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight(); - LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y); } + LLMenuGL* getMenu() { return mMenu; } + private: void onTakeOff() @@ -189,6 +190,16 @@ BOOL LLPanelWearing::postBuild() mCOFItemsList = getChild("cof_items_list"); mCOFItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onWearableItemsListRightClick, this, _1, _2, _3)); + LLMenuButton* menu_gear_btn = getChild("options_gear_btn"); + + // LLMenuButton::handleMouseDownCallback calls signal LLUICtrl::mouse_signal_t, not LLButton::commit_signal_t. + // That's why to set signal LLUICtrl::mouse_signal_t we need to upcast to LLUICtrl. Using static_cast instead + // of getChild(...) for performance. + static_cast(menu_gear_btn)->setMouseDownCallback(boost::bind(&LLPanelWearing::showGearMenu, this, _1)); + + menu_gear_btn->setMenu(mGearMenu->getMenu()); + + return TRUE; } @@ -257,7 +268,14 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata) void LLPanelWearing::showGearMenu(LLView* spawning_view) { if (!mGearMenu) return; + mGearMenu->show(spawning_view); + + LLMenuButton* btn = dynamic_cast(spawning_view); + if (btn) + { + btn->setMenuPosition(LLMenuButton::ON_TOP_LEFT); + } } boost::signals2::connection LLPanelWearing::setSelectionChangeCallback(commit_callback_t cb) diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 7e415f45a4..5106215835 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -115,7 +115,7 @@ layout="topleft" name="options_gear_btn_panel" width="32"> -