diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-10-22 19:41:17 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-10-29 15:02:34 +0100 |
commit | e00fd78e6e454491014f03370e14efa5ebc2eefe (patch) | |
tree | e8ab7adde7b828920d67af525a96f3744cc1c030 /sd | |
parent | 716c9ec53e619bf9dc70ee1c86c68a13d116e3af (diff) |
weld impress TabBarControl
Change-Id: Ia596830595289005a1c7e811ae4f446dc745f50c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104699
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sd')
-rw-r--r-- | sd/UIConfig_simpress.mk | 1 | ||||
-rw-r--r-- | sd/source/ui/inc/ViewTabBar.hxx | 31 | ||||
-rw-r--r-- | sd/source/ui/view/ViewTabBar.cxx | 156 | ||||
-rw-r--r-- | sd/uiconfig/simpress/ui/tabviewbar.ui | 46 |
4 files changed, 154 insertions, 80 deletions
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> |