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:
Peter Hartmann 2021-08-24 08:46:26 +02:00 committed by GitHub
parent 279ec9537c
commit 3a1a7c635c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 490 additions and 104 deletions

View File

@ -5,107 +5,190 @@
#include "CircularProgressBar.h" #include "CircularProgressBar.h"
#include <QPainter> #include <QskAnimator.h>
#include <QskFunctions.h>
CircularProgressBar::CircularProgressBar( const QskGradient& gradient, int progress, QQuickItem* parent ) QSK_SUBCONTROL( CircularProgressBar, Groove )
: QQuickPaintedItem( parent ) QSK_SUBCONTROL( CircularProgressBar, Bar )
, m_progress( progress )
namespace
{ {
// This is a bit hackish, but let's do this properly class PositionAnimator : public QskAnimator
// 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]()
{ {
auto size = contentsSize(); public:
QRadialGradient ringGradient( size.width() / 2, size.height() / 2, 45 ); PositionAnimator( CircularProgressBar* progressBar )
QGradientStop stop1( 0.0, "#c0c0c0" ); : m_progressBar( progressBar )
QGradientStop stop2( 0.5, "#f0f0f0" ); {
QGradientStop stop3( 1.0, "#c0c0c0" ); setAutoRepeat( true );
ringGradient.setStops( {stop1, stop2, stop3} ); 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; return minimum();
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
} }
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"

View File

@ -5,31 +5,59 @@
#pragma once #pragma once
#include <QskBoundedControl.h>
#include <QskGradient.h> #include <QskGradient.h>
#include <QGradient> #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: 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; bool isIndeterminate() const;
void setWidth( double width ); void setIndeterminate( bool on = true );
QColor backgroundColor() const; void resetOrigin();
void setBackgroundColor( const QColor& ); qreal origin() const;
QRadialGradient ringGradient() const; qreal value() const;
void setRingGradient( const QRadialGradient& ); 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: private:
QGradient m_gradient; void setValueInternal( qreal value );
QColor m_backgroundColor; void adjustValue();
QRadialGradient m_ringGradient;
double m_width = 20; class PrivateData;
int m_progress; std::unique_ptr< PrivateData > m_data;
}; };

View 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"

View 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;
};

View File

