layout code in QskSwitchButtonSkinlet improved - still some way to go
until the switch is perfectly themable and looks like in the material specs
This commit is contained in:
parent
0e334e5fd9
commit
1b4be3bc23
|
@ -492,36 +492,43 @@ void Editor::setupSwitchButton()
|
||||||
using A = QskAspect;
|
using A = QskAspect;
|
||||||
using Q = QskSwitchButton;
|
using Q = QskSwitchButton;
|
||||||
|
|
||||||
const qreal radius = qskDpiScaled( 18 );
|
const qreal radius = qskDpiScaled( 10 );
|
||||||
const qreal knopLength = radius - 4;
|
const qreal handleSize = 2 * radius;
|
||||||
|
|
||||||
|
setBoxShape( Q::Groove, 100, Qt::RelativeSize );
|
||||||
|
|
||||||
|
const QSizeF grooveSize( 3.4 * radius, 1.2 * radius );
|
||||||
|
setStrutSize( Q::Groove | A::Horizontal, grooveSize );
|
||||||
|
setStrutSize( Q::Groove | A::Vertical, grooveSize.transposed() );
|
||||||
|
|
||||||
|
setGradient( Q::Groove, m_pal.darker125 );
|
||||||
|
setGradient( Q::Groove | Q::Checkable | Q::Disabled, m_pal.lighter150 );
|
||||||
|
setGradient( Q::Groove | Q::Checkable | Q::Checked, m_pal.darker200 );
|
||||||
|
|
||||||
setBoxShape( Q::Groove, radius);
|
|
||||||
setStrutSize( Q::Groove, 3.4 * radius, 2 * radius );
|
|
||||||
setColor( Q::Groove, m_pal.accentColor );
|
|
||||||
setBoxBorderColors( Q::Groove, m_pal.darker200 );
|
setBoxBorderColors( Q::Groove, m_pal.darker200 );
|
||||||
setColor( Q::Groove | Q::Disabled, m_pal.lighter125 );
|
|
||||||
setBoxBorderMetrics( Q::Groove, 2 );
|
setBoxBorderMetrics( Q::Groove, 2 );
|
||||||
setBoxBorderColors( Q::Groove | Q::Disabled, m_pal.darker125 );
|
setBoxBorderColors( Q::Groove | Q::Disabled, m_pal.darker125 );
|
||||||
|
|
||||||
setBoxShape( Q::Handle, knopLength );
|
setBoxShape( Q::Handle, 100, Qt::RelativeSize );
|
||||||
setMetric( Q::Handle | A::Size,knopLength );
|
setStrutSize( Q::Handle, handleSize, handleSize );
|
||||||
setGradient( Q::Handle, QskGradient( Qt::Vertical, m_pal.lighter150, m_pal.lighter125 ) );
|
|
||||||
setBoxBorderMetrics( Q::Handle, 2 );
|
setBoxBorderMetrics( Q::Handle, 2 );
|
||||||
setColor( Q::Handle | Q::Disabled, m_pal.lighter125 );
|
|
||||||
|
setGradient( Q::Handle, QskGradient( Qt::Vertical, m_pal.lighter150, m_pal.lighter125 ) );
|
||||||
|
setGradient( Q::Handle | Q::Checkable | Q::Checked, m_pal.accentColor );
|
||||||
|
|
||||||
|
setGradient( Q::Handle | Q::Disabled, m_pal.lighter125 );
|
||||||
setBoxBorderColors( Q::Handle, m_pal.darker200 );
|
setBoxBorderColors( Q::Handle, m_pal.darker200 );
|
||||||
setBoxBorderColors( Q::Handle | Q::Disabled, m_pal.darker125 );
|
setBoxBorderColors( Q::Handle | Q::Disabled, m_pal.darker125 );
|
||||||
|
|
||||||
for( auto state : { A::NoState, Q::Disabled } )
|
for( auto state : { A::NoState, Q::Disabled } )
|
||||||
{
|
{
|
||||||
auto aspect = Q::Handle | state | A::Position;
|
auto aspect = Q::Handle | Q::Checkable | state | A::Position;
|
||||||
|
|
||||||
setMetric( aspect | Q::Checked, 0 );
|
setMetric( aspect, 0 );
|
||||||
setMetric( aspect, 1 );
|
setMetric( aspect | Q::Checked, 1 );
|
||||||
|
|
||||||
aspect = Q::Groove | state | A::Color;
|
|
||||||
setColor( aspect | Q::Checked, m_pal.baseColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setAnimation( Q::Handle | A::Color, qskDuration );
|
||||||
setAnimation( Q::Handle | A::Metric, qskDuration );
|
setAnimation( Q::Handle | A::Metric, qskDuration );
|
||||||
setAnimation( Q::Groove | A::Color, qskDuration );
|
setAnimation( Q::Groove | A::Color, qskDuration );
|
||||||
}
|
}
|
||||||
|
|
|
@ -859,33 +859,38 @@ void Editor::setupSwitchButton()
|
||||||
using Q = QskSwitchButton;
|
using Q = QskSwitchButton;
|
||||||
|
|
||||||
const qreal radius = qskDpiScaled( 18 );
|
const qreal radius = qskDpiScaled( 18 );
|
||||||
const qreal handleLength = radius - 4;
|
const qreal handleSize = 2 * ( radius - 2 );
|
||||||
|
|
||||||
|
setBoxShape( Q::Groove, 100, Qt::RelativeSize );
|
||||||
|
|
||||||
|
const QSizeF grooveSize( 3.4 * radius, 2 * radius );
|
||||||
|
setStrutSize( Q::Groove | A::Horizontal, grooveSize );
|
||||||
|
setStrutSize( Q::Groove | A::Vertical, grooveSize.transposed() );
|
||||||
|
|
||||||
|
setGradient( Q::Groove, m_pal.theme );
|
||||||
|
setGradient( Q::Groove | Q::Checkable | Q::Checked, m_pal.highlighted );
|
||||||
|
setGradient( Q::Groove | Q::Checkable | Q::Disabled, m_pal.lighter150 );
|
||||||
|
|
||||||
setBoxShape( Q::Groove, radius);
|
|
||||||
setStrutSize( Q::Groove, 3.4 * radius, 2 * radius );
|
|
||||||
setColor( Q::Groove, m_pal.highlighted );
|
|
||||||
setBoxBorderColors( Q::Groove | Q::Disabled, m_pal.theme );
|
setBoxBorderColors( Q::Groove | Q::Disabled, m_pal.theme );
|
||||||
setColor( Q::Groove | Q::Disabled, m_pal.lighter110 );
|
|
||||||
setBoxBorderMetrics( Q::Groove, 2 );
|
setBoxBorderMetrics( Q::Groove, 2 );
|
||||||
setBoxBorderColors( Q::Groove, m_pal.darker200 );
|
setBoxBorderColors( Q::Groove, m_pal.darker200 );
|
||||||
|
|
||||||
setBoxShape( Q::Handle, handleLength );
|
setBoxShape( Q::Handle, 100, Qt::RelativeSize );
|
||||||
setMetric( Q::Handle | A::Size, handleLength );
|
setStrutSize( Q::Handle, handleSize, handleSize );
|
||||||
|
|
||||||
setGradient( Q::Handle, QskGradient( Qt::Vertical, m_pal.lighter150, m_pal.lighter110 ) );
|
setGradient( Q::Handle, QskGradient( Qt::Vertical, m_pal.lighter150, m_pal.lighter110 ) );
|
||||||
|
setGradient( Q::Handle | Q::Disabled, m_pal.lighter110 );
|
||||||
|
|
||||||
setBoxBorderMetrics( Q::Handle, 2 );
|
setBoxBorderMetrics( Q::Handle, 2 );
|
||||||
setColor(Q::Handle | Q::Disabled, m_pal.lighter110 );
|
|
||||||
setBoxBorderColors( Q::Handle, m_pal.darker200 );
|
setBoxBorderColors( Q::Handle, m_pal.darker200 );
|
||||||
setBoxBorderColors( Q::Handle | Q::Disabled, m_pal.theme );
|
setBoxBorderColors( Q::Handle | Q::Disabled, m_pal.theme );
|
||||||
|
|
||||||
for( auto state : { A::NoState, Q::Disabled } )
|
for( auto state : { A::NoState, Q::Disabled } )
|
||||||
{
|
{
|
||||||
auto aspect = Q::Handle | state | A::Position;
|
auto aspect = Q::Handle | Q::Checkable | state | A::Position;
|
||||||
|
|
||||||
setMetric( aspect | Q::Checked, 0 );
|
setMetric( aspect, 0 );
|
||||||
setMetric( aspect, 1 );
|
setMetric( aspect | Q::Checked, 1 );
|
||||||
|
|
||||||
aspect = Q::Groove | state | A::Color;
|
|
||||||
setColor( aspect | Q::Checked, m_pal.baseActive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setAnimation( Q::Handle | A::Metric, qskDuration );
|
setAnimation( Q::Handle | A::Metric, qskDuration );
|
||||||
|
|
|
@ -7,6 +7,23 @@
|
||||||
#include "QskSwitchButtonSkinlet.h"
|
#include "QskSwitchButtonSkinlet.h"
|
||||||
#include "QskSGNode.h"
|
#include "QskSGNode.h"
|
||||||
|
|
||||||
|
static inline qreal qskEffectivePosition( const QskSwitchButton* switchButton )
|
||||||
|
{
|
||||||
|
auto pos = switchButton->metric( QskSwitchButton::Handle | QskAspect::Position );
|
||||||
|
pos = qBound( 0.0, pos, 1.0 );
|
||||||
|
|
||||||
|
if( switchButton->isInverted() )
|
||||||
|
pos = 1.0 - pos;
|
||||||
|
|
||||||
|
if ( switchButton->orientation() == Qt::Horizontal )
|
||||||
|
{
|
||||||
|
if( switchButton->layoutMirroring() )
|
||||||
|
pos = 1.0 - pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
QskSwitchButtonSkinlet::QskSwitchButtonSkinlet( QskSkin* skin )
|
QskSwitchButtonSkinlet::QskSwitchButtonSkinlet( QskSkin* skin )
|
||||||
: Inherited( skin )
|
: Inherited( skin )
|
||||||
{
|
{
|
||||||
|
@ -18,94 +35,38 @@ QskSwitchButtonSkinlet::~QskSwitchButtonSkinlet()
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskSwitchButtonSkinlet::subControlRect( const QskSkinnable* skinnable,
|
QRectF QskSwitchButtonSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
const QRectF& contentsRect, QskAspect::Subcontrol subControl) const
|
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
||||||
{
|
{
|
||||||
using Q = QskSwitchButton;
|
using Q = QskSwitchButton;
|
||||||
|
|
||||||
const auto switchButton = static_cast< const Q* >( skinnable );
|
|
||||||
|
|
||||||
if ( subControl == Q::Handle )
|
if ( subControl == Q::Handle )
|
||||||
{
|
{
|
||||||
const auto diameter = 2 * skinnable->metric( Q::Handle | QskAspect::Size );
|
return handleRect( skinnable, contentsRect );
|
||||||
const auto grooveSize = skinnable->strutSizeHint( Q::Groove );
|
|
||||||
|
|
||||||
auto position = skinnable->metric( Q::Handle | QskAspect::Position );
|
|
||||||
if( switchButton->isInverted() )
|
|
||||||
position = 1.0 - position;
|
|
||||||
|
|
||||||
auto rect = QRectF( 0, 0, diameter, diameter );
|
|
||||||
|
|
||||||
if( switchButton->orientation() == Qt::Vertical )
|
|
||||||
{
|
|
||||||
if( diameter < grooveSize.height() )
|
|
||||||
rect.moveLeft( ( grooveSize.height() - diameter ) / 2 );
|
|
||||||
|
|
||||||
rect.moveTop( ( grooveSize.height() - diameter ) / 2
|
|
||||||
+ position * ( grooveSize.width() - diameter
|
|
||||||
- ( grooveSize.height() - diameter ) ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( switchButton->layoutMirroring() )
|
|
||||||
position = 1.0 - position;
|
|
||||||
|
|
||||||
if( diameter < grooveSize.height() )
|
|
||||||
rect.moveTop( ( grooveSize.height() - diameter ) / 2 );
|
|
||||||
|
|
||||||
rect.moveLeft( ( grooveSize.height() - diameter ) / 2
|
|
||||||
+ position * ( grooveSize.width() - diameter
|
|
||||||
- ( grooveSize.height() - diameter ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return rect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( subControl == Q::Groove )
|
if ( subControl == Q::Groove )
|
||||||
{
|
{
|
||||||
auto diameter = 2 * skinnable->metric( Q::Handle | QskAspect::Size );
|
return grooveRect( skinnable, contentsRect );
|
||||||
const auto grooveSize = skinnable->strutSizeHint( Q::Groove );
|
|
||||||
|
|
||||||
auto result = contentsRect;
|
|
||||||
result.setSize( grooveSize );
|
|
||||||
|
|
||||||
if( switchButton->orientation() == Qt::Vertical )
|
|
||||||
{
|
|
||||||
if( grooveSize.height() < diameter )
|
|
||||||
result.moveLeft( ( diameter - result.height() ) / 2 );
|
|
||||||
|
|
||||||
return result.transposed();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( grooveSize.height() < diameter )
|
|
||||||
result.moveTop( ( diameter - result.height() ) / 2 );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||||
}
|
}
|
||||||
|
|
||||||
QSizeF QskSwitchButtonSkinlet::sizeHint( const QskSkinnable* skinnable,
|
QSizeF QskSwitchButtonSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||||
Qt::SizeHint, const QSizeF&) const
|
Qt::SizeHint which, const QSizeF& ) const
|
||||||
{
|
{
|
||||||
using Q = QskSwitchButton;
|
if ( which != Qt::PreferredSize )
|
||||||
|
return QSizeF();
|
||||||
|
|
||||||
const auto switchButton = static_cast< const Q* >( skinnable );
|
auto hint = skinnable->strutSizeHint( QskSwitchButton::Groove );
|
||||||
const auto diameter = 2 * skinnable->metric( Q::Handle | QskAspect::Size );
|
hint = hint.expandedTo( skinnable->strutSizeHint( QskSwitchButton::Handle ) );
|
||||||
|
|
||||||
auto hint = skinnable->strutSizeHint( Q::Groove );
|
|
||||||
hint = hint.expandedTo( QSizeF( diameter, diameter ) );
|
|
||||||
|
|
||||||
if( switchButton->orientation() == Qt::Vertical )
|
|
||||||
hint.transpose();
|
|
||||||
|
|
||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGNode* QskSwitchButtonSkinlet::updateSubNode( const QskSkinnable* skinnable,
|
QSGNode* QskSwitchButtonSkinlet::updateSubNode( const QskSkinnable* skinnable,
|
||||||
quint8 nodeRole, QSGNode* node) const
|
quint8 nodeRole, QSGNode* node ) const
|
||||||
{
|
{
|
||||||
using Q = QskSwitchButton;
|
using Q = QskSwitchButton;
|
||||||
|
|
||||||
|
@ -121,4 +82,76 @@ QSGNode* QskSwitchButtonSkinlet::updateSubNode( const QskSkinnable* skinnable,
|
||||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRectF QskSwitchButtonSkinlet::grooveRect(
|
||||||
|
const QskSkinnable* skinnable, const QRectF& contentsRect ) const
|
||||||
|
{
|
||||||
|
using Q = QskSwitchButton;
|
||||||
|
|
||||||
|
const auto switchButton = static_cast< const Q* >( skinnable );
|
||||||
|
|
||||||
|
auto size = skinnable->strutSizeHint( Q::Groove );
|
||||||
|
|
||||||
|
if ( switchButton->orientation() == Qt::Vertical )
|
||||||
|
{
|
||||||
|
if ( size.height() < 0.0 )
|
||||||
|
{
|
||||||
|
const auto handleSize = skinnable->strutSizeHint( Q::Handle );
|
||||||
|
size.setHeight( 2 * handleSize.height() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( size.width() < 0.0 )
|
||||||
|
{
|
||||||
|
const auto handleSize = skinnable->strutSizeHint( Q::Handle );
|
||||||
|
size.setWidth( 2 * handleSize.width() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size = size.expandedTo( QSize( 0.0, 0.0 ) );
|
||||||
|
|
||||||
|
QRectF r;
|
||||||
|
r.setSize( size );
|
||||||
|
r.moveCenter( contentsRect.center() );
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskSwitchButtonSkinlet::handleRect(
|
||||||
|
const QskSkinnable* skinnable, const QRectF& contentsRect ) const
|
||||||
|
{
|
||||||
|
using Q = QskSwitchButton;
|
||||||
|
|
||||||
|
const auto switchButton = static_cast< const Q* >( skinnable );
|
||||||
|
|
||||||
|
const auto grooveRect = subControlRect( skinnable, contentsRect, Q::Groove );
|
||||||
|
const auto pos = qskEffectivePosition( switchButton );
|
||||||
|
const auto size = skinnable->strutSizeHint( Q::Handle );
|
||||||
|
|
||||||
|
qreal cx, cy;
|
||||||
|
|
||||||
|
if( switchButton->orientation() == Qt::Vertical )
|
||||||
|
{
|
||||||
|
const qreal y0 = grooveRect.y() + 0.5 * size.height();
|
||||||
|
const qreal h = grooveRect.height() - size.height();
|
||||||
|
|
||||||
|
cx = grooveRect.x() + 0.5 * grooveRect.width();
|
||||||
|
cy = y0 + pos * h;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const qreal x0 = grooveRect.x() + 0.5 * size.width();
|
||||||
|
const qreal w = grooveRect.width() - size.width();
|
||||||
|
|
||||||
|
cx = x0 + pos * w;
|
||||||
|
cy = grooveRect.y() + 0.5 * grooveRect.height();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF r;
|
||||||
|
r.setSize( size );
|
||||||
|
r.moveCenter( QPointF( cx, cy ) );
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_QskSwitchButtonSkinlet.cpp"
|
#include "moc_QskSwitchButtonSkinlet.cpp"
|
||||||
|
|
|
@ -21,11 +21,11 @@ class QSK_EXPORT QskSwitchButtonSkinlet : public QskSkinlet
|
||||||
HandleRole
|
HandleRole
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_INVOKABLE QskSwitchButtonSkinlet( QskSkin* parent = nullptr );
|
Q_INVOKABLE QskSwitchButtonSkinlet( QskSkin* = nullptr );
|
||||||
~QskSwitchButtonSkinlet() override;
|
~QskSwitchButtonSkinlet() override;
|
||||||
|
|
||||||
QRectF subControlRect( const QskSkinnable*,
|
QRectF subControlRect( const QskSkinnable*,
|
||||||
const QRectF& rect, QskAspect::Subcontrol ) const override;
|
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||||
|
|
||||||
QSizeF sizeHint( const QskSkinnable*,
|
QSizeF sizeHint( const QskSkinnable*,
|
||||||
Qt::SizeHint, const QSizeF& ) const override;
|
Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
@ -33,6 +33,10 @@ class QSK_EXPORT QskSwitchButtonSkinlet : public QskSkinlet
|
||||||
protected:
|
protected:
|
||||||
QSGNode* updateSubNode( const QskSkinnable*,
|
QSGNode* updateSubNode( const QskSkinnable*,
|
||||||
quint8 nodeRole, QSGNode* ) const override;
|
quint8 nodeRole, QSGNode* ) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QRectF grooveRect( const QskSkinnable*, const QRectF& ) const;
|
||||||
|
QRectF handleRect( const QskSkinnable*, const QRectF& ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue