LibreOffice Module sw (master) 1
contentcontrolbutton.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
12#include <utility>
13#include <vcl/weldutils.hxx>
14#include <vcl/event.hxx>
15#include <vcl/decoview.hxx>
16
17#include <edtwin.hxx>
18#include <dview.hxx>
19
21 std::shared_ptr<SwContentControl> pContentControl)
22 : Control(pEditWin, WB_DIALOGCONTROL)
23 , m_pContentControl(std::move(pContentControl))
24{
25 assert(GetParent());
26 assert(dynamic_cast<SwEditWin*>(GetParent()));
27
30 SetParentClipMode(ParentClipMode::NoClip);
32}
33
35
37{
38 m_xPopup->connect_closed(LINK(this, SwContentControlButton, PopupModeEndHdl));
39
40 tools::Rectangle aRect(Point(0, 0), GetSizePixel());
41 weld::Window* pParent = weld::GetPopupParent(*this, aRect);
42 m_xPopup->popup_at_rect(pParent, aRect);
43}
44
46{
47 m_xPopup.reset();
48 m_xPopupBuilder.reset();
49}
50
52{
55}
56
57void SwContentControlButton::CalcPosAndSize(const SwRect& rPortionPaintArea)
58{
59 assert(GetParent());
60
61 Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos());
62 Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize());
63
64 // First calculate the size of the frame around the content control's last portion
65 int nPadding = aBoxSize.Height() / 4;
66 aBoxPos.AdjustX(-nPadding / 2);
67 aBoxPos.AdjustY(-1);
68 aBoxSize.AdjustWidth(nPadding);
69 aBoxSize.AdjustHeight(2);
70
71 m_aFramePixel = tools::Rectangle(aBoxPos, aBoxSize);
72
73 // Then extend the size with the button area
74 if (m_bRTL)
75 {
76 aBoxPos.AdjustX(-GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
77 }
78 aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
79
80 if (aBoxPos != GetPosPixel() || aBoxSize != GetSizePixel())
81 {
82 SetPosSizePixel(aBoxPos, aBoxSize);
83 Invalidate();
84 }
85}
86
88
90{
92 Invalidate();
93}
94
96{
97 DestroyPopup();
98 Show(false);
99 Invalidate();
100}
101
103{
104 SetMapMode(MapMode(MapUnit::MapPixel));
105
106 Color aLineColor = COL_BLACK;
107 Color aFillColor = aLineColor;
108 aFillColor.IncreaseLuminance(255 * (m_xPopup ? 0.5 : 0.75));
109
110 // Calc the frame around the content control's last portion
111 int nPadding = 1;
112 Point aPos(nPadding, nPadding);
113 Size aSize(m_aFramePixel.GetSize().Width() - nPadding,
114 m_aFramePixel.GetSize().Height() - nPadding);
115 const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize));
116
117 // Draw the button next to the frame
118 Point aButtonPos(aFrameRect.TopLeft());
119 if (m_bRTL)
120 {
121 aButtonPos.AdjustX(nPadding * 2);
122 }
123 else
124 {
125 aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - nPadding * 2);
126 }
127 Size aButtonSize(aFrameRect.GetSize());
128 aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getOpenWidth() - nPadding);
129 const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize));
130
131 // Background & border
132 rRenderContext.SetLineColor(aLineColor);
133 rRenderContext.SetFillColor(aFillColor);
134 rRenderContext.DrawRect(aButtonRect);
135
136 // the arrowhead
137 DecorationView aDecoView(&rRenderContext);
138 tools::Rectangle aSymbolRect(aButtonRect);
139 // 20% distance to the left and right button border
140 const tools::Long nBorderDistanceLeftAndRight = aSymbolRect.GetWidth() / 4;
141 aSymbolRect.AdjustLeft(nBorderDistanceLeftAndRight);
142 aSymbolRect.AdjustRight(-nBorderDistanceLeftAndRight);
143 // 20% distance to the top and bottom button border
144 const tools::Long nBorderDistanceTopAndBottom = aSymbolRect.GetHeight() / 4;
145 aSymbolRect.AdjustTop(nBorderDistanceTopAndBottom);
146 aSymbolRect.AdjustBottom(-nBorderDistanceTopAndBottom);
147 AntialiasingFlags eAntialiasing = rRenderContext.GetAntialiasing();
149 {
150 rRenderContext.SetAntialiasing(eAntialiasing | AntialiasingFlags::Enable);
151 }
152 aDecoView.DrawSymbol(aSymbolRect, SymbolType::SPIN_DOWN, GetTextColor(), DrawSymbolFlags::NONE);
154 {
155 rRenderContext.SetAntialiasing(eAntialiasing);
156 }
157}
158
160{
161 // We need to check whether the position hits the button (the frame should be mouse transparent)
162 WindowHitTest aResult = Control::ImplHitTest(rFramePos);
163 if (aResult != WindowHitTest::Inside)
164 return aResult;
165 else
166 {
167 if (m_bRTL)
168 {
169 return rFramePos.X() <= m_aFramePixel.Left() ? WindowHitTest::Inside
170 : WindowHitTest::Transparent;
171 }
172 return rFramePos.X() >= m_aFramePixel.Right() ? WindowHitTest::Inside
173 : WindowHitTest::Transparent;
174 }
175}
176
177/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AntialiasingFlags
void IncreaseLuminance(sal_uInt8 cLumInc)
virtual void dispose() override
void DrawSymbol(const tools::Rectangle &rRect, SymbolType eType, const Color &rColor, DrawSymbolFlags nStyle=DrawSymbolFlags::NONE)
void SetAntialiasing(AntialiasingFlags nMode)
void DrawRect(const tools::Rectangle &rRect)
void SetLineColor()
void SetFillColor()
AntialiasingFlags GetAntialiasing() 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
This button is shown when the cursor is inside a content control with drop-down capability.
virtual void dispose() override
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
virtual WindowHitTest ImplHitTest(const Point &rFramePos) override
void CalcPosAndSize(const SwRect &rPortionPaintArea)
SwContentControlButton(SwEditWin *pEditWin, std::shared_ptr< SwContentControl > pContentControl)
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
virtual ~SwContentControlButton() override
void StartPopup()
Shared MouseButtonDown() and KeyInput() code.
std::unique_ptr< weld::Builder > m_xPopupBuilder
std::unique_ptr< weld::Popover > m_xPopup
static bool IsAntiAliasing()
Definition: dview.cxx:130
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
constexpr tools::Long GetWidth() const
constexpr Point TopLeft() const
constexpr Size GetSize() const
constexpr tools::Long Right() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr tools::Long GetHeight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
tools::Long getOpenWidth() const
constexpr tools::Long Left() const
vcl::Window * GetParent() const
Point LogicToPixel(const Point &rLogicPt) const
void SetParentClipMode(ParentClipMode nMode=ParentClipMode::NONE)
virtual Point GetPosPixel() const
void SetMapMode()
const Color & GetTextColor() const
virtual Size GetSizePixel() const
virtual WindowHitTest ImplHitTest(const Point &rFramePos)
void SetPaintTransparent(bool bTransparent)
virtual 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)
IMPL_LINK_NOARG(SwContentControlButton, PopupModeEndHdl, weld::Popover &, void)
long Long
weld::Window * GetPopupParent(vcl::Window &rOutWin, tools::Rectangle &rRect)
WindowHitTest
WinBits const WB_DIALOGCONTROL