From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- vcl/source/control/ContextVBox.cxx | 62 + vcl/source/control/DropdownBox.cxx | 115 + vcl/source/control/InterimItemWindow.cxx | 195 ++ vcl/source/control/NotebookbarPopup.cxx | 161 + vcl/source/control/PriorityHBox.cxx | 197 ++ vcl/source/control/PriorityMergedHBox.cxx | 203 ++ vcl/source/control/WeldedTabbedNotebookbar.cxx | 23 + vcl/source/control/button.cxx | 3826 ++++++++++++++++++++++++ vcl/source/control/calendar.cxx | 1723 +++++++++++ vcl/source/control/combobox.cxx | 1572 ++++++++++ vcl/source/control/ctrl.cxx | 505 ++++ vcl/source/control/edit.cxx | 2929 ++++++++++++++++++ vcl/source/control/field.cxx | 1885 ++++++++++++ vcl/source/control/field2.cxx | 3183 ++++++++++++++++++++ vcl/source/control/fixed.cxx | 995 ++++++ vcl/source/control/fixedhyper.cxx | 186 ++ vcl/source/control/fmtfield.cxx | 1367 +++++++++ vcl/source/control/hyperlabel.cxx | 176 ++ vcl/source/control/imgctrl.cxx | 184 ++ vcl/source/control/imivctl.hxx | 513 ++++ vcl/source/control/imivctl1.cxx | 2927 ++++++++++++++++++ vcl/source/control/imivctl2.cxx | 715 +++++ vcl/source/control/imp_listbox.cxx | 3012 +++++++++++++++++++ vcl/source/control/ivctrl.cxx | 634 ++++ vcl/source/control/listbox.cxx | 1427 +++++++++ vcl/source/control/longcurr.cxx | 429 +++ vcl/source/control/managedmenubutton.cxx | 100 + vcl/source/control/menubtn.cxx | 290 ++ vcl/source/control/notebookbar.cxx | 347 +++ vcl/source/control/prgsbar.cxx | 232 ++ vcl/source/control/quickselectionengine.cxx | 158 + vcl/source/control/roadmap.cxx | 845 ++++++ vcl/source/control/roadmapwizard.cxx | 798 +++++ vcl/source/control/scrbar.cxx | 1467 +++++++++ vcl/source/control/slider.cxx | 905 ++++++ vcl/source/control/spinbtn.cxx | 468 +++ vcl/source/control/spinfld.cxx | 1034 +++++++ vcl/source/control/tabctrl.cxx | 2459 +++++++++++++++ vcl/source/control/throbber.cxx | 235 ++ vcl/source/control/thumbpos.hxx | 24 + vcl/source/control/wizardmachine.cxx | 1418 +++++++++ vcl/source/control/wizimpldata.hxx | 64 + 42 files changed, 39988 insertions(+) create mode 100644 vcl/source/control/ContextVBox.cxx create mode 100644 vcl/source/control/DropdownBox.cxx create mode 100644 vcl/source/control/InterimItemWindow.cxx create mode 100644 vcl/source/control/NotebookbarPopup.cxx create mode 100644 vcl/source/control/PriorityHBox.cxx create mode 100644 vcl/source/control/PriorityMergedHBox.cxx create mode 100644 vcl/source/control/WeldedTabbedNotebookbar.cxx create mode 100644 vcl/source/control/button.cxx create mode 100644 vcl/source/control/calendar.cxx create mode 100644 vcl/source/control/combobox.cxx create mode 100644 vcl/source/control/ctrl.cxx create mode 100644 vcl/source/control/edit.cxx create mode 100644 vcl/source/control/field.cxx create mode 100644 vcl/source/control/field2.cxx create mode 100644 vcl/source/control/fixed.cxx create mode 100644 vcl/source/control/fixedhyper.cxx create mode 100644 vcl/source/control/fmtfield.cxx create mode 100644 vcl/source/control/hyperlabel.cxx create mode 100644 vcl/source/control/imgctrl.cxx create mode 100644 vcl/source/control/imivctl.hxx create mode 100644 vcl/source/control/imivctl1.cxx create mode 100644 vcl/source/control/imivctl2.cxx create mode 100644 vcl/source/control/imp_listbox.cxx create mode 100644 vcl/source/control/ivctrl.cxx create mode 100644 vcl/source/control/listbox.cxx create mode 100644 vcl/source/control/longcurr.cxx create mode 100644 vcl/source/control/managedmenubutton.cxx create mode 100644 vcl/source/control/menubtn.cxx create mode 100644 vcl/source/control/notebookbar.cxx create mode 100644 vcl/source/control/prgsbar.cxx create mode 100644 vcl/source/control/quickselectionengine.cxx create mode 100644 vcl/source/control/roadmap.cxx create mode 100644 vcl/source/control/roadmapwizard.cxx create mode 100644 vcl/source/control/scrbar.cxx create mode 100644 vcl/source/control/slider.cxx create mode 100644 vcl/source/control/spinbtn.cxx create mode 100644 vcl/source/control/spinfld.cxx create mode 100644 vcl/source/control/tabctrl.cxx create mode 100644 vcl/source/control/throbber.cxx create mode 100644 vcl/source/control/thumbpos.hxx create mode 100644 vcl/source/control/wizardmachine.cxx create mode 100644 vcl/source/control/wizimpldata.hxx (limited to 'vcl/source/control') diff --git a/vcl/source/control/ContextVBox.cxx b/vcl/source/control/ContextVBox.cxx new file mode 100644 index 000000000..94090d5cd --- /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 + +#include +#include + +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( 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 000000000..6aaf2e553 --- /dev/null +++ b/vcl/source/control/DropdownBox.cxx @@ -0,0 +1,115 @@ +/* -*- 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 +#include +#include + +#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) + , m_bInFullView(true) +{ + m_pButton = VclPtr::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::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/InterimItemWindow.cxx b/vcl/source/control/InterimItemWindow.cxx new file mode 100644 index 000000000..0017065d7 --- /dev/null +++ b/vcl/source/control/InterimItemWindow.cxx @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 +#include +#include +#include + +InterimItemWindow::InterimItemWindow(vcl::Window* pParent, const OUString& rUIXMLDescription, + const OString& rID, bool bAllowCycleFocusOut, + sal_uInt64 nLOKWindowId) + : Control(pParent, WB_TABSTOP) + , m_pWidget(nullptr) // inheritors are expected to call InitControlBase + , m_aLayoutIdle("InterimItemWindow m_aLayoutIdle") +{ + m_aLayoutIdle.SetPriority(TaskPriority::RESIZE); + m_aLayoutIdle.SetInvokeHandler(LINK(this, InterimItemWindow, DoLayout)); + + m_xVclContentArea = VclPtr::Create(this); + m_xVclContentArea->Show(); + m_xBuilder = Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription, + bAllowCycleFocusOut, nLOKWindowId); + m_xContainer = m_xBuilder->weld_container(rID); + + SetBackground(); + SetPaintTransparent(true); +} + +void InterimItemWindow::StateChanged(StateChangedType nStateChange) +{ + if (nStateChange == StateChangedType::Enable) + m_xContainer->set_sensitive(IsEnabled()); + Control::StateChanged(nStateChange); +} + +InterimItemWindow::~InterimItemWindow() { disposeOnce(); } + +void InterimItemWindow::dispose() +{ + m_pWidget = nullptr; + + m_xContainer.reset(); + m_xBuilder.reset(); + m_xVclContentArea.disposeAndClear(); + + m_aLayoutIdle.Stop(); + + Control::dispose(); +} + +void InterimItemWindow::StartIdleLayout() +{ + if (!m_xVclContentArea) + return; + if (m_aLayoutIdle.IsActive()) + return; + m_aLayoutIdle.Start(); +} + +void InterimItemWindow::queue_resize(StateChangedType eReason) +{ + Control::queue_resize(eReason); + StartIdleLayout(); +} + +void InterimItemWindow::Resize() { Layout(); } + +void InterimItemWindow::UnclipVisibleSysObj() +{ + if (!IsVisible()) + return; + vcl::Window* pChild = m_xVclContentArea->GetWindow(GetWindowType::FirstChild); + if (!pChild) + return; + WindowImpl* pWindowImpl = pChild->ImplGetWindowImpl(); + if (!pWindowImpl) + return; + if (!pWindowImpl->mpSysObj) + return; + pWindowImpl->mpSysObj->Show(true); + pWindowImpl->mpSysObj->ResetClipRegion(); + // flag that sysobj clip is dirty and needs to be recalculated on next use + pWindowImpl->mbInitWinClipRegion = true; +} + +IMPL_LINK_NOARG(InterimItemWindow, DoLayout, Timer*, void) { Layout(); } + +void InterimItemWindow::Layout() +{ + m_aLayoutIdle.Stop(); + vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); + assert(pChild); + VclContainer::setLayoutAllocation(*pChild, Point(0, 0), GetSizePixel()); + Control::Resize(); +} + +Size InterimItemWindow::GetOptimalSize() const +{ + return VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild)); +} + +void InterimItemWindow::InvalidateChildSizeCache() +{ + // find the bottom vcl::Window of the hierarchy and queue_resize on that + // one will invalidate all the size caches upwards + vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); + while (true) + { + vcl::Window* pSubChild = pChild->GetWindow(GetWindowType::FirstChild); + if (!pSubChild) + break; + pChild = pSubChild; + } + pChild->queue_resize(); +} + +bool InterimItemWindow::ControlHasFocus() const +{ + if (!m_pWidget) + return false; + return m_pWidget->has_focus(); +} + +void InterimItemWindow::InitControlBase(weld::Widget* pWidget) { m_pWidget = pWidget; } + +void InterimItemWindow::GetFocus() +{ + if (m_pWidget) + m_pWidget->grab_focus(); + + /* let toolbox know this item window has focus so it updates its mnHighItemId to point + to this toolitem in case tab means to move to another toolitem within + the toolbox + */ + vcl::Window* pToolBox = GetParent(); + NotifyEvent aNEvt(MouseNotifyEvent::GETFOCUS, this); + pToolBox->EventNotify(aNEvt); +} + +bool InterimItemWindow::ChildKeyInput(const KeyEvent& rKEvt) +{ + sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); + if (nCode != KEY_TAB) + return false; + + /* if the native widget has focus, then no vcl window has focus. + + We want to grab focus to this vcl widget so that pressing tab will traverse + to the next vcl widget. + + But just using GrabFocus will, because no vcl widget has focus, trigger + bringing the toplevel to front with the expectation that a suitable widget + will be picked for focus when that happen, which is no use to us here. + + SetFakeFocus avoids the problem, allowing GrabFocus to do the expected thing + then sending the Tab to our parent will do the right traversal + */ + SetFakeFocus(true); + GrabFocus(); + + /* now give focus to our toolbox parent */ + vcl::Window* pToolBox = GetParent(); + pToolBox->GrabFocus(); + + /* let toolbox know this item window has focus so it updates its mnHighItemId to point + to this toolitem in case tab means to move to another toolitem within + the toolbox + */ + NotifyEvent aNEvt(MouseNotifyEvent::GETFOCUS, this); + pToolBox->EventNotify(aNEvt); + + /* send parent the tab */ + pToolBox->KeyInput(rKEvt); + + return true; +} + +void InterimItemWindow::Draw(OutputDevice* pDevice, const Point& rPos, + SystemTextColorFlags /*nFlags*/) +{ + m_xContainer->draw(*pDevice, rPos, GetSizePixel()); +} + +void InterimItemWindow::ImplPaintToDevice(::OutputDevice* pTargetOutDev, const Point& rPos) +{ + Draw(pTargetOutDev, rPos, SystemTextColorFlags::NONE); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/source/control/NotebookbarPopup.cxx b/vcl/source/control/NotebookbarPopup.cxx new file mode 100644 index 000000000..3cc21815a --- /dev/null +++ b/vcl/source/control/NotebookbarPopup.cxx @@ -0,0 +1,161 @@ +/* -*- 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 +#include +#include +#include +#include + +NotebookbarPopup::NotebookbarPopup(const VclPtr& pParent) + : FloatingWindow(pParent, "Popup", "sfx/ui/notebookbarpopup.ui") + , m_pParent(pParent) +{ + m_pUIBuilder->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(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 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 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 000000000..c893cc833 --- /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 +#include +#include + +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(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(pPrioritable); + + if (pWindow && pWindow->GetParent() == this) + { + nCurrentWidth -= pWindow->GetOutputSizePixel().Width() + get_spacing(); + pWindow->Show(); + pPrioritable->HideContent(); + nCurrentWidth += pWindow->GetOutputSizePixel().Width() + 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(*pChildR); + vcl::IPrioritable* pPrioritable = *pChildR; + + if (pWindow->GetParent() != this) + { + pChildR++; + continue; + } + + if (pWindow) + { + nCurrentWidth -= pWindow->GetOutputSizePixel().Width() + 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(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 000000000..65d51cce3 --- /dev/null +++ b/vcl/source/control/PriorityMergedHBox.cxx @@ -0,0 +1,203 @@ +/* -*- 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 +#include +#include +#include +#include +#include +#include + +#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::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->GetOutputSizePixel().Width()) + nCurrentWidth -= pWindow->GetOutputSizePixel().Width(); + 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); + } + + // find max height + for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild; + pChild = pChild->GetWindow(GetWindowType::Next)) + { + Size aChildSize = getLayoutRequisition(*pChild); + setPrimaryDimension(aChildSize, getPrimaryDimension(aSize)); + 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::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/WeldedTabbedNotebookbar.cxx b/vcl/source/control/WeldedTabbedNotebookbar.cxx new file mode 100644 index 000000000..1a3311de9 --- /dev/null +++ b/vcl/source/control/WeldedTabbedNotebookbar.cxx @@ -0,0 +1,23 @@ +/* -*- 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 +#include +#include + +WeldedTabbedNotebookbar::WeldedTabbedNotebookbar( + const VclPtr& pContainerWindow, const OUString& rUIFilePath, + const css::uno::Reference& rFrame, sal_uInt64 nWindowId) + : m_xBuilder(JSInstanceBuilder::CreateNotebookbarBuilder( + pContainerWindow, AllSettings::GetUIRootDir(), rUIFilePath, rFrame, nWindowId)) +{ + m_xContainer = m_xBuilder->weld_container("NotebookBar"); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx new file mode 100644 index 000000000..210d2b629 --- /dev/null +++ b/vcl/source/control/button.cxx @@ -0,0 +1,3826 @@ +/* -*- 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +using namespace css; + +constexpr auto PUSHBUTTON_VIEW_STYLE = WB_3DLOOK | + WB_LEFT | WB_CENTER | WB_RIGHT | + WB_TOP | WB_VCENTER | WB_BOTTOM | + WB_WORDBREAK | WB_NOLABEL | + WB_DEFBUTTON | WB_NOLIGHTBORDER | + WB_RECTSTYLE | WB_SMALLSTYLE | + WB_TOGGLE; +constexpr auto RADIOBUTTON_VIEW_STYLE = WB_3DLOOK | + WB_LEFT | WB_CENTER | WB_RIGHT | + WB_TOP | WB_VCENTER | WB_BOTTOM | + WB_WORDBREAK | WB_NOLABEL; +constexpr auto CHECKBOX_VIEW_STYLE = WB_3DLOOK | + WB_LEFT | WB_CENTER | WB_RIGHT | + WB_TOP | WB_VCENTER | WB_BOTTOM | + WB_WORDBREAK | WB_NOLABEL; + +#define STYLE_RADIOBUTTON_MONO (sal_uInt16(0x0001)) // legacy +#define STYLE_CHECKBOX_MONO (sal_uInt16(0x0001)) // legacy + +class ImplCommonButtonData +{ +public: + ImplCommonButtonData(); + + tools::Rectangle maFocusRect; + tools::Long mnSeparatorX; + DrawButtonFlags mnButtonState; + bool mbSmallSymbol; + bool mbGeneratedTooltip; + + Image maImage; + ImageAlign meImageAlign; + SymbolAlign meSymbolAlign; + + Image maCustomContentImage; + + /** StatusListener. Updates the button as the slot state changes */ + rtl::Reference> mpStatusListener; +}; + +ImplCommonButtonData::ImplCommonButtonData() : mnSeparatorX(0), mnButtonState(DrawButtonFlags::NONE), +mbSmallSymbol(false), mbGeneratedTooltip(false), meImageAlign(ImageAlign::Top), meSymbolAlign(SymbolAlign::LEFT) +{ +} + +Button::Button( WindowType nType ) : + Control( nType ), + mpButtonData( std::make_unique() ) +{ +} + +Button::~Button() +{ + disposeOnce(); +} + +void Button::dispose() +{ + if (mpButtonData->mpStatusListener.is()) + mpButtonData->mpStatusListener->dispose(); + Control::dispose(); +} + +void Button::SetCommandHandler(const OUString& aCommand) +{ + maCommand = aCommand; + SetClickHdl( LINK( this, Button, dispatchCommandHandler) ); + + mpButtonData->mpStatusListener = new VclStatusListener