progress bars: Introduce progress ring and refactor

Most of the code between rings and bars can be shared with a
common superclass QskProgressIndicator.

Resolves #98
This commit is contained in:
Peter Hartmann 2023-07-25 08:56:21 +02:00 committed by uwerat
parent 2d5db67e79
commit ec61c11ab6
23 changed files with 967 additions and 384 deletions

View File

@ -4,13 +4,18 @@
*****************************************************************************/
#include "ProgressBarPage.h"
#include <QskProgressBar.h>
#include <QskAnimator.h>
#include <QskGraphicProvider.h>
#include <QskGraphic.h>
#include <QskGradient.h>
#include <QskHctColor.h>
#include <QskProgressBar.h>
#include <QskProgressRing.h>
#include <QskRgbValue.h>
#include <QQuickWindow>
namespace
{
class ProgressBar : public QskProgressBar
@ -35,9 +40,32 @@ namespace
colors += hctColor.toned( 45 ).rgb();
colors += hctColor.toned( 30 ).rgb();
setBarGradient( qskBuildGradientStops( colors, true ) );
setFillGradient( qskBuildGradientStops( colors, true ) );
}
};
class DeterminateIndicatorsAnimator : public QskAnimator
{
public:
DeterminateIndicatorsAnimator( const QVector< QskProgressIndicator* >& indicators )
: QskAnimator()
, m_indicators( indicators )
{
setAutoRepeat( true );
setDuration( 3000 );
}
void advance( qreal value ) override
{
for( auto* indicator : m_indicators )
{
indicator->setValueAsRatio( value );
}
}
private:
const QVector< QskProgressIndicator* > m_indicators;
};
}
ProgressBarPage::ProgressBarPage( QQuickItem* parent )
@ -53,10 +81,7 @@ void ProgressBarPage::populate()
hBox->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
hBox->setSpacing( 20 );
{
auto bar = new ProgressBar( hBox );
bar->setValue( 35 );
}
QVector< QskProgressIndicator* > determinateIndicators;
{
auto bar = new ProgressBar( hBox );
@ -77,6 +102,11 @@ void ProgressBarPage::populate()
bar->setValue( 25 );
}
{
auto bar = new ProgressBar( hBox );
determinateIndicators.append( bar );
}
{
auto bar = new ProgressBar( hBox );
bar->setIndeterminate( true );
@ -106,8 +136,55 @@ void ProgressBarPage::populate()
bar->setValue( 10 );
}
{
auto bar = new ProgressBar( vBox );
determinateIndicators.append( bar );
}
{
auto bar = new ProgressBar( vBox );
bar->setIndeterminate( true );
}
const auto sizes = { QskProgressRing::SmallSize, QskProgressRing::NormalSize,
QskProgressRing::LargeSize };
auto determinateRingsHBox = new QskLinearBox( Qt::Horizontal, vBox );
auto indeterminateRingsHBox = new QskLinearBox( Qt::Horizontal, vBox );
for( const auto size : sizes )
{
for( const auto indeterminate : { true, false } )
{
auto* ring = new QskProgressRing( determinateRingsHBox );
ring->setSize( size );
QQuickItem* parentItem;
if( indeterminate )
{
parentItem = indeterminateRingsHBox;
ring->setIndeterminate( true );
}
else
{
parentItem = determinateRingsHBox;
determinateIndicators.append( ring );
}
ring->setParent( parentItem );
ring->setParentItem( parentItem );
}
}
connect( this, &QskQuickItem::windowChanged, this, [this, determinateIndicators]( QQuickWindow* window )
{
if( window )
{
m_determinateIndicatorsAnimator.reset( new DeterminateIndicatorsAnimator( determinateIndicators ) );
m_determinateIndicatorsAnimator->setWindow( window );
m_determinateIndicatorsAnimator->start();
}
} );
}

View File

@ -7,6 +7,8 @@
#include "Page.h"
class QskAnimator;
class ProgressBarPage : public Page
{
public:
@ -14,4 +16,6 @@ class ProgressBarPage : public Page
private:
void populate();
std::unique_ptr< QskAnimator > m_determinateIndicatorsAnimator;
};

View File

@ -33,7 +33,6 @@
#include <QskBoxShapeMetrics.h>
#include <QskColorFilter.h>
#include <QskFunctions.h>
#include <QskProgressBar.h>
#include <QskShadowMetrics.h>
#include <QskSkinHintTableEditor.h>
#include <QskStateCombination.h>

View File

@ -5,9 +5,6 @@
#include "StoragePage.h"
#include "Box.h"
#include "CircularProgressBar.h"
#include "Diagram.h"
#include "EnergyMeter.h"
#include "StorageBar.h"
#include "StorageMeter.h"
#include <QTimer>
@ -17,7 +14,6 @@
#include <QskGradient.h>
#include <QskGradientStop.h>
#include <QskGraphicLabel.h>
#include <QskProgressBar.h>
#include <QskPushButton.h>
#include <QskSkin.h>
#include <QskStackBox.h>

View File

@ -33,6 +33,7 @@
#include <QskPlacementPolicy.h>
#include <QskPopup.h>
#include <QskProgressBar.h>
#include <QskProgressRing.h>
#include <QskPushButton.h>
#include <QskRadioBox.h>
#include <QskScrollArea.h>
@ -220,6 +221,7 @@ void QskQml::registerTypes()
registerObject< QskFocusIndicator >();
registerObject< QskSeparator >();
registerObject< QskProgressBar >();
registerObject< QskProgressRing >();
registerObject< QskPushButton >();
registerObject< QskScrollView >();
registerObject< QskScrollArea >();

