diff --git a/src/controls/QskMenu.cpp b/src/controls/QskMenu.cpp index f224d982..22f9caef 100644 --- a/src/controls/QskMenu.cpp +++ b/src/controls/QskMenu.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -309,37 +310,8 @@ void QskMenu::setSelectedIndex( int index ) QRectF QskMenu::cellRect( int index ) const { - /* - Calculations like this one should be done in the skinlet. - We need an API like subControlRect( int index, ... ) TODO ... - */ - - if ( index < 0 || index >= count() ) - return QRectF(); - - const auto r = subControlContentsRect( QskMenu::Panel ); - const auto h = cellHeight(); - - return QRectF( r.x(), r.y() + index * h, r.width(), h ); -} - -qreal QskMenu::cellHeight() const -{ - /* - Calculations like this one should be done in the skinlet. - We need an API like subControlRect( int index, ... ) TODO ... - */ - const auto graphicHeight = strutSizeHint( Graphic ).height(); - const auto textHeight = effectiveFontHeight( Text ); - const auto padding = paddingHint( Cell ); - - qreal h = qMax( graphicHeight, textHeight ); - h += padding.top() + padding.bottom(); - - const auto minHeight = strutSizeHint( Cell ).height(); - h = qMax( h, minHeight ); - - return h; + return effectiveSkinlet()->itemRect( + this, contentsRect(), QskMenu::Cell, index ); } #include "moc_QskMenu.cpp" diff --git a/src/controls/QskMenu.h b/src/controls/QskMenu.h index e440af00..80a31951 100644 --- a/src/controls/QskMenu.h +++ b/src/controls/QskMenu.h @@ -65,7 +65,6 @@ class QSK_EXPORT QskMenu : public QskPopup QRectF focusIndicatorRect() const override; QRectF cellRect( int index ) const; - qreal cellHeight() const; Q_SIGNALS: void triggered( int index ); diff --git a/src/controls/QskMenuSkinlet.cpp b/src/controls/QskMenuSkinlet.cpp index 1e6f298b..63436cab 100644 --- a/src/controls/QskMenuSkinlet.cpp +++ b/src/controls/QskMenuSkinlet.cpp @@ -81,6 +81,23 @@ static qreal qskCellWidth( const QskMenu* menu ) return qMax( w, minWidth ); } +static qreal qskCellHeight( const QskMenu* menu ) +{ + using Q = QskMenu; + + const auto graphicHeight = menu->strutSizeHint( Q::Graphic ).height(); + const auto textHeight = menu->effectiveFontHeight( Q::Text ); + const auto padding = menu->paddingHint( Q::Cell ); + + qreal h = qMax( graphicHeight, textHeight ); + h += padding.top() + padding.bottom(); + + const auto minHeight = menu->strutSizeHint( Q::Cell ).height(); + h = qMax( h, minHeight ); + + return h; +} + static QSGNode* qskUpdateGraphicNode( const QskMenu* menu, const QRectF& rect, const QskGraphic& graphic, QSGNode* node ) { @@ -233,6 +250,27 @@ QRectF QskMenuSkinlet::subControlRect( return Inherited::subControlRect( skinnable, contentsRect, subControl ); } +QRectF QskMenuSkinlet::itemRect( + const QskSkinnable* skinnable, const QRectF& contentsRect, + QskAspect::Subcontrol subControl, int index ) const +{ + if ( subControl == QskMenu::Cell ) + { + const auto menu = static_cast< const QskMenu* >( skinnable ); + + if ( index < 0 || index >= menu->count() ) + return QRectF(); + + const auto r = menu->subControlContentsRect( QskMenu::Panel ); + const auto h = qskCellHeight( menu ); + + return QRectF( r.x(), r.y() + index * h, r.width(), h ); + } + + return Inherited::itemRect( + skinnable, contentsRect, subControl, index ); +} + QSGNode* QskMenuSkinlet::updateContentsNode( const QskPopup* popup, QSGNode* contentsNode ) const { @@ -289,7 +327,7 @@ QSizeF QskMenuSkinlet::sizeHint( const QskSkinnable* skinnable, const auto menu = static_cast< const QskMenu* >( skinnable ); const qreal w = qskCellWidth( menu ); - const auto h = menu->count() * menu->cellHeight(); + const auto h = menu->count() * qskCellHeight( menu ); return menu->outerBoxSize( QskMenu::Panel, QSizeF( w, h ) ); } diff --git a/src/controls/QskMenuSkinlet.h b/src/controls/QskMenuSkinlet.h index 45afc170..4b557810 100644 --- a/src/controls/QskMenuSkinlet.h +++ b/src/controls/QskMenuSkinlet.h @@ -23,6 +23,9 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QRectF itemRect( const QskSkinnable*, + const QRectF&, QskAspect::Subcontrol, int index ) const override; + QSizeF sizeHint( const QskSkinnable*, Qt::SizeHint, const QSizeF& ) const override; diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index cd43a5e9..2b1a7baf 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -581,4 +581,13 @@ QSizeF QskSkinlet::hintWithoutConstraint( return h; } +QRectF QskSkinlet::itemRect( const QskSkinnable*, + const QRectF&, QskAspect::Subcontrol, int index ) const +{ + // When a subControl is for a unknown number of item, f.e. in a menu + + Q_UNUSED( index ) + return QRectF(); +} + #include "moc_QskSkinlet.cpp" diff --git a/src/controls/QskSkinlet.h b/src/controls/QskSkinlet.h index f5e42795..7aef1716 100644 --- a/src/controls/QskSkinlet.h +++ b/src/controls/QskSkinlet.h @@ -39,6 +39,9 @@ class QSK_EXPORT QskSkinlet virtual QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const; + virtual QRectF itemRect( const QskSkinnable*, + const QRectF&, QskAspect::Subcontrol, int index ) const; + virtual QSizeF sizeHint( const QskSkinnable*, Qt::SizeHint, const QSizeF& ) const;