sizeHint calculations moved to skinlet

This commit is contained in:
Uwe Rathmann 2020-12-29 10:11:31 +01:00
parent afd3a3ded8
commit c419b26850
4 changed files with 64 additions and 39 deletions

View File

@ -54,6 +54,7 @@ class QskStatusIndicator::PrivateData
int currentStatus; int currentStatus;
QMap< int, StatusData > map; QMap< int, StatusData > map;
mutable QList<int> statusList;
}; };
QskStatusIndicator::QskStatusIndicator( QQuickItem* parent ) QskStatusIndicator::QskStatusIndicator( QQuickItem* parent )
@ -69,8 +70,8 @@ QskStatusIndicator::~QskStatusIndicator()
QUrl QskStatusIndicator::source( int status ) const QUrl QskStatusIndicator::source( int status ) const
{ {
const auto it = m_data->map.find( status ); const auto it = m_data->map.constFind( status );
if ( it != m_data->map.end() ) if ( it != m_data->map.constEnd() )
return it->source; return it->source;
return QUrl(); return QUrl();
@ -95,6 +96,8 @@ void QskStatusIndicator::setSource( int status, const QUrl& url )
else else
{ {
m_data->map.insert( status, StatusData( url ) ); m_data->map.insert( status, StatusData( url ) );
m_data->statusList.clear();
hasChanged = true; hasChanged = true;
} }
@ -111,7 +114,10 @@ QskGraphic QskStatusIndicator::graphic( int status ) const
{ {
const auto it = m_data->map.find( status ); const auto it = m_data->map.find( status );
if ( it != m_data->map.end() ) if ( it != m_data->map.end() )
{
it->ensureGraphic( this );
return it->graphic; return it->graphic;
}
return QskGraphic(); return QskGraphic();
} }
@ -135,6 +141,7 @@ void QskStatusIndicator::setGraphic( int status, const QskGraphic& graphic )
else else
{ {
m_data->map.insert( status, StatusData( graphic ) ); m_data->map.insert( status, StatusData( graphic ) );
m_data->statusList.clear();
hasChanged = true; hasChanged = true;
} }
@ -153,41 +160,6 @@ QskColorFilter QskStatusIndicator::graphicFilter( int status ) const
return effectiveGraphicFilter( QskStatusIndicator::Graphic ); 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 int QskStatusIndicator::status() const
{ {
return m_data->currentStatus; return m_data->currentStatus;
@ -222,6 +194,19 @@ void QskStatusIndicator::setStatus( int status )
update(); update();
} }
QList<int> 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 ) void QskStatusIndicator::changeEvent( QEvent* event )
{ {
if ( event->type() == QEvent::StyleChange ) if ( event->type() == QEvent::StyleChange )

View File

@ -38,6 +38,8 @@ class QSK_EXPORT QskStatusIndicator : public QskControl
int status() const; int status() const;
bool hasStatus( int status ) const; bool hasStatus( int status ) const;
QList<int> statusList() const;
public Q_SLOTS: public Q_SLOTS:
void setStatus( int status ); void setStatus( int status );
@ -48,8 +50,6 @@ class QSK_EXPORT QskStatusIndicator : public QskControl
void changeEvent( QEvent* ) override; void changeEvent( QEvent* ) override;
void updateLayout() override; void updateLayout() override;
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
private: private:
class PrivateData; class PrivateData;
std::unique_ptr< PrivateData > m_data; std::unique_ptr< PrivateData > m_data;

View File

@ -81,4 +81,41 @@ QSGNode* QskStatusIndicatorSkinlet::updateGraphicNode(
return node; 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" #include "moc_QskStatusIndicatorSkinlet.cpp"

View File

@ -28,6 +28,9 @@ class QSK_EXPORT QskStatusIndicatorSkinlet : public QskSkinlet
QRectF subControlRect( const QskSkinnable*, QRectF subControlRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol ) const override; const QRectF&, QskAspect::Subcontrol ) const override;
QSizeF sizeHint( const QskSkinnable*,
Qt::SizeHint, const QSizeF& ) const override;
protected: protected:
QSGNode* updateSubNode( const QskSkinnable*, QSGNode* updateSubNode( const QskSkinnable*,
quint8 nodeRole, QSGNode* ) const override; quint8 nodeRole, QSGNode* ) const override;