View File

@ -80,6 +80,7 @@
#include <QskPageIndicator.h>
#include <QskPushButton.h>
#include <QskProgressBar.h>
#include <QskProgressRing.h>
#include <QskRadioBox.h>
#include <QskScrollView.h>
#include <QskSegmentedBar.h>
@ -212,6 +213,9 @@ namespace
void setupProgressBarMetrics();
void setupProgressBarColors( QskAspect::Section, const QskFluent2Theme& );
void setupProgressRingMetrics();
void setupProgressRingColors( QskAspect::Section, const QskFluent2Theme& );
void setupPushButtonMetrics();
void setupPushButtonColors( QskAspect::Section, const QskFluent2Theme& );
@ -291,6 +295,7 @@ void Editor::setupMetrics()
setupMenuMetrics();
setupPageIndicatorMetrics();
setupProgressBarMetrics();
setupProgressRingMetrics();
setupPushButtonMetrics();
setupRadioBoxMetrics();
setupScrollViewMetrics();
@ -327,6 +332,7 @@ void Editor::setupColors( QskAspect::Section section, const QskFluent2Theme& the
setupMenuColors( section, theme );
setupPageIndicatorColors( section, theme );
setupProgressBarColors( section, theme );
setupProgressRingColors( section, theme );
setupPushButtonColors( section, theme );
setupRadioBoxColors( section, theme );
setupScrollViewColors( section, theme );
@ -839,8 +845,8 @@ void Editor::setupProgressBarMetrics()
setMetric( Q::Groove | A::Size, 1 );
setBoxShape( Q::Groove, 100, Qt::RelativeSize );
setMetric( Q::Bar | A::Size, 3 );
setBoxShape( Q::Bar, 100, Qt::RelativeSize );
setMetric( Q::Fill | A::Size, 3 );
setBoxShape( Q::Fill, 100, Qt::RelativeSize );
}
void Editor::setupProgressBarColors(
@ -851,7 +857,36 @@ void Editor::setupProgressBarColors(
const auto& pal = theme.palette;
setGradient( Q::Groove | section, pal.strokeColor.controlStrong.defaultColor );
setGradient( Q::Bar | section, pal.fillColor.accent.defaultColor );
setGradient( Q::Fill | section, pal.fillColor.accent.defaultColor );
}
void Editor::setupProgressRingMetrics()
{
using Q = QskProgressRing;
using A = QskAspect;
static constexpr QskAspect::Variation SmallSize = A::Small;
static constexpr QskAspect::Variation NormalSize = A::NoVariation;
static constexpr QskAspect::Variation LargeSize = A::Large;
setStrutSize( Q::Fill | SmallSize, { 16, 16 } );
setStrutSize( Q::Fill | NormalSize, { 32, 32 } );
setStrutSize( Q::Fill | LargeSize, { 64, 64 } );
const auto startAngle = 90, spanAngle = -360;
setArcMetrics( Q::Fill | SmallSize, startAngle, spanAngle, 1.5 );
setArcMetrics( Q::Fill | NormalSize, startAngle, spanAngle, 3 );
setArcMetrics( Q::Fill | LargeSize, startAngle, spanAngle, 6 );
}
void Editor::setupProgressRingColors(
QskAspect::Section section, const QskFluent2Theme& theme )
{
using Q = QskProgressRing;
const auto& pal = theme.palette;
setGradient( Q::Fill | section, pal.fillColor.accent.defaultColor );
}
void Editor::setupPushButtonMetrics()

View File

@ -23,6 +23,7 @@
#include <QskPageIndicator.h>
#include <QskPushButton.h>
#include <QskProgressBar.h>
#include <QskProgressRing.h>
#include <QskRadioBox.h>
#include <QskScrollView.h>
#include <QskSegmentedBar.h>
@ -94,6 +95,7 @@ namespace
void setupPageIndicator();
void setupPopup();
void setupProgressBar();
void setupProgressRing();
void setupRadioBox();
void setupPushButton();
void setupScrollView();
@ -161,6 +163,7 @@ void Editor::setup()
setupPageIndicator();
setupPopup();
setupProgressBar();
setupProgressRing();
setupPushButton();
setupRadioBox();
setupScrollView();
@ -431,9 +434,9 @@ void Editor::setupProgressBar()
using A = QskAspect;
using Q = QskProgressBar;
auto size = 5_dp;
auto size = 4_dp;
for ( auto subControl : { Q::Groove, Q::Bar } )
for ( auto subControl : { Q::Groove, Q::Fill } )
{
setMetric( subControl | A::Size, size );
setPadding( subControl, 0 );
@ -443,12 +446,21 @@ void Editor::setupProgressBar()
}
setMetric( Q::Groove | A::Size, size );
setGradient( Q::Groove, m_pal.primaryContainer );
setGradient( Q::Groove, m_pal.surfaceContainerHighest );
setGradient( Q::Groove | Q::Disabled, m_pal.onSurface12 );
setGradient( Q::Bar, m_pal.primary );
setGradient( Q::Bar | Q::Disabled, m_pal.onSurface38 );
setGradient( Q::Fill, m_pal.primary );
setGradient( Q::Fill | Q::Disabled, m_pal.onSurface38 );
}
void Editor::setupProgressRing()
{
using Q = QskProgressRing;
setStrutSize( Q::Fill, { 48_dp, 48_dp } );
setGradient( Q::Fill, m_pal.primary );
setArcMetrics( Q::Fill, 90, -360, 4_dp );
}
void Editor::setupRadioBox()
@ -1302,6 +1314,8 @@ QskMaterial3Theme::QskMaterial3Theme( QskSkin::ColorScheme colorScheme,
outline = m_palettes[ NeutralVariant ].toned( 50 ).rgb();
outlineVariant = m_palettes[ NeutralVariant ].toned( 80 ).rgb();
surfaceContainerHighest = m_palettes[ NeutralVariant ].toned( 90 ).rgb();
shadow = m_palettes[ Neutral ].toned( 0 ).rgb();
}
else if ( colorScheme == QskSkin::DarkScheme )
@ -1336,6 +1350,8 @@ QskMaterial3Theme::QskMaterial3Theme( QskSkin::ColorScheme colorScheme,
outline = m_palettes[ NeutralVariant ].toned( 60 ).rgb();
outlineVariant = m_palettes[ NeutralVariant ].toned( 30 ).rgb();
surfaceContainerHighest = m_palettes[ NeutralVariant ].toned( 22 ).rgb();
shadow = m_palettes[ Neutral ].toned( 0 ).rgb();
}

