2021-08-02 19:17:04 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
2023-04-06 09:23:37 +02:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
2021-08-02 19:17:04 +02:00
|
|
|
*****************************************************************************/
|
2021-08-02 13:22:37 +02:00
|
|
|
|
|
|
|
#include "QskSwitchButtonSkinlet.h"
|
2021-08-27 09:45:24 +02:00
|
|
|
#include "QskSwitchButton.h"
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
static inline qreal qskEffectivePosition( const QskSwitchButton* switchButton )
|
|
|
|
{
|
2021-12-29 17:05:29 +01:00
|
|
|
auto pos = switchButton->positionHint( QskSwitchButton::Handle );
|
2021-08-03 15:02:33 +02:00
|
|
|
pos = qBound( 0.0, pos, 1.0 );
|
|
|
|
|
|
|
|
if( switchButton->isInverted() )
|
|
|
|
pos = 1.0 - pos;
|
|
|
|
|
|
|
|
if ( switchButton->orientation() == Qt::Horizontal )
|
|
|
|
{
|
|
|
|
if( switchButton->layoutMirroring() )
|
|
|
|
pos = 1.0 - pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2021-08-02 19:17:04 +02:00
|
|
|
QskSwitchButtonSkinlet::QskSwitchButtonSkinlet( QskSkin* skin )
|
2021-08-02 13:22:37 +02:00
|
|
|
: Inherited( skin )
|
|
|
|
{
|
2021-08-27 09:09:10 +02:00
|
|
|
setNodeRoles( { GrooveRole, HandleRole, RippleRole } );
|
2021-08-02 13:22:37 +02:00
|
|
|
}
|
|
|
|
|
2021-08-02 19:17:04 +02:00
|
|
|
QskSwitchButtonSkinlet::~QskSwitchButtonSkinlet()
|
|
|
|
{
|
|
|
|
}
|
2021-08-02 13:22:37 +02:00
|
|
|
|
|
|
|
QRectF QskSwitchButtonSkinlet::subControlRect( const QskSkinnable* skinnable,
|
2021-08-03 15:02:33 +02:00
|
|
|
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
2021-08-02 13:22:37 +02:00
|
|
|
{
|
|
|
|
using Q = QskSwitchButton;
|
2021-08-02 19:17:04 +02:00
|
|
|
|
|
|
|
if ( subControl == Q::Handle )
|
2021-08-02 13:22:37 +02:00
|
|
|
{
|
2021-08-03 15:02:33 +02:00
|
|
|
return handleRect( skinnable, contentsRect );
|
|
|
|
}
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
if ( subControl == Q::Groove )
|
|
|
|
{
|
|
|
|
return grooveRect( skinnable, contentsRect );
|
|
|
|
}
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-27 09:09:10 +02:00
|
|
|
if ( subControl == Q::Ripple )
|
|
|
|
{
|
|
|
|
return rippleRect( skinnable, contentsRect );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
|
|
|
}
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
QSizeF QskSwitchButtonSkinlet::sizeHint( const QskSkinnable* skinnable,
|
|
|
|
Qt::SizeHint which, const QSizeF& ) const
|
|
|
|
{
|
|
|
|
if ( which != Qt::PreferredSize )
|
|
|
|
return QSizeF();
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-27 09:45:24 +02:00
|
|
|
auto grooveHint = skinnable->strutSizeHint( QskSwitchButton::Groove );
|
2021-08-27 09:09:10 +02:00
|
|
|
auto handleHint = skinnable->strutSizeHint( QskSwitchButton::Handle );
|
|
|
|
auto rippleHint = skinnable->strutSizeHint( QskSwitchButton::Ripple );
|
|
|
|
|
2022-06-06 07:08:33 +02:00
|
|
|
auto hint = grooveHint;
|
2021-08-27 09:09:10 +02:00
|
|
|
hint = hint.expandedTo( rippleHint );
|
|
|
|
hint = hint.expandedTo( handleHint );
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
return hint;
|
|
|
|
}
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
QSGNode* QskSwitchButtonSkinlet::updateSubNode( const QskSkinnable* skinnable,
|
|
|
|
quint8 nodeRole, QSGNode* node ) const
|
|
|
|
{
|
|
|
|
using Q = QskSwitchButton;
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
switch ( nodeRole )
|
|
|
|
{
|
2021-08-27 09:09:10 +02:00
|
|
|
case RippleRole:
|
|
|
|
return updateBoxNode( skinnable, node, Q::Ripple );
|
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
case HandleRole:
|
|
|
|
return updateBoxNode( skinnable, node, Q::Handle );
|
|
|
|
|
|
|
|
case GrooveRole:
|
|
|
|
return updateBoxNode( skinnable, node, Q::Groove );
|
2021-08-02 13:22:37 +02:00
|
|
|
}
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
|
|
|
}
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
QRectF QskSwitchButtonSkinlet::grooveRect(
|
|
|
|
const QskSkinnable* skinnable, const QRectF& contentsRect ) const
|
|
|
|
{
|
|
|
|
using Q = QskSwitchButton;
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
const auto switchButton = static_cast< const Q* >( skinnable );
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
auto size = skinnable->strutSizeHint( Q::Groove );
|
|
|
|
|
|
|
|
if ( switchButton->orientation() == Qt::Vertical )
|
|
|
|
{
|
|
|
|
if ( size.height() < 0.0 )
|
|
|
|
{
|
|
|
|
const auto handleSize = skinnable->strutSizeHint( Q::Handle );
|
|
|
|
size.setHeight( 2 * handleSize.height() );
|
2021-08-02 13:22:37 +02:00
|
|
|
}
|
2021-08-03 15:02:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( size.width() < 0.0 )
|
2021-08-02 13:22:37 +02:00
|
|
|
{
|
2021-08-03 15:02:33 +02:00
|
|
|
const auto handleSize = skinnable->strutSizeHint( Q::Handle );
|
|
|
|
size.setWidth( 2 * handleSize.width() );
|
2021-08-02 13:22:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
size = size.expandedTo( QSize( 0.0, 0.0 ) );
|
|
|
|
|
2021-08-04 09:31:16 +02:00
|
|
|
QRectF r;
|
2021-08-03 15:02:33 +02:00
|
|
|
r.setSize( size );
|
|
|
|
r.moveCenter( contentsRect.center() );
|
|
|
|
|
|
|
|
return r;
|
2021-08-02 13:22:37 +02:00
|
|
|
}
|
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
QRectF QskSwitchButtonSkinlet::handleRect(
|
|
|
|
const QskSkinnable* skinnable, const QRectF& contentsRect ) const
|
2021-08-02 13:22:37 +02:00
|
|
|
{
|
2021-08-02 19:17:04 +02:00
|
|
|
using Q = QskSwitchButton;
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-02 19:17:04 +02:00
|
|
|
const auto switchButton = static_cast< const Q* >( skinnable );
|
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
const auto grooveRect = subControlRect( skinnable, contentsRect, Q::Groove );
|
|
|
|
const auto pos = qskEffectivePosition( switchButton );
|
|
|
|
const auto size = skinnable->strutSizeHint( Q::Handle );
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
qreal cx, cy;
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
if( switchButton->orientation() == Qt::Vertical )
|
|
|
|
{
|
|
|
|
const qreal y0 = grooveRect.y() + 0.5 * size.height();
|
|
|
|
const qreal h = grooveRect.height() - size.height();
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
cx = grooveRect.x() + 0.5 * grooveRect.width();
|
|
|
|
cy = y0 + pos * h;
|
|
|
|
}
|
|
|
|
else
|
2021-08-02 13:22:37 +02:00
|
|
|
{
|
2021-08-03 15:02:33 +02:00
|
|
|
const qreal x0 = grooveRect.x() + 0.5 * size.width();
|
|
|
|
const qreal w = grooveRect.width() - size.width();
|
2021-08-02 13:22:37 +02:00
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
cx = x0 + pos * w;
|
|
|
|
cy = grooveRect.y() + 0.5 * grooveRect.height();
|
2021-08-02 13:22:37 +02:00
|
|
|
}
|
|
|
|
|
2021-08-03 15:02:33 +02:00
|
|
|
QRectF r;
|
|
|
|
r.setSize( size );
|
|
|
|
r.moveCenter( QPointF( cx, cy ) );
|
|
|
|
|
|
|
|
return r;
|
2021-08-02 13:22:37 +02:00
|
|
|
}
|
2021-08-02 19:17:04 +02:00
|
|
|
|
2021-08-27 09:09:10 +02:00
|
|
|
QRectF QskSwitchButtonSkinlet::rippleRect(
|
|
|
|
const QskSkinnable* skinnable, const QRectF& contentsRect ) const
|
|
|
|
{
|
|
|
|
using Q = QskSwitchButton;
|
|
|
|
|
|
|
|
const auto switchButton = static_cast< const Q* >( skinnable );
|
|
|
|
|
|
|
|
const auto grooveRect = subControlRect( skinnable, contentsRect, Q::Groove );
|
|
|
|
const auto pos = qskEffectivePosition( switchButton );
|
|
|
|
const auto sizeHandle = skinnable->strutSizeHint( Q::Handle );
|
|
|
|
const auto sizeRipple = skinnable->strutSizeHint( Q::Ripple );
|
|
|
|
|
|
|
|
qreal cx, cy;
|
|
|
|
|
|
|
|
if( switchButton->orientation() == Qt::Vertical )
|
|
|
|
{
|
|
|
|
const qreal y0 = grooveRect.y() + 0.5 * sizeHandle.height();
|
|
|
|
const qreal h = grooveRect.height() - sizeHandle.height();
|
|
|
|
|
|
|
|
cx = grooveRect.x() + 0.5 * grooveRect.width();
|
|
|
|
cy = y0 + pos * h;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const qreal x0 = grooveRect.x() + 0.5 * sizeHandle.width();
|
|
|
|
const qreal w = grooveRect.width() - sizeHandle.width();
|
|
|
|
|
|
|
|
cx = x0 + pos * w;
|
|
|
|
cy = grooveRect.y() + 0.5 * grooveRect.height();
|
|
|
|
}
|
|
|
|
|
|
|
|
QRectF r;
|
|
|
|
r.setSize( sizeRipple );
|
|
|
|
r.moveCenter( QPointF( cx, cy ) );
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2021-08-02 19:17:04 +02:00
|
|
|
#include "moc_QskSwitchButtonSkinlet.cpp"
|