diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2017-12-18 19:30:06 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2017-12-19 05:26:16 +0100 |
commit | 9f3b61e51f7f9de11436b0e4eaec164f2656fbdd (patch) | |
tree | ec02561c9b95895c0b5dbc53c49a2bbb64c4566e /vcl | |
parent | e11234d8d8d8ff2744b77a128f845dbe8e6faa1e (diff) |
show rest of the menu bar in a pop-up if the are is too small
In case when the window is to small to show the whole menu then
the use couldn't access the rest of the items in the menu. This
change adds a button in the end (using the ">>" marker as in
toolbar) which on click adds a pop-up that shows the rest of the
menu items.
Change-Id: I9218dba504464bdd44d61ebb383f7674f3df760f
Reviewed-on: https://gerrit.libreoffice.org/46711
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/window/menu.cxx | 88 | ||||
-rw-r--r-- | vcl/source/window/menubarwindow.cxx | 41 | ||||
-rw-r--r-- | vcl/source/window/menubarwindow.hxx | 1 | ||||
-rw-r--r-- | vcl/source/window/menuitemlist.hxx | 3 |
4 files changed, 129 insertions, 4 deletions
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index b6b2faa5206b..983a25a11ad6 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -121,8 +121,50 @@ void ImplClosePopupToolBox( const VclPtr<vcl::Window>& pWin ) } } +// TODO: Move to common code with the same function in toolbox +// Draw the ">>" - more indictor at the coordinates +void lclDrawMoreIndicator(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) +{ + rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR); + rRenderContext.SetLineColor(); + + if (rRenderContext.GetSettings().GetStyleSettings().GetFaceColor().IsDark()) + rRenderContext.SetFillColor(Color(COL_WHITE)); + else + rRenderContext.SetFillColor(Color(COL_BLACK)); + float fScaleFactor = rRenderContext.GetDPIScaleFactor(); + + int linewidth = 1 * fScaleFactor; + int space = 4 * fScaleFactor; + + long width = 8 * fScaleFactor; + long height = 5 * fScaleFactor; + + //Keep odd b/c drawing code works better + if ( height % 2 == 0 ) + height--; + + long heightOrig = height; + + long x = rRect.Left() + (rRect.getWidth() - width)/2 + 1; + long y = rRect.Top() + (rRect.getHeight() - height)/2 + 1; + while( height >= 1) + { + rRenderContext.DrawRect( tools::Rectangle( x, y, x + linewidth, y ) ); + x += space; + rRenderContext.DrawRect( tools::Rectangle( x, y, x + linewidth, y ) ); + x -= space; + y++; + if( height <= heightOrig / 2 + 1) x--; + else x++; + height--; + } + rRenderContext.Pop(); } +} // end anonymouse namespace + + Menu::Menu() : mpFirstDel(nullptr), pItemList(new MenuItemList), @@ -1138,6 +1180,22 @@ Menu& Menu::operator=( const Menu& rMenu ) return *this; } +// Returns true if the item is completely hidden on the GUI and shouldn't +// be possible to interact with +bool Menu::ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const +{ + MenuItemData* pData = pItemList->GetDataFromPos(nPos); + if (pData) + { + MenuItemData* pPreviousData = pItemList->GetDataFromPos( nPos - 1 ); + if (pPreviousData && pPreviousData->bHiddenOnGUI) + { + return true; + } + } + return false; +} + bool Menu::ImplIsVisible( sal_uInt16 nPos ) const { bool bVisible = true; @@ -1696,6 +1754,8 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize, if (!pThisItemOnly && !IsMenuBar() && nTitleHeight > 0) ImplPaintMenuTitle(rRenderContext, tools::Rectangle(aTopLeft, aOutSz)); + bool bHiddenItems = false; // are any items on the GUI hidden + for (size_t n = 0; n < nCount; n++) { MenuItemData* pData = pItemList->GetDataFromPos( n ); @@ -1921,7 +1981,25 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize, { nMaxItemTextWidth -= nFontHeight - nExtra; } - OUString aItemText(getShortenedString(pData->aText, rRenderContext, nMaxItemTextWidth)); + + OUString aItemText(pData->aText); + pData->bHiddenOnGUI = false; + + if (IsMenuBar()) // In case of menubar if we are out of bounds we shouldn't paint the item + { + if (nMaxItemTextWidth < rRenderContext.GetTextWidth(aItemText)) + { + aItemText = ""; + pData->bHiddenOnGUI = true; + bHiddenItems = true; + } + } + else + { + aItemText = getShortenedString(aItemText, rRenderContext, nMaxItemTextWidth); + pData->bHiddenOnGUI = false; + } + rRenderContext.DrawCtrlText(aTmpPos, aItemText, 0, aItemText.getLength(), nStyle, pVector, pDisplayText); if (bSetTmpBackground) rRenderContext.SetBackground(); @@ -2014,6 +2092,14 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize, else aTopLeft.X() += pData->aSz.Width(); } + + // draw "more" (">>") indicator if some items have been hidden as they go out of visible area + if (bHiddenItems) + { + sal_Int32 nSize = nFontHeight; + tools::Rectangle aRectangle(Point(aOutSz.Width() - nSize, (aOutSz.Height() / 2) - (nSize / 2)), Size(nSize, nSize)); + lclDrawMoreIndicator(rRenderContext, aRectangle); + } } Menu* Menu::ImplGetStartMenu() diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx index 0b4e6b7df5bc..6a8877263b43 100644 --- a/vcl/source/window/menubarwindow.cxx +++ b/vcl/source/window/menubarwindow.cxx @@ -160,6 +160,7 @@ void MenuBarWindow::dispose() aCloseBtn->RemoveEventListener(LINK(this, MenuBarWindow, ToolboxEventHdl)); RemoveEventListener(LINK(this, MenuBarWindow, ShowHideListener)); + mpParentPopup.disposeAndClear(); aHideBtn.disposeAndClear(); aFloatBtn.disposeAndClear(); aCloseBtn.disposeAndClear(); @@ -301,6 +302,29 @@ void MenuBarWindow::ImplCreatePopup( bool bPreSelectFirst ) Point aItemBottomRight( aItemTopLeft ); aItemBottomRight.X() += pData->aSz.Width(); + if (pData->bHiddenOnGUI) + { + mpParentPopup.disposeAndClear(); + mpParentPopup = VclPtr<PopupMenu>::Create(); + pActivePopup = mpParentPopup.get(); + + for (sal_uInt16 i = nHighlightedItem; i < pMenu->GetItemCount(); ++i) + { + sal_uInt16 nId = pMenu->GetItemId(i); + + MenuItemData* pParentItemData = pMenu->GetItemList()->GetData(nId); + + mpParentPopup->InsertItem(nId, pParentItemData->aText, pParentItemData->nBits, pParentItemData->sIdent); + mpParentPopup->SetHelpId(nId, pParentItemData->aHelpId); + mpParentPopup->SetHelpText(nId, pParentItemData->aHelpText); + mpParentPopup->SetAccelKey(nId, pParentItemData->aAccelKey); + mpParentPopup->SetItemCommand(nId, pParentItemData->aCommandStr); + mpParentPopup->SetHelpCommand(nId, pParentItemData->aHelpCommandStr); + + PopupMenu* pPopup = pMenu->GetPopupMenu(nId); + mpParentPopup->SetPopupMenu(nId, pPopup); + } + } // the menu bar could have height 0 in fullscreen mode: // so do not use always WindowHeight, as ItemHeight < WindowHeight. if ( GetSizePixel().Height() ) @@ -340,6 +364,15 @@ void MenuBarWindow::KillActivePopup() // check for pActivePopup, if stopped by deactivate... if ( pActivePopup->ImplGetWindow() ) { + if (mpParentPopup) + { + for (sal_uInt16 i = 0; i < mpParentPopup->GetItemCount(); ++i) + { + sal_uInt16 nId = mpParentPopup->GetItemId(i); + MenuItemData* pParentItemData = mpParentPopup->GetItemList()->GetData(nId); + pParentItemData->pSubMenu = nullptr; + } + } pActivePopup->ImplGetFloatingWindow()->StopExecute(); pActivePopup->ImplGetFloatingWindow()->doShutdown(); pActivePopup->pWindow->doLazyDelete(); @@ -769,7 +802,9 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu ) } MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( n ); - if ( ( pData->eType != MenuItemType::SEPARATOR ) && pMenu->ImplIsVisible( n ) ) + if (pData->eType != MenuItemType::SEPARATOR && + pMenu->ImplIsVisible(n) && + !pMenu->ImplCurrentlyHiddenOnGUI(n)) { bool bDoSelect = true; if( ImplGetSVData()->maNWFData.mbOpenMenuOnF10 ) @@ -891,9 +926,9 @@ void MenuBarWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Recta aOutputSize.Width() -= aCloseBtn->GetSizePixel().Width(); rRenderContext.SetFillColor(rStyleSettings.GetMenuColor()); - pMenu->ImplPaint(rRenderContext, aOutputSize, 0); - if (nHighlightedItem != ITEMPOS_INVALID) + + if (nHighlightedItem != ITEMPOS_INVALID && pMenu && !pMenu->GetItemList()->GetDataFromPos(nHighlightedItem)->bHiddenOnGUI) HighlightItem(rRenderContext, nHighlightedItem); else if (ImplGetSVData()->maNWFData.mbRolloverMenubar && nRolloveredItem != ITEMPOS_INVALID) HighlightItem(rRenderContext, nRolloveredItem); diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx index c1aa5ce49d0d..bdf785f36d13 100644 --- a/vcl/source/window/menubarwindow.hxx +++ b/vcl/source/window/menubarwindow.hxx @@ -69,6 +69,7 @@ private: VclPtr<Menu> pMenu; VclPtr<PopupMenu> pActivePopup; + VclPtr<PopupMenu> mpParentPopup; sal_uInt16 nHighlightedItem; sal_uInt16 nRolloveredItem; VclPtr<vcl::Window> xSaveFocusId; diff --git a/vcl/source/window/menuitemlist.hxx b/vcl/source/window/menuitemlist.hxx index 742c7728921b..cec1cf2073d4 100644 --- a/vcl/source/window/menuitemlist.hxx +++ b/vcl/source/window/menuitemlist.hxx @@ -50,6 +50,7 @@ struct MenuItemData bool bEnabled; // Enabled bool bVisible; // Visible (note: this flag will not override MenuFlags::HideDisabledEntries when true) bool bIsTemporary; // Temporary inserted ('No selection possible') + bool bHiddenOnGUI; Size aSz; // only temporarily valid OUString aAccessibleName; // accessible name @@ -66,6 +67,7 @@ struct MenuItemData , bEnabled(false) , bVisible(false) , bIsTemporary(false) + , bHiddenOnGUI(false) , pSalMenuItem(nullptr) { } @@ -82,6 +84,7 @@ struct MenuItemData , bEnabled(false) , bVisible(false) , bIsTemporary(false) + , bHiddenOnGUI(false) , pSalMenuItem(nullptr) { } |