diff --git a/src/controls/QskStatusIndicator.cpp b/src/controls/QskStatusIndicator.cpp index ab61cdff..fb364b64 100644 --- a/src/controls/QskStatusIndicator.cpp +++ b/src/controls/QskStatusIndicator.cpp @@ -54,6 +54,7 @@ class QskStatusIndicator::PrivateData int currentStatus; QMap< int, StatusData > map; + mutable QList statusList; }; QskStatusIndicator::QskStatusIndicator( QQuickItem* parent ) @@ -69,8 +70,8 @@ QskStatusIndicator::~QskStatusIndicator() QUrl QskStatusIndicator::source( int status ) const { - const auto it = m_data->map.find( status ); - if ( it != m_data->map.end() ) + const auto it = m_data->map.constFind( status ); + if ( it != m_data->map.constEnd() ) return it->source; return QUrl(); @@ -95,6 +96,8 @@ void QskStatusIndicator::setSource( int status, const QUrl& url ) else { m_data->map.insert( status, StatusData( url ) ); + m_data->statusList.clear(); + hasChanged = true; } @@ -111,7 +114,10 @@ QskGraphic QskStatusIndicator::graphic( int status ) const { const auto it = m_data->map.find( status ); if ( it != m_data->map.end() ) + { + it->ensureGraphic( this ); return it->graphic; + } return QskGraphic(); } @@ -135,6 +141,7 @@ void QskStatusIndicator::setGraphic( int status, const QskGraphic& graphic ) else { m_data->map.insert( status, StatusData( graphic ) ); + m_data->statusList.clear(); hasChanged = true; } @@ -153,41 +160,6 @@ QskColorFilter QskStatusIndicator::graphicFilter( int status ) const return effectiveGraphicFilter( QskStatusIndicator::Graphic ); } -QSizeF QskStatusIndicator::contentsSizeHint( - Qt::SizeHint which, const QSizeF& constraint ) const -{ - if ( which != Qt::PreferredSize ) - return QSizeF(); - - QSizeF sz; - - for ( auto& statusData : m_data->map ) - { - statusData.ensureGraphic( this ); - - if ( !statusData.graphic.isEmpty() ) - { - auto hint = statusData.graphic.defaultSize(); - - if ( !hint.isEmpty() ) - { - if ( constraint.width() >= 0.0 ) - { - hint.setHeight( sz.height() * constraint.width() / sz.width() ); - } - else if ( constraint.height() >= 0.0 ) - { - hint.setWidth( sz.width() * constraint.height() / sz.height() ); - } - } - - sz = sz.expandedTo( hint ); - } - } - - return sz; -} - int QskStatusIndicator::status() const { return m_data->currentStatus; @@ -222,6 +194,19 @@ void QskStatusIndicator::setStatus( int status ) update(); } +QList QskStatusIndicator::statusList() const +{ + /* + We should be have a QMap< int, QskGraphic >, so that + users can iterate over all entries without having to + do extra lookups for each entry. TODO ... + */ + if ( m_data->statusList.isEmpty() && !m_data->map.isEmpty() ) + m_data->statusList = m_data->map.keys(); + + return m_data->statusList; +} + void QskStatusIndicator::changeEvent( QEvent* event ) { if ( event->type() == QEvent::StyleChange ) diff --git a/src/controls/QskStatusIndicator.h b/src/controls/QskStatusIndicator.h index 16a6dda5..84fd6203 100644 --- a/src/controls/QskStatusIndicator.h +++ b/src/controls/QskStatusIndicator.h @@ -38,6 +38,8 @@ class QSK_EXPORT QskStatusIndicator : public QskControl int status() const; bool hasStatus( int status ) const; + QList statusList() const; + public Q_SLOTS: void setStatus( int status ); @@ -48,8 +50,6 @@ class QSK_EXPORT QskStatusIndicator : public QskControl void changeEvent( QEvent* ) override; void updateLayout() override; - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; - private: class PrivateData; std::unique_ptr< PrivateData > m_data; diff --git a/src/controls/QskStatusIndicatorSkinlet.cpp b/src/controls/QskStatusIndicatorSkinlet.cpp index 5a45762f..bf47d094 100644 --- a/src/controls/QskStatusIndicatorSkinlet.cpp +++ b/src/controls/QskStatusIndicatorSkinlet.cpp @@ -81,4 +81,41 @@ QSGNode* QskStatusIndicatorSkinlet::updateGraphicNode( return node; } +QSizeF QskStatusIndicatorSkinlet::sizeHint( const QskSkinnable* skinnable, + Qt::SizeHint which, const QSizeF& constraint ) const +{ + if ( which != Qt::PreferredSize ) + return QSizeF(); + + const auto indicator = static_cast< const QskStatusIndicator* >( skinnable ); + + QSizeF sz; + + for ( const auto status : indicator->statusList() ) + { + const auto graphic = indicator->graphic( status ); + + if ( !graphic.isEmpty() ) + { + auto hint = graphic.defaultSize(); + + if ( !hint.isEmpty() ) + { + if ( constraint.width() >= 0.0 ) + { + hint.setHeight( sz.height() * constraint.width() / sz.width() ); + } + else if ( constraint.height() >= 0.0 ) + { + hint.setWidth( sz.width() * constraint.height() / sz.height() ); + } + } + + sz = sz.expandedTo( hint ); + } + } + + return sz; +} + #include "moc_QskStatusIndicatorSkinlet.cpp" diff --git a/src/controls/QskStatusIndicatorSkinlet.h b/src/controls/QskStatusIndicatorSkinlet.h index fe715103..6984f947 100644 --- a/src/controls/QskStatusIndicatorSkinlet.h +++ b/src/controls/QskStatusIndicatorSkinlet.h @@ -28,6 +28,9 @@ class QSK_EXPORT QskStatusIndicatorSkinlet : 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;