From 511b0cfb9c86ec478aa0274a2c3bb8d4a5f753eb Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Wed, 6 Nov 2013 18:47:02 -0500 Subject: [PATCH] ContextMenu Support! LLContextMenu functionality pulled out of LLPieMenu, PieMenu is now derived from LLContextMenu - The more attribute boolean of pie_menu element determines whether or not to have an actual submenu if it's not a pie, defaults to false which means actual submenu.. -- in the future we may want to have more more="true" depending on feedback - Pie menu labels now dynamically get " >" appended to them (avoids stupid looking context menus) - Positioning logic combined in part, mostly conditional still, in the future we could probably combine it more. - handleHoverOver function combines common functionality between context and pies given an item and hover mouse coords. LiruUseContextMenus debug setting determines which to use, default is pie, of course - Context(/Pie) Menus are rebuilt when the setting changes value -- this is safe at any point because all startup states have been accounted for - "Use context menus instead of pie menus" added to System->General preferences (it's close to the bottom) --- indra/llui/llmenugl.cpp | 587 +++++++++++------- indra/llui/llmenugl.h | 93 ++- indra/llui/lluictrlfactory.cpp | 7 +- indra/llui/lluictrlfactory.h | 2 +- indra/newview/app_settings/settings.xml | 11 + indra/newview/ascentprefssys.cpp | 2 + indra/newview/ascentprefssys.h | 1 + indra/newview/lltoolpie.cpp | 12 +- indra/newview/llviewermenu.cpp | 89 +-- indra/newview/llviewermenu.h | 24 +- indra/newview/llvoavatarself.cpp | 89 ++- indra/newview/llvoavatarself.h | 1 + .../default/xui/de/menu_pie_attachment.xml | 4 +- .../skins/default/xui/de/menu_pie_avatar.xml | 4 +- .../skins/default/xui/de/menu_pie_object.xml | 14 +- .../skins/default/xui/de/menu_pie_self.xml | 12 +- .../default/xui/en-us/menu_pie_attachment.xml | 4 +- .../default/xui/en-us/menu_pie_avatar.xml | 4 +- .../default/xui/en-us/menu_pie_object.xml | 14 +- .../skins/default/xui/en-us/menu_pie_self.xml | 12 +- .../en-us/panel_preferences_ascent_system.xml | 3 +- .../default/xui/es/menu_pie_attachment.xml | 4 +- .../skins/default/xui/es/menu_pie_avatar.xml | 4 +- .../skins/default/xui/es/menu_pie_object.xml | 14 +- .../skins/default/xui/es/menu_pie_self.xml | 12 +- .../skins/default/xui/fr/menu_pie_avatar.xml | 2 +- .../skins/default/xui/fr/menu_pie_object.xml | 10 +- .../skins/default/xui/fr/menu_pie_self.xml | 12 +- .../skins/default/xui/pt/menu_pie_avatar.xml | 2 +- .../skins/default/xui/pt/menu_pie_object.xml | 8 +- .../skins/default/xui/pt/menu_pie_self.xml | 10 +- 31 files changed, 656 insertions(+), 411 deletions(-) diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 46c1f1b3e..19f348e9b 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3306,50 +3306,16 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->getParent()->sendChildToFront(menu); } -//----------------------------------------------------------------------------- -// class LLPieMenuBranch -// A branch to another pie menu -//----------------------------------------------------------------------------- -class LLPieMenuBranch : public LLMenuItemGL -{ -public: - LLPieMenuBranch(const std::string& name, const std::string& label, LLPieMenu* branch); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - - // called to rebuild the draw label - virtual void buildDrawLabel( void ); - - virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) - { - LLMenuItemGL::handleMouseUp(x,y,mask); - return TRUE; - } - - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ); - - LLPieMenu* getBranch() { return mBranch; } - -protected: - LLPieMenu* mBranch; -}; - -const F32 PIE_MENU_WIDTH = 190; -const F32 PIE_MENU_HEIGHT = 190; - -LLPieMenuBranch::LLPieMenuBranch(const std::string& name, - const std::string& label, - LLPieMenu* branch) +LLContextMenuBranch::LLContextMenuBranch(const std::string& name, const std::string& label, LLContextMenu* branch) : LLMenuItemGL( name, label, KEY_NONE, MASK_NONE ), mBranch( branch ) { - mBranch->hide(FALSE); + mBranch->hide(); mBranch->setParentMenuItem(this); } // virtual -LLXMLNodePtr LLPieMenuBranch::getXML(bool save_children) const +LLXMLNodePtr LLContextMenuBranch::getXML(bool save_children) const { if (mBranch) { @@ -3360,7 +3326,7 @@ LLXMLNodePtr LLPieMenuBranch::getXML(bool save_children) const } // called to rebuild the draw label -void LLPieMenuBranch::buildDrawLabel( void ) +void LLContextMenuBranch::buildDrawLabel( void ) { { // default enablement is this -- if any of the subitems are @@ -3386,63 +3352,72 @@ void LLPieMenuBranch::buildDrawLabel( void ) std::string st = mDrawAccelLabel; appendAcceleratorString( st ); mDrawAccelLabel = st; - - // No special branch suffix - mDrawBranchLabel.clear(); + + // Singu Note: This is meaningless to pies + mDrawBranchLabel = LLMenuGL::BRANCH_SUFFIX; +} + +void LLContextMenuBranch::showSubMenu() +{ + if (getDrawTextDisabled()) return; // Singu Note: Don't open disabled submenus! + S32 center_x; + S32 center_y; + static LLUICachedControl context("LiruUseContextMenus", false); + if (context) // Use the edge of this item + { + localPointToScreen(getRect().getWidth(), getRect().getHeight(), ¢er_x, ¢er_y); + } + else // Use the center of the parent pie menu, and hide it + { + LLContextMenu* parent = static_cast(getParent()); + const LLRect& rect = parent->getRect(); + parent->localPointToScreen(rect.getWidth() / 2, rect.getHeight() / 2, ¢er_x, ¢er_y); + parent->hide(); + } + mBranch->show(center_x, center_y, context); } // doIt() - do the primary funcationality of the menu item. -void LLPieMenuBranch::doIt( void ) +void LLContextMenuBranch::doIt( void ) { - if (getDrawTextDisabled()) return; // Singu Note: Don't open disabled submenus! - LLPieMenu *parent = (LLPieMenu *)getParent(); - - LLRect rect = parent->getRect(); - S32 center_x; - S32 center_y; - parent->localPointToScreen(rect.getWidth() / 2, rect.getHeight() / 2, ¢er_x, ¢er_y); - - parent->hide(FALSE); - mBranch->show( center_x, center_y, FALSE ); + showSubMenu(); } +void LLContextMenuBranch::setHighlight( BOOL highlight ) +{ + if (highlight == getHighlight()) return; + LLMenuItemGL::setHighlight(highlight); + + // Singu Note: Pie menus show subs only on click + static LLUICachedControl context("LiruUseContextMenus", false); + if (!context) return; + + if (highlight) + { + showSubMenu(); + } + else + { + mBranch->hide(); + } +} + +/////////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- -// class LLPieMenu -// A circular menu of items, icons, etc. +// class LLContextMenu +// A context menu //----------------------------------------------------------------------------- -LLPieMenu::LLPieMenu(const std::string& name, const std::string& label) -: LLMenuGL(name, label), - mFirstMouseDown(FALSE), - mUseInfiniteRadius(FALSE), - mHoverItem(NULL), - mHoverThisFrame(FALSE), +LLContextMenu::LLContextMenu(const std::string& name, const std::string& label) +: LLMenuGL(name, label.empty() ? name : label), mHoveredAnyItem(FALSE), - mOuterRingAlpha(1.f), - mCurRadius(0.f), - mRightMouseDown(FALSE) -{ - setRect(LLRect(0,PIE_MENU_HEIGHT,PIE_MENU_WIDTH,0)); + mHoverItem(NULL) +{ + //setBackgroundVisible(TRUE); LLMenuGL::setVisible(FALSE); } -LLPieMenu::LLPieMenu(const std::string& name) -: LLMenuGL(name, name), - mFirstMouseDown(FALSE), - mUseInfiniteRadius(FALSE), - mHoverItem(NULL), - mHoverThisFrame(FALSE), - mHoveredAnyItem(FALSE), - mOuterRingAlpha(1.f), - mCurRadius(0.f), - mRightMouseDown(FALSE) -{ - setRect(LLRect(0,PIE_MENU_HEIGHT,PIE_MENU_WIDTH,0)); - LLMenuGL::setVisible(FALSE); -} - - // virtual -LLXMLNodePtr LLPieMenu::getXML(bool save_children) const +LLXMLNodePtr LLContextMenu::getXML(bool save_children) const { LLXMLNodePtr node = LLMenuGL::getXML(); @@ -3451,22 +3426,34 @@ LLXMLNodePtr LLPieMenu::getXML(bool save_children) const return node; } -void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory) +void LLContextMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory, bool is_context) { LLXMLNodePtr child; for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { if (child->hasName(LL_PIE_MENU_TAG)) { - // SUBMENU - std::string name("menu"); - child->getAttributeString("name", name); - std::string label(name); - child->getAttributeString("label", label); + // In context menus, more submenu is just an extension of the parent + bool more(false); + if (is_context && child->getAttribute_bool("more", more) && more) + { + //addSeparator(); // Singu Note: perhaps a separator (above) is in order, too? + initXML(child, context, factory, true); + //addSeparator(); // Singu Note: perhaps a separator (below) is in order, too? + } + else + { + // SUBMENU + std::string name("menu"); + child->getAttributeString("name", name); + std::string label(name); + child->getAttributeString("label", label); - LLPieMenu *submenu = new LLPieMenu(name, label); - appendPieMenu(submenu); - submenu->initXML(child, context, factory); + // Singu Note: Pie Submenus are denoted with >, while context submenus have an obvious arrow at the end + LLContextMenu* submenu = is_context ? new LLContextMenu(name, label) : new LLPieMenu(name, label + " >"); + appendContextSubMenu(submenu); + submenu->initXML(child, context, factory, is_context); + } } else { @@ -3475,51 +3462,132 @@ void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *fac } } -bool LLPieMenu::addChild(LLView* view, S32 tab_group) -{ - if(LLMenuGL::addChild(view, tab_group)) - { - LLMenuItemSeparatorGL* sep = dynamic_cast(view); - if(sep) - sep->setVisible(false); - return true; - } - return false; -} - // virtual -void LLPieMenu::setVisible(BOOL visible) +void LLContextMenu::setVisible(BOOL visible) { if (!visible) { - hide(FALSE); + hide(); } } -BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) +void LLContextMenu::show(S32 x, S32 y, bool context) { - // This is mostly copied from the llview class, but it continues - // the hover handle code after a hover handler has been found. - BOOL handled = FALSE; - - // If we got a hover event, we've already moved the cursor - // for any menu shifts, so subsequent mouseup messages will be in the - // correct position. No need to correct them. - //mShiftHoriz = 0; - //mShiftVert = 0; - - // release mouse capture after short period of visibility if we're using a finite boundary - // so that right click outside of boundary will trigger new pie menu - if (hasMouseCapture() && - !mRightMouseDown && - mShrinkBorderTimer.getStarted() && - mShrinkBorderTimer.getElapsedTimeF32() >= PIE_SHRINK_TIME) + if (getChildList()->empty()) { - gFocusMgr.setMouseCapture(NULL); - mUseInfiniteRadius = FALSE; + // nothing to show, so abort + return; + } + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + // See also LLMenuGL::showPopup() + LLMenuHolderGL::sContextMenuSpawnPos.set(x,y); + + arrangeAndClear(); + + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); + const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); + LLView* parent_view = getParent(); + + // Singu TODO: These could probably be combined a bit more. + if (context) // Singu Note: Determine menu repositioning behavior based on menu type + { + // Open upwards if menu extends past bottom + if (y - height < menu_region_rect.mBottom) + { + if (getParentMenuItem()) + { + y += height - getParentMenuItem()->getNominalHeight(); + } + else + { + y += height; + } + } + + // Open out to the left if menu extends past right edge + if (x + width > menu_region_rect.mRight) + { + if (getParentMenuItem()) + { + x -= getParentMenuItem()->getRect().getWidth() + width; + } + else + { + x -= width; + } + } + + S32 local_x, local_y; + parent_view->screenPointToLocal(x, y, &local_x, &local_y); + + LLRect rect; + rect.setLeftTopAndSize(local_x, local_y, width, height); + setRect(rect); + } + else + { + S32 local_x, local_y; + parent_view->screenPointToLocal(x, y, &local_x, &local_y); + + LLRect rect; + rect.setCenterAndSize(local_x, local_y, width, height); + setRect(rect); + if (!menu_region_rect.contains(rect)) // Adjust the pie rectangle to keep it on screen + { + S32 trans[2]={0,0}; + if (rect.mLeft < menu_region_rect.mLeft) + { + trans[0] = menu_region_rect.mLeft - rect.mLeft; + } + else if (rect.mRight > menu_region_rect.mRight) + { + trans[0] = menu_region_rect.mRight - rect.mRight; + } + if (rect.mBottom < menu_region_rect.mBottom) + { + trans[1] = menu_region_rect.mBottom - rect.mBottom; + } + else if (rect.mTop > menu_region_rect.mTop) + { + trans[1] = menu_region_rect.mTop - rect.mTop; + } + setRect(rect.translate(trans[0],trans[1])); + LLUI::setMousePositionLocal(getParent(),rect.getCenterX(), rect.getCenterY()); + } } - LLMenuItemGL *item = pieItemFromXY( x, y ); + arrange(); + LLView::setVisible(TRUE); +} + +void LLContextMenu::hide() +{ + if (!getVisible()) return; + + LLView::setVisible(FALSE); + + if (mHoverItem) + { + mHoverItem->setHighlight( FALSE ); + mHoverItem = NULL; + } +} + +BOOL LLContextMenu::handleHover( S32 x, S32 y, MASK mask ) +{ + LLMenuGL::handleHover(x, y, mask); + + LLMenuItemGL* item = getHighlightedItem(); + + return handleHoverOver(item, x, y); +} + +BOOL LLContextMenu::handleHoverOver(LLMenuItemGL* item, S32 x, S32 y) +{ + BOOL handled = FALSE; if (item && item->getEnabled()) { @@ -3535,37 +3603,6 @@ BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) } mHoverItem = item; mHoverItem->setHighlight( TRUE ); - - switch(pieItemIndexFromXY(x, y)) - { - case 0: - make_ui_sound("UISndPieMenuSliceHighlight0"); - break; - case 1: - make_ui_sound("UISndPieMenuSliceHighlight1"); - break; - case 2: - make_ui_sound("UISndPieMenuSliceHighlight2"); - break; - case 3: - make_ui_sound("UISndPieMenuSliceHighlight3"); - break; - case 4: - make_ui_sound("UISndPieMenuSliceHighlight4"); - break; - case 5: - make_ui_sound("UISndPieMenuSliceHighlight5"); - break; - case 6: - make_ui_sound("UISndPieMenuSliceHighlight6"); - break; - case 7: - make_ui_sound("UISndPieMenuSliceHighlight7"); - break; - default: - make_ui_sound("UISndPieMenuSliceHighlight0"); - break; - } } mHoveredAnyItem = TRUE; } @@ -3586,11 +3623,170 @@ BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) handled = TRUE; } - mHoverThisFrame = TRUE; + return handled; +} + +// handleMouseUp and handleMouseDown are handled by LLMenuGL + + +BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handled = FALSE; + + // The click was somewhere within our rectangle + LLMenuItemGL* item = getHighlightedItem(); + + S32 local_x = x - getRect().mLeft; + S32 local_y = y - getRect().mBottom; + + BOOL clicked_in_menu = pointInView(local_x, local_y); + + // grab mouse if right clicking anywhere within pie (even deadzone in middle), to detect drag outside of pie + if (clicked_in_menu) + { + // capture mouse cursor as if on initial menu show + handled = TRUE; + } + + if (item) + { + // lie to the item about where the click happened + // to make sure it's within the item's rectangle + if (item->handleMouseDown( 0, 0, mask )) + { + handled = TRUE; + } + } return handled; } +BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask ) +{ + S32 local_x = x - getRect().mLeft; + S32 local_y = y - getRect().mBottom; + + if (!mHoveredAnyItem && !pointInView(local_x, local_y)) + { + sMenuContainer->hideMenus(); + return TRUE; + } + + + BOOL result = handleMouseUp( x, y, mask ); + mHoveredAnyItem = FALSE; + + return result; +} + +bool LLContextMenu::addChild(LLView* view, S32 tab_group) +{ + if (LLContextMenu* context = dynamic_cast(view)) + return appendContextSubMenu(context); + if (LLMenuItemGL* item = dynamic_cast(view)) + return append(item); + if (LLMenuGL* menu = dynamic_cast(view)) + return appendMenu(menu); + return false; +} + + +BOOL LLContextMenu::appendContextSubMenu(LLContextMenu* menu) +{ + if (menu == this) + { + llerrs << "Can't attach a context menu to itself" << llendl; + } + LLContextMenuBranch* item = new LLContextMenuBranch(menu->getName(), menu->getLabel(), menu); + getParent()->addChild(item->getBranch()); + return append(item); +} + +const S32 PIE_MENU_HEIGHT = 190; +const S32 PIE_MENU_WIDTH = 190; + +//----------------------------------------------------------------------------- +// class LLPieMenu +// A circular menu of items, icons, etc. +//----------------------------------------------------------------------------- +LLPieMenu::LLPieMenu(const std::string& name, const std::string& label) +: LLContextMenu(name, label), + mFirstMouseDown(FALSE), + mUseInfiniteRadius(FALSE), + mHoverThisFrame(FALSE), + mOuterRingAlpha(1.f), + mCurRadius(0.f), + mRightMouseDown(FALSE) +{ + setRect(LLRect(0,PIE_MENU_HEIGHT,PIE_MENU_WIDTH,0)); +} + +// Separators on pie menus are invisible +bool LLPieMenu::addChild(LLView* view, S32 tab_group) +{ + if (LLContextMenu::addChild(view, tab_group)) + { + LLMenuItemSeparatorGL* sep = dynamic_cast(view); + if(sep) + sep->setVisible(false); + return true; + } + return false; +} + +BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) +{ + // release mouse capture after short period of visibility if we're using a finite boundary + // so that right click outside of boundary will trigger new pie menu + if (hasMouseCapture() && + !mRightMouseDown && + mShrinkBorderTimer.getStarted() && + mShrinkBorderTimer.getElapsedTimeF32() >= PIE_SHRINK_TIME) + { + gFocusMgr.setMouseCapture(NULL); + mUseInfiniteRadius = FALSE; + } + + mHoverThisFrame = TRUE; + + LLMenuItemGL* item = pieItemFromXY( x, y ); + + if (item && item->getEnabled() && item != mHoverItem) + { + switch(pieItemIndexFromXY(x, y)) + { + case 0: + make_ui_sound("UISndPieMenuSliceHighlight0"); + break; + case 1: + make_ui_sound("UISndPieMenuSliceHighlight1"); + break; + case 2: + make_ui_sound("UISndPieMenuSliceHighlight2"); + break; + case 3: + make_ui_sound("UISndPieMenuSliceHighlight3"); + break; + case 4: + make_ui_sound("UISndPieMenuSliceHighlight4"); + break; + case 5: + make_ui_sound("UISndPieMenuSliceHighlight5"); + break; + case 6: + make_ui_sound("UISndPieMenuSliceHighlight6"); + break; + case 7: + make_ui_sound("UISndPieMenuSliceHighlight7"); + break; + default: + make_ui_sound("UISndPieMenuSliceHighlight0"); + break; + } + } + return handleHoverOver(item, x, y); +} + BOOL LLPieMenu::handleMouseDown( S32 x, S32 y, MASK mask ) { BOOL handled = FALSE; @@ -3689,7 +3885,7 @@ BOOL LLPieMenu::handleMouseUp( S32 x, S32 y, MASK mask ) if (item->getEnabled()) { handled = item->handleMouseUp( 0, 0, mask ); - hide(TRUE); + hide(); } } else if (!mRightMouseDown) @@ -3854,24 +4050,9 @@ BOOL LLPieMenu::append(LLMenuItemGL *item) BOOL LLPieMenu::addSeparator() { LLMenuItemGL* separator = new LLMenuItemBlankGL(); - separator->setFont( LLFontGL::getFontSansSerifSmall() ); return append( separator ); } - -BOOL LLPieMenu::appendPieMenu(LLPieMenu *menu) -{ - if (menu == this) - { - llerrs << "Can't attach a pie menu to itself" << llendl; - } - LLPieMenuBranch *item; - item = new LLPieMenuBranch(menu->getName(), menu->getLabel(), menu); - getParent()->addChild(item->getBranch()); - item->setFont( LLFontGL::getFontSansSerifSmall() ); - return append( item ); -} - // virtual void LLPieMenu::arrange() { @@ -4007,47 +4188,11 @@ S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) return which; } -void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) + +// virtual +void LLPieMenu::show(S32 x, S32 y, bool mouse_down) { - S32 width = getRect().getWidth(); - S32 height = getRect().getHeight(); - - const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); - - LLView* parent_view = getParent(); - - S32 local_x, local_y; - parent_view->screenPointToLocal(x, y, &local_x, &local_y); - - LLRect rect; - rect.setCenterAndSize(local_x, local_y, width, height); - setRect(rect); - - arrange(); - - // Adjust the pie rectangle to keep it on screen - if(!menu_region_rect.contains(rect)) - { - S32 trans[2]={0,0}; - if (rect.mLeft < menu_region_rect.mLeft) - { - trans[0] = menu_region_rect.mLeft - rect.mLeft; - } - else if (rect.mRight > menu_region_rect.mRight) - { - trans[0] = menu_region_rect.mRight - rect.mRight; - } - if (rect.mBottom < menu_region_rect.mBottom) - { - trans[1] = menu_region_rect.mBottom - rect.mBottom; - } - else if (rect.mTop > menu_region_rect.mTop) - { - trans[1] = menu_region_rect.mTop - rect.mTop; - } - setRect(rect.translate(trans[0],trans[1])); - LLUI::setMousePositionLocal(getParent(),rect.getCenterX(), rect.getCenterY()); - } + LLContextMenu::show(x, y, false); // *FIX: what happens when mouse buttons reversed? mRightMouseDown = mouse_down; @@ -4060,8 +4205,6 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) make_ui_sound("UISndPieMenuAppear"); } - LLView::setVisible(TRUE); - // we want all mouse events in case user does quick right click again off of pie menu // rectangle, to support gestural menu traversal gFocusMgr.setMouseCapture(this); @@ -4076,16 +4219,10 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) } } -void LLPieMenu::hide(BOOL item_selected) +// virtual +void LLPieMenu::hide() { - if (!getVisible()) return; - - if (mHoverItem) - { - mHoverItem->setHighlight( FALSE ); - mHoverItem = NULL; - } - + LLContextMenu::hide(); make_ui_sound("UISndPieMenuHide"); mFirstMouseDown = FALSE; @@ -4093,8 +4230,6 @@ void LLPieMenu::hide(BOOL item_selected) mUseInfiniteRadius = FALSE; mHoveredAnyItem = FALSE; - LLView::setVisible(FALSE); - gFocusMgr.setMouseCapture(NULL); } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 07effab8d..cac496497 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -685,29 +685,59 @@ private: +//----------------------------------------------------------------------------- +// class LLContextMenu +// A context menu +//----------------------------------------------------------------------------- +class LLContextMenu +: public LLMenuGL +{ +public: + LLContextMenu(const std::string& name, const std::string& label = ""); + + virtual LLXMLNodePtr getXML(bool save_children = true) const; + void initXML(LLXMLNodePtr node, LLView* context, LLUICtrlFactory* factory, bool is_context); + +public: + virtual ~LLContextMenu() {} + + // LLView Functionality + // can't set visibility directly, must call show or hide + virtual void setVisible(BOOL visible); + + virtual void show(S32 x, S32 y, bool context = true); + virtual void hide(); + + virtual BOOL handleHover( S32 x, S32 y, MASK mask ); + BOOL handleHoverOver(LLMenuItemGL* item, S32 x, S32 y); // Singu Note: Unify common functionality between Pie and Context hover behaviors + virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleRightMouseUp( S32 x, S32 y, MASK mask ); + + virtual bool addChild(LLView* view, S32 tab_group = 0); + + BOOL appendContextSubMenu(LLContextMenu* menu); + +protected: + BOOL mHoveredAnyItem; + LLMenuItemGL* mHoverItem; +}; + //----------------------------------------------------------------------------- // class LLPieMenu // A circular menu of items, icons, etc. //----------------------------------------------------------------------------- class LLPieMenu -: public LLMenuGL +: public LLContextMenu { public: - LLPieMenu(const std::string& name, const std::string& label); - LLPieMenu(const std::string& name); + LLPieMenu(const std::string& name, const std::string& label = ""); virtual ~LLPieMenu() {} - virtual LLXMLNodePtr getXML(bool save_children = true) const; - void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory); - // LLView Functionality // hide separators. they are added to 'pad' in empty cells. virtual bool addChild(LLView* view, S32 tab_group = 0); - // can't set visibility directly, must call show or hide - virtual void setVisible(BOOL visible); - virtual BOOL handleHover( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); @@ -721,34 +751,57 @@ private: public: virtual BOOL addSeparator(); - BOOL appendPieMenu(LLPieMenu *menu); - virtual void arrange( void ); // Display the menu centered on this point on the screen. - void show(S32 x, S32 y, BOOL mouse_down); - void hide(BOOL item_selected); + /*virtual*/ void show(S32 x, S32 y, bool mouse_down = true); + /*virtual*/ void hide(); private: LLMenuItemGL *pieItemFromXY(S32 x, S32 y); S32 pieItemIndexFromXY(S32 x, S32 y); - // These cause menu items to be spuriously selected by right-clicks - // near the window edge at low frame rates. I don't think they are - // needed unless you shift the menu position in the draw() function. JC - //S32 mShiftHoriz; // non-zero if menu had to shift this frame - //S32 mShiftVert; // non-zero if menu had to shift this frame BOOL mFirstMouseDown; // true from show until mouse up BOOL mUseInfiniteRadius; // allow picking pie menu items anywhere outside of center circle - LLMenuItemGL* mHoverItem; BOOL mHoverThisFrame; - BOOL mHoveredAnyItem; LLFrameTimer mShrinkBorderTimer; F32 mOuterRingAlpha; // for rendering pie menus as both bounded and unbounded F32 mCurRadius; BOOL mRightMouseDown; }; +//----------------------------------------------------------------------------- +// class LLContextMenuBranch +// A branch to another context menu +//----------------------------------------------------------------------------- +class LLContextMenuBranch : public LLMenuItemGL +{ +public: + LLContextMenuBranch(const std::string& name, const std::string& label, LLContextMenu* branch); + + virtual LLXMLNodePtr getXML(bool save_children = true) const; + + // called to rebuild the draw label + virtual void buildDrawLabel( void ); + + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) + { + LLMenuItemGL::handleMouseUp(x,y,mask); + return TRUE; + } + + // doIt() - do the primary funcationality of the menu item. + virtual void doIt( void ); + + LLContextMenu* getBranch() { return mBranch; } + void setHighlight( BOOL highlight ); + +protected: + void showSubMenu(); + + LLContextMenu* mBranch; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuBarGL diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index d5bb963d4..9cd8aa9d8 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -446,7 +446,7 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const std::string &filename, LLView* parent //----------------------------------------------------------------------------- // buildMenu() //----------------------------------------------------------------------------- -LLPieMenu *LLUICtrlFactory::buildPieMenu(const std::string &filename, LLView* parentp) +LLContextMenu* LLUICtrlFactory::buildContextMenu(const std::string& filename, LLView* parentp) { LLXMLNodePtr root; @@ -465,9 +465,10 @@ LLPieMenu *LLUICtrlFactory::buildPieMenu(const std::string &filename, LLView* pa std::string name("menu"); root->getAttributeString("name", name); - LLPieMenu *menu = new LLPieMenu(name); + static LLUICachedControl context("LiruUseContextMenus", false); + LLContextMenu* menu = context ? new LLContextMenu(name) : new LLPieMenu(name); parentp->addChild(menu); - menu->initXML(root, parentp, this); + menu->initXML(root, parentp, this, context); if (LLUI::sShowXUINames) { diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 3fac2bdb5..b3ef3aeeb 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -106,7 +106,7 @@ public: bool builtPanel(LLPanel* panelp) {return mBuiltPanels.find(panelp->getHandle()) != mBuiltPanels.end();} class LLMenuGL *buildMenu(const std::string &filename, LLView* parentp); - class LLPieMenu *buildPieMenu(const std::string &filename, LLView* parentp); + class LLContextMenu* buildContextMenu(const std::string& filename, LLView* parentp); // Does what you want for LLFloaters and LLPanels // Returns 0 on success diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6e872f10e..94b0fdf8f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -846,6 +846,17 @@ Found in Advanced->Rendering->Info Displays Value 0 + LiruUseContextMenus + + Comment + Use context menus instead of the default pie menus we all know and love. + Persist + 1 + Type + Boolean + Value + 0 + SLBShowFPS Comment diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index 41e17241e..c287fea3e 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -222,6 +222,7 @@ void LLPrefsAscentSys::refreshValues() mEnableClassicClouds = gSavedSettings.getBOOL("SkyUseClassicClouds"); mSpeedRez = gSavedSettings.getBOOL("SpeedRez"); mSpeedRezInterval = gSavedSettings.getU32("SpeedRezInterval"); + mUseContextMenus = gSavedSettings.getBOOL("LiruUseContextMenus"); mUseWebProfiles = gSavedSettings.getBOOL("UseWebProfiles"); mUseWebSearch = gSavedSettings.getBOOL("UseWebSearch"); @@ -377,6 +378,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("SkyUseClassicClouds", mEnableClassicClouds); gSavedSettings.setBOOL("SpeedRez", mSpeedRez); gSavedSettings.setU32("SpeedRezInterval", mSpeedRezInterval); + gSavedSettings.setBOOL("LiruUseContextMenus", mUseContextMenus); gSavedSettings.setBOOL("UseWebProfiles", mUseWebProfiles); gSavedSettings.setBOOL("UseWebSearch", mUseWebSearch); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index a862e9166..785d14940 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -73,6 +73,7 @@ private: bool mEnableClassicClouds; bool mSpeedRez; U32 mSpeedRezInterval; + bool mUseContextMenus; bool mUseWebProfiles; bool mUseWebSearch; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index f1904b312..fa74444ff 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1101,7 +1101,7 @@ BOOL LLToolPie::handleRightClickPick() { LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal ); gMenuHolder->setParcelSelection(selection); - gPieLand->show(x, y, true); + gPieLand->show(x, y); showVisualContextMenuEffect(); @@ -1115,7 +1115,7 @@ BOOL LLToolPie::handleRightClickPick() return TRUE ; } - gPieSelf->show(x, y, true); + gPieSelf->show(x, y); } else if (object) { @@ -1159,11 +1159,11 @@ BOOL LLToolPie::handleRightClickPick() // [/RLVa:KB] /*if (is_other_attachment) { - gPieAttachmentOther->show(x, y, true); + gPieAttachmentOther->show(x, y); } else*/ { - gPieAvatar->show(x, y, true); + gPieAvatar->show(x, y); } // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l } @@ -1175,7 +1175,7 @@ BOOL LLToolPie::handleRightClickPick() } else if (object->isAttachment()) { - gPieAttachment->show(x, y, true); + gPieAttachment->show(x, y); } else { @@ -1204,7 +1204,7 @@ BOOL LLToolPie::handleRightClickPick() { // [/RLVa:KB] gMenuHolder->childSetText("Object Mute", mute_msg); - gPieObject->show(x, y, true); + gPieObject->show(x, y); showVisualContextMenuEffect(); // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.el) | Modified: RLVa-1.1.0l diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e32525a9d..c009980e1 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -249,11 +249,11 @@ LLMenuGL *gPopupMenuView = NULL; LLMenuBarGL *gLoginMenuBarView = NULL; // Pie menus -LLPieMenu *gPieSelf = NULL; -LLPieMenu *gPieAvatar = NULL; -LLPieMenu *gPieObject = NULL; -LLPieMenu *gPieAttachment = NULL; -LLPieMenu *gPieLand = NULL; +LLContextMenu *gPieSelf = NULL; +LLContextMenu *gPieAvatar = NULL; +LLContextMenu *gPieObject = NULL; +LLContextMenu *gPieAttachment = NULL; +LLContextMenu *gPieLand = NULL; // local constants const std::string CLIENT_MENU_NAME("Advanced"); @@ -266,13 +266,13 @@ LLMenuGL* gAttachSubMenu = NULL; LLMenuGL* gDetachSubMenu = NULL; LLMenuGL* gTakeOffClothes = NULL; LLMenuGL* gMeshesAndMorphsMenu = NULL; -LLPieMenu* gPieRate = NULL; -LLPieMenu* gAttachScreenPieMenu = NULL; -LLPieMenu* gAttachPieMenu = NULL; -LLPieMenu* gAttachBodyPartPieMenus[8]; -LLPieMenu* gDetachPieMenu = NULL; -LLPieMenu* gDetachScreenPieMenu = NULL; -LLPieMenu* gDetachBodyPartPieMenus[8]; +LLContextMenu* gPieRate = NULL; +LLContextMenu* gAttachScreenPieMenu = NULL; +LLContextMenu* gAttachPieMenu = NULL; +LLContextMenu* gAttachBodyPartPieMenus[8]; +LLContextMenu* gDetachPieMenu = NULL; +LLContextMenu* gDetachScreenPieMenu = NULL; +LLContextMenu* gDetachBodyPartPieMenus[8]; LLMenuItemCallGL* gAFKMenu = NULL; LLMenuItemCallGL* gBusyMenu = NULL; @@ -602,6 +602,42 @@ void set_underclothes_menu_options() static std::vector > sMenus; +void build_pie_menus() +{ + if (gPieSelf) delete gPieSelf; + gPieSelf = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_self.xml", gMenuHolder); + + // TomY TODO: what shall we do about these? + gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); + gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); + + if (gPieAvatar) delete gPieAvatar; + gPieAvatar = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_avatar.xml", gMenuHolder); + + if (gPieObject) delete gPieObject; + gPieObject = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_object.xml", gMenuHolder); + + gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); + gAttachPieMenu = gMenuHolder->getChild("Object Attach"); + gPieRate = gMenuHolder->getChild("Rate Menu"); + + if (gPieAttachment) delete gPieAttachment; + gPieAttachment = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_attachment.xml", gMenuHolder); + + if (gPieLand) delete gPieLand; + gPieLand = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_land.xml", gMenuHolder); +} + +void rebuild_context_menus() +{ + llassert_always(gMenuHolder); + if (!gMenuHolder) return; // This should never happen, if it does, don't do anything, menus haven't been built yet or were destroyed. + gMenuHolder->hideMenus(); + build_pie_menus(); + if (!gAgentAvatarp) return; // The agent's avatar isn't here yet, don't bother with the dynamic attach/detach submenus. + gAgentAvatarp->buildContextMenus(); +} + void init_menus() { S32 top = gViewerWindow->getRootView()->getRect().getHeight(); @@ -633,36 +669,15 @@ void init_menus() /// /// Pie menus /// - gPieSelf = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_self.xml", gMenuHolder); + build_pie_menus(); + gSavedSettings.getControl("LiruUseContextMenus")->getSignal()->connect(boost::bind(rebuild_context_menus)); - // TomY TODO: what shall we do about these? - gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); - gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); - - gPieAvatar = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_avatar.xml", gMenuHolder); - - gPieObject = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_object.xml", gMenuHolder); - - gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); - gAttachPieMenu = gMenuHolder->getChild("Object Attach"); - gPieRate = gMenuHolder->getChild("Rate Menu"); - - gPieAttachment = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_attachment.xml", gMenuHolder); - - gPieLand = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_land.xml", gMenuHolder); /// /// set up the colors /// LLColor4 color; - LLColor4 pie_color = gColors.getColor("PieMenuBgColor"); - gPieSelf->setBackgroundColor( pie_color ); - gPieAvatar->setBackgroundColor( pie_color ); - gPieObject->setBackgroundColor( pie_color ); - gPieAttachment->setBackgroundColor( pie_color ); - gPieLand->setBackgroundColor( pie_color ); - color = gColors.getColor( "MenuPopupBgColor" ); gPopupMenuView->setBackgroundColor( color ); @@ -5549,7 +5564,7 @@ class LLEditDelete : public view_listener_t // When deleting an object we may not actually be done // Keep selection so we know what to delete when confirmation is needed about the delete - gPieObject->hide(TRUE); + gPieObject->hide(); return true; } }; @@ -5669,7 +5684,7 @@ void handle_object_delete() // When deleting an object we may not actually be done // Keep selection so we know what to delete when confirmation is needed about the delete - gPieObject->hide(TRUE); + gPieObject->hide(); return; } diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 6d3c2947f..b45cf7633 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -167,24 +167,24 @@ extern LLViewerMenuHolderGL* gMenuHolder; extern LLMenuBarGL* gLoginMenuBarView; // Pie menus -extern LLPieMenu *gPieSelf; -extern LLPieMenu *gPieAvatar; -extern LLPieMenu *gPieObject; -extern LLPieMenu *gPieAttachment; -extern LLPieMenu *gPieLand; -extern LLPieMenu *gPieRate; +extern LLContextMenu *gPieSelf; +extern LLContextMenu *gPieAvatar; +extern LLContextMenu *gPieObject; +extern LLContextMenu *gPieAttachment; +extern LLContextMenu *gPieLand; +extern LLContextMenu *gPieRate; // Needed to build menus when attachment site list available extern LLMenuGL* gAttachSubMenu; extern LLMenuGL* gDetachSubMenu; extern LLMenuGL* gTakeOffClothes; extern LLMenuGL* gMeshesAndMorphsMenu; -extern LLPieMenu* gAttachScreenPieMenu; -extern LLPieMenu* gDetachScreenPieMenu; -extern LLPieMenu* gAttachPieMenu; -extern LLPieMenu* gDetachPieMenu; -extern LLPieMenu* gAttachBodyPartPieMenus[8]; -extern LLPieMenu* gDetachBodyPartPieMenus[8]; +extern LLContextMenu* gAttachScreenPieMenu; +extern LLContextMenu* gDetachScreenPieMenu; +extern LLContextMenu* gAttachPieMenu; +extern LLContextMenu* gDetachPieMenu; +extern LLContextMenu* gAttachBodyPartPieMenus[8]; +extern LLContextMenu* gDetachBodyPartPieMenus[8]; extern LLMenuItemCallGL* gAFKMenu; extern LLMenuItemCallGL* gBusyMenu; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 6fdd2c277..ab2833220 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -325,29 +325,55 @@ BOOL LLVOAvatarSelf::buildMenus() //------------------------------------------------------------------------- if(gNoRender) return TRUE; - gAttachBodyPartPieMenus[0] = NULL; - gAttachBodyPartPieMenus[1] = new LLPieMenu(LLTrans::getString("BodyPartsRightArm") + " >"); - gAttachBodyPartPieMenus[2] = new LLPieMenu(LLTrans::getString("BodyPartsHead") + " >"); - gAttachBodyPartPieMenus[3] = new LLPieMenu(LLTrans::getString("BodyPartsLeftArm") + " >"); - gAttachBodyPartPieMenus[4] = NULL; - gAttachBodyPartPieMenus[5] = new LLPieMenu(LLTrans::getString("BodyPartsLeftLeg") + " >"); - gAttachBodyPartPieMenus[6] = new LLPieMenu(LLTrans::getString("BodyPartsTorso") + " >"); - gAttachBodyPartPieMenus[7] = new LLPieMenu(LLTrans::getString("BodyPartsRightLeg") + " >"); + buildContextMenus(); - gDetachBodyPartPieMenus[0] = NULL; - gDetachBodyPartPieMenus[1] = new LLPieMenu(LLTrans::getString("BodyPartsRightArm") + " >"); - gDetachBodyPartPieMenus[2] = new LLPieMenu(LLTrans::getString("BodyPartsHead") + " >"); - gDetachBodyPartPieMenus[3] = new LLPieMenu(LLTrans::getString("BodyPartsLeftArm") + " >"); - gDetachBodyPartPieMenus[4] = NULL; - gDetachBodyPartPieMenus[5] = new LLPieMenu(LLTrans::getString("BodyPartsLeftLeg") + " >"); - gDetachBodyPartPieMenus[6] = new LLPieMenu(LLTrans::getString("BodyPartsTorso") + " >"); - gDetachBodyPartPieMenus[7] = new LLPieMenu(LLTrans::getString("BodyPartsRightLeg") + " >"); + init_meshes_and_morphs_menu(); + + return TRUE; +} + +// Convenience function to create context or pie menu with label +static LLContextMenu* make_part_menu(const std::string& label, bool context) +{ + return context ? new LLContextMenu(label) : new LLPieMenu(label + " >"); +} + +void LLVOAvatarSelf::buildContextMenus() +{ + gAttachBodyPartPieMenus[0] = gDetachBodyPartPieMenus[0] = NULL; + + bool context(gSavedSettings.getBOOL("LiruUseContextMenus")); + std::string label = LLTrans::getString("BodyPartsRightArm"); + gAttachBodyPartPieMenus[1] = make_part_menu(label, context); + gDetachBodyPartPieMenus[1] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsHead"); + gAttachBodyPartPieMenus[2] = make_part_menu(label, context); + gDetachBodyPartPieMenus[2] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsLeftArm"); + gAttachBodyPartPieMenus[3] = make_part_menu(label, context); + gDetachBodyPartPieMenus[3] = make_part_menu(label, context); + + gAttachBodyPartPieMenus[4] = gDetachBodyPartPieMenus[4] = NULL; + + label = LLTrans::getString("BodyPartsLeftLeg"); + gAttachBodyPartPieMenus[5] = make_part_menu(label, context); + gDetachBodyPartPieMenus[5] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsTorso"); + gAttachBodyPartPieMenus[6] = make_part_menu(label, context); + gDetachBodyPartPieMenus[6] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsRightLeg"); + gAttachBodyPartPieMenus[7] = make_part_menu(label, context); + gDetachBodyPartPieMenus[7] = make_part_menu(label, context); for (S32 i = 0; i < 8; i++) { if (gAttachBodyPartPieMenus[i]) { - gAttachPieMenu->appendPieMenu( gAttachBodyPartPieMenus[i] ); + gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] ); } else { @@ -379,7 +405,7 @@ BOOL LLVOAvatarSelf::buildMenus() } } - if (!attachment_found) + if (!context && !attachment_found) { gAttachPieMenu->addSeparator(); } @@ -387,7 +413,7 @@ BOOL LLVOAvatarSelf::buildMenus() if (gDetachBodyPartPieMenus[i]) { - gDetachPieMenu->appendPieMenu( gDetachBodyPartPieMenus[i] ); + gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] ); } else { @@ -407,7 +433,7 @@ BOOL LLVOAvatarSelf::buildMenus() } } - if (!attachment_found) + if (!context && !attachment_found) { gDetachPieMenu->addSeparator(); } @@ -466,7 +492,7 @@ BOOL LLVOAvatarSelf::buildMenus() &handle_detach_from_avatar, object_attached, &detach_label, attachment)); } - if (pass == 0) + if (!context && pass == 0) { // put separator between non-hud and hud attachments gAttachSubMenu->addSeparator(); @@ -503,14 +529,17 @@ BOOL LLVOAvatarSelf::buildMenus() for (std::multimap::iterator attach_it = attachment_pie_menu_map.begin(); attach_it != attachment_pie_menu_map.end(); ++attach_it) { - S32 requested_pie_slice = attach_it->first; - S32 attach_index = attach_it->second; - while (cur_pie_slice < requested_pie_slice) + if (!context) // Singu Note: Separators are only needed to keep slices of pies from moving { - gAttachBodyPartPieMenus[group]->addSeparator(); - gDetachBodyPartPieMenus[group]->addSeparator(); - cur_pie_slice++; + S32 requested_pie_slice = attach_it->first; + while (cur_pie_slice < requested_pie_slice) + { + gAttachBodyPartPieMenus[group]->addSeparator(); + gDetachBodyPartPieMenus[group]->addSeparator(); + cur_pie_slice++; + } } + S32 attach_index = attach_it->second; LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL); if (attachment) @@ -527,14 +556,10 @@ BOOL LLVOAvatarSelf::buildMenus() gDetachBodyPartPieMenus[group]->addChild(new LLMenuItemCallGL(attachment->getName(), &handle_detach_from_avatar, object_attached, attachment)); - cur_pie_slice++; + if (!context) cur_pie_slice++; } } } - - init_meshes_and_morphs_menu(); - - return TRUE; } void LLVOAvatarSelf::cleanup() diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 99e45bcff..2c9d69b8b 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -63,6 +63,7 @@ public: virtual ~LLVOAvatarSelf(); virtual void markDead(); virtual void initInstance(); // Called after construction to initialize the class. + void buildContextMenus(); void cleanup(); protected: /*virtual*/ BOOL loadAvatar(); diff --git a/indra/newview/skins/default/xui/de/menu_pie_attachment.xml b/indra/newview/skins/default/xui/de/menu_pie_attachment.xml index da6e10ad0..dd6092c32 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_attachment.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_attachment.xml @@ -5,8 +5,8 @@ - - + + diff --git a/indra/newview/skins/default/xui/de/menu_pie_avatar.xml b/indra/newview/skins/default/xui/de/menu_pie_avatar.xml index 53988dd8d..6288151a6 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_avatar.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_avatar.xml @@ -6,11 +6,11 @@ - + - + diff --git a/indra/newview/skins/default/xui/de/menu_pie_object.xml b/indra/newview/skins/default/xui/de/menu_pie_object.xml index 254eaeb92..bf03eeb99 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_object.xml @@ -6,16 +6,16 @@ - + - - + + - + - + @@ -29,11 +29,11 @@ - + - + diff --git a/indra/newview/skins/default/xui/de/menu_pie_self.xml b/indra/newview/skins/default/xui/de/menu_pie_self.xml index 7184ae7cd..5f0ad5214 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_self.xml @@ -2,15 +2,15 @@ - - + + - + @@ -21,13 +21,13 @@ - + - + - + diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml b/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml index 03b0b0fdf..fa7c19687 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml @@ -19,8 +19,8 @@ - - + + diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml b/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml index c57ab3059..05621b010 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml @@ -21,7 +21,7 @@ - + @@ -32,7 +32,7 @@ - + - + @@ -37,15 +37,15 @@ - - + + - + - + @@ -92,7 +92,7 @@ - + @@ -102,7 +102,7 @@ - + diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_self.xml b/indra/newview/skins/default/xui/en-us/menu_pie_self.xml index 9b35ae1f3..24444019b 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_self.xml @@ -6,8 +6,8 @@ - - + + @@ -38,7 +38,7 @@ - + @@ -76,16 +76,16 @@ - + - + - + diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml index 0a4e7f7ca..e4d6537c0 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml @@ -34,9 +34,10 @@ - seconds + diff --git a/indra/newview/skins/default/xui/es/menu_pie_attachment.xml b/indra/newview/skins/default/xui/es/menu_pie_attachment.xml index da8c71d3c..da90d803f 100644 --- a/indra/newview/skins/default/xui/es/menu_pie_attachment.xml +++ b/indra/newview/skins/default/xui/es/menu_pie_attachment.xml @@ -11,8 +11,8 @@ - - + + diff --git a/indra/newview/skins/default/xui/es/menu_pie_avatar.xml b/indra/newview/skins/default/xui/es/menu_pie_avatar.xml index cc58b2a6f..3c13382d0 100644 --- a/indra/newview/skins/default/xui/es/menu_pie_avatar.xml +++ b/indra/newview/skins/default/xui/es/menu_pie_avatar.xml @@ -6,11 +6,11 @@ - + - + diff --git a/indra/newview/skins/default/xui/es/menu_pie_object.xml b/indra/newview/skins/default/xui/es/menu_pie_object.xml index 0cfa33588..3f970ffe0 100644 --- a/indra/newview/skins/default/xui/es/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/es/menu_pie_object.xml @@ -14,15 +14,15 @@ - + - - + + - - + + @@ -36,11 +36,11 @@ - + - + diff --git a/indra/newview/skins/default/xui/es/menu_pie_self.xml b/indra/newview/skins/default/xui/es/menu_pie_self.xml index 6b33db0c8..75b367c22 100644 --- a/indra/newview/skins/default/xui/es/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/es/menu_pie_self.xml @@ -2,15 +2,15 @@ - - + + - + @@ -21,13 +21,13 @@ - + - + - + diff --git a/indra/newview/skins/default/xui/fr/menu_pie_avatar.xml b/indra/newview/skins/default/xui/fr/menu_pie_avatar.xml index 472bf62f3..b7798a18f 100644 --- a/indra/newview/skins/default/xui/fr/menu_pie_avatar.xml +++ b/indra/newview/skins/default/xui/fr/menu_pie_avatar.xml @@ -6,7 +6,7 @@ - + diff --git a/indra/newview/skins/default/xui/fr/menu_pie_object.xml b/indra/newview/skins/default/xui/fr/menu_pie_object.xml index f89754353..adebd70fd 100644 --- a/indra/newview/skins/default/xui/fr/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/fr/menu_pie_object.xml @@ -24,7 +24,7 @@ - + @@ -37,15 +37,15 @@ - - + + - + - + diff --git a/indra/newview/skins/default/xui/fr/menu_pie_self.xml b/indra/newview/skins/default/xui/fr/menu_pie_self.xml index c8f94a1a2..defb0f161 100644 --- a/indra/newview/skins/default/xui/fr/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/fr/menu_pie_self.xml @@ -6,30 +6,30 @@ - + - - + + - + - + - + diff --git a/indra/newview/skins/default/xui/pt/menu_pie_avatar.xml b/indra/newview/skins/default/xui/pt/menu_pie_avatar.xml index 2773fde7f..158c492a9 100644 --- a/indra/newview/skins/default/xui/pt/menu_pie_avatar.xml +++ b/indra/newview/skins/default/xui/pt/menu_pie_avatar.xml @@ -6,7 +6,7 @@ - + diff --git a/indra/newview/skins/default/xui/pt/menu_pie_object.xml b/indra/newview/skins/default/xui/pt/menu_pie_object.xml index 6be6063b6..a1c6c10c0 100644 --- a/indra/newview/skins/default/xui/pt/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/pt/menu_pie_object.xml @@ -6,14 +6,14 @@ - + - - + + - + diff --git a/indra/newview/skins/default/xui/pt/menu_pie_self.xml b/indra/newview/skins/default/xui/pt/menu_pie_self.xml index 75bf9367e..25b0b83ec 100644 --- a/indra/newview/skins/default/xui/pt/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_pie_self.xml @@ -6,23 +6,23 @@ - - + + - + - - + +