Kaydet (Commit) 713f5792 authored tarafından Szymon Kłos's avatar Szymon Kłos

Notebookbar: PriorityMergedHBox, OptionalBox

Change-Id: I7822fb1b6a342065d66a3fd62f1277e43c2562dd
Reviewed-on: https://gerrit.libreoffice.org/44694Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarSzymon Kłos <szymon.klos@collabora.com>
üst c690d38b
......@@ -841,6 +841,9 @@
<glade-widget-class title="Horizontal box hiding children depending on its priorities" name="sfxlo-PriorityHBox"
generic-name="PriorityHBox" parent="GtkBox"
icon-name="widget-gtk-box"/>
<glade-widget-class title="Horizontal box hiding children depending on its priorities" name="sfxlo-PriorityMergedHBox"
generic-name="PriorityMergedHBox" parent="GtkBox"
icon-name="widget-gtk-box"/>
<glade-widget-class title="Table Design Control" name="sdlo-TableDesignBox"
generic-name="TableDesignBox" parent="GtkImage"
icon-name="widget-gtk-image"/>
......@@ -850,6 +853,9 @@
<glade-widget-class title="Box which can move own content to the popup" name="sfxlo-DropdownBox"
generic-name="DropdownBox" parent="GtkBox"
icon-name="widget-gtk-box"/>
<glade-widget-class title="Box which can hide own content" name="sfxlo-OptionalBox"
generic-name="OptionalBox" parent="GtkBox"
icon-name="widget-gtk-box"/>
<glade-widget-class title="Notebookbar ToolBox" name="sfxlo-NotebookbarToolBox"
generic-name="Notebookbar ToolBox" parent="sfxlo-SidebarToolBox"
icon-name="widget-gtk-toolbar"/>
......
......@@ -39,6 +39,7 @@ public:
virtual void HideContent() = 0;
virtual void ShowContent() = 0;
virtual bool IsHidden() = 0;
private:
int m_nPriority;
......
......@@ -241,8 +241,11 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/inet/inettbc \
sfx2/source/notebookbar/ContextVBox \
sfx2/source/notebookbar/DropdownBox \
sfx2/source/notebookbar/OptionalBox \
sfx2/source/notebookbar/PriorityHBox \
sfx2/source/notebookbar/PriorityMergedHBox \
sfx2/source/notebookbar/SfxNotebookBar \
sfx2/source/notebookbar/NotebookbarPopup \
sfx2/source/notebookbar/NotebookbarTabControl \
sfx2/source/notify/eventsupplier \
sfx2/source/notify/globalevents \
......
......@@ -25,87 +25,6 @@
#define NOTEBOOK_HEADER_HEIGHT 30
/*
* Popup - shows hidden content, controls are moved to this popup
* and after close moved to the original parent
*/
class Popup : public FloatingWindow
{
private:
VclPtr<VclHBox> m_pBox;
ScopedVclPtr<DropdownBox> m_pParent;
public:
explicit Popup(const VclPtr<DropdownBox>& pParent)
: FloatingWindow(pParent, "Popup", "sfx/ui/notebookbarpopup.ui")
, m_pParent(pParent)
{
get(m_pBox, "box");
m_pBox->SetSizePixel(Size(100, 75));
}
virtual ~Popup() override
{
disposeOnce();
}
VclHBox* getBox()
{
return m_pBox.get();
}
virtual void PopupModeEnd() override
{
hideSeparators(false);
for (int i = 0; i < m_pBox->GetChildCount(); i++)
{
m_pBox->GetChild(i)->Hide();
m_pBox->GetChild(i)->SetParent(m_pParent);
}
FloatingWindow::PopupModeEnd();
}
void hideSeparators(bool bHide = true)
{
// separator on the beginning
Window* pWindow = m_pBox->GetChild(0);
while (pWindow && pWindow->GetType() == WindowType::CONTAINER)
{
pWindow = pWindow->GetChild(0);
}
if (pWindow && pWindow->GetType() == WindowType::FIXEDLINE)
{
if (bHide)
pWindow->Hide();
else
pWindow->Show();
}
// separator on the end
pWindow = m_pBox->GetChild(m_pBox->GetChildCount() - 1);
while (pWindow && pWindow->GetType() == WindowType::CONTAINER)
{
pWindow = pWindow->GetChild(pWindow->GetChildCount() - 1);
}
if (pWindow && pWindow->GetType() == WindowType::FIXEDLINE)
{
if (bHide)
pWindow->Hide();
else
pWindow->Show();
}
}
void dispose() override
{
m_pBox.disposeAndClear();
m_pParent.clear();
FloatingWindow::dispose();
}
};
/*
* DropdownBox - shows content or moves it to the popup
* which can be opened by clicking on a button
......@@ -152,6 +71,11 @@ void DropdownBox::HideContent()
}
}
bool DropdownBox::IsHidden()
{
return !m_bInFullView;
}
void DropdownBox::ShowContent()
{
if (!m_bInFullView)
......@@ -170,7 +94,7 @@ IMPL_LINK(DropdownBox, PBClickHdl, Button*, /*pButton*/, void)
if (m_pPopup)
m_pPopup.disposeAndClear();
m_pPopup = VclPtr<Popup>::Create(this);
m_pPopup = VclPtr<NotebookbarPopup>::Create(this);
for (int i = 0; i < GetChildCount(); i++)
{
......@@ -180,6 +104,8 @@ IMPL_LINK(DropdownBox, PBClickHdl, Button*, /*pButton*/, void)
pChild->Show();
pChild->SetParent(m_pPopup->getBox());
// count is decreased because we moved child
i--;
}
}
......
......@@ -28,8 +28,7 @@
#include <vcl/floatwin.hxx>
#include <vcl/toolbox.hxx>
#include <sfx2/tbxctrl.hxx>
class Popup;
#include "NotebookbarPopup.hxx"
class SFX2_DLLPUBLIC DropdownBox : public VclHBox,
public vcl::IPrioritable
......@@ -37,7 +36,7 @@ class SFX2_DLLPUBLIC DropdownBox : public VclHBox,
private:
bool m_bInFullView;
VclPtr<PushButton> m_pButton;
VclPtr<Popup> m_pPopup;
VclPtr<NotebookbarPopup> m_pPopup;
public:
explicit DropdownBox(vcl::Window *pParent);
......@@ -46,6 +45,7 @@ public:
void HideContent() override;
void ShowContent() override;
bool IsHidden() override;
private:
DECL_LINK(PBClickHdl, Button*, void);
......
/* -*- 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/.
*/
#include "NotebookbarPopup.hxx"
#include <vcl/IPrioritable.hxx>
#include <vcl/layout.hxx>
NotebookbarPopup::NotebookbarPopup(const VclPtr<VclHBox>& pParent)
: FloatingWindow(pParent, "Popup", "sfx/ui/notebookbarpopup.ui")
, m_pParent(pParent)
{
get(m_pBox, "box");
m_pBox->SetSizePixel(Size(100, 75));
}
NotebookbarPopup::~NotebookbarPopup() { disposeOnce(); }
VclHBox* NotebookbarPopup::getBox() { return m_pBox.get(); }
void NotebookbarPopup::PopupModeEnd()
{
hideSeparators(false);
while (m_pBox->GetChildCount())
{
vcl::IPrioritable* pChild = dynamic_cast<vcl::IPrioritable*>(GetChild(0));
if (pChild)
pChild->HideContent();
vcl::Window* pWindow = m_pBox->GetChild(0);
pWindow->SetParent(m_pParent);
if (m_pParent)
m_pParent->Resize();
}
FloatingWindow::PopupModeEnd();
}
void NotebookbarPopup::hideSeparators(bool bHide)
{
// separator on the beginning
vcl::Window* pWindow = m_pBox->GetChild(0);
while (pWindow && pWindow->GetType() == WindowType::CONTAINER)
{
pWindow = pWindow->GetChild(0);
}
if (pWindow && pWindow->GetType() == WindowType::FIXEDLINE)
{
if (bHide)
pWindow->Hide();
else
pWindow->Show();
}
// separator on the end
pWindow = m_pBox->GetChild(m_pBox->GetChildCount() - 1);
while (pWindow && pWindow->GetType() == WindowType::CONTAINER)
{
pWindow = pWindow->GetChild(pWindow->GetChildCount() - 1);
}
if (pWindow && pWindow->GetType() == WindowType::FIXEDLINE)
{
if (bHide)
pWindow->Hide();
else
pWindow->Show();
}
}
void NotebookbarPopup::dispose()
{
PopupModeEnd();
m_pBox.disposeAndClear();
m_pParent.clear();
FloatingWindow::dispose();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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 .
*/
#ifndef INCLUDED_SFX2_NOTEBOOKBAR_NOTEBOOKBARPOPUP_HXX
#define INCLUDED_SFX2_NOTEBOOKBAR_NOTEBOOKBARPOPUP_HXX
#include <vcl/layout.hxx>
#include <sfx2/dllapi.h>
#include <sfx2/viewfrm.hxx>
#include <vcl/floatwin.hxx>
/*
* Popup - shows hidden content, controls are moved to this popup
* and after close moved to the original parent
*/
class SFX2_DLLPUBLIC NotebookbarPopup : public FloatingWindow
{
private:
VclPtr<VclHBox> m_pBox;
ScopedVclPtr<VclHBox> m_pParent;
public:
explicit NotebookbarPopup(const VclPtr<VclHBox>& pParent);
virtual ~NotebookbarPopup() override;
VclHBox* getBox();
virtual void PopupModeEnd() override;
void hideSeparators(bool bHide = true);
void dispose() override;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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 .
*/
#include <vcl/builderfactory.hxx>
#include <vcl/layout.hxx>
#include <sfx2/dllapi.h>
#include <sfx2/viewfrm.hxx>
#include "OptionalBox.hxx"
/*
* OptionalBox - shows or hides the content. To use with PriorityHBox
* or PriorityMergedHBox
*/
OptionalBox::OptionalBox(vcl::Window* pParent)
: VclHBox(pParent)
, IPrioritable()
, m_bInFullView(true)
{
}
OptionalBox::~OptionalBox() { disposeOnce(); }
void OptionalBox::HideContent()
{
if (m_bInFullView)
{
m_bInFullView = false;
for (int i = 0; i < GetChildCount(); i++)
GetChild(i)->Hide();
SetOutputSizePixel(Size(10, GetSizePixel().Height()));
}
}
void OptionalBox::ShowContent()
{
if (!m_bInFullView)
{
m_bInFullView = true;
for (int i = 0; i < GetChildCount(); i++)
GetChild(i)->Show();
}
}
bool OptionalBox::IsHidden() { return !m_bInFullView; }
VCL_BUILDER_FACTORY(OptionalBox)
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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 .
*/
#ifndef INCLUDED_SFX2_NOTEBOOKBAR_OPTIONALBOX_HXX
#define INCLUDED_SFX2_NOTEBOOKBAR_OPTIONALBOX_HXX
#include <vcl/builderfactory.hxx>
#include <vcl/IPrioritable.hxx>
#include <vcl/layout.hxx>
#include <sfx2/dllapi.h>
#include <sfx2/viewfrm.hxx>
#include <vcl/floatwin.hxx>
#include <vcl/toolbox.hxx>
#include <sfx2/tbxctrl.hxx>
class SFX2_DLLPUBLIC OptionalBox : public VclHBox, public vcl::IPrioritable
{
private:
bool m_bInFullView;
public:
explicit OptionalBox(vcl::Window* pParent);
virtual ~OptionalBox() override;
void HideContent() override;
void ShowContent() override;
bool IsHidden() override;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -22,170 +22,189 @@
#include <sfx2/dllapi.h>
#include <sfx2/viewfrm.hxx>
#include "DropdownBox.hxx"
#include "PriorityHBox.hxx"
#include <vector>
namespace
{
bool lcl_comparePriority(const vcl::IPrioritable* a, const vcl::IPrioritable* b)
{
return a->GetPriority() < b->GetPriority();
}
}
bool lcl_comparePriority(const vcl::IPrioritable* a, const vcl::IPrioritable* b)
PriorityHBox::PriorityHBox(vcl::Window *pParent)
: VclHBox(pParent)
, m_bInitialized(false)
{
return a->GetPriority() < b->GetPriority();
}
/*
* PriorityHBox is a VclHBox which hides its own children if there is no sufficient space.
* Hiding order can be modified using child's priorities. If a control have default
* priority assigned (VCL_PRIORITY_DEFAULT), it is always shown.
*/
PriorityHBox::~PriorityHBox()
{
disposeOnce();
}
class SFX2_DLLPUBLIC PriorityHBox : public VclHBox
void PriorityHBox::Initialize()
{
private:
bool m_bInitialized;
m_bInitialized = true;
std::vector<vcl::IPrioritable*> m_aSortedChilds;
GetChildrenWithPriorities();
SetSizeFromParent();
}
public:
explicit PriorityHBox(vcl::Window *pParent)
: VclHBox(pParent)
, m_bInitialized(false)
{
}
int PriorityHBox::GetHiddenCount() const
{
int nCount = 0;
virtual ~PriorityHBox() override
{
disposeOnce();
}
for (auto pWindow : m_aSortedChildren)
if (pWindow->IsHidden())
nCount++;
void Initialize()
{
m_bInitialized = true;
return nCount;
}
GetChildrenWithPriorities();
SetSizeFromParent();
void PriorityHBox::SetSizeFromParent()
{
vcl::Window* pParent = GetParent();
if (pParent)
{
Size aParentSize = pParent->GetSizePixel();
SetSizePixel(Size(aParentSize.getWidth(), aParentSize.getHeight()));
}
}
void SetSizeFromParent()
Size PriorityHBox::calculateRequisition() const
{
if (!m_bInitialized)
{
vcl::Window* pParent = GetParent();
if (pParent)
{
Size aParentSize = pParent->GetSizePixel();
SetSizePixel(Size(aParentSize.getWidth(), aParentSize.getHeight()));
}
return VclHBox::calculateRequisition();
}
virtual Size calculateRequisition() const override
sal_uInt16 nVisibleChildren = 0;
Size aSize;
for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
{
if (!m_bInitialized)
{
return VclHBox::calculateRequisition();
}
if (!pChild->IsVisible())
continue;
++nVisibleChildren;
Size aChildSize = getLayoutRequisition(*pChild);
sal_uInt16 nVisibleChildren = 0;
bool bAllwaysExpanded = true;
Size aSize;
for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
{
if (!pChild->IsVisible())
continue;
++nVisibleChildren;
Size aChildSize = getLayoutRequisition(*pChild);
vcl::IPrioritable* pPrioritable = dynamic_cast<vcl::IPrioritable*>(pChild);
if (pPrioritable && pPrioritable->GetPriority() != VCL_PRIORITY_DEFAULT)
bAllwaysExpanded = false;
bool bAllwaysExpanded = true;
if (bAllwaysExpanded)
{
long nPrimaryDimension = getPrimaryDimension(aChildSize);
nPrimaryDimension += pChild->get_padding() * 2;
setPrimaryDimension(aChildSize, nPrimaryDimension);
}
else
setPrimaryDimension(aChildSize, 0);
vcl::IPrioritable* pPrioritable = dynamic_cast<vcl::IPrioritable*>(pChild);
if (pPrioritable && pPrioritable->GetPriority() != VCL_PRIORITY_DEFAULT)
bAllwaysExpanded = false;
accumulateMaxes(aChildSize, aSize);
}
if (bAllwaysExpanded)
{
long nPrimaryDimension = getPrimaryDimension(aChildSize);
nPrimaryDimension += pChild->get_padding() * 2;
setPrimaryDimension(aChildSize, nPrimaryDimension);
}
else
setPrimaryDimension(aChildSize, 0);
return finalizeMaxes(aSize, nVisibleChildren);
}
accumulateMaxes(aChildSize, aSize);
}
void PriorityHBox::Resize()
{
if (!m_bInitialized && SfxViewFrame::Current())
Initialize();
return finalizeMaxes(aSize, nVisibleChildren);
if (!m_bInitialized)
{
return VclHBox::Resize();
}
virtual void Resize() override
long nWidth = GetSizePixel().Width();
long nCurrentWidth = VclHBox::calculateRequisition().getWidth();
// Hide lower priority controls
auto pChild = m_aSortedChildren.begin();
while (nCurrentWidth > nWidth && pChild != m_aSortedChildren.end())
{
if (!m_bInitialized && SfxViewFrame::Current())
Initialize();
vcl::Window* pWindow = dynamic_cast<vcl::Window*>(*pChild);
vcl::IPrioritable* pPrioritable = *pChild;
if (!m_bInitialized)
if(pWindow->GetParent() != this)
{
return VclHBox::Resize();
pChild++;
continue;
}
long nWidth = GetSizePixel().Width();
long nCurrentWidth = VclHBox::calculateRequisition().getWidth();
// Hide lower priority controls
auto pChild = m_aSortedChilds.begin();
while (nCurrentWidth > nWidth && pChild != m_aSortedChilds.end())
if (pWindow)
{
// ATM DropdownBox is the only one derived class from IPrioritable
DropdownBox* pDropdownBox = static_cast<DropdownBox*>(*pChild);
nCurrentWidth -= pWindow->GetOutputWidthPixel() + get_spacing();
pWindow->Show();
pPrioritable->HideContent();
nCurrentWidth += pWindow->GetOutputWidthPixel() + get_spacing();
}
nCurrentWidth -= pDropdownBox->GetOutputWidthPixel() + get_spacing();
pDropdownBox->HideContent();
nCurrentWidth += pDropdownBox->GetOutputWidthPixel() + get_spacing();
pChild++;
}
pChild++;
}
auto pChildR = m_aSortedChildren.rbegin();
// Show higher priority controls if we already have enough space
while (pChildR != m_aSortedChildren.rend())
{
vcl::Window* pWindow = dynamic_cast<vcl::Window*>(*pChildR);
vcl::IPrioritable* pPrioritable = *pChildR;
auto pChildR = m_aSortedChilds.rbegin();
// Show higher priority controls if we already have enough space
while (pChildR != m_aSortedChilds.rend())
if(pWindow->GetParent() != this)
{
DropdownBox* pBox = static_cast<DropdownBox*>(*pChildR);
pChildR++;
continue;
}
nCurrentWidth -= pBox->GetOutputWidthPixel() + get_spacing();
pBox->ShowContent();
nCurrentWidth += getLayoutRequisition(*pBox).Width() + get_spacing();
if (pWindow)
{
nCurrentWidth -= pWindow->GetOutputWidthPixel() + get_spacing();
pWindow->Show();
pPrioritable->ShowContent();
nCurrentWidth += getLayoutRequisition(*pWindow).Width() + get_spacing();
if (nCurrentWidth > nWidth)
{
pBox->HideContent();
pPrioritable->HideContent();
break;
}
pChildR++;
}
VclHBox::Resize();
pChildR++;
}
virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override
{
if (!m_bInitialized && SfxViewFrame::Current())
Initialize();
VclHBox::Resize();
}
VclHBox::Paint(rRenderContext, rRect);
}
void PriorityHBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
if (!m_bInitialized && SfxViewFrame::Current())
Initialize();
void GetChildrenWithPriorities()
VclHBox::Paint(rRenderContext, rRect);
}
void PriorityHBox::GetChildrenWithPriorities()
{
for (sal_uInt16 i = 0; i < GetChildCount(); ++i)
{