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 
30 ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomY, ScDocument* pDoc) :
31  mpDoc(pDoc),
32  mpOutDev(pOutDev),
33  mpStyle(pStyle),
34  mbBaseButton(true),
35  mbPopupButton(false),
36  mbHasHiddenMember(false),
37  mbPopupPressed(false),
38  mbPopupLeft(false)
39 {
40  if (pZoomY)
41  maZoomY = *pZoomY;
42  else
43  maZoomY = Fraction(1, 1);
44 }
45 
47 {
48 }
49 
50 void ScDPFieldButton::setText(const OUString& rText)
51 {
52  maText = rText;
53 }
54 
55 void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL)
56 {
57  maPos = rPos;
58  maSize = rSize;
59  if (bLayoutRTL)
60  {
61  // rPos is the logical-left position, adjust maPos to visual-left (inside the cell border)
62  maPos.AdjustX( -(maSize.Width() - 1) );
63  }
64 }
65 
67 {
68  mbBaseButton = b;
69 }
70 
72 {
73  mbPopupButton = b;
74 }
75 
77 {
79 }
80 
82 {
83  mbPopupPressed = b;
84 }
85 
87 {
88  mbPopupLeft = b;
89 }
90 
92 {
93  bool bOldMapEnabled = mpOutDev->IsMapModeEnabled();
94 
95  if (mpOutDev->GetMapMode().GetMapUnit() != MapUnit::MapPixel)
96  mpOutDev->EnableMapMode(false);
97 
98  if (mbBaseButton)
99  {
100  // Background
101  tools::Rectangle aRect(maPos, maSize);
104  mpOutDev->DrawRect(aRect);
105 
106  // Border lines
108  mpOutDev->DrawLine(maPos, Point(maPos.X(), maPos.Y()+maSize.Height()-1));
109  mpOutDev->DrawLine(maPos, Point(maPos.X()+maSize.Width()-1, maPos.Y()));
110 
112  mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
113  Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
114  mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
115  Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
116 
117  // Field name.
118  // Get the font and size the same way as in scenario selection (lcl_DrawOneFrame in gridwin4.cxx)
119  vcl::Font aTextFont( mpStyle->GetAppFont() );
120  if ( mpDoc )
121  {
122  // use ScPatternAttr::GetFont only for font size
123  vcl::Font aAttrFont;
125  GetFont( aAttrFont, SC_AUTOCOL_BLACK, mpOutDev, &maZoomY );
126  aTextFont.SetFontSize( aAttrFont.GetFontSize() );
127  }
128  mpOutDev->SetFont(aTextFont);
130 
131  Point aTextPos = maPos;
132  tools::Long nTHeight = mpOutDev->GetTextHeight();
133  aTextPos.setX(maPos.getX() + 2); // 2 = Margin
134  aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
135 
138  mpOutDev->DrawText(aTextPos, maText);
139  mpOutDev->Pop();
140  }
141 
142  if (mbPopupButton)
143  drawPopupButton();
144 
145  mpOutDev->EnableMapMode(bOldMapEnabled);
146 }
147 
148 void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
149 {
150  float fScaleFactor = mpOutDev->GetDPIScaleFactor();
151 
152  tools::Long nMaxSize = 18 * fScaleFactor; // Button max size in either dimension
153 
154  tools::Long nW = std::min(maSize.getWidth() / 2, nMaxSize);
155  tools::Long nH = std::min(maSize.getHeight(), nMaxSize);
156 
157  double fZoom = static_cast<double>(maZoomY) > 1.0 ? static_cast<double>(maZoomY) : 1.0;
158  if (fZoom > 1.0)
159  {
160  nW = fZoom * (nW - 1);
161  nH = fZoom * (nH - 1);
162  }
163 
164  // #i114944# AutoFilter button is left-aligned in RTL.
165  // DataPilot button is always right-aligned for now, so text output isn't affected.
166  if (mbPopupLeft)
167  rPos.setX(maPos.getX());
168  else
169  rPos.setX(maPos.getX() + maSize.getWidth() - nW);
170 
171  rPos.setY(maPos.getY() + maSize.getHeight() - nH);
172  rSize.setWidth(nW);
173  rSize.setHeight(nH);
174 }
175 
177 {
178  Point aPos;
179  Size aSize;
180  getPopupBoundingBox(aPos, aSize);
181 
182  float fScaleFactor = mpOutDev->GetDPIScaleFactor();
183 
184  // Background & outer black border
186  Color aBackgroundColor
189  mpOutDev->SetFillColor(aBackgroundColor);
190  mpOutDev->DrawRect(tools::Rectangle(aPos, aSize));
191 
192  // the arrowhead
194  // FIXME: HACK: The following DrawPolygon draws twice in lok rtl mode for some reason.
195  // => one at the correct location with fill (possibly no outline)
196  // => and the other at an x offset with outline and without fill
197  // eg. Replacing this with a DrawRect() does not have any such problems.
199  mpOutDev->SetFillColor(aArrowColor);
200 
201  Point aCenter(aPos.X() + (aSize.Width() / 2), aPos.Y() + (aSize.Height() / 2));
202 
203  Size aArrowSize(4 * fScaleFactor, 2 * fScaleFactor);
204 
205  tools::Polygon aPoly(3);
206  aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0);
207  aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1);
208  aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2);
209  mpOutDev->DrawPolygon(aPoly);
210 
211  if (mbHasHiddenMember)
212  {
213  // tiny little box to display in presence of hidden member(s).
214  Point aBoxPos(aPos.X() + aSize.Width() - 5 * fScaleFactor, aPos.Y() + aSize.Height() - 5 * fScaleFactor);
215  Size aBoxSize(3 * fScaleFactor, 3 * fScaleFactor);
216  mpOutDev->DrawRect(tools::Rectangle(aBoxPos, aBoxSize));
217  }
218 }
219 
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScDocument * mpDoc
Definition: dpcontrol.hxx:61
const Color & GetShadowColor() const
void setDrawBaseButton(bool b)
Definition: dpcontrol.cxx:66
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)
void setWidth(tools::Long nWidth)
const Color & GetHighlightTextColor() const
long Long
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
const Color & GetFaceColor() const
bool mbHasHiddenMember
Definition: dpcontrol.hxx:66
bool IsMapModeEnabled() const
void DrawPolygon(const tools::Polygon &rPoly)
const MapMode & GetMapMode() const
void IntersectClipRegion(const tools::Rectangle &rRect)
void EnableMapMode(bool bEnable=true)
void SetPoint(const Point &rPt, sal_uInt16 nPos)
Fraction maZoomY
Definition: dpcontrol.hxx:60
const Color & GetHighlightColor() const
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6156
constexpr tools::Long Width() const
void setPopupPressed(bool b)
Definition: dpcontrol.cxx:81
const StyleSettings * mpStyle
Definition: dpcontrol.hxx:63
void getPopupBoundingBox(Point &rPos, Size &rSize) const
Definition: dpcontrol.cxx:148
void setText(const OUString &rText)
Definition: dpcontrol.cxx:50
const Color & GetLightColor() const
constexpr tools::Long getHeight() const
void DrawLine(const Point &rStartPt, const Point &rEndPt)
void DrawRect(const tools::Rectangle &rRect)
OUString maText
Definition: dpcontrol.hxx:59
void SetLineColor()
VclPtr< OutputDevice > mpOutDev
Definition: dpcontrol.hxx:62
void SetFillColor()
void SetTextColor(const Color &rColor)
const Size & GetFontSize() const
MapUnit GetMapUnit() const
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
float GetDPIScaleFactor() const
ScDPFieldButton(OutputDevice *pOutDev, const StyleSettings *pStyle, const Fraction *pZoomY=nullptr, ScDocument *pDoc=nullptr)
Definition: dpcontrol.cxx:30
void drawPopupButton()
Definition: dpcontrol.cxx:176
void setDrawPopupButton(bool b)
Definition: dpcontrol.cxx:71
const Color & GetButtonTextColor() const
constexpr tools::Long Height() const
void SetFont(const vcl::Font &rNewFont)
tools::Long GetTextHeight() const
void setHasHiddenMember(bool b)
Definition: dpcontrol.cxx:76
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
const vcl::Font & GetAppFont() const
void setHeight(tools::Long nHeight)
constexpr tools::Long getWidth() const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
void setPopupLeft(bool b)
Definition: dpcontrol.cxx:86
void setBoundingBox(const Point &rPos, const Size &rSize, bool bLayoutRTL)
Definition: dpcontrol.cxx:55
bool m_bDetectedRangeSegmentation false