@ -47,7 +47,6 @@ class ProgressBarAnimator : public QskAnimator
void setup() override void setup() override
{ {
m_backgroundColor = m_pieChart->color( PieChartPainted::Panel ); m_backgroundColor = m_pieChart->color( PieChartPainted::Panel );
m_ringGradient = m_progressBar->ringGradient();
} }
void advance( qreal value ) override void advance( qreal value ) override
@ -68,7 +67,6 @@ class ProgressBarAnimator : public QskAnimator
newGradient.setColorAt( stop.first, newColor ); newGradient.setColorAt( stop.first, newColor );
} }
m_progressBar->setRingGradient( newGradient );
m_progressBar->update(); m_progressBar->update();
} }
@ -83,13 +81,16 @@ PieChartPainted::PieChartPainted( const QColor& color, const QskGradient& gradie
: QskControl( parent ) : QskControl( parent )
, m_color( color ) , m_color( color )
, m_gradient( gradient ) , m_gradient( gradient )
, m_progressBar( new CircularProgressBar( gradient, progress, this ) ) , m_progressBar( new CircularProgressBar( this ) )
, m_progressLabel( new QskTextLabel( this ) ) , m_progressLabel( new QskTextLabel( this ) )
, m_animator( new ProgressBarAnimator( this, m_progressBar ) ) , m_animator( new ProgressBarAnimator( this, m_progressBar ) )
{ {
setAutoLayoutChildren( true ); setAutoLayoutChildren( true );
setSubcontrolProxy( QskBox::Panel, PieChartPainted::Panel ); setSubcontrolProxy( QskBox::Panel, PieChartPainted::Panel );
m_progressBar->setGradientHint( CircularProgressBar::Bar, gradient );
m_progressBar->setValue( progress );
auto progressText = QString::number( progress ) + " %"; auto progressText = QString::number( progress ) + " %";
m_progressLabel->setText( progressText ); m_progressLabel->setText( progressText );
m_progressLabel->setFontRole( QskSkin::SmallFont ); m_progressLabel->setFontRole( QskSkin::SmallFont );
@ -109,7 +110,6 @@ QSizeF PieChartPainted::contentsSizeHint( Qt::SizeHint /*sizeHint*/, const QSize
void PieChartPainted::updateLayout() void PieChartPainted::updateLayout()
{ {
m_progressBar->setContentsSize( size().toSize() );
m_progressBar->update(); m_progressBar->update();
const auto rect = layoutRect(); const auto rect = layoutRect();

View File

@ -7,6 +7,8 @@
#include "Box.h" #include "Box.h"
#include "BoxWithButtons.h" #include "BoxWithButtons.h"
#include "CircularProgressBar.h"
#include "CircularProgressBarSkinlet.h"
#include "Diagram.h" #include "Diagram.h"
#include "DiagramSkinlet.h" #include "DiagramSkinlet.h"
#include "LightIntensity.h" #include "LightIntensity.h"
@ -48,6 +50,7 @@ namespace
Skin::Skin( const Palette& palette, QObject* parent ) Skin::Skin( const Palette& palette, QObject* parent )
: QskSkin( parent ) : QskSkin( parent )
{ {
declareSkinlet< CircularProgressBar, CircularProgressBarSkinlet >();
declareSkinlet< Diagram, DiagramSkinlet >(); declareSkinlet< Diagram, DiagramSkinlet >();
initHints( palette ); initHints( palette );
@ -104,10 +107,15 @@ void Skin::initHints( const Palette& palette )
ed.setColor( TopBarItem::Item3 | QskAspect::TextColor, "#f99055" ); ed.setColor( TopBarItem::Item3 | QskAspect::TextColor, "#f99055" );
ed.setColor( TopBarItem::Item4 | QskAspect::TextColor, "#6776ff" ); ed.setColor( TopBarItem::Item4 | QskAspect::TextColor, "#6776ff" );
ed.setGradient( TopBarItem::Item1, { Qt::Horizontal, "#FF5C00", "#FF3122" } ); // conical gradients are counterclockwise, so specify the 2nd color first:
ed.setGradient( TopBarItem::Item2, { Qt::Horizontal, "#6776FF", "#6100FF" } ); ed.setGradient( TopBarItem::Item1, { Qt::Horizontal, "#FF3122", "#FF5C00" } );
ed.setGradient( TopBarItem::Item3, { Qt::Horizontal, "#FFCE50", "#FF3122" } ); ed.setGradient( TopBarItem::Item2, { Qt::Horizontal, "#6100FF", "#6776FF" } );
ed.setGradient( TopBarItem::Item4, { Qt::Horizontal, "#6776FF", "#6100FF" } ); 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 ); ed.setFontRole( TimeTitleLabel::Text, Skin::TitleFont );
@ -180,4 +188,5 @@ void Skin::initHints( const Palette& palette )
ed.setColor( QskTextLabel::Text, palette.text ); ed.setColor( QskTextLabel::Text, palette.text );
ed.setColor( UsageDiagramBox::DayText, palette.text ); ed.setColor( UsageDiagramBox::DayText, palette.text );
ed.setColor( ShadowPositioner::Panel, palette.shadow ); ed.setColor( ShadowPositioner::Panel, palette.shadow );
ed.setGradient( CircularProgressBar::Groove, palette.circularProgressBarGroove );
} }

View File

@ -17,7 +17,8 @@ class Skin : public QskSkin
Palette( const QskGradient& menuBar, const QskGradient& mainContent, Palette( const QskGradient& menuBar, const QskGradient& mainContent,
const QskGradient& box, const QColor& lightDisplay, const QColor& pieChart, const QskGradient& box, const QColor& lightDisplay, const QColor& pieChart,
const QskGradient& roundButton, const QColor& weekdayBox, const QskGradient& roundButton, const QColor& weekdayBox,
const QColor& text, const QColor& shadow ) const QColor& text, const QColor& shadow,
const QskGradient& circularProgressBarGroove )
: menuBar( menuBar ) : menuBar( menuBar )
, mainContent( mainContent ) , mainContent( mainContent )
, box( box ) , box( box )
@ -27,6 +28,7 @@ class Skin : public QskSkin
, weekdayBox( weekdayBox ) , weekdayBox( weekdayBox )
, text( text ) , text( text )
, shadow( shadow ) , shadow( shadow )
, circularProgressBarGroove( circularProgressBarGroove )
{ {
} }
QskGradient menuBar; QskGradient menuBar;
@ -38,6 +40,7 @@ class Skin : public QskSkin
QColor weekdayBox; QColor weekdayBox;
QColor text; QColor text;
QColor shadow; QColor shadow;
QskGradient circularProgressBarGroove;
}; };
Skin( const Palette& palette, QObject* parent = nullptr ); Skin( const Palette& palette, QObject* parent = nullptr );
@ -59,7 +62,8 @@ class DaytimeSkin : public Skin
: Skin( : Skin(
Skin::Palette( {"#6D7BFB"}, {"#fbfbfb"}, {"#ffffff"}, Skin::Palette( {"#6D7BFB"}, {"#fbfbfb"}, {"#ffffff"},
"#ffffff", "#ffffff", {"#f7f7f7"}, "#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 ) , parent )
{ {
} }
@ -72,7 +76,8 @@ class NighttimeSkin : public Skin
: Skin( : Skin(
Skin::Palette( {"#2937A7"}, {"#040404"}, {"#000000"}, Skin::Palette( {"#2937A7"}, {"#040404"}, {"#000000"},
"#000000", "#000000", {"#0a0a0a"}, "#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 ) , parent )
{ {
} }

View File

@ -4,6 +4,7 @@ SOURCES += \
Box.cpp \ Box.cpp \
BoxWithButtons.cpp \ BoxWithButtons.cpp \
CircularProgressBar.cpp \ CircularProgressBar.cpp \
CircularProgressBarSkinlet.cpp \
Diagram.cpp \ Diagram.cpp \
DiagramSkinlet.cpp \ DiagramSkinlet.cpp \
LightIntensity.cpp \ LightIntensity.cpp \
@ -30,6 +31,7 @@ HEADERS += \
Box.h \ Box.h \
BoxWithButtons.h \ BoxWithButtons.h \
CircularProgressBar.h \ CircularProgressBar.h \
CircularProgressBarSkinlet.h \
Diagram.h \ Diagram.h \
DiagramSkinlet.h \ DiagramSkinlet.h \
LightIntensity.h \ LightIntensity.h \