2023-02-17 11:01:56 +00:00
|
|
|
/******************************************************************************
|
2023-02-17 13:05:05 +00:00
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
2023-02-17 11:01:56 +00:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskSpinBoxSkinlet.h"
|
|
|
|
#include "QskSpinBox.h"
|
2023-02-19 13:24:09 +00:00
|
|
|
|
2023-02-17 12:30:39 +00:00
|
|
|
#include <array>
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
inline QPointF cursorPosSkinHint( const QskSpinBox& spinbox )
|
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
const auto aspect = QskSpinBox::Panel | QskAspect::Metric | QskAspect::Position;
|
2023-02-17 14:22:40 +00:00
|
|
|
return spinbox.effectiveSkinHint( aspect ).toPointF();
|
|
|
|
}
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
enum
|
2023-02-17 14:22:40 +00:00
|
|
|
{
|
|
|
|
Dec = 0,
|
|
|
|
Txt = 1,
|
|
|
|
Inc = 2,
|
|
|
|
Count
|
|
|
|
};
|
|
|
|
}
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
QskSpinBoxSkinlet::QskSpinBoxSkinlet( QskSkin* )
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
setNodeRoles( { IncrementPanel, DecrementPanel, TextPanel,
|
|
|
|
IncrementIndicator, DecrementIndicator, Text } );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
int QskSpinBoxSkinlet::sampleCount(
|
|
|
|
const QskSkinnable*, QskAspect::Subcontrol ) const
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-17 16:46:52 +00:00
|
|
|
return 1;
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
QRectF QskSpinBoxSkinlet::sampleRect( const QskSkinnable* skinnable, const QRectF& rect,
|
2023-02-17 14:22:40 +00:00
|
|
|
QskAspect::Subcontrol subControl, int index ) const
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-17 14:22:40 +00:00
|
|
|
if ( index == Dec || index == Inc || index == Txt )
|
|
|
|
{
|
|
|
|
return subControlRect( skinnable, rect, subControl );
|
|
|
|
}
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
return Inherited::sampleRect( skinnable, rect, subControl, index );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
QskAspect::States QskSpinBoxSkinlet::sampleStates(
|
|
|
|
const QskSkinnable* const skinnable, QskAspect::Subcontrol subControl, int index ) const
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-17 14:22:40 +00:00
|
|
|
using S = QskSpinBox;
|
2023-02-19 13:24:09 +00:00
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
auto states = Inherited::sampleStates( skinnable, subControl, index );
|
|
|
|
|
|
|
|
if ( subControl == S::DecrementPanel || subControl == S::IncrementPanel ||
|
|
|
|
subControl == S::TextPanel )
|
|
|
|
{
|
|
|
|
const auto* const spinbox = static_cast< const S* >( skinnable );
|
|
|
|
const auto cursorPos = cursorPosSkinHint( *spinbox );
|
|
|
|
const QPointF cursorPosAbs{ qAbs( cursorPos.x() ), qAbs( cursorPos.y() ) };
|
|
|
|
const auto subControlRect = spinbox->subControlRect( subControl );
|
|
|
|
|
|
|
|
const auto contain = !cursorPosAbs.isNull() && subControlRect.contains( cursorPosAbs );
|
|
|
|
const auto pressed = contain && ( cursorPos.x() < 0 || cursorPos.y() < 0 );
|
|
|
|
const auto hovered = contain && !pressed;
|
|
|
|
|
|
|
|
states.setFlag( QskControl::Hovered, hovered );
|
|
|
|
states.setFlag( QskSpinBox::Pressed, pressed );
|
|
|
|
}
|
|
|
|
|
|
|
|
return states;
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
QSizeF QskSpinBoxSkinlet::sizeHint( const QskSkinnable* skinnable,
|
|
|
|
Qt::SizeHint which, const QSizeF& size ) const
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
if ( which != Qt::PreferredSize )
|
|
|
|
return QSizeF();
|
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
using S = QskSpinBox;
|
2023-02-19 13:24:09 +00:00
|
|
|
|
|
|
|
const auto spinbox = static_cast< const QskSpinBox* >( skinnable );
|
|
|
|
|
|
|
|
const auto layout = spinbox->alignmentHint( S::Panel );
|
|
|
|
const auto spacing = spinbox->spacingHint( S::Panel );
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
const auto strutInc = spinbox->strutSizeHint( S::IncrementPanel );
|
|
|
|
const auto strutDec = spinbox->strutSizeHint( S::DecrementPanel );
|
|
|
|
const auto strutTxt = spinbox->strutSizeHint( S::TextPanel );
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
if ( layout == Qt::AlignTop || layout == Qt::AlignBottom || layout == Qt::AlignVCenter )
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
const auto w = qMax( strutDec.width(), qMax( strutTxt.width(), strutInc.width() ) );
|
|
|
|
const auto h = strutDec.height() + strutTxt.height() + strutInc.height();
|
2023-02-17 14:22:40 +00:00
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
return QSizeF( w, h + 2.0 * spacing );
|
|
|
|
}
|
2023-02-17 14:22:40 +00:00
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
if ( layout == Qt::AlignLeft || layout == Qt::AlignRight || layout == Qt::AlignHCenter )
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
const auto w = strutDec.width() + strutTxt.width() + strutInc.width();
|
|
|
|
const auto h = qMax( strutDec.height(), qMax( strutTxt.height(), strutInc.height() ) );
|
|
|
|
|
|
|
|
return QSizeF( w + 2.0 * spacing, h );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
2023-02-19 13:24:09 +00:00
|
|
|
|
|
|
|
if ( layout == ( Qt::AlignLeft | Qt::AlignVCenter ) ||
|
|
|
|
layout == ( Qt::AlignRight | Qt::AlignVCenter ) )
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
const auto w = strutTxt.width() + qMax( strutInc.width(), strutDec.width() );
|
|
|
|
const auto h =
|
|
|
|
qMax( 2.0 * qMax( strutInc.height(), strutDec.height() ), strutTxt.height() );
|
|
|
|
|
|
|
|
return QSizeF( w + spacing, h + spacing );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
2023-02-19 13:24:09 +00:00
|
|
|
|
|
|
|
if ( layout == ( Qt::AlignTop | Qt::AlignHCenter ) ||
|
|
|
|
layout == ( Qt::AlignTop | Qt::AlignHCenter ) )
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
const auto w = qMax( strutTxt.width(), strutInc.width() + strutDec.width() );
|
|
|
|
const auto h = strutTxt.height() + qMax( strutInc.height(), strutDec.height() );
|
|
|
|
|
|
|
|
return QSizeF( w + spacing, h + spacing );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
return Inherited::sizeHint( skinnable, which, size );
|
|
|
|
}
|
|
|
|
|
|
|
|
QRectF QskSpinBoxSkinlet::subControlRect( const QskSkinnable* skinnable,
|
|
|
|
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
|
|
|
{
|
|
|
|
using Q = QskSpinBox;
|
|
|
|
|
|
|
|
if ( subControl == Q::DecrementIndicator )
|
|
|
|
return skinnable->subControlContentsRect( contentsRect, Q::DecrementPanel );
|
|
|
|
|
|
|
|
if ( subControl == Q::IncrementIndicator )
|
|
|
|
return skinnable->subControlContentsRect( contentsRect, Q::IncrementPanel );
|
|
|
|
|
|
|
|
if ( subControl == Q::Text )
|
|
|
|
return skinnable->subControlContentsRect( contentsRect, Q::TextPanel );
|
|
|
|
|
|
|
|
const auto* const spinbox = static_cast< const QskSpinBox* >( skinnable );
|
|
|
|
|
|
|
|
const auto layout = spinbox->alignmentHint( Q::Panel );
|
|
|
|
const auto spacing = spinbox->spacingHint( Q::Panel );
|
2023-02-17 14:22:40 +00:00
|
|
|
|
|
|
|
std::array< QRectF, Count > rects = {
|
2023-02-19 13:24:09 +00:00
|
|
|
QRectF{ QPointF(), spinbox->strutSizeHint( Q::DecrementPanel ) },
|
|
|
|
QRectF{ QPointF(), spinbox->strutSizeHint( Q::TextPanel ) },
|
|
|
|
QRectF{ QPointF(), spinbox->strutSizeHint( Q::IncrementPanel ) },
|
2023-02-17 14:22:40 +00:00
|
|
|
};
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
const auto center = contentsRect.center();
|
2023-02-17 14:22:40 +00:00
|
|
|
|
|
|
|
if ( layout == Qt::AlignLeft )
|
|
|
|
{
|
|
|
|
rects[ Txt ].moveTopLeft( { 0.0, center.y() - rects[ Txt ].height() * 0.5 } );
|
|
|
|
rects[ Dec ].moveTopLeft(
|
|
|
|
{ rects[ Txt ].right() + spacing, center.y() - rects[ Dec ].height() * 0.5 } );
|
|
|
|
rects[ Inc ].moveTopLeft(
|
|
|
|
{ rects[ Dec ].right() + spacing, center.y() - rects[ Inc ].height() * 0.5 } );
|
|
|
|
}
|
|
|
|
else if ( layout == Qt::AlignRight )
|
|
|
|
{
|
|
|
|
rects[ Dec ].moveTopLeft( { 0.0, center.y() - rects[ Dec ].height() * 0.5 } );
|
|
|
|
rects[ Inc ].moveTopLeft(
|
|
|
|
{ rects[ Dec ].right() + spacing, center.y() - rects[ Inc ].height() * 0.5 } );
|
|
|
|
rects[ Txt ].moveTopLeft(
|
|
|
|
{ rects[ Inc ].right() + spacing, center.y() - rects[ Txt ].height() * 0.5 } );
|
|
|
|
}
|
|
|
|
else if ( layout == Qt::AlignTop )
|
|
|
|
{
|
|
|
|
rects[ Txt ].moveTopLeft( { center.x() - rects[ Txt ].width() * 0.5, 0.0 } );
|
|
|
|
rects[ Inc ].moveTopLeft(
|
|
|
|
{ center.x() - rects[ Inc ].width() * 0.5, rects[ Txt ].bottom() + spacing } );
|
|
|
|
rects[ Dec ].moveTopLeft(
|
|
|
|
{ center.x() - rects[ Dec ].width() * 0.5, rects[ Inc ].bottom() + spacing } );
|
|
|
|
}
|
|
|
|
else if ( layout == Qt::AlignBottom )
|
|
|
|
{
|
|
|
|
rects[ Inc ].moveTopLeft( { center.x() - rects[ Inc ].width() * 0.5, 0.0 } );
|
|
|
|
rects[ Dec ].moveTopLeft(
|
|
|
|
{ center.x() - rects[ Dec ].width() * 0.5, rects[ Inc ].bottom() + spacing } );
|
|
|
|
rects[ Txt ].moveTopLeft(
|
|
|
|
{ center.x() - rects[ Txt ].width() * 0.5, rects[ Dec ].bottom() + spacing } );
|
|
|
|
}
|
|
|
|
else if ( layout == Qt::AlignHCenter )
|
|
|
|
{
|
|
|
|
rects[ Dec ].moveTopLeft( { 0.0, center.y() - rects[ Dec ].height() * 0.5 } );
|
|
|
|
rects[ Txt ].moveTopLeft(
|
|
|
|
{ rects[ Dec ].right() + spacing, center.y() - rects[ Txt ].height() * 0.5 } );
|
|
|
|
rects[ Inc ].moveTopLeft(
|
|
|
|
{ rects[ Txt ].right() + spacing, center.y() - rects[ Inc ].height() * 0.5 } );
|
|
|
|
}
|
|
|
|
else if ( layout == Qt::AlignVCenter )
|
|
|
|
{
|
|
|
|
rects[ Inc ].moveTopLeft( { center.x() - rects[ Inc ].width() * 0.5, 0.0 } );
|
|
|
|
rects[ Txt ].moveTopLeft(
|
|
|
|
{ center.x() - rects[ Txt ].width() * 0.5, rects[ Inc ].bottom() + spacing } );
|
|
|
|
rects[ Dec ].moveTopLeft(
|
|
|
|
{ center.x() - rects[ Dec ].width() * 0.5, rects[ Txt ].bottom() + spacing } );
|
|
|
|
}
|
|
|
|
else if ( layout == ( Qt::AlignLeft | Qt::AlignVCenter ) )
|
|
|
|
{
|
|
|
|
rects[ Txt ].moveTopLeft( { 0.0, center.y() - rects[ Txt ].height() * 0.5 } );
|
|
|
|
rects[ Inc ].moveTopLeft( { rects[ Txt ].right() + spacing,
|
|
|
|
center.y() - spacing * 0.5 - rects[ Inc ].height() } );
|
|
|
|
rects[ Dec ].moveTopLeft( { rects[ Txt ].right() + spacing, center.y() + spacing * 0.5 } );
|
|
|
|
}
|
|
|
|
else if ( layout == ( Qt::AlignRight | Qt::AlignVCenter ) )
|
|
|
|
{
|
|
|
|
const auto dx = qMax( rects[ Inc ].width(), rects[ Dec ].width() );
|
|
|
|
rects[ Inc ].moveTopLeft(
|
|
|
|
{ dx - rects[ Inc ].width(), center.y() - spacing * 0.5 - rects[ Inc ].height() } );
|
|
|
|
rects[ Dec ].moveTopLeft( { dx - rects[ Dec ].width(), center.y() + spacing * 0.5 } );
|
|
|
|
rects[ Txt ].moveTopLeft( { dx + spacing, center.y() - rects[ Txt ].height() * 0.5 } );
|
|
|
|
}
|
|
|
|
else if ( layout == ( Qt::AlignTop | Qt::AlignHCenter ) )
|
|
|
|
{
|
|
|
|
rects[ Txt ].moveTopLeft( { center.x() - rects[ Txt ].width() * 0.5, 0.0 } );
|
|
|
|
rects[ Dec ].moveTopLeft(
|
|
|
|
{ rects[ Txt ].center().x() - spacing * 0.5 - rects[ Dec ].width(),
|
|
|
|
rects[ Txt ].bottom() + spacing } );
|
|
|
|
rects[ Inc ].moveTopLeft(
|
|
|
|
{ rects[ Txt ].center().x() + spacing * 0.5, rects[ Txt ].bottom() + spacing } );
|
|
|
|
}
|
|
|
|
else if ( layout == ( Qt::AlignBottom | Qt::AlignHCenter ) )
|
|
|
|
{
|
|
|
|
rects[ Txt ].moveTopLeft(
|
|
|
|
{ center.x() - rects[ Txt ].width() * 0.5, center.y() - rects[ Txt ].height() * 0.5 } );
|
|
|
|
rects[ Dec ].moveTopLeft( { center.x() - spacing * 0.5 - rects[ Dec ].width(),
|
|
|
|
rects[ Txt ].top() - spacing - rects[ Dec ].height() } );
|
|
|
|
rects[ Inc ].moveTopLeft(
|
|
|
|
{ center.x() + spacing * 0.5, rects[ Txt ].top() - spacing - rects[ Inc ].height() } );
|
|
|
|
}
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
if ( subControl == Q::DecrementPanel )
|
2023-02-17 14:22:40 +00:00
|
|
|
return rects[ Dec ];
|
2023-02-19 13:24:09 +00:00
|
|
|
|
|
|
|
if ( subControl == Q::TextPanel )
|
2023-02-17 14:22:40 +00:00
|
|
|
return rects[ Txt ];
|
2023-02-19 13:24:09 +00:00
|
|
|
|
|
|
|
if ( subControl == Q::IncrementPanel )
|
2023-02-17 14:22:40 +00:00
|
|
|
return rects[ Inc ];
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
QSGNode* QskSpinBoxSkinlet::updateSubNode(
|
2023-02-19 13:24:09 +00:00
|
|
|
const QskSkinnable* skinnable, const quint8 nodeRole, QSGNode* const node ) const
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
using Q = QskSpinBox;
|
|
|
|
|
|
|
|
switch( nodeRole )
|
2023-02-17 14:22:40 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
case IncrementPanel:
|
|
|
|
return updateSeriesNode( skinnable, Q::IncrementPanel, node );
|
|
|
|
|
|
|
|
case DecrementPanel:
|
|
|
|
return updateSeriesNode( skinnable, Q::DecrementPanel, node );
|
|
|
|
|
|
|
|
case IncrementIndicator:
|
|
|
|
{
|
|
|
|
return updateTextNode( skinnable, node,
|
|
|
|
QStringLiteral( "+" ), Q::IncrementIndicator );
|
|
|
|
}
|
|
|
|
|
|
|
|
case DecrementIndicator:
|
|
|
|
{
|
|
|
|
return updateTextNode( skinnable, node,
|
|
|
|
QStringLiteral( "-" ), Q::DecrementIndicator );
|
|
|
|
}
|
|
|
|
|
|
|
|
case TextPanel:
|
|
|
|
return updateSeriesNode( skinnable, Q::TextPanel, node );
|
|
|
|
|
|
|
|
case Text:
|
|
|
|
{
|
|
|
|
const auto* const spinbox = static_cast< const QskSpinBox* >( skinnable );
|
|
|
|
|
|
|
|
return updateTextNode( skinnable, node,
|
|
|
|
QString::number( spinbox->value() ), Q::Text );
|
|
|
|
}
|
2023-02-17 14:22:40 +00:00
|
|
|
}
|
2023-02-19 13:24:09 +00:00
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
QSGNode* QskSpinBoxSkinlet::updateSampleNode( const QskSkinnable* skinnable,
|
2023-02-17 14:22:40 +00:00
|
|
|
QskAspect::Subcontrol subControl, const int index, QSGNode* const node ) const
|
2023-02-17 11:01:56 +00:00
|
|
|
{
|
2023-02-19 13:24:09 +00:00
|
|
|
using Q = QskSpinBox;
|
|
|
|
const auto* const spinbox = static_cast< const QskSpinBox* >( skinnable );
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-19 13:24:09 +00:00
|
|
|
if ( subControl == Q::DecrementPanel || subControl == Q::IncrementPanel ||
|
|
|
|
subControl == Q::TextPanel )
|
2023-02-17 14:22:40 +00:00
|
|
|
{
|
|
|
|
const auto rect = sampleRect( spinbox, spinbox->contentsRect(), subControl, index );
|
|
|
|
return updateBoxNode( skinnable, node, rect, subControl );
|
|
|
|
}
|
2023-02-17 11:01:56 +00:00
|
|
|
|
2023-02-17 14:22:40 +00:00
|
|
|
return Inherited::updateSampleNode( skinnable, subControl, index, node );
|
2023-02-17 11:01:56 +00:00
|
|
|
}
|