diff --git a/src/controls/QskPushButtonSkinlet.cpp b/src/controls/QskPushButtonSkinlet.cpp index 07982bf4..a7fcf71b 100644 --- a/src/controls/QskPushButtonSkinlet.cpp +++ b/src/controls/QskPushButtonSkinlet.cpp @@ -32,66 +32,11 @@ namespace LayoutEngine( const QskPushButton* button ) : QskSubcontrolLayoutEngine( qskOrientation( button ) ) { - using Q = QskPushButton; + setSpacing( button->spacingHint( QskPushButton::Panel ) ); - setSpacing( button->spacingHint( Q::Panel ) ); - - const auto graphicSourceSize = button->graphic().defaultSize(); - - const bool hasText = !button->text().isEmpty(); - const bool hasGraphic = !graphicSourceSize.isEmpty(); - - auto graphicElement = new GraphicElement( button, Q::Graphic ); - graphicElement->setSourceSize( graphicSourceSize ); - graphicElement->setIgnored( !hasGraphic ); - - auto textElement = new TextElement( button, Q::Text ); - textElement->setText( button->text() ); - textElement->setIgnored( !hasText ); - - using SP = QskSizePolicy; - - if ( hasText && !hasGraphic ) - { - textElement->setSizePolicy( SP::Preferred, SP::Constrained ); - } - else if ( hasGraphic && !hasText ) - { - const auto size = graphicElement->effectiveStrutSize(); - - if ( !size.isEmpty() ) - graphicElement->setFixedSize( size ); - else - graphicElement->setSizePolicy( SP::Ignored, SP::ConstrainedExpanding ); - } - else if ( hasText && hasGraphic ) - { - if ( orientation() == Qt::Horizontal ) - { - graphicElement->setSizePolicy( SP::Constrained, SP::Fixed ); - textElement->setSizePolicy( SP::Preferred, SP::Preferred ); - } - else - { - graphicElement->setSizePolicy( SP::Fixed, SP::Fixed ); - textElement->setSizePolicy( SP::Preferred, SP::Constrained ); - } - - auto size = graphicElement->effectiveStrutSize(); - - if ( size.isEmpty() ) - { - const auto h = 1.5 * button->effectiveFontHeight( Q::Text ); - - size.setWidth( graphicElement->widthForHeight( h ) ); - size.setHeight( h ); - } - - graphicElement->setPreferredSize( size ); - } - - setElementAt( 0, graphicElement ); - setElementAt( 1, textElement ); + setGraphicTextElements( button, + QskPushButton::Text, button->text(), + QskPushButton::Graphic, button->graphic().defaultSize() ); } }; } @@ -107,24 +52,26 @@ QskPushButtonSkinlet::~QskPushButtonSkinlet() = default; QRectF QskPushButtonSkinlet::subControlRect( const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const { + using Q = QskPushButton; + const auto button = static_cast< const QskPushButton* >( skinnable ); - if ( subControl == QskPushButton::Text ) + if ( ( subControl == Q::Text ) || ( subControl == Q::Graphic ) ) { - return textRect( button, contentsRect ); + const auto r = button->subControlContentsRect( contentsRect, Q::Panel ); + + LayoutEngine layoutEngine( button ); + layoutEngine.setGeometries( r ); + + return layoutEngine.subControlRect( subControl ); } - if ( subControl == QskPushButton::Graphic ) - { - return graphicRect( button, contentsRect ); - } - - if ( subControl == QskPushButton::Panel ) + if ( subControl == Q::Panel ) { return contentsRect; } - if ( subControl == QskPushButton::Ripple ) + if ( subControl == Q::Ripple ) { return rippleRect( button, contentsRect ); } @@ -135,13 +82,15 @@ QRectF QskPushButtonSkinlet::subControlRect( const QskSkinnable* skinnable, QSGNode* QskPushButtonSkinlet::updateSubNode( const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const { + using Q = QskPushButton; + const auto button = static_cast< const QskPushButton* >( skinnable ); switch ( nodeRole ) { case PanelRole: { - return updateBoxNode( button, node, QskPushButton::Panel ); + return updateBoxNode( button, node, Q::Panel ); } case RippleRole: @@ -156,40 +105,13 @@ QSGNode* QskPushButtonSkinlet::updateSubNode( case GraphicRole: { - return updateGraphicNode( button, node, - button->graphic(), QskPushButton::Graphic ); + return updateGraphicNode( button, node, button->graphic(), Q::Graphic ); } } return Inherited::updateSubNode( skinnable, nodeRole, node ); } -QRectF QskPushButtonSkinlet::textRect( - const QskPushButton* button, const QRectF& contentsRect ) const -{ - using Q = QskPushButton; - - const auto r = button->subControlContentsRect( contentsRect, Q::Panel ); - - LayoutEngine layoutEngine( button ); - layoutEngine.setGeometries( r ); - - return layoutEngine.elementAt( 1 )->geometry(); -} - -QRectF QskPushButtonSkinlet::graphicRect( - const QskPushButton* button, const QRectF& contentsRect ) const -{ - using Q = QskPushButton; - - const auto r = button->subControlContentsRect( contentsRect, Q::Panel ); - - LayoutEngine layoutEngine( button ); - layoutEngine.setGeometries( r ); - - return layoutEngine.elementAt( 0 )->geometry(); -} - QRectF QskPushButtonSkinlet::rippleRect( const QskPushButton* button, const QRectF& contentsRect ) const { diff --git a/src/controls/QskPushButtonSkinlet.h b/src/controls/QskPushButtonSkinlet.h index 2147a1d1..722b225e 100644 --- a/src/controls/QskPushButtonSkinlet.h +++ b/src/controls/QskPushButtonSkinlet.h @@ -41,8 +41,6 @@ class QSK_EXPORT QskPushButtonSkinlet : public QskSkinlet quint8 nodeRole, QSGNode* ) const override; private: - QRectF textRect( const QskPushButton*, const QRectF& ) const; - QRectF graphicRect( const QskPushButton*, const QRectF& ) const; QRectF rippleRect( const QskPushButton*, const QRectF& ) const; QSGNode* updateTextNode( const QskPushButton*, QSGNode* ) const; diff --git a/src/layouts/QskSubcontrolLayoutEngine.cpp b/src/layouts/QskSubcontrolLayoutEngine.cpp index 3cfa3229..d66309f8 100644 --- a/src/layouts/QskSubcontrolLayoutEngine.cpp +++ b/src/layouts/QskSubcontrolLayoutEngine.cpp @@ -322,6 +322,66 @@ qreal QskSubcontrolLayoutEngine::spacing() const return Inherited::spacing( m_data->orientation ); } +void QskSubcontrolLayoutEngine::setGraphicTextElements( const QskSkinnable* skinnable, + QskAspect::Subcontrol textSubcontrol, const QString& text, + QskAspect::Subcontrol graphicSubControl, const QSizeF& graphicSize ) +{ + const bool hasText = !text.isEmpty(); + const bool hasGraphic = !graphicSize.isEmpty(); + + auto graphicElement = new GraphicElement( skinnable, graphicSubControl ); + graphicElement->setSourceSize( graphicSize ); + graphicElement->setIgnored( !hasGraphic ); + + auto textElement = new TextElement( skinnable, textSubcontrol ); + textElement->setText( text ); + textElement->setIgnored( !hasText ); + + using SP = QskSizePolicy; + + if ( hasText && !hasGraphic ) + { + textElement->setSizePolicy( SP::Preferred, SP::Constrained ); + } + else if ( hasGraphic && !hasText ) + { + const auto size = graphicElement->effectiveStrutSize(); + + if ( !size.isEmpty() ) + graphicElement->setFixedSize( size ); + else + graphicElement->setSizePolicy( SP::Ignored, SP::ConstrainedExpanding ); + } + else if ( hasText && hasGraphic ) + { + if ( orientation() == Qt::Horizontal ) + { + graphicElement->setSizePolicy( SP::Constrained, SP::Fixed ); + textElement->setSizePolicy( SP::Preferred, SP::Preferred ); + } + else + { + graphicElement->setSizePolicy( SP::Fixed, SP::Fixed ); + textElement->setSizePolicy( SP::Preferred, SP::Constrained ); + } + + auto size = graphicElement->effectiveStrutSize(); + + if ( size.isEmpty() ) + { + const auto h = 1.5 * skinnable->effectiveFontHeight( textSubcontrol ); + + size.setWidth( graphicElement->widthForHeight( h ) ); + size.setHeight( h ); + } + + graphicElement->setPreferredSize( size ); + } + + setElementAt( 0, graphicElement ); + setElementAt( 1, textElement ); +} + void QskSubcontrolLayoutEngine::setElementAt( int index, LayoutElement* element ) { if ( index >= 0 && index < count() ) @@ -339,6 +399,18 @@ QskSubcontrolLayoutEngine::LayoutElement* QskSubcontrolLayoutEngine::elementAt( return nullptr; } +QskSubcontrolLayoutEngine::LayoutElement* QskSubcontrolLayoutEngine::element( + QskAspect::Subcontrol subControl ) const +{ + for ( auto element : m_data->elements ) + { + if ( element->subControl() == subControl ) + return element; + } + + return nullptr; +} + QskSizePolicy QskSubcontrolLayoutEngine::sizePolicyAt( int index ) const { if ( index >= 0 && index < count() ) @@ -380,6 +452,14 @@ int QskSubcontrolLayoutEngine::effectiveCount( Qt::Orientation orientation ) con return ( orientation == m_data->orientation ) ? 2 : 1; } +QRectF QskSubcontrolLayoutEngine::subControlRect( QskAspect::Subcontrol subControl ) const +{ + if ( const auto el = element( subControl ) ) + return el->geometry(); + + return QRectF( 0.0, 0.0, -1.0, -1.0 ); // something invalid +} + void QskSubcontrolLayoutEngine::invalidateElementCache() { } diff --git a/src/layouts/QskSubcontrolLayoutEngine.h b/src/layouts/QskSubcontrolLayoutEngine.h index 42911013..4d4eca07 100644 --- a/src/layouts/QskSubcontrolLayoutEngine.h +++ b/src/layouts/QskSubcontrolLayoutEngine.h @@ -124,8 +124,16 @@ class QskSubcontrolLayoutEngine : public QskLayoutEngine2D void setElementAt( int index, LayoutElement* ); LayoutElement* elementAt( int ) const; + LayoutElement* element( QskAspect::Subcontrol ) const; + int count() const override final; + void setGraphicTextElements( const QskSkinnable*, + QskAspect::Subcontrol, const QString& text, + QskAspect::Subcontrol, const QSizeF& graphicSize ); + + QRectF subControlRect( QskAspect::Subcontrol ) const; + private: QskSizePolicy sizePolicyAt( int index ) const override; void layoutItems() override;