QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskBoxBorderMetrics.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskBoxBorderMetrics.h"
7
8#include <qhashfunctions.h>
9#include <qvariant.h>
10#include <qrect.h>
11
12static void qskRegisterBoxBorderMetrics()
13{
14 qRegisterMetaType< QskBoxBorderMetrics >();
15
16#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
17 QMetaType::registerEqualsComparator< QskBoxBorderMetrics >();
18#endif
19
20 QMetaType::registerConverter< QskMargins, QskBoxBorderMetrics >(
21 []( const QskMargins& margins ) { return QskBoxBorderMetrics( margins ); } );
22
23 QMetaType::registerConverter< int, QskBoxBorderMetrics >(
24 []( int width ) { return QskBoxBorderMetrics( width ); } );
25
26 QMetaType::registerConverter< qreal, QskBoxBorderMetrics >(
27 []( qreal width ) { return QskBoxBorderMetrics( width ); } );
28}
29
30Q_CONSTRUCTOR_FUNCTION( qskRegisterBoxBorderMetrics )
31
32static inline qreal qskToAbsolute( qreal length, qreal percentage )
33{
34 // 100% means -> 0.5 of length
35 percentage = qBound( 0.0, percentage, 100.0 );
36 return percentage / 100.0 * 0.5 * length;
37}
38
39void QskBoxBorderMetrics::setSizeMode( Qt::SizeMode sizeMode ) noexcept
40{
41 m_sizeMode = sizeMode;
42}
43
44void QskBoxBorderMetrics::setWidths( const QskMargins& widths ) noexcept
45{
46 m_widths.setLeft( qMax( widths.left(), 0.0 ) );
47 m_widths.setTop( qMax( widths.top(), 0.0 ) );
48 m_widths.setRight( qMax( widths.right(), 0.0 ) );
49 m_widths.setBottom( qMax( widths.bottom(), 0.0 ) );
50}
51
52void QskBoxBorderMetrics::setWidthAt( Qt::Edges edges, qreal width ) noexcept
53{
54 m_widths.setMarginsAt( edges, qMax( width, 0.0 ) );
55}
56
57QskBoxBorderMetrics QskBoxBorderMetrics::toAbsolute( const QSizeF& size ) const noexcept
58{
59 if ( m_sizeMode != Qt::RelativeSize )
60 return *this;
61
62 QskBoxBorderMetrics absoluted = *this;
63
64 auto& w = absoluted.m_widths;
65
66 if ( size.isEmpty() )
67 {
68 w = QskMargins();
69 }
70 else
71 {
72 w.setLeft( qskToAbsolute( size.width(), w.left() ) );
73 w.setTop( qskToAbsolute( size.height(), w.top() ) );
74 w.setRight( qskToAbsolute( size.width(), w.right() ) );
75 w.setBottom( qskToAbsolute( size.height(), w.bottom() ) );
76 }
77
78 absoluted.m_sizeMode = Qt::AbsoluteSize;
79
80 return absoluted;
81}
82
83QRectF QskBoxBorderMetrics::adjustedRect( const QRectF& rect ) const
84{
85 if ( m_sizeMode == Qt::AbsoluteSize )
86 return rect.marginsRemoved( m_widths );
87
88 const auto m = toAbsolute( rect.size() );
89 return rect.marginsRemoved( m.m_widths );
90}
91
92QskBoxBorderMetrics QskBoxBorderMetrics::interpolated(
93 const QskBoxBorderMetrics& to, qreal ratio ) const noexcept
94{
95 if ( ( *this == to ) || ( m_sizeMode != to.m_sizeMode ) )
96 return to;
97
98 const auto widths = m_widths.interpolated( to.m_widths, ratio );
99 return QskBoxBorderMetrics( widths, m_sizeMode );
100}
101
102QVariant QskBoxBorderMetrics::interpolate(
103 const QskBoxBorderMetrics& from, const QskBoxBorderMetrics& to,
104 qreal progress )
105{
106 return QVariant::fromValue( from.interpolated( to, progress ) );
107}
108
109QskHashValue QskBoxBorderMetrics::hash( QskHashValue seed ) const noexcept
110{
111 auto hash = qHashBits( &m_widths, sizeof( m_widths ), seed );
112
113 const int mode = m_sizeMode;
114 return qHashBits( &mode, sizeof( mode ), hash );
115}
116
117#ifndef QT_NO_DEBUG_STREAM
118
119#include <qdebug.h>
120
121QDebug operator<<( QDebug debug, const QskBoxBorderMetrics& metrics )
122{
123 QDebugStateSaver saver( debug );
124 debug.nospace();
125
126 debug << "BoxBorder" << "( ";
127
128 if ( metrics.sizeMode() != Qt::AbsoluteSize )
129 debug << metrics.sizeMode() << ", ";
130
131 const auto& w = metrics.widths();
132
133 if ( metrics.isEquidistant() )
134 {
135 debug << w.left();
136 }
137 else
138 {
139 const char s[] = ", ";
140 debug << w.left() << s << w.top() << s << w.right() << s << w.bottom();
141 }
142
143 debug << " )";
144
145 return debug;
146}
147
148#endif
149
150#include "moc_QskBoxBorderMetrics.cpp"