summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2013-10-29 16:10:18 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-10-29 16:11:08 +0000
commit0881ae68b0d7f977003e0798e52548caa2556f44 (patch)
tree0b6772d22c2ea8251520e5d0a24a44d239633428 /vcl
parentfdf00229816f5d0f59f90b0266115d293060e2cc (diff)
Resolves: rhbz#1021915 force menubar menus to be up/down only
If a menu won't fit in the desired location the default mode is to place it somewhere it will fit. e.g. above, left, right. For some cases, e.g. menubars, it's desirable to limit the options to above/below and force the menu to scroll if it won't fit Change-Id: I1998a842d25752389ec9032e54673408d1ed6cb5
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/window/menu.cxx34
1 files changed, 28 insertions, 6 deletions
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index f567ba3a1da9..6083554f09dd 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -3562,7 +3562,6 @@ sal_uInt16 PopupMenu::Execute( Window* pExecWindow, const Rectangle& rRect, sal_
{
ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 );
-
sal_uLong nPopupModeFlags = 0;
if ( nFlags & POPUPMENU_EXECUTE_DOWN )
nPopupModeFlags = FLOATWIN_POPUPMODE_DOWN;
@@ -3578,6 +3577,9 @@ sal_uInt16 PopupMenu::Execute( Window* pExecWindow, const Rectangle& rRect, sal_
if (nFlags & POPUPMENU_NOMOUSEUPCLOSE ) // allow popup menus to stay open on mouse button up
nPopupModeFlags |= FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE; // useful if the menu was opened on mousebutton down (eg toolbox configuration)
+ if (nFlags & POPUPMENU_NOHORZ_PLACEMENT)
+ nPopupModeFlags |= FLOATWIN_POPUPMODE_NOHORZPLACEMENT;
+
return ImplExecute( pExecWindow, rRect, nPopupModeFlags, 0, sal_False );
}
@@ -3681,17 +3683,37 @@ sal_uInt16 PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, sal_uLong
Size aSz = ImplCalcSize( pWin );
- long nMaxHeight = pWin->GetDesktopRectPixel().GetHeight();
+ Rectangle aDesktopRect(pWin->GetDesktopRectPixel());
if( Application::GetScreenCount() > 1 && Application::IsUnifiedDisplay() )
{
Window* pDeskW = pWindow->GetWindow( WINDOW_REALPARENT );
if( ! pDeskW )
pDeskW = pWindow;
Point aDesktopTL( pDeskW->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) );
- nMaxHeight = Application::GetScreenPosSizePixel(
- Application::GetBestScreen( Rectangle( aDesktopTL, aRect.GetSize() ) )
- ).GetHeight();
+ aDesktopRect = Application::GetScreenPosSizePixel(
+ Application::GetBestScreen( Rectangle( aDesktopTL, aRect.GetSize() ) ));
}
+
+ long nMaxHeight = aDesktopRect.GetHeight();
+
+ //rhbz#1021915. If a menu won't fit in the desired location the default
+ //mode is to place it somewhere it will fit. e.g. above, left, right. For
+ //some cases, e.g. menubars, it's desirable to limit the options to
+ //above/below and force the menu to scroll if it won't fit
+ if (nPopupModeFlags & FLOATWIN_POPUPMODE_NOHORZPLACEMENT)
+ {
+ Window* pRef = pWin;
+ if ( pRef->GetParent() )
+ pRef = pRef->GetParent();
+
+ Rectangle devRect( pRef->OutputToAbsoluteScreenPixel( aRect.TopLeft() ),
+ pRef->OutputToAbsoluteScreenPixel( aRect.BottomRight() ) );
+
+ long nHeightAbove = devRect.Top() - aDesktopRect.Top();
+ long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom();
+ nMaxHeight = std::min(nMaxHeight, std::max(nHeightAbove, nHeightBelow));
+ }
+
if ( pStartedFrom && pStartedFrom->bIsMenuBar )
nMaxHeight -= pW->GetSizePixel().Height();
sal_Int32 nLeft, nTop, nRight, nBottom;
@@ -5326,7 +5348,7 @@ void MenuBarWindow::ImplCreatePopup( sal_Bool bPreSelectFirst )
// #99071# do not grab the focus, otherwise it will be restored to the menubar
// when the frame is reactivated later
//GrabFocus();
- pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN, pMenu, bPreSelectFirst );
+ pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_NOHORZPLACEMENT, pMenu, bPreSelectFirst );
if ( pActivePopup )
{
// does not have a window, if aborted before or if there are no entries