QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskGradient.h
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#ifndef QSK_GRADIENT_H
7#define QSK_GRADIENT_H
8
9#include "QskGradientStop.h"
10
11#include <qbrush.h>
12#include <qmetatype.h>
13
17
18class QVariant;
19class QGradient;
20
21class QSK_EXPORT QskGradient
22{
23 Q_GADGET
24
25 Q_PROPERTY( Type type READ type )
26
27 Q_PROPERTY( QskLinearDirection linear READ linearDirection WRITE setLinearDirection )
28 Q_PROPERTY( QskConicDirection conic READ conicDirection WRITE setConicDirection )
29 Q_PROPERTY( QskRadialDirection radial READ radialDirection WRITE setRadialDirection )
30
31 Q_PROPERTY( QskGradientStops stops READ stops WRITE setStops )
32
33 Q_PROPERTY( SpreadMode spreadMode READ spreadMode WRITE setSpreadMode )
34 Q_PROPERTY( StretchMode stretchMode READ stretchMode WRITE setStretchMode )
35
36 Q_PROPERTY( bool valid READ isValid )
37 Q_PROPERTY( bool visible READ isVisible )
38 Q_PROPERTY( bool monochrome READ isMonochrome )
39
40 Q_CLASSINFO( "DefaultProperty", "stops" )
41
42 public:
43 enum Type
44 {
45 Stops,
46
47 Linear,
48 Radial,
49 Conic
50 };
51 Q_ENUM( Type )
52
53 enum SpreadMode
54 {
55 PadSpread,
56 ReflectSpread,
57 RepeatSpread
58 };
59 Q_ENUM( SpreadMode )
60
61 enum StretchMode
62 {
63 NoStretch,
64 StretchToSize
65 };
66 Q_ENUM( StretchMode )
67
68 QskGradient() noexcept;
69
70 QskGradient( Qt::GlobalColor );
71 QskGradient( QRgb );
72 QskGradient( const QColor& );
73 QskGradient( const QColor&, const QColor& );
74 QskGradient( QGradient::Preset );
75 QskGradient( const QskGradientStops& );
76
77 QskGradient( const QGradient& );
78
79 QskGradient( const QskGradient& ) noexcept;
80
82
83 QskGradient& operator=( const QskGradient& ) noexcept;
84
85 bool operator==( const QskGradient& ) const noexcept;
86 bool operator!=( const QskGradient& ) const noexcept;
87
88 QskGradient::Type type() const noexcept;
89
90 void setLinearDirection( const QskLinearDirection& );
91 void setLinearDirection( qreal, qreal, qreal, qreal );
92 void setLinearDirection( Qt::Orientation );
93 QskLinearDirection linearDirection() const;
94
95 void setRadialDirection( const QskRadialDirection& );
96 void setRadialDirection( const qreal x, qreal y, qreal radius );
97 void setRadialDirection( const qreal x, qreal y, qreal radiusX, qreal radiusY );
98 QskRadialDirection radialDirection() const;
99
100 void setConicDirection( qreal x, qreal y );
101
102 void setConicDirection( qreal x, qreal y,
103 qreal startAngle, qreal spanAngle = 360.0 );
104
105 void setConicDirection( qreal x, qreal y,
106 qreal startAngle, qreal spanAngle, qreal aspectRatio );
107
108 void setConicDirection( const QskConicDirection& );
109 QskConicDirection conicDirection() const;
110
111 void setDirection( Type );
112 void resetDirection();
113
114 bool isValid() const noexcept;
115 bool isMonochrome() const noexcept;
116 bool isVisible() const noexcept;
117
118 void setStops( const QskGradientStops& );
119 const QskGradientStops& stops() const noexcept;
120
121 void setStops( const QRgb );
122 void setStops( Qt::GlobalColor );
123 void setStops( const QColor& );
124
125 void setStops( const QColor&, const QColor& );
126 void setStops( QGradient::Preset );
127
128 void clearStops();
129
130 Q_INVOKABLE bool hasStopAt( qreal value ) const noexcept;
131
132 Q_INVOKABLE QColor startColor() const noexcept;
133 Q_INVOKABLE QColor endColor() const noexcept;
134
135 QRgb rgbStart() const;
136 QRgb rgbEnd() const;
137
138 void setAlpha( int alpha );
139
140 void setSpreadMode( SpreadMode );
141 SpreadMode spreadMode() const noexcept;
142
143 void setStretchMode( StretchMode );
144 StretchMode stretchMode() const noexcept;
145
146 void reverse();
147 QskGradient reversed() const;
148
149 QskGradient interpolated( const QskGradient&, qreal value ) const;
150
151 void stretchTo( const QRectF& );
152 QskGradient stretchedTo( const QSizeF& ) const;
153 QskGradient stretchedTo( const QRectF& ) const;
154
155 static QVariant interpolate( const QskGradient&,
156 const QskGradient&, qreal progress );
157
158 // all stops between [from, to] with positions streched into [0,1]
159 QskGradient extracted( qreal from, qreal start ) const;
160
161 QskHashValue hash( QskHashValue seed = 0 ) const;
162
163 Q_INVOKABLE qreal stopAt( int index ) const noexcept;
164 Q_INVOKABLE QColor colorAt( int index ) const noexcept;
165
166 int stepCount() const noexcept;
167
168 QGradient toQGradient() const;
169
170 private:
171 void updateStatusBits() const;
172
173 private:
174 QskGradientStops m_stops;
175
176 /*
177 Linear: x1, y1, x2, y2
178 Radial: centerX, centerY, radiusX, radiusY
179 Conic: centerX, centerY, startAngle, spanAngle, aspectRatio
180 */
181 qreal m_values[5] = {};
182
183 unsigned int m_type : 3;
184 unsigned int m_spreadMode : 3;
185 unsigned int m_stretchMode : 3;
186
187 mutable bool m_isDirty : 1;
188 mutable bool m_isValid : 1;
189 mutable bool m_isMonchrome : 1;
190 mutable bool m_isVisible : 1;
191};
192
193Q_DECLARE_METATYPE( QskGradient )
194
195inline QskGradient::QskGradient() noexcept
196 : m_type( Stops )
197 , m_spreadMode( PadSpread )
198 , m_stretchMode( StretchToSize )
199 , m_isDirty( false )
200 , m_isValid( false )
201 , m_isMonchrome( true )
202 , m_isVisible( false )
203{
204}
205
206inline QskGradient::QskGradient( Qt::GlobalColor color )
207 : QskGradient( QColor( color ) )
208{
209}
210
211inline QskGradient::QskGradient( QRgb rgb )
212 : QskGradient( QColor::fromRgba( rgb ) )
213{
214}
215
216inline bool QskGradient::operator!=( const QskGradient& other ) const noexcept
217{
218 return !( *this == other );
219}
220
221inline QskGradient::Type QskGradient::type() const noexcept
222{
223 return static_cast< Type >( m_type );
224}
225
226inline const QskGradientStops& QskGradient::stops() const noexcept
227{
228#if 1
229 /*
230 Returning a const& so that it is possible to write:
231 for ( const auto& stop : gradient.stops() )
232
233 Once we have changed QskGradientStop from QColor to QRgb
234 we should check if there is a better solution possible
235 */
236#endif
237 return m_stops;
238}
239
240inline void QskGradient::setStops( QRgb rgb )
241{
242 setStops( QColor::fromRgba( rgb ) );
243}
244
245inline void QskGradient::setStops( Qt::GlobalColor color )
246{
247 setStops( QColor( color ) );
248}
249
250inline QColor QskGradient::startColor() const noexcept
251{
252 return m_stops.isEmpty() ? QColor() : m_stops.first().color();
253}
254
255inline QColor QskGradient::endColor() const noexcept
256{
257 return m_stops.isEmpty() ? QColor() : m_stops.last().color();
258}
259
260inline QRgb QskGradient::rgbStart() const
261{
262 return m_stops.isEmpty() ? qRgba( 0, 0, 0, 255 ) : m_stops.first().rgb();
263}
264
265inline QRgb QskGradient::rgbEnd() const
266{
267 return m_stops.isEmpty() ? qRgba( 0, 0, 0, 255 ) : m_stops.last().rgb();
268}
269
270inline QskGradient::SpreadMode QskGradient::spreadMode() const noexcept
271{
272 return static_cast< SpreadMode >( m_spreadMode );
273}
274
275inline QskGradient::StretchMode QskGradient::stretchMode() const noexcept
276{
277 return static_cast< StretchMode >( m_stretchMode );
278}
279
280#ifndef QT_NO_DEBUG_STREAM
281
282class QDebug;
283
284QSK_EXPORT QDebug operator<<( QDebug, const QskGradient& );
285
286#endif
287
288#endif