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 Q = QskSwitchButton;
|
||||
|
||||
const qreal radius = qskDpiScaled( 18 );
|
||||
const qreal knopLength = radius - 4;
|
||||
const qreal radius = qskDpiScaled( 10 );
|
||||
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 );
|
||||
setColor( Q::Groove | Q::Disabled, m_pal.lighter125 );
|
||||
setBoxBorderMetrics( Q::Groove, 2 );
|
||||
setBoxBorderColors( Q::Groove | Q::Disabled, m_pal.darker125 );
|
||||
|
||||
setBoxShape( Q::Handle, knopLength );
|
||||
setMetric( Q::Handle | A::Size,knopLength );
|
||||
setGradient( Q::Handle, QskGradient( Qt::Vertical, m_pal.lighter150, m_pal.lighter125 ) );
|
||||
setBoxShape( Q::Handle, 100, Qt::RelativeSize );
|
||||
setStrutSize( Q::Handle, handleSize, handleSize );
|
||||
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 | Q::Disabled, m_pal.darker125 );
|
||||
|
||||
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, 1 );
|
||||
|
||||
aspect = Q::Groove | state | A::Color;
|
||||
setColor( aspect | Q::Checked, m_pal.baseColor);
|
||||
setMetric( aspect, 0 );
|
||||
setMetric( aspect | Q::Checked, 1 );
|
||||
}
|
||||
|
||||
setAnimation( Q::Handle | A::Color, qskDuration );
|
||||
setAnimation( Q::Handle | A::Metric, qskDuration );
|
||||
setAnimation( Q::Groove | A::Color, qskDuration );
|
||||
}
|
||||
|
@ -859,33 +859,38 @@ void Editor::setupSwitchButton()
|
||||
using Q = QskSwitchButton;
|
||||
|
||||
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 );
|
||||
setColor( Q::Groove | Q::Disabled, m_pal.lighter110 );
|
||||
setBoxBorderMetrics( Q::Groove, 2 );
|
||||
setBoxBorderColors( Q::Groove, m_pal.darker200 );
|
||||
|
||||
setBoxShape( Q::Handle, handleLength );
|
||||
setMetric( Q::Handle | A::Size, handleLength );
|
||||
setBoxShape( Q::Handle, 100, Qt::RelativeSize );
|
||||
setStrutSize( Q::Handle, handleSize, handleSize );
|
||||
|
||||
setGradient( Q::Handle, QskGradient( Qt::Vertical, m_pal.lighter150, m_pal.lighter110 ) );
|
||||
setGradient( Q::Handle | Q::Disabled, m_pal.lighter110 );
|
||||
|
||||
setBoxBorderMetrics( Q::Handle, 2 );
|
||||
setColor(Q::Handle | Q::Disabled, m_pal.lighter110 );
|
||||
setBoxBorderColors( Q::Handle, m_pal.darker200 );
|
||||
setBoxBorderColors( Q::Handle | Q::Disabled, m_pal.theme );
|
||||
|
||||
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, 1 );
|
||||
|
||||
aspect = Q::Groove | state | A::Color;
|
||||
setColor( aspect | Q::Checked, m_pal.baseActive);
|
||||
setMetric( aspect, 0 );
|
||||
setMetric( aspect | Q::Checked, 1 );
|
||||
}
|
||||
|
||||
setAnimation( Q::Handle | A::Metric, qskDuration );
|
||||
|
@ -7,6 +7,23 @@
|
||||
#include "QskSwitchButtonSkinlet.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 )
|
||||
: Inherited( skin )
|
||||
{
|
||||
@ -18,94 +35,38 @@ QskSwitchButtonSkinlet::~QskSwitchButtonSkinlet()
|
||||
}
|
||||
|
||||
QRectF QskSwitchButtonSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||
const QRectF& contentsRect, QskAspect::Subcontrol subControl) const
|
||||
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
using Q = QskSwitchButton;
|
||||
|
||||
const auto switchButton = static_cast< const Q* >( skinnable );
|
||||
|
||||
if ( subControl == Q::Handle )
|
||||
{
|
||||
const auto diameter = 2 * skinnable->metric( Q::Handle | QskAspect::Size );
|
||||
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;
|
||||
return handleRect( skinnable, contentsRect );
|
||||
}
|
||||
|
||||
if ( subControl == Q::Groove )
|
||||
{
|
||||
auto diameter = 2 * skinnable->metric( Q::Handle | QskAspect::Size );
|
||||
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 grooveRect( skinnable, contentsRect );
|
||||
}
|
||||
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
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 );
|
||||
const auto diameter = 2 * skinnable->metric( Q::Handle | QskAspect::Size );
|
||||
|
||||
auto hint = skinnable->strutSizeHint( Q::Groove );
|
||||
hint = hint.expandedTo( QSizeF( diameter, diameter ) );
|
||||
|
||||
if( switchButton->orientation() == Qt::Vertical )
|
||||
hint.transpose();
|
||||
auto hint = skinnable->strutSizeHint( QskSwitchButton::Groove );
|
||||
hint = hint.expandedTo( skinnable->strutSizeHint( QskSwitchButton::Handle ) );
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
QSGNode* QskSwitchButtonSkinlet::updateSubNode( const QskSkinnable* skinnable,
|
||||
quint8 nodeRole, QSGNode* node) const
|
||||
quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
using Q = QskSwitchButton;
|
||||
|
||||
@ -121,4 +82,76 @@ QSGNode* QskSwitchButtonSkinlet::updateSubNode( const QskSkinnable* skinnable,
|
||||
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"
|
||||
|
@ -21,11 +21,11 @@ class QSK_EXPORT QskSwitchButtonSkinlet : public QskSkinlet
|
||||
HandleRole
|
||||
};
|
||||
|
||||
Q_INVOKABLE QskSwitchButtonSkinlet( QskSkin* parent = nullptr );
|
||||
Q_INVOKABLE QskSwitchButtonSkinlet( QskSkin* = nullptr );
|
||||
~QskSwitchButtonSkinlet() override;
|
||||
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF& rect, QskAspect::Subcontrol ) const override;
|
||||
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||
|
||||
QSizeF sizeHint( const QskSkinnable*,
|
||||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
@ -33,6 +33,10 @@ class QSK_EXPORT QskSwitchButtonSkinlet : public QskSkinlet
|
||||
protected:
|
||||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
|
||||
private:
|
||||
QRectF grooveRect( const QskSkinnable*, const QRectF& ) const;
|
||||
QRectF handleRect( const QskSkinnable*, const QRectF& ) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user