formal adjustments

This commit is contained in:
Uwe Rathmann 2023-02-26 17:04:47 +01:00
parent c4efbf65f0
commit 2e667f3ff2
7 changed files with 412 additions and 338 deletions

View File

@ -119,6 +119,8 @@ namespace
: QskLinearBox( Qt::Horizontal, parent )
{
setSpacing( 20 );
setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge );
for ( auto orientation : { Qt::Vertical, Qt::Horizontal } )
@ -144,7 +146,7 @@ namespace
CheckButtonBox( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, 2, parent )
{
setSpacing( 40 );
setSpacing( 20 );
setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge );
auto button1 = new QskCheckBox( "Options 1", this );
@ -155,10 +157,22 @@ namespace
auto button3 = new QskCheckBox( "Error", this );
button3->setSkinStateFlag( QskCheckBox::Error );
}
};
class RadioButtonBox : public QskLinearBox
{
public:
RadioButtonBox( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, parent )
{
setSpacing( 20 );
setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge );
new QskRadioBox( { "One", "Two", "Three" }, this );
auto radios = new QskRadioBox( { "One", "Two", "Three" }, this );
radios->setLayoutMirroring(true);
auto radioBox = new QskRadioBox( { "One", "Two", "Three" }, this );
radioBox->setLayoutMirroring( true );
}
};
}
@ -176,5 +190,8 @@ void ButtonPage::populate()
new QskSeparator( Qt::Horizontal, this );
new SwitchButtonBox( this );
new QskSeparator( Qt::Horizontal, this );
new CheckButtonBox( this );
auto hBox = new QskLinearBox( Qt::Horizontal, this );
new CheckButtonBox( hBox );
new RadioButtonBox( hBox );
}

View File

