summaryrefslogtreecommitdiff
path: root/indra/llui/llmenugl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llmenugl.cpp')
-rw-r--r--indra/llui/llmenugl.cpp188
1 files changed, 123 insertions, 65 deletions
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index e5c32846a0..4edae46f32 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -184,6 +184,13 @@ LLMenuItemGL::LLMenuItemGL(const LLMenuItemGL::Params& p)
<< LL_ENDL;
}
+//virtual
+void LLMenuItemGL::setValue(const LLSD& value)
+{
+ setLabel(value.asString());
+}
+
+//virtual
BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
{
if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
@@ -201,6 +208,26 @@ BOOL LLMenuItemGL::handleHover(S32 x, S32 y, MASK mask)
return TRUE;
}
+//virtual
+BOOL LLMenuItemGL::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ return LLUICtrl::handleRightMouseDown(x,y,mask);
+}
+
+//virtual
+BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
+{
+ // If this event came from a right-click context menu spawn,
+ // process as a left-click to allow menu items to be hit
+ if (LLMenuHolderGL::sContextMenuSpawnPos.mX != S32_MAX
+ || LLMenuHolderGL::sContextMenuSpawnPos.mY != S32_MAX)
+ {
+ BOOL handled = handleMouseUp(x, y, mask);
+ return handled;
+ }
+ return LLUICtrl::handleRightMouseUp(x,y,mask);
+}
+
// This function checks to see if the accelerator key is already in use;
// if not, it will be added to the list
BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
@@ -306,6 +333,17 @@ U32 LLMenuItemGL::getNominalHeight( void ) const
return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING;
}
+//virtual
+void LLMenuItemGL::setBriefItem(BOOL brief)
+{
+ mBriefItem = brief;
+}
+
+//virtual
+BOOL LLMenuItemGL::isBriefItem() const
+{
+ return mBriefItem;
+}
// Get the parent menu for this item
LLMenuGL* LLMenuItemGL::getMenu() const
@@ -800,15 +838,8 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask )
return FALSE;
}
-BOOL LLMenuItemCallGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
-{
- if (pointInView(x, y))
- {
- mRightClickSignal(this,x,y, mask);
- }
-
- return TRUE;
-}
+// handleRightMouseUp moved into base class LLMenuItemGL so clicks are
+// handled for all menu item types
///============================================================================
/// Class LLMenuItemCheckGL
@@ -898,24 +929,38 @@ LLMenuItemBranchGL::~LLMenuItemBranchGL()
}
// virtual
-LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
+LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse) const
{
LLMenuGL* branch = getBranch();
- if (!branch)
- return LLView::getChildView(name, recurse, create_if_missing);
-
- // richard: this is redundant with parent, remove
- if (branch->getName() == name)
+ if (branch)
{
- return branch;
+ if (branch->getName() == name)
+ {
+ return branch;
+ }
+
+ // Always recurse on branches
+ return branch->getChildView(name, recurse);
}
- // Always recurse on branches
- LLView* child = branch->getChildView(name, recurse, FALSE);
- if (!child)
+
+ return LLView::getChildView(name, recurse);
+}
+
+LLView* LLMenuItemBranchGL::findChildView(const std::string& name, BOOL recurse) const
+{
+ LLMenuGL* branch = getBranch();
+ if (branch)
{
- child = LLView::getChildView(name, recurse, create_if_missing);
+ if (branch->getName() == name)
+ {
+ return branch;
+ }
+
+ // Always recurse on branches
+ return branch->findChildView(name, recurse);
}
- return child;
+
+ return LLView::findChildView(name, recurse);
}
// virtual
@@ -1123,6 +1168,18 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
return LLMenuItemGL::handleKeyHere(key, mask);
}
+//virtual
+BOOL LLMenuItemBranchGL::isActive() const
+{
+ return isOpen() && getBranch() && getBranch()->getHighlightedItem();
+}
+
+//virtual
+BOOL LLMenuItemBranchGL::isOpen() const
+{
+ return getBranch() && getBranch()->isOpen();
+}
+
void LLMenuItemBranchGL::openMenu()
{
LLMenuGL* branch = getBranch();
@@ -1296,20 +1353,26 @@ void LLMenuItemBranchDownGL::openMenu( void )
// set the hover status (called by it's menu)
void LLMenuItemBranchDownGL::setHighlight( BOOL highlight )
{
- if (highlight == getHighlight()) return;
+ if (highlight == getHighlight())
+ return;
//NOTE: Purposely calling all the way to the base to bypass auto-open.
LLMenuItemGL::setHighlight(highlight);
+
+ LLMenuGL* branch = getBranch();
+ if (!branch)
+ return;
+
if( !highlight)
{
- if (getBranch()->getTornOff())
+ if (branch->getTornOff())
{
- ((LLFloater*)getBranch()->getParent())->setFocus(FALSE);
- getBranch()->clearHoverItem();
+ ((LLFloater*)branch->getParent())->setFocus(FALSE);
+ branch->clearHoverItem();
}
else
{
- getBranch()->setVisible( FALSE );
+ branch->setVisible( FALSE );
}
}
}
@@ -1578,6 +1641,7 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
mDropShadowed( p.drop_shadow ),
mHorizontalLayout( p.horizontal_layout ),
mScrollable(mHorizontalLayout ? FALSE : p.scrollable), // Scrolling is supported only for vertical layout
+ mMaxScrollableItems(p.max_scrollable_items),
mKeepFixedSize( p.keep_fixed_size ),
mLabel (p.label),
mLastMouseX(0),
@@ -1851,6 +1915,7 @@ void LLMenuGL::arrange( void )
item_list_t::iterator first_hidden_item_iter = mItems.end();
S32 height_before_first_visible_item = -1;
S32 visible_items_height = 0;
+ U32 scrollable_items_cnt = 0;
if (mHorizontalLayout)
{
@@ -1945,12 +2010,16 @@ void LLMenuGL::arrange( void )
{
height_before_first_visible_item = height - (*item_iter)->getNominalHeight();
first_visible_item_iter = item_iter;
+ scrollable_items_cnt = 0;
}
- if (-1 != height_before_first_visible_item && 0 == visible_items_height && height - height_before_first_visible_item > max_height - spillover_item_height * 2)
+ if (-1 != height_before_first_visible_item && 0 == visible_items_height &&
+ (++scrollable_items_cnt > mMaxScrollableItems ||
+ height - height_before_first_visible_item > max_height - spillover_item_height * 2 ))
{
first_hidden_item_iter = item_iter;
visible_items_height = height - height_before_first_visible_item - (*item_iter)->getNominalHeight();
+ scrollable_items_cnt--;
}
}
}
@@ -1960,16 +2029,16 @@ void LLMenuGL::arrange( void )
{
S32 max_items_height = max_height - spillover_item_height * 2;
+ if (visible_items_height == 0)
+ visible_items_height = height - height_before_first_visible_item;
+
// Fix mFirstVisibleItem value, if it doesn't allow to display all items, that can fit
- if (visible_items_height < max_items_height)
+ if (visible_items_height < max_items_height && scrollable_items_cnt < mMaxScrollableItems)
{
- if (visible_items_height == 0)
- {
- visible_items_height = height - height_before_first_visible_item;
- }
-
item_list_t::iterator tmp_iter(first_visible_item_iter);
- while (visible_items_height < max_items_height && first_visible_item_iter != mItems.begin())
+ while (visible_items_height < max_items_height &&
+ scrollable_items_cnt < mMaxScrollableItems &&
+ first_visible_item_iter != mItems.begin())
{
if ((*first_visible_item_iter)->getVisible())
{
@@ -1983,6 +2052,7 @@ void LLMenuGL::arrange( void )
{
visible_items_height += (*first_visible_item_iter)->getNominalHeight();
height_before_first_visible_item -= (*first_visible_item_iter)->getNominalHeight();
+ scrollable_items_cnt++;
}
}
@@ -1991,6 +2061,7 @@ void LLMenuGL::arrange( void )
{
visible_items_height -= (*first_visible_item_iter)->getNominalHeight();
height_before_first_visible_item += (*first_visible_item_iter)->getNominalHeight();
+ scrollable_items_cnt--;
first_visible_item_iter = tmp_iter;
}
if (!(*first_visible_item_iter)->getVisible())
@@ -2803,9 +2874,9 @@ void LLMenuGL::setVisible(BOOL visible)
}
}
-LLMenuGL* LLMenuGL::getChildMenuByName(const std::string& name, BOOL recurse) const
+LLMenuGL* LLMenuGL::findChildMenuByName(const std::string& name, BOOL recurse) const
{
- LLView* view = getChildView(name, recurse, FALSE);
+ LLView* view = findChildView(name, recurse);
if (view)
{
LLMenuItemBranchGL* branch = dynamic_cast<LLMenuItemBranchGL*>(view);
@@ -2844,9 +2915,19 @@ void hide_top_view( LLView* view )
}
+// x and y are the desired location for the popup, NOT necessarily the
+// mouse location
// static
void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
{
+ // 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 LLContextMenu::show()
+ S32 mouse_x, mouse_y;
+ LLUI::getCursorPositionLocal(menu->getParent(), &mouse_x, &mouse_y);
+ LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
+
const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
const S32 HPAD = 2;
@@ -2857,9 +2938,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
spawning_view->localPointToOtherView(left, top, &left, &top, menu->getParent());
rect.setLeftTopAndSize( left, top,
rect.getWidth(), rect.getHeight() );
-
-
- //rect.setLeftTopAndSize(x + HPAD, y, rect.getWidth(), rect.getHeight());
menu->setRect( rect );
// Resetting scrolling position
@@ -2871,18 +2949,16 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
menu->arrangeAndClear(); // Fix menu rect if needed.
rect = menu->getRect();
+ // Adjust context menu to fit onscreen
S32 bottom;
left = rect.mLeft;
bottom = rect.mBottom;
- //menu->getParent()->localPointToScreen( rect.mLeft, rect.mBottom,
- // &left, &bottom );
S32 delta_x = 0;
S32 delta_y = 0;
if( bottom < menu_region_rect.mBottom )
{
// At this point, we need to move the context menu to the
// other side of the mouse.
- //delta_y = menu_region_rect.mBottom - bottom;
delta_y = (rect.getHeight() + 2 * HPAD);
}
@@ -2890,7 +2966,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
{
// At this point, we need to move the context menu to the
// other side of the mouse.
- //delta_x = (window_width - rect.getWidth()) - x;
delta_x = -(rect.getWidth() + 2 * HPAD);
}
menu->translate( delta_x, delta_y );
@@ -3003,21 +3078,6 @@ BOOL LLMenuBarGL::handleMouseDown(S32 x, S32 y, MASK mask)
return LLMenuGL::handleMouseDown(x, y, mask);
}
-/*
-BOOL LLMenuBarGL::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- // clicks on menu bar closes existing menus from other contexts but leave
- // own menu open so that we get toggle behavior
- if (!getHighlightedItem() || !getHighlightedItem()->isActive())
- {
- LLMenuGL::sMenuContainer->hideMenus();
- }
-
- return LLMenuGL::handleMouseDown(x, y, mask);
-}
-*/
-
-
void LLMenuBarGL::draw()
{
LLMenuItemGL* itemp = getHighlightedItem();
@@ -3400,17 +3460,14 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
// highlight first item (tear off item will be disabled)
mMenu->highlightNextItem(NULL);
-}
-LLTearOffMenu::~LLTearOffMenu()
-{
+ // Can't do this in postBuild() because that is only called for floaters
+ // constructed from XML.
+ mCloseSignal.connect(boost::bind(&LLTearOffMenu::closeTearOff, this));
}
-// virtual
-BOOL LLTearOffMenu::postBuild()
+LLTearOffMenu::~LLTearOffMenu()
{
- mCloseSignal.connect(boost::bind(&LLTearOffMenu::closeTearOff, this));
- return TRUE;
}
void LLTearOffMenu::draw()
@@ -3651,6 +3708,7 @@ void LLContextMenu::show(S32 x, S32 y)
// 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();