[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - include/vcl vcl/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Tue Dec 19 21:17:07 UTC 2017


 include/vcl/menu.hxx                |    1 
 vcl/source/window/menu.cxx          |   90 +++++++++++++++++++++++++++++++++++-
 vcl/source/window/menubarwindow.cxx |   41 +++++++++++++++-
 vcl/source/window/menubarwindow.hxx |    1 
 vcl/source/window/menuitemlist.hxx  |    3 +
 5 files changed, 132 insertions(+), 4 deletions(-)

New commits:
commit b5d400d689e5b0e29cd4fb34d407f356421aa39b
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Mon Dec 18 19:30:06 2017 +0900

    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.
    
    Reviewed-on: https://gerrit.libreoffice.org/46711
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    (cherry picked from commit 9f3b61e51f7f9de11436b0e4eaec164f2656fbdd)
    
    Change-Id: I9218dba504464bdd44d61ebb383f7674f3df760f
    Reviewed-on: https://gerrit.libreoffice.org/46795
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index 992d7b849b98..26328ff989df 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -171,6 +171,7 @@ protected:
     SAL_DLLPRIVATE Menu* ImplFindMenu( sal_uInt16 nId );
     SAL_DLLPRIVATE Size  ImplCalcSize( vcl::Window* pWin );
     SAL_DLLPRIVATE bool  ImplIsVisible( sal_uInt16 nPos ) const;
+    SAL_DLLPRIVATE bool  ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const;
     SAL_DLLPRIVATE bool  ImplIsSelectable( sal_uInt16 nPos ) const;
     SAL_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const;
     SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisible() const;
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 5b7906ad8383..305c83c86668 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -113,6 +113,51 @@ static void ImplSetMenuItemData( MenuItemData* pData )
         pData->eType = MenuItemType::STRINGIMAGE;
 }
 
+namespace {
+
+// TODO: Move to common code with the same function in toolbox
+// Draw the ">>" - more indictor at the coordinates
+void lclDrawMoreIndicator(vcl::RenderContext& rRenderContext, const 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( Rectangle( x, y, x + linewidth, y ) );
+        x += space;
+        rRenderContext.DrawRect( 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),
@@ -1221,6 +1266,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;
@@ -1792,6 +1853,8 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize,
     if (!pThisItemOnly && !IsMenuBar() && nTitleHeight > 0)
         ImplPaintMenuTitle(rRenderContext, 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 );
@@ -2014,7 +2077,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();
@@ -2129,6 +2210,13 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize,
         Point aLogoPos(0, aOutSz.Height() - aLogoSz.Height());
         pLogo->aBitmap.Draw(&rRenderContext, aLogoPos);
     }
+    // draw "more" (">>") indicator if some items have been hidden as they go out of visible area
+    if (bHiddenItems)
+    {
+        sal_Int32 nSize = nFontHeight;
+        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 8eb2fb67a81d..42c398ed8af7 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -177,6 +177,8 @@ void MenuBarWindow::dispose()
     aFloatBtn.disposeAndClear();
     aCloseBtn.disposeAndClear();
 
+    mpParentPopup.reset();
+
     Window::dispose();
 }
 
@@ -311,6 +313,28 @@ void MenuBarWindow::ImplCreatePopup( bool bPreSelectFirst )
             Point aItemBottomRight( aItemTopLeft );
             aItemBottomRight.X() += pData->aSz.Width();
 
+            if (pData->bHiddenOnGUI)
+            {
+                mpParentPopup.reset(new PopupMenu());
+                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() )
@@ -350,6 +374,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();
@@ -767,7 +800,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 )
@@ -880,9 +915,9 @@ void MenuBarWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
     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);
 
     // in high contrast mode draw a separating line on the lower edge
diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx
index 57127b1fbaac..ae0b6ae9a7c8 100644
--- a/vcl/source/window/menubarwindow.hxx
+++ b/vcl/source/window/menubarwindow.hxx
@@ -76,6 +76,7 @@ private:
 
     Menu*           pMenu;
     PopupMenu*      pActivePopup;
+    std::unique_ptr<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 f4b9deb45073..047b3146ffff 100644
--- a/vcl/source/window/menuitemlist.hxx
+++ b/vcl/source/window/menuitemlist.hxx
@@ -52,6 +52,7 @@ struct MenuItemData
     bool            bIsTemporary;           // Temporary inserted ('No selection possible')
     bool            bMirrorMode;
     long            nItemImageAngle;
+    bool            bHiddenOnGUI;
     Size            aSz;                    // only temporarily valid
     OUString        aAccessibleName;        // accessible name
 
@@ -71,6 +72,7 @@ struct MenuItemData
         , bIsTemporary(false)
         , bMirrorMode(false)
         , nItemImageAngle(0)
+        , bHiddenOnGUI(false)
         , pSalMenuItem(nullptr)
     {
     }
@@ -90,6 +92,7 @@ struct MenuItemData
         , bIsTemporary(false)
         , bMirrorMode(false)
         , nItemImageAngle(0)
+        , bHiddenOnGUI(false)
         , pSalMenuItem(nullptr)
     {
     }


More information about the Libreoffice-commits mailing list