Merge branch 'master' into arcrenderer2
This commit is contained in:
commit
7f0e0126be
|
@ -159,6 +159,7 @@ void ProgressBarPage::populate()
|
|||
{
|
||||
auto* ring = new QskProgressRing( determinateRingsHBox );
|
||||
ring->setSize( size );
|
||||
ring->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||
|
||||
QQuickItem* parentItem;
|
||||
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
set(SOURCES
|
||||
Box.h Box.cpp
|
||||
BoxWithButtons.h BoxWithButtons.cpp
|
||||
CircularProgressBar.h CircularProgressBar.cpp
|
||||
CircularProgressBarSkinlet.h CircularProgressBarSkinlet.cpp
|
||||
Diagram.h Diagram.cpp
|
||||
DiagramSkinlet.h DiagramSkinlet.cpp
|
||||
EnergyMeter.h EnergyMeter.cpp
|
||||
GraphicProvider.h GraphicProvider.cpp
|
||||
GridBox.h GridBox.cpp
|
||||
LightDisplaySkinlet.h LightDisplaySkinlet.cpp
|
||||
|
@ -31,7 +28,7 @@ set(SOURCES
|
|||
UsageBox.h UsageBox.cpp
|
||||
UsageDiagram.h UsageDiagram.cpp
|
||||
StoragePage.h StoragePage.cpp
|
||||
StorageMeter.h StorageMeter.cpp
|
||||
ValueMeter.h ValueMeter.cpp
|
||||
StorageBar.h StorageBar.cpp
|
||||
StorageBarSkinlet.h StorageBarSkinlet.cpp
|
||||
nodes/DiagramDataNode.h nodes/DiagramDataNode.cpp
|
||||
|
|
|
@ -1,197 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2021 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "CircularProgressBar.h"
|
||||
|
||||
#include <QskAnimator.h>
|
||||
#include <QskFunctions.h>
|
||||
|
||||
QSK_SUBCONTROL( CircularProgressBar, Groove )
|
||||
QSK_SUBCONTROL( CircularProgressBar, Bar )
|
||||
|
||||
namespace
|
||||
{
|
||||
class PositionAnimator : public QskAnimator
|
||||
{
|
||||
public:
|
||||
PositionAnimator( CircularProgressBar* progressBar )
|
||||
: m_progressBar( progressBar )
|
||||
{
|
||||
setAutoRepeat( true );
|
||||
setDuration( 1300 );
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
class CircularProgressBar::PrivateData
|
||||
{
|
||||
public:
|
||||
void updateIndeterminateAnimator( CircularProgressBar* 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;
|
||||
|
||||
bool hasOrigin = false;
|
||||
bool isIndeterminate = false;
|
||||
};
|
||||
|
||||
CircularProgressBar::~CircularProgressBar() = default;
|
||||
|
||||
CircularProgressBar::CircularProgressBar( qreal min, qreal max, QQuickItem* parent )
|
||||
: QskBoundedControl( min, max, parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
m_data->value = minimum();
|
||||
|
||||
initSizePolicy( QskSizePolicy::MinimumExpanding, QskSizePolicy::MinimumExpanding );
|
||||
|
||||
connect( this, &QskBoundedControl::boundariesChanged,
|
||||
this, &CircularProgressBar::adjustValue );
|
||||
}
|
||||
|
||||
CircularProgressBar::CircularProgressBar( QQuickItem* parent )
|
||||
: CircularProgressBar( 0.0, 100.0, parent )
|
||||
{
|
||||
}
|
||||
|
||||
bool CircularProgressBar::isIndeterminate() const
|
||||
{
|
||||
return m_data->isIndeterminate;
|
||||
}
|
||||
|
||||
void CircularProgressBar::setIndeterminate( bool on )
|
||||
{
|
||||
if ( on == m_data->isIndeterminate )
|
||||
return;
|
||||
|
||||
m_data->isIndeterminate = on;
|
||||
m_data->updateIndeterminateAnimator( this );
|
||||
|
||||
update();
|
||||
Q_EMIT indeterminateChanged( on );
|
||||
}
|
||||
|
||||
void CircularProgressBar::resetOrigin()
|
||||
{
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
m_data->hasOrigin = false;
|
||||
|
||||
update();
|
||||
Q_EMIT originChanged( origin() );
|
||||
}
|
||||
}
|
||||
|
||||
qreal CircularProgressBar::origin() const
|
||||
{
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
return boundedValue( m_data->origin );
|
||||
}
|
||||
|
||||
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"
|
|
@ -1,61 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2021 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskBoundedControl.h>
|
||||
|
||||
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:
|
||||
QSK_SUBCONTROLS( Groove, Bar )
|
||||
|
||||
CircularProgressBar( qreal min, qreal max, QQuickItem* parent = nullptr );
|
||||
CircularProgressBar( QQuickItem* parent = nullptr );
|
||||
~CircularProgressBar() override;
|
||||
|
||||
bool isIndeterminate() const;
|
||||
void setIndeterminate( bool on = true );
|
||||
|
||||
void resetOrigin();
|
||||
qreal origin() const;
|
||||
|
||||
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:
|
||||
void setValueInternal( qreal value );
|
||||
void adjustValue();
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
|
@ -1,49 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2021 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "CircularProgressBarSkinlet.h"
|
||||
#include "CircularProgressBar.h"
|
||||
|
||||
CircularProgressBarSkinlet::CircularProgressBarSkinlet( QskSkin* skin )
|
||||
: QskSkinlet( skin )
|
||||
{
|
||||
setNodeRoles( { GrooveRole, BarRole } );
|
||||
}
|
||||
|
||||
CircularProgressBarSkinlet::~CircularProgressBarSkinlet()
|
||||
{
|
||||
}
|
||||
|
||||
QRectF CircularProgressBarSkinlet::subControlRect(
|
||||
const QskSkinnable*, const QRectF& contentsRect, QskAspect::Subcontrol ) const
|
||||
{
|
||||
return contentsRect;
|
||||
}
|
||||
|
||||
QSGNode* CircularProgressBarSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
switch( nodeRole )
|
||||
{
|
||||
case GrooveRole:
|
||||
{
|
||||
return updateArcNode( skinnable, node, CircularProgressBar::Groove );
|
||||
}
|
||||
case BarRole:
|
||||
{
|
||||
const auto bar = static_cast< const CircularProgressBar* >( skinnable );
|
||||
|
||||
const qreal startAngle = 90.0;
|
||||
const qreal spanAngle = 360.0 * bar->valueAsRatio();
|
||||
|
||||
return updateArcNode( skinnable, node, startAngle, -spanAngle,
|
||||
CircularProgressBar::Bar );
|
||||
}
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
#include "moc_CircularProgressBarSkinlet.cpp"
|
|
@ -1,36 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2021 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#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;
|
||||
};
|
|
@ -1,69 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2021 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "EnergyMeter.h"
|
||||
#include "CircularProgressBar.h"
|
||||
|
||||
#include <QskTextLabel.h>
|
||||
#include <QskFontRole.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
class ValueLabel : public QskTextLabel
|
||||
{
|
||||
public:
|
||||
ValueLabel( QQuickItem* parent )
|
||||
: QskTextLabel( parent )
|
||||
{
|
||||
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
setLayoutAlignmentHint( Qt::AlignCenter );
|
||||
setFontRole( QskFontRole::Caption );
|
||||
}
|
||||
|
||||
void setValue( int value )
|
||||
{
|
||||
setText( locale().toString( value ) + " " + locale().percent() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
EnergyMeter::EnergyMeter( const QColor& textColor,
|
||||
const QskGradient& gradient, int value, QQuickItem* parent )
|
||||
: QskControl( parent )
|
||||
{
|
||||
setAutoLayoutChildren( true );
|
||||
|
||||
auto valueBar = new CircularProgressBar( this );
|
||||
valueBar->setGradientHint( CircularProgressBar::Bar, gradient );
|
||||
valueBar->setValue( value );
|
||||
|
||||
auto valueLabel = new ValueLabel( this );
|
||||
valueLabel->setTextColor( textColor );
|
||||
valueLabel->setValue( value );
|
||||
}
|
||||
|
||||
QSizeF EnergyMeter::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
qreal size;
|
||||
|
||||
if ( constraint.width() > 0 )
|
||||
{
|
||||
size = constraint.width();
|
||||
}
|
||||
else if ( constraint.height() > 0 )
|
||||
{
|
||||
size = constraint.height();
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 57;
|
||||
}
|
||||
|
||||
return QSizeF( size, size );
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2021 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskControl.h>
|
||||
|
||||
class EnergyMeter : public QskControl
|
||||
{
|
||||
public:
|
||||
EnergyMeter( const QColor&, const QskGradient&,
|
||||
int progress, QQuickItem* parent = nullptr );
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
};
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
#include "Box.h"
|
||||
#include "BoxWithButtons.h"
|
||||
#include "CircularProgressBar.h"
|
||||
#include "CircularProgressBarSkinlet.h"
|
||||
#include "DashboardPage.h"
|
||||
#include "Diagram.h"
|
||||
#include "DiagramSkinlet.h"
|
||||
|
@ -21,7 +19,6 @@
|
|||
#include "RoundedIcon.h"
|
||||
#include "StorageBar.h"
|
||||
#include "StorageBarSkinlet.h"
|
||||
#include "StorageMeter.h"
|
||||
#include "StoragePage.h"
|
||||
#include "TopBar.h"
|
||||
#include "UsageBox.h"
|
||||
|
@ -37,6 +34,7 @@
|
|||
#include <QskSkinHintTableEditor.h>
|
||||
#include <QskStateCombination.h>
|
||||
#include <QskTextLabel.h>
|
||||
#include <QskProgressRing.h>
|
||||
#include <QskGraphicLabel.h>
|
||||
#include <QskFontRole.h>
|
||||
|
||||
|
@ -56,7 +54,6 @@ Skin::Skin( QObject* parent )
|
|||
{
|
||||
setObjectName( "iot" );
|
||||
|
||||
declareSkinlet< CircularProgressBar, CircularProgressBarSkinlet >();
|
||||
declareSkinlet< Diagram, DiagramSkinlet >();
|
||||
declareSkinlet< LightDisplay, LightDisplaySkinlet >();
|
||||
declareSkinlet< StorageBar, StorageBarSkinlet >();
|
||||
|
@ -87,9 +84,9 @@ void Skin::initHints()
|
|||
|
||||
ed.setPadding( MainContentGridBox::Panel, { 19, 0, 27, 24 } );
|
||||
|
||||
// menu bar:
|
||||
|
||||
{
|
||||
// menu bar:
|
||||
|
||||
using Q = QskPushButton;
|
||||
using A = QskAspect;
|
||||
|
||||
|
@ -113,25 +110,27 @@ void Skin::initHints()
|
|||
ed.setAlignment( Q::Icon | A::Header, Qt::AlignCenter );
|
||||
}
|
||||
|
||||
// top bar:
|
||||
ed.setPadding( TopBar::Panel, { 25, 35, 25, 0 } );
|
||||
{
|
||||
// top bar:
|
||||
|
||||
ed.setColor( TopBarItem::Item1 | QskAspect::TextColor, 0xffff3122 );
|
||||
ed.setColor( TopBarItem::Item2 | QskAspect::TextColor, 0xff6776ff );
|
||||
ed.setColor( TopBarItem::Item3 | QskAspect::TextColor, 0xfff99055 );
|
||||
ed.setColor( TopBarItem::Item4 | QskAspect::TextColor, 0xff6776ff );
|
||||
ed.setPadding( TopBar::Panel, { 25, 35, 25, 0 } );
|
||||
|
||||
// arcs are counterclockwise, so specify the 2nd color first:
|
||||
ed.setGradient( TopBarItem::Item1, 0xffff3122, 0xffff5c00 );
|
||||
ed.setGradient( TopBarItem::Item2, 0xff6100ff, 0xff6776ff );
|
||||
ed.setGradient( TopBarItem::Item3, 0xffff3122, 0xffffce50 );
|
||||
ed.setGradient( TopBarItem::Item4, 0xff6100ff, 0xff6776ff );
|
||||
ed.setColor( TopBarItem::Item1 | QskAspect::TextColor, 0xffff3122 );
|
||||
ed.setColor( TopBarItem::Item2 | QskAspect::TextColor, 0xff6776ff );
|
||||
ed.setColor( TopBarItem::Item3 | QskAspect::TextColor, 0xfff99055 );
|
||||
ed.setColor( TopBarItem::Item4 | QskAspect::TextColor, 0xff6776ff );
|
||||
|
||||
ed.setGradient( TopBarItem::Item1, 0xffff5c00, 0xffff3122 );
|
||||
ed.setGradient( TopBarItem::Item2, 0xff6776ff, 0xff6100ff );
|
||||
ed.setGradient( TopBarItem::Item3, 0xffffce50, 0xffff3122 );
|
||||
ed.setGradient( TopBarItem::Item4, 0xff6776ff, 0xff6100ff );
|
||||
}
|
||||
|
||||
// the bar gradient is defined through the top bar items above
|
||||
ed.setArcMetrics( CircularProgressBar::Groove, 90, -360, 8.53 );
|
||||
ed.setArcMetrics( QskProgressRing::Groove, 90, -360, 8.53 );
|
||||
// the span angle will be set in the progress bar, we just give a dummy
|
||||
// value here:
|
||||
ed.setArcMetrics( CircularProgressBar::Bar, 90, -180, 8.53 );
|
||||
ed.setArcMetrics( QskProgressRing::Fill, ed.arcMetrics( QskProgressRing::Groove ) );
|
||||
|
||||
ed.setFontRole( TimeTitleLabel::Text, { QskFontRole::Caption, QskFontRole::High } );
|
||||
|
||||
|
@ -283,8 +282,8 @@ void Skin::initHints()
|
|||
ed.setColor( QskTextLabel::Text, palette.text );
|
||||
ed.setColor( UsageDiagramBox::DayText, palette.text );
|
||||
|
||||
ed.setMetric( CircularProgressBar::Groove | QskAspect::Border, 2 );
|
||||
ed.setColor( CircularProgressBar::Groove | QskAspect::Border,
|
||||
ed.setMetric( QskProgressRing::Groove | QskAspect::Border, 2 );
|
||||
ed.setColor( QskProgressRing::Groove | QskAspect::Border,
|
||||
palette.circularProgressBarGroove );
|
||||
|
||||
// storage bar
|
||||
|
@ -302,9 +301,13 @@ void Skin::initHints()
|
|||
|
||||
// storage meter
|
||||
{
|
||||
ed.setGradient( StorageMeter::Status,
|
||||
{ { { 0.00, "#00ff00" }, { 0.33, "#00ff00" }, { 0.33, "#ffaf00" }, { 0.66, "#ffaf00" },
|
||||
{ 0.66, "#ff0000" }, { 1.00, "#ff0000" } } } );
|
||||
ed.setGradient( StoragePage::Status,
|
||||
{ {
|
||||
{ 0.00, "#00ff00" }, { 0.33, "#00ff00" },
|
||||
{ 0.33, "#ffaf00" }, { 0.66, "#ffaf00" },
|
||||
{ 0.66, "#ff0000" }, { 1.00, "#ff0000" }
|
||||
} }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2022 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "StorageMeter.h"
|
||||
#include "CircularProgressBar.h"
|
||||
#include <QskFontRole.h>
|
||||
#include <QskTextLabel.h>
|
||||
|
||||
QSK_SUBCONTROL( StorageMeter, Status )
|
||||
|
||||
namespace
|
||||
{
|
||||
inline QString make_text( const QLocale& locale, const qreal value )
|
||||
{
|
||||
return locale.toString( static_cast< int >( value ) ) + " " + locale.percent();
|
||||
}
|
||||
}
|
||||
|
||||
StorageMeter::StorageMeter( QQuickItem* parent ) noexcept
|
||||
: CircularProgressBar( parent )
|
||||
, label( new QskTextLabel( this ) )
|
||||
{
|
||||
setAutoLayoutChildren( true );
|
||||
setSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Constrained );
|
||||
|
||||
label->setText( make_text( locale(), value() ) );
|
||||
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
label->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||
label->setFontRole( QskFontRole::Caption );
|
||||
}
|
||||
|
||||
void StorageMeter::setValue( const qreal value )
|
||||
{
|
||||
const auto gradient = gradientHint( StorageMeter::Status );
|
||||
const auto color = gradient.extracted( value / 100.0, value / 100.0 ).startColor();
|
||||
setGradientHint( StorageMeter::Bar, { color, color.lighter() } );
|
||||
CircularProgressBar::setValue( value );
|
||||
label->setTextColor( color );
|
||||
label->setText( make_text( locale(), value ) );
|
||||
}
|
||||
|
||||
QSizeF StorageMeter::contentsSizeHint( Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
qreal size;
|
||||
|
||||
if ( constraint.width() > 0 )
|
||||
{
|
||||
size = constraint.width();
|
||||
}
|
||||
else if ( constraint.height() > 0 )
|
||||
{
|
||||
size = constraint.height();
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 57;
|
||||
}
|
||||
|
||||
return QSizeF( size, size );
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2022 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CircularProgressBar.h"
|
||||
#include <QskControl.h>
|
||||
|
||||
class StorageMeter final : public CircularProgressBar
|
||||
{
|
||||
public:
|
||||
QSK_SUBCONTROLS( Status )
|
||||
explicit StorageMeter( QQuickItem* parent = nullptr ) noexcept;
|
||||
public Q_SLOTS:
|
||||
void setValue( qreal value );
|
||||
|
||||
private:
|
||||
QSizeF contentsSizeHint( Qt::SizeHint which, const QSizeF& constraint ) const override;
|
||||
class QskTextLabel* label = nullptr;
|
||||
};
|
|
@ -6,7 +6,7 @@
|
|||
#include "StoragePage.h"
|
||||
#include "Box.h"
|
||||
#include "StorageBar.h"
|
||||
#include "StorageMeter.h"
|
||||
#include "ValueMeter.h"
|
||||
#include <QTimer>
|
||||
#include <QskAnimator.h>
|
||||
#include <QskBox.h>
|
||||
|
@ -20,6 +20,60 @@
|
|||
#include <QskTextLabel.h>
|
||||
|
||||
QSK_SUBCONTROL( StoragePage, Panel )
|
||||
QSK_SUBCONTROL( StoragePage, Status )
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Storage
|
||||
{
|
||||
struct Media
|
||||
{
|
||||
qreal pictures = 0;
|
||||
qreal music = 0;
|
||||
qreal videos = 0;
|
||||
qreal documents = 0;
|
||||
qreal others = 0;
|
||||
|
||||
inline constexpr bool operator==( const Media& rhs ) const noexcept
|
||||
{
|
||||
return pictures == rhs.pictures && music == rhs.music && videos == rhs.videos &&
|
||||
documents == rhs.documents && others == rhs.others;
|
||||
}
|
||||
|
||||
inline constexpr qreal free() const noexcept
|
||||
{
|
||||
return 1.0 - pictures - music - videos - documents - others;
|
||||
}
|
||||
};
|
||||
|
||||
QString title;
|
||||
QString description;
|
||||
Media distribution;
|
||||
};
|
||||
|
||||
class StorageMeter final : public ValueMeter
|
||||
{
|
||||
public:
|
||||
StorageMeter( QQuickItem* parent = nullptr )
|
||||
: ValueMeter( parent )
|
||||
{
|
||||
setFixedSize( 64, 64 );
|
||||
|
||||
connect( this, &ValueMeter::valueChanged,
|
||||
this, &StorageMeter::setStatusColor );
|
||||
}
|
||||
|
||||
private:
|
||||
void setStatusColor( qreal value )
|
||||
{
|
||||
const auto color = qskInterpolatedColorAt(
|
||||
gradientHint( StoragePage::Status ).stops(), value / 100.0 );
|
||||
|
||||
setFillGradient( { color, color.lighter() } );
|
||||
setTextColor( color );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct StorageRowAnimator final : public QObject, public QskAnimator
|
||||
{
|
||||
|
@ -85,8 +139,6 @@ void StoragePage::addRow( const QString& title, const QString& description,
|
|||
const auto percent = 100.0 * ( 1.0 - storage.distribution.free() );
|
||||
auto* const meter = new StorageMeter( left );
|
||||
meter->setValue( percent );
|
||||
meter->setMinimumSize( 64, 64 );
|
||||
meter->setMaximumSize( 64, 64 );
|
||||
|
||||
auto* const maintitle = new QskTextLabel( storage.title, center );
|
||||
maintitle->setFontRole( QskFontRole::Headline );
|
||||
|
@ -136,5 +188,6 @@ void StoragePage::addRow( const QString& title, const QString& description,
|
|||
bar->setDocuments( media.documents * v );
|
||||
bar->setOthers( media.others * v );
|
||||
};
|
||||
connect( sync, &QskPushButton::clicked, animator, [ animator ]() { animator->start(); } );
|
||||
connect( sync, &QskPushButton::clicked,
|
||||
animator, [ animator ]() { animator->start(); } );
|
||||
}
|
||||
|
|
|
@ -7,44 +7,15 @@
|
|||
|
||||
#include <QVector>
|
||||
#include <QskLinearBox.h>
|
||||
#include <memory>
|
||||
|
||||
class QQuickItem;
|
||||
|
||||
class StoragePage final : public QskLinearBox
|
||||
{
|
||||
public:
|
||||
QSK_SUBCONTROLS( Panel )
|
||||
explicit StoragePage( QQuickItem* parent = nullptr );
|
||||
QSK_SUBCONTROLS( Panel, Status )
|
||||
|
||||
StoragePage( QQuickItem* parent = nullptr );
|
||||
|
||||
private:
|
||||
struct Storage
|
||||
{
|
||||
struct Media
|
||||
{
|
||||
qreal pictures = 0;
|
||||
qreal music = 0;
|
||||
qreal videos = 0;
|
||||
qreal documents = 0;
|
||||
qreal others = 0;
|
||||
|
||||
inline constexpr bool operator==( const Media& rhs ) const noexcept
|
||||
{
|
||||
return pictures == rhs.pictures && music == rhs.music && videos == rhs.videos &&
|
||||
documents == rhs.documents && others == rhs.others;
|
||||
}
|
||||
|
||||
inline constexpr qreal free() const noexcept
|
||||
{
|
||||
return 1.0 - pictures - music - videos - documents - others;
|
||||
}
|
||||
};
|
||||
|
||||
QString title;
|
||||
QString description;
|
||||
Media distribution;
|
||||
};
|
||||
|
||||
void addRow( const QString& title, const QString& description,
|
||||
qreal pictures, qreal music, qreal videos, qreal documents, qreal others );
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "TopBar.h"
|
||||
#include "EnergyMeter.h"
|
||||
#include "ValueMeter.h"
|
||||
|
||||
#include <QskFontRole.h>
|
||||
#include <QskTextLabel.h>
|
||||
|
@ -41,6 +41,22 @@ namespace
|
|||
return TopBarItem::Item4;
|
||||
}
|
||||
}
|
||||
|
||||
class EnergyMeter : public ValueMeter
|
||||
{
|
||||
public:
|
||||
EnergyMeter( const QColor& textColor,
|
||||
const QskGradient& gradient, int value, QQuickItem* parent )
|
||||
: ValueMeter( parent )
|
||||
{
|
||||
setFillGradient( gradient );
|
||||
setValue( value );
|
||||
setTextColor( textColor );
|
||||
|
||||
setFixedSize( 57, 57 );
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TopBarItem::TopBarItem(
|
||||
|
@ -62,9 +78,7 @@ TopBarItem::TopBarItem(
|
|||
const auto subcontrol = subcontrolForIndex( index );
|
||||
const auto textColor = color( subcontrol | QskAspect::TextColor );
|
||||
|
||||
auto pieChart = new EnergyMeter(
|
||||
textColor, gradient, progress, pieChartAndDisplay );
|
||||
pieChart->setSizePolicy( Qt::Horizontal, QskSizePolicy::Constrained );
|
||||
(void) new EnergyMeter( textColor, gradient, progress, pieChartAndDisplay );
|
||||
|
||||
auto display = new QskLinearBox( Qt::Vertical, pieChartAndDisplay );
|
||||
display->setSpacing( 0 );
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2022 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ValueMeter.h"
|
||||
|
||||
#include <QskFontRole.h>
|
||||
#include <QskTextLabel.h>
|
||||
|
||||
ValueMeter::ValueMeter( QQuickItem* parent )
|
||||
: QskProgressRing( parent )
|
||||
{
|
||||
setAutoLayoutChildren( true );
|
||||
initSizePolicy( QskSizePolicy::MinimumExpanding, QskSizePolicy::Constrained );
|
||||
|
||||
m_label = new QskTextLabel( this );
|
||||
m_label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
m_label->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||
m_label->setFontRole( QskFontRole::Caption );
|
||||
|
||||
connect( this, &QskProgressRing::valueChanged,
|
||||
this, &ValueMeter::updateMeter );
|
||||
|
||||
updateMeter( value() );
|
||||
}
|
||||
|
||||
void ValueMeter::updateMeter( const qreal value )
|
||||
{
|
||||
m_label->setText( text( value ) );
|
||||
}
|
||||
|
||||
QString ValueMeter::text( qreal value ) const
|
||||
{
|
||||
value = static_cast< int >( value );
|
||||
return locale().toString( value ) + ' ' + locale().percent();
|
||||
}
|
||||
|
||||
void ValueMeter::setTextColor( const QColor& color )
|
||||
{
|
||||
m_label->setTextColor( color );
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2022 Edelhirsch Software GmbH
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskProgressRing.h>
|
||||
|
||||
class QskTextLabel;
|
||||
|
||||
class ValueMeter : public QskProgressRing
|
||||
{
|
||||
public:
|
||||
ValueMeter( QQuickItem* parent = nullptr );
|
||||
|
||||
void setTextColor( const QColor& );
|
||||
|
||||
protected:
|
||||
virtual QString text( qreal ) const;
|
||||
|
||||
private:
|
||||
void updateMeter( qreal value );
|
||||
QskTextLabel* m_label = nullptr;
|
||||
};
|
|
@ -15,13 +15,13 @@ using Q = QskProgressBar;
|
|||
|
||||
namespace
|
||||
{
|
||||
QskIntervalF qskFillInterval( const Q* bar )
|
||||
QskIntervalF qskFillInterval( const QskProgressIndicator* indicator )
|
||||
{
|
||||
qreal pos1, pos2;
|
||||
|
||||
if ( bar->isIndeterminate() )
|
||||
if ( indicator->isIndeterminate() )
|
||||
{
|
||||
const auto pos = bar->positionHint( QskProgressIndicator::Fill );
|
||||
const auto pos = indicator->positionHint( QskProgressIndicator::Fill );
|
||||
|
||||
static const QEasingCurve curve( QEasingCurve::InOutCubic );
|
||||
|
||||
|
@ -32,10 +32,11 @@ namespace
|
|||
}
|
||||
else
|
||||
{
|
||||
pos1 = bar->valueAsRatio( bar->origin() );
|
||||
pos2 = bar->valueAsRatio( bar->value() );
|
||||
pos1 = indicator->valueAsRatio( indicator->origin() );
|
||||
pos2 = indicator->valueAsRatio( indicator->value() );
|
||||
}
|
||||
|
||||
auto bar = static_cast< const QskProgressBar* >( indicator );
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
if ( bar->layoutMirroring() )
|
||||
|
@ -107,11 +108,11 @@ QSGNode* QskProgressBarSkinlet::updateFillNode(
|
|||
|
||||
const auto subControl = Q::Fill;
|
||||
|
||||
const auto rect = bar->subControlRect( subControl );
|
||||
const auto rect = indicator->subControlRect( subControl );
|
||||
if ( rect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto gradient = bar->gradientHint( subControl );
|
||||
auto gradient = indicator->gradientHint( subControl );
|
||||
if ( !gradient.isVisible() )
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "QskProgressRing.h"
|
||||
|
||||
#include "QskIntervalF.h"
|
||||
|
||||
QSK_SUBCONTROL( QskProgressRing, Groove )
|
||||
|
@ -20,6 +19,8 @@ QskProgressRing::QskProgressRing( qreal min, qreal max, QQuickItem* parent )
|
|||
: Inherited( min, max, parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
|
||||
m_data->size = NormalSize;
|
||||
|
||||
setSubcontrolProxy( Inherited::Groove, Groove );
|
||||
|
|
|
@ -10,31 +10,6 @@
|
|||
|
||||
using Q = QskProgressRing;
|
||||
|
||||
namespace
|
||||
{
|
||||
QskIntervalF qskFillInterval( const Q* ring )
|
||||
{
|
||||
qreal pos1, pos2;
|
||||
|
||||
if ( ring->isIndeterminate() )
|
||||
{
|
||||
const auto pos = ring->positionHint( QskProgressIndicator::Fill );
|
||||
|
||||
pos1 = pos2 = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos1 = ring->valueAsRatio( ring->origin() );
|
||||
pos2 = ring->valueAsRatio( ring->value() );
|
||||
}
|
||||
|
||||
if ( pos1 > pos2 )
|
||||
std::swap( pos1, pos2 );
|
||||
|
||||
return QskIntervalF( pos1, pos2 );
|
||||
}
|
||||
}
|
||||
|
||||
QskProgressRingSkinlet::QskProgressRingSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
|
@ -48,27 +23,8 @@ QRectF QskProgressRingSkinlet::subControlRect(
|
|||
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||
QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
const auto ring = static_cast< const Q* >( skinnable );
|
||||
|
||||
if( subControl == Q::Groove || subControl == Q::Fill )
|
||||
{
|
||||
auto rect = contentsRect;
|
||||
const auto size = ring->strutSizeHint( Q::Fill );
|
||||
|
||||
if( ring->layoutMirroring() )
|
||||
{
|
||||
rect.setLeft( rect.right() - size.width() );
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setWidth( size.width() );
|
||||
}
|
||||
|
||||
rect.setTop( rect.top() + 0.5 * ( rect.height() - size.height() ) );
|
||||
rect.setHeight( size.height() );
|
||||
|
||||
return rect;
|
||||
}
|
||||
return contentsRect;
|
||||
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
@ -90,36 +46,74 @@ QSGNode* QskProgressRingSkinlet::updateFillNode(
|
|||
if ( rect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
const auto metrics = ring->arcMetricsHint( subControl );
|
||||
if ( metrics.isNull() )
|
||||
return nullptr;
|
||||
|
||||
auto gradient = ring->gradientHint( subControl );
|
||||
if ( !gradient.isVisible() )
|
||||
return nullptr;
|
||||
|
||||
const auto intv = fillInterval( ring );
|
||||
|
||||
if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
|
||||
{
|
||||
const auto center = rect.center();
|
||||
const auto arcMetrics = ring->arcMetricsHint( Q::Fill );
|
||||
gradient.setConicDirection( center.x(), center.y(), arcMetrics.startAngle(), arcMetrics.spanAngle() );
|
||||
const auto stops = qskExtractedGradientStops( gradient.stops(),
|
||||
intv.lowerBound(), intv.upperBound() );
|
||||
|
||||
gradient.setStops( stops );
|
||||
|
||||
if ( metrics.spanAngle() < 0.0 )
|
||||
gradient.reverse();
|
||||
}
|
||||
|
||||
const auto interval = qskFillInterval( ring );
|
||||
const auto arcMetrics = ring->arcMetricsHint( subControl );
|
||||
|
||||
const auto startAngle = arcMetrics.startAngle() + interval.lowerBound() * arcMetrics.spanAngle();
|
||||
const auto spanAngle = interval.upperBound() * arcMetrics.spanAngle();
|
||||
const auto startAngle = metrics.startAngle() + intv.lowerBound() * metrics.spanAngle();
|
||||
const auto spanAngle = intv.upperBound() * metrics.spanAngle();
|
||||
|
||||
return updateArcNode( ring, node, rect, gradient, startAngle, spanAngle, subControl );
|
||||
}
|
||||
|
||||
QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const auto ring = static_cast< const Q* >( skinnable );
|
||||
auto hint = skinnable->strutSizeHint( Q::Fill );
|
||||
hint = hint.expandedTo( skinnable->strutSizeHint( Q::Groove ) );
|
||||
|
||||
const auto r = ring->strutSizeHint( Q::Fill );
|
||||
return r;
|
||||
if ( !constraint.isEmpty() )
|
||||
{
|
||||
const qreal aspectRatio = hint.isEmpty() ? 1.0 : hint.width() / hint.height();
|
||||
|
||||
if ( constraint.width() >= 0.0 )
|
||||
hint.setHeight( constraint.width() / aspectRatio );
|
||||
else
|
||||
hint.setWidth( constraint.height() * aspectRatio );
|
||||
}
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
QskIntervalF QskProgressRingSkinlet::fillInterval(
|
||||
const QskProgressIndicator* indicator ) const
|
||||
{
|
||||
qreal pos1, pos2;
|
||||
|
||||
if ( indicator->isIndeterminate() )
|
||||
{
|
||||
pos1 = pos2 = indicator->positionHint( QskProgressIndicator::Fill );
|
||||
}
|
||||
else
|
||||
{
|
||||
pos1 = indicator->valueAsRatio( indicator->origin() );
|
||||
pos2 = indicator->valueAsRatio( indicator->value() );
|
||||
}
|
||||
|
||||
if ( pos1 > pos2 )
|
||||
std::swap( pos1, pos2 );
|
||||
|
||||
return QskIntervalF( pos1, pos2 );
|
||||
}
|
||||
|
||||
#include "moc_QskProgressRingSkinlet.cpp"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "QskProgressIndicatorSkinlet.h"
|
||||
|
||||
class QskProgressRing;
|
||||
class QskIntervalF;
|
||||
|
||||
class QSK_EXPORT QskProgressRingSkinlet : public QskProgressIndicatorSkinlet
|
||||
{
|
||||
|
@ -29,6 +29,8 @@ class QSK_EXPORT QskProgressRingSkinlet : public QskProgressIndicatorSkinlet
|
|||
protected:
|
||||
QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const override;
|
||||
QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const override;
|
||||
|
||||
QskIntervalF fillInterval( const QskProgressIndicator* ) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue