diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index cce9eb172..943dcac59 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1945,7 +1945,7 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory { // SUBMENU LLMenuGL *submenu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory); - appendMenu(submenu); + appendMenu(submenu, 0); if (LLMenuGL::sMenuContainer != NULL) { submenu->updateParent(LLMenuGL::sMenuContainer); @@ -2214,18 +2214,24 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory } } +// This wrapper is needed because the virtual linkage causes errors if default parameters are used bool LLMenuGL::addChild(LLView* view, S32 tab_group) +{ + return addChild(view, 0, tab_group); +} + +bool LLMenuGL::addChild(LLView* view, LLView* insert_before, S32 tab_group) { if (LLMenuGL* menup = dynamic_cast(view)) { lldebugs << "Adding menu " << menup->getName() << " to " << getName() << llendl; - appendMenu(menup); + appendMenu(menup, insert_before); return true; } else if (LLMenuItemGL* itemp = dynamic_cast(view)) { lldebugs << "Adding " << itemp->getName() << " to " << getName() << llendl; - append(itemp); + append(itemp, insert_before); return true; } lldebugs << "Error adding unknown child '"<<(view ? view->getName() : std::string("NULL")) << "' to " << getName() << llendl; @@ -2712,10 +2718,29 @@ BOOL LLMenuGL::handleJumpKey(KEY key) // Add the menu item to this menu. +// This wrapper is needed because the virtual linkage causes errors if default parameters are used BOOL LLMenuGL::append( LLMenuItemGL* item ) +{ + return append(item, 0); +} + +BOOL LLMenuGL::append(LLMenuItemGL* item, LLView* insert_before) { if (!item) return FALSE; + if (!insert_before) + { mItems.push_back( item ); + } + else + { + item_list_t::iterator i; + + for (i = mItems.begin(); i != mItems.end(); ++i) + if (*i == insert_before) + break; + mItems.insert(i, item); + } + LLUICtrl::addChild(item); needsArrange(); return TRUE; @@ -2729,7 +2754,13 @@ BOOL LLMenuGL::addSeparator() } // add a menu - this will create a cascading menu +// This wrapper is needed because the virtual linkage causes errors if default parameters are used BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) +{ + return appendMenu(menu, 0); +} + +BOOL LLMenuGL::appendMenu(LLMenuGL* menu, LLView* insert_before) { if( menu == this ) { @@ -2741,7 +2772,7 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) LLMenuItemBranchGL* branch = NULL; branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu->getHandle() ); branch->setJumpKey(menu->getJumpKey()); - success &= append( branch ); + success &= append( branch, insert_before ); // Inherit colors menu->setBackgroundColor( mBackgroundColor ); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 581fcc1a5..07effab8d 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -476,6 +476,8 @@ public: /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); + bool addChild(LLView* view, LLView* insert_before, S32 tab_group = 0); + virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLMenuGL* getChildMenuByName(const std::string& name, BOOL recurse) const; @@ -572,11 +574,14 @@ public: protected: void createSpilloverBranch(); void cleanupSpilloverBranch(); + // Add the menu item to this menu. virtual BOOL append( LLMenuItemGL* item ); + BOOL append(LLMenuItemGL* item, LLView* insert_before); // add a menu - this will create a cascading menu virtual BOOL appendMenu( LLMenuGL* menu ); + BOOL appendMenu(LLMenuGL* menu, LLView* insert_before); // TODO: create accessor methods for these? typedef std::list< LLMenuItemGL* > item_list_t; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f1b2d4aff..7cd5efada 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -93,6 +93,7 @@ #include "lldrawable.h" #include "lldrawpoolalpha.h" #include "lldrawpooltree.h" +#include "llenvmanager.h" #include "llface.h" #include "llfirstuse.h" #include "llfloater.h" @@ -278,6 +279,8 @@ void init_client_menu(LLMenuGL* menu); void init_server_menu(LLMenuGL* menu); typedef LLPointer LLViewerObjectPtr; +typedef std::vector custom_menu_item_list_t; +custom_menu_item_list_t gCustomMenuItems; void init_debug_world_menu(LLMenuGL* menu); void init_debug_rendering_menu(LLMenuGL* menu); @@ -621,6 +624,10 @@ void menu_toggle_attached_particles(void* user_data); BOOL enable_dump_archetype_xm(void*); void handle_dump_archetype_xml(void *); +void region_change(); +void parse_simulator_features(); +void custom_selected(void* user_data); + class LLMenuParcelObserver : public LLParcelObserver { public: @@ -895,6 +902,18 @@ void init_menus() gLoginMenuBarView->setBackgroundColor( color ); gMenuHolder->addChild(gLoginMenuBarView); + + LLView* ins = gMenuBarView->getChildView("insert_world", true, false); + ins->setVisible(false); + ins = gMenuBarView->getChildView("insert_agent", true, false); + ins->setVisible(false); + ins = gMenuBarView->getChildView("insert_tools", true, false); + ins->setVisible(false); + /* Singu Note: When the advanced menu is made xml, this should be uncommented. + ins = gMenuBarView->getChildView("insert_advanced", true, false); + ins->setVisible(false);*/ + + LLEnvManagerNew::instance().setRegionChangeCallback(®ion_change); } @@ -1181,6 +1200,13 @@ void init_client_menu(LLMenuGL* menu) NULL, &menu_check_control, (void*) "MouseSmooth")); + + // Singu Note: When this menu is xml, handle this above, with the other insertion points + { + LLMenuItemCallGL* item = new LLMenuItemCallGL("insert_advanced", NULL); + item->setVisible(false); + menu->addChild(item); + } menu->addSeparator(); menu->addChild(new LLMenuItemCheckGL( "Console Window", @@ -9695,3 +9721,73 @@ void initialize_menus() LLToolMgr::getInstance()->initMenu(sMenus); } + +void region_change() +{ + // Remove current dynamic items + for (custom_menu_item_list_t::iterator i = gCustomMenuItems.begin(); i != gCustomMenuItems.end(); ++i) + { + LLMenuItemCallGL* item = (*i); + item->getParent()->removeChild(item); + delete item; + } + gCustomMenuItems.clear(); + + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + if (regionp->getFeaturesReceived()) + { + parse_simulator_features(); + } + else + { + regionp->setFeaturesReceivedCallback(boost::bind(&parse_simulator_features)); + } +} + +void parse_simulator_features() +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + LLSD info; + regionp->getSimulatorFeatures(info); + if (!info.has("menus")) return; + + LLSD menus = info["menus"]; + for (LLSD::map_iterator i = menus.beginMap(); i != menus.endMap(); ++i) + { + std::string insertMarker = "insert_" + i->first; + + LLView* marker = gMenuBarView->getChildView(insertMarker, true, false); + if (!marker) continue; + + LLMenuGL* menu = dynamic_cast(marker->getParent()); + if (!menu) continue; + + for (LLSD::map_iterator j = i->second.beginMap(); j != i->second.endMap(); ++j) + { + LLMenuItemCallGL* custom = new LLMenuItemCallGL(j->second.asString(), j->first, custom_selected); + custom->setUserData(custom); + gCustomMenuItems.push_back(custom); + menu->addChild(custom, marker); + } + } +} + +void custom_selected(void* user_data) +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + std::string url = regionp->getCapability("CustomMenuAction"); + if (url.empty()) return; + + LLMenuItemCallGL* custom = (LLMenuItemCallGL*)user_data; + + LLSD menuAction = LLSD::emptyMap(); + menuAction["action"] = LLSD(custom->getName()); + + LLHTTPClient::post(url, menuAction, new LLHTTPClient::ResponderIgnore); +} diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 4638a1522..d4cbd7821 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1637,6 +1637,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("CreateInventoryCategory"); + capabilityNames.append("CustomMenuAction"); capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("EnvironmentSettings"); capabilityNames.append("EstateChangeInfo"); diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 23f964546..43a7a4f33 100644 --- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -544,6 +544,7 @@ + + +