Add repaint optimization to TQProgressBar

This optimization makes TQProgressBar::setProgress() only repaint itself
if stepping to the new progress would cause a graphical change. This means
that for a width W and a total number of steps S, it will repaint itself
'W' times (every 'S/W' steps) instead of 'S' times (every step) as it is
right now.
pull/2/head
Frerich Raabe 11 years ago committed by Slávek Banko
parent b716176cec
commit 9f882f9de7

@ -51,6 +51,14 @@
#endif #endif
#include <limits.h> #include <limits.h>
class QProgressBarPrivate
{
public:
QProgressBarPrivate() : last_painted_progress( 0 ) { }
int last_painted_progress;
};
/*! /*!
\class QProgressBar qprogressbar.h \class QProgressBar qprogressbar.h
\brief The QProgressBar widget provides a horizontal progress bar. \brief The QProgressBar widget provides a horizontal progress bar.
@ -103,7 +111,7 @@ QProgressBar::QProgressBar( QWidget *parent, const char *name, WFlags f )
center_indicator( TRUE ), center_indicator( TRUE ),
auto_indicator( TRUE ), auto_indicator( TRUE ),
percentage_visible( TRUE ), percentage_visible( TRUE ),
d( 0 ), d( new QProgressBarPrivate ),
m_orientation( Horizontal ) m_orientation( Horizontal )
{ {
setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
@ -135,7 +143,7 @@ QProgressBar::QProgressBar( int totalSteps,
center_indicator( TRUE ), center_indicator( TRUE ),
auto_indicator( TRUE ), auto_indicator( TRUE ),
percentage_visible( TRUE ), percentage_visible( TRUE ),
d( 0 ), d( new QProgressBarPrivate ),
m_orientation( Horizontal ) m_orientation( Horizontal )
{ {
setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
@ -143,6 +151,16 @@ QProgressBar::QProgressBar( int totalSteps,
} }
/*!
Destroys the object and frees any allocated ressources.
*/
QProgressBar::~QProgressBar()
{
delete d;
}
/*! /*!
Reset the progress bar. The progress bar "rewinds" and shows no Reset the progress bar. The progress bar "rewinds" and shows no
progress. progress.
@ -194,11 +212,16 @@ void QProgressBar::setProgress( int progress )
progress < 0 || ( ( progress > total_steps ) && total_steps ) ) progress < 0 || ( ( progress > total_steps ) && total_steps ) )
return; return;
const bool needRepaint = isVisible() && requireRepaint( progress );
progress_val = progress; progress_val = progress;
setIndicator( progress_str, progress_val, total_steps ); setIndicator( progress_str, progress_val, total_steps );
repaint( FALSE ); if ( needRepaint ) {
repaint( FALSE );
d->last_painted_progress = progress;
}
#if defined(QT_ACCESSIBILITY_SUPPORT) #if defined(QT_ACCESSIBILITY_SUPPORT)
QAccessible::updateAccessibility( this, 0, QAccessible::ValueChanged ); QAccessible::updateAccessibility( this, 0, QAccessible::ValueChanged );
@ -330,6 +353,32 @@ void QProgressBar::styleChange( QStyle& old )
QFrame::styleChange( old ); QFrame::styleChange( old );
} }
/*!
This method returns whether changing the progress to the \a newValue
would require a repaint of the progress bar. This allows efficient
repainting.
*/
bool QProgressBar::requireRepaint( int newProgress ) const
{
if ( newProgress == progress_val ||
newProgress == d->last_painted_progress ) {
return false;
}
const int width = contentsRect().width();
if ( width == 0 ) {
return false;
}
float progressPerPixel = 1.0;
if ( total_steps > width ) {
progressPerPixel = float( total_steps ) / float( width );
}
const int delta = d->last_painted_progress - newProgress;
return QABS( delta ) >= progressPerPixel;
}
Qt::Orientation QProgressBar::orientation() const Qt::Orientation QProgressBar::orientation() const
{ {
return m_orientation; return m_orientation;

@ -65,6 +65,7 @@ class Q_EXPORT QProgressBar : public QFrame
public: public:
QProgressBar( QWidget* parent=0, const char* name=0, WFlags f=0 ); QProgressBar( QWidget* parent=0, const char* name=0, WFlags f=0 );
QProgressBar( int totalSteps, QWidget* parent=0, const char* name=0, WFlags f=0 ); QProgressBar( int totalSteps, QWidget* parent=0, const char* name=0, WFlags f=0 );
virtual ~QProgressBar();
int totalSteps() const; int totalSteps() const;
int progress() const; int progress() const;
@ -95,6 +96,7 @@ protected:
virtual bool setIndicator( QString & progress_str, int progress, virtual bool setIndicator( QString & progress_str, int progress,
int totalSteps ); int totalSteps );
void styleChange( QStyle& ); void styleChange( QStyle& );
bool requireRepaint( int newProgress ) const;
private: private:
int total_steps; int total_steps;

Loading…
Cancel
Save