qskinny/src/controls/QskPageIndicatorSkinlet.cpp

181 lines
5.4 KiB
C++
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
2023-04-06 09:23:37 +02:00
* SPDX-License-Identifier: BSD-3-Clause
2017-07-21 18:21:34 +02:00
*****************************************************************************/
#include "QskPageIndicatorSkinlet.h"
2018-08-03 08:15:28 +02:00
#include "QskPageIndicator.h"
2017-07-21 18:21:34 +02:00
2020-11-22 15:27:58 +01:00
#include "QskSGNode.h"
2022-01-04 13:58:34 +01:00
#include "QskFunctions.h"
static QRectF qskBulletRect( const QskPageIndicator* indicator,
const QRectF& rect, int index )
{
using Q = QskPageIndicator;
2022-01-04 14:34:15 +01:00
const auto n = indicator->count();
if ( n <= 0 || index < 0 || index >= n )
return QRectF();
2022-01-04 13:58:34 +01:00
2022-01-04 15:58:49 +01:00
if ( indicator->layoutMirroring() )
{
if ( indicator->orientation() == Qt::Horizontal )
index = n - ( index + 1 );
}
2022-01-04 13:58:34 +01:00
const auto size = indicator->strutSizeHint( Q::Bullet );
2022-01-04 14:34:15 +01:00
const qreal spacing = indicator->spacingHint( Q::Panel );
const auto alignment = indicator->alignmentHint( Q::Panel, Qt::AlignCenter );
2022-01-04 13:58:34 +01:00
2022-01-04 14:34:15 +01:00
qreal x, y;
2022-01-04 13:58:34 +01:00
if ( indicator->orientation() == Qt::Horizontal )
{
2022-01-04 14:34:15 +01:00
const auto maxWidth = n * size.width() + ( n - 1 ) * spacing;
const auto r = qskAlignedRectF( rect, maxWidth, size.height(), alignment );
2022-03-23 11:54:34 +01:00
2022-01-04 14:34:15 +01:00
x = r.x() + index * ( size.width() + spacing );
y = r.y();
2022-01-04 13:58:34 +01:00
}
else
{
2022-01-04 14:34:15 +01:00
const auto maxHeight = n * size.height() + ( n - 1 ) * spacing;
const auto r = qskAlignedRectF( rect, maxHeight, size.height(), alignment );
2022-03-23 11:54:34 +01:00
2022-01-04 14:34:15 +01:00
x = r.x();
y = r.y() + index * ( size.height() + spacing );;
2022-01-04 13:58:34 +01:00
}
return QRectF( x, y, size.width(), size.height() );
}
2018-08-03 08:30:23 +02:00
2018-08-03 08:15:28 +02:00
QskPageIndicatorSkinlet::QskPageIndicatorSkinlet( QskSkin* skin )
: QskSkinlet( skin )
2017-07-21 18:21:34 +02:00
{
setNodeRoles( { PanelRole, BulletsRole } );
}
QskPageIndicatorSkinlet::~QskPageIndicatorSkinlet()
{
}
QRectF QskPageIndicatorSkinlet::subControlRect( const QskSkinnable* skinnable,
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
2017-07-21 18:21:34 +02:00
{
if ( subControl == QskPageIndicator::Panel )
return contentsRect;
2017-07-21 18:21:34 +02:00
return Inherited::subControlRect( skinnable, contentsRect, subControl );
2017-07-21 18:21:34 +02:00
}
2018-08-03 08:15:28 +02:00
QSGNode* QskPageIndicatorSkinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
2017-09-01 11:55:55 +02:00
{
2022-01-04 13:58:34 +01:00
using Q = QskPageIndicator;
2017-09-01 11:55:55 +02:00
2018-08-03 08:15:28 +02:00
switch ( nodeRole )
2017-09-01 11:55:55 +02:00
{
case PanelRole:
2022-01-04 13:58:34 +01:00
return updateBoxNode( skinnable, node, Q::Panel );
2017-09-01 11:55:55 +02:00
case BulletsRole:
2022-01-04 13:58:34 +01:00
return updateSeriesNode( skinnable, Q::Bullet, node );
2017-09-01 11:55:55 +02:00
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
2022-01-04 13:58:34 +01:00
int QskPageIndicatorSkinlet::sampleCount(
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const
2017-07-21 18:21:34 +02:00
{
using Q = QskPageIndicator;
2018-08-03 08:15:28 +02:00
2022-01-04 13:58:34 +01:00
if ( subControl == Q::Bullet )
2017-07-21 18:21:34 +02:00
{
2022-01-04 13:58:34 +01:00
const auto indicator = static_cast< const QskPageIndicator* >( skinnable );
return indicator->count();
2017-07-21 18:21:34 +02:00
}
2017-09-01 13:09:24 +02:00
2022-01-04 13:58:34 +01:00
return Inherited::sampleCount( skinnable, subControl );
}
2017-07-21 18:21:34 +02:00
2022-01-04 13:58:34 +01:00
QRectF QskPageIndicatorSkinlet::sampleRect( const QskSkinnable* skinnable,
const QRectF& contentsRect, QskAspect::Subcontrol subControl, int index ) const
{
using Q = QskPageIndicator;
2020-12-17 16:14:56 +01:00
2022-01-04 13:58:34 +01:00
if ( subControl == Q::Bullet )
2017-07-21 18:21:34 +02:00
{
2022-01-04 13:58:34 +01:00
const auto indicator = static_cast< const QskPageIndicator* >( skinnable );
2020-12-17 16:14:56 +01:00
2022-01-04 13:58:34 +01:00
const auto rect = indicator->subControlContentsRect( Q::Panel );
return qskBulletRect( indicator, rect, index );
}
2021-08-04 09:31:16 +02:00
2022-01-04 13:58:34 +01:00
return Inherited::sampleRect( skinnable, contentsRect, subControl, index );
2017-07-21 18:21:34 +02:00
}
2022-01-04 13:58:34 +01:00
int QskPageIndicatorSkinlet::sampleIndexAt(
const QskSkinnable* skinnable, const QRectF& contentsRect,
QskAspect::Subcontrol subControl, const QPointF& pos ) const
2017-07-21 18:21:34 +02:00
{
2022-01-04 13:58:34 +01:00
// TODO ...
return Inherited::sampleIndexAt( skinnable, contentsRect, subControl, pos );
}
2017-07-21 18:21:34 +02:00
2022-01-04 13:58:34 +01:00
QSGNode* QskPageIndicatorSkinlet::updateSampleNode( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl, int index, QSGNode* node ) const
{
using Q = QskPageIndicator;
2017-07-21 18:21:34 +02:00
2022-01-04 13:58:34 +01:00
if ( subControl == Q::Bullet )
2017-07-21 18:21:34 +02:00
{
2022-01-04 13:58:34 +01:00
auto indicator = static_cast< const QskPageIndicator* >( skinnable );
2017-07-21 18:21:34 +02:00
2022-01-04 13:58:34 +01:00
const auto rect = sampleRect( indicator, indicator->contentsRect(), Q::Bullet, index );
const auto ratio = indicator->valueRatioAt( index );
2022-02-20 11:06:48 +01:00
/*
QskSkinnable::effectiveSkinHint() does not add the skinStates(), when
the aspect already has a state. So we need add thmen here.
*/
const auto selectedStates = Q::Selected | indicator->skinStates();
2022-01-04 13:58:34 +01:00
return QskSkinlet::updateInterpolatedBoxNode( skinnable, node,
2022-02-20 11:06:48 +01:00
rect, Q::Bullet, Q::Bullet | selectedStates, ratio );
2017-07-21 18:21:34 +02:00
}
2022-01-04 13:58:34 +01:00
return nullptr;
2017-07-21 18:21:34 +02:00
}
QSizeF QskPageIndicatorSkinlet::sizeHint( const QskSkinnable* skinnable,
Qt::SizeHint which, const QSizeF& ) const
{
using Q = QskPageIndicator;
if ( which != Qt::PreferredSize )
return QSizeF();
const auto indicator = static_cast< const QskPageIndicator* >( skinnable );
2022-01-04 13:58:34 +01:00
QSizeF size( 0.0, 0.0 );
const int n = indicator->count();
2022-01-04 13:58:34 +01:00
if ( n > 0 )
{
2022-01-04 13:58:34 +01:00
size = indicator->strutSizeHint( Q::Bullet );
const qreal spacing = indicator->spacingHint( Q::Panel );
2022-01-04 13:58:34 +01:00
if ( indicator->orientation() == Qt::Horizontal )
size.rwidth() += ( n - 1 ) * ( size.width() + spacing );
else
size.rheight() += ( n - 1 ) * ( size.height() + spacing );
}
2022-01-04 13:58:34 +01:00
const auto hint = indicator->outerBoxSize( Q::Panel, size );
return hint.expandedTo( indicator->strutSizeHint( Q::Panel ) );
}
2017-07-21 18:21:34 +02:00
#include "moc_QskPageIndicatorSkinlet.cpp"