|
|
|
|
@@ -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<bool> 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<LLContextMenu*>(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<bool> 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<LLMenuItemSeparatorGL*>(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<LLContextMenu*>(view))
|
|
|
|
|
return appendContextSubMenu(context);
|
|
|
|
|
if (LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view))
|
|
|
|
|
return append(item);
|
|
|
|
|
if (LLMenuGL* menu = dynamic_cast<LLMenuGL*>(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<LLMenuItemSeparatorGL*>(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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|