@ -14,51 +14,39 @@ namespace
{
class Box : public QskGridBox
{
public:
public:
Box( QQuickItem* parent )
: QskGridBox( parent )
{
auto* messageButton = new QskPushButton( "message", this );
connect( messageButton, &QskPushButton::clicked, this, []()
{
qskDialog->message( "message", "text", QskStandardSymbol::Ok );
} );
connect( messageButton, &QskPushButton::clicked, this,
[]() { qskDialog->message( "message", "text", QskStandardSymbol::Ok ); } );
auto* informationButton = new QskPushButton( "information", this );
connect( informationButton, &QskPushButton::clicked, this, []()
{
qskDialog->information( "information", "text" );
} );
connect( informationButton, &QskPushButton::clicked, this,
[]() { qskDialog->information( "information", "text" ); } );
auto* warningButton = new QskPushButton( "warning", this );
connect( warningButton, &QskPushButton::clicked, this, []()
{
qskDialog->warning( "warning", "text" );
} );
connect( warningButton, &QskPushButton::clicked, this,
[]() { qskDialog->warning( "warning", "text" ); } );
auto* criticalButton = new QskPushButton( "critical", this );
connect( criticalButton, &QskPushButton::clicked, this, []()
{
qskDialog->critical( "critical", "text" );
} );
connect( criticalButton, &QskPushButton::clicked, this,
[]() { qskDialog->critical( "critical", "text" ); } );
auto* questionButton = new QskPushButton( "question", this );
connect( questionButton, &QskPushButton::clicked, this, []()
{
qskDialog->question( "question", "text" );
} );
connect( questionButton, &QskPushButton::clicked, this,
[]() { qskDialog->question( "question", "text" ); } );
auto* selectButton = new QskPushButton( "select", this );
connect( selectButton, &QskPushButton::clicked, this, []()
{
qskDialog->select( "select", "text", { "yes", "no", "maybe" } );
} );
connect( selectButton, &QskPushButton::clicked, this,
[]() { qskDialog->select( "select", "text", { "yes", "no", "maybe" } ); } );
addItem( messageButton, 0, 0 );
addItem( informationButton, 0, 1 );

View File

@ -32,7 +32,7 @@ namespace
{
auto bar = new QskSegmentedBar( orientation, this );
for ( const auto text: texts )
for ( const auto text : texts )
bar->addOption( {}, text );
}

View File

@ -1,3 +1,8 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskRadioBox.h"
#include "QskEvent.h"
#include "QskAnimationHint.h"
@ -13,175 +18,194 @@ QSK_STATE( QskRadioBox, Selected, QskAspect::FirstUserState << 1 )
QSK_STATE( QskRadioBox, Pressed, QskAspect::FirstUserState << 2 )
QSK_STATE( QskRadioBox, Focused, QskAspect::FirstUserState << 3 )
class QskRadioBox::PrivateData {
public:
class QskRadioBox::PrivateData
{
public:
QStringList items;
int selectedIndex = -1;
int focusedIndex = -1;
int pressedIndex = -1;
};
QskRadioBox::QskRadioBox( QQuickItem* parent ) :
Inherited( parent ),
m_data( new PrivateData{} ) {
QskRadioBox::QskRadioBox( QQuickItem* parent )
: Inherited( parent )
, m_data( new PrivateData() )
{
setFocusPolicy( Qt::NoFocus );
setAcceptedMouseButtons( Qt::LeftButton );
connect(this, &QskRadioBox::itemsChanged, this,
[this]( const QStringList& items ) {
if( items.count() > 0 ) {
setFocusPolicy( Qt::StrongFocus );
} else {
setFocusPolicy( Qt::NoFocus );
}
});
[this]( const QStringList& items )
{
setFocusPolicy( items.count() > 0 ? Qt::StrongFocus : Qt::NoFocus );
}
);
setFocusedIndex( -1 );
}
QskRadioBox::QskRadioBox( const QStringList& list, QQuickItem* parent ) :
QskRadioBox( parent ) {
QskRadioBox::QskRadioBox( const QStringList& list, QQuickItem* parent )
: QskRadioBox( parent )
{
setItems( list );
}
QskRadioBox::QskRadioBox( const QStringList& items,
int selectedIndex, QQuickItem* parent ) :
QskRadioBox( items, parent ) {
int selectedIndex, QQuickItem* parent )
: QskRadioBox( items, parent )
{
if( selectedIndex >= 0 && selectedIndex < items.count() )
{
m_data->selectedIndex = selectedIndex;
}
m_data->selectedIndex = selectedIndex;
}
QRectF QskRadioBox::focusIndicatorRect() const {
if( m_data->focusedIndex > -1) {
auto textRect = effectiveSkinlet()->sampleRect( this,
contentsRect(), QskRadioBox::Text, m_data->focusedIndex );
QskRadioBox::~QskRadioBox()
{
}
auto buttonRect = effectiveSkinlet()->sampleRect( this,
contentsRect(), QskRadioBox::Button, m_data->focusedIndex );
QRectF QskRadioBox::focusIndicatorRect() const
{
if( m_data->focusedIndex > -1)
{
auto skinlet = effectiveSkinlet();
if( textRect == QRectF() ) {
return buttonRect;
}
auto textRect = skinlet->sampleRect( this,
contentsRect(), QskRadioBox::Text, m_data->focusedIndex );
auto result = QRectF(
qMin( textRect.x(), buttonRect.x() ),
auto buttonRect = skinlet->sampleRect( this,
contentsRect(), QskRadioBox::Button, m_data->focusedIndex );
if( textRect == QRectF() )
return buttonRect;
auto result = QRectF(
qMin( textRect.x(), buttonRect.x() ),
qMin( textRect.y(), buttonRect.y() ),
buttonRect.width() + textRect.width(),
qMax( buttonRect.height(), textRect.height() ));
qMax( buttonRect.height(), textRect.height() ) );
if( layoutMirroring() ) {
result.setWidth(
result.width() + marginHint( Text ).right()
+ marginHint( Button ).left() );
} else {
result.setWidth(
result.width() + marginHint( Text ).left()
+ marginHint( Button ).right() );
}
if( layoutMirroring() )
{
result.setWidth(
result.width() + marginHint( Text ).right()
+ marginHint( Button ).left() );
}
else
{
result.setWidth(
result.width() + marginHint( Text ).left()
+ marginHint( Button ).right() );
}
return result;
return result;
}
return QRectF();
}
int QskRadioBox::selectedIndex() const {
int QskRadioBox::selectedIndex() const
{
return m_data->selectedIndex;
}
const QStringList& QskRadioBox::items() const {
const QStringList& QskRadioBox::items() const
{
return m_data->items;
}
int QskRadioBox::pressedIndex() const {
int QskRadioBox::pressedIndex() const
{
return m_data->pressedIndex;
}
void QskRadioBox::setSelectedIndex( int index ) {
if( index == m_data->selectedIndex
|| index >= m_data->items.count() ) {
return;
}
void QskRadioBox::setSelectedIndex( int index )
{
if( index == m_data->selectedIndex || index >= m_data->items.count() )
return;
if( index < 0 ) {
m_data->selectedIndex = -1;
} else {
m_data->selectedIndex = index;
}
if( index < 0 )
m_data->selectedIndex = -1;
else
m_data->selectedIndex = index;
selectedIndexChanged( m_data->selectedIndex );
}
void QskRadioBox::setItems( const QStringList& items ){
if( m_data->items == items ) {
return;
}
void QskRadioBox::setItems( const QStringList& items )
{
if( m_data->items == items )
return;
m_data->items = items;
itemsChanged( items );
setSelectedIndex( m_data->selectedIndex );
if( m_data->focusedIndex > items.size() ) {
setFocusedIndex( 0 );
}
if( m_data->focusedIndex > items.size() )
setFocusedIndex( 0 );
}
void QskRadioBox::keyPressEvent( QKeyEvent* event )
{
switch ( event->key() )
{
case Qt::Key_Up:
case Qt::Key_Left:
m_data->selectedIndex = qMax( m_data->selectedIndex - 1, 0 );
setFocusedIndex( m_data->selectedIndex );
event->setAccepted( true );
update();
return;
case Qt::Key_Down:
case Qt::Key_Right:
m_data->selectedIndex = qMin( m_data->selectedIndex + 1,
items().size() - 1 );
setFocusedIndex( m_data->selectedIndex );
event->setAccepted( true );
update();
return;
case Qt::Key_Select:
case Qt::Key_Return:
case Qt::Key_Space:
m_data->selectedIndex = m_data->focusedIndex;
event->setAccepted( true );
update();
return;
case Qt::Key_Up:
case Qt::Key_Left:
{
m_data->selectedIndex = qMax( m_data->selectedIndex - 1, 0 );
setFocusedIndex( m_data->selectedIndex );
update();
return;
}
case Qt::Key_Down:
case Qt::Key_Right:
{
m_data->selectedIndex = qMin( m_data->selectedIndex + 1,
items().size() - 1 );
setFocusedIndex( m_data->selectedIndex );
update();
return;
}
case Qt::Key_Select:
case Qt::Key_Return:
case Qt::Key_Space:
{
m_data->selectedIndex = m_data->focusedIndex;
update();
return;
}
}
auto currentTabIndex = m_data->focusedIndex;
auto nextTabIndex = currentTabIndex + qskFocusChainIncrement( event );
if( nextTabIndex >= items().size()
|| nextTabIndex < 0 ) {
Inherited::keyPressEvent( event );
setFocusedIndex( -1 );
update();
} else {
event->setAccepted( true );
const auto currentTabIndex = m_data->focusedIndex;
const auto nextTabIndex = currentTabIndex + qskFocusChainIncrement( event );
if( nextTabIndex >= items().size() || nextTabIndex < 0 )
{
Inherited::keyPressEvent( event );
setFocusedIndex( -1 );
}
else
{
setFocusedIndex( ( float ) nextTabIndex );
const auto aspect = Ripple | QskAspect::Metric | QskAspect::Position;
auto hint = animationHint(aspect | skinStates());
if( hint.isValid()) {
startTransition( aspect, hint,
( float ) currentTabIndex, ( float ) nextTabIndex );
}
update();
const auto aspect = Ripple | QskAspect::Metric | QskAspect::Position;
const auto hint = animationHint( aspect | skinStates() );
if( hint.isValid() )
{
startTransition( aspect, hint,
( float ) currentTabIndex, ( float ) nextTabIndex );
}
}
update();
}
void QskRadioBox::keyReleaseEvent( QKeyEvent* e )
void QskRadioBox::keyReleaseEvent( QKeyEvent* )
{
e->setAccepted( true );
}
void QskRadioBox::mousePressEvent( QMouseEvent* e )
@ -192,52 +216,54 @@ void QskRadioBox::mousePressEvent( QMouseEvent* e )
m_data->selectedIndex = -1;
setFocusedIndex( indexAtPosition );
e->setAccepted( true );
update();
}
void QskRadioBox::mouseReleaseEvent( QMouseEvent* e )
{
auto index = indexAt( e->localPos() );
if( index == m_data->pressedIndex ) {
setSelectedIndex( index );
}
const auto index = indexAt( e->localPos() );
if( index == m_data->pressedIndex )
setSelectedIndex( index );
e->setAccepted( true );
update();
}
void QskRadioBox::focusInEvent( QFocusEvent* e ) {
if( e->reason() == Qt::TabFocusReason ) {
setFocusedIndex(0 );
} else if( e->reason() == Qt::BacktabFocusReason ) {
setFocusedIndex( items().size() - 1 );
void QskRadioBox::focusInEvent( QFocusEvent* e )
{
if( e->reason() == Qt::TabFocusReason )
{
setFocusedIndex( 0 );
}
else if( e->reason() == Qt::BacktabFocusReason )
{
setFocusedIndex( items().size() - 1 );
}
update();
Inherited::focusInEvent( e );
}
void QskRadioBox::focusOutEvent( QFocusEvent* e ) {
void QskRadioBox::focusOutEvent( QFocusEvent* e )
{
setFocusedIndex( -1 );
update();
Inherited::focusOutEvent( e );
}
int QskRadioBox::indexAt( const QPointF& target ) const {
auto itemHeight = contentsRect().height() / items().size();
int QskRadioBox::indexAt( const QPointF& target ) const
{
const auto itemHeight = contentsRect().height() / items().size();
auto index = target.y() / itemHeight;
if( index < 0 || index >= items().size() ) {
return -1;
}
if( index < 0 || index >= items().size() )
return -1;
return index;
}
void QskRadioBox::setFocusedIndex( int index ) {
void QskRadioBox::setFocusedIndex( int index )
{
m_data->focusedIndex = index;
setPositionHint( Ripple, index );
focusIndicatorRectChanged();

View File

@ -1,23 +1,23 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_RADIO_BOX_H
#define QSK_RADIO_BOX_H
#include "QskControl.h"
#include <QStringList>
#include <qstringlist.h>
class QSK_EXPORT QskRadioBox : public QskControl
{
Q_OBJECT
Q_PROPERTY( int selectedIndex
READ selectedIndex
WRITE setSelectedIndex
NOTIFY selectedIndexChanged FINAL )
Q_PROPERTY( int selectedIndex READ selectedIndex
WRITE setSelectedIndex NOTIFY selectedIndexChanged FINAL )
Q_PROPERTY( QStringList items
READ items
WRITE setItems
NOTIFY itemsChanged FINAL )
Q_PROPERTY( QStringList items READ items
WRITE setItems NOTIFY itemsChanged FINAL )
using Inherited = QskControl;
@ -29,9 +29,12 @@ class QSK_EXPORT QskRadioBox : public QskControl
QskRadioBox( const QStringList&, QQuickItem* parent = nullptr );
QskRadioBox( const QStringList&, int, QQuickItem* parent = nullptr );
~QskRadioBox() override;
QRectF focusIndicatorRect() const override;
const QStringList& items() const;
int selectedIndex() const;
int pressedIndex() const;
@ -57,6 +60,7 @@ class QSK_EXPORT QskRadioBox : public QskControl
private:
void setFocusedIndex( int index );
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};

View File

@ -1,3 +1,8 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskRadioBoxSkinlet.h"
#include "QskAspect.h"
@ -10,8 +15,42 @@
#include "QskFunctions.h"
#include "QskSkin.h"
namespace {
using Q = QskRadioBox;
#include <qfontmetrics.h>
namespace
{
QskAspect::States statesForIndex( const QskRadioBox* radioBox, int index )
{
using Q = QskRadioBox;
auto states = radioBox->skinStates();
if( radioBox->selectedIndex() == index )
states |= Q::Selected;
if( radioBox->pressedIndex() == index )
states |= Q::Pressed;
if( radioBox->positionHint( Q::Ripple ) == index )
states |= Q::Focused;
return states;
}
qreal lineHeight( const QskRadioBox* radioBox )
{
using Q = QskRadioBox;
auto strutHight = qMax( radioBox->strutSizeHint( Q::Button ).height(),
radioBox->strutSizeHint( Q::Text ).height() );
const auto textMargins = radioBox->marginHint( Q::Text );
auto fontHeight = radioBox->effectiveFontHeight( Q::Text );
fontHeight += textMargins.top() + textMargins.bottom();
return qMax( strutHight, fontHeight );
}
}
QskRadioBoxSkinlet::QskRadioBoxSkinlet( QskSkin* )
@ -23,32 +62,13 @@ QskRadioBoxSkinlet::~QskRadioBoxSkinlet()
{
}
QskAspect::States statesForIndex( const QskRadioBox* radio, int index ) {
auto states = radio->skinStates();
if( radio->selectedIndex() == index ) {
states |= Q::Selected;
}
if( radio->pressedIndex() == index ) {
states |= Q::Pressed;
}
if( radio->positionHint( Q::Ripple ) == index ) {
states |= Q::Focused;
}
return states;
}
QRectF QskRadioBoxSkinlet::subControlRect( const QskSkinnable* skinnable,
const QRectF& contentsRect, QskAspect::Subcontrol subcontrol ) const
{
auto radio = static_cast< const QskRadioBox* >( skinnable );
auto radioBox = static_cast< const QskRadioBox* >( skinnable );
if( subcontrol == Q::Ripple ) {
return rippleRect( radio, contentsRect );
}
if( subcontrol == QskRadioBox::Ripple )
return rippleRect( radioBox, contentsRect );
return contentsRect;
}
@ -56,7 +76,9 @@ QRectF QskRadioBoxSkinlet::subControlRect( const QskSkinnable* skinnable,
QSizeF QskRadioBoxSkinlet::sizeHint( const QskSkinnable* skinnable,
Qt::SizeHint, const QSizeF& ) const
{
auto radio = static_cast< const QskRadioBox* >( skinnable );
using Q = QskRadioBox;
auto radioBox = static_cast< const QskRadioBox* >( skinnable );
const auto font = skinnable->effectiveFont( Q::Text );
const auto textMargins = skinnable->marginHint( Q::Text );
@ -64,232 +86,245 @@ QSizeF QskRadioBoxSkinlet::sizeHint( const QskSkinnable* skinnable,
const auto symbolMargins = skinnable->marginHint( Q::Symbol );
qreal maxTextWidth = 0;
for( auto& item : radio->items() ) {
maxTextWidth = std::max( maxTextWidth, qskHorizontalAdvance( font, item ) );
}
for( const auto& item : radioBox->items() )
maxTextWidth = std::max( maxTextWidth, qskHorizontalAdvance( font, item ) );
auto buttonWidth = radio->strutSizeHint( Q::Button ).width();
auto symbolWidth = radio->strutSizeHint( Q::Symbol ).width();
auto buttonWidth = radioBox->strutSizeHint( Q::Button ).width();
auto symbolWidth = radioBox->strutSizeHint( Q::Symbol ).width();
maxTextWidth += textMargins.left() + textMargins.right();
buttonWidth += buttonMargins.left() + buttonMargins.right();
symbolWidth += symbolMargins.left() + symbolMargins.right();
auto spacing = radio->spacingHint( Q::Panel );
auto spacing = radioBox->spacingHint( Q::Panel );
return QSizeF( maxTextWidth + qMax( buttonWidth, symbolWidth ),
( lineHeight( radio ) + spacing ) * radio->items().size() - spacing );
( lineHeight( radioBox ) + spacing ) * radioBox->items().size() - spacing );
}
QSGNode* QskRadioBoxSkinlet::updateSubNode( const QskSkinnable* skinnable,
quint8 nodeRole, QSGNode* node ) const
{
auto radio = static_cast< const QskRadioBox* >( skinnable );
using Q = QskRadioBox;
switch( nodeRole )
{
case PanelRole:
return updateBoxNode( skinnable, node, Q::Panel );
return updateBoxNode( skinnable, node, Q::Panel );
case ButtonRole:
return updateSeriesNode( radio, Q::Button, node );
return updateSeriesNode( skinnable, Q::Button, node );
case SymbolRole:
return updateSeriesNode( radio, Q::Symbol, node );
return updateSeriesNode( skinnable, Q::Symbol, node );
case TextRole:
return updateSeriesNode( radio, Q::Text, node );
return updateSeriesNode( skinnable, Q::Text, node );
case RippleRole:
{
QskSkinStateChanger changer( radio );
auto ripplePosition = radio->positionHint( Q::Ripple );
changer.setStates( statesForIndex( radio, ripplePosition ) );
{
auto radioBox = static_cast< const QskRadioBox* >( skinnable );
return updateBoxNode( radio, node, Q::Ripple );
}
QskSkinStateChanger changer( radioBox );
auto ripplePosition = radioBox->positionHint( Q::Ripple );
changer.setStates( statesForIndex( radioBox, ripplePosition ) );
return updateBoxNode( radioBox, node, Q::Ripple );
}
};
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
qreal QskRadioBoxSkinlet::lineHeight(const QskRadioBox* target) const {
auto strutHight = qMax( target->strutSizeHint( Q::Button ).height(),
target->strutSizeHint( Q::Text ).height() );
const auto textMargins = target->marginHint( Q::Text );
auto fontHeight = target->effectiveFontHeight( Q::Text );
fontHeight += textMargins.top() + textMargins.bottom();
return qMax( strutHight, fontHeight );
int QskRadioBoxSkinlet::sampleCount(
const QskSkinnable* skinnable, QskAspect::Subcontrol ) const
{
const auto radioBox = static_cast< const QskRadioBox* >( skinnable );
return radioBox->items().count();
}
int QskRadioBoxSkinlet::sampleCount( const QskSkinnable* skinnable, QskAspect::Subcontrol ) const {
const auto radio = static_cast< const QskRadioBox* >( skinnable );
return radio->items().count();
}
QSizeF QskRadioBoxSkinlet::buttonSymbolSize( const QskRadioBox* radioBox ) const
{
using Q = QskRadioBox;
QSizeF QskRadioBoxSkinlet::buttonSymbolSize( const QskRadioBox* radio ) const {
auto buttonStrut = radio->strutSizeHint( Q::Button );
auto symbolStrut = radio->strutSizeHint( Q::Symbol );
auto buttonStrut = radioBox->strutSizeHint( Q::Button );
auto symbolStrut = radioBox->strutSizeHint( Q::Symbol );
buttonStrut = buttonStrut.grownBy( radio->marginHint( Q::Button ) );
symbolStrut = symbolStrut.grownBy( radio->marginHint( Q::Symbol ) );
buttonStrut = buttonStrut.grownBy( radioBox->marginHint( Q::Button ) );
symbolStrut = symbolStrut.grownBy( radioBox->marginHint( Q::Symbol ) );
return QSizeF(
qMax( buttonStrut.width(), symbolStrut.width() ),
return QSizeF( qMax( buttonStrut.width(), symbolStrut.width() ),
qMax( buttonStrut.height(), symbolStrut.height() ) );
}
QRectF QskRadioBoxSkinlet::rippleRect( const QskRadioBox* radio, const QRectF& rect ) const {
auto ripplePosition = radio->positionHint( Q::Ripple );
QRectF QskRadioBoxSkinlet::rippleRect(
const QskRadioBox* radioBox, const QRectF& rect ) const
{
using Q = QskRadioBox;
if( ripplePosition < 0 ) {
return QRectF();
}
auto ripplePosition = radioBox->positionHint( Q::Ripple );
auto button = buttonRect( radio, Q::Button, rect, ripplePosition );
auto rippleSize = radio->strutSizeHint( Q::Ripple );
button.moveLeft( button.x() - ( rippleSize.width() - button.width() ) / 2 );
button.moveTop( button.y() - ( rippleSize.height() - button.height() ) / 2 );
button.setSize( rippleSize );
return button;
if( ripplePosition < 0 )
return QRectF();
auto rippleSize = radioBox->strutSizeHint( Q::Ripple );
auto r = buttonRect( radioBox, Q::Button, rect, ripplePosition );
r.moveLeft( r.x() - ( rippleSize.width() - r.width() ) / 2 );
r.moveTop( r.y() - ( rippleSize.height() - r.height() ) / 2 );
r.setSize( rippleSize );
return r;
}
QRectF QskRadioBoxSkinlet::buttonRect( const QskRadioBox* radio,
const QskAspect::Subcontrol target, const QRectF& rect, double index ) const {
if( index < 0 ) {
return QRectF();
}
QRectF QskRadioBoxSkinlet::buttonRect( const QskRadioBox* radioBox,
const QskAspect::Subcontrol target, const QRectF& rect, double index ) const
{
using Q = QskRadioBox;
if( index < 0 )
return QRectF();
auto result = rect;
result.setSize( radio->strutSizeHint( target ) );
result.setSize( radioBox->strutSizeHint( target ) );
auto spacing = radio->spacingHint( Q::Panel );
result.moveTop( ( lineHeight( radio ) + spacing ) * index );
auto spacing = radioBox->spacingHint( Q::Panel );
result.moveTop( ( lineHeight( radioBox ) + spacing ) * index );
auto margins = radio->marginHint( target );
auto margins = radioBox->marginHint( target );
auto withMargins = result.size().grownBy( margins );
auto maxSize = buttonSymbolSize( radio );
auto alignment = radio->alignmentHint( target );
auto maxSize = buttonSymbolSize( radioBox );
auto alignment = radioBox->alignmentHint( target );
// Vertical positioning
auto alignHeight = maxSize.height() - withMargins.height();
if( alignment.testFlag( Qt::AlignVCenter ) ) {
result.moveTop( result.top() + alignHeight / 2 );
} else if( alignment.testFlag( Qt::AlignBottom ) ) {
result.moveTop( result.top() + alignHeight );
}
const auto alignHeight = maxSize.height() - withMargins.height();
if( alignment.testFlag( Qt::AlignVCenter ) )
result.moveTop( result.top() + alignHeight / 2 );
else if( alignment.testFlag( Qt::AlignBottom ) )
result.moveTop( result.top() + alignHeight );
result.moveTop( result.top() + margins.top() );
// Horizontal positioning
auto alignWidth = 0;
if( alignment.testFlag( Qt::AlignHCenter ) ) {
alignWidth = ( maxSize.width() - withMargins.width() ) / 2;
} else if ( alignment.testFlag( Qt::AlignRight )) {
alignWidth = maxSize.width() - withMargins.width();
}
if( alignment.testFlag( Qt::AlignHCenter ) )
alignWidth = ( maxSize.width() - withMargins.width() ) / 2;
else if ( alignment.testFlag( Qt::AlignRight ) )
alignWidth = maxSize.width() - withMargins.width();
if( radio->layoutMirroring() ) {
result.moveRight( rect.width() - ( alignWidth + margins.right() ) );
} else {
result.moveLeft( margins.left() + alignWidth );
}
if( radioBox->layoutMirroring() )
result.moveRight( rect.width() - ( alignWidth + margins.right() ) );
else
result.moveLeft( margins.left() + alignWidth );
return result;
}
QRectF QskRadioBoxSkinlet::textRect( const QskRadioBox* radio,
const QRectF& rect, int index ) const {
auto text = radio->items()[ index ];
QRectF QskRadioBoxSkinlet::textRect( const QskRadioBox* radioBox,
const QRectF& rect, int index ) const
{
using Q = QskRadioBox;
if(text.isEmpty()) {
return QRectF();
}
const auto text = radioBox->items()[ index ];
if( text.isEmpty() )
return QRectF();
QRectF result = rect;
auto spacing = radio->spacingHint( Q::Panel );
auto lh = lineHeight( radio );
const auto textMargins = radio->marginHint( Q::Text );
const auto font = radio->effectiveFont( Q::Text );
auto spacing = radioBox->spacingHint( Q::Panel );
auto lh = lineHeight( radioBox );
const auto textMargins = radioBox->marginHint( Q::Text );
const auto font = radioBox->effectiveFont( Q::Text );
result.moveTop( index * ( lh + spacing )
+ lh - radio->effectiveFontHeight( Q::Text )
+ textMargins.top());
+ lh - QFontMetricsF( font ).height() + textMargins.top() );
result.setHeight( lh );
result.setWidth( qskHorizontalAdvance( font, text ) );
auto button = buttonRect( radio, Q::Button, rect, index );
auto buttonsMargins = radio->marginHint( Q::Button );
auto buttonWidth = button.marginsAdded( buttonsMargins ).width();
const auto button = buttonRect( radioBox, Q::Button, rect, index );
const auto buttonsMargins = radioBox->marginHint( Q::Button );
const auto buttonWidth = button.marginsAdded( buttonsMargins ).width();
if( radio->layoutMirroring() ) {
result.moveLeft( rect.width() - textMargins.right()
- result.width() - buttonWidth);
} else {
result.moveLeft( buttonWidth + textMargins.left() );
if( radioBox->layoutMirroring() )
{
result.moveLeft( rect.width() - textMargins.right()
- result.width() - buttonWidth);
}
else
{
result.moveLeft( buttonWidth + textMargins.left() );
}
return result;
}
QRectF QskRadioBoxSkinlet::sampleRect( const QskSkinnable* skinnable,
const QRectF& rect, QskAspect::Subcontrol subcontrol, int index ) const {
const QRectF& rect, QskAspect::Subcontrol subcontrol, int index ) const
{
using Q = QskRadioBox;
const auto radio = static_cast< const QskRadioBox* >( skinnable );
auto radioBox = static_cast< const QskRadioBox* >( skinnable );
if( subcontrol == Q::Text ) {
return textRect( radio, rect, index );
}
if( subcontrol == Q::Text )
return textRect( radioBox, rect, index );
return buttonRect( radio, subcontrol, rect, index);
return buttonRect( radioBox, subcontrol, rect, index);
}
QskAspect::States QskRadioBoxSkinlet::sampleStates( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl, int index ) const {
QskAspect::Subcontrol subControl, int index ) const
{
auto radioBox = static_cast< const QskRadioBox* >( skinnable );
auto states = Inherited::sampleStates( skinnable, subControl, index );
auto radio = static_cast< const QskRadioBox* >( skinnable );
auto states = Inherited::sampleStates( skinnable, subControl, index );
return states | statesForIndex( radio, index );
return states | statesForIndex( radioBox, index );
}
QSGNode* QskRadioBoxSkinlet::updateSampleNode( const QskSkinnable* skinnable,
QskAspect::Subcontrol subcontrol, int index, QSGNode* node ) const {
QSGNode* QskRadioBoxSkinlet::updateSampleNode( const QskSkinnable* skinnable,
QskAspect::Subcontrol subcontrol, int index, QSGNode* node ) const
{
using Q = QskRadioBox;
auto radio = static_cast< const QskRadioBox* >( skinnable );
auto radioBox = static_cast< const QskRadioBox* >( skinnable );
auto rect = sampleRect( skinnable, radio->contentsRect(),
subcontrol, index );
auto rect = sampleRect( skinnable, radioBox->contentsRect(), subcontrol, index );
if( subcontrol == Q::Text ) {
return QskSkinlet::updateTextNode( radio, node, rect, Qt::AlignLeft,
radio->items()[ index ], subcontrol );
} else if ( subcontrol == Q::Button ) {
return QskSkinlet::updateBoxNode( radio, node, rect, subcontrol );
} else if( subcontrol == Q::Symbol ) {
if( subcontrol == Q::Text )
{
return QskSkinlet::updateTextNode( radioBox, node, rect, Qt::AlignLeft,
radioBox->items()[ index ], subcontrol );
}
else if ( subcontrol == Q::Button )
{
return QskSkinlet::updateBoxNode( radioBox, node, rect, subcontrol );
}
else if( subcontrol == Q::Symbol )
{
auto symbol = QskStandardSymbol::NoSymbol;
auto color = radio->color( subcontrol ).rgb();
auto color = radioBox->color( subcontrol ).rgb();
if( radio->selectedIndex() == index ) {
symbol = QskStandardSymbol::Bullet;
color = radio->color( subcontrol | Q::Selected ).rgb();
}
if( radioBox->selectedIndex() == index )
{
symbol = QskStandardSymbol::Bullet;
color = radioBox->color( subcontrol | Q::Selected ).rgb();
}
auto graphic = radio->effectiveSkin()->symbol( symbol );
auto graphic = radioBox->effectiveSkin()->symbol( symbol );
/*
Our default skins do not have the concept of colorRoles
implemented. Until then we do the recoloring manually here
*/
QskColorFilter filter;
filter.addColorSubstitution( Qt::black, color );
auto colorSub = radio->color( subcontrol | statesForIndex( radio, index ) );
filter.addColorSubstitution( Qt::black, colorSub.rgb() );
/*
Our default skins do not have the concept of colorRoles
implemented. Until then we do the recoloring manually here
*/
QskColorFilter filter;
filter.addColorSubstitution( Qt::black, color );
QskGraphic::fromGraphic( graphic, filter );
auto colorSub = radioBox->color( subcontrol | statesForIndex( radioBox, index ) );
filter.addColorSubstitution( Qt::black, colorSub.rgb() );
return updateGraphicNode( radio, node, graphic, filter, rect );
QskGraphic::fromGraphic( graphic, filter );
return updateGraphicNode( radioBox, node, graphic, filter, rect );
}
return node;

View File

@ -1,3 +1,8 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_RADIO_BOX_SKINLET_H
#define QSK_RADIO_BOX_SKINLET_H
@ -37,13 +42,6 @@ class QSK_EXPORT QskRadioBoxSkinlet : public QskSkinlet
QRectF sampleRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, int index ) const override;
QSizeF buttonSymbolSize( const QskRadioBox* radio ) const;
QRectF textRect( const QskRadioBox*, const QRectF&, int ) const;
QRectF buttonRect( const QskRadioBox*, const QskAspect::Subcontrol target, const QRectF&,
double ) const;
QRectF rippleRect( const QskRadioBox*, const QRectF& ) const;
QskAspect::States sampleStates( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const override;
@ -55,7 +53,13 @@ class QSK_EXPORT QskRadioBoxSkinlet : public QskSkinlet
QskAspect::Subcontrol, int index, QSGNode* ) const override;
private:
qreal lineHeight( const QskRadioBox* target ) const;
QRectF textRect( const QskRadioBox*, const QRectF&, int ) const;
QSizeF buttonSymbolSize( const QskRadioBox* ) const;
QRectF buttonRect( const QskRadioBox*,
const QskAspect::Subcontrol, const QRectF&, double ) const;
QRectF rippleRect( const QskRadioBox*, const QRectF& ) const;
};
#endif