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 <vcl/weldutils.hxx>
13#include <vcl/event.hxx>
14
15#include <edtwin.hxx>
16
18 SwEditWin* pEditWin, const std::shared_ptr<SwContentControl>& pContentControl)
19 : Control(pEditWin, WB_DIALOGCONTROL)
20 , m_pContentControl(pContentControl)
21{
22 assert(GetParent());
23 assert(dynamic_cast<SwEditWin*>(GetParent()));
24
27 SetParentClipMode(ParentClipMode::NoClip);
29}
30
32
34{
35 m_xPopup->connect_closed(LINK(this, SwContentControlButton, PopupModeEndHdl));
36
37 tools::Rectangle aRect(Point(0, 0), GetSizePixel());
38 weld::Window* pParent = weld::GetPopupParent(*this, aRect);
39 m_xPopup->popup_at_rect(pParent, aRect);
40}
41
43{
44 m_xPopup.reset();
45 m_xPopupBuilder.reset();
46}
47
49{
52}
53
54void SwContentControlButton::CalcPosAndSize(const SwRect& rPortionPaintArea)
55{
56 assert(GetParent());
57
58 Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos());
59 Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize());
60
61 // First calculate the size of the frame around the content control's last portion
62 int nPadding = aBoxSize.Height() / 4;
63 aBoxPos.AdjustX(-nPadding / 2);
64 aBoxPos.AdjustY(-1);
65 aBoxSize.AdjustWidth(nPadding);
66 aBoxSize.AdjustHeight(2);
67
68 m_aFramePixel = tools::Rectangle(aBoxPos, aBoxSize);
69
70 // Then extend the size with the button area
71 aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
72
73 if (aBoxPos != GetPosPixel() || aBoxSize != GetSizePixel())
74 {
75 SetPosSizePixel(aBoxPos, aBoxSize);
76 Invalidate();
77 }
78}
79
81{
83 Invalidate();
84}
85
87{
88 DestroyPopup();
89 Show(false);
90 Invalidate();
91}
92
94{
95 SetMapMode(MapMode(MapUnit::MapPixel));
96
97 Color aLineColor = COL_BLACK;
98 Color aFillColor = aLineColor;
99 aFillColor.IncreaseLuminance(255 * (m_xPopup ? 0.5 : 0.75));
100
101 // Calc the frame around the content control's last portion
102 int nPadding = 1;
103 Point aPos(nPadding, nPadding);
104 Size aSize(m_aFramePixel.GetSize().Width() - nPadding,
105 m_aFramePixel.GetSize().Height() - nPadding);
106 const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize));
107
108 // Draw the button next to the frame
109 Point aButtonPos(aFrameRect.TopLeft());
110 aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - 1);
111 Size aButtonSize(aFrameRect.GetSize());
112 aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getWidth() - nPadding);
113 const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize));
114
115 // Background & border
116 rRenderContext.SetLineColor(aLineColor);
117 rRenderContext.SetFillColor(aFillColor);
118 rRenderContext.DrawRect(aButtonRect);
119
120 // the arrowhead
121 rRenderContext.SetLineColor(aLineColor);
122 rRenderContext.SetFillColor(aLineColor);
123
124 Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2),
125 aButtonPos.Y() + (aButtonSize.Height() / 2));
126 tools::Long nMinWidth = 4;
127 tools::Long nMinHeight = 2;
128 Size aArrowSize(std::max(aButtonSize.Width() / 4, nMinWidth),
129 std::max(aButtonSize.Height() / 10, nMinHeight));
130
131 tools::Polygon aPoly(3);
132 aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0);
133 aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1);
134 aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2);
135 rRenderContext.DrawPolygon(aPoly);
136}
137
139{
140 // We need to check whether the position hits the button (the frame should be mouse transparent)
141 WindowHitTest aResult = Control::ImplHitTest(rFramePos);
142 if (aResult != WindowHitTest::Inside)
143 return aResult;
144 else
145 {
146 return rFramePos.X() >= m_aFramePixel.Right() ? WindowHitTest::Inside
147 : WindowHitTest::Transparent;
148 }
149}
150
151/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void IncreaseLuminance(sal_uInt8 cLumInc)
virtual void dispose() override
void DrawRect(const tools::Rectangle &rRect)
void SetLineColor()
void DrawPolygon(const tools::Polygon &rPoly)
void SetFillColor()
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, const std::shared_ptr< SwContentControl > &pContentControl)
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
virtual ~SwContentControlButton() override
std::unique_ptr< weld::Builder > m_xPopupBuilder
std::unique_ptr< weld::Popover > m_xPopup
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 SetPoint(const Point &rPt, sal_uInt16 nPos)
constexpr Point TopLeft() const
constexpr Size GetSize() const
constexpr tools::Long Right() const
tools::Long getWidth() 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)
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