LibreOffice Module sc (master) 1
dpcontrol.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <dpcontrol.hxx>
21
22#include <vcl/outdev.hxx>
23#include <vcl/settings.hxx>
24#include <comphelper/lok.hxx>
25#include <scitems.hxx>
26#include <document.hxx>
27#include <docpool.hxx>
28#include <patattr.hxx>
29#include <svtools/colorcfg.hxx>
30
31ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomY, ScDocument* pDoc) :
32 mpDoc(pDoc),
33 mpOutDev(pOutDev),
34 mpStyle(pStyle),
35 mnToggleIndent(0),
36 mbBaseButton(true),
37 mbPopupButton(false),
38 mbPopupButtonMulti(false),
39 mbToggleButton(false),
40 mbToggleCollapse(false),
41 mbHasHiddenMember(false),
42 mbPopupPressed(false),
43 mbPopupLeft(false)
44{
45 if (pZoomY)
46 maZoomY = *pZoomY;
47 else
48 maZoomY = Fraction(1, 1);
49}
50
52{
53}
54
55void ScDPFieldButton::setText(const OUString& rText)
56{
57 maText = rText;
58}
59
60void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL)
61{
62 maPos = rPos;
63 maSize = rSize;
64 if (bLayoutRTL)
65 {
66 // rPos is the logical-left position, adjust maPos to visual-left (inside the cell border)
67 maPos.AdjustX( -(maSize.Width() - 1) );
68 }
69}
70
72{
73 mbBaseButton = b;
74}
75
77{
78 mbPopupButton = b;
79}
80
82{
84}
85
86void ScDPFieldButton::setDrawToggleButton(bool b, bool bCollapse, sal_Int32 nIndent)
87{
89 mbToggleCollapse = bCollapse;
90 mnToggleIndent = nIndent;
91}
92
94{
96}
97
99{
100 mbPopupPressed = b;
101}
102
104{
105 mbPopupLeft = b;
106}
107
109{
110 bool bOldMapEnabled = mpOutDev->IsMapModeEnabled();
111
112 if (mpOutDev->GetMapMode().GetMapUnit() != MapUnit::MapPixel)
113 mpOutDev->EnableMapMode(false);
114
115 if (mbBaseButton)
116 {
117 // Background
119 mpOutDev->SetLineColor(mpStyle->GetFaceColor());
120 mpOutDev->SetFillColor(mpStyle->GetFaceColor());
121 mpOutDev->DrawRect(aRect);
122
123 // Border lines
124 mpOutDev->SetLineColor(mpStyle->GetLightColor());
125 mpOutDev->DrawLine(maPos, Point(maPos.X(), maPos.Y()+maSize.Height()-1));
126 mpOutDev->DrawLine(maPos, Point(maPos.X()+maSize.Width()-1, maPos.Y()));
127
128 mpOutDev->SetLineColor(mpStyle->GetShadowColor());
129 mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
130 Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
131 mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
132 Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
133
134 // Field name.
135 // Get the font and size the same way as in scenario selection (lcl_DrawOneFrame in gridwin4.cxx)
136 vcl::Font aTextFont( mpStyle->GetAppFont() );
137 if ( mpDoc )
138 {
139 // use ScPatternAttr::GetFont only for font size
140 vcl::Font aAttrFont;
141 mpDoc->GetPool()->GetDefaultItem(ATTR_PATTERN).fillFontOnly(aAttrFont, mpOutDev, &maZoomY);
142 aTextFont.SetFontSize(aAttrFont.GetFontSize());
143 }
144 mpOutDev->SetFont(aTextFont);
145 mpOutDev->SetTextColor(mpStyle->GetButtonTextColor());
146
147 Point aTextPos = maPos;
148 tools::Long nTHeight = mpOutDev->GetTextHeight();
149 aTextPos.setX(maPos.getX() + 2); // 2 = Margin
150 aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
151
153 mpOutDev->IntersectClipRegion(aRect);
154 mpOutDev->DrawText(aTextPos, maText);
155 mpOutDev->Pop();
156 }
157
160
161 if (mbToggleButton)
163
164 mpOutDev->EnableMapMode(bOldMapEnabled);
165}
166
168{
169 float fScaleFactor = mpOutDev->GetDPIScaleFactor();
170
171 tools::Long nMaxSize = 18 * fScaleFactor; // Button max size in either dimension
172
173 tools::Long nW = std::min(maSize.getWidth() / 2, nMaxSize);
174 tools::Long nH = std::min(maSize.getHeight(), nMaxSize);
175
176 double fZoom = static_cast<double>(maZoomY) > 1.0 ? static_cast<double>(maZoomY) : 1.0;
177 if (fZoom > 1.0)
178 {
179 nW = fZoom * (nW - 1);
180 nH = fZoom * (nH - 1);
181 }
182
183 // #i114944# AutoFilter button is left-aligned in RTL.
184 // DataPilot button is always right-aligned for now, so text output isn't affected.
185 if (mbPopupLeft)
186 rPos.setX(maPos.getX());
187 else
188 rPos.setX(maPos.getX() + maSize.getWidth() - nW);
189
190 rPos.setY(maPos.getY() + maSize.getHeight() - nH);
191 rSize.setWidth(nW);
192 rSize.setHeight(nH);
193}
194
196{
197 const float fScaleFactor = mpOutDev->GetDPIScaleFactor();
198
199 tools::Long nMaxSize = 13 * fScaleFactor; // Button max size in either dimension
200 tools::Long nMargin = 3 * fScaleFactor;
201
203 tools::Long nW = std::min(maSize.getWidth() / 2, nMaxSize);
204 tools::Long nH = std::min(maSize.getHeight(), nMaxSize);
205 nIndent = std::min(nIndent, maSize.getWidth());
206
207 double fZoom = static_cast<double>(maZoomY) > 1.0 ? static_cast<double>(maZoomY) : 1.0;
208 if (fZoom > 1.0)
209 {
210 nW = fZoom * (nW - 1);
211 nH = fZoom * (nH - 1);
212 nIndent = fZoom * (nIndent -1);
213 nMargin = fZoom * (nMargin - 1);
214 }
215
216 // FIXME: RTL case ?
217 rPos.setX(maPos.getX() + nIndent - nW + nMargin);
218 rPos.setY(maPos.getY() + maSize.getHeight() / 2 - nH / 2 + nMargin);
219 rSize.setWidth(nW - nMargin - 1);
220 rSize.setHeight(nH - nMargin - 1);
221}
222
224{
225 Point aPos;
226 Size aSize;
227 getPopupBoundingBox(aPos, aSize);
228
229 float fScaleFactor = mpOutDev->GetDPIScaleFactor();
230
231 // Button background color
232 Color aFaceColor = mpStyle->GetFaceColor();
233 Color aBackgroundColor
235 : mbPopupPressed ? mpStyle->GetShadowColor() : aFaceColor;
236
237 // Button line color
238 mpOutDev->SetLineColor(mpStyle->GetLabelTextColor());
239 // If the document background is light and face color is dark, use ShadowColor instead
241 if (aDocColor.IsBright() && aFaceColor.IsDark())
242 mpOutDev->SetLineColor(mpStyle->GetShadowColor());
243
244 mpOutDev->SetFillColor(aBackgroundColor);
245 mpOutDev->DrawRect(tools::Rectangle(aPos, aSize));
246
247 // the arrowhead
249 // FIXME: HACK: The following DrawPolygon draws twice in lok rtl mode for some reason.
250 // => one at the correct location with fill (possibly no outline)
251 // => and the other at an x offset with outline and without fill
252 // eg. Replacing this with a DrawRect() does not have any such problems.
253 comphelper::LibreOfficeKit::isActive() ? mpOutDev->SetLineColor() : mpOutDev->SetLineColor(aArrowColor);
254 mpOutDev->SetFillColor(aArrowColor);
255
256 Point aCenter(aPos.X() + (aSize.Width() / 2), aPos.Y() + (aSize.Height() / 2));
257
258 Size aArrowSize(4 * fScaleFactor, 2 * fScaleFactor);
259
260 tools::Polygon aPoly(3);
261 aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0);
262 aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1);
263 aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2);
264 mpOutDev->DrawPolygon(aPoly);
265
267 {
268 // tiny little box to display in presence of hidden member(s).
269 Point aBoxPos(aPos.X() + aSize.Width() - 5 * fScaleFactor, aPos.Y() + aSize.Height() - 5 * fScaleFactor);
270 Size aBoxSize(3 * fScaleFactor, 3 * fScaleFactor);
271 mpOutDev->DrawRect(tools::Rectangle(aBoxPos, aBoxSize));
272 }
273}
274
276{
277 Point aPos;
278 Size aSize;
279 getToggleBoundingBox(aPos, aSize);
280
281 // Background & outer black border
282 mpOutDev->SetLineColor(COL_BLACK);
283 mpOutDev->SetFillColor();
284 mpOutDev->DrawRect(tools::Rectangle(aPos, aSize));
285
286 Point aCenter(aPos.X() + aSize.getWidth() / 2, aPos.Y() + aSize.getHeight() / 2);
287
288 mpOutDev->DrawLine(
289 Point(aPos.X() + 2, aCenter.Y()),
290 Point(aPos.X() + aSize.getWidth() - 2, aCenter.Y()));
291
292 if (!mbToggleCollapse)
293 {
294 mpOutDev->DrawLine(
295 Point(aCenter.X(), aPos.Y() + 2),
296 Point(aCenter.X(), aPos.Y() + aSize.getHeight() - 2));
297 }
298}
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsBright() const
bool IsDark() const
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
constexpr tools::Long getX() const
constexpr tools::Long getY() const
void setHasHiddenMember(bool b)
Definition: dpcontrol.cxx:93
void getToggleBoundingBox(Point &rPos, Size &rSize) const
Definition: dpcontrol.cxx:195
VclPtr< OutputDevice > mpOutDev
Definition: dpcontrol.hxx:66
void setDrawPopupButton(bool b)
Definition: dpcontrol.cxx:76
const StyleSettings * mpStyle
Definition: dpcontrol.hxx:67
void setPopupPressed(bool b)
Definition: dpcontrol.cxx:98
void drawPopupButton()
Definition: dpcontrol.cxx:223
void setPopupLeft(bool b)
Definition: dpcontrol.cxx:103
void setDrawPopupButtonMulti(bool b)
Definition: dpcontrol.cxx:81
bool mbHasHiddenMember
Definition: dpcontrol.hxx:74
void setDrawToggleButton(bool b, bool bCollapse, sal_Int32 nIndent)
Definition: dpcontrol.cxx:86
Fraction maZoomY
Definition: dpcontrol.hxx:64
void setBoundingBox(const Point &rPos, const Size &rSize, bool bLayoutRTL)
Definition: dpcontrol.cxx:60
bool mbToggleCollapse
Definition: dpcontrol.hxx:73
void setText(const OUString &rText)
Definition: dpcontrol.cxx:55
ScDPFieldButton(OutputDevice *pOutDev, const StyleSettings *pStyle, const Fraction *pZoomY=nullptr, ScDocument *pDoc=nullptr)
Definition: dpcontrol.cxx:31
void setDrawBaseButton(bool b)
Definition: dpcontrol.cxx:71
OUString maText
Definition: dpcontrol.hxx:63
ScDocument * mpDoc
Definition: dpcontrol.hxx:65
sal_Int32 mnToggleIndent
Definition: dpcontrol.hxx:68
void drawToggleButton()
Definition: dpcontrol.cxx:275
bool mbPopupButtonMulti
Definition: dpcontrol.hxx:71
void getPopupBoundingBox(Point &rPos, Size &rSize) const
Definition: dpcontrol.cxx:167
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6050
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
constexpr tools::Long getHeight() const
constexpr tools::Long Height() const
constexpr tools::Long getWidth() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
const Color & GetShadowColor() const
const Color & GetLabelTextColor() const
const Color & GetLightColor() const
const Color & GetHighlightColor() const
const Color & GetFaceColor() const
const vcl::Font & GetAppFont() const
const Color & GetHighlightTextColor() const
const Color & GetButtonTextColor() const
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
void SetPoint(const Point &rPt, sal_uInt16 nPos)
void SetFontSize(const Size &)
const Size & GetFontSize() const
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
long Long
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)