[Libreoffice-commits] core.git: sd/source sd/uiconfig sd/UIConfig_simpress.mk

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Thu Oct 29 14:03:13 UTC 2020


 sd/UIConfig_simpress.mk               |    1 
 sd/source/ui/inc/ViewTabBar.hxx       |   31 +++++-
 sd/source/ui/view/ViewTabBar.cxx      |  156 +++++++++++++++++-----------------
 sd/uiconfig/simpress/ui/tabviewbar.ui |   46 ++++++++++
 4 files changed, 154 insertions(+), 80 deletions(-)

New commits:
commit e00fd78e6e454491014f03370e14efa5ebc2eefe
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Oct 22 19:41:17 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Thu Oct 29 15:02:34 2020 +0100

    weld impress TabBarControl
    
    Change-Id: Ia596830595289005a1c7e811ae4f446dc745f50c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104699
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sd/UIConfig_simpress.mk b/sd/UIConfig_simpress.mk
index f8e10c675609..92d12d7ecc5c 100644
--- a/sd/UIConfig_simpress.mk
+++ b/sd/UIConfig_simpress.mk
@@ -156,6 +156,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/simpress,\
 	sd/uiconfig/simpress/ui/slidecontextmenu \
 	sd/uiconfig/simpress/ui/slidedesigndialog \
 	sd/uiconfig/simpress/ui/slidetransitionspanel \
+	sd/uiconfig/simpress/ui/tabviewbar \
 	sd/uiconfig/simpress/ui/tabledesignpanel \
 	sd/uiconfig/simpress/ui/templatedialog \
 ))
diff --git a/sd/source/ui/inc/ViewTabBar.hxx b/sd/source/ui/inc/ViewTabBar.hxx
index 534eb215dd2b..f48f76d495fd 100644
--- a/sd/source/ui/inc/ViewTabBar.hxx
+++ b/sd/source/ui/inc/ViewTabBar.hxx
@@ -25,8 +25,8 @@
 #include <com/sun/star/drawing/framework/XToolBar.hpp>
 #include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
-#include <vcl/tabctrl.hxx>
 #include <cppuhelper/compbase.hxx>
+#include <vcl/InterimItemWindow.hxx>
 #include "MutexOwner.hxx"
 
 #include <vector>
@@ -39,10 +39,28 @@ namespace vcl { class Window; }
 
 namespace sd {
     class ViewShellBase;
+    class ViewTabBar;
 }
 
 namespace sd {
 
+class TabBarControl : public InterimItemWindow
+{
+public:
+    TabBarControl(vcl::Window* pParentWindow, const ::rtl::Reference<ViewTabBar>& rpViewTabBar);
+    virtual void dispose() override;
+    virtual ~TabBarControl() override;
+    weld::Notebook& GetNotebook() { return *mxTabControl; }
+    int GetAllocatedWidth() const { return mnAllocatedWidth; }
+private:
+    std::unique_ptr<weld::Notebook> mxTabControl;
+    ::rtl::Reference<ViewTabBar> mpViewTabBar;
+    int mnAllocatedWidth;
+
+    DECL_LINK(ActivatePageHdl, const OString&, void);
+    DECL_LINK(NotebookSizeAllocHdl, const Size&, void);
+};
+
 typedef ::cppu::WeakComponentImplHelper <
     css::drawing::framework::XToolBar,
     css::drawing::framework::XTabBar,
@@ -64,9 +82,9 @@ public:
 
     virtual void SAL_CALL disposing() override;
 
-    const VclPtr< ::TabControl>& GetTabControl() const { return mpTabControl;}
+    const VclPtr<TabBarControl>& GetTabControl() const { return mpTabControl; }
 
-    bool ActivatePage();
+    bool ActivatePage(size_t nIndex);
 
     //----- drawing::framework::XConfigurationChangeListener ------------------
 
@@ -125,6 +143,8 @@ public:
     */
     int GetHeight() const;
 
+    void UpdateActiveButton();
+
     void AddTabBarButton (
         const css::drawing::framework::TabBarButton& rButton,
         const css::drawing::framework::TabBarButton& rAnchor);
@@ -138,16 +158,15 @@ public:
         GetTabBarButtons();
 
 private:
-    VclPtr< ::TabControl> mpTabControl;
+    VclPtr<TabBarControl> mpTabControl;
     css::uno::Reference<css::frame::XController> mxController;
     css::uno::Reference<css::drawing::framework::XConfigurationController> mxConfigurationController;
     typedef ::std::vector<css::drawing::framework::TabBarButton> TabBarButtonList;
     TabBarButtonList maTabBarButtons;
-    VclPtr<TabPage> mpTabPage;
     css::uno::Reference<css::drawing::framework::XResourceId> mxViewTabBarId;
     ViewShellBase* mpViewShellBase;
+    int mnNoteBookWidthPadding;
 
-    void UpdateActiveButton();
     void AddTabBarButton (
         const css::drawing::framework::TabBarButton& rButton,
         sal_Int32 nPosition);
diff --git a/sd/source/ui/view/ViewTabBar.cxx b/sd/source/ui/view/ViewTabBar.cxx
index 0a8fc750510b..c045b2295827 100644
--- a/sd/source/ui/view/ViewTabBar.cxx
+++ b/sd/source/ui/view/ViewTabBar.cxx
@@ -25,9 +25,8 @@
 #include <DrawController.hxx>
 
 #include <Client.hxx>
-#include <vcl/svapp.hxx>
-#include <vcl/tabpage.hxx>
 #include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
 
 #include <sfx2/viewfrm.hxx>
 #include <com/sun/star/drawing/framework/ResourceId.hpp>
@@ -54,16 +53,6 @@ bool IsEqual (const TabBarButton& rButton1, const TabBarButton& rButton2)
         || rButton1.ButtonLabel == rButton2.ButtonLabel);
 }
 
