1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QANDROIDSTYLE_P_H
41 #define QANDROIDSTYLE_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists for the convenience
48 // of qstylefactory.cpp.  This header may change from version to version
49 // without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include <QtWidgets/private/qtwidgetsglobal_p.h>
55 #include <QtWidgets/private/qfusionstyle_p.h>
56 #include <QtCore/QList>
57 #include <QtCore/QMargins>
58 #include <QtCore/QHash>
59 #include <QtCore/QVariantMap>
60 
61 QT_BEGIN_NAMESPACE
62 
63 class Q_WIDGETS_EXPORT QAndroidStyle : public QFusionStyle
64 {
65     Q_OBJECT
66 
67 public:
68     enum ItemType
69     {
70         QC_UnknownType = -1,
71         QC_View,
72         QC_GroupBox,
73         QC_Button,
74         QC_Checkbox,
75         QC_RadioButton,
76         QC_Slider,
77         QC_Switch,
78         QC_EditText,
79         QC_Combobox,
80         QC_BusyIndicator,
81         QC_ProgressBar,
82         QC_Tab,
83         QC_TabButton,
84         QC_RatingIndicator,
85         QC_SearchBox,
86         QC_CustomControl=0xf00,
87         QC_ControlMask=0xfff
88     };
89 
90     struct Android9PatchChunk
91     {
92         QVector<int> xDivs;
93         QVector<int> yDivs;
94         QVector<int> colors;
95     };
96 
97     struct AndroidItemStateInfo
98     {
AndroidItemStateInfoAndroidItemStateInfo99         AndroidItemStateInfo():state(0){}
100         int state;
101         QByteArray filePath;
102         QByteArray hashKey;
103         Android9PatchChunk chunkData;
104         QSize size;
105         QMargins padding;
106     };
107 
108     enum AndroidDrawableType
109     {
110         Color,
111         Image,
112         Clip,
113         NinePatch,
114         Gradient,
115         State,
116         Layer
117     };
118 
119     class AndroidDrawable
120     {
121     public:
122         AndroidDrawable(const QVariantMap &drawable, ItemType itemType);
123         virtual ~AndroidDrawable();
124         virtual void initPadding(const QVariantMap &drawable);
125         virtual AndroidDrawableType type() const = 0;
126         virtual void draw(QPainter *painter,const QStyleOption *opt) const = 0;
127         const QMargins &padding() const;
128         virtual QSize size() const;
129         static AndroidDrawable *fromMap(const QVariantMap &drawable, ItemType itemType);
130         static QMargins extractMargins(const QVariantMap &value);
131         virtual void setPaddingLeftToSizeWidth();
132     protected:
133         ItemType m_itemType;
134         QMargins m_padding;
135     };
136 
137     class AndroidColorDrawable: public AndroidDrawable
138     {
139     public:
140         AndroidColorDrawable(const QVariantMap &drawable, ItemType itemType);
141         virtual AndroidDrawableType type() const;
142         virtual void draw(QPainter *painter,const QStyleOption *opt) const;
143 
144     protected:
145         QColor m_color;
146     };
147 
148     class AndroidImageDrawable: public AndroidDrawable
149     {
150     public:
151         AndroidImageDrawable(const QVariantMap &drawable, ItemType itemType);
152         virtual AndroidDrawableType type() const;
153         virtual void draw(QPainter *painter,const QStyleOption *opt) const;
154         virtual QSize size() const;
155 
156     protected:
157         QString m_filePath;
158         mutable QString m_hashKey;
159         QSize m_size;
160     };
161 
162     class Android9PatchDrawable: public AndroidImageDrawable
163     {
164     public:
165         Android9PatchDrawable(const QVariantMap &drawable, ItemType itemType);
166         virtual AndroidDrawableType type() const;
167         virtual void draw(QPainter *painter, const QStyleOption *opt) const;
168     private:
169         static int calculateStretch(int boundsLimit, int startingPoint,
170                                   int srcSpace, int numStrechyPixelsRemaining,
171                                   int numFixedPixelsRemaining);
172         void extractIntArray(const QVariantList &values, QVector<int> &array);
173     private:
174         Android9PatchChunk m_chunkData;
175     };
176 
177     class AndroidGradientDrawable: public AndroidDrawable
178     {
179     public:
180         enum GradientOrientation
181         {
182             TOP_BOTTOM,
183             TR_BL,
184             RIGHT_LEFT,
185             BR_TL,
186             BOTTOM_TOP,
187             BL_TR,
188             LEFT_RIGHT,
189             TL_BR
190         };
191 
192     public:
193         AndroidGradientDrawable(const QVariantMap &drawable, ItemType itemType);
194         virtual AndroidDrawableType type() const;
195         virtual void draw(QPainter *painter, const QStyleOption *opt) const;
196         QSize size() const;
197     private:
198         mutable QLinearGradient m_gradient;
199         GradientOrientation m_orientation;
200         int m_radius;
201     };
202 
203     class AndroidClipDrawable: public AndroidDrawable
204     {
205     public:
206         AndroidClipDrawable(const QVariantMap &drawable, ItemType itemType);
207         ~AndroidClipDrawable();
208         virtual AndroidDrawableType type() const;
209         virtual void setFactor(double factor, Qt::Orientation orientation);
210         virtual void draw(QPainter *painter, const QStyleOption *opt) const;
211 
212     private:
213         double m_factor;
214         Qt::Orientation m_orientation;
215         const AndroidDrawable *m_drawable;
216     };
217 
218     class AndroidStateDrawable: public AndroidDrawable
219     {
220     public:
221         AndroidStateDrawable(const QVariantMap &drawable, ItemType itemType);
222         ~AndroidStateDrawable();
223         virtual AndroidDrawableType type() const;
224         virtual void draw(QPainter *painter, const QStyleOption *opt) const;
225         inline const AndroidDrawable *bestAndroidStateMatch(const QStyleOption *opt) const;
226         static int extractState(const QVariantMap &value);
227         virtual void setPaddingLeftToSizeWidth();
228         QSize sizeImage(const QStyleOption *opt) const;
229     private:
230         typedef QPair<int, const AndroidDrawable *> StateType;
231         QList<StateType> m_states;
232     };
233 
234     class AndroidLayerDrawable: public AndroidDrawable
235     {
236     public:
237         AndroidLayerDrawable(const QVariantMap &drawable, QAndroidStyle::ItemType itemType);
238         ~AndroidLayerDrawable();
239         virtual AndroidDrawableType type() const;
240         virtual void setFactor(int id, double factor, Qt::Orientation orientation);
241         virtual void draw(QPainter *painter, const QStyleOption *opt) const;
242         AndroidDrawable *layer(int id) const;
243         QSize size() const;
244     private:
245         typedef QPair<int, AndroidDrawable *> LayerType;
246         QList<LayerType> m_layers;
247         int m_id;
248         double m_factor;
249         Qt::Orientation m_orientation;
250     };
251 
252     class AndroidControl
253     {
254     public:
255         AndroidControl(const QVariantMap &control, ItemType itemType);
256         virtual ~AndroidControl();
257         virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w);
258         virtual QRect subElementRect(SubElement subElement,
259                                      const QStyleOption *option,
260                                      const QWidget *widget = 0) const;
261         virtual QRect subControlRect(const QStyleOptionComplex *option,
262                                      SubControl sc,
263                                      const QWidget *widget = 0) const;
264         virtual QSize sizeFromContents(const QStyleOption *opt,
265                                        const QSize &contentsSize,
266                                        const QWidget *w) const;
267         virtual QMargins padding();
268         virtual QSize size(const QStyleOption *option);
269     protected:
270         virtual const AndroidDrawable * backgroundDrawable() const;
271         const AndroidDrawable *m_background;
272         QSize m_minSize;
273         QSize m_maxSize;
274     };
275 
276     class AndroidCompoundButtonControl : public AndroidControl
277     {
278     public:
279         AndroidCompoundButtonControl(const QVariantMap &control, ItemType itemType);
280         virtual ~AndroidCompoundButtonControl();
281         virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w);
282         virtual QMargins padding();
283         virtual QSize size(const QStyleOption *option);
284     protected:
285         virtual const AndroidDrawable * backgroundDrawable() const;
286         const AndroidDrawable *m_button;
287     };
288 
289     class AndroidProgressBarControl : public AndroidControl
290     {
291     public:
292         AndroidProgressBarControl(const QVariantMap &control, ItemType itemType);
293         virtual ~AndroidProgressBarControl();
294         virtual void drawControl(const QStyleOption *option, QPainter *p, const QWidget *w);
295         virtual QRect subElementRect(SubElement subElement,
296                                      const QStyleOption *option,
297                                      const QWidget *widget = 0) const;
298 
299         QSize sizeFromContents(const QStyleOption *opt,
300                                const QSize &contentsSize,
301                                const QWidget *w) const;
302     protected:
303         AndroidDrawable *m_progressDrawable;
304         AndroidDrawable *m_indeterminateDrawable;
305         int m_secondaryProgress_id;
306         int m_progressId;
307     };
308 
309     class AndroidSeekBarControl : public AndroidProgressBarControl
310     {
311     public:
312         AndroidSeekBarControl(const QVariantMap &control, ItemType itemType);
313         virtual ~AndroidSeekBarControl();
314         virtual void drawControl(const QStyleOption *option, QPainter *p, const QWidget *w);
315         QSize sizeFromContents(const QStyleOption *opt,
316                                        const QSize &contentsSize, const QWidget *w) const;
317         QRect subControlRect(const QStyleOptionComplex *option, SubControl sc,
318                                      const QWidget *widget = 0) const;
319     private:
320         AndroidDrawable *m_seekBarThumb;
321     };
322 
323     class AndroidSpinnerControl : public AndroidControl
324     {
325     public:
326         AndroidSpinnerControl(const QVariantMap &control, ItemType itemType);
~AndroidSpinnerControl()327         virtual ~AndroidSpinnerControl(){}
328         virtual QRect subControlRect(const QStyleOptionComplex *option,
329                                      SubControl sc,
330                                      const QWidget *widget = 0) const;
331     };
332 
333     typedef QList<AndroidItemStateInfo *> AndroidItemStateInfoList;
334 
335 public:
336     QAndroidStyle();
337     ~QAndroidStyle();
338 
339     virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
340                                const QWidget *w = 0) const;
341 
342     virtual void drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p,
343                              const QWidget *w = 0) const;
344 
345     virtual QRect subElementRect(SubElement subElement, const QStyleOption *option,
346                                  const QWidget *widget = 0) const;
347     virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
348                                     const QWidget *widget = 0) const;
349     virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
350                                              const QPoint &pt, const QWidget *widget = 0) const;
351     virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
352                                  SubControl sc, const QWidget *widget = 0) const;
353 
354     virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
355                             const QWidget *widget = 0) const;
356 
357     virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
358                                    const QSize &contentsSize, const QWidget *w = 0) const;
359 
360     virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = 0,
361                                    const QWidget *widget = 0) const;
362 
363     virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
364                                         const QStyleOption *opt) const;
365 
366     int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
367                   QStyleHintReturn *returnData = 0) const;
368 
369     virtual QPalette standardPalette() const;
370     void polish(QWidget *widget);
371     void unpolish(QWidget *widget);
372 
373 private:
374     Q_DISABLE_COPY_MOVE(QAndroidStyle)
375     static ItemType qtControl(QStyle::ComplexControl control);
376     static ItemType qtControl(QStyle::ContentsType contentsType);
377     static ItemType qtControl(QStyle::ControlElement controlElement);
378     static ItemType qtControl(QStyle::PrimitiveElement primitiveElement);
379     static ItemType qtControl(QStyle::SubElement subElement);
380     static ItemType qtControl(const QString &android);
381 
382 private:
383     typedef QHash<int, AndroidControl *> AndroidControlsHash;
384     AndroidControlsHash m_androidControlsHash;
385     QPalette m_standardPalette;
386     AndroidCompoundButtonControl *checkBoxControl;
387 };
388 
389 QT_END_NAMESPACE
390 
391 #endif // QANDROIDSTYLE_P_H
392