View File

@ -79,6 +79,8 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme
QRgb outline;
QRgb outlineVariant;
QRgb surfaceContainerHighest;
QRgb shadow;
QskShadowMetrics elevation0;

View File

@ -20,6 +20,7 @@
#include <QskPageIndicator.h>
#include <QskPopup.h>
#include <QskProgressBar.h>
#include <QskProgressRing.h>
#include <QskPushButton.h>
#include <QskRadioBox.h>
#include <QskScrollView.h>
@ -162,6 +163,7 @@ namespace
void setupPageIndicator();
void setupPopup();
void setupProgressBar();
void setupProgressRing();
void setupPushButton();
void setupRadioBox();
void setupScrollView();
@ -287,6 +289,7 @@ void Editor::setup()
setupPageIndicator();
setupPopup();
setupProgressBar();
setupProgressRing();
setupPushButton();
setupRadioBox();
setupScrollView();
@ -521,15 +524,35 @@ void Editor::setupProgressBar()
using A = QskAspect;
using Q = QskProgressBar;
for ( auto subControl : { Q::Groove, Q::Bar } )
for ( auto subControl : { Q::Groove, Q::Fill } )
{
setMetric( subControl | A::Size, 6 );
setPadding( subControl, 0 );
setBoxShape( subControl, 4 );
}
setGradient( Q::Groove, m_pal.darker200 );
setGradient( Q::Bar, m_pal.highlighted );
setGradient( Q::Groove, m_pal.lighter110 );
setGradient( Q::Fill, m_pal.highlighted );
}
void Editor::setupProgressRing()
{
using A = QskAspect;
using Q = QskProgressRing;
for ( auto subControl : { Q::Groove, Q::Fill } )
{
setMetric( subControl | A::Size, 6 );
setPadding( subControl, 0 );
setBoxShape( subControl, 4 );
}
setArcMetrics( Q::Groove, 90, -360, 6 );
setGradient( Q::Groove, m_pal.lighter110 );
setStrutSize( Q::Fill, { 60, 60 } );
setGradient( Q::Fill, m_pal.highlighted );
setArcMetrics( Q::Fill, 90, -360, 6 );
}
void Editor::setupFocusIndicator()

View File

