QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskArcMetrics.h
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#ifndef QSK_ARC_METRICS_H
7#define QSK_ARC_METRICS_H
8
9#include "QskFunctions.h"
10
11#include <qmetatype.h>
12
13class QVariant;
14class QPainterPath;
15
16class QSK_EXPORT QskArcMetrics
17{
18 Q_GADGET
19
20 Q_PROPERTY( qreal startAngle READ startAngle WRITE setStartAngle )
21 Q_PROPERTY( qreal spanAngle READ spanAngle WRITE setSpanAngle )
22
23 Q_PROPERTY( qreal thickness READ thickness WRITE setThickness )
24 Q_PROPERTY( Qt::SizeMode sizeMode READ sizeMode WRITE setSizeMode )
25
26 public:
27 constexpr QskArcMetrics() noexcept = default;
28
29 constexpr QskArcMetrics( qreal thickness,
30 Qt::SizeMode = Qt::AbsoluteSize ) noexcept;
31
32 constexpr QskArcMetrics( qreal startAngle, qreal spanAngle, qreal thickness,
33 Qt::SizeMode = Qt::AbsoluteSize ) noexcept;
34
35 bool operator==( const QskArcMetrics& ) const noexcept;
36 bool operator!=( const QskArcMetrics& ) const noexcept;
37
38 constexpr bool isNull() const noexcept;
39
40 void setStartAngle( qreal startAngle ) noexcept;
41 constexpr qreal startAngle() const noexcept;
42
43 void setSpanAngle( qreal spanAngle ) noexcept;
44 constexpr qreal spanAngle() const noexcept;
45
46 constexpr qreal endAngle() const noexcept;
47 constexpr qreal angleAtRatio( qreal ratio ) const noexcept;
48
49 bool containsAngle( qreal ) const;
50 bool isClosed() const;
51
52 void setThickness( qreal ) noexcept;
53 constexpr qreal thickness() const noexcept;
54
55 void setSizeMode( Qt::SizeMode ) noexcept;
56 constexpr Qt::SizeMode sizeMode() const noexcept;
57
58 QskArcMetrics interpolated( const QskArcMetrics&,
59 qreal value ) const noexcept;
60
61 QskArcMetrics toAbsolute( const QSizeF& ) const noexcept;
62 QskArcMetrics toAbsolute( qreal radiusX, qreal radiusY ) const noexcept;
63 QskArcMetrics toAbsolute( qreal radius ) const noexcept;
64
65 /*
66 The arc is interpolated by pairs of points, where one point is on
67 the outer and the other on the inner side of the arc. The length between
68 these points depends on the thickness.
69
70 When radial is set the inner point lies on the line between the outer point
71 and the center of the arc. This corresponds to the lines of a conic gradient.
72
73 Otherwise the line between the inner and outer point is orthogonal to the
74 tangent at the point in the middle of the arc. This is how the width
75 of the pen is expanded by QPainter::drawArc.
76
77 Note, that the radial flag is irrelevant for circular arcs as the tangent
78 is always orthogonal to any point on the circle.
79 */
80 QPainterPath painterPath( const QRectF& ellipseRect, bool radial = false ) const;
81
82 QRectF boundingRect( const QRectF& ellipseRect ) const;
83 QSizeF boundingSize( const QSizeF& ellipseSize ) const;
84
85 QskHashValue hash( QskHashValue seed = 0 ) const noexcept;
86
87 static QVariant interpolate( const QskArcMetrics&,
88 const QskArcMetrics&, qreal progress );
89
90 private:
91 qreal m_startAngle = 0.0;
92 qreal m_spanAngle = 0.0;
93
94 qreal m_thickness = 0.0;
95
96 bool m_relativeSize = false;
97};
98
99inline constexpr QskArcMetrics::QskArcMetrics(
100 qreal thickness, Qt::SizeMode sizeMode ) noexcept
101 : QskArcMetrics( 0.0, 360.0, thickness, sizeMode )
102{
103}
104
105inline constexpr QskArcMetrics::QskArcMetrics( qreal startAngle, qreal spanAngle,
106 qreal thickness, Qt::SizeMode sizeMode ) noexcept
107 : m_startAngle( startAngle )
108 , m_spanAngle( spanAngle )
109 , m_thickness( thickness )
110 , m_relativeSize( sizeMode == Qt::RelativeSize )
111{
112}
113
114inline bool QskArcMetrics::operator==(
115 const QskArcMetrics& other ) const noexcept
116{
117 return qskFuzzyCompare( m_thickness, other.m_thickness )
118 && qskFuzzyCompare( m_startAngle, other.m_startAngle )
119 && qskFuzzyCompare( m_spanAngle, other.m_spanAngle )
120 && ( m_relativeSize == other.m_relativeSize );
121}
122
123inline bool QskArcMetrics::operator!=(
124 const QskArcMetrics& other ) const noexcept
125{
126 return !( *this == other );
127}
128
129inline constexpr bool QskArcMetrics::isNull() const noexcept
130{
131 return qFuzzyIsNull( m_thickness ) || qFuzzyIsNull( m_spanAngle );
132}
133
134inline constexpr qreal QskArcMetrics::thickness() const noexcept
135{
136 return m_thickness;
137}
138
139inline constexpr qreal QskArcMetrics::startAngle() const noexcept
140{
141 return m_startAngle;
142}
143
144inline constexpr qreal QskArcMetrics::spanAngle() const noexcept
145{
146 return m_spanAngle;
147}
148
149inline constexpr qreal QskArcMetrics::endAngle() const noexcept
150{
151 return m_startAngle + m_spanAngle;
152}
153
154inline constexpr qreal QskArcMetrics::angleAtRatio( qreal ratio ) const noexcept
155{
156 return m_startAngle + ratio * m_spanAngle;
157}
158
159inline constexpr Qt::SizeMode QskArcMetrics::sizeMode() const noexcept
160{
161 return m_relativeSize ? Qt::RelativeSize : Qt::AbsoluteSize;
162}
163
164#ifndef QT_NO_DEBUG_STREAM
165
166class QDebug;
167QSK_EXPORT QDebug operator<<( QDebug, const QskArcMetrics& );
168
169#endif
170
171Q_DECLARE_TYPEINFO( QskArcMetrics, Q_MOVABLE_TYPE );
172Q_DECLARE_METATYPE( QskArcMetrics )
173
174#endif