/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
ViewTabBar::ViewTabBar ( const Reference<XResourceId>& rxViewTabBarId, const rtl::Reference<::sd::DrawController>& rxController)
: mpTabControl(VclPtr<TabBarControl>::Create(GetAnchorWindow(rxViewTabBarId,rxController), this)),
mxController(rxController),
mxViewTabBarId(rxViewTabBarId),
mpViewShellBase(nullptr),
mnNoteBookWidthPadding(0)
{ // Do this manually instead of via uno::Reference, so we don't delete ourselves.
osl_atomic_increment(&m_refCount);
// Tunnel through the controller and use the ViewShellBase to obtain the // view frame. if (mxController)
mpViewShellBase = mxController->GetViewShellBase();
// Register as listener at XConfigurationController. if (mxController.is())
{
mxConfigurationController = mxController->getConfigurationController(); if (mxConfigurationController.is())
{
mxConfigurationController->addConfigurationChangeListener( this,
FrameworkHelper::msResourceActivationEvent,
Any());
}
}
if (mxConfigurationController.is())
{ // Unregister listener from XConfigurationController. try
{
mxConfigurationController->removeConfigurationChangeListener(this);
} catch (const lang::DisposedException&)
{ // Receiving a disposed exception is the normal case. Is there // a way to avoid it?
}
mxConfigurationController = nullptr;
}
// Tunnel through the controller and use the ViewShellBase to obtain the // view frame. if (rxController)
pBase = rxController->GetViewShellBase();
// The ViewTabBar supports at the moment only the center pane. if (rxViewTabBarId.is()
&& rxViewTabBarId->isBoundToURL(
FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT))
{ if (pBase != nullptr)
pWindow = &pBase->GetViewFrame().GetWindow();
}
// The rest is (at the moment) just for the emergency case. if (pWindow == nullptr)
{
Reference<XPane> xPane; try
{
Reference<XConfigurationController> xCC (
rxController->getConfigurationController()); if (xCC.is())
xPane.set(xCC->getResource(rxViewTabBarId->getAnchor()), UNO_QUERY);
} catch (const RuntimeException&)
{
}
// Tunnel through the XWindow to the VCL side. try
{ if (auto pPane = dynamic_cast<framework::Pane*>(xPane.get()))
pWindow = pPane->GetWindow()->GetParent();
} catch (const RuntimeException&)
{
}
}
int ViewTabBar::GetHeight() const
{ int nHeight (0);
if (!maTabBarButtons.empty())
{ 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)
{
OUString sIdent(OUString::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;
}
}
void ViewTabBar::UpdateActiveButton()
{
Reference<XView> xView; if (mpViewShellBase != nullptr)
xView = FrameworkHelper::Instance(*mpViewShellBase)->GetView(
mxViewTabBarId->getAnchor()); if (!xView.is()) return;
Reference<XResourceId> xViewId (xView->getResourceId()); for (size_t nIndex=0; nIndex<maTabBarButtons.size(); ++nIndex)
{ if (maTabBarButtons[nIndex].ResourceId->compareTo(xViewId) == 0)
{
mpTabControl->GetNotebook().set_current_page(nIndex); break;
}
}
}
void ViewTabBar::UpdateTabBarButtons()
{ int nMaxPageWidthReq(0);
weld::Notebook& rNotebook = mpTabControl->GetNotebook(); int nPageCount(rNotebook.get_n_pages()); int nIndex = 1; for (constauto& rTab : maTabBarButtons)
{
OUString sIdent(OUString::number(nIndex)); // Create a new tab when there are not enough. if (nPageCount < nIndex)
rNotebook.append_page(sIdent, rTab.ButtonLabel); else
{ // Update the tab.
rNotebook.set_tab_label_text(sIdent, rTab.ButtonLabel);
}
// 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)
rNotebook.remove_page(OUString::number(nIndex));
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 allocated width of the notebook
mnNoteBookWidthPadding = nWidthReq - nMaxPageWidthReq;
}
TabBarControl::TabBarControl (
vcl::Window* pParentWindow,
::rtl::Reference<ViewTabBar> pViewTabBar)
: InterimItemWindow(pParentWindow, u"modules/simpress/ui/tabviewbar.ui"_ustr, u"TabViewBar"_ustr)
, mxTabControl(m_xBuilder->weld_notebook(u"tabcontrol"_ustr))
, mpViewTabBar(std::move(pViewTabBar))
, mnAllocatedWidth(0)
{ // 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.
SetPaintTransparent(false);
SetBackground(Application::GetSettings().GetStyleSettings().GetDialogColor());
IMPL_LINK(TabBarControl, ActivatePageHdl, const OUString&, rPage, void)
{ if (!mpViewTabBar->ActivatePage(mxTabControl->get_page_index(rPage)))
{ // 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();
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.