From 0eadfa8fa25e9b2f5aac9bfc419938b0551befde Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 29 Dec 2020 09:45:00 +0100 Subject: [PATCH] sizeHint calculations moved to the skinlet --- examples/gallery/slider/CustomSlider.cpp | 11 --- examples/gallery/slider/CustomSlider.h | 3 - .../gallery/slider/CustomSliderSkinlet.cpp | 11 +++ examples/gallery/slider/CustomSliderSkinlet.h | 3 + examples/layouts/DynamicConstraintsPage.cpp | 4 +- examples/mycontrols/MyToggleButton.cpp | 27 ------ examples/mycontrols/MyToggleButton.h | 1 - examples/mycontrols/MyToggleButtonSkinlet.cpp | 26 ++++++ examples/mycontrols/MyToggleButtonSkinlet.h | 6 +- src/controls/QskBox.cpp | 9 -- src/controls/QskBox.h | 3 - src/controls/QskBoxSkinlet.cpp | 11 +++ src/controls/QskBoxSkinlet.h | 3 + src/controls/QskControl.cpp | 5 +- src/controls/QskGraphicLabel.cpp | 27 +----- src/controls/QskGraphicLabel.h | 3 - src/controls/QskGraphicLabelSkinlet.cpp | 27 ++++++ src/controls/QskGraphicLabelSkinlet.h | 3 + src/controls/QskListView.cpp | 17 ---- src/controls/QskListView.h | 1 - src/controls/QskListViewSkinlet.cpp | 21 ++++- src/controls/QskListViewSkinlet.h | 3 + src/controls/QskPageIndicator.cpp | 45 --------- src/controls/QskPageIndicator.h | 3 - src/controls/QskPageIndicatorSkinlet.cpp | 51 ++++++++++ src/controls/QskPageIndicatorSkinlet.h | 3 + src/controls/QskProgressBar.cpp | 11 --- src/controls/QskProgressBar.h | 1 - src/controls/QskProgressBarSkinlet.cpp | 16 ++++ src/controls/QskProgressBarSkinlet.h | 3 + src/controls/QskPushButton.cpp | 71 +++----------- src/controls/QskPushButton.h | 4 +- src/controls/QskPushButtonSkinlet.cpp | 62 +++++++++++++ src/controls/QskPushButtonSkinlet.h | 3 + src/controls/QskSeparator.cpp | 14 --- src/controls/QskSeparator.h | 3 - src/controls/QskSeparatorSkinlet.cpp | 16 ++++ src/controls/QskSeparatorSkinlet.h | 3 + src/controls/QskSkinlet.h | 17 ++-- src/controls/QskSlider.cpp | 11 --- src/controls/QskSlider.h | 2 - src/controls/QskSliderSkinlet.cpp | 16 ++++ src/controls/QskSliderSkinlet.h | 3 + src/controls/QskTabButton.cpp | 17 ---- src/controls/QskTabButton.h | 1 - src/controls/QskTabButtonSkinlet.cpp | 21 +++++ src/controls/QskTabButtonSkinlet.h | 3 + src/controls/QskTextInput.cpp | 11 ++- src/controls/QskTextInput.h | 2 +- src/controls/QskTextLabel.cpp | 92 ++----------------- src/controls/QskTextLabel.h | 5 +- src/controls/QskTextLabelSkinlet.cpp | 82 +++++++++++++++++ src/controls/QskTextLabelSkinlet.h | 3 + src/dialogs/QskSelectionSubWindow.cpp | 15 +-- src/dialogs/QskSelectionWindow.cpp | 15 +-- 55 files changed, 452 insertions(+), 398 deletions(-) diff --git a/examples/gallery/slider/CustomSlider.cpp b/examples/gallery/slider/CustomSlider.cpp index 993ef68a..0625931d 100644 --- a/examples/gallery/slider/CustomSlider.cpp +++ b/examples/gallery/slider/CustomSlider.cpp @@ -50,17 +50,6 @@ CustomSlider::CustomSlider( QQuickItem* parentItem ) this, &QskControl::focusIndicatorRectChanged ); } -QSizeF CustomSlider::contentsSizeHint( - Qt::SizeHint which, const QSizeF& constraint ) const -{ - auto size = Inherited::contentsSizeHint( which, constraint ); - - if ( which == Qt::PreferredSize && size.height() >= 0 ) - size.setHeight( size.height() + 40 ); - - return size; -} - QRectF CustomSlider::focusIndicatorRect() const { return subControlRect( Handle ); diff --git a/examples/gallery/slider/CustomSlider.h b/examples/gallery/slider/CustomSlider.h index e1364648..7a8a119c 100644 --- a/examples/gallery/slider/CustomSlider.h +++ b/examples/gallery/slider/CustomSlider.h @@ -18,9 +18,6 @@ class CustomSlider : public QskSlider CustomSlider( QQuickItem* parent = nullptr ); QRectF focusIndicatorRect() const override; - - protected: - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; }; #endif diff --git a/examples/gallery/slider/CustomSliderSkinlet.cpp b/examples/gallery/slider/CustomSliderSkinlet.cpp index fcf2df22..54dd1cea 100644 --- a/examples/gallery/slider/CustomSliderSkinlet.cpp +++ b/examples/gallery/slider/CustomSliderSkinlet.cpp @@ -370,3 +370,14 @@ QSGNode* CustomSliderSkinlet::updateHandleNode( return handleNode; } + +QSizeF CustomSliderSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& constraint ) const +{ + auto size = Inherited::sizeHint( skinnable, which, constraint ); + + if ( which == Qt::PreferredSize && size.height() >= 0 ) + size.rheight() += 40; + + return size; +} diff --git a/examples/gallery/slider/CustomSliderSkinlet.h b/examples/gallery/slider/CustomSliderSkinlet.h index aad8bbaf..b9e232b1 100644 --- a/examples/gallery/slider/CustomSliderSkinlet.h +++ b/examples/gallery/slider/CustomSliderSkinlet.h @@ -27,6 +27,9 @@ class CustomSliderSkinlet : public QskSliderSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/examples/layouts/DynamicConstraintsPage.cpp b/examples/layouts/DynamicConstraintsPage.cpp index 63081547..658a68d6 100644 --- a/examples/layouts/DynamicConstraintsPage.cpp +++ b/examples/layouts/DynamicConstraintsPage.cpp @@ -22,7 +22,7 @@ namespace void transpose(); protected: - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; + QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override; private: qreal m_aspectRatio; @@ -65,7 +65,7 @@ Control::Control( const char* colorName, qreal aspectRatio, QQuickItem* parent ) setPreferredHeight( 100 ); } -QSizeF Control::contentsSizeHint( +QSizeF Control::layoutSizeHint( Qt::SizeHint which, const QSizeF& constraint ) const { if ( which == Qt::PreferredSize ) diff --git a/examples/mycontrols/MyToggleButton.cpp b/examples/mycontrols/MyToggleButton.cpp index 9ae8d3d6..b39c6561 100644 --- a/examples/mycontrols/MyToggleButton.cpp +++ b/examples/mycontrols/MyToggleButton.cpp @@ -179,33 +179,6 @@ QskGraphic MyToggleButton::graphicAt( int index ) const return data.icon; } -QSizeF MyToggleButton::contentsSizeHint( - Qt::SizeHint which, const QSizeF& constraint ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - QSizeF hint; - - // better use Minimum Width/Height hints TODO ... - constexpr qreal aspectRatio = 4.0 / 3.0; - - if ( constraint.width() >= 0.0 ) - { - hint.rheight() = constraint.width() / aspectRatio; - } - else if ( constraint.height() >= 0.0 ) - { - hint.rwidth() = constraint.height() * aspectRatio; - } - else - { - hint = strutSizeHint( Panel ); - } - - return hint; -} - void MyToggleButton::updateResources() { for( int i = 0; i < 2; i++ ) diff --git a/examples/mycontrols/MyToggleButton.h b/examples/mycontrols/MyToggleButton.h index c7d1c348..9b492b3b 100644 --- a/examples/mycontrols/MyToggleButton.h +++ b/examples/mycontrols/MyToggleButton.h @@ -42,7 +42,6 @@ class MyToggleButton : public QskAbstractButton protected: void updateResources() override; - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; private: class PrivateData; diff --git a/examples/mycontrols/MyToggleButtonSkinlet.cpp b/examples/mycontrols/MyToggleButtonSkinlet.cpp index c7ab887f..1185380a 100644 --- a/examples/mycontrols/MyToggleButtonSkinlet.cpp +++ b/examples/mycontrols/MyToggleButtonSkinlet.cpp @@ -145,4 +145,30 @@ QSGNode* MyToggleButtonSkinlet::updateSubNode( } } +QSizeF MyToggleButtonSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& constraint ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + QSizeF hint; + + constexpr qreal aspectRatio = 4.0 / 3.0; + + if ( constraint.width() >= 0.0 ) + { + hint.rheight() = constraint.width() / aspectRatio; + } + else if ( constraint.height() >= 0.0 ) + { + hint.rwidth() = constraint.height() * aspectRatio; + } + else + { + hint = skinnable->strutSizeHint( MyToggleButton::Panel ); + } + + return hint; +} + #include "moc_MyToggleButtonSkinlet.cpp" diff --git a/examples/mycontrols/MyToggleButtonSkinlet.h b/examples/mycontrols/MyToggleButtonSkinlet.h index 5828c2bb..576a3a08 100644 --- a/examples/mycontrols/MyToggleButtonSkinlet.h +++ b/examples/mycontrols/MyToggleButtonSkinlet.h @@ -37,8 +37,12 @@ class MyToggleButtonSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: - QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; + QSGNode* updateSubNode( const QskSkinnable*, + quint8 nodeRole, QSGNode* ) const override; private: QRectF innerRect( const QskSkinnable*, diff --git a/src/controls/QskBox.cpp b/src/controls/QskBox.cpp index bda4bdc0..820ac9e0 100644 --- a/src/controls/QskBox.cpp +++ b/src/controls/QskBox.cpp @@ -72,13 +72,4 @@ QRectF QskBox::layoutRectForSize( const QSizeF& size ) const return innerBox( Panel, subControlRect( size, Panel ) ); } -QSizeF QskBox::contentsSizeHint( - Qt::SizeHint which, const QSizeF& constraint ) const -{ - if ( m_hasPanel && which == Qt::PreferredSize ) - return strutSizeHint( Panel ); - - return Inherited::contentsSizeHint( which, constraint ); -} - #include "moc_QskBox.cpp" diff --git a/src/controls/QskBox.h b/src/controls/QskBox.h index b429c92d..d2aac33f 100644 --- a/src/controls/QskBox.h +++ b/src/controls/QskBox.h @@ -42,9 +42,6 @@ class QSK_EXPORT QskBox : public QskControl void panelChanged( bool ); void paddingChanged( const QMarginsF& ); - protected: - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; - private: bool m_hasPanel; }; diff --git a/src/controls/QskBoxSkinlet.cpp b/src/controls/QskBoxSkinlet.cpp index ae817509..cdd4e240 100644 --- a/src/controls/QskBoxSkinlet.cpp +++ b/src/controls/QskBoxSkinlet.cpp @@ -46,4 +46,15 @@ QSGNode* QskBoxSkinlet::updateSubNode( return Inherited::updateSubNode( skinnable, nodeRole, node ); } +QSizeF QskBoxSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& constraint ) const +{ + const auto box = static_cast< const QskBox* >( skinnable ); + + if ( box->hasPanel() && which == Qt::PreferredSize ) + return box->strutSizeHint( QskBox::Panel ); + + return Inherited::sizeHint( skinnable, which, constraint ); +} + #include "moc_QskBoxSkinlet.cpp" diff --git a/src/controls/QskBoxSkinlet.h b/src/controls/QskBoxSkinlet.h index 7ca5ad2f..d56638fe 100644 --- a/src/controls/QskBoxSkinlet.h +++ b/src/controls/QskBoxSkinlet.h @@ -26,6 +26,9 @@ class QSK_EXPORT QskBoxSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index 0c0752bb..806f1e1b 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -951,9 +951,10 @@ void QskControl::updateResources() { } -QSizeF QskControl::contentsSizeHint( Qt::SizeHint, const QSizeF& ) const +QSizeF QskControl::contentsSizeHint( + Qt::SizeHint which, const QSizeF& constraint ) const { - return QSizeF(); + return effectiveSkinlet()->sizeHint( this, which, constraint ); } QSizeF QskControl::layoutSizeHint( diff --git a/src/controls/QskGraphicLabel.cpp b/src/controls/QskGraphicLabel.cpp index af9c0ccc..86c2cedb 100644 --- a/src/controls/QskGraphicLabel.cpp +++ b/src/controls/QskGraphicLabel.cpp @@ -248,34 +248,9 @@ void QskGraphicLabel::updateResources() m_data->isSourceDirty = false; } -QSizeF QskGraphicLabel::contentsSizeHint( - Qt::SizeHint which, const QSizeF& constraint ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - auto sz = effectiveSourceSize(); - - if ( !sz.isEmpty() ) - { - if ( constraint.width() >= 0.0 ) - { - sz.setHeight( sz.height() * constraint.width() / sz.width() ); - sz.setWidth( -1.0 ); - } - else if ( constraint.height() >= 0.0 ) - { - sz.setWidth( sz.width() * constraint.height() / sz.height() ); - sz.setHeight( -1.0 ); - } - } - - return sz; -} - QSizeF QskGraphicLabel::effectiveSourceSize() const { - const QSizeF& sourceSize = m_data->sourceSize; + const auto& sourceSize = m_data->sourceSize; if ( sourceSize.width() >= 0 && sourceSize.height() >= 0 ) { diff --git a/src/controls/QskGraphicLabel.h b/src/controls/QskGraphicLabel.h index a1eb43ce..ae1f93e7 100644 --- a/src/controls/QskGraphicLabel.h +++ b/src/controls/QskGraphicLabel.h @@ -100,9 +100,6 @@ class QSK_EXPORT QskGraphicLabel : public QskControl void updateResources() override; virtual QskGraphic loadSource( const QUrl& ) const; - QSizeF contentsSizeHint( - Qt::SizeHint, const QSizeF& constraint ) const override; - private: class PrivateData; std::unique_ptr< PrivateData > m_data; diff --git a/src/controls/QskGraphicLabelSkinlet.cpp b/src/controls/QskGraphicLabelSkinlet.cpp index 173e21fc..dd3479ed 100644 --- a/src/controls/QskGraphicLabelSkinlet.cpp +++ b/src/controls/QskGraphicLabelSkinlet.cpp @@ -103,4 +103,31 @@ QSGNode* QskGraphicLabelSkinlet::updateGraphicNode( return node; } +QSizeF QskGraphicLabelSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& constraint ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto label = static_cast< const QskGraphicLabel* >( skinnable ); + + auto sz = label->effectiveSourceSize(); + + if ( !sz.isEmpty() ) + { + if ( constraint.width() >= 0.0 ) + { + sz.setHeight( sz.height() * constraint.width() / sz.width() ); + sz.setWidth( -1.0 ); + } + else if ( constraint.height() >= 0.0 ) + { + sz.setWidth( sz.width() * constraint.height() / sz.height() ); + sz.setHeight( -1.0 ); + } + } + + return sz; +} + #include "moc_QskGraphicLabelSkinlet.cpp" diff --git a/src/controls/QskGraphicLabelSkinlet.h b/src/controls/QskGraphicLabelSkinlet.h index b7ecbeaf..8034a48b 100644 --- a/src/controls/QskGraphicLabelSkinlet.h +++ b/src/controls/QskGraphicLabelSkinlet.h @@ -28,6 +28,9 @@ class QSK_EXPORT QskGraphicLabelSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskListView.cpp b/src/controls/QskListView.cpp index 7e33c2a8..13efb44e 100644 --- a/src/controls/QskListView.cpp +++ b/src/controls/QskListView.cpp @@ -153,23 +153,6 @@ QskAspect::Subcontrol QskListView::textSubControlAt( int row, int col ) const return ( row == selectedRow() ) ? TextSelected : Text; } -QSizeF QskListView::contentsSizeHint( - Qt::SizeHint which, const QSizeF& ) const -{ - qreal w = -1.0; // shouldn't we return something ??? - - if ( which != Qt::MaximumSize ) - { - if ( m_data->preferredWidthFromColumns ) - { - w = scrollableSize().width(); - w += metric( QskScrollView::VerticalScrollBar | QskAspect::Size ); - } - } - - return QSizeF( w, -1.0 ); -} - void QskListView::keyPressEvent( QKeyEvent* event ) { if ( m_data->selectionMode == NoSelection ) diff --git a/src/controls/QskListView.h b/src/controls/QskListView.h index d76d56e7..15e90799 100644 --- a/src/controls/QskListView.h +++ b/src/controls/QskListView.h @@ -99,7 +99,6 @@ class QSK_EXPORT QskListView : public QskScrollView void updateScrollableSize(); - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; void componentComplete() override; private: diff --git a/src/controls/QskListViewSkinlet.cpp b/src/controls/QskListViewSkinlet.cpp index db115238..0169a9f7 100644 --- a/src/controls/QskListViewSkinlet.cpp +++ b/src/controls/QskListViewSkinlet.cpp @@ -95,7 +95,7 @@ QskListViewSkinlet::~QskListViewSkinlet() = default; QSGNode* QskListViewSkinlet::updateContentsNode( const QskScrollView* scrollView, QSGNode* node ) const { - const auto* listView = static_cast< const QskListView* >( scrollView ); + const auto listView = static_cast< const QskListView* >( scrollView ); auto* listViewNode = static_cast< QskListViewNode* >( node ); if ( listViewNode == nullptr ) @@ -482,4 +482,23 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView, return newNode; } +QSizeF QskListViewSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& ) const +{ + const auto listView = static_cast< const QskListView* >( skinnable ); + + qreal w = -1.0; // shouldn't we return something ??? + + if ( which != Qt::MaximumSize ) + { + if ( listView->preferredWidthFromColumns() ) + { + w = listView->scrollableSize().width(); + w += listView->metric( QskScrollView::VerticalScrollBar | QskAspect::Size ); + } + } + + return QSizeF( w, -1.0 ); +} + #include "moc_QskListViewSkinlet.cpp" diff --git a/src/controls/QskListViewSkinlet.h b/src/controls/QskListViewSkinlet.h index 89646a47..ad82a0f8 100644 --- a/src/controls/QskListViewSkinlet.h +++ b/src/controls/QskListViewSkinlet.h @@ -27,6 +27,9 @@ class QSK_EXPORT QskListViewSkinlet : public QskScrollViewSkinlet Q_INVOKABLE QskListViewSkinlet( QskSkin* = nullptr ); ~QskListViewSkinlet() override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: enum NodeRole { diff --git a/src/controls/QskPageIndicator.cpp b/src/controls/QskPageIndicator.cpp index 8d335533..afd0d1b8 100644 --- a/src/controls/QskPageIndicator.cpp +++ b/src/controls/QskPageIndicator.cpp @@ -97,49 +97,4 @@ void QskPageIndicator::setCurrentIndex( qreal index ) } } -QSizeF QskPageIndicator::contentsSizeHint( - Qt::SizeHint which, const QSizeF& ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - const auto bulletSize = strutSizeHint( Bullet ); - const auto maxSize = bulletSize.expandedTo( strutSizeHint( Highlighted ) ); - - const qreal spacing = spacingHint( Panel ); - - const int n = m_data->count; - - qreal w = 0; - qreal h = 0; - - if ( m_data->orientation == Qt::Horizontal ) - { - if ( n > 0 ) - { - w += maxSize.width(); - - if ( n > 1 ) - w += ( n - 1 ) * ( bulletSize.width() + spacing ); - } - - h = maxSize.height(); - } - else - { - if ( n > 0 ) - { - h += maxSize.height(); - - if ( n > 1 ) - h += ( n - 1 ) * ( bulletSize.height() + spacing ); - } - - w = maxSize.width(); - } - - const auto hint = outerBoxSize( Panel, QSizeF( w, h ) ); - return hint.expandedTo( strutSizeHint( Panel ) ); -} - #include "moc_QskPageIndicator.cpp" diff --git a/src/controls/QskPageIndicator.h b/src/controls/QskPageIndicator.h index 63028864..23e306d0 100644 --- a/src/controls/QskPageIndicator.h +++ b/src/controls/QskPageIndicator.h @@ -49,9 +49,6 @@ class QSK_EXPORT QskPageIndicator : public QskControl void setCount( int count ); void setCurrentIndex( qreal index ); - protected: - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; - private: class PrivateData; std::unique_ptr< PrivateData > m_data; diff --git a/src/controls/QskPageIndicatorSkinlet.cpp b/src/controls/QskPageIndicatorSkinlet.cpp index 6829f26d..2d00e945 100644 --- a/src/controls/QskPageIndicatorSkinlet.cpp +++ b/src/controls/QskPageIndicatorSkinlet.cpp @@ -172,4 +172,55 @@ QSGNode* QskPageIndicatorSkinlet::updateBulletsNode( return node; } +QSizeF QskPageIndicatorSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& ) const +{ + using Q = QskPageIndicator; + + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto indicator = static_cast< const QskPageIndicator* >( skinnable ); + + const auto bulletSize = indicator->strutSizeHint( Q::Bullet ); + + const auto maxSize = bulletSize.expandedTo( + indicator->strutSizeHint( Q::Highlighted ) ); + + const qreal spacing = indicator->spacingHint( Q::Panel ); + + const int n = indicator->count(); + + qreal w = 0; + qreal h = 0; + + if ( indicator->orientation() == Qt::Horizontal ) + { + if ( n > 0 ) + { + w += maxSize.width(); + + if ( n > 1 ) + w += ( n - 1 ) * ( bulletSize.width() + spacing ); + } + + h = maxSize.height(); + } + else + { + if ( n > 0 ) + { + h += maxSize.height(); + + if ( n > 1 ) + h += ( n - 1 ) * ( bulletSize.height() + spacing ); + } + + w = maxSize.width(); + } + + const auto hint = indicator->outerBoxSize( Q::Panel, QSizeF( w, h ) ); + return hint.expandedTo( indicator->strutSizeHint( Q::Panel ) ); +} + #include "moc_QskPageIndicatorSkinlet.cpp" diff --git a/src/controls/QskPageIndicatorSkinlet.h b/src/controls/QskPageIndicatorSkinlet.h index a1c0ff14..0685a309 100644 --- a/src/controls/QskPageIndicatorSkinlet.h +++ b/src/controls/QskPageIndicatorSkinlet.h @@ -29,6 +29,9 @@ class QSK_EXPORT QskPageIndicatorSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskProgressBar.cpp b/src/controls/QskProgressBar.cpp index 2271cb52..d2fd621d 100644 --- a/src/controls/QskProgressBar.cpp +++ b/src/controls/QskProgressBar.cpp @@ -266,17 +266,6 @@ qreal QskProgressBar::valueAsRatio() const return valueAsRatio( m_data->value ); } -QSizeF QskProgressBar::contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - if ( orientation() == Qt::Horizontal ) - return QSizeF( -1, extent() ); - else - return QSizeF( extent(), -1 ); -} - void QskProgressBar::componentComplete() { Inherited::componentComplete(); diff --git a/src/controls/QskProgressBar.h b/src/controls/QskProgressBar.h index 4185cad4..b24a271c 100644 --- a/src/controls/QskProgressBar.h +++ b/src/controls/QskProgressBar.h @@ -79,7 +79,6 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl void originChanged( qreal ); protected: - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; void componentComplete() override; void itemChange( ItemChange, const ItemChangeData& ) override; diff --git a/src/controls/QskProgressBarSkinlet.cpp b/src/controls/QskProgressBarSkinlet.cpp index 63584d38..56300c18 100644 --- a/src/controls/QskProgressBarSkinlet.cpp +++ b/src/controls/QskProgressBarSkinlet.cpp @@ -171,4 +171,20 @@ QRectF QskProgressBarSkinlet::barRect( const QskProgressBar* bar ) const return rect; } +QSizeF QskProgressBarSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto bar = static_cast< const QskProgressBar* >( skinnable ); + + const auto extent = bar->extent(); + + if ( bar->orientation() == Qt::Horizontal ) + return QSizeF( -1, extent ); + else + return QSizeF( extent, -1 ); +} + #include "moc_QskProgressBarSkinlet.cpp" diff --git a/src/controls/QskProgressBarSkinlet.h b/src/controls/QskProgressBarSkinlet.h index c1cb760b..c7eebdd2 100644 --- a/src/controls/QskProgressBarSkinlet.h +++ b/src/controls/QskProgressBarSkinlet.h @@ -31,6 +31,9 @@ class QSK_EXPORT QskProgressBarSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskPushButton.cpp b/src/controls/QskPushButton.cpp index 2f9a7aab..b1875259 100644 --- a/src/controls/QskPushButton.cpp +++ b/src/controls/QskPushButton.cpp @@ -31,6 +31,17 @@ class QskPushButton::PrivateData textOptions.setElideMode( Qt::ElideMiddle ); } + void ensureGraphic( const QskPushButton* button ) + { + if ( isGraphicSourceDirty ) + { + if ( !graphicSource.isEmpty() ) + graphic = button->loadGraphic( graphicSource ); + + isGraphicSourceDirty = false; + } + } + QString text; QskTextOptions textOptions; @@ -215,6 +226,7 @@ void QskPushButton::setGraphic( const QskGraphic& graphic ) QskGraphic QskPushButton::graphic() const { + m_data->ensureGraphic( this ); return m_data->graphic; } @@ -223,15 +235,9 @@ bool QskPushButton::hasGraphic() const return !( graphic().isEmpty() && graphicSource().isEmpty() ); } -void QskPushButton::updateLayout() +void QskPushButton::updateResources() { - if ( m_data->isGraphicSourceDirty ) - { - if ( !m_data->graphicSource.isEmpty() ) - m_data->graphic = loadGraphic( m_data->graphicSource ); - - m_data->isGraphicSourceDirty = false; - } + m_data->ensureGraphic( this ); } QRectF QskPushButton::layoutRectForSize( const QSizeF& size ) const @@ -239,55 +245,6 @@ QRectF QskPushButton::layoutRectForSize( const QSizeF& size ) const return innerBox( Panel, subControlRect( size, Panel ) ); } -QSizeF QskPushButton::contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - QSizeF size( 0, 0 ); - - const QFontMetricsF fm( font() ); - - if ( !m_data->text.isEmpty() ) - { - // in elide mode we might want to ignore the text width ??? - - size += fm.size( Qt::TextShowMnemonic, m_data->text ); - } - - if ( m_data->isGraphicSourceDirty ) - { - if ( !m_data->graphicSource.isEmpty() ) - m_data->graphic = loadGraphic( m_data->graphicSource ); - - m_data->isGraphicSourceDirty = false; - } - - if ( !m_data->graphic.isEmpty() ) - { - qreal w = m_data->graphicSourceSize.width(); - qreal h = m_data->graphicSourceSize.height(); - - if ( ( w < 0.0 ) && ( h < 0.0 ) ) - h = 1.5 * fm.height(); - - if ( w < 0 ) - w = m_data->graphic.widthForHeight( h ); - else if ( h < 0 ) - h = m_data->graphic.heightForWidth( w ); - - const qreal padding = 2.0; // Graphic::Padding ??? - - size.rheight() += 2 * padding + h; - size.rwidth() = qMax( size.width(), w ); - } - - size = size.expandedTo( strutSizeHint( Panel ) ); - size = outerBoxSize( Panel, size ); - - return size; -} - void QskPushButton::changeEvent( QEvent* event ) { switch ( event->type() ) diff --git a/src/controls/QskPushButton.h b/src/controls/QskPushButton.h index ccec1b9d..7bf4a168 100644 --- a/src/controls/QskPushButton.h +++ b/src/controls/QskPushButton.h @@ -92,11 +92,9 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton void hoverLeaveEvent( QHoverEvent* ) override; void changeEvent( QEvent* ) override; - void updateLayout() override; + void updateResources() override; virtual QskGraphic loadGraphic( const QUrl& ) const; - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; - private: class PrivateData; std::unique_ptr< PrivateData > m_data; diff --git a/src/controls/QskPushButtonSkinlet.cpp b/src/controls/QskPushButtonSkinlet.cpp index 77950f57..198e2474 100644 --- a/src/controls/QskPushButtonSkinlet.cpp +++ b/src/controls/QskPushButtonSkinlet.cpp @@ -165,4 +165,66 @@ QSGNode* QskPushButtonSkinlet::updateTextNode( button->text(), button->textOptions(), QskPushButton::Text ); } +QSizeF QskPushButtonSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto button = static_cast< const QskPushButton* >( skinnable ); + + QSizeF size( 0, 0 ); + + const QFontMetricsF fm( button->font() ); + + if ( !button->text().isEmpty() ) + { + // in elide mode we might want to ignore the text width ??? + + size += fm.size( Qt::TextShowMnemonic, button->text() ); + } + + if ( button->hasGraphic() ) + { + const auto sz = button->graphicSourceSize(); + + qreal w = sz.width(); + qreal h = sz.height(); + + if ( w < 0.0 || h < 0.0 ) + { + const auto graphic = button->graphic(); + + if ( !graphic.isEmpty() ) + { + + if ( ( w < 0.0 ) && ( h < 0.0 ) ) + { + // strutSizeHint( Graphic ) ??? + h = 1.5 * fm.height(); + } + + if ( w < 0 ) + { + w = graphic.widthForHeight( h ); + } + else if ( h < 0 ) + { + h = graphic.heightForWidth( w ); + } + } + } + + const qreal padding = 2.0; // paddingHint( Graphic ) ??? + + size.rheight() += 2 * padding + h; + size.rwidth() = qMax( size.width(), w ); + } + + size = size.expandedTo( button->strutSizeHint( QskPushButton::Panel ) ); + size = button->outerBoxSize( QskPushButton::Panel, size ); + + return size; +} + #include "moc_QskPushButtonSkinlet.cpp" diff --git a/src/controls/QskPushButtonSkinlet.h b/src/controls/QskPushButtonSkinlet.h index 990cd944..088b4a70 100644 --- a/src/controls/QskPushButtonSkinlet.h +++ b/src/controls/QskPushButtonSkinlet.h @@ -30,6 +30,9 @@ class QSK_EXPORT QskPushButtonSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskSeparator.cpp b/src/controls/QskSeparator.cpp index 6ea1a311..8d789c67 100644 --- a/src/controls/QskSeparator.cpp +++ b/src/controls/QskSeparator.cpp @@ -70,20 +70,6 @@ qreal QskSeparator::extent() const return metric( Panel | QskAspect::Size ); } -QSizeF QskSeparator::contentsSizeHint( - Qt::SizeHint which, const QSizeF& ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - const qreal m = extent(); - - if ( m_orientation == Qt::Horizontal ) - return QSizeF( -1, m ); - else - return QSizeF( m, -1 ); -} - QskAspect::Placement QskSeparator::effectivePlacement() const { return static_cast< QskAspect::Placement >( m_orientation ); diff --git a/src/controls/QskSeparator.h b/src/controls/QskSeparator.h index fcb95199..f9c2f71b 100644 --- a/src/controls/QskSeparator.h +++ b/src/controls/QskSeparator.h @@ -41,9 +41,6 @@ class QSK_EXPORT QskSeparator : public QskControl void orientationChanged( Qt::Orientation ); void extentChanged( qreal ); - protected: - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; - private: Qt::Orientation m_orientation; }; diff --git a/src/controls/QskSeparatorSkinlet.cpp b/src/controls/QskSeparatorSkinlet.cpp index 7160a2cd..7df87569 100644 --- a/src/controls/QskSeparatorSkinlet.cpp +++ b/src/controls/QskSeparatorSkinlet.cpp @@ -67,4 +67,20 @@ QRectF QskSeparatorSkinlet::panelRect( return r; } +QSizeF QskSeparatorSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto separator = static_cast< const QskSeparator* >( skinnable ); + + const qreal extent = separator->extent(); + + if ( separator->orientation() == Qt::Horizontal ) + return QSizeF( -1, extent ); + else + return QSizeF( extent, -1 ); +} + #include "moc_QskSeparatorSkinlet.cpp" diff --git a/src/controls/QskSeparatorSkinlet.h b/src/controls/QskSeparatorSkinlet.h index 2c6fb740..012552a6 100644 --- a/src/controls/QskSeparatorSkinlet.h +++ b/src/controls/QskSeparatorSkinlet.h @@ -28,6 +28,9 @@ class QSK_EXPORT QskSeparatorSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF& rect, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskSkinlet.h b/src/controls/QskSkinlet.h index dc219dc4..8aa8d379 100644 --- a/src/controls/QskSkinlet.h +++ b/src/controls/QskSkinlet.h @@ -23,10 +23,6 @@ class QskTextOptions; class QSGNode; -class QRectF; -class QRect; -class QSize; - class QSK_EXPORT QskSkinlet { Q_GADGET @@ -39,8 +35,11 @@ class QSK_EXPORT QskSkinlet virtual void updateNode( QskSkinnable*, QSGNode* parent ) const; - virtual QRectF subControlRect( - const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const; + virtual QRectF subControlRect( const QskSkinnable*, + const QRectF&, QskAspect::Subcontrol ) const; + + virtual QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const; const QVector< quint8 >& nodeRoles() const; @@ -116,4 +115,10 @@ inline QSGNode* QskSkinlet::updateSubNode( return nullptr; } +inline QSizeF QskSkinlet::sizeHint( + const QskSkinnable*, Qt::SizeHint, const QSizeF& ) const +{ + return QSizeF(); +} + #endif diff --git a/src/controls/QskSlider.cpp b/src/controls/QskSlider.cpp index c5085448..e65d0269 100644 --- a/src/controls/QskSlider.cpp +++ b/src/controls/QskSlider.cpp @@ -111,17 +111,6 @@ void QskSlider::aboutToShow() Inherited::aboutToShow(); } -QSizeF QskSlider::contentsSizeHint( - Qt::SizeHint which, const QSizeF& ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - const qreal extent = metric( QskSlider::Panel | QskAspect::Size ); - return ( m_data->orientation == Qt::Horizontal ) - ? QSizeF( 4 * extent, extent ) : QSizeF( extent, 4 * extent ); -} - QSizeF QskSlider::handleSize() const { return handleRect().size(); diff --git a/src/controls/QskSlider.h b/src/controls/QskSlider.h index e54c1510..21d77d4a 100644 --- a/src/controls/QskSlider.h +++ b/src/controls/QskSlider.h @@ -56,8 +56,6 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput void mouseMoveEvent( QMouseEvent* e ) override; void mouseReleaseEvent( QMouseEvent* e ) override; - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; - QSizeF handleSize() const; QRectF handleRect() const; diff --git a/src/controls/QskSliderSkinlet.cpp b/src/controls/QskSliderSkinlet.cpp index f6907e04..c7b46186 100644 --- a/src/controls/QskSliderSkinlet.cpp +++ b/src/controls/QskSliderSkinlet.cpp @@ -220,4 +220,20 @@ QRectF QskSliderSkinlet::handleRect( return handleRect; } +QSizeF QskSliderSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto slider = static_cast< const QskSlider* >( skinnable ); + + // strutSizeHint( ... ) ??? + const qreal m1 = slider->metric( QskSlider::Panel | QskAspect::Size ); + const qreal m2 = 4 * m1; + + return ( slider->orientation() == Qt::Horizontal ) + ? QSizeF( m2, m1 ) : QSizeF( m1, m2 ); +} + #include "moc_QskSliderSkinlet.cpp" diff --git a/src/controls/QskSliderSkinlet.h b/src/controls/QskSliderSkinlet.h index dd9ed61e..b77460bb 100644 --- a/src/controls/QskSliderSkinlet.h +++ b/src/controls/QskSliderSkinlet.h @@ -31,6 +31,9 @@ class QSK_EXPORT QskSliderSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF& rect, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskTabButton.cpp b/src/controls/QskTabButton.cpp index 0dc29f62..adbf0800 100644 --- a/src/controls/QskTabButton.cpp +++ b/src/controls/QskTabButton.cpp @@ -87,23 +87,6 @@ QskTextOptions QskTabButton::textOptions() const return m_data->textOptions; } -QSizeF QskTabButton::contentsSizeHint( - Qt::SizeHint which, const QSizeF& ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - auto size = strutSizeHint( Panel ); - - if ( !m_data->text.isEmpty() ) - { - const QFontMetricsF fm( effectiveFont( Text ) ); - size += fm.size( Qt::TextShowMnemonic, m_data->text ); - } - - return size; -} - QRectF QskTabButton::layoutRectForSize( const QSizeF& size ) const { return innerBox( Panel, subControlRect( size, Panel ) ); diff --git a/src/controls/QskTabButton.h b/src/controls/QskTabButton.h index b05db510..c70382c7 100644 --- a/src/controls/QskTabButton.h +++ b/src/controls/QskTabButton.h @@ -49,7 +49,6 @@ class QSK_EXPORT QskTabButton : public QskAbstractButton protected: void changeEvent( QEvent* ) override; - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; private: class PrivateData; diff --git a/src/controls/QskTabButtonSkinlet.cpp b/src/controls/QskTabButtonSkinlet.cpp index abd03607..2df6e976 100644 --- a/src/controls/QskTabButtonSkinlet.cpp +++ b/src/controls/QskTabButtonSkinlet.cpp @@ -7,6 +7,7 @@ #include "QskTabButton.h" #include "QskTextOptions.h" +#include QskTabButtonSkinlet::QskTabButtonSkinlet( QskSkin* skin ) : Inherited( skin ) @@ -58,4 +59,24 @@ QSGNode* QskTabButtonSkinlet::updateSubNode( return Inherited::updateSubNode( skinnable, nodeRole, node ); } +QSizeF QskTabButtonSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto tabButton = static_cast< const QskTabButton* >( skinnable ); + + auto size = tabButton->strutSizeHint( QskTabButton::Panel ); + const auto text = tabButton->text(); + + if ( !text.isEmpty() ) + { + const QFontMetricsF fm( tabButton->effectiveFont( QskTabButton::Text ) ); + size += fm.size( Qt::TextShowMnemonic, text ); + } + + return size; +} + #include "moc_QskTabButtonSkinlet.cpp" diff --git a/src/controls/QskTabButtonSkinlet.h b/src/controls/QskTabButtonSkinlet.h index 5a846797..e7daaa51 100644 --- a/src/controls/QskTabButtonSkinlet.h +++ b/src/controls/QskTabButtonSkinlet.h @@ -27,6 +27,9 @@ class QSK_EXPORT QskTabButtonSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF& rect, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/controls/QskTextInput.cpp b/src/controls/QskTextInput.cpp index 4b0e3e13..a00be277 100644 --- a/src/controls/QskTextInput.cpp +++ b/src/controls/QskTextInput.cpp @@ -451,7 +451,7 @@ void QskTextInput::focusOutEvent( QFocusEvent* event ) Inherited::focusOutEvent( event ); } -QSizeF QskTextInput::contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const +QSizeF QskTextInput::layoutSizeHint( Qt::SizeHint which, const QSizeF& ) const { if ( which != Qt::PreferredSize ) return QSizeF(); @@ -460,11 +460,12 @@ QSizeF QskTextInput::contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const input->updateMetrics(); - const qreal w = input->implicitWidth(); - const qreal h = input->implicitHeight(); + QSizeF hint( input->implicitWidth(), input->implicitHeight() ); - const auto hint = outerBoxSize( Panel, QSizeF( w, h ) ); - return hint.expandedTo( strutSizeHint( Panel ) ); + hint = outerBoxSize( Panel, hint ); + hint = hint.expandedTo( strutSizeHint( Panel ) ); + + return hint; } void QskTextInput::updateLayout() diff --git a/src/controls/QskTextInput.h b/src/controls/QskTextInput.h index 7a22c621..769b271c 100644 --- a/src/controls/QskTextInput.h +++ b/src/controls/QskTextInput.h @@ -201,7 +201,7 @@ class QSK_EXPORT QskTextInput : public QskControl void keyPressEvent( QKeyEvent* ) override; void keyReleaseEvent( QKeyEvent* ) override; - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; + QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override; void updateLayout() override; void updateNode( QSGNode* ) override; diff --git a/src/controls/QskTextLabel.cpp b/src/controls/QskTextLabel.cpp index 8ddac3ea..bedebc79 100644 --- a/src/controls/QskTextLabel.cpp +++ b/src/controls/QskTextLabel.cpp @@ -6,10 +6,6 @@ #include "QskTextLabel.h" #include "QskAspect.h" #include "QskTextOptions.h" -#include "QskTextRenderer.h" - -#include -#include QSK_SUBCONTROL( QskTextLabel, Panel ) QSK_SUBCONTROL( QskTextLabel, Text ) @@ -24,18 +20,15 @@ class QskTextLabel::PrivateData effectiveTextFormat = textOptions.format(); } - QskTextOptions effectiveOptions() const + inline QskTextOptions::TextFormat effectiveFormat() const { if ( textOptions.format() != QskTextOptions::AutoText ) - return textOptions; + return textOptions.format(); if ( effectiveTextFormat == QskTextOptions::AutoText ) effectiveTextFormat = textOptions.effectiveFormat( text ); - QskTextOptions options = textOptions; - options.setFormat( effectiveTextFormat ); - - return options; + return effectiveTextFormat; } QString text; @@ -140,6 +133,11 @@ QskTextOptions::TextFormat QskTextLabel::textFormat() const return m_data->textOptions.format(); } +QskTextOptions::TextFormat QskTextLabel::effectiveTextFormat() const +{ + return m_data->effectiveFormat(); +} + void QskTextLabel::setWrapMode( QskTextOptions::WrapMode wrapMode ) { auto options = m_data->textOptions; @@ -223,80 +221,6 @@ QFont QskTextLabel::font() const return effectiveFont( QskTextLabel::Text ); } -QSizeF QskTextLabel::contentsSizeHint( - Qt::SizeHint which, const QSizeF& constraint ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - const auto font = effectiveFont( Text ); - - QSizeF hint; - - const qreal lineHeight = QFontMetricsF( font ).height(); - - if ( m_data->text.isEmpty() ) - { - if ( constraint.height() < 0.0 ) - hint.setHeight( qCeil( lineHeight ) ); - } - else if ( constraint.width() >= 0.0 ) - { - if ( m_data->textOptions.effectiveElideMode() != Qt::ElideNone ) - { - hint.setHeight( qCeil( lineHeight ) ); - } - else - { - /* - In case of QskTextOptions::NoWrap we could count - the line numbers and calculate the height from - lineHeight. TODO ... - */ - qreal maxHeight = std::numeric_limits< qreal >::max(); - if ( maxHeight / lineHeight > m_data->textOptions.maximumLineCount() ) - { - // be careful with overflows - maxHeight = m_data->textOptions.maximumLineCount() * lineHeight; - } - - QSizeF size( constraint.width(), maxHeight ); - - size = QskTextRenderer::textSize( - m_data->text, font, m_data->effectiveOptions(), size ); - - if ( m_data->hasPanel ) - size = outerBoxSize( Panel, size ); - - hint.setHeight( qCeil( size.height() ) ); - } - } - else if ( constraint.height() >= 0.0 ) - { - const qreal maxWidth = std::numeric_limits< qreal >::max(); - - QSizeF size( maxWidth, constraint.height() ); - - size = QskTextRenderer::textSize( m_data->text, font, - m_data->effectiveOptions(), size ); - - if ( m_data->hasPanel ) - size = outerBoxSize( Panel, size ); - - hint.setWidth( qCeil( size.width() ) ); - } - else - { - hint = QskTextRenderer::textSize( - m_data->text, font, m_data->effectiveOptions() ); - - if ( m_data->hasPanel ) - hint = outerBoxSize( Panel, hint ); - } - - return hint; -} - void QskTextLabel::changeEvent( QEvent* event ) { switch ( event->type() ) diff --git a/src/controls/QskTextLabel.h b/src/controls/QskTextLabel.h index be847206..7957ecf2 100644 --- a/src/controls/QskTextLabel.h +++ b/src/controls/QskTextLabel.h @@ -58,6 +58,8 @@ class QSK_EXPORT QskTextLabel : public QskControl void setTextFormat( QskTextOptions::TextFormat ); QskTextOptions::TextFormat textFormat() const; + QskTextOptions::TextFormat effectiveTextFormat() const; + void setWrapMode( QskTextOptions::WrapMode ); QskTextOptions::WrapMode wrapMode() const; @@ -87,9 +89,6 @@ class QSK_EXPORT QskTextLabel : public QskControl protected: void changeEvent( QEvent* ) override; - QSizeF contentsSizeHint( - Qt::SizeHint, const QSizeF& ) const override; - private: class PrivateData; std::unique_ptr< PrivateData > m_data; diff --git a/src/controls/QskTextLabelSkinlet.cpp b/src/controls/QskTextLabelSkinlet.cpp index a06f446b..229afc49 100644 --- a/src/controls/QskTextLabelSkinlet.cpp +++ b/src/controls/QskTextLabelSkinlet.cpp @@ -7,6 +7,10 @@ #include "QskTextLabel.h" #include "QskTextOptions.h" +#include "QskTextRenderer.h" + +#include +#include QskTextLabelSkinlet::QskTextLabelSkinlet( QskSkin* skin ) : Inherited( skin ) @@ -63,4 +67,82 @@ QSGNode* QskTextLabelSkinlet::updateSubNode( return Inherited::updateSubNode( skinnable, nodeRole, node ); } +QSizeF QskTextLabelSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& constraint ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto label = static_cast< const QskTextLabel* >( skinnable ); + + const auto font = label->effectiveFont( QskTextLabel::Text ); + + auto textOptions = label->textOptions(); + textOptions.setFormat( label->effectiveTextFormat() ); + + const auto text = label->text(); + + QSizeF hint; + + const qreal lineHeight = QFontMetricsF( font ).height(); + + if ( text.isEmpty() ) + { + if ( constraint.height() < 0.0 ) + hint.setHeight( qCeil( lineHeight ) ); + } + else if ( constraint.width() >= 0.0 ) + { + if ( textOptions.effectiveElideMode() != Qt::ElideNone ) + { + hint.setHeight( qCeil( lineHeight ) ); + } + else + { + /* + In case of QskTextOptions::NoWrap we could count + the line numbers and calculate the height from + lineHeight. TODO ... + */ + qreal maxHeight = std::numeric_limits< qreal >::max(); + if ( maxHeight / lineHeight > textOptions.maximumLineCount() ) + { + // be careful with overflows + maxHeight = textOptions.maximumLineCount() * lineHeight; + } + + QSizeF size( constraint.width(), maxHeight ); + + size = QskTextRenderer::textSize( text, font, textOptions, size ); + + if ( label->hasPanel() ) + size = label->outerBoxSize( QskTextLabel::Panel, size ); + + hint.setHeight( qCeil( size.height() ) ); + } + } + else if ( constraint.height() >= 0.0 ) + { + const qreal maxWidth = std::numeric_limits< qreal >::max(); + + QSizeF size( maxWidth, constraint.height() ); + + size = QskTextRenderer::textSize( text, font, textOptions, size ); + + if ( label->hasPanel() ) + size = label->outerBoxSize( QskTextLabel::Panel, size ); + + hint.setWidth( qCeil( size.width() ) ); + } + else + { + hint = QskTextRenderer::textSize( text, font, textOptions ); + + if ( label->hasPanel() ) + hint = label->outerBoxSize( QskTextLabel::Panel, hint ); + } + + return hint; +} + #include "moc_QskTextLabelSkinlet.cpp" diff --git a/src/controls/QskTextLabelSkinlet.h b/src/controls/QskTextLabelSkinlet.h index 3bcd6f36..499dc857 100644 --- a/src/controls/QskTextLabelSkinlet.h +++ b/src/controls/QskTextLabelSkinlet.h @@ -26,6 +26,9 @@ class QSK_EXPORT QskTextLabelSkinlet : public QskSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; + QSizeF sizeHint( const QskSkinnable*, + Qt::SizeHint, const QSizeF& ) const override; + protected: QSGNode* updateSubNode( const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; diff --git a/src/dialogs/QskSelectionSubWindow.cpp b/src/dialogs/QskSelectionSubWindow.cpp index 5341cb89..60d27a1a 100644 --- a/src/dialogs/QskSelectionSubWindow.cpp +++ b/src/dialogs/QskSelectionSubWindow.cpp @@ -45,18 +45,6 @@ namespace connect( this, &QskSimpleListBox::entriesChanged, subWindow, &QskSelectionSubWindow::entriesChanged ); } - -#if 1 - // how to find a reasonable default size ??? - QSizeF contentsSizeHint( - Qt::SizeHint which, const QSizeF& ) const override - { - if ( which == Qt::PreferredSize ) - return QSizeF( 500, 500 ); - - return QSizeF(); - } -#endif }; } @@ -75,6 +63,9 @@ QskSelectionSubWindow::QskSelectionSubWindow( QQuickItem* parent ) m_data->textLabel->setVisible( false ); m_data->listBox = new ListBox( this ); +#if 1 + m_data->listBox->setPreferredSize( 500, 500 ); +#endif auto box = new QskLinearBox( Qt::Vertical ); box->setSpacing( 10 ); // hint diff --git a/src/dialogs/QskSelectionWindow.cpp b/src/dialogs/QskSelectionWindow.cpp index c321ac6b..6229b2d9 100644 --- a/src/dialogs/QskSelectionWindow.cpp +++ b/src/dialogs/QskSelectionWindow.cpp @@ -48,18 +48,6 @@ namespace connect( this, &QskSimpleListBox::entriesChanged, window, &QskSelectionWindow::entriesChanged ); } - -#if 1 - // how to find a reasonable default size ??? - QSizeF contentsSizeHint( - Qt::SizeHint which, const QSizeF& ) const override - { - if ( which == Qt::PreferredSize ) - return QSizeF( 500, 500 ); - - return QSizeF(); - } -#endif }; } @@ -81,6 +69,9 @@ QskSelectionWindow::QskSelectionWindow( QWindow* parent ) m_data->textLabel->setVisible( false ); m_data->listBox = new ListBox( this ); +#if 1 + m_data->listBox->setPreferredSize( 500, 500 ); +#endif auto box = new QskLinearBox( Qt::Vertical ); box->setMargins( 5 );