indeterminated progress bars

This commit is contained in:
Uwe Rathmann 2020-08-09 10:49:32 +02:00
parent 606a3e2ce2
commit 48a5e387d4
3 changed files with 117 additions and 3 deletions

View File

@ -8,18 +8,73 @@
#include "QskIntervalF.h" #include "QskIntervalF.h"
#include "QskGradient.h" #include "QskGradient.h"
#include "QskFunctions.h" #include "QskFunctions.h"
#include "QskAnimator.h"
#include "QskAspect.h" #include "QskAspect.h"
QSK_SUBCONTROL( QskProgressBar, Groove ) QSK_SUBCONTROL( QskProgressBar, Groove )
QSK_SUBCONTROL( QskProgressBar, Bar ) QSK_SUBCONTROL( QskProgressBar, Bar )
namespace
{
class PositionAnimator : public QskAnimator
{
public:
PositionAnimator( QskProgressBar* progressBar )
: m_progressBar( progressBar )
{
setAutoRepeat( true );
setDuration( 1300 );
setWindow( progressBar->window() );
}
void advance( qreal value ) override
{
const auto aspect = QskProgressBar::Bar | QskAspect::Position;
m_progressBar->setMetric( aspect, value );
m_progressBar->update();
}
private:
QskProgressBar* m_progressBar;
};
}
class QskProgressBar::PrivateData class QskProgressBar::PrivateData
{ {
public: public:
qreal value = 0.0; void updateIndeterminateAnimator( QskProgressBar* progressBar )
{
if ( !isIndeterminate )
{
delete animator;
animator = nullptr;
return;
}
if ( progressBar->window() && progressBar->isVisible() )
{
if ( animator == nullptr )
animator = new PositionAnimator( progressBar );
animator->start();
}
else
{
if ( animator )
animator->stop();
}
}
PositionAnimator* animator = nullptr;
qreal value = 0.0;
qreal origin = 0.0; qreal origin = 0.0;
bool hasOrigin = false; bool hasOrigin = false;
bool isIndeterminate = false;
Qt::Orientation orientation; Qt::Orientation orientation;
}; };
@ -63,6 +118,7 @@ QskProgressBar::QskProgressBar( QQuickItem* parent )
QskProgressBar::~QskProgressBar() QskProgressBar::~QskProgressBar()
{ {
delete m_data->animator;
} }
Qt::Orientation QskProgressBar::orientation() const Qt::Orientation QskProgressBar::orientation() const
@ -84,6 +140,23 @@ void QskProgressBar::setOrientation( Qt::Orientation orientation )
} }
} }
bool QskProgressBar::isIndeterminate() const
{
return m_data->isIndeterminate;
}
void QskProgressBar::setIndeterminate( bool on )
{
if ( on == m_data->isIndeterminate )
return;
m_data->isIndeterminate = on;
m_data->updateIndeterminateAnimator( this );
update();
Q_EMIT indeterminateChanged( on );
}
QskAspect::Placement QskProgressBar::effectivePlacement() const QskAspect::Placement QskProgressBar::effectivePlacement() const
{ {
// so you can define different hints depending on the orientation // so you can define different hints depending on the orientation
@ -228,4 +301,20 @@ void QskProgressBar::setValueInternal( qreal value )
} }
} }
void QskProgressBar::itemChange( QQuickItem::ItemChange change,
const QQuickItem::ItemChangeData& value )
{
switch( static_cast< int >( change ) )
{
case QQuickItem::ItemVisibleHasChanged:
case QQuickItem::ItemSceneChange:
{
m_data->updateIndeterminateAnimator( this );
break;
}
}
Inherited::itemChange( change, value );
}
#include "moc_QskProgressBar.cpp" #include "moc_QskProgressBar.cpp"

View File

@ -17,6 +17,9 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
Q_PROPERTY( Qt::Orientation orientation READ orientation Q_PROPERTY( Qt::Orientation orientation READ orientation
WRITE setOrientation NOTIFY orientationChanged ) WRITE setOrientation NOTIFY orientationChanged )
Q_PROPERTY( bool indeterminate READ isIndeterminate
WRITE setIndeterminate NOTIFY indeterminateChanged )
Q_PROPERTY( qreal origin READ origin Q_PROPERTY( qreal origin READ origin
WRITE setOrigin RESET resetOrigin NOTIFY originChanged ) WRITE setOrigin RESET resetOrigin NOTIFY originChanged )
@ -40,6 +43,9 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
Qt::Orientation orientation() const; Qt::Orientation orientation() const;
void setOrientation( Qt::Orientation orientation ); void setOrientation( Qt::Orientation orientation );
bool isIndeterminate() const;
void setIndeterminate( bool on = true );
QskAspect::Placement effectivePlacement() const override; QskAspect::Placement effectivePlacement() const override;
void setBarGradient( const QskGradient & ); void setBarGradient( const QskGradient & );
@ -63,12 +69,14 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
Q_SIGNALS: Q_SIGNALS:
void orientationChanged( Qt::Orientation ); void orientationChanged( Qt::Orientation );
void indeterminateChanged( bool );
void valueChanged( qreal ); void valueChanged( qreal );
void originChanged( qreal ); void originChanged( qreal );
protected: protected:
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
void componentComplete() override; void componentComplete() override;
void itemChange( ItemChange, const ItemChangeData& ) override;
private: private:
void setValueInternal( qreal value ); void setValueInternal( qreal value );

View File

@ -8,12 +8,29 @@
#include "QskIntervalF.h" #include "QskIntervalF.h"
#include "QskBoxBorderMetrics.h" #include "QskBoxBorderMetrics.h"
#include <qeasingcurve.h>
#include <cmath> #include <cmath>
static inline QskIntervalF qskBarInterval( const QskProgressBar* bar ) static inline QskIntervalF qskBarInterval( const QskProgressBar* bar )
{ {
auto pos1 = bar->valueAsRatio( bar->origin() ); qreal pos1, pos2;
auto pos2 = bar->valueAsRatio( bar->value() );
if ( bar->isIndeterminate() )
{
const auto pos = bar->metric( QskProgressBar::Bar | QskAspect::Position );
static const QEasingCurve curve( QEasingCurve::InOutCubic );
const qreal off = 0.15;
pos1 = curve.valueForProgress( qMax( pos - off, 0.0 ) );
pos2 = curve.valueForProgress( qMin( pos + off, 1.0 ) );
}
else
{
pos1 = bar->valueAsRatio( bar->origin() );
pos2 = bar->valueAsRatio( bar->value() );
}
if( bar->orientation() == Qt::Horizontal ) if( bar->orientation() == Qt::Horizontal )
{ {