Plasma

svg.h
1 /*
2  SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef PLASMA_SVG_H
8 #define PLASMA_SVG_H
9 
10 #include <QObject>
11 #include <QPixmap>
12 
13 #include <plasma/plasma_export.h>
14 #include <plasma/theme.h>
15 
16 class QPainter;
17 class QPoint;
18 class QPointF;
19 class QRect;
20 class QRectF;
21 class QSize;
22 class QSizeF;
23 class QMatrix;
24 
25 namespace Plasma
26 {
27 class FrameSvgPrivate;
28 class SvgPrivate;
29 
30 /**
31  * @class Svg plasma/svg.h <Plasma/Svg>
32  *
33  * @short A theme aware image-centric SVG class
34  *
35  * Plasma::Svg provides a class for rendering SVG images to a QPainter in a
36  * convenient manner. Unless an absolute path to a file is provided, it loads
37  * the SVG document using Plasma::Theme. It also provides a number of internal
38  * optimizations to help lower the cost of painting SVGs, such as caching.
39  *
40  * @see Plasma::FrameSvg
41  **/
42 class PLASMA_EXPORT Svg : public QObject
43 {
44  Q_OBJECT
45  Q_PROPERTY(QSize size READ size WRITE resize NOTIFY sizeChanged)
46  Q_PROPERTY(bool multipleImages READ containsMultipleImages WRITE setContainsMultipleImages)
47  Q_PROPERTY(QString imagePath READ imagePath WRITE setImagePath NOTIFY imagePathChanged)
48  Q_PROPERTY(bool usingRenderingCache READ isUsingRenderingCache WRITE setUsingRenderingCache)
49  Q_PROPERTY(bool fromCurrentTheme READ fromCurrentTheme NOTIFY fromCurrentThemeChanged)
50  Q_PROPERTY(Plasma::Theme::ColorGroup colorGroup READ colorGroup WRITE setColorGroup NOTIFY colorGroupChanged)
51  Q_PROPERTY(Plasma::Svg::Status status READ status WRITE setStatus NOTIFY statusChanged)
52 
53 public:
54  enum Status {
55  Normal = 0,
56  Selected,
57  Inactive,
58  };
59  Q_ENUM(Status)
60 
61  /**
62  * Constructs an SVG object that implicitly shares and caches rendering.
63  *
64  * Unlike QSvgRenderer, which this class uses internally,
65  * Plasma::Svg represents an image generated from an SVG. As such, it
66  * has a related size and transform matrix (the latter being provided
67  * by the painter used to paint the image).
68  *
69  * The size is initialized to be the SVG's native size.
70  *
71  * @param parent options QObject to parent this to
72  *
73  * @related Plasma::Theme
74  */
75  explicit Svg(QObject *parent = nullptr);
76  ~Svg() override;
77 
78  /**
79  * Set the device pixel ratio for the Svg. This is the ratio between
80  * image pixels and device-independent pixels.
81  * The Svg will produce pixmaps scaled by devicePixelRatio, but all the sizes and element
82  * rects will not be altered.
83  * The default value is 1.0 and the scale will be done rounded to the floor integer
84  * Setting it to something more, will make all the elements of this svg appear bigger.
85  */
86  void setDevicePixelRatio(qreal ratio);
87 
88  /**
89  * @return the device pixel ratio for this Svg.
90  */
91  qreal devicePixelRatio();
92 
93  /**
94  * Setting a scale factor greater than one it will result in final images scaled by it.
95  * Unlike devicePixelRatio, every size and element rect will be scaled accordingly.
96  * @return how much to scale the rendered image.
97  */
98  qreal scaleFactor() const;
99 
100  /**
101  * Setting a scale factor greater than one it will result in final images scaled by it.
102  * Unlike devicePixelRatio, every size and element rect will be scaled accordingly.
103  * The default value is 1.0 and the scale will be done rounded to the floor integer.
104  * @param how much to scale the Svg
105  */
106  void setScaleFactor(qreal factor);
107 
108  /**
109  * Set a color group for the Svg.
110  * if the Svg uses stylesheets and has elements
111  * that are either TextColor or BackgroundColor class,
112  * make them use ButtonTextColor/ButtonBackgroundColor
113  * or ViewTextColor/ViewBackgroundColor
114  */
115  void setColorGroup(Plasma::Theme::ColorGroup group);
116 
117  /**
118  * @return the color group for this Svg
119  */
120  Plasma::Theme::ColorGroup colorGroup() const;
121 
122  /**
123  * Returns a pixmap of the SVG represented by this object.
124  *
125  * The size of the pixmap will be the size of this Svg object (size())
126  * if containsMultipleImages is @c true; otherwise, it will be the
127  * size of the requested element after the whole SVG has been scaled
128  * to size().
129  *
130  * @param elementId the ID string of the element to render, or an empty
131  * string for the whole SVG (the default)
132  * @return a QPixmap of the rendered SVG
133  */
134  Q_INVOKABLE QPixmap pixmap(const QString &elementID = QString());
135 
136  /**
137  * Returns an image of the SVG represented by this object.
138  *
139  * The size of the image will be the size of this Svg object (size())
140  * if containsMultipleImages is @c true; otherwise, it will be the
141  * size of the requested element after the whole SVG has been scaled
142  * to size().
143  *
144  * @param elementId the ID string of the element to render, or an empty
145  * string for the whole SVG (the default)
146  * @return a QPixmap of the rendered SVG
147  */
148  Q_INVOKABLE QImage image(const QSize &size, const QString &elementID = QString());
149 
150  /**
151  * Paints all or part of the SVG represented by this object
152  *
153  * The size of the painted area will be the size of this Svg object
154  * (size()) if containsMultipleImages is @c true; otherwise, it will
155  * be the size of the requested element after the whole SVG has been
156  * scaled to size().
157  *
158  * @param painter the QPainter to use
159  * @param point the position to start drawing; the entire svg will be
160  * drawn starting at this point.
161  * @param elementId the ID string of the element to render, or an empty
162  * string for the whole SVG (the default)
163  */
164  Q_INVOKABLE void paint(QPainter *painter, const QPointF &point, const QString &elementID = QString());
165 
166  /**
167  * Paints all or part of the SVG represented by this object
168  *
169  * The size of the painted area will be the size of this Svg object
170  * (size()) if containsMultipleImages is @c true; otherwise, it will
171  * be the size of the requested element after the whole SVG has been
172  * scaled to size().
173  *
174  * @param painter the QPainter to use
175  * @param x the horizontal coordinate to start painting from
176  * @param y the vertical coordinate to start painting from
177  * @param elementId the ID string of the element to render, or an empty
178  * string for the whole SVG (the default)
179  */
180  Q_INVOKABLE void paint(QPainter *painter, int x, int y, const QString &elementID = QString());
181 
182  /**
183  * Paints all or part of the SVG represented by this object
184  *
185  * @param painter the QPainter to use
186  * @param rect the rect to draw into; if smaller than the current size
187  * the drawing is starting at this point.
188  * @param elementId the ID string of the element to render, or an empty
189  * string for the whole SVG (the default)
190  */
191  Q_INVOKABLE void paint(QPainter *painter, const QRectF &rect, const QString &elementID = QString());
192 
193  /**
194  * Paints all or part of the SVG represented by this object
195  *
196  * @param painter the QPainter to use
197  * @param x the horizontal coordinate to start painting from
198  * @param y the vertical coordinate to start painting from
199  * @param width the width of the element to draw
200  * @param height the height of the element do draw
201  * @param elementId the ID string of the element to render, or an empty
202  * string for the whole SVG (the default)
203  */
204  Q_INVOKABLE void paint(QPainter *painter, int x, int y, int width, int height, const QString &elementID = QString());
205 
206  /**
207  * The size of the SVG.
208  *
209  * If the SVG has been resized with resize(), that size will be
210  * returned; otherwise, the natural size of the SVG will be returned.
211  *
212  * If containsMultipleImages is @c true, each element of the SVG
213  * will be rendered at this size by default.
214  *
215  * @return the current size of the SVG
216  **/
217  QSize size() const;
218 
219  /**
220  * Resizes the rendered image.
221  *
222  * Rendering will actually take place on the next call to paint.
223  *
224  * If containsMultipleImages is @c true, each element of the SVG
225  * will be rendered at this size by default; otherwise, the entire
226  * image will be scaled to this size and each element will be
227  * scaled appropriately.
228  *
229  * @param width the new width
230  * @param height the new height
231  **/
232  Q_INVOKABLE void resize(qreal width, qreal height);
233 
234  /**
235  * Resizes the rendered image.
236  *
237  * Rendering will actually take place on the next call to paint.
238  *
239  * If containsMultipleImages is @c true, each element of the SVG
240  * will be rendered at this size by default; otherwise, the entire
241  * image will be scaled to this size and each element will be
242  * scaled appropriately.
243  *
244  * @param size the new size of the image
245  **/
246  Q_INVOKABLE void resize(const QSizeF &size);
247 
248  /**
249  * Resizes the rendered image to the natural size of the SVG.
250  *
251  * Rendering will actually take place on the next call to paint.
252  **/
253  Q_INVOKABLE void resize();
254 
255  /**
256  * Find the size of a given element.
257  *
258  * This is the size of the element with ID @p elementId after the SVG
259  * has been scaled (see resize()). Note that this is unaffected by
260  * the containsMultipleImages property.
261  *
262  * @param elementId the id of the element to check
263  * @return the size of a given element, given the current size of the SVG
264  **/
265  Q_INVOKABLE QSize elementSize(const QString &elementId) const;
266 
267  QSize elementSize(QStringView elementId) const;
268 
269  /**
270  * The bounding rect of a given element.
271  *
272  * This is the bounding rect of the element with ID @p elementId after
273  * the SVG has been scaled (see resize()). Note that this is
274  * unaffected by the containsMultipleImages property.
275  *
276  * @param elementId the id of the element to check
277  * @return the current rect of a given element, given the current size of the SVG
278  **/
279  Q_INVOKABLE QRectF elementRect(const QString &elementId) const;
280 
281  QRectF elementRect(QStringView elementId) const;
282 
283  /**
284  * Check whether an element exists in the loaded SVG.
285  *
286  * @param elementId the id of the element to check for
287  * @return @c true if the element is defined in the SVG, otherwise @c false
288  **/
289  Q_INVOKABLE bool hasElement(const QString &elementId) const;
290 
291  bool hasElement(QStringView elementId) const;
292 
293  /**
294  * Check whether this object is backed by a valid SVG file.
295  *
296  * This method can be expensive as it causes disk access.
297  *
298  * @return @c true if the SVG file exists and the document is valid,
299  * otherwise @c false.
300  **/
301  Q_INVOKABLE bool isValid() const;
302 
303  /**
304  * Set whether the SVG contains a single image or multiple ones.
305  *
306  * If this is set to @c true, the SVG will be treated as a
307  * collection of related images, rather than a consistent
308  * drawing.
309  *
310  * In particular, when individual elements are rendered, this
311  * affects whether the elements are resized to size() by default.
312  * See paint() and pixmap().
313  *
314  * @param multiple true if the svg contains multiple images
315  */
316  void setContainsMultipleImages(bool multiple);
317 
318  /**
319  * Whether the SVG contains multiple images.
320  *
321  * If this is @c true, the SVG will be treated as a
322  * collection of related images, rather than a consistent
323  * drawing.
324  *
325  * @return @c true if the SVG will be treated as containing
326  * multiple images, @c false if it will be treated
327  * as a coherent image.
328  */
329  bool containsMultipleImages() const;
330 
331  /**
332  * Set the SVG file to render.
333  *
334  * Relative paths are looked for in the current Plasma theme,
335  * and should not include the file extension (.svg and .svgz
336  * files will be searched for). See Theme::imagePath().
337  *
338  * If the parent object of this Svg is a Plasma::Applet,
339  * relative paths will be searched for in the applet's package
340  * first.
341  *
342  * @param svgFilePath either an absolute path to an SVG file, or
343  * an image name
344  */
345  virtual void setImagePath(const QString &svgFilePath);
346 
347  /**
348  * The SVG file to render.
349  *
350  * If this SVG is themed, this will be a relative path, and will not
351  * include a file extension.
352  *
353  * @return either an absolute path to an SVG file, or an image name
354  * @see Theme::imagePath()
355  */
356  QString imagePath() const;
357 
358  /**
359  * Sets whether or not to cache the results of rendering to pixmaps.
360  *
361  * If the SVG is resized and re-rendered often (and does not keep using the
362  * same small set of pixmap dimensions), then it may be less efficient to do
363  * disk caching. A good example might be a progress meter that uses an Svg
364  * object to paint itself: the meter will be changing often enough, with
365  * enough unpredictability and without re-use of the previous pixmaps to
366  * not get a gain from caching.
367  *
368  * Most Svg objects should use the caching feature, however.
369  * Therefore, the default is to use the render cache.
370  *
371  * @param useCache true to cache rendered pixmaps
372  * @since 4.3
373  */
374  void setUsingRenderingCache(bool useCache);
375 
376  /**
377  * Whether the rendering cache is being used.
378  *
379  * @return @c true if the Svg object is using caching for rendering results
380  * @since 4.3
381  */
382  bool isUsingRenderingCache() const;
383 
384  /**
385  * Whether the current theme has this Svg, without any fallback
386  * to the default theme involved
387  *
388  * @return true if the svg is loaded from the current theme
389  * @see Theme::currentThemeHasImage
390  */
391  bool fromCurrentTheme() const;
392 
393  /**
394  * Sets whether the Svg uses the global system theme for its colors or
395  * the Plasma theme. Default is False.
396  *
397  * @since 5.16
398  */
399  void setUseSystemColors(bool system);
400 
401  /**
402  * @returns True if colors from the system theme are used.
403  * Default is False
404  * @since 5.16
405  */
406  bool useSystemColors() const;
407 
408  /**
409  * Sets the Plasma::Theme to use with this Svg object.
410  *
411  * By default, Svg objects use Plasma::Theme::default().
412  *
413  * This determines how relative image paths are interpreted.
414  *
415  * @param theme the theme object to use
416  * @since 4.3
417  */
418  void setTheme(Plasma::Theme *theme);
419 
420  /**
421  * The Plasma::Theme used by this Svg object.
422  *
423  * This determines how relative image paths are interpreted.
424  *
425  * @return the theme used by this Svg
426  */
427  Theme *theme() const;
428 
429  /**
430  * Sets the image in a selected status.
431  * Svgs can be colored with system color themes, if the status is selected,
432  * the TextColor will become HighlightedText color and BackgroundColor
433  * will become HighlightColor, making the svg graphics (for instance an icon)
434  * will look correct together selected text
435  * Supported statuses as of 5.23 are Normal and Selected
436  * @since 5.23
437  */
438  void setStatus(Svg::Status status);
439 
440  /**
441  * @return the status of the Svg
442  * @since 5.23
443  */
444  Svg::Status status() const;
445 
446 Q_SIGNALS:
447  /**
448  * Emitted whenever the SVG data has changed in such a way that a repaint is required.
449  * Any usage of an Svg object that does the painting itself must connect to this signal
450  * and respond by updating the painting. Note that connected to Theme::themeChanged is
451  * incorrect in such a use case as the Svg itself may not be updated yet nor may theme
452  * change be the only case when a repaint is needed. Also note that classes or QML code
453  * which take Svg objects as parameters for their own painting all respond to this signal
454  * so that in those cases manually responding to the signal is unnecessary; ONLY when
455  * direct, manual painting with an Svg object is done in application code is this signal
456  * used.
457  */
458  void repaintNeeded();
459 
460  /**
461  * Emitted whenever the size of the Svg is changed. @see resize()
462  */
463  void sizeChanged();
464 
465  /**
466  * Emitted whenever the image path of the Svg is changed.
467  */
468  void imagePathChanged();
469 
470  /**
471  * Emitted whenever the color hint has changed.
472  */
473  void colorHintChanged();
474 
475  /**
476  * Emitted whenever the color group has changed.
477  */
478  void colorGroupChanged();
479 
480  /**
481  * Emitted when fromCurrentTheme() value has changed
482  */
483  void fromCurrentThemeChanged(bool fromCurrentTheme);
484 
485  /**
486  * Emitted when the status changes
487  * @since 5.23
488  */
489  void statusChanged(Plasma::Svg::Status status);
490 
491 private:
492  SvgPrivate *const d;
493  bool eventFilter(QObject *watched, QEvent *event) override;
494 
495  Q_PRIVATE_SLOT(d, void themeChanged())
496  Q_PRIVATE_SLOT(d, void colorsChanged())
497 
498  friend class SvgPrivate;
499  friend class FrameSvgPrivate;
500  friend class FrameSvg;
501 };
502 
503 } // Plasma namespace
504 
505 #endif // multiple inclusion guard
Namespace for everything in libplasma.
Definition: datamodel.cpp:14
Q_SCRIPTABLE CaptureState status()
A theme aware image-centric SVG class.
Definition: svg.h:42
Interface to the Plasma theme.
Definition: theme.h:42
Provides an SVG with borders.
Definition: framesvg.h:62
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Mar 23 2023 04:18:17 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.