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>
This commit is contained in:
@@ -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 \
|
||||
))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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::ActivatePage()
|
||||
void TabBarControl::dispose()
|
||||
{
|
||||
if (mpViewTabBar->ActivatePage())
|
||||
mxTabControl.reset();
|
||||
InterimItemWindow::dispose();
|
||||
}
|
||||
|
||||
TabBarControl::~TabBarControl()
|
||||
{
|
||||
disposeOnce();
|
||||
}
|
||||
|
||||
IMPL_LINK(TabBarControl, NotebookSizeAllocHdl, const Size&, rSize, void)
|
||||
{
|
||||
mnAllocatedWidth = rSize.Width();
|
||||
}
|
||||
|
||||
IMPL_LINK(TabBarControl, ActivatePageHdl, const OString&, rPage, void)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user