LibreOffice Module sw (master) 1
FormFieldButton.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
11#include <edtwin.hxx>
13#include <bookmark.hxx>
14#include <vcl/weldutils.hxx>
15#include <vcl/event.hxx>
16
18 : Control(pEditWin, WB_DIALOGCONTROL)
19 , m_rFieldmark(rFieldmark)
20{
21 assert(GetParent());
22 assert(dynamic_cast<SwEditWin*>(GetParent()));
23
26 SetParentClipMode(ParentClipMode::NoClip);
28}
29
31
33{
34 m_xFieldPopup->connect_closed(LINK(this, DropDownFormFieldButton, FieldPopupModeEndHdl));
35
36 tools::Rectangle aRect(Point(0, 0), GetSizePixel());
37 weld::Window* pParent = weld::GetPopupParent(*this, aRect);
38 m_xFieldPopup->popup_at_rect(pParent, aRect);
39}
40
42{
43 m_xFieldPopup.reset();
45}
46
48{
51}
52
53void FormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea)
54{
55 assert(GetParent());
56
57 Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos());
58 Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize());
59
60 // First calculate the size of the frame around the field
61 int nPadding = aBoxSize.Height() / 4;
62 aBoxPos.AdjustX(-nPadding);
63 aBoxPos.AdjustY(-nPadding);
64 aBoxSize.AdjustWidth(2 * nPadding);
65 aBoxSize.AdjustHeight(2 * nPadding);
66
67 m_aFieldFramePixel = tools::Rectangle(aBoxPos, aBoxSize);
68
69 // Then extend the size with the button area
70 aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
71
72 if (aBoxPos != GetPosPixel() || aBoxSize != GetSizePixel())
73 {
74 SetPosSizePixel(aBoxPos, aBoxSize);
75 Invalidate();
76 }
77}
78
80{
82 Invalidate();
83}
84
85IMPL_LINK_NOARG(FormFieldButton, FieldPopupModeEndHdl, weld::Popover&, void)
86{
87 DestroyPopup();
88 m_rFieldmark.Invalidate();
89 // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen
90 Show(false);
91 Invalidate();
92}
93
94static basegfx::BColor lcl_GetFillColor(const basegfx::BColor& rLineColor, double aLuminance)
95{
96 basegfx::BColor aHslLine = basegfx::utils::rgb2hsl(rLineColor);
97 aHslLine.setZ(aLuminance);
98 return basegfx::utils::hsl2rgb(aHslLine);
99}
100
102{
103 SetMapMode(MapMode(MapUnit::MapPixel));
104
105 //const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
106 Color aLineColor = COL_BLACK;
107 Color aFillColor(lcl_GetFillColor(aLineColor.getBColor(), (m_xFieldPopup ? 0.5 : 0.75)));
108
109 // Draw the frame around the field
110 // GTK3 backend cuts down the frame's top and left border, to avoid that add a padding around the frame
111 int nPadding = 1;
112 Point aPos(nPadding, nPadding);
113 Size aSize(m_aFieldFramePixel.GetSize().Width() - nPadding,
114 m_aFieldFramePixel.GetSize().Height() - nPadding);
115 const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize));
116 rRenderContext.SetLineColor(aLineColor);
117 rRenderContext.SetFillColor(COL_TRANSPARENT);
118 rRenderContext.DrawRect(aFrameRect);
119
120 // Draw the button next to the frame
121 Point aButtonPos(aFrameRect.TopLeft());
122 aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - 1);
123 Size aButtonSize(aFrameRect.GetSize());
124 aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getOpenWidth() - nPadding);
125 const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize));
126
127 // Background & border
128 rRenderContext.SetLineColor(aLineColor);
129 rRenderContext.SetFillColor(aFillColor);
130 rRenderContext.DrawRect(aButtonRect);
131
132 // the arrowhead
133 rRenderContext.SetLineColor(aLineColor);
134 rRenderContext.SetFillColor(aLineColor);
135
136 Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2),
137 aButtonPos.Y() + (aButtonSize.Height() / 2));
138 Size aArrowSize(aButtonSize.Width() / 4, aButtonSize.Height() / 10);
139
140 tools::Polygon aPoly(3);
141 aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0);
142 aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1);
143 aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2);
144 rRenderContext.DrawPolygon(aPoly);
145}
146
148{
149 // We need to check whether the position hits the button (the frame should be mouse transparent)
150 WindowHitTest aResult = Control::ImplHitTest(rFramePos);
151 if (aResult != WindowHitTest::Inside)
152 return aResult;
153 else
154 {
155 return rFramePos.X() >= m_aFieldFramePixel.Right() ? WindowHitTest::Inside
156 : WindowHitTest::Transparent;
157 }
158}
159
160/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
IMPL_LINK_NOARG(FormFieldButton, FieldPopupModeEndHdl, weld::Popover &, void)
static basegfx::BColor lcl_GetFillColor(const basegfx::BColor &rLineColor, double aLuminance)
basegfx::BColor getBColor() const
virtual void dispose() override
This button is shown when the cursor is on a drop-down form field.
This button is shown when the cursor is on a form field with drop-down capability.
void CalcPosAndSize(const SwRect &rPortionPaintArea)
std::unique_ptr< weld::Popover > m_xFieldPopup
virtual void dispose() override
virtual WindowHitTest ImplHitTest(const Point &rFramePos) override
virtual void DestroyPopup()
tools::Rectangle m_aFieldFramePixel
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
FormFieldButton(SwEditWin *pEditWin, sw::mark::Fieldmark &rFieldMark)
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
virtual void LaunchPopup()
std::unique_ptr< weld::Builder > m_xFieldPopupBuilder
virtual ~FormFieldButton() override
void DrawRect(const tools::Rectangle &rRect)
void SetLineColor()
void DrawPolygon(const tools::Polygon &rPoly)
void SetFillColor()
constexpr tools::Long Y() const
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
constexpr tools::Long getWidth() const
void setWidth(tools::Long nWidth)
tools::Long AdjustWidth(tools::Long n)
constexpr tools::Long Width() const
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:61
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Pos(const Point &rNew)
Definition: swrect.hxx:171
void SSize(const Size &rNew)
Definition: swrect.hxx:180
void setZ(TYPE fZ)
void SetPoint(const Point &rPt, sal_uInt16 nPos)
constexpr Point TopLeft() const
constexpr Size GetSize() const
constexpr tools::Long Right() const
tools::Long getOpenWidth() const
vcl::Window * GetParent() const
Point LogicToPixel(const Point &rLogicPt) const
void SetParentClipMode(ParentClipMode nMode=ParentClipMode::NONE)
virtual Point GetPosPixel() const
void SetMapMode()
virtual Size GetSizePixel() const
virtual WindowHitTest ImplHitTest(const Point &rFramePos)
void SetPaintTransparent(bool bTransparent)
void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
void EnableChildTransparentMode(bool bEnable=true)
void SetBackground()
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
BColor rgb2hsl(const BColor &rRGBColor)
BColor hsl2rgb(const BColor &rHSLColor)
weld::Window * GetPopupParent(vcl::Window &rOutWin, tools::Rectangle &rRect)
WindowHitTest
WinBits const WB_DIALOGCONTROL