diff options
author | Tamás Zolnai <tamas.zolnai@collabora.com> | 2019-06-07 17:46:58 +0200 |
---|---|---|
committer | Tamás Zolnai <tamas.zolnai@collabora.com> | 2019-07-12 03:15:59 +0200 |
commit | 1d2fdd443b0d9cb6721400ab97a2073092be724b (patch) | |
tree | 46d00ab91f7423f7fe9861256809f506a0bbf45c /sw | |
parent | a9ce5e5fc5188a0c776ba4cff9d5ac84a2bcd7a5 (diff) |
MSForms: Generalize some parts of the drop-down form field's popup button
We'll need a similar button for the new text-based date field.
Change-Id: I9cf69f98dae3d761d9cddfbaed138d6453af887d
Reviewed-on: https://gerrit.libreoffice.org/75442
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
Tested-by: Tamás Zolnai <tamas.zolnai@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/Library_sw.mk | 1 | ||||
-rw-r--r-- | sw/source/core/crsr/DropDownFormFieldButton.cxx | 122 | ||||
-rw-r--r-- | sw/source/core/crsr/FormFieldButton.cxx | 155 | ||||
-rw-r--r-- | sw/source/core/inc/DropDownFormFieldButton.hxx | 19 | ||||
-rw-r--r-- | sw/source/core/inc/FormFieldButton.hxx | 56 |
5 files changed, 218 insertions, 135 deletions
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index ededa54c689b..15b921947018 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -155,6 +155,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/core/crsr/findcoll \ sw/source/core/crsr/findfmt \ sw/source/core/crsr/findtxt \ + sw/source/core/crsr/FormFieldButton \ sw/source/core/crsr/pam \ sw/source/core/crsr/paminit \ sw/source/core/crsr/swcrsr \ diff --git a/sw/source/core/crsr/DropDownFormFieldButton.cxx b/sw/source/core/crsr/DropDownFormFieldButton.cxx index 158751fe308d..d2c97f382e22 100644 --- a/sw/source/core/crsr/DropDownFormFieldButton.cxx +++ b/sw/source/core/crsr/DropDownFormFieldButton.cxx @@ -8,8 +8,6 @@ */ #include <DropDownFormFieldButton.hxx> -#include <vcl/svapp.hxx> -#include <vcl/settings.hxx> #include <edtwin.hxx> #include <basegfx/color/bcolortools.hxx> #include <viewopt.hxx> @@ -124,132 +122,16 @@ IMPL_LINK(SwFieldDialog, MyListBoxHandler, ListBox&, rBox, void) DropDownFormFieldButton::DropDownFormFieldButton(SwEditWin* pEditWin, sw::mark::DropDownFieldmark& rFieldmark) - : MenuButton(pEditWin, WB_DIALOGCONTROL) - , m_rFieldmark(rFieldmark) + : FormFieldButton(pEditWin, rFieldmark) { - assert(GetParent()); - assert(dynamic_cast<SwEditWin*>(GetParent())); } DropDownFormFieldButton::~DropDownFormFieldButton() { disposeOnce(); } -void DropDownFormFieldButton::dispose() +void DropDownFormFieldButton::InitPopup() { - m_pFieldPopup.disposeAndClear(); - MenuButton::dispose(); -} - -void DropDownFormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea) -{ - assert(GetParent()); - - Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos()); - Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize()); - - // First calculate the size of the frame around the field - int nPadding = aBoxSize.Height() / 4; - aBoxPos.AdjustX(-nPadding); - aBoxPos.AdjustY(-nPadding); - aBoxSize.AdjustWidth(2 * nPadding); - aBoxSize.AdjustHeight(2 * nPadding); - - m_aFieldFramePixel = tools::Rectangle(aBoxPos, aBoxSize); - - // Then extend the size with the button area - aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height()); - - SetPosSizePixel(aBoxPos, aBoxSize); -} - -void DropDownFormFieldButton::MouseButtonUp(const MouseEvent&) -{ - assert(GetParent()); - - Point aPixPos = GetPosPixel(); - aPixPos.AdjustY(GetSizePixel().Height()); - m_pFieldPopup = VclPtr<SwFieldDialog>::Create(static_cast<SwEditWin*>(GetParent()), &m_rFieldmark, GetSizePixel().Width()); - m_pFieldPopup->SetPopupModeEndHdl(LINK(this, DropDownFormFieldButton, FieldPopupModeEndHdl)); - - tools::Rectangle aRect(GetParent()->OutputToScreenPixel(aPixPos), Size(0, 0)); - m_pFieldPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus); - Invalidate(); -} - -IMPL_LINK_NOARG(DropDownFormFieldButton, FieldPopupModeEndHdl, FloatingWindow*, void) -{ - m_pFieldPopup.disposeAndClear(); - m_rFieldmark.Invalidate(); - // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen - Show(false); - Invalidate(); -} - -static basegfx::BColor lcl_GetFillColor(const basegfx::BColor& rLineColor, double aLuminance) -{ - basegfx::BColor aHslLine = basegfx::utils::rgb2hsl(rLineColor); - aHslLine.setZ(aLuminance); - return basegfx::utils::hsl2rgb(aHslLine); -} - -void DropDownFormFieldButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) -{ - SetMapMode(MapMode(MapUnit::MapPixel)); - - //const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); - Color aLineColor = COL_BLACK; - Color aFillColor(lcl_GetFillColor(aLineColor.getBColor(), (m_pFieldPopup ? 0.5 : 0.75))); - - // Draw the frame around the field - // GTK3 backend cuts down the frame's top and left border, to avoid that add a padding around the frame - int nPadding = 1; - Point aPos(nPadding, nPadding); - Size aSize(m_aFieldFramePixel.GetSize().Width() - nPadding, - m_aFieldFramePixel.GetSize().Height() - nPadding); - const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize)); - rRenderContext.SetLineColor(aLineColor); - rRenderContext.SetFillColor(COL_TRANSPARENT); - rRenderContext.DrawRect(aFrameRect); - - // Draw the button next to the frame - Point aButtonPos(aFrameRect.TopLeft()); - aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - 1); - Size aButtonSize(aFrameRect.GetSize()); - aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getWidth() - nPadding); - const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize)); - - // Background & border - rRenderContext.SetLineColor(aLineColor); - rRenderContext.SetFillColor(aFillColor); - rRenderContext.DrawRect(aButtonRect); - - // the arrowhead - rRenderContext.SetLineColor(aLineColor); - rRenderContext.SetFillColor(aLineColor); - - Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2), - aButtonPos.Y() + (aButtonSize.Height() / 2)); - Size aArrowSize(aButtonSize.Width() / 4, aButtonSize.Height() / 10); - - tools::Polygon aPoly(3); - aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0); - aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1); - aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2); - rRenderContext.DrawPolygon(aPoly); -} - -WindowHitTest DropDownFormFieldButton::ImplHitTest(const Point& rFramePos) -{ - // We need to check whether the position hits the button (the frame should be mouse transparent) - WindowHitTest aResult = MenuButton::ImplHitTest(rFramePos); - if (aResult != WindowHitTest::Inside) - return aResult; - else - { - return rFramePos.X() >= m_aFieldFramePixel.Right() ? WindowHitTest::Inside - : WindowHitTest::Transparent; - } } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/core/crsr/FormFieldButton.cxx b/sw/source/core/crsr/FormFieldButton.cxx new file mode 100644 index 000000000000..b69fab1d86d1 --- /dev/null +++ b/sw/source/core/crsr/FormFieldButton.cxx @@ -0,0 +1,155 @@ +/* -*- 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 <DropDownFormFieldButton.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <edtwin.hxx> +#include <basegfx/color/bcolortools.hxx> +#include <viewopt.hxx> +#include <bookmrk.hxx> +#include <vcl/floatwin.hxx> +#include <vcl/event.hxx> +#include <vcl/lstbox.hxx> +#include <IMark.hxx> +#include <view.hxx> +#include <docsh.hxx> +#include <strings.hrc> + +FormFieldButton::FormFieldButton(SwEditWin* pEditWin, sw::mark::Fieldmark& rFieldmark) + : MenuButton(pEditWin, WB_DIALOGCONTROL) + , m_rFieldmark(rFieldmark) +{ + assert(GetParent()); + assert(dynamic_cast<SwEditWin*>(GetParent())); +} + +FormFieldButton::~FormFieldButton() { disposeOnce(); } + +void FormFieldButton::dispose() +{ + m_pFieldPopup.disposeAndClear(); + MenuButton::dispose(); +} + +void FormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea) +{ + assert(GetParent()); + + Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos()); + Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize()); + + // First calculate the size of the frame around the field + int nPadding = aBoxSize.Height() / 4; + aBoxPos.AdjustX(-nPadding); + aBoxPos.AdjustY(-nPadding); + aBoxSize.AdjustWidth(2 * nPadding); + aBoxSize.AdjustHeight(2 * nPadding); + + m_aFieldFramePixel = tools::Rectangle(aBoxPos, aBoxSize); + + // Then extend the size with the button area + aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height()); + + SetPosSizePixel(aBoxPos, aBoxSize); +} + +void FormFieldButton::MouseButtonUp(const MouseEvent&) +{ + assert(GetParent()); + + Point aPixPos = GetPosPixel(); + aPixPos.AdjustY(GetSizePixel().Height()); + + // sets m_pFieldPopup + InitPopup(); + + m_pFieldPopup->SetPopupModeEndHdl(LINK(this, DropDownFormFieldButton, FieldPopupModeEndHdl)); + + tools::Rectangle aRect(GetParent()->OutputToScreenPixel(aPixPos), Size(0, 0)); + m_pFieldPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus); + Invalidate(); +} + +IMPL_LINK_NOARG(FormFieldButton, FieldPopupModeEndHdl, FloatingWindow*, void) +{ + m_pFieldPopup.disposeAndClear(); + m_rFieldmark.Invalidate(); + // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen + Show(false); + Invalidate(); +} + +static basegfx::BColor lcl_GetFillColor(const basegfx::BColor& rLineColor, double aLuminance) +{ + basegfx::BColor aHslLine = basegfx::utils::rgb2hsl(rLineColor); + aHslLine.setZ(aLuminance); + return basegfx::utils::hsl2rgb(aHslLine); +} + +void FormFieldButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) +{ + SetMapMode(MapMode(MapUnit::MapPixel)); + + //const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); + Color aLineColor = COL_BLACK; + Color aFillColor(lcl_GetFillColor(aLineColor.getBColor(), (m_pFieldPopup ? 0.5 : 0.75))); + + // Draw the frame around the field + // GTK3 backend cuts down the frame's top and left border, to avoid that add a padding around the frame + int nPadding = 1; + Point aPos(nPadding, nPadding); + Size aSize(m_aFieldFramePixel.GetSize().Width() - nPadding, + m_aFieldFramePixel.GetSize().Height() - nPadding); + const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize)); + rRenderContext.SetLineColor(aLineColor); + rRenderContext.SetFillColor(COL_TRANSPARENT); + rRenderContext.DrawRect(aFrameRect); + + // Draw the button next to the frame + Point aButtonPos(aFrameRect.TopLeft()); + aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - 1); + Size aButtonSize(aFrameRect.GetSize()); + aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getWidth() - nPadding); + const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize)); + + // Background & border + rRenderContext.SetLineColor(aLineColor); + rRenderContext.SetFillColor(aFillColor); + rRenderContext.DrawRect(aButtonRect); + + // the arrowhead + rRenderContext.SetLineColor(aLineColor); + rRenderContext.SetFillColor(aLineColor); + + Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2), + aButtonPos.Y() + (aButtonSize.Height() / 2)); + Size aArrowSize(aButtonSize.Width() / 4, aButtonSize.Height() / 10); + + tools::Polygon aPoly(3); + aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0); + aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1); + aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2); + rRenderContext.DrawPolygon(aPoly); +} + +WindowHitTest FormFieldButton::ImplHitTest(const Point& rFramePos) +{ + // We need to check whether the position hits the button (the frame should be mouse transparent) + WindowHitTest aResult = MenuButton::ImplHitTest(rFramePos); + if (aResult != WindowHitTest::Inside) + return aResult; + else + { + return rFramePos.X() >= m_aFieldFramePixel.Right() ? WindowHitTest::Inside + : WindowHitTest::Transparent; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/core/inc/DropDownFormFieldButton.hxx b/sw/source/core/inc/DropDownFormFieldButton.hxx index 1147f59dfc9b..ab1004cc8119 100644 --- a/sw/source/core/inc/DropDownFormFieldButton.hxx +++ b/sw/source/core/inc/DropDownFormFieldButton.hxx @@ -12,6 +12,7 @@ #include <vcl/menubtn.hxx> #include <swrect.hxx> +#include "FormFieldButton.hxx" class SwEditWin; class FloatingWindow; @@ -24,28 +25,16 @@ class DropDownFieldmark; } /** - * This button is shown when the cursor is in a drop-down form field. + * This button is shown when the cursor is on a drop-down form field. * The user can select an item of the field using this button while filling in a form. */ -class DropDownFormFieldButton : public MenuButton +class DropDownFormFieldButton : public FormFieldButton { public: DropDownFormFieldButton(SwEditWin* pEditWin, sw::mark::DropDownFieldmark& rFieldMark); virtual ~DropDownFormFieldButton() override; - virtual void dispose() override; - void CalcPosAndSize(const SwRect& rPortionPaintArea); - - virtual void MouseButtonUp(const MouseEvent& rMEvt) override; - DECL_LINK(FieldPopupModeEndHdl, FloatingWindow*, void); - - virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; - virtual WindowHitTest ImplHitTest(const Point& rFramePos) override; - -private: - tools::Rectangle m_aFieldFramePixel; - sw::mark::DropDownFieldmark& m_rFieldmark; - VclPtr<FloatingWindow> m_pFieldPopup; + virtual void InitPopup() override; }; #endif diff --git a/sw/source/core/inc/FormFieldButton.hxx b/sw/source/core/inc/FormFieldButton.hxx new file mode 100644 index 000000000000..987d86d15d70 --- /dev/null +++ b/sw/source/core/inc/FormFieldButton.hxx @@ -0,0 +1,56 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_SW_SOURCE_CORE_TEXT_FORMEFIELDBUTTO_HXX +#define INCLUDED_SW_SOURCE_CORE_TEXT_FORMEFIELDBUTTO_HXX + +#include <vcl/menubtn.hxx> +#include <swrect.hxx> + +class SwEditWin; +class FloatingWindow; +namespace sw +{ +namespace mark +{ +class Fieldmark; +} +} // namespace sw + +/** + * This button is shown when the cursor is on a form field with drop-down capability. + */ +class FormFieldButton : public MenuButton +{ +public: + FormFieldButton(SwEditWin* pEditWin, sw::mark::Fieldmark& rFieldMark); + virtual ~FormFieldButton() override; + virtual void dispose() override; + + void CalcPosAndSize(const SwRect& rPortionPaintArea); + + virtual void MouseButtonUp(const MouseEvent& rMEvt) override; + DECL_LINK(FieldPopupModeEndHdl, FloatingWindow*, void); + + virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; + virtual WindowHitTest ImplHitTest(const Point& rFramePos) override; + + virtual void InitPopup() = 0; + +private: + tools::Rectangle m_aFieldFramePixel; + +protected: + sw::mark::Fieldmark& m_rFieldmark; + VclPtr<FloatingWindow> m_pFieldPopup; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |