Iot dashboard: Make circular progress bar a QskControl (#124)
* IOT example, circular progress bar: Use a pen instead of a brush That way we don't have to draw two circles, and we can in addition use a conical gradient. * IOT example: Make circular progress bar a QskControl ... and internally use a QskPaintedNode for now. By doing this we already have the API ready (similar to QskProgressBar) and can swap the QskPaintedNode with an arc renderer at a later point in time.
This commit is contained in:
parent
279ec9537c
commit
3a1a7c635c
@ -5,107 +5,190 @@
|
||||
|
||||
#include "CircularProgressBar.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QskAnimator.h>
|
||||
#include <QskFunctions.h>
|
||||
|
||||
CircularProgressBar::CircularProgressBar( const QskGradient& gradient, int progress, QQuickItem* parent )
|
||||
: QQuickPaintedItem( parent )
|
||||
, m_progress( progress )
|
||||
QSK_SUBCONTROL( CircularProgressBar, Groove )
|
||||
QSK_SUBCONTROL( CircularProgressBar, Bar )
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is a bit hackish, but let's do this properly
|
||||
// once QSkinny has an arc renderer in place
|
||||
QLinearGradient g( 0, 0, 30, 0 );
|
||||
QGradientStop stop1( 0.0, gradient.colorAt( 0 ) );
|
||||
QGradientStop stop2( 1.0, gradient.colorAt( 1 ) );
|
||||
g.setStops( {stop1, stop2} );
|
||||
m_gradient = g;
|
||||
|
||||
connect( this, &QQuickPaintedItem::contentsSizeChanged, [this]()
|
||||
class PositionAnimator : public QskAnimator
|
||||
{
|
||||
auto size = contentsSize();
|
||||
QRadialGradient ringGradient( size.width() / 2, size.height() / 2, 45 );
|
||||
QGradientStop stop1( 0.0, "#c0c0c0" );
|
||||
QGradientStop stop2( 0.5, "#f0f0f0" );
|
||||
QGradientStop stop3( 1.0, "#c0c0c0" );
|
||||
ringGradient.setStops( {stop1, stop2, stop3} );
|
||||
public:
|
||||
PositionAnimator( CircularProgressBar* progressBar )
|
||||
: m_progressBar( progressBar )
|
||||
{
|
||||
setAutoRepeat( true );
|
||||
setDuration( 1300 );
|
||||
|
||||
m_ringGradient = ringGradient;
|
||||
} );
|
||||
setWindow( progressBar->window() );
|
||||
}
|
||||
|
||||
void advance( qreal value ) override
|
||||
{
|
||||
const auto aspect = CircularProgressBar::Bar | QskAspect::Position;
|
||||
|
||||
m_progressBar->setMetric( aspect, value );
|
||||
m_progressBar->update();
|
||||
}
|
||||
|
||||
private:
|
||||
CircularProgressBar* m_progressBar;
|
||||
};
|
||||
}
|
||||
|
||||
double CircularProgressBar::width() const
|
||||
class CircularProgressBar::PrivateData
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
public:
|
||||
void updateIndeterminateAnimator( CircularProgressBar* progressBar )
|
||||
{
|
||||
if ( !isIndeterminate )
|
||||
{
|
||||
delete animator;
|
||||
animator = nullptr;
|
||||
|
||||
void CircularProgressBar::setWidth( double width )
|
||||
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;
|
||||
|
||||
bool hasOrigin = false;
|
||||
bool isIndeterminate = false;
|
||||
};
|
||||
|
||||
CircularProgressBar::CircularProgressBar( qreal min, qreal max, QQuickItem* parent )
|
||||
: QskBoundedControl( min, max, parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
m_width = width;
|
||||
m_data->value = minimum();
|
||||
|
||||
initSizePolicy( QskSizePolicy::MinimumExpanding, QskSizePolicy::MinimumExpanding );
|
||||
|
||||
connect( this, &QskBoundedControl::boundariesChanged,
|
||||
this, &CircularProgressBar::adjustValue );
|
||||
}
|
||||
|
||||
QColor CircularProgressBar::backgroundColor() const
|
||||
CircularProgressBar::CircularProgressBar( QQuickItem* parent )
|
||||
: CircularProgressBar( 0.0, 100.0, parent )
|
||||
{
|
||||
return m_backgroundColor;
|
||||
}
|
||||
|
||||
void CircularProgressBar::setBackgroundColor( const QColor& color )
|
||||
bool CircularProgressBar::isIndeterminate() const
|
||||
{
|
||||
m_backgroundColor = color;
|
||||
return m_data->isIndeterminate;
|
||||
}
|
||||
|
||||
QRadialGradient CircularProgressBar::ringGradient() const
|
||||
void CircularProgressBar::setIndeterminate( bool on )
|
||||
{
|
||||
return m_ringGradient;
|
||||
if ( on == m_data->isIndeterminate )
|
||||
return;
|
||||
|
||||
m_data->isIndeterminate = on;
|
||||
m_data->updateIndeterminateAnimator( this );
|
||||
|
||||
update();
|
||||
Q_EMIT indeterminateChanged( on );
|
||||
}
|
||||
|
||||
void CircularProgressBar::setRingGradient( const QRadialGradient& gradient )
|
||||
void CircularProgressBar::resetOrigin()
|
||||
{
|
||||
m_ringGradient = gradient;
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
m_data->hasOrigin = false;
|
||||
|
||||
update();
|
||||
Q_EMIT originChanged( origin() );
|
||||
}
|
||||
}
|
||||
|
||||
void CircularProgressBar::paint( QPainter* painter )
|
||||
qreal CircularProgressBar::origin() const
|
||||
{
|
||||
const auto size = contentsSize();
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
return boundedValue( m_data->origin );
|
||||
}
|
||||
|
||||
const int startAngle = 1440;
|
||||
const int endAngle = -16 * ( m_progress / 100.0 ) * 360;
|
||||
|
||||
painter->setRenderHint( QPainter::Antialiasing, true );
|
||||
|
||||
#if 1
|
||||
QRectF outerRect( {0, 0}, size );
|
||||
|
||||
painter->setBrush( m_ringGradient );
|
||||
painter->setPen( m_backgroundColor );
|
||||
painter->drawEllipse( outerRect );
|
||||
|
||||
painter->setBrush( m_gradient );
|
||||
painter->drawPie( outerRect, startAngle, endAngle );
|
||||
|
||||
painter->setBrush( m_backgroundColor );
|
||||
painter->setPen( m_backgroundColor );
|
||||
QRectF innerRect( width() / 2, width() / 2, size.width() - width(), size.height() - width() );
|
||||
painter->drawEllipse( innerRect );
|
||||
#else
|
||||
const qreal w = 10;
|
||||
|
||||
const QRectF r( 0.5 * w, 0.5 * w, size.width() - w, size.height() - w );
|
||||
|
||||
const QColor c0 ( Qt::lightGray );
|
||||
|
||||
QRadialGradient g1( r.center(), qMin( r.width(), r.height() ) );
|
||||
g1.setColorAt( 0.0, c0 );
|
||||
g1.setColorAt( 0.5, c0.lighter( 120 ) );
|
||||
g1.setColorAt( 1.0, c0 );
|
||||
|
||||
painter->setPen( QPen( g1, w, Qt::SolidLine, Qt::FlatCap ) );
|
||||
painter->drawArc( r, startAngle, 16 * 360 );
|
||||
|
||||
QConicalGradient g2( r.center(), 0 );
|
||||
g2.setColorAt( 0.0, Qt::red );
|
||||
g2.setColorAt( 0.5, Qt::blue );
|
||||
g2.setColorAt( 1.0, Qt::red );
|
||||
|
||||
painter->setPen( QPen( g2, w, Qt::SolidLine, Qt::FlatCap ) );
|
||||
painter->drawArc( r, startAngle, endAngle );
|
||||
#endif
|
||||
return minimum();
|
||||
}
|
||||
|
||||
qreal CircularProgressBar::value() const
|
||||
{
|
||||
return m_data->value;
|
||||
}
|
||||
|
||||
qreal CircularProgressBar::valueAsRatio() const
|
||||
{
|
||||
return QskBoundedControl::valueAsRatio( m_data->value );
|
||||
}
|
||||
|
||||
void CircularProgressBar::setValue( qreal value )
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
value = boundedValue( value );
|
||||
|
||||
setValueInternal( value );
|
||||
}
|
||||
|
||||
void CircularProgressBar::setValueAsRatio( qreal ratio )
|
||||
{
|
||||
ratio = qBound( 0.0, ratio, 1.0 );
|
||||
setValue( minimum() + ratio * boundaryLength() );
|
||||
}
|
||||
|
||||
void CircularProgressBar::setOrigin( qreal origin )
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
origin = boundedValue( origin );
|
||||
|
||||
if( !m_data->hasOrigin || !qskFuzzyCompare( m_data->origin, origin ) )
|
||||
{
|
||||
m_data->hasOrigin = true;
|
||||
m_data->origin = origin;
|
||||
|
||||
update();
|
||||
Q_EMIT originChanged( origin );
|
||||
}
|
||||
}
|
||||
|
||||
void CircularProgressBar::componentComplete()
|
||||
{
|
||||
Inherited::componentComplete();
|
||||
adjustValue();
|
||||
}
|
||||
|
||||
void CircularProgressBar::setValueInternal( qreal value )
|
||||
{
|
||||
if ( !qskFuzzyCompare( value, m_data->value ) )
|
||||
{
|
||||
m_data->value = value;
|
||||
Q_EMIT valueChanged( value );
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void CircularProgressBar::adjustValue()
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
setValueInternal( boundedValue( m_data->value ) );
|
||||
}
|
||||
|
||||
#include "moc_CircularProgressBar.cpp"
|
||||
|
@ -5,31 +5,59 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskBoundedControl.h>
|
||||
#include <QskGradient.h>
|
||||
|
||||
#include <QGradient>
|
||||
#include <QQuickPaintedItem>
|
||||
|
||||
class CircularProgressBar : public QQuickPaintedItem
|
||||
class CircularProgressBar : public QskBoundedControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( bool indeterminate READ isIndeterminate
|
||||
WRITE setIndeterminate NOTIFY indeterminateChanged )
|
||||
|
||||
Q_PROPERTY( qreal origin READ origin
|
||||
WRITE setOrigin RESET resetOrigin NOTIFY originChanged )
|
||||
|
||||
Q_PROPERTY( qreal value READ value WRITE setValue NOTIFY valueChanged )
|
||||
Q_PROPERTY( qreal valueAsRatio READ valueAsRatio
|
||||
WRITE setValueAsRatio NOTIFY valueChanged )
|
||||
|
||||
using Inherited = QskBoundedControl;
|
||||
|
||||
public:
|
||||
CircularProgressBar( const QskGradient&, int progress, QQuickItem* parent = nullptr );
|
||||
QSK_SUBCONTROLS( Groove, Bar )
|
||||
|
||||
virtual void paint( QPainter* painter ) override;
|
||||
CircularProgressBar( qreal min, qreal max, QQuickItem* parent = nullptr );
|
||||
CircularProgressBar( QQuickItem* parent = nullptr );
|
||||
|
||||
double width() const;
|
||||
void setWidth( double width );
|
||||
bool isIndeterminate() const;
|
||||
void setIndeterminate( bool on = true );
|
||||
|
||||
QColor backgroundColor() const;
|
||||
void setBackgroundColor( const QColor& );
|
||||
void resetOrigin();
|
||||
qreal origin() const;
|
||||
|
||||
QRadialGradient ringGradient() const;
|
||||
void setRingGradient( const QRadialGradient& );
|
||||
qreal value() const;
|
||||
qreal valueAsRatio() const; // [0.0, 1.0]
|
||||
|
||||
public Q_SLOTS:
|
||||
void setValue( qreal );
|
||||
void setValueAsRatio( qreal );
|
||||
void setOrigin( qreal );
|
||||
|
||||
Q_SIGNALS:
|
||||
void indeterminateChanged( bool );
|
||||
void valueChanged( qreal );
|
||||
void originChanged( qreal );
|
||||
|
||||
protected:
|
||||
void componentComplete() override;
|
||||
|
||||
private:
|
||||
QGradient m_gradient;
|
||||
QColor m_backgroundColor;
|
||||
QRadialGradient m_ringGradient;
|
||||
double m_width = 20;
|
||||
int m_progress;
|
||||
void setValueInternal( qreal value );
|
||||
void adjustValue();
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
220
examples/iotdashboard/CircularProgressBarSkinlet.cpp
Normal file
220
examples/iotdashboard/CircularProgressBarSkinlet.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2021 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#include "CircularProgressBarSkinlet.h"
|
||||
#include "CircularProgressBar.h"
|
||||
|
||||
#include <QskPaintedNode.h>
|
||||
|
||||
#include <QEasingCurve>
|
||||
#include <QPainter>
|
||||
|
||||
namespace {
|
||||
class ArcNode : public QskPaintedNode
|
||||
{
|
||||
public:
|
||||
ArcNode() : QskPaintedNode()
|
||||
{
|
||||
}
|
||||
|
||||
void setGradient( const QskGradient& gradient )
|
||||
{
|
||||
m_gradient = gradient;
|
||||
}
|
||||
|
||||
void setGradientType( QGradient::Type type )
|
||||
{
|
||||
m_gradientType = type;
|
||||
}
|
||||
|
||||
void setWidth( double width )
|
||||
{
|
||||
m_width = width;
|
||||
}
|
||||
|
||||
void setValue( double value )
|
||||
{
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
void setOrigin( double origin )
|
||||
{
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
void setMaximum( double maximum )
|
||||
{
|
||||
m_maximum = maximum;
|
||||
}
|
||||
|
||||
void setIndeterminate( bool isIndeterminate )
|
||||
{
|
||||
m_isIndeterminate = isIndeterminate;
|
||||
}
|
||||
|
||||
void setPosition( double position )
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
virtual void paint( QPainter* painter, const QSizeF& size ) override
|
||||
{
|
||||
int startAngle;
|
||||
int spanAngle;
|
||||
|
||||
if( m_isIndeterminate )
|
||||
{
|
||||
static const QEasingCurve curve( QEasingCurve::Linear );
|
||||
|
||||
startAngle = -1 * m_position * 360;
|
||||
// the other option is to just set a fixed value for the
|
||||
// span angle (or do some advanced stuff with easing curves)
|
||||
spanAngle = qAbs( 0.5 - m_position ) * 360;
|
||||
}
|
||||
else
|
||||
{
|
||||
startAngle = 90 + -1 * ( m_origin / m_maximum ) * 360;
|
||||
spanAngle = -1 * ( m_value / m_maximum ) * 360;
|
||||
}
|
||||
|
||||
painter->setRenderHint( QPainter::Antialiasing, true );
|
||||
|
||||
const QRectF r( 0.5 * m_width, 0.5 * m_width, size.width() - m_width, size.height() - m_width );
|
||||
|
||||
QGradientStops stops;
|
||||
|
||||
for( const QskGradientStop& stop : m_gradient.stops() )
|
||||
{
|
||||
QGradientStop s( stop.position(), stop.color() );
|
||||
stops.append( s );
|
||||
}
|
||||
|
||||
if( m_gradientType == QGradient::RadialGradient )
|
||||
{
|
||||
QRadialGradient radialGradient( r.center(), qMin( r.width(), r.height() ) );
|
||||
radialGradient.setStops( stops );
|
||||
|
||||
painter->setPen( QPen( radialGradient, m_width, Qt::SolidLine, Qt::FlatCap ) );
|
||||
painter->drawArc( r, startAngle * 16, spanAngle * 16 );
|
||||
}
|
||||
else
|
||||
{
|
||||
QConicalGradient conicalGradient( r.center(), startAngle );
|
||||
conicalGradient.setStops( stops );
|
||||
|
||||
painter->setPen( QPen( conicalGradient, m_width, Qt::SolidLine, Qt::FlatCap ) );
|
||||
painter->drawArc( r, startAngle * 16, spanAngle * 16 );
|
||||
}
|
||||
}
|
||||
|
||||
virtual uint hash() const override
|
||||
{
|
||||
uint h = qHash( m_gradientType );
|
||||
h = qHash( m_width, h );
|
||||
h = qHash( m_value, h );
|
||||
h = qHash( m_origin, h );
|
||||
h = qHash( m_maximum, h );
|
||||
h = qHash( m_isIndeterminate, h );
|
||||
h = qHash( m_position, h );
|
||||
|
||||
for( const QskGradientStop& stop : m_gradient.stops() )
|
||||
{
|
||||
h = stop.hash( h );
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
private:
|
||||
QskGradient m_gradient;
|
||||
QGradient::Type m_gradientType;
|
||||
double m_width;
|
||||
double m_value;
|
||||
double m_origin;
|
||||
double m_maximum;
|
||||
bool m_isIndeterminate;
|
||||
double m_position;
|
||||
};
|
||||
}
|
||||
|
||||
CircularProgressBarSkinlet::CircularProgressBarSkinlet( QskSkin* skin )
|
||||
: QskSkinlet( skin )
|
||||
{
|
||||
setNodeRoles( { GrooveRole, BarRole } );
|
||||
}
|
||||
|
||||
CircularProgressBarSkinlet::~CircularProgressBarSkinlet()
|
||||
{
|
||||
}
|
||||
|
||||
QRectF CircularProgressBarSkinlet::subControlRect(
|
||||
const QskSkinnable* /*skinnable*/, const QRectF& contentsRect,
|
||||
QskAspect::Subcontrol /*subControl*/ ) const
|
||||
{
|
||||
return contentsRect;
|
||||
}
|
||||
|
||||
QSGNode* CircularProgressBarSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
const auto bar = static_cast< const CircularProgressBar* >( skinnable );
|
||||
|
||||
switch( nodeRole )
|
||||
{
|
||||
case GrooveRole: // fall through
|
||||
case BarRole:
|
||||
{
|
||||
return updateBarNode( bar, nodeRole, node );
|
||||
}
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QSGNode* CircularProgressBarSkinlet::updateBarNode( const CircularProgressBar* bar, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
auto arcNode = static_cast< ArcNode* >( node );
|
||||
|
||||
if( arcNode == nullptr )
|
||||
{
|
||||
arcNode = new ArcNode();
|
||||
}
|
||||
|
||||
const auto subControl = ( nodeRole == GrooveRole ) ? CircularProgressBar::Groove
|
||||
: CircularProgressBar::Bar;
|
||||
|
||||
const QskGradient gradient = bar->gradientHint( subControl );
|
||||
|
||||
const QGradient::Type type = ( nodeRole == GrooveRole ) ?
|
||||
QGradient::RadialGradient : QGradient::ConicalGradient;
|
||||
|
||||
const double width = bar->metric( subControl | QskAspect::Size );
|
||||
const double value = ( nodeRole == GrooveRole ) ? bar->maximum() : bar->value();
|
||||
|
||||
arcNode->setGradient( gradient );
|
||||
arcNode->setGradientType( type );
|
||||
arcNode->setWidth( width );
|
||||
arcNode->setOrigin( bar->origin() );
|
||||
arcNode->setMaximum( bar->maximum() );
|
||||
arcNode->setIndeterminate( bar->isIndeterminate() );
|
||||
|
||||
if( bar->isIndeterminate() )
|
||||
{
|
||||
const double position = bar->metric( CircularProgressBar::Bar | QskAspect::Position );
|
||||
arcNode->setPosition( position );
|
||||
}
|
||||
else
|
||||
{
|
||||
arcNode->setValue( value );
|
||||
}
|
||||
|
||||
QQuickWindow* window = bar->window();
|
||||
const QRect rect = bar->contentsRect().toRect();
|
||||
arcNode->update( window, QskTextureRenderer::AutoDetect, rect );
|
||||
|
||||
return arcNode;
|
||||
}
|
||||
|
||||
#include "moc_CircularProgressBarSkinlet.cpp"
|
39
examples/iotdashboard/CircularProgressBarSkinlet.h
Normal file
39
examples/iotdashboard/CircularProgressBarSkinlet.h
Normal file
@ -0,0 +1,39 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2021 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskSkinlet.h>
|
||||
|
||||
class CircularProgressBar;
|
||||
|
||||
class CircularProgressBarSkinlet : public QskSkinlet
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
using Inherited = QskSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole
|
||||
{
|
||||
GrooveRole,
|
||||
BarRole,
|
||||
|
||||
RoleCount,
|
||||
};
|
||||
|
||||
Q_INVOKABLE CircularProgressBarSkinlet( QskSkin* = nullptr );
|
||||
~CircularProgressBarSkinlet() override;
|
||||
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||
|
||||
protected:
|
||||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
|
||||
private:
|
||||
QSGNode* updateBarNode( const CircularProgressBar*, quint8 nodeRole, QSGNode* ) const;
|
||||
};
|
@ -47,7 +47,6 @@ class ProgressBarAnimator : public QskAnimator
|
||||
void setup() override
|
||||
{
|
||||
m_backgroundColor = m_pieChart->color( PieChartPainted::Panel );
|
||||
m_ringGradient = m_progressBar->ringGradient();
|
||||
}
|
||||
|
||||
void advance( qreal value ) override
|
||||
@ -68,7 +67,6 @@ class ProgressBarAnimator : public QskAnimator
|
||||
newGradient.setColorAt( stop.first, newColor );
|
||||
}
|
||||
|
||||
m_progressBar->setRingGradient( newGradient );
|
||||
m_progressBar->update();
|
||||
}
|
||||
|
||||
@ -83,13 +81,16 @@ PieChartPainted::PieChartPainted( const QColor& color, const QskGradient& gradie
|
||||
: QskControl( parent )
|
||||
, m_color( color )
|
||||
, m_gradient( gradient )
|
||||
, m_progressBar( new CircularProgressBar( gradient, progress, this ) )
|
||||
, m_progressBar( new CircularProgressBar( this ) )
|
||||
, m_progressLabel( new QskTextLabel( this ) )
|
||||
, m_animator( new ProgressBarAnimator( this, m_progressBar ) )
|
||||
{
|
||||
setAutoLayoutChildren( true );
|
||||
setSubcontrolProxy( QskBox::Panel, PieChartPainted::Panel );
|
||||
|
||||
m_progressBar->setGradientHint( CircularProgressBar::Bar, gradient );
|
||||
m_progressBar->setValue( progress );
|
||||
|
||||
auto progressText = QString::number( progress ) + " %";
|
||||
m_progressLabel->setText( progressText );
|
||||
m_progressLabel->setFontRole( QskSkin::SmallFont );
|
||||
@ -109,7 +110,6 @@ QSizeF PieChartPainted::contentsSizeHint( Qt::SizeHint /*sizeHint*/, const QSize
|
||||
|
||||
void PieChartPainted::updateLayout()
|
||||
{
|
||||
m_progressBar->setContentsSize( size().toSize() );
|
||||
m_progressBar->update();
|
||||
|
||||
const auto rect = layoutRect();
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include "Box.h"
|
||||
#include "BoxWithButtons.h"
|
||||
#include "CircularProgressBar.h"
|
||||
#include "CircularProgressBarSkinlet.h"
|
||||
#include "Diagram.h"
|
||||
#include "DiagramSkinlet.h"
|
||||
#include "LightIntensity.h"
|
||||
@ -48,6 +50,7 @@ namespace
|
||||
Skin::Skin( const Palette& palette, QObject* parent )
|
||||
: QskSkin( parent )
|
||||
{
|
||||
declareSkinlet< CircularProgressBar, CircularProgressBarSkinlet >();
|
||||
declareSkinlet< Diagram, DiagramSkinlet >();
|
||||
|
||||
initHints( palette );
|
||||
@ -104,10 +107,15 @@ void Skin::initHints( const Palette& palette )
|
||||
ed.setColor( TopBarItem::Item3 | QskAspect::TextColor, "#f99055" );
|
||||
ed.setColor( TopBarItem::Item4 | QskAspect::TextColor, "#6776ff" );
|
||||
|
||||
ed.setGradient( TopBarItem::Item1, { Qt::Horizontal, "#FF5C00", "#FF3122" } );
|
||||
ed.setGradient( TopBarItem::Item2, { Qt::Horizontal, "#6776FF", "#6100FF" } );
|
||||
ed.setGradient( TopBarItem::Item3, { Qt::Horizontal, "#FFCE50", "#FF3122" } );
|
||||
ed.setGradient( TopBarItem::Item4, { Qt::Horizontal, "#6776FF", "#6100FF" } );
|
||||
// conical gradients are counterclockwise, so specify the 2nd color first:
|
||||
ed.setGradient( TopBarItem::Item1, { Qt::Horizontal, "#FF3122", "#FF5C00" } );
|
||||
ed.setGradient( TopBarItem::Item2, { Qt::Horizontal, "#6100FF", "#6776FF" } );
|
||||
ed.setGradient( TopBarItem::Item3, { Qt::Horizontal, "#FF3122", "#FFCE50" } );
|
||||
ed.setGradient( TopBarItem::Item4, { Qt::Horizontal, "#6100FF", "#6776FF" } );
|
||||
|
||||
// the bar gradient is defined through the top bar items above
|
||||
ed.setMetricHint( CircularProgressBar::Groove | QskAspect::Size, 8.53 );
|
||||
ed.setMetricHint( CircularProgressBar::Bar | QskAspect::Size, 8.53 );
|
||||
|
||||
ed.setFontRole( TimeTitleLabel::Text, Skin::TitleFont );
|
||||
|
||||
@ -180,4 +188,5 @@ void Skin::initHints( const Palette& palette )
|
||||
ed.setColor( QskTextLabel::Text, palette.text );
|
||||
ed.setColor( UsageDiagramBox::DayText, palette.text );
|
||||
ed.setColor( ShadowPositioner::Panel, palette.shadow );
|
||||
ed.setGradient( CircularProgressBar::Groove, palette.circularProgressBarGroove );
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ class Skin : public QskSkin
|
||||
Palette( const QskGradient& menuBar, const QskGradient& mainContent,
|
||||
const QskGradient& box, const QColor& lightDisplay, const QColor& pieChart,
|
||||
const QskGradient& roundButton, const QColor& weekdayBox,
|
||||
const QColor& text, const QColor& shadow )
|
||||
const QColor& text, const QColor& shadow,
|
||||
const QskGradient& circularProgressBarGroove )
|
||||
: menuBar( menuBar )
|
||||
, mainContent( mainContent )
|
||||
, box( box )
|
||||
@ -27,6 +28,7 @@ class Skin : public QskSkin
|
||||
, weekdayBox( weekdayBox )
|
||||
, text( text )
|
||||
, shadow( shadow )
|
||||
, circularProgressBarGroove( circularProgressBarGroove )
|
||||
{
|
||||
}
|
||||
QskGradient menuBar;
|
||||
@ -38,6 +40,7 @@ class Skin : public QskSkin
|
||||
QColor weekdayBox;
|
||||
QColor text;
|
||||
QColor shadow;
|
||||
QskGradient circularProgressBarGroove;
|
||||
};
|
||||
|
||||
Skin( const Palette& palette, QObject* parent = nullptr );
|
||||
@ -59,7 +62,8 @@ class DaytimeSkin : public Skin
|
||||
: Skin(
|
||||
Skin::Palette( {"#6D7BFB"}, {"#fbfbfb"}, {"#ffffff"},
|
||||
"#ffffff", "#ffffff", {"#f7f7f7"},
|
||||
{"#f4f4f4"}, Qt::black, Qt::black )
|
||||
{"#f4f4f4"}, Qt::black, Qt::black,
|
||||
{ Qt::Horizontal, { { 0.0, 0xc4c4c4 }, { 0.5, 0xf8f8f8 }, { 1.0, 0xc4c4c4 } } } )
|
||||
, parent )
|
||||
{
|
||||
}
|
||||
@ -72,7 +76,8 @@ class NighttimeSkin : public Skin
|
||||
: Skin(
|
||||
Skin::Palette( {"#2937A7"}, {"#040404"}, {"#000000"},
|
||||
"#000000", "#000000", {"#0a0a0a"},
|
||||
{"#0c0c0c"}, Qt::white, Qt::white )
|
||||
{"#0c0c0c"}, Qt::white, Qt::white,
|
||||
{ Qt::Horizontal, { { 0.0, 0x666666 }, { 0.5, 0x222222 }, { 1.0, 0x333333 } } } )
|
||||
, parent )
|
||||
{
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ SOURCES += \
|
||||
Box.cpp \
|
||||
BoxWithButtons.cpp \
|
||||
CircularProgressBar.cpp \
|
||||
CircularProgressBarSkinlet.cpp \
|
||||
Diagram.cpp \
|
||||
DiagramSkinlet.cpp \
|
||||
LightIntensity.cpp \
|
||||
@ -30,6 +31,7 @@ HEADERS += \
|
||||
Box.h \
|
||||
BoxWithButtons.h \
|
||||
CircularProgressBar.h \
|
||||
CircularProgressBarSkinlet.h \
|
||||
Diagram.h \
|
||||
DiagramSkinlet.h \
|
||||
LightIntensity.h \
|
||||
|
Loading…
x
Reference in New Issue
Block a user