@ -196,10 +196,14 @@ list(APPEND HEADERS
controls/QskPanGestureRecognizer.h
controls/QskPopup.h
controls/QskPopupSkinlet.h
controls/QskPushButton.h
controls/QskPushButtonSkinlet.h
controls/QskProgressBar.h
controls/QskProgressBarSkinlet.h
controls/QskProgressIndicator.h
controls/QskProgressIndicatorSkinlet.h
controls/QskProgressRing.h
controls/QskProgressRingSkinlet.h
controls/QskPushButton.h
controls/QskPushButtonSkinlet.h
controls/QskQuick.h
controls/QskQuickItem.h
controls/QskRadioBox.h
@ -294,10 +298,14 @@ list(APPEND SOURCES
controls/QskPanGestureRecognizer.cpp
controls/QskPopup.cpp
controls/QskPopupSkinlet.cpp
controls/QskPushButton.cpp
controls/QskPushButtonSkinlet.cpp
controls/QskProgressBar.cpp
controls/QskProgressBarSkinlet.cpp
controls/QskProgressIndicator.cpp
controls/QskProgressIndicatorSkinlet.cpp
controls/QskProgressRing.cpp
controls/QskProgressRingSkinlet.cpp
controls/QskPushButton.cpp
controls/QskPushButtonSkinlet.cpp
controls/QskQuick.cpp
controls/QskQuickItem.cpp
controls/QskQuickItemPrivate.cpp

View File

@ -6,91 +6,30 @@
#include "QskProgressBar.h"
#include "QskIntervalF.h"
#include "QskFunctions.h"
#include "QskAnimator.h"
#include "QskAspect.h"
QSK_SUBCONTROL( QskProgressBar, Groove )
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
{
if ( m_progressBar->setPositionHint( QskProgressBar::Bar, value ) )
m_progressBar->update();
}
private:
QskProgressBar* m_progressBar;
};
}
QSK_SUBCONTROL( QskProgressBar, Fill )
class QskProgressBar::PrivateData
{
public:
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;
bool hasOrigin = false;
bool isIndeterminate = false;
Qt::Orientation orientation;
};
QskProgressBar::QskProgressBar( Qt::Orientation orientation,
qreal min, qreal max, QQuickItem* parent )
: QskBoundedControl( min, max, parent )
: Inherited( min, max, parent )
, m_data( new PrivateData )
{
m_data->orientation = orientation;
m_data->value = minimum();
if ( orientation == Qt::Horizontal )
initSizePolicy( QskSizePolicy::MinimumExpanding, QskSizePolicy::Fixed );
else
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::MinimumExpanding );
connect( this, &QskBoundedControl::boundariesChanged,
this, &QskProgressBar::adjustValue );
setSubcontrolProxy( Inherited::Groove, Groove );
setSubcontrolProxy( Inherited::Fill, Fill );
}
QskProgressBar::QskProgressBar( Qt::Orientation orientation, QQuickItem* parent )
@ -115,7 +54,12 @@ QskProgressBar::QskProgressBar( QQuickItem* parent )
QskProgressBar::~QskProgressBar()
{
delete m_data->animator;
}
QskAspect::Variation QskProgressBar::effectiveVariation() const
{
// so you can define different hints depending on the orientation
return static_cast< QskAspect::Variation >( m_data->orientation );
}
Qt::Orientation QskProgressBar::orientation() const
@ -137,163 +81,4 @@ 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::Variation QskProgressBar::effectiveVariation() const
{
// so you can define different hints depending on the orientation
return static_cast< QskAspect::Variation >( m_data->orientation );
}
void QskProgressBar::setBarGradient( const QskGradient& gradient )
{
setGradientHint( Bar, gradient );
}
void QskProgressBar::resetBarGradient()
{
resetColor( Bar );
}
QskGradient QskProgressBar::barGradient() const
{
return gradientHint( QskProgressBar::Bar );
}
void QskProgressBar::setExtent( qreal extent )
{
if ( extent < 0.0 )
extent = 0.0;
if ( setMetric( Groove | QskAspect::Size, extent ) )
Q_EMIT extentChanged( extent );
}
void QskProgressBar::resetExtent()
{
if ( resetMetric( Groove | QskAspect::Size ) )
Q_EMIT extentChanged( extent() );
}
qreal QskProgressBar::extent() const
{
auto grooveSize = metric( Groove | QskAspect::Size );
auto barSize = metric( Bar | QskAspect::Size );
return qMax( grooveSize, barSize );
}
void QskProgressBar::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 QskProgressBar::resetOrigin()
{
if ( m_data->hasOrigin )
{
m_data->hasOrigin = false;
update();
Q_EMIT originChanged( origin() );
}
}
qreal QskProgressBar::origin() const
{
if ( m_data->hasOrigin )
{
return boundedValue( m_data->origin );
}
return minimum();
}
void QskProgressBar::setValue( qreal value )
{
if ( isComponentComplete() )
value = boundedValue( value );
setValueInternal( value );
}
qreal QskProgressBar::value() const
{
return m_data->value;
}
void QskProgressBar::setValueAsRatio( qreal ratio )
{
ratio = qBound( 0.0, ratio, 1.0 );
setValue( minimum() + ratio * boundaryLength() );
}
qreal QskProgressBar::valueAsRatio() const
{
return valueAsRatio( m_data->value );
}
void QskProgressBar::componentComplete()
{
Inherited::componentComplete();
adjustValue();
}
void QskProgressBar::adjustValue()
{
if ( isComponentComplete() )
setValueInternal( boundedValue( m_data->value ) );
}
void QskProgressBar::setValueInternal( qreal value )
{
if ( !qskFuzzyCompare( value, m_data->value ) )
{
m_data->value = value;
Q_EMIT valueChanged( value );
update();
}
}
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"

View File

@ -6,34 +6,19 @@
#ifndef QSK_PROGRESS_BAR_H
#define QSK_PROGRESS_BAR_H
#include "QskBoundedControl.h"
#include "QskProgressIndicator.h"
class QskIntervalF;
class QSK_EXPORT QskProgressBar : public QskBoundedControl
class QSK_EXPORT QskProgressBar : public QskProgressIndicator
{
Q_OBJECT
Q_PROPERTY( Qt::Orientation orientation READ orientation
WRITE setOrientation NOTIFY orientationChanged )
Q_PROPERTY( qreal extent READ extent
WRITE setExtent RESET resetExtent NOTIFY extentChanged )
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;
using Inherited = QskProgressIndicator;
public:
QSK_SUBCONTROLS( Groove, Bar )
QSK_SUBCONTROLS( Groove, Fill )
QskProgressBar( Qt::Orientation, QQuickItem* parent = nullptr );
QskProgressBar( Qt::Orientation, qreal min, qreal max, QQuickItem* parent = nullptr );
@ -43,50 +28,15 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
~QskProgressBar() override;
QskAspect::Variation effectiveVariation() const override;
Qt::Orientation orientation() const;
void setOrientation( Qt::Orientation orientation );
bool isIndeterminate() const;
void setIndeterminate( bool on = true );
QskAspect::Variation effectiveVariation() const override;
void setBarGradient( const QskGradient& );
void resetBarGradient();
QskGradient barGradient() const;
void setExtent( qreal );
void resetExtent();
qreal extent() const;
void resetOrigin();
qreal origin() const;
qreal value() const;
qreal valueAsRatio() const; // [0.0, 1.0]
using QskBoundedControl::valueAsRatio;
public Q_SLOTS:
void setValue( qreal );
void setValueAsRatio( qreal );
void setOrigin( qreal );
Q_SIGNALS:
void orientationChanged( Qt::Orientation );
void extentChanged( qreal );
void indeterminateChanged( bool );
void valueChanged( qreal );
void originChanged( qreal );
protected:
void componentComplete() override;
void itemChange( ItemChange, const ItemChangeData& ) override;
private:
void setValueInternal( qreal value );
void adjustBoundaries( bool increasing );
void adjustValue();
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};

