progress indicators: Update to newest M3 spec
This commit is contained in:
parent
a2719b4ccd
commit
35eb98292e
|
@ -486,22 +486,21 @@ void Editor::setupProgressBar()
|
|||
using A = QskAspect;
|
||||
using Q = QskProgressBar;
|
||||
|
||||
auto size = 4_dp;
|
||||
|
||||
for ( auto subControl : { Q::Groove, Q::Fill } )
|
||||
{
|
||||
setMetric( subControl | A::Size, size );
|
||||
setPadding( subControl, 0 );
|
||||
|
||||
setBoxShape( subControl, 0 );
|
||||
setBoxBorderMetrics( subControl, 0 );
|
||||
setBoxShape( subControl, { 100, Qt::RelativeSize } );
|
||||
setMetric( subControl | A::Size, 4_dp );
|
||||
}
|
||||
|
||||
setMetric( Q::Groove | A::Size, size );
|
||||
setGradient( Q::Groove, m_pal.surfaceContainerHighest );
|
||||
|
||||
setGradient( Q::Groove | Q::Disabled, m_pal.onSurface12 );
|
||||
|
||||
setStrutSize( Q::GrooveStopIndicator, { 4_dp, 4_dp } );
|
||||
setBoxShape( Q::GrooveStopIndicator, { 100, Qt::RelativeSize } );
|
||||
setGradient( Q::GrooveStopIndicator, m_pal.primary );
|
||||
setGradient( Q::GrooveStopIndicator | Q::Disabled, m_pal.onSurface38 );
|
||||
|
||||
setSpacing( Q::Fill, 4_dp );
|
||||
setGradient( Q::Fill, m_pal.primary );
|
||||
setGradient( Q::Fill | Q::Disabled, m_pal.onSurface38 );
|
||||
}
|
||||
|
@ -510,9 +509,15 @@ void Editor::setupProgressRing()
|
|||
{
|
||||
using Q = QskProgressRing;
|
||||
|
||||
setArcMetrics( Q::Groove, 90, -360, 4_dp );
|
||||
setGradient( Q::Groove, m_pal.surfaceContainerHighest );
|
||||
setGradient( Q::Groove | Q::Disabled, m_pal.onSurface12 );
|
||||
|
||||
setSpacing( Q::Fill, 10 );
|
||||
setStrutSize( Q::Fill, { 48_dp, 48_dp } );
|
||||
setGradient( Q::Fill, m_pal.primary );
|
||||
setArcMetrics( Q::Fill, 90, -360, 4_dp );
|
||||
setGradient( Q::Fill, m_pal.primary );
|
||||
setGradient( Q::Fill | Q::Disabled, m_pal.onSurface38 );
|
||||
}
|
||||
|
||||
void Editor::setupRadioBox()
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
QSK_SUBCONTROL( QskProgressBar, Groove )
|
||||
QSK_SUBCONTROL( QskProgressBar, Fill )
|
||||
QSK_SUBCONTROL( QskProgressBar, GrooveStopIndicator )
|
||||
|
||||
class QskProgressBar::PrivateData
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ class QSK_EXPORT QskProgressBar : public QskProgressIndicator
|
|||
using Inherited = QskProgressIndicator;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Groove, Fill )
|
||||
QSK_SUBCONTROLS( Groove, Fill, GrooveStopIndicator )
|
||||
|
||||
QskProgressBar( Qt::Orientation, QQuickItem* parent = nullptr );
|
||||
QskProgressBar( Qt::Orientation, qreal min, qreal max, QQuickItem* parent = nullptr );
|
||||
|
|
|
@ -15,6 +15,26 @@ using Q = QskProgressBar;
|
|||
|
||||
namespace
|
||||
{
|
||||
QRectF qskFullGrooveRect( const QskProgressBar* bar )
|
||||
{
|
||||
const auto grooveSize = bar->metric( Q::Groove | QskAspect::Size );
|
||||
|
||||
auto rect = bar->contentsRect();
|
||||
|
||||
if ( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
rect.setY( rect.y() + 0.5 * ( rect.height() - grooveSize ) );
|
||||
rect.setHeight( grooveSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setX( rect.x() + 0.5 * ( rect.width() - grooveSize ) );
|
||||
rect.setWidth( grooveSize );
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
QskIntervalF qskFillInterval( const QskProgressIndicator* indicator )
|
||||
{
|
||||
qreal pos1, pos2;
|
||||
|
@ -37,6 +57,7 @@ namespace
|
|||
}
|
||||
|
||||
auto bar = static_cast< const QskProgressBar* >( indicator );
|
||||
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
if ( bar->layoutMirroring() )
|
||||
|
@ -51,11 +72,17 @@ namespace
|
|||
|
||||
return QskIntervalF( pos1, pos2 );
|
||||
}
|
||||
|
||||
inline bool qskIsContiguous( const QskProgressBar* bar )
|
||||
{
|
||||
return qFuzzyIsNull( bar->spacingHint( Q::Fill ) );
|
||||
}
|
||||
}
|
||||
|
||||
QskProgressBarSkinlet::QskProgressBarSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
setNodeRoles( { GrooveRole, FillRole, GrooveStopIndicatorRole } );
|
||||
}
|
||||
|
||||
QskProgressBarSkinlet::~QskProgressBarSkinlet()
|
||||
|
@ -68,37 +95,46 @@ QRectF QskProgressBarSkinlet::subControlRect(
|
|||
{
|
||||
const auto bar = static_cast< const Q* >( skinnable );
|
||||
|
||||
if( subControl == Q::Groove )
|
||||
{
|
||||
const auto grooveSize = bar->metric( Q::Groove | QskAspect::Size );
|
||||
|
||||
auto rect = contentsRect;
|
||||
if ( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
rect.setY( rect.y() + 0.5 * ( rect.height() - grooveSize ) );
|
||||
rect.setHeight( grooveSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setX( rect.x() + 0.5 * ( rect.width() - grooveSize ) );
|
||||
rect.setWidth( grooveSize );
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
if( subControl == Q::Fill )
|
||||
{
|
||||
return barRect( bar );
|
||||
}
|
||||
|
||||
if( subControl == Q::GrooveStopIndicator )
|
||||
{
|
||||
return grooveStopIndicatorRect( bar );
|
||||
}
|
||||
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressBarSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
const auto bar = static_cast< const Q* >( skinnable );
|
||||
|
||||
switch( nodeRole )
|
||||
{
|
||||
case GrooveStopIndicatorRole:
|
||||
{
|
||||
if( bar->isIndeterminate() || bar->hasOrigin() )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return updateBoxNode( skinnable, node, Q::GrooveStopIndicator );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressBarSkinlet::updateGrooveNode(
|
||||
const QskProgressIndicator* indicator, QSGNode* node ) const
|
||||
{
|
||||
return updateBoxNode( indicator, node, Q::Groove );
|
||||
return updateSeriesNode( indicator, Q::Groove, node );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressBarSkinlet::updateFillNode(
|
||||
|
@ -146,12 +182,21 @@ QSGNode* QskProgressBarSkinlet::updateFillNode(
|
|||
return updateBoxNode( indicator, node, rect, gradient, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressBarSkinlet::updateSampleNode( const QskSkinnable* skinnable,
|
||||
QskAspect::Subcontrol subControl, int index, QSGNode* node ) const
|
||||
{
|
||||
const auto bar = static_cast< const QskProgressBar* >( skinnable );
|
||||
const auto rect = sampleRect( bar, bar->contentsRect(), subControl, index );
|
||||
|
||||
return updateBoxNode( skinnable, node, rect, subControl );
|
||||
}
|
||||
|
||||
QRectF QskProgressBarSkinlet::barRect( const Q* bar ) const
|
||||
{
|
||||
const auto subControl = Q::Groove;
|
||||
|
||||
const auto barSize = bar->metric( Q::Fill | QskAspect::Size );
|
||||
auto rect = bar->subControlRect( subControl );
|
||||
auto rect = qskFullGrooveRect( bar );
|
||||
|
||||
if ( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
|
@ -207,4 +252,70 @@ QSizeF QskProgressBarSkinlet::sizeHint( const QskSkinnable* skinnable,
|
|||
return QSizeF( extent, -1 );
|
||||
}
|
||||
|
||||
int QskProgressBarSkinlet::sampleCount( const QskSkinnable* skinnable, QskAspect::Subcontrol ) const
|
||||
{
|
||||
const auto bar = static_cast< const Q* >( skinnable );
|
||||
const auto samples = ( ( bar->isIndeterminate() || bar->hasOrigin() ) && !qskIsContiguous( bar ) ) ? 2 : 1;
|
||||
return samples;
|
||||
}
|
||||
|
||||
QRectF QskProgressBarSkinlet::sampleRect( const QskSkinnable* skinnable,
|
||||
const QRectF&, QskAspect::Subcontrol, int index ) const
|
||||
{
|
||||
const auto bar = static_cast< const Q* >( skinnable );
|
||||
const auto br = barRect( bar );
|
||||
QRectF rect = qskFullGrooveRect( bar );
|
||||
const auto spacing = bar->spacingHint( Q::Fill );
|
||||
const auto isContiguous = qskIsContiguous( bar );
|
||||
|
||||
if( isContiguous )
|
||||
{
|
||||
return rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
if( index == 0 )
|
||||
{
|
||||
rect.setLeft( br.right() + spacing );
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setRight( br.left() - spacing );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( index == 0 )
|
||||
{
|
||||
rect.setBottom( br.top() - spacing );
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setTop( br.bottom() + spacing );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
QRectF QskProgressBarSkinlet::grooveStopIndicatorRect( const QskProgressBar* bar ) const
|
||||
{
|
||||
auto rect = qskFullGrooveRect( bar );
|
||||
const auto size = bar->strutSizeHint( Q::GrooveStopIndicator );
|
||||
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
rect.setLeft( rect.right() - size.width() );
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setBottom( rect.top() + size.height() );
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
#include "moc_QskProgressBarSkinlet.cpp"
|
||||
|
|
|
@ -17,6 +17,11 @@ class QSK_EXPORT QskProgressBarSkinlet : public QskProgressIndicatorSkinlet
|
|||
using Inherited = QskProgressIndicatorSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole
|
||||
{
|
||||
GrooveStopIndicatorRole = Inherited::RoleCount,
|
||||
};
|
||||
|
||||
Q_INVOKABLE QskProgressBarSkinlet( QskSkin* = nullptr );
|
||||
~QskProgressBarSkinlet() override;
|
||||
|
||||
|
@ -26,12 +31,23 @@ class QSK_EXPORT QskProgressBarSkinlet : public QskProgressIndicatorSkinlet
|
|||
QSizeF sizeHint( const QskSkinnable*,
|
||||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
int sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const override;
|
||||
|
||||
QRectF sampleRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, int index ) 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;
|
||||
|
||||
QSGNode* updateSampleNode( const QskSkinnable*,
|
||||
QskAspect::Subcontrol, int index, QSGNode* ) const override;
|
||||
|
||||
private:
|
||||
QRectF barRect( const QskProgressBar* ) const;
|
||||
QRectF grooveStopIndicatorRect( const QskProgressBar* ) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -189,6 +189,11 @@ qreal QskProgressIndicator::origin() const
|
|||
return minimum();
|
||||
}
|
||||
|
||||
bool QskProgressIndicator::hasOrigin() const
|
||||
{
|
||||
return m_data->hasOrigin;
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setValue( qreal value )
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
|
|
|
@ -51,6 +51,7 @@ class QSK_EXPORT QskProgressIndicator : public QskBoundedControl
|
|||
|
||||
void resetOrigin();
|
||||
qreal origin() const;
|
||||
bool hasOrigin() const;
|
||||
|
||||
qreal value() const;
|
||||
qreal valueAsRatio() const; // [0.0, 1.0]
|
||||
|
|
|
@ -10,6 +10,49 @@
|
|||
|
||||
using Q = QskProgressRing;
|
||||
|
||||
namespace
|
||||
{
|
||||
inline bool qskIsContiguous( const QskProgressRing* ring )
|
||||
{
|
||||
return qFuzzyIsNull( ring->spacingHint( Q::Fill ) );
|
||||
}
|
||||
|
||||
QskIntervalF fillInterval( const QskProgressIndicator* indicator )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
inline QskArcMetrics fillAngles( const QskProgressRing* ring )
|
||||
{
|
||||
const auto intv = fillInterval( ring );
|
||||
|
||||
const auto metrics = ring->arcMetricsHint( Q::Fill );
|
||||
|
||||
if ( metrics.isNull() )
|
||||
return {};
|
||||
|
||||
const auto startAngle = metrics.startAngle() + intv.lowerBound() * metrics.spanAngle();
|
||||
const auto spanAngle = intv.upperBound() * metrics.spanAngle();
|
||||
|
||||
return QskArcMetrics( startAngle, spanAngle, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
QskProgressRingSkinlet::QskProgressRingSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
|
@ -32,7 +75,22 @@ QRectF QskProgressRingSkinlet::subControlRect(
|
|||
QSGNode* QskProgressRingSkinlet::updateGrooveNode(
|
||||
const QskProgressIndicator* indicator, QSGNode* node ) const
|
||||
{
|
||||
return updateArcNode( indicator, node, Q::Groove );
|
||||
const auto ring = static_cast< const Q* >( indicator );
|
||||
|
||||
if( qskIsContiguous( ring ) )
|
||||
{
|
||||
return updateArcNode( indicator, node, Q::Groove );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto angles = fillAngles( ring );
|
||||
const auto spacing = ring->spacingHint( Q::Fill );
|
||||
const auto sign = ( angles.spanAngle() > 0 ) ? 1 : -1;
|
||||
const auto startAngle = angles.endAngle() + sign * spacing;
|
||||
const auto spanAngle = sign * 360 - angles.spanAngle() - sign * 2 * spacing;
|
||||
|
||||
return updateArcNode( ring, node, startAngle, spanAngle, Q::Groove );
|
||||
}
|
||||
}
|
||||
|
||||
QSGNode* QskProgressRingSkinlet::updateFillNode(
|
||||
|
@ -67,10 +125,9 @@ QSGNode* QskProgressRingSkinlet::updateFillNode(
|
|||
gradient.reverse();
|
||||
}
|
||||
|
||||
const auto startAngle = metrics.startAngle() + intv.lowerBound() * metrics.spanAngle();
|
||||
const auto spanAngle = intv.upperBound() * metrics.spanAngle();
|
||||
const auto angles = fillAngles( ring );
|
||||
|
||||
return updateArcNode( ring, node, rect, gradient, startAngle, spanAngle, subControl );
|
||||
return updateArcNode( ring, node, rect, gradient, angles.startAngle(), angles.spanAngle(), subControl );
|
||||
}
|
||||
|
||||
QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
|
@ -95,25 +152,4 @@ QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,
|
|||
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"
|
||||
|
|
|
@ -29,8 +29,6 @@ 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