6#include "QskSliderSkinlet.h"
8#include "QskFunctions.h"
19static QRectF qskInnerRect( const
QskSlider* slider,
20 const QRectF& contentsRect,
QskAspect::Subcontrol subControl )
26 const qreal extent = slider->metric( subControl |
QskAspect::Size, &status );
28 if ( slider->orientation() == Qt::Horizontal )
30 if ( status.
isValid() && ( extent < r.height() ) )
32 r.setTop( r.center().y() - 0.5 * extent );
33 r.setHeight( extent );
38 if ( status.
isValid() && ( extent < r.width() ) )
40 r.setLeft( r.center().x() - 0.5 * extent );
48static inline bool qskHasGraduation(
const QskSlider* slider )
50 if ( slider->stepSize() )
52 switch( slider->graduationPolicy() )
58 return slider->isSnapping();
68static inline QPair< qreal, qreal > qskTickSpan( qreal min, qreal max, qreal length )
73 min += 0.5 * ( max - min - length );
81QskSliderSkinlet::QskSliderSkinlet(
QskSkin* skin )
84 setNodeRoles( { PanelRole, GrooveRole, FillRole, TicksRole, HandleRole } );
87QskSliderSkinlet::~QskSliderSkinlet()
91QRectF QskSliderSkinlet::subControlRect(
const QskSkinnable* skinnable,
94 const auto slider =
static_cast< const QskSlider*
>( skinnable );
96 if ( subControl == Q::Panel )
97 return panelRect( slider, contentsRect );
99 if ( subControl == Q::Groove )
100 return qskInnerRect( slider, contentsRect, Q::Groove );
102 if ( subControl == Q::Fill )
103 return fillRect( slider, contentsRect );
105 if ( subControl == Q::Scale )
106 return subControlRect( skinnable, contentsRect, Q::Groove );
108 if ( subControl == Q::Handle )
109 return handleRect( slider, contentsRect );
111 return Inherited::subControlRect( skinnable, contentsRect, subControl );
114QSGNode* QskSliderSkinlet::updateSubNode(
115 const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node )
const
117 const auto slider =
static_cast< const QskSlider*
>( skinnable );
122 return updateBoxNode( slider, node, Q::Panel );
125 return updateBoxNode( slider, node, Q::Groove );
128 return updateBoxNode( slider, node, Q::Fill );
131 return updateBoxNode( slider, node, Q::Handle );
134 return updateSeriesNode( slider, Q::Tick, node );
137 return Inherited::updateSubNode( skinnable, nodeRole, node );
140int QskSliderSkinlet::sampleCount(
const QskSkinnable* skinnable,
143 if ( subControl == Q::Tick )
145 const auto slider =
static_cast< const QskSlider*
>( skinnable );
146 return graduation( slider ).count();
149 return Inherited::sampleCount( skinnable, subControl );
152QVariant QskSliderSkinlet::sampleAt(
const QskSkinnable* skinnable,
155 if ( subControl == Q::Tick )
157 const auto slider =
static_cast< const QskSlider*
>( skinnable );
158 return graduation( slider ).value( index );
161 return Inherited::sampleAt( skinnable, subControl, index );
164QskAspect::States QskSliderSkinlet::sampleStates(
167 auto states = Inherited::sampleStates( skinnable, subControl, index );
169 if ( subControl == Q::Tick )
171 const auto tickValue = sampleAt( skinnable, subControl, index );
172 if ( tickValue.canConvert< qreal >() )
174 const auto slider =
static_cast< const QskSlider*
>( skinnable );
176 if ( tickValue.value< qreal >() <= slider->value() )
184QRectF QskSliderSkinlet::sampleRect(
185 const QskSkinnable* skinnable,
const QRectF& contentsRect,
188 if ( subControl == Q::Tick )
190 const auto slider =
static_cast< const QskSlider*
>( skinnable );
191 return tickRect( slider, contentsRect, index );
194 return Inherited::sampleRect( skinnable, contentsRect, subControl, index );
197QSGNode* QskSliderSkinlet::updateSampleNode(
const QskSkinnable* skinnable,
200 if ( subControl == Q::Tick )
202 const auto slider =
static_cast< const QskSlider*
>( skinnable );
203 const auto rect = sampleRect( slider, slider->
contentsRect(), subControl, index );
205 return updateBoxNode( skinnable, node, rect, subControl );
208 return Inherited::updateSampleNode( skinnable, subControl, index, node );
211QRectF QskSliderSkinlet::panelRect(
212 const QskSlider* slider,
const QRectF& contentsRect )
const
214 auto r = contentsRect;
217 if ( size > 0 && size < r.height() )
221 if ( slider->orientation() == Qt::Horizontal )
222 r = qskAlignedRectF( r, r.width(), size, alignment & Qt::AlignVertical_Mask );
224 r = qskAlignedRectF( r, size, r.height(), alignment & Qt::AlignHorizontal_Mask );
230QRectF QskSliderSkinlet::fillRect(
231 const QskSlider* slider,
const QRectF& contentsRect )
const
233 const auto pos = qBound( 0.0, slider->handlePosition(), 1.0 );
235 auto r = qskInnerRect( slider, contentsRect, QskSlider::Fill );
237 auto scaleRect = subControlRect( slider, contentsRect, Q::Scale );
239 if ( slider->orientation() == Qt::Horizontal )
240 r.setRight( scaleRect.left() + pos * scaleRect.width() );
242 r.setTop( scaleRect.bottom() - pos * scaleRect.height() );
247QRectF QskSliderSkinlet::handleRect(
248 const QskSlider* slider,
const QRectF& contentsRect )
const
251 const auto pos = qBound( 0.0, slider->handlePosition(), 1.0 );
253 const auto r = subControlRect( slider, contentsRect, Q::Scale );
254 auto center = r.center();
256 if ( slider->orientation() == Qt::Horizontal )
258 if ( handleSize.height() < 0.0 )
259 handleSize.setHeight( r.height() );
261 if ( handleSize.width() < 0.0 )
262 handleSize.setWidth( handleSize.height() );
264 center.setX( r.left() + pos * r.width() );
268 if ( handleSize.width() < 0.0 )
269 handleSize.setWidth( r.width() );
271 if ( handleSize.height() < 0.0 )
272 handleSize.setHeight( handleSize.width() );
274 center.setY( r.bottom() - pos * r.height() );
277 QRectF handleRect( 0, 0, handleSize.width(), handleSize.height() );
278 handleRect.moveCenter( center );
283QRectF QskSliderSkinlet::tickRect(
const QskSlider* slider,
284 const QRectF& contentsRect,
int index )
const
286 const auto tickValue = sampleAt( slider, Q::Tick, index );
287 if ( !tickValue.canConvert< qreal >() )
290 const auto tickPos = slider->valueAsRatio( tickValue.value< qreal >() );
292 const auto r = subControlRect( slider, contentsRect, Q::Scale );
294 const auto padding = slider->
paddingHint( Q::Scale );
297 if( slider->orientation() == Qt::Horizontal )
299 const auto x = tickPos * r.width() - 0.5 * size.width();
301 const auto span = qskTickSpan(
302 padding.top(), r.height() - padding.bottom(), size.height() );
304 return QRectF( r.x() + x, r.y() + span.first,
305 size.width(), span.second - span.first );
309 const auto y = tickPos * r.height() + 0.5 * size.height();
311 const auto span = qskTickSpan(
312 padding.left(), r.width() - padding.right(), size.width() );
314 return QRectF( r.x() + span.first, r.bottom() - y,
315 span.second - span.first, size.height() );
319QSizeF QskSliderSkinlet::sizeHint(
const QskSkinnable* skinnable,
320 Qt::SizeHint which,
const QSizeF& )
const
322 if ( which != Qt::PreferredSize )
326 hint = hint.expandedTo( skinnable->
strutSizeHint( Q::Groove ) );
327 hint = hint.expandedTo( skinnable->
strutSizeHint( Q::Fill ) );
328 hint = hint.expandedTo( skinnable->
strutSizeHint( Q::Handle ) );
333QVector< qreal > QskSliderSkinlet::graduation(
const QskSlider* slider )
const
335 QVector< qreal > graduation;
337 if ( qskHasGraduation( slider ) )
339 const auto from = slider->minimum();
340 const auto to = slider->maximum();
342 auto step = slider->stepSize();
346 const auto n = qCeil( ( to - from ) / step ) - 1;
348 graduation.reserve( n );
350 for (
int i = 1; i <= n; i++ )
351 graduation += from + i * step;
357#include "moc_QskSliderSkinlet.cpp"
Lookup key for a QskSkinHintTable.
Subcontrol
For use within the rendering or lay-outing of a specific QskSkinnable.
QRectF subControlContentsRect(QskAspect::Subcontrol) const
QRectF contentsRect() const
QMarginsF paddingHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a padding hint.
QSizeF strutSizeHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a strut size hint.
qreal metric(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a metric hint.
Qt::Alignment alignmentHint(QskAspect, Qt::Alignment=Qt::Alignment()) const
Retrieves an alignment hint.