diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-12-07 11:18:33 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-12-07 21:05:06 +0100 |
commit | 35b5f03e41e21085b67b56e29c52dcddc9a36c30 (patch) | |
tree | fdd93138f52d9f2f83a02fb3f54f50f23eb8732f /vcl | |
parent | a91e21b9acab16bd31dbefa4640d2e5f3c3c7d63 (diff) |
move various notebookbar widgets into vcl
and we can drop their factories then
Change-Id: I1e261886dd7700710ba628da4bbeeba65efa1531
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107134
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 5 | ||||
-rw-r--r-- | vcl/inc/ContextVBox.hxx | 38 | ||||
-rw-r--r-- | vcl/inc/DropdownBox.hxx | 49 | ||||
-rw-r--r-- | vcl/inc/OptionalBox.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/PriorityHBox.hxx | 63 | ||||
-rw-r--r-- | vcl/inc/PriorityMergedHBox.hxx | 49 | ||||
-rw-r--r-- | vcl/inc/brdwin.hxx | 4 | ||||
-rw-r--r-- | vcl/source/control/ContextVBox.cxx | 62 | ||||
-rw-r--r-- | vcl/source/control/DropdownBox.cxx | 116 | ||||
-rw-r--r-- | vcl/source/control/NotebookbarPopup.cxx | 159 | ||||
-rw-r--r-- | vcl/source/control/PriorityHBox.cxx | 197 | ||||
-rw-r--r-- | vcl/source/control/PriorityMergedHBox.cxx | 194 | ||||
-rw-r--r-- | vcl/source/control/notebookbar.cxx | 2 | ||||
-rw-r--r-- | vcl/source/control/tabctrl.cxx | 2 | ||||
-rw-r--r-- | vcl/source/window/NotebookBarAddonsMerger.cxx | 4 | ||||
-rw-r--r-- | vcl/source/window/builder.cxx | 26 |
16 files changed, 964 insertions, 8 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index efddab108293..927954e7b49b 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -184,6 +184,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/control/calendar \ vcl/source/control/combobox \ vcl/source/control/ctrl \ + vcl/source/control/ContextVBox \ + vcl/source/control/DropdownBox \ vcl/source/control/edit \ vcl/source/control/field2 \ vcl/source/control/field \ @@ -201,6 +203,9 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/control/listbox \ vcl/source/control/managedmenubutton \ vcl/source/control/menubtn \ + vcl/source/control/NotebookbarPopup \ + vcl/source/control/PriorityHBox \ + vcl/source/control/PriorityMergedHBox \ vcl/source/control/notebookbar \ vcl/source/control/WeldedTabbedNotebookbar \ vcl/source/control/quickselectionengine \ diff --git a/vcl/inc/ContextVBox.hxx b/vcl/inc/ContextVBox.hxx new file mode 100644 index 000000000000..1dc31656adb7 --- /dev/null +++ b/vcl/inc/ContextVBox.hxx @@ -0,0 +1,38 @@ +/* -*- 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 <sal/config.h> + +#include <vcl/NotebookbarContextControl.hxx> +#include <vcl/layout.hxx> + +/* + * ContextVBox is a VclVBox which shows own children depending on current context. + * This control can be used in the notebookbar .ui files + */ + +class ContextVBox : public VclVBox, public NotebookbarContextControl +{ +public: + explicit ContextVBox(vcl::Window* pParent); + virtual ~ContextVBox() override; + void SetContext(vcl::EnumContext::Context eContext) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/DropdownBox.hxx b/vcl/inc/DropdownBox.hxx new file mode 100644 index 000000000000..3aa55b5ef367 --- /dev/null +++ b/vcl/inc/DropdownBox.hxx @@ -0,0 +1,49 @@ +/* -*- 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_DROPDOWNBOX_HXX +#define INCLUDED_SFX2_NOTEBOOKBAR_DROPDOWNBOX_HXX + +#include <vcl/notebookbar/IPrioritable.hxx> +#include <vcl/notebookbar/NotebookbarPopup.hxx> +#include <vcl/layout.hxx> + +class DropdownBox : public VclHBox, public vcl::IPrioritable +{ +private: + bool m_bInFullView; + VclPtr<PushButton> m_pButton; + VclPtr<NotebookbarPopup> m_pPopup; + +public: + explicit DropdownBox(vcl::Window* pParent); + virtual ~DropdownBox() override; + virtual void dispose() override; + + void HideContent() override; + void ShowContent() override; + bool IsHidden() override; + +private: + DECL_LINK(PBClickHdl, Button*, void); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/OptionalBox.hxx b/vcl/inc/OptionalBox.hxx index 326fc7536c2d..54c7b720508b 100644 --- a/vcl/inc/OptionalBox.hxx +++ b/vcl/inc/OptionalBox.hxx @@ -20,7 +20,7 @@ #ifndef INCLUDED_VCL_OPTIONALBOX_HXX #define INCLUDED_VCL_OPTIONALBOX_HXX -#include <vcl/IPrioritable.hxx> +#include <vcl/notebookbar/IPrioritable.hxx> #include <vcl/layout.hxx> class OptionalBox final : public VclHBox, public vcl::IPrioritable diff --git a/vcl/inc/PriorityHBox.hxx b/vcl/inc/PriorityHBox.hxx new file mode 100644 index 000000000000..e3e8c4c19b9c --- /dev/null +++ b/vcl/inc/PriorityHBox.hxx @@ -0,0 +1,63 @@ +/* -*- 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/notebookbar/IPrioritable.hxx> +#include <vcl/layout.hxx> + +#include <vector> + +#ifndef INCLUDED_SFX2_NOTEBOOKBAR_PRIORITYHBOX_HXX +#define INCLUDED_SFX2_NOTEBOOKBAR_PRIORITYHBOX_HXX + +/* + * 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. + */ + +class PriorityHBox : public VclHBox +{ +protected: + bool m_bInitialized; + + std::vector<vcl::IPrioritable*> m_aSortedChildren; + + virtual int GetHiddenCount() const; + + virtual void GetChildrenWithPriorities(); + +public: + explicit PriorityHBox(vcl::Window* pParent); + + virtual ~PriorityHBox() override; + + void Initialize(); + + void SetSizeFromParent(); + + virtual Size calculateRequisition() const override; + + virtual void Resize() override; + + virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/PriorityMergedHBox.hxx b/vcl/inc/PriorityMergedHBox.hxx new file mode 100644 index 000000000000..15972d2d7531 --- /dev/null +++ b/vcl/inc/PriorityMergedHBox.hxx @@ -0,0 +1,49 @@ +/* -*- 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/toolkit/button.hxx> +#include <vcl/layout.hxx> +#include "PriorityHBox.hxx" +#include <vcl/notebookbar/NotebookbarPopup.hxx> + +class PriorityMergedHBox : public PriorityHBox +{ +private: + VclPtr<PushButton> m_pButton; + VclPtr<NotebookbarPopup> m_pPopup; + + DECL_LINK(PBClickHdl, Button*, void); + +public: + explicit PriorityMergedHBox(vcl::Window* pParent); + + virtual ~PriorityMergedHBox() override { disposeOnce(); } + + virtual void Resize() override; + + virtual void dispose() override; + + int GetHiddenCount() const override; + + Size calculateRequisition() const override; + + void GetChildrenWithPriorities() override{}; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/brdwin.hxx b/vcl/inc/brdwin.hxx index b32fd963fb57..deb2cdd182a8 100644 --- a/vcl/inc/brdwin.hxx +++ b/vcl/inc/brdwin.hxx @@ -20,10 +20,10 @@ #ifndef INCLUDED_VCL_INC_BRDWIN_HXX #define INCLUDED_VCL_INC_BRDWIN_HXX -#include <vcl/notebookbar.hxx> +#include <vcl/notebookbar/notebookbar.hxx> #include <vcl/window.hxx> #include <o3tl/typed_flags_set.hxx> -#include <vcl/NotebookBarAddonsMerger.hxx> +#include <vcl/notebookbar/NotebookBarAddonsMerger.hxx> #include <com/sun/star/frame/XFrame.hpp> diff --git a/vcl/source/control/ContextVBox.cxx b/vcl/source/control/ContextVBox.cxx new file mode 100644 index 000000000000..94090d5cd680 --- /dev/null +++ b/vcl/source/control/ContextVBox.cxx @@ -0,0 +1,62 @@ +/* -*- 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 <sal/config.h> + +#include <vcl/NotebookbarContextControl.hxx> +#include <ContextVBox.hxx> + +ContextVBox::ContextVBox( vcl::Window *pParent ) + : VclVBox( pParent ) +{ +} + +ContextVBox::~ContextVBox() +{ + disposeOnce(); +} + +void ContextVBox::SetContext( vcl::EnumContext::Context eContext ) +{ + for (int nChild = 0; nChild < GetChildCount(); ++nChild) + { + if ( GetChild( nChild )->GetType() == WindowType::CONTAINER ) + { + VclContainer* pChild = static_cast<VclContainer*>( GetChild( nChild ) ); + + if ( pChild->HasContext( eContext ) || pChild->HasContext( vcl::EnumContext::Context::Any ) ) + { + Size aSize( pChild->GetOptimalSize() ); + aSize.AdjustHeight(6 ); + pChild->Show(); + pChild->SetSizePixel( aSize ); + } + else + { + pChild->Hide(); + pChild->SetSizePixel( Size( 0, 0 ) ); + } + } + } + Size aSize( GetOptimalSize() ); + aSize.AdjustWidth(6 ); + SetSizePixel( aSize ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/DropdownBox.cxx b/vcl/source/control/DropdownBox.cxx new file mode 100644 index 000000000000..8155a8bac5c9 --- /dev/null +++ b/vcl/source/control/DropdownBox.cxx @@ -0,0 +1,116 @@ +/* -*- 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/button.hxx> +#include <vcl/layout.hxx> +#include <DropdownBox.hxx> + +#define NOTEBOOK_HEADER_HEIGHT 30 + +/* + * DropdownBox - shows content or moves it to the popup + * which can be opened by clicking on a button + */ + +DropdownBox::DropdownBox(vcl::Window* pParent) + : VclHBox(pParent) + , IPrioritable() + , m_bInFullView(true) +{ + m_pButton = VclPtr<PushButton>::Create(this, WB_FLATBUTTON); + m_pButton->SetClickHdl(LINK(this, DropdownBox, PBClickHdl)); + m_pButton->SetSymbol(SymbolType::MENU); + m_pButton->set_width_request(15); + m_pButton->SetQuickHelpText(GetQuickHelpText()); + m_pButton->Resize(); +} + +DropdownBox::~DropdownBox() { disposeOnce(); } + +void DropdownBox::dispose() +{ + m_pButton.disposeAndClear(); + if (m_pPopup) + m_pPopup.disposeAndClear(); + + VclHBox::dispose(); +} + +void DropdownBox::HideContent() +{ + if (m_bInFullView) + { + m_bInFullView = false; + + for (int i = 0; i < GetChildCount(); i++) + GetChild(i)->Hide(); + + m_pButton->Show(); + SetOutputSizePixel(Size(m_pButton->GetSizePixel().Width(), GetSizePixel().Height())); + } +} + +bool DropdownBox::IsHidden() { return !m_bInFullView; } + +void DropdownBox::ShowContent() +{ + if (!m_bInFullView) + { + m_bInFullView = true; + + for (int i = 0; i < GetChildCount(); i++) + GetChild(i)->Show(); + + m_pButton->Hide(); + } +} + +IMPL_LINK(DropdownBox, PBClickHdl, Button*, /*pButton*/, void) +{ + if (m_pPopup) + m_pPopup.disposeAndClear(); + + m_pPopup = VclPtr<NotebookbarPopup>::Create(this); + + for (int i = 0; i < GetChildCount(); i++) + { + if (GetChild(i) != m_pButton) + { + Window* pChild = GetChild(i); + pChild->Show(); + + pChild->SetParent(m_pPopup->getBox()); + // count is decreased because we moved child + i--; + } + } + + m_pPopup->hideSeparators(true); + + m_pPopup->getBox()->set_height_request(GetSizePixel().Height()); + + tools::Long x = GetPosPixel().getX(); + tools::Long y = GetPosPixel().getY() + NOTEBOOK_HEADER_HEIGHT + GetSizePixel().Height(); + tools::Rectangle aRect(x, y, x, y); + + m_pPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus + | FloatWinPopupFlags::AllMouseButtonClose); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/NotebookbarPopup.cxx b/vcl/source/control/NotebookbarPopup.cxx new file mode 100644 index 000000000000..a1a3571d2dc0 --- /dev/null +++ b/vcl/source/control/NotebookbarPopup.cxx @@ -0,0 +1,159 @@ +/* -*- 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 <vcl/notebookbar/NotebookbarPopup.hxx> +#include <vcl/notebookbar/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)); + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + const BitmapEx& aPersona = rStyleSettings.GetPersonaHeader(); + + if (!aPersona.IsEmpty()) + m_pBox->SetBackground(Wallpaper(aPersona)); + else + m_pBox->SetBackground(rStyleSettings.GetDialogColor()); +} + +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); + + // resize after all children of box are empty + if (m_pParent && !m_pBox->GetChildCount()) + 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(); + } + + if (bHide) + { + sal_Int32 BoxId = 0; + while (BoxId <= m_pBox->GetChildCount() - 1) + { + if (m_pBox->GetChild(BoxId)) + { + pWindow = m_pBox->GetChild(BoxId); + ApplyBackground(pWindow); + } + BoxId++; + } + } + else + { + sal_Int32 BoxId = m_pBox->GetChildCount() - 1; + while (BoxId >= 0) + { + if (m_pBox->GetChild(BoxId)) + { + pWindow = m_pBox->GetChild(BoxId); + RemoveBackground(pWindow); + } + BoxId--; + } + } +} + +void NotebookbarPopup::dispose() +{ + PopupModeEnd(); + m_pBox.disposeAndClear(); + m_pParent.clear(); + + FloatingWindow::dispose(); +} + +void NotebookbarPopup::ApplyBackground(vcl::Window* pWindow) +{ + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + const BitmapEx& aPersona = rStyleSettings.GetPersonaHeader(); + + if (!aPersona.IsEmpty()) + pWindow->SetBackground(Wallpaper(aPersona)); + else + pWindow->SetBackground(rStyleSettings.GetDialogColor()); + + sal_Int32 nNext = 0; + VclPtr<vcl::Window> pChild = pWindow->GetChild(nNext); + while (pChild && pWindow->GetType() == WindowType::CONTAINER) + { + ApplyBackground(pChild); + nNext++; + if (pWindow->GetChild(nNext) && pWindow->GetType() == WindowType::CONTAINER) + pChild = pWindow->GetChild(nNext); + else + break; + } +} + +void NotebookbarPopup::RemoveBackground(vcl::Window* pWindow) +{ + pWindow->SetBackground(Wallpaper(COL_TRANSPARENT)); + + sal_Int32 nNext = 0; + VclPtr<vcl::Window> pChild = pWindow->GetChild(nNext); + while (pChild && pWindow->GetType() == WindowType::CONTAINER) + { + RemoveBackground(pChild); + nNext++; + if (pWindow->GetChild(nNext) && pWindow->GetType() == WindowType::CONTAINER) + pChild = pWindow->GetChild(nNext); + else + break; + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/PriorityHBox.cxx b/vcl/source/control/PriorityHBox.cxx new file mode 100644 index 000000000000..cb3219bf5a5c --- /dev/null +++ b/vcl/source/control/PriorityHBox.cxx @@ -0,0 +1,197 @@ +/* -*- 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/layout.hxx> +#include <PriorityHBox.hxx> +#include <comphelper/lok.hxx> + +namespace +{ +bool lcl_comparePriority(const vcl::IPrioritable* a, const vcl::IPrioritable* b) +{ + return a->GetPriority() < b->GetPriority(); +} +} + +PriorityHBox::PriorityHBox(vcl::Window* pParent) + : VclHBox(pParent) + , m_bInitialized(false) +{ +} + +PriorityHBox::~PriorityHBox() { disposeOnce(); } + +void PriorityHBox::Initialize() +{ + m_bInitialized = true; + + GetChildrenWithPriorities(); + SetSizeFromParent(); +} + +int PriorityHBox::GetHiddenCount() const +{ + int nCount = 0; + + for (auto pWindow : m_aSortedChildren) + if (pWindow->IsHidden()) + nCount++; + + return nCount; +} + +void PriorityHBox::SetSizeFromParent() +{ + vcl::Window* pParent = GetParent(); + if (pParent) + { + Size aParentSize = pParent->GetSizePixel(); + SetSizePixel(Size(aParentSize.getWidth(), aParentSize.getHeight())); + } +} + +Size PriorityHBox::calculateRequisition() const +{ + if (!m_bInitialized) + { + return VclHBox::calculateRequisition(); + } + + sal_uInt16 nVisibleChildren = 0; + + Size aSize; + for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild; + pChild = pChild->GetWindow(GetWindowType::Next)) + { + if (!pChild->IsVisible()) + continue; + ++nVisibleChildren; + Size aChildSize = getLayoutRequisition(*pChild); + + bool bAlwaysExpanded = true; + + vcl::IPrioritable* pPrioritable = dynamic_cast<vcl::IPrioritable*>(pChild); + if (pPrioritable && pPrioritable->GetPriority() != VCL_PRIORITY_DEFAULT) + bAlwaysExpanded = false; + + if (bAlwaysExpanded) + { + tools::Long nPrimaryDimension = getPrimaryDimension(aChildSize); + nPrimaryDimension += pChild->get_padding() * 2; + setPrimaryDimension(aChildSize, nPrimaryDimension); + } + else + setPrimaryDimension(aChildSize, 0); + + accumulateMaxes(aChildSize, aSize); + } + + return finalizeMaxes(aSize, nVisibleChildren); +} + +void PriorityHBox::Resize() +{ + if (!m_bInitialized) + Initialize(); + + if (!m_bInitialized || comphelper::LibreOfficeKit::isActive()) + { + return VclHBox::Resize(); + } + + tools::Long nWidth = GetSizePixel().Width(); + tools::Long nCurrentWidth = VclHBox::calculateRequisition().getWidth(); + + // Hide lower priority controls + for (vcl::IPrioritable* pPrioritable : m_aSortedChildren) + { + if (nCurrentWidth <= nWidth) + break; + + vcl::Window* pWindow = dynamic_cast<vcl::Window*>(pPrioritable); + + if (pWindow && pWindow->GetParent() == this) + { + nCurrentWidth -= pWindow->GetOutputWidthPixel() + get_spacing(); + pWindow->Show(); + pPrioritable->HideContent(); + nCurrentWidth += pWindow->GetOutputWidthPixel() + get_spacing(); + } + } + + 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; + + if (pWindow->GetParent() != this) + { + pChildR++; + continue; + } + + if (pWindow) + { + nCurrentWidth -= pWindow->GetOutputWidthPixel() + get_spacing(); + pWindow->Show(); + pPrioritable->ShowContent(); + nCurrentWidth += getLayoutRequisition(*pWindow).Width() + get_spacing(); + + if (nCurrentWidth > nWidth) + { + pPrioritable->HideContent(); + break; + } + } + + pChildR++; + } + + VclHBox::Resize(); +} + +void PriorityHBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) +{ + if (!m_bInitialized) + Initialize(); + + VclHBox::Paint(rRenderContext, rRect); +} + +void PriorityHBox::GetChildrenWithPriorities() +{ + for (sal_uInt16 i = 0; i < GetChildCount(); ++i) + { + vcl::Window* pChild = GetChild(i); + + // Add only containers which have explicitly assigned priority. + vcl::IPrioritable* pPrioritable = dynamic_cast<vcl::IPrioritable*>(pChild); + if (pPrioritable && pPrioritable->GetPriority() != VCL_PRIORITY_DEFAULT) + m_aSortedChildren.push_back(pPrioritable); + } + + if (m_aSortedChildren.empty()) + m_bInitialized = false; + + std::sort(m_aSortedChildren.begin(), m_aSortedChildren.end(), lcl_comparePriority); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/PriorityMergedHBox.cxx b/vcl/source/control/PriorityMergedHBox.cxx new file mode 100644 index 000000000000..be89d8f35cf5 --- /dev/null +++ b/vcl/source/control/PriorityMergedHBox.cxx @@ -0,0 +1,194 @@ +/* -*- 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/button.hxx> +#include <vcl/layout.hxx> +#include <bitmaps.hlst> +#include <PriorityHBox.hxx> +#include <PriorityMergedHBox.hxx> +#include <vcl/notebookbar/NotebookbarPopup.hxx> +#include <comphelper/lok.hxx> + +#define DUMMY_WIDTH 50 +#define BUTTON_WIDTH 30 + +/* +* PriorityMergedHBox is a VclHBox which hides its own children if there is no sufficient space. +*/ + +PriorityMergedHBox::PriorityMergedHBox(vcl::Window* pParent) + : PriorityHBox(pParent) +{ + m_pButton = VclPtr<PushButton>::Create(this, WB_FLATBUTTON); + m_pButton->SetClickHdl(LINK(this, PriorityMergedHBox, PBClickHdl)); + m_pButton->SetModeImage(Image(StockImage::Yes, CHEVRON)); + m_pButton->set_width_request(25); + m_pButton->set_pack_type(VclPackType::End); + m_pButton->Show(); +} + +void PriorityMergedHBox::Resize() +{ + if (comphelper::LibreOfficeKit::isActive()) + return VclHBox::Resize(); + + if (!m_bInitialized) + Initialize(); + + if (!m_bInitialized) + { + return VclHBox::Resize(); + } + + tools::Long nWidth = GetSizePixel().Width(); + tools::Long nCurrentWidth = VclHBox::calculateRequisition().getWidth() + BUTTON_WIDTH; + + // Hide lower priority controls + for (int i = GetChildCount() - 1; i >= 0; i--) + { + vcl::Window* pWindow = GetChild(i); + + if (nCurrentWidth <= nWidth) + break; + + if (pWindow && pWindow->GetParent() == this && pWindow->IsVisible()) + { + if (pWindow->GetOutputWidthPixel()) + nCurrentWidth -= pWindow->GetOutputWidthPixel(); + else + nCurrentWidth -= DUMMY_WIDTH; + pWindow->Hide(); + } + } + + // Show higher priority controls if we already have enough space + for (int i = 0; i < GetChildCount(); i++) + { + vcl::Window* pWindow = GetChild(i); + + if (pWindow->GetParent() != this) + { + continue; + } + + if (pWindow && !pWindow->IsVisible()) + { + pWindow->Show(); + nCurrentWidth += getLayoutRequisition(*pWindow).Width() + get_spacing(); + + if (nCurrentWidth > nWidth) + { + pWindow->Hide(); + break; + } + } + } + + VclHBox::Resize(); + + if (GetHiddenCount()) + m_pButton->Show(); + else + m_pButton->Hide(); +} + +void PriorityMergedHBox::dispose() +{ + m_pButton.disposeAndClear(); + if (m_pPopup) + m_pPopup.disposeAndClear(); + PriorityHBox::dispose(); +} + +int PriorityMergedHBox::GetHiddenCount() const +{ + int nCount = 0; + + for (int i = GetChildCount() - 1; i >= 0; i--) + { + vcl::Window* pWindow = GetChild(i); + if (pWindow && pWindow->GetParent() == this && !pWindow->IsVisible()) + nCount++; + } + + return nCount; +} + +Size PriorityMergedHBox::calculateRequisition() const +{ + if (!m_bInitialized) + { + return VclHBox::calculateRequisition(); + } + + sal_uInt16 nVisibleChildren = 0; + + Size aSize; + for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild; + pChild = pChild->GetWindow(GetWindowType::Next)) + { + if (!pChild->IsVisible()) + continue; + ++nVisibleChildren; + Size aChildSize = getLayoutRequisition(*pChild); + + tools::Long nPrimaryDimension = getPrimaryDimension(aChildSize); + nPrimaryDimension += pChild->get_padding() * 2; + setPrimaryDimension(aChildSize, nPrimaryDimension); + + accumulateMaxes(aChildSize, aSize); + } + + setPrimaryDimension(aSize, 200); + return finalizeMaxes(aSize, nVisibleChildren); +} + +IMPL_LINK(PriorityMergedHBox, PBClickHdl, Button*, /*pButton*/, void) +{ + if (m_pPopup) + m_pPopup.disposeAndClear(); + + m_pPopup = VclPtr<NotebookbarPopup>::Create(this); + + for (int i = 0; i < GetChildCount(); i++) + { + vcl::Window* pWindow = GetChild(i); + if (pWindow != m_pButton) + { + if (!pWindow->IsVisible()) + { + pWindow->Show(); + pWindow->SetParent(m_pPopup->getBox()); + // count is decreased because we moved child + i--; + } + } + } + + m_pPopup->hideSeparators(true); + + tools::Long x = m_pButton->GetPosPixel().getX(); + tools::Long y = m_pButton->GetPosPixel().getY() + GetSizePixel().Height(); + tools::Rectangle aRect(x, y, x, y); + + m_pPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus + | FloatWinPopupFlags::AllMouseButtonClose); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/notebookbar.cxx b/vcl/source/control/notebookbar.cxx index 64686e1729b5..8feb96ee51fd 100644 --- a/vcl/source/control/notebookbar.cxx +++ b/vcl/source/control/notebookbar.cxx @@ -8,7 +8,7 @@ */ #include <vcl/layout.hxx> -#include <vcl/notebookbar.hxx> +#include <vcl/notebookbar/notebookbar.hxx> #include <vcl/syswin.hxx> #include <vcl/taskpanelist.hxx> #include <vcl/NotebookbarContextControl.hxx> diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx index faeb70ecd4e1..dee5e226452c 100644 --- a/vcl/source/control/tabctrl.cxx +++ b/vcl/source/control/tabctrl.cxx @@ -20,7 +20,7 @@ #include <sal/config.h> #include <sal/log.hxx> -#include <vcl/notebookbar.hxx> +#include <vcl/notebookbar/notebookbar.hxx> #include <vcl/svapp.hxx> #include <vcl/help.hxx> #include <vcl/event.hxx> diff --git a/vcl/source/window/NotebookBarAddonsMerger.cxx b/vcl/source/window/NotebookBarAddonsMerger.cxx index 1bbbc66b9452..b2e3d4649939 100644 --- a/vcl/source/window/NotebookBarAddonsMerger.cxx +++ b/vcl/source/window/NotebookBarAddonsMerger.cxx @@ -21,11 +21,11 @@ #include <cstddef> -#include <vcl/NotebookBarAddonsMerger.hxx> +#include <vcl/notebookbar/IPrioritable.hxx> +#include <vcl/notebookbar/NotebookBarAddonsMerger.hxx> #include <vcl/commandinfoprovider.hxx> #include <vcl/vclenum.hxx> #include <vcl/toolbox.hxx> -#include <vcl/IPrioritable.hxx> #include <OptionalBox.hxx> const char STYLE_TEXT[] = "Text"; diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 4c264b3e4bfe..4d252f579adf 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -32,7 +32,7 @@ #include <vcl/toolkit/fixed.hxx> #include <vcl/toolkit/fixedhyper.hxx> #include <vcl/headbar.hxx> -#include <vcl/IPrioritable.hxx> +#include <vcl/notebookbar/IPrioritable.hxx> #include <vcl/toolkit/ivctrl.hxx> #include <vcl/layout.hxx> #include <vcl/toolkit/lstbox.hxx> @@ -59,7 +59,11 @@ #include <bitmaps.hlst> #include <managedmenubutton.hxx> #include <messagedialog.hxx> +#include <ContextVBox.hxx> +#include <DropdownBox.hxx> #include <OptionalBox.hxx> +#include <PriorityMergedHBox.hxx> +#include <PriorityHBox.hxx> #include <window.h> #include <xmlreader/xmlreader.hxx> #include <desktop/crashreport.hxx> @@ -1979,6 +1983,26 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString & m_pParserState->m_aButtonMenuMaps.emplace_back(id, sMenu); setupFromActionName(static_cast<Button*>(xWindow.get()), rMap, m_xFrame); } + else if (name == "sfxlo-PriorityMergedHBox") + { + // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore + xWindow = VclPtr<PriorityMergedHBox>::Create(pParent); + } + else if (name == "sfxlo-PriorityHBox") + { + // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore + xWindow = VclPtr<PriorityHBox>::Create(pParent); + } + else if (name == "sfxlo-DropdownBox") + { + // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore + xWindow = VclPtr<DropdownBox>::Create(pParent); + } + else if (name == "sfxlo-ContextVBox") + { + // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore + xWindow = VclPtr<ContextVBox>::Create(pParent); + } else if (name == "GtkIconView") { assert(rMap.find(OString("model")) != rMap.end() && "GtkIconView must have a model"); |