summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-10-22 19:41:17 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-10-29 15:02:34 +0100
commite00fd78e6e454491014f03370e14efa5ebc2eefe (patch)
treee8ab7adde7b828920d67af525a96f3744cc1c030 /sd
parent716c9ec53e619bf9dc70ee1c86c68a13d116e3af (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.mk1
-rw-r--r--sd/source/ui/inc/ViewTabBar.hxx31
-rw-r--r--sd/source/ui/view/ViewTabBar.cxx156
-rw-r--r--sd/uiconfig/simpress/ui/tabviewbar.ui46
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>