2017-07-21 18:21:34 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskStatusIndicator.h"
|
|
|
|
#include "QskColorFilter.h"
|
2018-08-03 08:15:28 +02:00
|
|
|
#include "QskGraphic.h"
|
2017-07-21 18:21:34 +02:00
|
|
|
#include "QskGraphicProvider.h"
|
2018-07-19 14:10:48 +02:00
|
|
|
|
|
|
|
#include <qdebug.h>
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
QSK_SUBCONTROL( QskStatusIndicator, Graphic )
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
class StatusData
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
public:
|
|
|
|
StatusData( const QskGraphic& graphic )
|
|
|
|
: graphic( graphic )
|
|
|
|
, isDirty( false )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
StatusData( const QUrl& url )
|
|
|
|
: source( url )
|
|
|
|
, isDirty( !url.isEmpty() )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ensureGraphic( const QskStatusIndicator* indicator )
|
|
|
|
{
|
|
|
|
if ( !source.isEmpty() && isDirty )
|
|
|
|
{
|
|
|
|
graphic = indicator->loadSource( source );
|
|
|
|
isDirty = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QUrl source;
|
|
|
|
QskGraphic graphic;
|
|
|
|
bool isDirty : 1;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
class QskStatusIndicator::PrivateData
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
public:
|
|
|
|
PrivateData()
|
|
|
|
: currentStatus( -1 )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int currentStatus;
|
|
|
|
QMap< int, StatusData > map;
|
|
|
|
};
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
QskStatusIndicator::QskStatusIndicator( QQuickItem* parent )
|
|
|
|
: Inherited( parent )
|
|
|
|
, m_data( new PrivateData() )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2017-08-31 09:09:05 +02:00
|
|
|
initSizePolicy( QskSizePolicy::Expanding, QskSizePolicy::Expanding );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QskStatusIndicator::~QskStatusIndicator()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QUrl QskStatusIndicator::source( int status ) const
|
|
|
|
{
|
|
|
|
const auto it = m_data->map.find( status );
|
|
|
|
if ( it != m_data->map.end() )
|
|
|
|
return it->source;
|
|
|
|
|
|
|
|
return QUrl();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStatusIndicator::setSource( int status, const QUrl& url )
|
|
|
|
{
|
|
|
|
bool hasChanged = false;
|
|
|
|
|
|
|
|
const auto it = m_data->map.find( status );
|
|
|
|
if ( it != m_data->map.end() )
|
|
|
|
{
|
|
|
|
if ( it->source != url )
|
|
|
|
{
|
|
|
|
it->source = url;
|
|
|
|
it->graphic.reset();
|
|
|
|
it->isDirty = !url.isEmpty();
|
|
|
|
|
|
|
|
hasChanged = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_data->map.insert( status, StatusData( url ) );
|
|
|
|
hasChanged = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasChanged )
|
|
|
|
{
|
|
|
|
resetImplicitSize();
|
|
|
|
|
|
|
|
if ( status == m_data->currentStatus )
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QskGraphic QskStatusIndicator::graphic( int status ) const
|
|
|
|
{
|
|
|
|
const auto it = m_data->map.find( status );
|
|
|
|
if ( it != m_data->map.end() )
|
|
|
|
return it->graphic;
|
|
|
|
|
|
|
|
return QskGraphic();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStatusIndicator::setGraphic( int status, const QskGraphic& graphic )
|
|
|
|
{
|
|
|
|
bool hasChanged = false;
|
|
|
|
|
|
|
|
const auto it = m_data->map.find( status );
|
|
|
|
if ( it != m_data->map.end() )
|
|
|
|
{
|
|
|
|
if ( !it->source.isEmpty() || graphic != it->graphic )
|
|
|
|
{
|
|
|
|
it->source.clear();
|
|
|
|
it->isDirty = false;
|
|
|
|
it->graphic = graphic;
|
|
|
|
|
|
|
|
hasChanged = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_data->map.insert( status, StatusData( graphic ) );
|
|
|
|
hasChanged = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasChanged )
|
|
|
|
{
|
|
|
|
resetImplicitSize();
|
|
|
|
|
|
|
|
if ( status == m_data->currentStatus )
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QskColorFilter QskStatusIndicator::graphicFilter( int status ) const
|
|
|
|
{
|
|
|
|
Q_UNUSED( status )
|
|
|
|
return effectiveGraphicFilter( QskStatusIndicator::Graphic );
|
|
|
|
}
|
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
QSizeF QskStatusIndicator::contentsSizeHint(
|
|
|
|
Qt::SizeHint which, const QSizeF& constraint ) const
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2019-09-10 17:01:47 +02:00
|
|
|
if ( which != Qt::PreferredSize )
|
|
|
|
return QSizeF();
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
QSizeF sz;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
for ( auto& statusData : m_data->map )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
statusData.ensureGraphic( this );
|
|
|
|
|
|
|
|
if ( !statusData.graphic.isEmpty() )
|
|
|
|
{
|
2019-09-10 17:01:47 +02:00
|
|
|
auto hint = statusData.graphic.defaultSize();
|
|
|
|
|
|
|
|
if ( !hint.isEmpty() )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2019-09-10 17:01:47 +02:00
|
|
|
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() );
|
|
|
|
}
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
sz = sz.expandedTo( hint );
|
|
|
|
}
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return sz;
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskStatusIndicator::status() const
|
|
|
|
{
|
|
|
|
return m_data->currentStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool QskStatusIndicator::hasStatus( int status ) const
|
|
|
|
{
|
|
|
|
return m_data->map.contains( status );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStatusIndicator::setStatus( int status )
|
|
|
|
{
|
|
|
|
if ( status == m_data->currentStatus )
|
|
|
|
return;
|
|
|
|
|
2017-10-29 14:01:06 +01:00
|
|
|
const auto it = m_data->map.constFind( status );
|
2017-07-21 18:21:34 +02:00
|
|
|
if ( it == m_data->map.constEnd() )
|
|
|
|
{
|
|
|
|
qWarning() << "QskStatusIndicator: invalid status:" << status;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_data->currentStatus = status;
|
|
|
|
Q_EMIT statusChanged( m_data->currentStatus );
|
|
|
|
|
|
|
|
// we should have a mode to decide if we
|
|
|
|
// want to keep the hidden graphics in memory
|
|
|
|
|
|
|
|
if ( it->isDirty )
|
|
|
|
polish();
|
|
|
|
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStatusIndicator::changeEvent( QEvent* event )
|
|
|
|
{
|
|
|
|
if ( event->type() == QEvent::StyleChange )
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
for ( auto& statusData : m_data->map )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
if ( !statusData.source.isEmpty() )
|
|
|
|
{
|
|
|
|
statusData.graphic.reset();
|
|
|
|
statusData.isDirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Inherited::changeEvent( event );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStatusIndicator::updateLayout()
|
|
|
|
{
|
|
|
|
const auto it = m_data->map.find( m_data->currentStatus );
|
|
|
|
if ( it != m_data->map.end() )
|
|
|
|
it->ensureGraphic( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
QskGraphic QskStatusIndicator::loadSource( const QUrl& url ) const
|
|
|
|
{
|
|
|
|
return Qsk::loadGraphic( url );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "moc_QskStatusIndicator.cpp"
|