1 /*
2     SPDX-FileCopyrightText: 2010 Marco Martin <mart@kde.org>
3     SPDX-FileCopyrightText: 2014 David Edmundson <davidedmundson@kde.org>
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 #ifndef FRAMESVGITEM_P
8 #define FRAMESVGITEM_P
9 
10 #include <QQmlParserStatus>
11 #include <QQuickItem>
12 
13 #include <Plasma/FrameSvg>
14 
15 #include "units.h"
16 
17 namespace Plasma
18 {
19 class FrameSvg;
20 
21 /**
22  * @class FrameSvgItemMargins
23  *
24  * @short The sizes of a frame's margins.
25  */
26 class FrameSvgItemMargins : public QObject
27 {
28     Q_OBJECT
29 
30     /**
31      * Width in pixels of the left margin.
32      */
33     Q_PROPERTY(qreal left READ left NOTIFY marginsChanged)
34 
35     /**
36      * Height in pixels of the top margin.
37      */
38     Q_PROPERTY(qreal top READ top NOTIFY marginsChanged)
39 
40     /**
41      * Width in pixels of the right margin.
42      */
43     Q_PROPERTY(qreal right READ right NOTIFY marginsChanged)
44 
45     /**
46      * Height in pixels of the bottom margin.
47      */
48     Q_PROPERTY(qreal bottom READ bottom NOTIFY marginsChanged)
49 
50     /**
51      * Width in pixels of the left and right margins combined.
52      */
53     Q_PROPERTY(qreal horizontal READ horizontal NOTIFY marginsChanged)
54 
55     /**
56      * Height in pixels of the top and bottom margins combined.
57      */
58     Q_PROPERTY(qreal vertical READ vertical NOTIFY marginsChanged)
59 
60 public:
61     FrameSvgItemMargins(Plasma::FrameSvg *frameSvg, QObject *parent = nullptr);
62 
63     qreal left() const;
64     qreal top() const;
65     qreal right() const;
66     qreal bottom() const;
67     qreal horizontal() const;
68     qreal vertical() const;
69 
70     /// returns a vector with left, top, right, bottom
71     QVector<qreal> margins() const;
72 
73     void setFixed(bool fixed);
74     bool isFixed() const;
75 
76     void setInset(bool inset);
77     bool isInset() const;
78 
79 public Q_SLOTS:
80     void update();
81 
82 Q_SIGNALS:
83     void marginsChanged();
84 
85 private:
86     FrameSvg *m_frameSvg;
87     bool m_fixed;
88     bool m_inset;
89 };
90 
91 /**
92  * @class FrameSvgItem
93  *
94  * @short Provides an SVG with borders.
95  *
96  * It is exposed as org.kde.plasma.core.FrameSvgItem
97  */
98 class FrameSvgItem : public QQuickItem
99 {
100     Q_OBJECT
101     Q_INTERFACES(QQmlParserStatus)
102 
103     /**
104      * Theme relative path of the svg, like "widgets/background"
105      */
106     Q_PROPERTY(QString imagePath READ imagePath WRITE setImagePath NOTIFY imagePathChanged)
107 
108     /**
109      * prefix for the 9 piece svg, like "pushed" or "normal" for the button
110      * see https://techbase.kde.org/Development/Tutorials/Plasma5/ThemeDetails
111      * for a list of paths and prefixes
112      * It can also be an array of strings, specifying a fallback chain in case
113      * the first element isn't found in the theme, eg ["toolbutton-normal", "normal"]
114      * so it's easy to keep backwards compatibility with old themes
115      * (Note: fallback chain is supported only @since 5.32)
116      */
117     Q_PROPERTY(QVariant prefix READ prefix WRITE setPrefix NOTIFY prefixChanged)
118 
119     /**
120      * the actual prefix that was used, if a fallback chain array was set as "prefix"
121      * @since 5.34
122      */
123     Q_PROPERTY(QString usedPrefix READ usedPrefix NOTIFY usedPrefixChanged)
124 
125     /**
126      * The margins of the frame, read only
127      * @see FrameSvgItemMargins
128      */
129     Q_PROPERTY(QObject *margins READ margins CONSTANT)
130 
131     /**
132      * The margins of the frame, regardless if they are enabled or not
133      * read only
134      * @see FrameSvgItemMargins
135      */
136     Q_PROPERTY(QObject *fixedMargins READ fixedMargins CONSTANT)
137 
138     /**
139      * The inset of the frame
140      * read only
141      * @see FrameSvgItemMargins
142      * @since 5.77
143      */
144     Q_PROPERTY(QObject *inset READ inset CONSTANT)
145 
146     /**
147      * The borders that will be rendered, it's a flag combination of:
148      *  NoBorder
149      *  TopBorder
150      *  BottomBorder
151      *  LeftBorder
152      *  RightBorder
153      */
154     Q_PROPERTY(Plasma::FrameSvg::EnabledBorders enabledBorders READ enabledBorders WRITE setEnabledBorders NOTIFY enabledBordersChanged)
155 
156     /**
157      * Holds whether the current svg is present in the current theme and NO fallback is involved
158      */
159     Q_PROPERTY(bool fromCurrentTheme READ fromCurrentTheme NOTIFY fromCurrentThemeChanged)
160 
161     /**
162      * Set a color group for the FrameSvgItem.
163      * if the Svg uses stylesheets and has elements
164      * that are either TextColor or BackgroundColor class,
165      * make them use ButtonTextColor/ButtonBackgroundColor
166      * or ViewTextColor/ViewBackgroundColor, ComplementaryTextColor etc.
167      */
168     Q_PROPERTY(Plasma::Theme::ColorGroup colorGroup READ colorGroup WRITE setColorGroup NOTIFY colorGroupChanged)
169 
170     /**
171      * Sets the image in a selected status.
172      * Svgs can be colored with system color themes, if the status is selected,
173      * the TextColor will become HighlightedText color and BackgroundColor
174      * will become HighlightColor, making the svg graphics (for instance an icon)
175      * will look correct together selected text
176      * @see Plasma::Svg::status
177      * @since 5.23
178      */
179     Q_PROPERTY(Plasma::Svg::Status status READ status WRITE setStatus NOTIFY statusChanged)
180 
181     /**
182      * The mask that tightly contains the painted areas
183      * @since 5.58
184      */
185     Q_PROPERTY(QRegion mask READ mask NOTIFY maskChanged)
186 
187 public:
188     /**
189      * @return true if the svg has the necessary elements with the given prefix
190      * to draw a frame
191      * @param prefix the given prefix we want to check if drawable
192      */
193     Q_INVOKABLE bool hasElementPrefix(const QString &prefix) const;
194 
195     /// @cond INTERNAL_DOCS
196     FrameSvgItem(QQuickItem *parent = nullptr);
197     ~FrameSvgItem() override;
198 
199     void setImagePath(const QString &path);
200     QString imagePath() const;
201 
202     void setPrefix(const QVariant &prefix);
203     QVariant prefix() const;
204 
205     QString usedPrefix() const;
206 
207     void setEnabledBorders(const Plasma::FrameSvg::EnabledBorders borders);
208     Plasma::FrameSvg::EnabledBorders enabledBorders() const;
209 
210     FrameSvgItemMargins *margins();
211     FrameSvgItemMargins *fixedMargins();
212     FrameSvgItemMargins *inset();
213 
214     void setColorGroup(Plasma::Theme::ColorGroup group);
215     Plasma::Theme::ColorGroup colorGroup() const;
216 
217     bool fromCurrentTheme() const;
218 
219     void setStatus(Plasma::Svg::Status status);
220     Plasma::Svg::Status status() const;
221 
222     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
223 
224     QRegion mask() const;
225 
226     /**
227      * Only to be used from inside this library, is not intended to be invokable
228      */
229     Plasma::FrameSvg *frameSvg() const;
230 
231     QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
232 
233     void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) override;
234 
235 protected:
236     void classBegin() override;
237     void componentComplete() override;
238 
239     /// @endcond
240 
241 Q_SIGNALS:
242     void imagePathChanged();
243     void prefixChanged();
244     void enabledBordersChanged();
245     void fromCurrentThemeChanged();
246     void colorGroupChanged();
247     void repaintNeeded();
248     void statusChanged();
249     void usedPrefixChanged();
250     void maskChanged();
251 
252 private Q_SLOTS:
253     void doUpdate();
254     void updateDevicePixelRatio();
255 
256 private:
257     void applyPrefixes();
258 
259     Plasma::FrameSvg *m_frameSvg;
260     FrameSvgItemMargins *m_margins;
261     FrameSvgItemMargins *m_fixedMargins;
262     FrameSvgItemMargins *m_insetMargins;
263     // logged margins to check for changes
264     QVector<qreal> m_oldMargins;
265     QVector<qreal> m_oldFixedMargins;
266     QVector<qreal> m_oldInsetMargins;
267     QStringList m_prefixes;
268     bool m_textureChanged;
269     bool m_sizeChanged;
270     bool m_fastPath;
271 };
272 
273 }
274 
275 #endif
276