QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskPageIndicatorSkinlet.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskPageIndicatorSkinlet.h"
7#include "QskPageIndicator.h"
8
9#include "QskSGNode.h"
10#include "QskFunctions.h"
11
12static QRectF qskBulletRect( const QskPageIndicator* indicator,
13 const QRectF& rect, int index )
14{
15 using Q = QskPageIndicator;
16
17 const auto n = indicator->count();
18 if ( n <= 0 || index < 0 || index >= n )
19 return QRectF();
20
21 if ( indicator->layoutMirroring() )
22 {
23 if ( indicator->orientation() == Qt::Horizontal )
24 index = n - ( index + 1 );
25 }
26
27 const auto size = indicator->strutSizeHint( Q::Bullet );
28 const qreal spacing = indicator->spacingHint( Q::Panel );
29 const auto alignment = indicator->alignmentHint( Q::Panel, Qt::AlignCenter );
30
31 qreal x, y;
32
33 if ( indicator->orientation() == Qt::Horizontal )
34 {
35 const auto maxWidth = n * size.width() + ( n - 1 ) * spacing;
36 const auto r = qskAlignedRectF( rect, maxWidth, size.height(), alignment );
37
38 x = r.x() + index * ( size.width() + spacing );
39 y = r.y();
40 }
41 else
42 {
43 const auto maxHeight = n * size.height() + ( n - 1 ) * spacing;
44 const auto r = qskAlignedRectF( rect, maxHeight, size.height(), alignment );
45
46 x = r.x();
47 y = r.y() + index * ( size.height() + spacing );;
48 }
49
50 return QRectF( x, y, size.width(), size.height() );
51}
52
53QskPageIndicatorSkinlet::QskPageIndicatorSkinlet( QskSkin* skin )
54 : QskSkinlet( skin )
55{
56 setNodeRoles( { PanelRole, BulletsRole } );
57}
58
59QskPageIndicatorSkinlet::~QskPageIndicatorSkinlet()
60{
61}
62
63QRectF QskPageIndicatorSkinlet::subControlRect( const QskSkinnable* skinnable,
64 const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
65{
66 if ( subControl == QskPageIndicator::Panel )
67 return contentsRect;
68
69 return Inherited::subControlRect( skinnable, contentsRect, subControl );
70}
71
72QSGNode* QskPageIndicatorSkinlet::updateSubNode(
73 const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
74{
75 using Q = QskPageIndicator;
76
77 switch ( nodeRole )
78 {
79 case PanelRole:
80 return updateBoxNode( skinnable, node, Q::Panel );
81
82 case BulletsRole:
83 return updateSeriesNode( skinnable, Q::Bullet, node );
84 }
85
86 return Inherited::updateSubNode( skinnable, nodeRole, node );
87}
88
89int QskPageIndicatorSkinlet::sampleCount(
90 const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const
91{
92 using Q = QskPageIndicator;
93
94 if ( subControl == Q::Bullet )
95 {
96 const auto indicator = static_cast< const QskPageIndicator* >( skinnable );
97 return indicator->count();
98 }
99
100 return Inherited::sampleCount( skinnable, subControl );
101}
102
103QRectF QskPageIndicatorSkinlet::sampleRect( const QskSkinnable* skinnable,
104 const QRectF& contentsRect, QskAspect::Subcontrol subControl, int index ) const
105{
106 using Q = QskPageIndicator;
107
108 if ( subControl == Q::Bullet )
109 {
110 const auto indicator = static_cast< const QskPageIndicator* >( skinnable );
111
112 const auto rect = indicator->subControlContentsRect( Q::Panel );
113 return qskBulletRect( indicator, rect, index );
114 }
115
116 return Inherited::sampleRect( skinnable, contentsRect, subControl, index );
117}
118
119int QskPageIndicatorSkinlet::sampleIndexAt(
120 const QskSkinnable* skinnable, const QRectF& contentsRect,
121 QskAspect::Subcontrol subControl, const QPointF& pos ) const
122{
123 // TODO ...
124 return Inherited::sampleIndexAt( skinnable, contentsRect, subControl, pos );
125}
126
127QSGNode* QskPageIndicatorSkinlet::updateSampleNode( const QskSkinnable* skinnable,
128 QskAspect::Subcontrol subControl, int index, QSGNode* node ) const
129{
130 using Q = QskPageIndicator;
131
132 if ( subControl == Q::Bullet )
133 {
134 auto indicator = static_cast< const QskPageIndicator* >( skinnable );
135
136 const auto rect = sampleRect( indicator, indicator->contentsRect(), Q::Bullet, index );
137 const auto ratio = indicator->valueRatioAt( index );
138
139 /*
140 QskSkinnable::effectiveSkinHint() does not add the skinStates(), when
141 the aspect already has a state. So we need add thmen here.
142 */
143 const auto selectedStates = Q::Selected | indicator->skinStates();
144
145 return QskSkinlet::updateInterpolatedBoxNode( skinnable, node,
146 rect, Q::Bullet, Q::Bullet | selectedStates, ratio );
147 }
148
149 return nullptr;
150}
151
152QSizeF QskPageIndicatorSkinlet::sizeHint( const QskSkinnable* skinnable,
153 Qt::SizeHint which, const QSizeF& ) const
154{
155 using Q = QskPageIndicator;
156
157 if ( which != Qt::PreferredSize )
158 return QSizeF();
159
160 const auto indicator = static_cast< const QskPageIndicator* >( skinnable );
161
162 QSizeF size( 0.0, 0.0 );
163 const int n = indicator->count();
164
165 if ( n > 0 )
166 {
167 size = indicator->strutSizeHint( Q::Bullet );
168 const qreal spacing = indicator->spacingHint( Q::Panel );
169
170 if ( indicator->orientation() == Qt::Horizontal )
171 size.rwidth() += ( n - 1 ) * ( size.width() + spacing );
172 else
173 size.rheight() += ( n - 1 ) * ( size.height() + spacing );
174 }
175
176 const auto hint = indicator->outerBoxSize( Q::Panel, size );
177 return hint.expandedTo( indicator->strutSizeHint( Q::Panel ) );
178}
179
180#include "moc_QskPageIndicatorSkinlet.cpp"
Subcontrol
For use within the rendering or lay-outing of a specific QskSkinnable.
Definition QskAspect.h:104
QRectF subControlContentsRect(QskAspect::Subcontrol) const
QRectF contentsRect() const
bool layoutMirroring() const
Definition QskItem.cpp:511
Describes the rendering interface of a QskControl. Change the skinlet to change the appearance of the...
Definition QskSkinlet.h:34
qreal spacingHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a spacing hint.
QSizeF strutSizeHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a strut size hint.
QSizeF outerBoxSize(QskAspect, const QSizeF &innerBoxSize) const
Calculate the size, when being expanded by paddings, indentations.
Qt::Alignment alignmentHint(QskAspect, Qt::Alignment=Qt::Alignment()) const
Retrieves an alignment hint.