View File

@ -7,51 +7,54 @@
#include "QskProgressBar.h"
#include "QskIntervalF.h"
#include "QskBoxBorderMetrics.h"
#include "QskGradientDirection.h"
#include <qeasingcurve.h>
#include <cmath>
static inline QskIntervalF qskBarInterval( const QskProgressBar* bar )
using Q = QskProgressBar;
namespace
{
qreal pos1, pos2;
if ( bar->isIndeterminate() )
QskIntervalF qskFillInterval( const Q* bar )
{
const auto pos = bar->positionHint( QskProgressBar::Bar );
qreal pos1, pos2;
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->layoutMirroring() )
if ( bar->isIndeterminate() )
{
pos1 = 1.0 - pos1;
pos2 = 1.0 - pos2;
const auto pos = bar->positionHint( QskProgressIndicator::Fill );
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->layoutMirroring() )
{
pos1 = 1.0 - pos1;
pos2 = 1.0 - pos2;
}
}
if ( pos1 > pos2 )
std::swap( pos1, pos2 );
return QskIntervalF( pos1, pos2 );
}
if ( pos1 > pos2 )
std::swap( pos1, pos2 );
return QskIntervalF( pos1, pos2 );
}
QskProgressBarSkinlet::QskProgressBarSkinlet( QskSkin* skin )
: QskSkinlet( skin )
: Inherited( skin )
{
setNodeRoles( { GrooveRole, BarRole } );
}
QskProgressBarSkinlet::~QskProgressBarSkinlet()
@ -62,7 +65,6 @@ QRectF QskProgressBarSkinlet::subControlRect(
const QskSkinnable* skinnable, const QRectF& contentsRect,
QskAspect::Subcontrol subControl ) const
{
using Q = QskProgressBar;
const auto bar = static_cast< const Q* >( skinnable );
if( subControl == Q::Groove )
@ -84,7 +86,7 @@ QRectF QskProgressBarSkinlet::subControlRect(
return rect;
}
if( subControl == Q::Bar )
if( subControl == Q::Fill )
{
return barRect( bar );
}
@ -92,30 +94,18 @@ QRectF QskProgressBarSkinlet::subControlRect(
return Inherited::subControlRect( skinnable, contentsRect, subControl );
}
QSGNode* QskProgressBarSkinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
QSGNode* QskProgressBarSkinlet::updateGrooveNode(
const QskProgressIndicator* indicator, QSGNode* node ) const
{
switch( nodeRole )
{
case GrooveRole:
{
return updateBoxNode( skinnable, node, QskProgressBar::Groove );
}
case BarRole:
{
const auto bar = static_cast< const QskProgressBar* >( skinnable );
return updateBarNode( bar, node );
}
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
return updateBoxNode( indicator, node, Q::Groove );
}
QSGNode* QskProgressBarSkinlet::updateBarNode(
const QskProgressBar* bar, QSGNode* node ) const
QSGNode* QskProgressBarSkinlet::updateFillNode(
const QskProgressIndicator* indicator, QSGNode* node ) const
{
const auto subControl = QskProgressBar::Bar;
const auto bar = static_cast< const Q* >( indicator );
const auto subControl = Q::Fill;
const auto rect = bar->subControlRect( subControl );
if ( rect.isEmpty() )
@ -139,26 +129,27 @@ QSGNode* QskProgressBarSkinlet::updateBarNode(
not supporting this yet. TODO ...
*/
const auto intv = qskBarInterval( bar );
const auto intv = qskFillInterval( bar );
const auto stops = qskExtractedGradientStops( gradient.stops(),
intv.lowerBound(), intv.upperBound() );
gradient.setStops( stops );
gradient.setLinearDirection( bar->orientation() );
gradient.setLinearDirection( static_cast< Qt::Orientation >( bar->orientation() ) );
if ( bar->orientation() == Qt::Vertical || bar->layoutMirroring() )
gradient.reverse();
}
return updateBoxNode( bar, node, rect, gradient, subControl );
return updateBoxNode( indicator, node, rect, gradient, subControl );
}
QRectF QskProgressBarSkinlet::barRect( const QskProgressBar* bar ) const
QRectF QskProgressBarSkinlet::barRect( const Q* bar ) const
{
using Q = QskProgressBar;
const auto subControl = Q::Groove;
const auto barSize = bar->metric( Q::Bar | QskAspect::Size );
const auto barSize = bar->metric( Q::Fill | QskAspect::Size );
auto rect = bar->subControlRect( subControl );
if ( bar->orientation() == Qt::Horizontal )
@ -179,7 +170,7 @@ QRectF QskProgressBarSkinlet::barRect( const QskProgressBar* bar ) const
rect = rect.marginsRemoved( m );
const auto intv = qskBarInterval( bar );
const auto intv = qskFillInterval( bar );
if( bar->orientation() == Qt::Horizontal )
{
@ -205,7 +196,7 @@ QSizeF QskProgressBarSkinlet::sizeHint( const QskSkinnable* skinnable,
if ( which != Qt::PreferredSize )
return QSizeF();
const auto bar = static_cast< const QskProgressBar* >( skinnable );
const auto bar = static_cast< const Q* >( skinnable );
const auto extent = bar->extent();

View File

@ -6,25 +6,17 @@
#ifndef QSK_PROGRESS_BAR_SKINLET_H
#define QSK_PROGRESS_BAR_SKINLET_H
#include "QskSkinlet.h"
#include "QskProgressIndicatorSkinlet.h"
class QskProgressBar;
class QSK_EXPORT QskProgressBarSkinlet : public QskSkinlet
class QSK_EXPORT QskProgressBarSkinlet : public QskProgressIndicatorSkinlet
{
Q_GADGET
using Inherited = QskSkinlet;
using Inherited = QskProgressIndicatorSkinlet;
public:
enum NodeRole
{
GrooveRole,
BarRole,
RoleCount
};
Q_INVOKABLE QskProgressBarSkinlet( QskSkin* = nullptr );
~QskProgressBarSkinlet() override;
@ -35,11 +27,10 @@ class QSK_EXPORT QskProgressBarSkinlet : public QskSkinlet
Qt::SizeHint, const QSizeF& ) const override;
protected:
QSGNode* updateSubNode( const QskSkinnable*,
quint8 nodeRole, QSGNode* ) const override;
QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const override;
QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const override;
private:
QSGNode* updateBarNode( const QskProgressBar*, QSGNode* ) const;
QRectF barRect( const QskProgressBar* ) const;
};

View File

@ -0,0 +1,255 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskProgressIndicator.h"
#include "QskIntervalF.h"
#include "QskFunctions.h"
#include "QskAnimator.h"
#include "QskAspect.h"
QSK_SUBCONTROL( QskProgressIndicator, Groove )
QSK_SUBCONTROL( QskProgressIndicator, Fill )
namespace
{
class PositionAnimator : public QskAnimator
{
public:
PositionAnimator( QskProgressIndicator* indicator )
: m_indicator( indicator )
{
setAutoRepeat( true );
setDuration( 1300 );
setWindow( indicator->window() );
}
void advance( qreal value ) override
{
if ( m_indicator->setPositionHint( QskProgressIndicator::Fill, value ) )
m_indicator->update();
}
private:
QskProgressIndicator* m_indicator;
};
}
class QskProgressIndicator::PrivateData
{
public:
void updateIndeterminateAnimator( QskProgressIndicator* indicator )
{
if ( !isIndeterminate )
{
delete animator;
animator = nullptr;
return;
}
if ( indicator->window() && indicator->isVisible() )
{
if ( animator == nullptr )
animator = new PositionAnimator( indicator );
animator->start();
}
else
{
if ( animator )
animator->stop();
}
}
PositionAnimator* animator = nullptr;
qreal value = 0.0;
qreal origin = 0.0;
bool hasOrigin = false;
bool isIndeterminate = false;
};
QskProgressIndicator::QskProgressIndicator( qreal min, qreal max, QQuickItem* parent )
: QskBoundedControl( min, max, parent )
, m_data( new PrivateData )
{
m_data->value = minimum();
connect( this, &QskBoundedControl::boundariesChanged,
this, &QskProgressIndicator::adjustValue );
}
QskProgressIndicator::QskProgressIndicator( QQuickItem* parent )
: QskProgressIndicator( 0.0, 100.0, parent )
{
}
QskProgressIndicator::QskProgressIndicator( const QskIntervalF& boundaries, QQuickItem* parent )
: QskProgressIndicator( boundaries.lowerBound(), boundaries.upperBound(), parent )
{
}
QskProgressIndicator::~QskProgressIndicator()
{
delete m_data->animator;
}
bool QskProgressIndicator::isIndeterminate() const
{
return m_data->isIndeterminate;
}
void QskProgressIndicator::setIndeterminate( bool on )
{
if ( on == m_data->isIndeterminate )
return;
m_data->isIndeterminate = on;
m_data->updateIndeterminateAnimator( this );
update();
Q_EMIT indeterminateChanged( on );
}
void QskProgressIndicator::setFillGradient( const QskGradient& gradient )
{
setGradientHint( Fill, gradient );
}
void QskProgressIndicator::resetFillGradient()
{
resetColor( Fill );
}
QskGradient QskProgressIndicator::fillGradient() const
{
return gradientHint( Fill );
}
void QskProgressIndicator::setExtent( qreal extent )
{
if ( extent < 0.0 )
extent = 0.0;
if ( setMetric( Groove | QskAspect::Size, extent ) )
Q_EMIT extentChanged( extent );
}
void QskProgressIndicator::resetExtent()
{
if ( resetMetric( Groove | QskAspect::Size ) )
Q_EMIT extentChanged( extent() );
}
qreal QskProgressIndicator::extent() const
{
auto grooveSize = metric( Groove | QskAspect::Size );
auto fillSize = metric( Fill | QskAspect::Size );
return qMax( grooveSize, fillSize );
}
void QskProgressIndicator::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 QskProgressIndicator::resetOrigin()
{
if ( m_data->hasOrigin )
{
m_data->hasOrigin = false;
update();
Q_EMIT originChanged( origin() );
}
}
qreal QskProgressIndicator::origin() const
{
if ( m_data->hasOrigin )
{
return boundedValue( m_data->origin );
}
return minimum();
}
void QskProgressIndicator::setValue( qreal value )
{
if ( isComponentComplete() )
value = boundedValue( value );
setValueInternal( value );
}
qreal QskProgressIndicator::value() const
{
return m_data->value;
}
void QskProgressIndicator::setValueAsRatio( qreal ratio )
{
ratio = qBound( 0.0, ratio, 1.0 );
setValue( minimum() + ratio * boundaryLength() );
}
qreal QskProgressIndicator::valueAsRatio() const
{
return valueAsRatio( m_data->value );
}
void QskProgressIndicator::componentComplete()
{
Inherited::componentComplete();
adjustValue();
}
void QskProgressIndicator::adjustValue()
{
if ( isComponentComplete() )
setValueInternal( boundedValue( m_data->value ) );
}
void QskProgressIndicator::setValueInternal( qreal value )
{
if ( !qskFuzzyCompare( value, m_data->value ) )
{
m_data->value = value;
Q_EMIT valueChanged( value );
update();
}
}
void QskProgressIndicator::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_QskProgressIndicator.cpp"

View File

@ -0,0 +1,83 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_PROGRESS_INDICATOR_H
#define QSK_PROGRESS_INDICATOR_H
#include "QskBoundedControl.h"
class QskIntervalF;
class QSK_EXPORT QskProgressIndicator : public QskBoundedControl
{
Q_OBJECT
Q_PROPERTY( qreal extent READ extent
WRITE setExtent RESET resetExtent NOTIFY extentChanged )
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, Fill )
QskProgressIndicator( QQuickItem* parent = nullptr );
QskProgressIndicator( qreal min, qreal max, QQuickItem* parent = nullptr );
QskProgressIndicator( const QskIntervalF&, QQuickItem* parent = nullptr );
~QskProgressIndicator() override;
bool isIndeterminate() const;
void setIndeterminate( bool on = true );
void setFillGradient( const QskGradient& );
void resetFillGradient();
QskGradient fillGradient() const;
void setExtent( qreal );
void resetExtent();
qreal extent() const;
void resetOrigin();
qreal origin() const;
qreal value() const;
qreal valueAsRatio() const; // [0.0, 1.0]
using QskBoundedControl::valueAsRatio;
public Q_SLOTS:
void setValue( qreal );
void setValueAsRatio( qreal );
void setOrigin( qreal );
Q_SIGNALS:
void extentChanged( qreal );
void indeterminateChanged( bool );
void valueChanged( qreal );
void originChanged( qreal );
protected:
void componentComplete() override;
void itemChange( ItemChange, const ItemChangeData& ) override;
private:
void setValueInternal( qreal value );
void adjustBoundaries( bool increasing );
void adjustValue();
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
#endif

View File

@ -0,0 +1,40 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskProgressIndicatorSkinlet.h"
#include "QskProgressIndicator.h"
QskProgressIndicatorSkinlet::QskProgressIndicatorSkinlet( QskSkin* skin )
: Inherited( skin )
{
setNodeRoles( { GrooveRole, FillRole } );
}
QskProgressIndicatorSkinlet::~QskProgressIndicatorSkinlet()
{
}
QSGNode* QskProgressIndicatorSkinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
{
const auto indicator = static_cast< const QskProgressIndicator* >( skinnable );
switch( nodeRole )
{
case GrooveRole:
{
return updateGrooveNode( indicator, node );
}
case FillRole:
{
return updateFillNode( indicator, node );
}
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
#include "moc_QskProgressIndicatorSkinlet.cpp"

View File

@ -0,0 +1,37 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_PROGRESS_INDICATOR_SKINLET_H
#define QSK_PROGRESS_INDICATOR_SKINLET_H
#include "QskSkinlet.h"
class QskProgressIndicator;
class QSK_EXPORT QskProgressIndicatorSkinlet : public QskSkinlet
{
using Inherited = QskSkinlet;
public:
enum NodeRole
{
GrooveRole,
FillRole,
RoleCount
};
QskProgressIndicatorSkinlet( QskSkin* = nullptr );
~QskProgressIndicatorSkinlet() override;
protected:
QSGNode* updateSubNode( const QskSkinnable*,
quint8 nodeRole, QSGNode* ) const override;
virtual QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const = 0;
virtual QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const = 0;
};
#endif

View File

@ -0,0 +1,76 @@
/******************************************************************************
* QSkinny - Copyright (C) 2023 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskProgressRing.h"
#include "QskIntervalF.h"
QSK_SUBCONTROL( QskProgressRing, Groove )
QSK_SUBCONTROL( QskProgressRing, Fill )
class QskProgressRing::PrivateData
{
public:
int size : 2;
};
QskProgressRing::QskProgressRing( qreal min, qreal max, QQuickItem* parent )
: Inherited( min, max, parent )
, m_data( new PrivateData )
{
m_data->size = NormalSize;
setSubcontrolProxy( Inherited::Groove, Groove );
setSubcontrolProxy( Inherited::Fill, Fill );
}
QskProgressRing::QskProgressRing( QQuickItem* parent )
: QskProgressRing( 0.0, 100.0, parent )
{
}
QskProgressRing::QskProgressRing( const QskIntervalF& boundaries, QQuickItem* parent )
: QskProgressRing( boundaries.lowerBound(), boundaries.upperBound(), parent )
{
}
QskProgressRing::~QskProgressRing()
{
}
QskAspect::Variation QskProgressRing::effectiveVariation() const
{
switch( size() )
{
case SmallSize:
return QskAspect::Small;
case LargeSize:
return QskAspect::Large;
default:
return QskAspect::NoVariation;
}
}
void QskProgressRing::setSize( Size size )
{
if ( size != m_data->size )
{
m_data->size = size;
resetImplicitSize();
update();
Q_EMIT sizeChanged( size );
}
}
QskProgressRing::Size QskProgressRing::size() const
{
return static_cast< Size >( m_data->size );
}
#include "moc_QskProgressRing.cpp"

View File

@ -0,0 +1,50 @@
/******************************************************************************
* QSkinny - Copyright (C) 2023 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_PROGRESS_RING_H
#define QSK_PROGRESS_RING_H
#include "QskProgressIndicator.h"
class QSK_EXPORT QskProgressRing : public QskProgressIndicator
{
Q_OBJECT
Q_PROPERTY( Size size READ size
WRITE setSize NOTIFY sizeChanged )
using Inherited = QskProgressIndicator;
public:
QSK_SUBCONTROLS( Groove, Fill )
enum Size
{
SmallSize = -1,
NormalSize = 0,
LargeSize = 1
};
Q_ENUM( Size )
QskProgressRing( QQuickItem* parent = nullptr );
QskProgressRing( qreal min, qreal max, QQuickItem* parent = nullptr );
QskProgressRing( const QskIntervalF&, QQuickItem* parent = nullptr );
~QskProgressRing() override;
QskAspect::Variation effectiveVariation() const override;
void setSize( Size );
Size size() const;
Q_SIGNALS:
void sizeChanged( Size );
private:
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
#endif

View File

@ -0,0 +1,125 @@
/******************************************************************************
* QSkinny - Copyright (C) 2023 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskProgressRingSkinlet.h"
#include "QskArcMetrics.h"
#include "QskProgressRing.h"
#include "QskIntervalF.h"
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 )
{
}
QskProgressRingSkinlet::~QskProgressRingSkinlet()
{
}
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 Inherited::subControlRect( skinnable, contentsRect, subControl );
}
QSGNode* QskProgressRingSkinlet::updateGrooveNode(
const QskProgressIndicator* indicator, QSGNode* node ) const
{
return updateArcNode( indicator, node, Q::Groove );
}
QSGNode* QskProgressRingSkinlet::updateFillNode(
const QskProgressIndicator* indicator, QSGNode* node ) const
{
const auto ring = static_cast< const Q* >( indicator );
const auto subControl = Q::Fill;
const auto rect = ring->subControlRect( subControl );
if ( rect.isEmpty() )
return nullptr;
auto gradient = ring->gradientHint( subControl );
if ( !gradient.isVisible() )
return nullptr;
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 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();
return updateArcNode( ring, node, rect, gradient, startAngle, spanAngle, subControl );
}
QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,
Qt::SizeHint which, const QSizeF& ) const
{
if ( which != Qt::PreferredSize )
return QSizeF();
const auto ring = static_cast< const Q* >( skinnable );
const auto r = ring->strutSizeHint( Q::Fill );
return r;
}
#include "moc_QskProgressRingSkinlet.cpp"

View File

@ -0,0 +1,34 @@
/******************************************************************************
* QSkinny - Copyright (C) 2023 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_PROGRESS_RING_SKINLET_H
#define QSK_PROGRESS_RING_SKINLET_H
#include "QskProgressIndicatorSkinlet.h"
class QskProgressRing;
class QSK_EXPORT QskProgressRingSkinlet : public QskProgressIndicatorSkinlet
{
Q_GADGET
using Inherited = QskProgressIndicatorSkinlet;
public:
Q_INVOKABLE QskProgressRingSkinlet( QskSkin* = nullptr );
~QskProgressRingSkinlet() override;
QRectF subControlRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol ) const override;
QSizeF sizeHint( const QskSkinnable*,
Qt::SizeHint, const QSizeF& ) const override;
protected:
QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const override;
QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const override;
};
#endif

View File

@ -53,6 +53,9 @@
#include "QskProgressBar.h"
#include "QskProgressBarSkinlet.h"
#include "QskProgressRing.h"
#include "QskProgressRingSkinlet.h"
#include "QskRadioBox.h"
#include "QskRadioBoxSkinlet.h"
@ -178,6 +181,7 @@ QskSkin::QskSkin( QObject* parent )
declareSkinlet< QskTextLabel, QskTextLabelSkinlet >();
declareSkinlet< QskTextInput, QskTextInputSkinlet >();
declareSkinlet< QskProgressBar, QskProgressBarSkinlet >();
declareSkinlet< QskProgressRing, QskProgressRingSkinlet >();
declareSkinlet< QskRadioBox, QskRadioBoxSkinlet >();
const QFont font = QGuiApplication::font();