-class TabBarControl : public ::TabControl
-{
-public:
-    TabBarControl (vcl::Window* pParentWindow, const ::rtl::Reference<ViewTabBar>& rpViewTabBar);
-    virtual void Paint (vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
-    virtual void ActivatePage() override;
-private:
-    ::rtl::Reference<ViewTabBar> mpViewTabBar;
-};
-
 } // end of anonymous namespace
 
 ViewTabBar::ViewTabBar (
@@ -73,18 +62,10 @@ ViewTabBar::ViewTabBar (
       mpTabControl(VclPtr<TabBarControl>::Create(GetAnchorWindow(rxViewTabBarId,rxController), this)),
       mxController(rxController),
       maTabBarButtons(),
-      mpTabPage(nullptr),
       mxViewTabBarId(rxViewTabBarId),
-      mpViewShellBase(nullptr)
+      mpViewShellBase(nullptr),
+      mnNoteBookWidthPadding(0)
 {
-    // Set one new tab page for all tab entries.  We need it only to
-    // determine the height of the tab bar.
-    mpTabPage.reset(VclPtr<TabPage>::Create(mpTabControl.get()));
-    mpTabPage->Hide();
-
-    // add some space before the tabitems
-    mpTabControl->SetItemsOffset(Point(5, 3));
-
     // Tunnel through the controller and use the ViewShellBase to obtain the
     // view frame.
     try
@@ -152,10 +133,6 @@ void ViewTabBar::disposing()
 
     {
         const SolarMutexGuard aSolarGuard;
-        // Set all references to the one tab page to NULL and delete the page.
-        for (sal_uInt16 nIndex=0; nIndex<mpTabControl->GetPageCount(); ++nIndex)
-            mpTabControl->SetTabPage(nIndex, nullptr);
-        mpTabPage.disposeAndClear();
         mpTabControl.disposeAndClear();
     }
 
@@ -319,7 +296,7 @@ sal_Int64 SAL_CALL ViewTabBar::getSomething (const Sequence<sal_Int8>& rId)
     return nResult;
 }
 
-bool ViewTabBar::ActivatePage()
+bool ViewTabBar::ActivatePage(size_t nIndex)
 {
     try
     {
@@ -346,7 +323,6 @@ bool ViewTabBar::ActivatePage()
             pIPClient = dynamic_cast<Client*>(mpViewShellBase->GetIPClient());
         if (pIPClient==nullptr || ! pIPClient->IsObjectInPlaceActive())
         {
-            sal_uInt16 nIndex (mpTabControl->GetCurPageId() - 1);
             if (nIndex < maTabBarButtons.size())
             {
                 xConfigurationController->requestResourceActivation(
@@ -356,13 +332,6 @@ bool ViewTabBar::ActivatePage()
 
             return true;
         }
-        else
-        {
-            // When we run into this else branch then we have an active OLE
-            // object.  We ignore the request to switch views.  Additionally
-            // we put the active tab back to the one for the current view.
-            UpdateActiveButton();
-        }
     }
     catch (const RuntimeException&)
     {
@@ -378,16 +347,31 @@ int ViewTabBar::GetHeight() const
 
     if (!maTabBarButtons.empty())
     {
-        TabPage* pActivePage (mpTabControl->GetTabPage(
-            mpTabControl->GetCurPageId()));
-        if (pActivePage!=nullptr && mpTabControl->IsReallyVisible())
-            nHeight = pActivePage->GetPosPixel().Y();
+        if (mpTabControl->IsReallyVisible())
+        {
+            weld::Notebook& rNotebook = mpTabControl->GetNotebook();
+            int nAllocatedWidth = mpTabControl->GetAllocatedWidth();
+            int nPageWidth = nAllocatedWidth - mnNoteBookWidthPadding;
+
+            // set each page width-request to the size it takes to fit the notebook allocation
+            for (int nIndex = 1, nPageCount = rNotebook.get_n_pages(); nIndex <= nPageCount; ++nIndex)
+            {
+                OString sIdent(OString::number(nIndex));
+                weld::Container* pContainer = rNotebook.get_page(sIdent);
+                pContainer->set_size_request(nPageWidth, -1);
+            }
+
+            // get the height-for-width for this allocation
+            nHeight = mpTabControl->get_preferred_size().Height();
+        }
 
         if (nHeight <= 0)
+        {
             // Using a default when the real height can not be determined.
             // To get correct height this method should be called when the
             // control is visible.
             nHeight = 21;
+        }
     }
 
     return nHeight;
@@ -430,13 +414,11 @@ void ViewTabBar::AddTabBarButton (
     const css::drawing::framework::TabBarButton& rButton,
     sal_Int32 nPosition)
 {
-    if (nPosition>=0
-        && nPosition<=mpTabControl->GetPageCount())
+    if (nPosition >= 0 &&
+        nPosition <= mpTabControl->GetNotebook().get_n_pages())
     {
-        sal_uInt16 nIndex (static_cast<sal_uInt16>(nPosition));
-
         // Insert the button into our local array.
-        maTabBarButtons.insert(maTabBarButtons.begin()+nIndex, rButton);
+        maTabBarButtons.insert(maTabBarButtons.begin() + nPosition, rButton);
         UpdateTabBarButtons();
         UpdateActiveButton();
     }
@@ -501,8 +483,7 @@ void ViewTabBar::UpdateActiveButton()
     {
         if (maTabBarButtons[nIndex].ResourceId->compareTo(xViewId) == 0)
         {
-            mpTabControl->SetCurPageId(nIndex+1);
-            mpTabControl->::TabControl::ActivatePage();
+            mpTabControl->GetNotebook().set_current_page(nIndex);
             break;
         }
     }
@@ -510,27 +491,42 @@ void ViewTabBar::UpdateActiveButton()
 
 void ViewTabBar::UpdateTabBarButtons()
 {
-    sal_uInt16 nPageCount (mpTabControl->GetPageCount());
-    sal_uInt16 nIndex = 1;
+    int nMaxPageWidthReq(0);
+
+    weld::Notebook& rNotebook = mpTabControl->GetNotebook();
+    int nPageCount(rNotebook.get_n_pages());
+    int nIndex = 1;
     for (const auto& rTab : maTabBarButtons)
     {
+        OString sIdent(OString::number(nIndex));
         // Create a new tab when there are not enough.
         if (nPageCount < nIndex)
-            mpTabControl->InsertPage(nIndex, rTab.ButtonLabel);
+            rNotebook.append_page(sIdent, rTab.ButtonLabel);
+        else
+        {
+            // Update the tab.
+            rNotebook.set_tab_label_text(sIdent, rTab.ButtonLabel);
+        }
 
-        // Update the tab.
-        mpTabControl->SetPageText(nIndex, rTab.ButtonLabel);
-        mpTabControl->SetHelpText(nIndex, rTab.HelpText);
-        mpTabControl->SetTabPage(nIndex, mpTabPage.get());
+        // Set a fairly arbitrary initial width request for the pages so we can
+        // measure what extra width the notebook itself uses
+        weld::Container* pContainer = rNotebook.get_page(sIdent);
+        int nTextWidth = pContainer->get_pixel_size(rTab.ButtonLabel).Width();
+        pContainer->set_size_request(nTextWidth, -1);
+        nMaxPageWidthReq = std::max(nMaxPageWidthReq, nTextWidth);
 
         ++nIndex;
     }
 
     // Delete tabs that are no longer used.
     for (; nIndex<=nPageCount; ++nIndex)
-        mpTabControl->RemovePage(nIndex);
+        rNotebook.remove_page(OString::number(nIndex));
 
-    mpTabPage->Hide();
+    int nWidthReq = rNotebook.get_preferred_size().Width();
+    // The excess width over the page request that the notebook uses we will
+    // use this later to help measure the best height-for-width given the
+    // eventual allocatated width of the notebook
+    mnNoteBookWidthPadding = nWidthReq - nMaxPageWidthReq;
 }
 
 //===== TabBarControl =========================================================
@@ -538,36 +534,48 @@ void ViewTabBar::UpdateTabBarButtons()
 TabBarControl::TabBarControl (
     vcl::Window* pParentWindow,
     const ::rtl::Reference<ViewTabBar>& rpViewTabBar)
-    : ::TabControl(pParentWindow),
-      mpViewTabBar(rpViewTabBar)
+    : InterimItemWindow(pParentWindow, "modules/simpress/ui/tabviewbar.ui", "TabViewBar")
+    , mxTabControl(m_xBuilder->weld_notebook("tabcontrol"))
+    , mpViewTabBar(rpViewTabBar)
+    , mnAllocatedWidth(0)
 {
-}
-
-void TabBarControl::Paint (vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect)
-{
-    Color aOriginalFillColor(rRenderContext.GetFillColor());
-    Color aOriginalLineColor(rRenderContext.GetLineColor());
-
     // Because the actual window background is transparent--to avoid
     // flickering due to multiple background paintings by this and by child
     // windows--we have to paint the background for this control explicitly:
     // the actual control is not painted over its whole bounding box.
-    rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetDialogColor());
-    rRenderContext.SetLineColor();
-    rRenderContext.DrawRect(rRect);
+    SetPaintTransparent(false);
+    SetBackground(Application::GetSettings().GetStyleSettings().GetDialogColor());
 
-    ::TabControl::Paint(rRenderContext, rRect);
+    InitControlBase(mxTabControl.get());
 
-    rRenderContext.SetFillColor(aOriginalFillColor);
-    rRenderContext.SetLineColor(aOriginalLineColor);
+    mxTabControl->connect_enter_page(LINK(this, TabBarControl, ActivatePageHdl));
+    mxTabControl->connect_size_allocate(LINK(this, TabBarControl, NotebookSizeAllocHdl));
+}
+
+void TabBarControl::dispose()
+{
+    mxTabControl.reset();
+    InterimItemWindow::dispose();
+}
+
+TabBarControl::~TabBarControl()
+{
+    disposeOnce();
+}
+
+IMPL_LINK(TabBarControl, NotebookSizeAllocHdl, const Size&, rSize, void)
+{
+    mnAllocatedWidth = rSize.Width();
 }
 
-void TabBarControl::ActivatePage()
+IMPL_LINK(TabBarControl, ActivatePageHdl, const OString&, rPage, void)
 {
-    if (mpViewTabBar->ActivatePage())
+    if (!mpViewTabBar->ActivatePage(mxTabControl->get_page_index(rPage)))
     {
-        // Call the parent so that the correct tab is highlighted.
-        this->::TabControl::ActivatePage();
+        // When we run into this else branch then we have an active OLE
+        // object.  We ignore the request to switch views.  Additionally
+        // we put the active tab back to the one for the current view.
+        mpViewTabBar->UpdateActiveButton();
     }
 }
 
diff --git a/sd/uiconfig/simpress/ui/tabviewbar.ui b/sd/uiconfig/simpress/ui/tabviewbar.ui
new file mode 100644
index 000000000000..e0c67c3ff692
--- /dev/null
+++ b/sd/uiconfig/simpress/ui/tabviewbar.ui
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="sd">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkBox" id="TabViewBar">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkNotebook" id="tabcontrol">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="margin_left">5</property>
+        <property name="margin_top">3</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="scrollable">True</property>
+        <property name="enable_popup">True</property>
+        <child>
+          <object class="GtkGrid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+        </child>
+        <child type="tab">
+          <object class="GtkLabel" id="1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label">placeholder</property>
+          </object>
+          <packing>
+            <property name="tab_fill">False</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>


More information about the Libreoffice-commits mailing list