Plasma

framesvg.h
1 /*
2  SPDX-FileCopyrightText: 2008 Aaron Seigo <[email protected]>
3  SPDX-FileCopyrightText: 2008 Marco Martin <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef PLASMA_FRAMESVG_H
9 #define PLASMA_FRAMESVG_H
10 
11 #include <QObject>
12 #include <QPixmap>
13 
14 #include <plasma/plasma_export.h>
15 
16 #include <plasma/plasma.h>
17 #include <plasma/svg.h>
18 
19 class QPainter;
20 class QPoint;
21 class QPointF;
22 class QRect;
23 class QRectF;
24 class QSize;
25 class QSizeF;
26 class QMatrix;
27 
28 namespace Plasma
29 {
30 class FrameSvgPrivate;
31 
32 /**
33  * @class FrameSvg plasma/framesvg.h <Plasma/FrameSvg>
34  *
35  * @short Provides an SVG with borders.
36  *
37  * When using SVG images for a background of an object that may change
38  * its aspect ratio, such as a dialog, simply scaling a single image
39  * may not be enough.
40  *
41  * FrameSvg allows SVGs to provide several elements for borders as well
42  * as a central element, each of which are scaled individually. These
43  * elements should be named
44  *
45  * - @c center - the central element, which will be scaled in both directions
46  * - @c top - the top border; the height is fixed, but it will be scaled
47  * horizontally to the same width as @c center
48  * - @c bottom - the bottom border; scaled in the same way as @c top
49  * - @c left - the left border; the width is fixed, but it will be scaled
50  * vertically to the same height as @c center
51  * - @c right - the right border; scaled in the same way as @c left
52  * - @c topleft - fixed size; must be the same height as @c top and the same
53  * width as @c left
54  * - @c bottomleft, @c topright, @c bottomright - similar to @c topleft
55  *
56  * @c center must exist, but all the others are optional. @c topleft and
57  * @c topright will be ignored if @c top does not exist, and similarly for
58  * @c bottomleft and @c bottomright.
59  *
60  * @see Plasma::Svg
61  **/
62 class PLASMA_EXPORT FrameSvg : public Svg
63 {
64  Q_OBJECT
65 
66  Q_PROPERTY(EnabledBorders enabledBorders READ enabledBorders WRITE setEnabledBorders)
67 
68 public:
69  /**
70  * These flags represents what borders should be drawn
71  */
73  NoBorder = 0,
74  TopBorder = 1,
75  BottomBorder = 2,
76  LeftBorder = 4,
77  RightBorder = 8,
78  AllBorders = TopBorder | BottomBorder | LeftBorder | RightBorder,
79  };
80  Q_DECLARE_FLAGS(EnabledBorders, EnabledBorder)
81  Q_FLAG(EnabledBorders)
82 
83  /**
84  * Constructs a new FrameSvg that paints the proper named subelements
85  * as borders. It may also be used as a regular Plasma::Svg object
86  * for direct access to elements in the Svg.
87  *
88  * @param parent options QObject to parent this to
89  *
90  * @related Plasma::Theme
91  */
92  explicit FrameSvg(QObject *parent = nullptr);
93  ~FrameSvg() override;
94 
95  /**
96  * Loads a new Svg
97  * @param imagePath the new file
98  */
99  Q_INVOKABLE void setImagePath(const QString &path) override;
100 
101  /**
102  * Sets what borders should be painted
103  * @param flags borders we want to paint
104  */
105  void setEnabledBorders(const EnabledBorders borders);
106 
107  /**
108  * Convenience method to get the enabled borders
109  * @return what borders are painted
110  */
111  EnabledBorders enabledBorders() const;
112 
113  /**
114  * Resize the frame maintaining the same border size
115  * @param size the new size of the frame
116  */
117  Q_INVOKABLE void resizeFrame(const QSizeF &size);
118 
119  /**
120  * @returns the size of the frame
121  */
122  Q_INVOKABLE QSizeF frameSize() const;
123 
124  /**
125  * Returns the margin size given the margin edge we want
126  * If the given margin is disabled, it will return 0.
127  * If you don't care about the margin being on or off, use fixedMarginSize()
128  * @param edge the margin edge we want, top, bottom, left or right
129  * @return the margin size
130  */
131  Q_INVOKABLE qreal marginSize(const Plasma::Types::MarginEdge edge) const;
132 
133  /**
134  * Convenience method that extracts the size of the four margins
135  * in the four output parameters
136  * The disabled margins will be 0.
137  * If you don't care about the margins being on or off, use getFixedMargins()
138  * @param left left margin size
139  * @param top top margin size
140  * @param right right margin size
141  * @param bottom bottom margin size
142  */
143  Q_INVOKABLE void getMargins(qreal &left, qreal &top, qreal &right, qreal &bottom) const;
144 
145  /**
146  * Returns the margin size given the margin edge we want.
147  * Compared to marginSize(), this doesn't depend whether the margin is enabled or not
148  * @param edge the margin edge we want, top, bottom, left or right
149  * @return the margin size
150  */
151  Q_INVOKABLE qreal fixedMarginSize(const Plasma::Types::MarginEdge edge) const;
152 
153  /**
154  * Convenience method that extracts the size of the four margins
155  * in the four output parameters
156  * Compared to getMargins(), this doesn't depend whether the margins are enabled or not
157  * @param left left margin size
158  * @param top top margin size
159  * @param right right margin size
160  * @param bottom bottom margin size
161  */
162  Q_INVOKABLE void getFixedMargins(qreal &left, qreal &top, qreal &right, qreal &bottom) const;
163 
164  /**
165  * Returns the insets margin size given the margin edge we want.
166  * @param edge the margin edge we want, top, bottom, left or right
167  * @return the margin size
168  * @since 5.77
169  */
170  Q_INVOKABLE qreal insetSize(const Plasma::Types::MarginEdge edge) const;
171 
172  /**
173  * Convenience method that extracts the size of the four inset margins
174  * in the four output parameters
175  * @param left left margin size
176  * @param top top margin size
177  * @param right right margin size
178  * @param bottom bottom margin size
179  * @since 5.77
180  */
181  Q_INVOKABLE void getInset(qreal &left, qreal &top, qreal &right, qreal &bottom) const;
182 
183  /**
184  * @return the rectangle of the center element, taking the margins into account.
185  */
186  Q_INVOKABLE QRectF contentsRect() const;
187 
188  /**
189  * Sets the prefix (@see setElementPrefix) to 'north', 'south', 'west' and 'east'
190  * when the location is TopEdge, BottomEdge, LeftEdge and RightEdge,
191  * respectively. Clears the prefix in other cases.
192  *
193  * The prefix must exist in the SVG document, which means that this can only be
194  * called successfully after setImagePath is called.
195  * @param location location in the UI this frame will be drawn
196  */
197  Q_INVOKABLE void setElementPrefix(Plasma::Types::Location location);
198 
199  /**
200  * Sets the prefix for the SVG elements to be used for painting. For example,
201  * if prefix is 'active', then instead of using the 'top' element of the SVG
202  * file to paint the top border, 'active-top' element will be used. The same
203  * goes for other SVG elements.
204  *
205  * If the elements with prefixes are not present, the default ones are used.
206  * (for the sake of speed, the test is present only for the 'center' element)
207  *
208  * Setting the prefix manually resets the location to Floating.
209  *
210  * The prefix must exist in the SVG document, which means that this can only be
211  * called successfully after setImagePath is called.
212  *
213  * @param prefix prefix for the SVG elements that make up the frame
214  */
215  Q_INVOKABLE void setElementPrefix(const QString &prefix);
216 
217  /**
218  * @return true if the svg has the necessary elements with the given prefix
219  * to draw a frame
220  * @param prefix the given prefix we want to check if drawable (can have trailing '-' since 5.59)
221  */
222  Q_INVOKABLE bool hasElementPrefix(const QString &prefix) const;
223 
224  /**
225  * This is an overloaded method provided for convenience equivalent to
226  * hasElementPrefix("north"), hasElementPrefix("south")
227  * hasElementPrefix("west") and hasElementPrefix("east")
228  * @return true if the svg has the necessary elements with the given prefix
229  * to draw a frame.
230  * @param location the given prefix we want to check if drawable
231  */
232  Q_INVOKABLE bool hasElementPrefix(Plasma::Types::Location location) const;
233 
234  /**
235  * Returns the prefix for SVG elements of the FrameSvg (including a '-' at the end if not empty)
236  * @return the prefix
237  * @sa actualPrefix()
238  */
239  Q_INVOKABLE QString prefix();
240 
241  /**
242  * Returns a mask that tightly contains the fully opaque areas of the svg
243  * @return a region of opaque areas
244  */
245  Q_INVOKABLE QRegion mask() const;
246 
247  /**
248  * @return a pixmap whose alpha channel is the opacity of the frame. It may be the frame itself or a special frame with the mask- prefix
249  */
250  QPixmap alphaMask() const;
251 
252  /**
253  * Sets whether saving all the rendered prefixes in a cache or not
254  * @param cache if use the cache or not
255  */
256  Q_INVOKABLE void setCacheAllRenderedFrames(bool cache);
257 
258  /**
259  * @return if all the different prefixes should be kept in a cache when rendered
260  */
261  Q_INVOKABLE bool cacheAllRenderedFrames() const;
262 
263  /**
264  * Deletes the internal cache freeing memory: use this if you want to switch the rendered
265  * element and you don't plan to switch back to the previous one for a long time and you
266  * used setUsingRenderingCache(true)
267  */
268  Q_INVOKABLE void clearCache();
269 
270  /**
271  * Returns a pixmap of the SVG represented by this object.
272  *
273  * @param elelementId the ID string of the element to render, or an empty
274  * string for the whole SVG (the default)
275  * @return a QPixmap of the rendered SVG
276  */
277  Q_INVOKABLE QPixmap framePixmap();
278 
279  /**
280  * Paints the loaded SVG with the elements that represents the border
281  * @param painter the QPainter to use
282  * @param target the target rectangle on the paint device
283  * @param source the portion rectangle of the source image
284  */
285  Q_INVOKABLE void paintFrame(QPainter *painter, const QRectF &target, const QRectF &source = QRectF());
286 
287  /**
288  * Paints the loaded SVG with the elements that represents the border
289  * This is an overloaded member provided for convenience
290  * @param painter the QPainter to use
291  * @param pos where to paint the svg
292  */
293  Q_INVOKABLE void paintFrame(QPainter *painter, const QPointF &pos = QPointF(0, 0));
294 
295  /**
296  * @returns the prefix that is actually used (including a '-' at the end if not empty)
297  * @sa prefix()
298  */
299  QString actualPrefix() const;
300 
301  /**
302  * @returns true if we are in a transaction of many changes at once
303  * and we don't want to rebuild the generated graphics for each change yet
304  * @since 5.31
305  */
306  bool isRepaintBlocked() const;
307 
308  /**
309  * If we will do several changes at once in the frame properties,
310  * such as prefix, enabled borders and size, in order to not regenerate
311  * the graphics for each change, set this property to true, and set
312  * it to false again after applying all the changes needed.
313  * Note that any change will not be visible in the painted frame while this property is set to true.
314  * @since 5.31
315  */
316  void setRepaintBlocked(bool blocked);
317 
318 private:
319  FrameSvgPrivate *const d;
320  friend class FrameData;
321 
322  // Q_PRIVATE_SLOT(d, void updateSizes())
323 };
324 
325 Q_DECLARE_OPERATORS_FOR_FLAGS(FrameSvg::EnabledBorders)
326 
327 } // Plasma namespace
328 
329 #endif // multiple inclusion guard
Provides an SVG with borders.
Definition: framesvg.h:62
Namespace for everything in libplasma.
Definition: datamodel.cpp:14
EnabledBorder
These flags represents what borders should be drawn.
Definition: framesvg.h:72
Location
The Location enumeration describes where on screen an element, such as an Applet or its managing cont...
Definition: plasma.h:158
A theme aware image-centric SVG class.
Definition: svg.h:42
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Apr 22 2021 22:41:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.