Skip to content

Commit

Permalink
slider ticks - not only for M3
Browse files Browse the repository at this point in the history
  • Loading branch information
uwerat committed Nov 21, 2024
1 parent d04c030 commit 9a5dd88
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 86 deletions.
12 changes: 6 additions & 6 deletions designsystems/material3/QskMaterial3Skin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,15 +927,15 @@ void Editor::setupSlider()
setBoxShape( Q::Groove, 100, Qt::RelativeSize );
setBoxShape( Q::Fill, 100, Qt::RelativeSize );

setStrutSize( Q::Ticks, { 4_dp, 4_dp } );
setBoxShape( Q::Ticks, 100, Qt::RelativeSize );
setStrutSize( Q::Tick, { 4_dp, 4_dp } );
setBoxShape( Q::Tick, 100, Qt::RelativeSize );

setGradient( Q::Ticks, m_pal.primary );
setGradient( Q::Ticks | Q::Disabled, m_pal.onSurface );
setGradient( Q::Tick, m_pal.primary );
setGradient( Q::Tick | Q::Disabled, m_pal.onSurface );

setGradient( Q::Ticks | SK::Filled, m_pal.secondaryContainer,
setGradient( Q::Tick | SK::Filled, m_pal.secondaryContainer,
{ QskStateCombination::CombinationNoState, Q::Focused | Q::Pressed } );
setGradient( Q::Ticks | SK::Filled | Q::Disabled, m_pal.inverseOnSurface );
setGradient( Q::Tick | SK::Filled | Q::Disabled, m_pal.inverseOnSurface );

for ( const auto variation : { A::Horizontal, A::Vertical } )
{
Expand Down
112 changes: 39 additions & 73 deletions designsystems/material3/QskMaterial3SliderSkinlet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,9 @@ QSK_SYSTEM_STATE( QskMaterial3SliderSkinlet, Filled, QskAspect::FirstUserState >

using Q = QskSlider;

static inline bool qskHasOrigin( const QskSlider* )
static inline bool qskHasBoundaryTicks( const QskSlider* slider )
{
return false; // TODO
}

static inline qreal qskTickValue( const QskSlider* slider, int index )
{
if( slider->isSnapping() && slider->stepSize() )
return slider->minimum() + index * slider->stepSize();

if ( qskHasOrigin( slider ) )
{
switch( index )
{
case 0:
return slider->minimum();

#if 0
case 1:
return slider->origin();
#endif
}
}

return slider->maximum();
return ( slider->graduationPolicy() == Qsk::Maybe ) && !slider->isSnapping();
}

QskMaterial3SliderSkinlet::QskMaterial3SliderSkinlet( QskSkin* skin )
Expand Down Expand Up @@ -82,7 +60,7 @@ QSGNode* QskMaterial3SliderSkinlet::updateSubNode(
case GrooveRole:
case FillRole:
{
auto clippedNode = QskSGNode::findChildNode( node, nodeRole );
auto clippedNode = QskSGNode::findChildNode( node, nodeRole );
clippedNode = Inherited::updateSubNode( skinnable, nodeRole, clippedNode );

if ( clippedNode )
Expand All @@ -102,11 +80,6 @@ QSGNode* QskMaterial3SliderSkinlet::updateSubNode(

return nullptr;
}

case TicksRole:
{
return updateSeriesNode( skinnable, Q::Ticks, node );
}
}

return Inherited::updateSubNode( skinnable, nodeRole, node );
Expand All @@ -115,77 +88,70 @@ QSGNode* QskMaterial3SliderSkinlet::updateSubNode(
int QskMaterial3SliderSkinlet::sampleCount( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl ) const
{
if ( subControl == Q::Ticks )
if ( subControl == Q::Tick )
{
const auto slider = static_cast< const QskSlider* >( skinnable );

if( slider->isSnapping() && slider->stepSize() )
return qCeil( slider->boundaryLength() / slider->stepSize() ) + 1;
if ( qskHasBoundaryTicks( slider ) )
{
const bool hasOrigin = false;

// min/origin/max or max
return qskHasOrigin( slider ) ? 3 : 1;
// min/origin/max or max
return hasOrigin ? 3 : 1;
}
}

return Inherited::sampleCount( skinnable, subControl );
}

QRectF QskMaterial3SliderSkinlet::sampleRect(
const QskSkinnable* skinnable, const QRectF& contentsRect,
QVariant QskMaterial3SliderSkinlet::sampleAt( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl, int index ) const
{
if ( subControl != Q::Ticks )
return Inherited::sampleRect( skinnable, contentsRect, subControl, index );

const auto slider = static_cast< const QskSlider* >( skinnable );
if ( subControl == Q::Tick )
{
const auto slider = static_cast< const QskSlider* >( skinnable );

const auto tickPos = slider->valueAsRatio( qskTickValue( slider, index ) );
if ( qskHasBoundaryTicks( slider ) )
{
switch( index )
{
case 1:
return slider->minimum();

const auto size = skinnable->strutSizeHint( Q::Ticks );
const auto r = subControlRect( skinnable, contentsRect, Q::Scale );
#if 0
case 2:
return slider->origin();
#endif

qreal x, y;
default:
return slider->maximum();
}

if( slider->orientation() == Qt::Horizontal )
{
x = tickPos * r.width() - 0.5 * size.width();
y = 0.5 * ( r.height() - size.height() );
}
else
{
y = r.height() - ( tickPos * r.height() ) - 0.5 * size.height();
x = 0.5 * ( r.width() - size.width() );
return QVariant();
}
}

return QRectF( r.x() + x, r.y() + y, size.width(), size.height() );
return Inherited::sampleAt( skinnable, subControl, index );
}

QskAspect::States QskMaterial3SliderSkinlet::sampleStates(
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index ) const
{
auto states = Inherited::sampleStates( skinnable, subControl, index );

if ( subControl == Q::Ticks )
{
const auto slider = static_cast< const QskSlider* >( skinnable );
if ( qskTickValue( slider, index ) <= slider->value() )
states |= QskMaterial3SliderSkinlet::Filled;
}

return states;
}

QSGNode* QskMaterial3SliderSkinlet::updateSampleNode( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl, int index, QSGNode* node ) const
{
if ( subControl == Q::Ticks )
if ( subControl == Q::Tick )
{
const auto slider = static_cast< const QskSlider* >( skinnable );
const auto rect = sampleRect( slider, slider->contentsRect(), subControl, index );
const auto tickValue = sampleAt( skinnable, subControl, index );
if ( tickValue.canConvert< qreal >() )
{
const auto slider = static_cast< const QskSlider* >( skinnable );

return updateBoxNode( skinnable, node, rect, subControl );
if ( tickValue.value< qreal >() <= slider->value() )
states |= QskMaterial3SliderSkinlet::Filled;
}
}

return Inherited::updateSampleNode( skinnable, subControl, index, node );
return states;
}

#include "moc_QskMaterial3SliderSkinlet.cpp"
7 changes: 2 additions & 5 deletions designsystems/material3/QskMaterial3SliderSkinlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,15 @@ class QskMaterial3SliderSkinlet : QskSliderSkinlet

int sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const override;

QRectF sampleRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, int index ) const override;
QVariant sampleAt( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const override;

QskAspect::States sampleStates( const QskSkinnable*,
QskAspect::Subcontrol, int ) const override;

protected:
QSGNode* updateSubNode( const QskSkinnable*,
quint8 nodeRole, QSGNode* ) const override;

QSGNode* updateSampleNode( const QskSkinnable*,
QskAspect::Subcontrol, int index, QSGNode* ) const override;
};

#endif
8 changes: 8 additions & 0 deletions src/common/QskNamespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ namespace Qsk
{
Q_NAMESPACE_EXPORT( QSK_EXPORT )

enum Policy
{
Maybe,
Always,
Never
};
Q_ENUM_NS( Policy )

enum Direction
{
LeftToRight,
Expand Down
65 changes: 64 additions & 1 deletion src/controls/QskSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,42 @@
#include "QskIntervalF.h"
#include "QskEvent.h"

#include <qmath.h>

QSK_SUBCONTROL( QskSlider, Panel )
QSK_SUBCONTROL( QskSlider, Groove )
QSK_SUBCONTROL( QskSlider, Fill )
QSK_SUBCONTROL( QskSlider, Scale )
QSK_SUBCONTROL( QskSlider, Ticks )
QSK_SUBCONTROL( QskSlider, Tick )
QSK_SUBCONTROL( QskSlider, Handle )

QSK_SYSTEM_STATE( QskSlider, Pressed, QskAspect::FirstSystemState << 2 )

static inline constexpr QskAspect qskAspectGraduationPolicy()
{
return QskSlider::Tick | QskAspect::Option;
}

static inline bool qskHasGraduation( const QskSlider* slider )
{
if ( slider->stepSize() )
{
switch( slider->graduationPolicy() )
{
case Qsk::Always:
return true;

case Qsk::Maybe:
return slider->isSnapping();

case Qsk::Never:
return false;
}
}

return false;
}

class QskSlider::PrivateData
{
public:
Expand Down Expand Up @@ -90,6 +117,42 @@ QskAspect::Variation QskSlider::effectiveVariation() const
return static_cast< QskAspect::Variation >( m_data->orientation );
}

void QskSlider::setGraduationPolicy( Qsk::Policy policy )
{
if ( setFlagHint( qskAspectGraduationPolicy(), policy ) )
Q_EMIT graduationPolicyChanged( graduationPolicy() );
}

void QskSlider::resetGraduationPolicy()
{
if ( resetSkinHint( qskAspectGraduationPolicy() ) )
Q_EMIT graduationPolicyChanged( graduationPolicy() );
}

Qsk::Policy QskSlider::graduationPolicy() const
{
return flagHint< Qsk::Policy >( qskAspectGraduationPolicy(), Qsk::Maybe );
}

QVector< qreal > QskSlider::visualGraduation() const
{
QVector< qreal > graduation;

if ( qskHasGraduation( this ) )
{
const auto n = qCeil( boundaryLength() / stepSize() ) + 1;

graduation.reserve( n );

for ( int i = 0; i < n - 1; i++ )
graduation += minimum() + i * stepSize();

graduation += maximum();
}

return graduation;
}

void QskSlider::setTracking( bool on )
{
if ( on != m_data->tracking )
Expand Down
16 changes: 15 additions & 1 deletion src/controls/QskSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@
#define QSK_SLIDER_H

#include "QskBoundedValueInput.h"
#include "QskNamespace.h"

#include <qvector.h>

class QSK_EXPORT QskSlider : public QskBoundedValueInput
{
Q_OBJECT

Q_PROPERTY( bool isPressed READ isPressed NOTIFY pressedChanged )

Q_PROPERTY( Qsk::Policy graduationPolicy READ graduationPolicy
WRITE setGraduationPolicy RESET resetGraduationPolicy
NOTIFY graduationPolicyChanged )

Q_PROPERTY( Qt::Orientation orientation READ orientation
WRITE setOrientation NOTIFY orientationChanged )

Expand All @@ -25,7 +32,7 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
using Inherited = QskBoundedValueInput;

public:
QSK_SUBCONTROLS( Panel, Groove, Fill, Scale, Ticks, Handle )
QSK_SUBCONTROLS( Panel, Groove, Fill, Scale, Tick, Handle )
QSK_STATES( Pressed )

explicit QskSlider( QQuickItem* parent = nullptr );
Expand All @@ -38,6 +45,12 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
void setOrientation( Qt::Orientation );
Qt::Orientation orientation() const;

void setGraduationPolicy( Qsk::Policy );
void resetGraduationPolicy();
Qsk::Policy graduationPolicy() const;

virtual QVector< qreal > visualGraduation() const;

void setTracking( bool );
bool isTracking() const;

Expand All @@ -49,6 +62,7 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
void pressedChanged( bool );
void orientationChanged( Qt::Orientation );
void trackingChanged( bool );
void graduationPolicyChanged( Qsk::Policy );

protected:
void mousePressEvent( QMouseEvent* ) override;
Expand Down
Loading

0 comments on commit 9a5dd88

Please sign in to comment.