code duplication eliminated

This commit is contained in:
Uwe Rathmann 2024-09-04 17:08:40 +02:00
parent 11df0bb694
commit 86942d4226
7 changed files with 63 additions and 103 deletions

View File

@ -5,13 +5,13 @@
#pragma once
#include <QskProgressIndicator.h>
#include <QskProgressRing.h>
class CircularProgressBar : public QskProgressIndicator
class CircularProgressBar : public QskProgressRing
{
Q_OBJECT
using Inherited = QskProgressIndicator;
using Inherited = QskProgressRing;
public:
CircularProgressBar( qreal min, qreal max, QQuickItem* parent = nullptr );

View File

@ -4,12 +4,11 @@
*****************************************************************************/
#include "CircularProgressBarSkinlet.h"
#include "CircularProgressBar.h"
#include <QskProgressIndicator.h>
CircularProgressBarSkinlet::CircularProgressBarSkinlet( QskSkin* skin )
: QskSkinlet( skin )
: Inherited( skin )
{
setNodeRoles( { GrooveRole, BarRole } );
}
CircularProgressBarSkinlet::~CircularProgressBarSkinlet()
@ -22,28 +21,4 @@ QRectF CircularProgressBarSkinlet::subControlRect(
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::Fill );
}
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
#include "moc_CircularProgressBarSkinlet.cpp"

View File

@ -5,32 +5,19 @@
#pragma once
#include <QskSkinlet.h>
#include <QskProgressRingSkinlet.h>
class CircularProgressBar;
class CircularProgressBarSkinlet : public QskSkinlet
class CircularProgressBarSkinlet : public QskProgressRingSkinlet
{
Q_GADGET
using Inherited = QskSkinlet;
using Inherited = QskProgressRingSkinlet;
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;
};

View File

@ -121,17 +121,16 @@ void Skin::initHints()
ed.setColor( TopBarItem::Item3 | QskAspect::TextColor, 0xfff99055 );
ed.setColor( TopBarItem::Item4 | QskAspect::TextColor, 0xff6776ff );
// 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.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 );
// the span angle will be set in the progress bar, we just give a dummy
// value here:
ed.setArcMetrics( CircularProgressBar::Fill, 90, -180, 8.53 );
ed.setArcMetrics( CircularProgressBar::Fill, 90, -360, 8.53 );
ed.setFontRole( TimeTitleLabel::Text, { QskFontRole::Caption, QskFontRole::High } );

View File

@ -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;

View File

@ -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,21 +23,17 @@ 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 ring = static_cast< const Q* >( skinnable );
const auto size = ring->strutSizeHint( Q::Fill );
auto rect = contentsRect;
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() );
@ -90,22 +61,29 @@ 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 );
}
@ -116,10 +94,28 @@ QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,
if ( which != Qt::PreferredSize )
return QSizeF();
const auto ring = static_cast< const Q* >( skinnable );
return skinnable->strutSizeHint( Q::Fill );
}
const auto r = ring->strutSizeHint( Q::Fill );
return r;
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"

View File

@ -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