QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskStippleMetrics.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskStippleMetrics.h"
7
8#include <qhashfunctions.h>
9#include <qpen.h>
10#include <qvariant.h>
11
12static void qskRegisterStippleMetrics()
13{
14 qRegisterMetaType< QskStippleMetrics >();
15
16#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
17 QMetaType::registerEqualsComparator< QskStippleMetrics >();
18#endif
19
20 QMetaType::registerConverter< QPen, QskStippleMetrics >(
21 []( const QPen& pen ) { return QskStippleMetrics( pen ); } );
22
23 QMetaType::registerConverter< Qt::PenStyle, QskStippleMetrics >(
24 []( Qt::PenStyle style ) { return QskStippleMetrics( style ); } );
25}
26
27Q_CONSTRUCTOR_FUNCTION( qskRegisterStippleMetrics )
28
29QVector< qreal > qskDashPattern( Qt::PenStyle style )
30{
31 static const QVector< qreal > pattern[] =
32 {
33 {}, { 1 }, { 4, 2 }, { 1, 2 },
34 { 4, 2, 1, 2 }, { 4, 2, 1, 2, 1, 2 }, {}
35 };
36
37 return pattern[ style ];
38}
39
40static inline qreal qskInterpolated( qreal from, qreal to, qreal ratio )
41{
42 return from + ( to - from ) * ratio;
43}
44
45static inline QVector< qreal > qskInterpolatedSpaces(
46 const QVector< qreal >& pattern, qreal progress )
47{
48 QVector< qreal > interpolated;
49 interpolated.reserve( pattern.count() );
50
51 for ( int i = 1; i < pattern.count(); i += 2 )
52 interpolated[i] = progress * pattern[i];
53
54 return interpolated;
55}
56
57QskStippleMetrics::QskStippleMetrics( Qt::PenStyle penStyle )
58 : m_pattern( qskDashPattern( penStyle ) )
59{
60}
61
62QskStippleMetrics::QskStippleMetrics( const QPen& pen )
63 : QskStippleMetrics( pen.style() )
64{
65 if ( pen.style() == Qt::CustomDashLine )
66 {
67 m_offset = pen.dashOffset();
68 m_pattern = pen.dashPattern();
69 }
70}
71
72void QskStippleMetrics::setPattern( const QVector< qreal >& pattern )
73{
74 m_pattern = pattern;
75}
76
77void QskStippleMetrics::setOffset( qreal offset ) noexcept
78{
79 m_offset = offset;
80}
81
82QskStippleMetrics QskStippleMetrics::interpolated(
83 const QskStippleMetrics& to, qreal progress ) const
84{
85 if ( *this == to )
86 return to;
87
88 const auto offset = qskInterpolated( m_offset, to.m_offset, progress );
89
90 QVector< qreal > pattern;
91
92 if ( isSolid() )
93 {
94 pattern = qskInterpolatedSpaces( to.m_pattern, progress );
95 }
96 else if ( to.isSolid() )
97 {
98 pattern = qskInterpolatedSpaces( m_pattern, 1.0 - progress );
99 }
100 else
101 {
102 const auto count = qMax( m_pattern.count(), to.m_pattern.count() );
103 pattern.reserve( count );
104
105 for ( int i = 0; i < count; i++ )
106 {
107 const auto v1 = m_pattern.value( i, 0.0 );
108 const auto v2 = to.m_pattern.value( i, 0.0 );
109
110 pattern += qskInterpolated( v1, v2, progress );
111 }
112 }
113
114 return QskStippleMetrics( pattern, offset );
115}
116
117QVariant QskStippleMetrics::interpolate(
118 const QskStippleMetrics& from, const QskStippleMetrics& to, qreal progress )
119{
120 return QVariant::fromValue( from.interpolated( to, progress ) );
121}
122
123QskHashValue QskStippleMetrics::hash( QskHashValue seed ) const noexcept
124{
125 auto hash = qHash( m_offset, seed );
126 return qHash( m_pattern, hash );
127}
128
129#ifndef QT_NO_DEBUG_STREAM
130
131#include <qdebug.h>
132
133QDebug operator<<( QDebug debug, const QskStippleMetrics& metrics )
134{
135 QDebugStateSaver saver( debug );
136 debug.nospace();
137
138 debug << "QskStippleMetrics" << '(';
139 debug << metrics.offset() << ',' << metrics.pattern();
140 debug << ')';
141
142 return debug;
143}
144
145#endif
146
147#include "moc_QskStippleMetrics.cpp"