1 | /* |
2 | * Copyright 2008 by Aaron Seigo <aseigo@kde.org> |
3 | * Copyright 2008 Marco Martin <notmart@gmail.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU Library General Public License as |
7 | * published by the Free Software Foundation; either version 2, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details |
14 | * |
15 | * You should have received a copy of the GNU Library General Public |
16 | * License along with this program; if not, write to the |
17 | * Free Software Foundation, Inc., |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #ifndef PLASMA_FRAMESVG_H |
22 | #define PLASMA_FRAMESVG_H |
23 | |
24 | #include <QtCore/QObject> |
25 | #include <QtGui/QPixmap> |
26 | |
27 | #include <plasma/plasma_export.h> |
28 | |
29 | #include <plasma/plasma.h> |
30 | #include <plasma/svg.h> |
31 | |
32 | class QPainter; |
33 | class QPoint; |
34 | class QPointF; |
35 | class QRect; |
36 | class QRectF; |
37 | class QSize; |
38 | class QSizeF; |
39 | class QMatrix; |
40 | |
41 | namespace Plasma |
42 | { |
43 | |
44 | class FrameSvgPrivate; |
45 | |
46 | /** |
47 | * @class FrameSvg plasma/framesvg.h <Plasma/FrameSvg> |
48 | * |
49 | * @short Provides an SVG with borders. |
50 | * |
51 | * When using SVG images for a background of an object that may change |
52 | * its aspect ratio, such as a dialog, simply scaling a single image |
53 | * may not be enough. |
54 | * |
55 | * FrameSvg allows SVGs to provide several elements for borders as well |
56 | * as a central element, each of which are scaled individually. These |
57 | * elements should be named |
58 | * |
59 | * - @c center - the central element, which will be scaled in both directions |
60 | * - @c top - the top border; the height is fixed, but it will be scaled |
61 | * horizontally to the same width as @c center |
62 | * - @c bottom - the bottom border; scaled in the same way as @c top |
63 | * - @c left - the left border; the width is fixed, but it will be scaled |
64 | * vertically to the same height as @c center |
65 | * - @c right - the right border; scaled in the same way as @c left |
66 | * - @c topleft - fixed size; must be the same height as @c top and the same |
67 | * width as @c left |
68 | * - @c bottomleft, @c topright, @c bottomright - similar to @c topleft |
69 | * |
70 | * @c center must exist, but all the others are optional. @c topleft and |
71 | * @c topright will be ignored if @c top does not exist, and similarly for |
72 | * @c bottomleft and @c bottomright. |
73 | * |
74 | * @see Plasma::Svg |
75 | **/ |
76 | class PLASMA_EXPORT FrameSvg : public Svg |
77 | { |
78 | Q_OBJECT |
79 | |
80 | Q_FLAGS(EnabledBorders) |
81 | Q_PROPERTY(EnabledBorders enabledBorders READ enabledBorders WRITE setEnabledBorders) |
82 | |
83 | public: |
84 | /** |
85 | * These flags represents what borders should be drawn |
86 | */ |
87 | enum EnabledBorder { |
88 | NoBorder = 0, |
89 | TopBorder = 1, |
90 | BottomBorder = 2, |
91 | LeftBorder = 4, |
92 | RightBorder = 8, |
93 | AllBorders = TopBorder | BottomBorder | LeftBorder | RightBorder |
94 | }; |
95 | Q_DECLARE_FLAGS(EnabledBorders, EnabledBorder) |
96 | |
97 | /** |
98 | * Constructs a new FrameSvg that paints the proper named subelements |
99 | * as borders. It may also be used as a regular Plasma::Svg object |
100 | * for direct access to elements in the Svg. |
101 | * |
102 | * @param parent options QObject to parent this to |
103 | * |
104 | * @related Plasma::Theme |
105 | */ |
106 | explicit FrameSvg(QObject *parent = 0); |
107 | ~FrameSvg(); |
108 | |
109 | /** |
110 | * Loads a new Svg |
111 | * @param imagePath the new file |
112 | */ |
113 | Q_INVOKABLE void setImagePath(const QString &path); |
114 | |
115 | /** |
116 | * Sets what borders should be painted |
117 | * @param flags borders we want to paint |
118 | */ |
119 | void setEnabledBorders(const EnabledBorders borders); |
120 | |
121 | /** |
122 | * Convenience method to get the enabled borders |
123 | * @return what borders are painted |
124 | */ |
125 | EnabledBorders enabledBorders() const; |
126 | |
127 | /** |
128 | * Resize the frame maintaining the same border size |
129 | * @param size the new size of the frame |
130 | */ |
131 | Q_INVOKABLE void resizeFrame(const QSizeF &size); |
132 | |
133 | /** |
134 | * @returns the size of the frame |
135 | */ |
136 | Q_INVOKABLE QSizeF frameSize() const; |
137 | |
138 | /** |
139 | * Returns the margin size given the margin edge we want |
140 | * @param edge the margin edge we want, top, bottom, left or right |
141 | * @return the margin size |
142 | */ |
143 | Q_INVOKABLE qreal marginSize(const Plasma::MarginEdge edge) const; |
144 | |
145 | /** |
146 | * Convenience method that extracts the size of the four margins |
147 | * in the four output parameters |
148 | * @param left left margin size |
149 | * @param top top margin size |
150 | * @param right right margin size |
151 | * @param bottom bottom margin size |
152 | */ |
153 | Q_INVOKABLE void getMargins(qreal &left, qreal &top, qreal &right, qreal &bottom) const; |
154 | |
155 | /** |
156 | * @return the rectangle of the center element, taking the margins into account. |
157 | */ |
158 | Q_INVOKABLE QRectF contentsRect() const; |
159 | |
160 | /** |
161 | * Sets the prefix (@see setElementPrefix) to 'north', 'south', 'west' and 'east' |
162 | * when the location is TopEdge, BottomEdge, LeftEdge and RightEdge, |
163 | * respectively. Clears the prefix in other cases. |
164 | * |
165 | * The prefix must exist in the SVG document, which means that this can only be |
166 | * called successfully after setImagePath is called. |
167 | * @param location location in the UI this frame will be drawn |
168 | */ |
169 | Q_INVOKABLE void setElementPrefix(Plasma::Location location); |
170 | |
171 | /** |
172 | * Sets the prefix for the SVG elements to be used for painting. For example, |
173 | * if prefix is 'active', then instead of using the 'top' element of the SVG |
174 | * file to paint the top border, 'active-top' element will be used. The same |
175 | * goes for other SVG elements. |
176 | * |
177 | * If the elements with prefixes are not present, the default ones are used. |
178 | * (for the sake of speed, the test is present only for the 'center' element) |
179 | * |
180 | * Setting the prefix manually resets the location to Floating. |
181 | * |
182 | * The prefix must exist in the SVG document, which means that this can only be |
183 | * called successfully after setImagePath is called. |
184 | * |
185 | * @param prefix prefix for the SVG elements that make up the frame |
186 | */ |
187 | Q_INVOKABLE void setElementPrefix(const QString & prefix); |
188 | |
189 | /** |
190 | * @return true if the svg has the necessary elements with the given prefix |
191 | * to draw a frame |
192 | * @param prefix the given prefix we want to check if drawable |
193 | */ |
194 | Q_INVOKABLE bool hasElementPrefix(const QString & prefix) const; |
195 | |
196 | /** |
197 | * This is an overloaded method provided for convenience equivalent to |
198 | * hasElementPrefix("north"), hasElementPrefix("south") |
199 | * hasElementPrefix("west") and hasElementPrefix("east") |
200 | * @return true if the svg has the necessary elements with the given prefix |
201 | * to draw a frame. |
202 | * @param location the given prefix we want to check if drawable |
203 | */ |
204 | Q_INVOKABLE bool hasElementPrefix(Plasma::Location location) const; |
205 | |
206 | /** |
207 | * Returns the prefix for SVG elements of the FrameSvg |
208 | * @return the prefix |
209 | */ |
210 | Q_INVOKABLE QString prefix(); |
211 | |
212 | /** |
213 | * Returns a mask that tightly contains the fully opaque areas of the svg |
214 | * @return a region of opaque areas |
215 | */ |
216 | Q_INVOKABLE QRegion mask() const; |
217 | |
218 | /** |
219 | * @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 |
220 | */ |
221 | QPixmap alphaMask() const; |
222 | |
223 | /** |
224 | * Sets whether saving all the rendered prefixes in a cache or not |
225 | * @param cache if use the cache or not |
226 | */ |
227 | Q_INVOKABLE void setCacheAllRenderedFrames(bool cache); |
228 | |
229 | /** |
230 | * @return if all the different prefixes should be kept in a cache when rendered |
231 | */ |
232 | Q_INVOKABLE bool cacheAllRenderedFrames() const; |
233 | |
234 | /** |
235 | * Deletes the internal cache freeing memory: use this if you want to switch the rendered |
236 | * element and you don't plan to switch back to the previous one for a long time and you |
237 | * used setUsingRenderingCache(true) |
238 | */ |
239 | Q_INVOKABLE void clearCache(); |
240 | |
241 | /** |
242 | * Returns a pixmap of the SVG represented by this object. |
243 | * |
244 | * @param elelementId the ID string of the element to render, or an empty |
245 | * string for the whole SVG (the default) |
246 | * @return a QPixmap of the rendered SVG |
247 | */ |
248 | Q_INVOKABLE QPixmap framePixmap(); |
249 | |
250 | /** |
251 | * Paints the loaded SVG with the elements that represents the border |
252 | * @param painter the QPainter to use |
253 | * @param target the target rectangle on the paint device |
254 | * @param source the portion rectangle of the source image |
255 | */ |
256 | Q_INVOKABLE void paintFrame(QPainter *painter, const QRectF &target, |
257 | const QRectF &source = QRectF()); |
258 | |
259 | /** |
260 | * Paints the loaded SVG with the elements that represents the border |
261 | * This is an overloaded member provided for convenience |
262 | * @param painter the QPainter to use |
263 | * @param pos where to paint the svg |
264 | */ |
265 | Q_INVOKABLE void paintFrame(QPainter *painter, const QPointF &pos = QPointF(0, 0)); |
266 | |
267 | private: |
268 | FrameSvgPrivate *const d; |
269 | friend class Applet; |
270 | |
271 | Q_PRIVATE_SLOT(d, void updateSizes()) |
272 | Q_PRIVATE_SLOT(d, void updateNeeded()) |
273 | }; |
274 | |
275 | } // Plasma namespace |
276 | |
277 | Q_DECLARE_OPERATORS_FOR_FLAGS(Plasma::FrameSvg::EnabledBorders) |
278 | |
279 | #endif // multiple inclusion guard |
280 | |