From 2e667f3ff2780527bb3e3f4589d0fa722994fb9c Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sun, 26 Feb 2023 17:04:47 +0100 Subject: [PATCH] formal adjustments --- examples/gallery/button/ButtonPage.cpp | 25 +- examples/gallery/dialog/DialogPage.cpp | 38 +-- examples/gallery/selector/SelectorPage.cpp | 2 +- src/controls/QskRadioBox.cpp | 274 ++++++++------- src/controls/QskRadioBox.h | 24 +- src/controls/QskRadioBoxSkinlet.cpp | 367 +++++++++++---------- src/controls/QskRadioBoxSkinlet.h | 20 +- 7 files changed, 412 insertions(+), 338 deletions(-) diff --git a/examples/gallery/button/ButtonPage.cpp b/examples/gallery/button/ButtonPage.cpp index a80b79c0..b62865ce 100644 --- a/examples/gallery/button/ButtonPage.cpp +++ b/examples/gallery/button/ButtonPage.cpp @@ -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 ); } diff --git a/examples/gallery/dialog/DialogPage.cpp b/examples/gallery/dialog/DialogPage.cpp index 8bd36eb5..46f750d5 100644 --- a/examples/gallery/dialog/DialogPage.cpp +++ b/examples/gallery/dialog/DialogPage.cpp @@ -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 ); diff --git a/examples/gallery/selector/SelectorPage.cpp b/examples/gallery/selector/SelectorPage.cpp index d617641e..974a0c5d 100644 --- a/examples/gallery/selector/SelectorPage.cpp +++ b/examples/gallery/selector/SelectorPage.cpp @@ -32,7 +32,7 @@ namespace { auto bar = new QskSegmentedBar( orientation, this ); - for ( const auto text: texts ) + for ( const auto text : texts ) bar->addOption( {}, text ); } diff --git a/src/controls/QskRadioBox.cpp b/src/controls/QskRadioBox.cpp index 3ba7f174..e87835fa 100644 --- a/src/controls/QskRadioBox.cpp +++ b/src/controls/QskRadioBox.cpp @@ -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 result = QRectF( - qMin( textRect.x(), buttonRect.x() ), + auto textRect = skinlet->sampleRect( this, + contentsRect(), QskRadioBox::Text, m_data->focusedIndex ); + + 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(); diff --git a/src/controls/QskRadioBox.h b/src/controls/QskRadioBox.h index de96be13..c510bb96 100644 --- a/src/controls/QskRadioBox.h +++ b/src/controls/QskRadioBox.h @@ -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 +#include 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; }; diff --git a/src/controls/QskRadioBoxSkinlet.cpp b/src/controls/QskRadioBoxSkinlet.cpp index 337f00ce..13cff7e0 100644 --- a/src/controls/QskRadioBoxSkinlet.cpp +++ b/src/controls/QskRadioBoxSkinlet.cpp @@ -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 + +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,240 +76,255 @@ 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 ); const auto buttonMargins = skinnable->marginHint( Q::Button ); const auto symbolMargins = skinnable->marginHint( Q::Symbol ); - - qreal maxTextWidth = 0; - for( auto& item : radio->items() ) { - maxTextWidth = std::max( maxTextWidth, qskHorizontalAdvance( font, item ) ); - } - auto buttonWidth = radio->strutSizeHint( Q::Button ).width(); - auto symbolWidth = radio->strutSizeHint( Q::Symbol ).width(); + qreal maxTextWidth = 0; + for( const auto& item : radioBox->items() ) + maxTextWidth = std::max( maxTextWidth, qskHorizontalAdvance( font, item ) ); + + 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 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; + auto ripplePosition = radioBox->positionHint( Q::Ripple ); + + 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( radioBox->layoutMirroring() ) + result.moveRight( rect.width() - ( alignWidth + margins.right() ) ); + else + result.moveLeft( margins.left() + alignWidth ); - if( radio->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 ); - - 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 ) { + auto rect = sampleRect( skinnable, radioBox->contentsRect(), subcontrol, index ); + + 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(); - } - - auto graphic = radio->effectiveSkin()->symbol( symbol ); + if( radioBox->selectedIndex() == index ) + { + symbol = QskStandardSymbol::Bullet; + color = radioBox->color( subcontrol | Q::Selected ).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 ); - auto colorSub = radio->color( subcontrol | statesForIndex( radio, index ) ); - filter.addColorSubstitution( Qt::black, colorSub.rgb() ); + auto graphic = radioBox->effectiveSkin()->symbol( symbol ); - QskGraphic::fromGraphic( graphic, filter ); + /* + 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 ); - return updateGraphicNode( radio, node, graphic, filter, rect ); + auto colorSub = radioBox->color( subcontrol | statesForIndex( radioBox, index ) ); + filter.addColorSubstitution( Qt::black, colorSub.rgb() ); + + QskGraphic::fromGraphic( graphic, filter ); + + return updateGraphicNode( radioBox, node, graphic, filter, rect ); } return node; diff --git a/src/controls/QskRadioBoxSkinlet.h b/src/controls/QskRadioBoxSkinlet.h index 4b0be65b..c1c4f359 100644 --- a/src/controls/QskRadioBoxSkinlet.h +++ b/src/controls/QskRadioBoxSkinlet.h @@ -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