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 <vcl/svapp.hxx>
12 #include <vcl/settings.hxx>
13 #include <edtwin.hxx>
15 #include <viewopt.hxx>
16 #include <bookmrk.hxx>
17 #include <vcl/floatwin.hxx>
18 #include <vcl/event.hxx>
19 #include <vcl/lstbox.hxx>
20 #include <IMark.hxx>
21 #include <view.hxx>
22 #include <docsh.hxx>
23 #include <strings.hrc>
24 
26  : MenuButton(pEditWin, WB_DIALOGCONTROL)
27  , m_rFieldmark(rFieldmark)
28 {
29  assert(GetParent());
30  assert(dynamic_cast<SwEditWin*>(GetParent()));
31 }
32 
34 
36 {
39 }
40 
41 void FormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea)
42 {
43  assert(GetParent());
44 
45  Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos());
46  Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize());
47 
48  // First calculate the size of the frame around the field
49  int nPadding = aBoxSize.Height() / 4;
50  aBoxPos.AdjustX(-nPadding);
51  aBoxPos.AdjustY(-nPadding);
52  aBoxSize.AdjustWidth(2 * nPadding);
53  aBoxSize.AdjustHeight(2 * nPadding);
54 
55  m_aFieldFramePixel = tools::Rectangle(aBoxPos, aBoxSize);
56 
57  // Then extend the size with the button area
58  aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
59 
60  SetPosSizePixel(aBoxPos, aBoxSize);
61 }
62 
64 {
65  assert(GetParent());
66 
67  Point aPixPos = GetPosPixel();
68  aPixPos.AdjustY(GetSizePixel().Height());
69 
70  // sets m_pFieldPopup
71  InitPopup();
72 
73  m_pFieldPopup->SetPopupModeEndHdl(LINK(this, DropDownFormFieldButton, FieldPopupModeEndHdl));
74 
75  tools::Rectangle aRect(GetParent()->OutputToScreenPixel(aPixPos), Size(0, 0));
76  m_pFieldPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus);
77  Invalidate();
78 }
79 
80 IMPL_LINK_NOARG(FormFieldButton, FieldPopupModeEndHdl, FloatingWindow*, void)
81 {
82  m_pFieldPopup.disposeAndClear();
83  m_rFieldmark.Invalidate();
84  // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen
85  Show(false);
86  Invalidate();
87 }
88 
89 static basegfx::BColor lcl_GetFillColor(const basegfx::BColor& rLineColor, double aLuminance)
90 {
91  basegfx::BColor aHslLine = basegfx::utils::rgb2hsl(rLineColor);
92  aHslLine.setZ(aLuminance);
93  return basegfx::utils::hsl2rgb(aHslLine);
94 }
95 
97 {
98  SetMapMode(MapMode(MapUnit::MapPixel));
99 
100  //const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
101  Color aLineColor = COL_BLACK;
102  Color aFillColor(lcl_GetFillColor(aLineColor.getBColor(), (m_pFieldPopup ? 0.5 : 0.75)));
103 
104  // Draw the frame around the field
105  // GTK3 backend cuts down the frame's top and left border, to avoid that add a padding around the frame
106  int nPadding = 1;
107  Point aPos(nPadding, nPadding);
108  Size aSize(m_aFieldFramePixel.GetSize().Width() - nPadding,
109  m_aFieldFramePixel.GetSize().Height() - nPadding);
110  const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize));
111  rRenderContext.SetLineColor(aLineColor);
112  rRenderContext.SetFillColor(COL_TRANSPARENT);
113  rRenderContext.DrawRect(aFrameRect);
114 
115  // Draw the button next to the frame
116  Point aButtonPos(aFrameRect.TopLeft());
117  aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - 1);
118  Size aButtonSize(aFrameRect.GetSize());
119  aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getWidth() - nPadding);
120  const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize));
121 
122  // Background & border
123  rRenderContext.SetLineColor(aLineColor);
124  rRenderContext.SetFillColor(aFillColor);
125  rRenderContext.DrawRect(aButtonRect);
126 
127  // the arrowhead
128  rRenderContext.SetLineColor(aLineColor);
129  rRenderContext.SetFillColor(aLineColor);
130 
131  Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2),
132  aButtonPos.Y() + (aButtonSize.Height() / 2));
133  Size aArrowSize(aButtonSize.Width() / 4, aButtonSize.Height() / 10);
134 
135  tools::Polygon aPoly(3);
136  aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0);
137  aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1);
138  aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2);
139  rRenderContext.DrawPolygon(aPoly);
140 }
141 
143 {
144  // We need to check whether the position hits the button (the frame should be mouse transparent)
145  WindowHitTest aResult = MenuButton::ImplHitTest(rFramePos);
146  if (aResult != WindowHitTest::Inside)
147  return aResult;
148  else
149  {
150  return rFramePos.X() >= m_aFieldFramePixel.Right() ? WindowHitTest::Inside
151  : WindowHitTest::Transparent;
152  }
153 }
154 
155 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
virtual Point GetPosPixel() const
long Width() const
void StartPopupMode(const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
BColor rgb2hsl(const BColor &rRGBColor)
void SetPopupModeEndHdl(const Link< FloatingWindow *, void > &rLink)
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
WindowHitTest
long AdjustWidth(long n)
long AdjustX(long nHorzMove)
long Height() const
virtual WindowHitTest ImplHitTest(const Point &rFramePos)
virtual void dispose() override
void DrawPolygon(const tools::Polygon &rPoly)
virtual Size GetSizePixel() const
virtual WindowHitTest ImplHitTest(const Point &rFramePos) override
void Pos(const Point &rNew)
Definition: swrect.hxx:167
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
long AdjustHeight(long n)
void SetMapMode()
static basegfx::BColor lcl_GetFillColor(const basegfx::BColor &rLineColor, double aLuminance)
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
long Right() const
VclPtr< FloatingWindow > m_pFieldPopup
virtual void InitPopup()=0
void DrawRect(const tools::Rectangle &rRect)
This button is shown when the cursor is on a form field with drop-down capability.
BColor hsl2rgb(const BColor &rHSLColor)
WinBits const WB_DIALOGCONTROL
void SetLineColor()
long AdjustY(long nVertMove)
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
void CalcPosAndSize(const SwRect &rPortionPaintArea)
tools::Rectangle m_aFieldFramePixel
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
void SetFillColor()
void SSize(const Size &rNew)
Definition: swrect.hxx:176
virtual void MouseButtonUp(const MouseEvent &rMEvt) override
vcl::Window * GetParent() const
long X() const
virtual ~FormFieldButton() override
Size GetSize() const
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Point LogicToPixel(const Point &rLogicPt) const
virtual void dispose() override
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
FormFieldButton(SwEditWin *pEditWin, sw::mark::Fieldmark &rFieldMark)
basegfx::BColor getBColor() const
Point OutputToScreenPixel(const Point &rPos) const
long getWidth() const
void setWidth(long nWidth)
void setZ(double fZ)
long Y() const
IMPL_LINK_NOARG(FormFieldButton, FieldPopupModeEndHdl, FloatingWindow *, void)
This button is shown when the cursor is on a drop-down form field.