implementation improved

This commit is contained in:
Uwe Rathmann 2021-12-27 18:47:46 +01:00
parent b6f464316c
commit 2201c80d09
6 changed files with 113 additions and 152 deletions

View File

@ -91,32 +91,28 @@ class MySkinEditor : public QskSkinHintTableEditor
using A = QskAspect;
using Q = MyToggleButton;
for( auto subControl : { Q::UncheckedLabel, Q::CheckedLabel } )
for( auto subControl : { Q::UncheckedText, Q::CheckedText } )
{
QColor color1 = foregroundTextColor;
QColor color2 = baseTextColor;
if( subControl == Q::UncheckedLabel )
{
if( subControl == Q::CheckedText )
std::swap( color1, color2 );
}
setColor( subControl | Q::Checked, color1 );
setColor( subControl, color2 );
setColor( subControl, color1 );
setColor( subControl | Q::Checked, color2 );
setAlignment( subControl, Qt::AlignCenter );
setAnimation( subControl | A::Color, animator() );
}
for( auto subControl : { Q::UncheckedIcon, Q::CheckedIcon } )
for( auto subControl : { Q::UncheckedGraphic, Q::CheckedGraphic } )
{
int role1 = MySkin::GraphicRoleNormal;
int role2 = MySkin::GraphicRoleInverted;
int role1 = MySkin::GraphicRoleInverted;
int role2 = MySkin::GraphicRoleNormal;
if( subControl == Q::UncheckedIcon )
{
if( subControl == Q::CheckedGraphic )
std::swap( role1, role2 );
}
setGraphicRole( subControl, role1 );
setGraphicRole( subControl | Q::Checked, role2 );
@ -157,8 +153,8 @@ class MySkinEditor : public QskSkinHintTableEditor
{
const auto aspect = Q::Cursor | state | A::Position;
setMetric( aspect | Q::Checked, 0 );
setMetric( aspect, 1 );
setMetric( aspect, 0 );
setMetric( aspect | Q::Checked, 1 );
}
setAnimation( Q::Cursor | A::Metric, animator() );
@ -179,66 +175,69 @@ class MySkinEditor : public QskSkinHintTableEditor
QskAnimationHint m_animationHint;
};
class MySkin1 : public MySkin
namespace
{
public:
MySkin1()
class SkinBlue : public MySkin
{
using namespace QskRgb;
public:
SkinBlue()
{
using namespace QskRgb;
setGraphicFilter( GraphicRoleNormal, Crimson );
setGraphicFilter( GraphicRoleInverted, Gold );
setGraphicFilter( GraphicRoleNormal, Crimson );
setGraphicFilter( GraphicRoleInverted, Gold );
MySkinEditor editor;
editor.setTable( &hintTable() );
editor.setAnimator( 200, QEasingCurve::Linear );
MySkinEditor editor;
editor.setTable( &hintTable() );
editor.setAnimator( 200, QEasingCurve::Linear );
editor.setGradient( QskAspect::Control, Qt::gray );
editor.setGradient( QskAspect::Control, Qt::gray );
editor.setupFocusIndicator( 2, 3, 6, DarkBlue );
editor.setupBox( 2, 8, DarkCyan, LightCyan );
editor.setupFocusIndicator( 2, 3, 6, DarkBlue );
editor.setupBox( 2, 8, DarkCyan, LightCyan );
editor.setupToggleButton( false, 150, 120, 6,
AliceBlue, Black, CornflowerBlue, White );
}
};
editor.setupToggleButton( false, 150, 120, 6,
AliceBlue, Black, CornflowerBlue, White );
}
};
class MySkin2 : public MySkin
{
public:
MySkin2()
class SkinPink : public MySkin
{
using namespace QskRgb;
public:
SkinPink()
{
using namespace QskRgb;
setGraphicFilter( GraphicRoleNormal, HotPink );
setGraphicFilter( GraphicRoleInverted, White );
setGraphicFilter( GraphicRoleNormal, HotPink );
setGraphicFilter( GraphicRoleInverted, White );
MySkinEditor editor;
editor.setTable( &hintTable() );
editor.setAnimator( 100, QEasingCurve::InQuad );
MySkinEditor editor;
editor.setTable( &hintTable() );
editor.setAnimator( 100, QEasingCurve::InQuad );
editor.setGradient( QskAspect::Control, Qt::gray );
editor.setGradient( QskAspect::Control, Qt::gray );
editor.setupFocusIndicator( 2, 6, 6, Crimson );
editor.setupBox( 4, 30, LightPink, MistyRose );
editor.setupFocusIndicator( 2, 6, 6, Crimson );
editor.setupBox( 4, 30, LightPink, MistyRose );
editor.setupToggleButton( true, 130, 100, 40,
LightPink, Black, HotPink, White );
}
};
editor.setupToggleButton( true, 130, 100, 40,
LightPink, Black, HotPink, White );
}
};
}
QStringList MySkinFactory::skinNames() const
{
return { QStringLiteral( "MySkin1" ), QStringLiteral( "MySkin2" ) };
return { QStringLiteral( "Blue" ), QStringLiteral( "Pink" ) };
}
QskSkin* MySkinFactory::createSkin( const QString& skinName )
{
if ( skinName == QStringLiteral( "MySkin1" ) )
return new MySkin1();
if ( skinName == QStringLiteral( "Blue" ) )
return new SkinBlue();
if ( skinName == QStringLiteral( "MySkin2" ) )
return new MySkin2();
if ( skinName == QStringLiteral( "Pink" ) )
return new SkinPink();
return nullptr;
}

View File

@ -13,11 +13,11 @@
QSK_SUBCONTROL( MyToggleButton, Panel )
QSK_SUBCONTROL( MyToggleButton, Cursor )
QSK_SUBCONTROL( MyToggleButton, CheckedPanel )
QSK_SUBCONTROL( MyToggleButton, CheckedLabel )
QSK_SUBCONTROL( MyToggleButton, CheckedText )
QSK_SUBCONTROL( MyToggleButton, UncheckedPanel )
QSK_SUBCONTROL( MyToggleButton, UncheckedLabel )
QSK_SUBCONTROL( MyToggleButton, CheckedIcon )
QSK_SUBCONTROL( MyToggleButton, UncheckedIcon )
QSK_SUBCONTROL( MyToggleButton, UncheckedText )
QSK_SUBCONTROL( MyToggleButton, CheckedGraphic )
QSK_SUBCONTROL( MyToggleButton, UncheckedGraphic )
class MyToggleButton::PrivateData
{
@ -93,14 +93,9 @@ QskTextOptions MyToggleButton::textOptions() const
return m_data->textOptions;
}
void MyToggleButton::setTextAt( int index, const QString& text )
void MyToggleButton::setText( bool isChecked, const QString& text )
{
if( index < 0 || index > 1 )
{
return;
}
auto& data = m_data->content[ index ];
auto& data = m_data->content[ isChecked ];
if( !data.icon.isNull() )
{
@ -118,24 +113,14 @@ void MyToggleButton::setTextAt( int index, const QString& text )
}
}
QString MyToggleButton::textAt( int index ) const
QString MyToggleButton::text( bool isChecked ) const
{
if( index < 0 || index > 1 )
{
return QString();
}
return m_data->content[ index ].text;
return m_data->content[ isChecked ].text;
}
void MyToggleButton::setIconAt( int index, const QString& icon )
void MyToggleButton::setIcon( bool isChecked, const QString& icon )
{
if( index < 0 || index > 1 )
{
return;
}
auto& data = m_data->content[ index ];
auto& data = m_data->content[ isChecked ];
if( !data.text.isEmpty() )
{
@ -155,24 +140,14 @@ void MyToggleButton::setIconAt( int index, const QString& icon )
}
}
QString MyToggleButton::iconAt( int index ) const
QString MyToggleButton::icon( bool isChecked ) const
{
if( index < 0 || index > 1 )
{
return QString();
}
return m_data->content[ index ].iconSource;
return m_data->content[ isChecked ].iconSource;
}
QskGraphic MyToggleButton::graphicAt( int index ) const
QskGraphic MyToggleButton::graphic( bool isChecked ) const
{
if( index < 0 || index > 1 )
{
return QskGraphic();
}
auto& data = const_cast< MyToggleButton* >( this )->m_data->content[ index ];
auto& data = const_cast< MyToggleButton* >( this )->m_data->content[ isChecked ];
if( data.iconDirty )
{
@ -185,13 +160,8 @@ QskGraphic MyToggleButton::graphicAt( int index ) const
void MyToggleButton::updateResources()
{
for( int i = 0; i < 2; i++ )
{
if( m_data->content[ i ].iconDirty )
{
( void )graphicAt( Checked );
}
}
(void) graphic( false );
(void) graphic( true );
}
#include "moc_MyToggleButton.cpp"

View File

@ -16,24 +16,24 @@ class MyToggleButton : public QskAbstractButton
using Inherited = QskAbstractButton;
public:
QSK_SUBCONTROLS( Panel, Cursor, CheckedPanel, CheckedLabel, CheckedIcon,
UncheckedPanel, UncheckedLabel, UncheckedIcon )
QSK_SUBCONTROLS( Panel, Cursor, CheckedPanel, CheckedText, CheckedGraphic,
UncheckedPanel, UncheckedText, UncheckedGraphic )
MyToggleButton( QQuickItem* parent = nullptr );
~MyToggleButton() override;
bool isCheckable() const override final;
void setTextAt( int index, const QString& );
QString textAt( int index ) const;
void setText( bool isChecked, const QString& );
QString text( bool isChecked ) const;
void setIconAt( int index, const QString& icon );
QString iconAt( int index ) const;
void setIcon( bool isChecked, const QString& icon );
QString icon( bool isChecked ) const;
void setTextOptions( const QskTextOptions& );
QskTextOptions textOptions() const;
QskGraphic graphicAt( int index ) const;
QskGraphic graphic( bool isChecked ) const;
void setInverted( bool );
bool isInverted() const;

View File

@ -27,8 +27,9 @@ MyToggleButtonSkinlet::MyToggleButtonSkinlet( QskSkin* skin )
// sorted in stacking order
setNodeRoles(
{ PanelRole, CursorRole, UncheckedPanelRole, UncheckedLabelRole,
UncheckedIconRole, CheckedPanelRole, CheckedLabelRole, CheckedIconRole
{
PanelRole, CursorRole, UncheckedLabelRole,
UncheckedGraphicRole, CheckedLabelRole, CheckedGraphicRole
}
);
}
@ -47,18 +48,18 @@ QRectF MyToggleButtonSkinlet::subControlRect( const QskSkinnable* skinnable,
else if( subControl == Q::UncheckedPanel )
{
const auto r = button->subControlContentsRect( contentsRect, Q::Panel );
return sectionRect( r, button->isInverted() ? 0 : 1 );
return sectionRect( r, button->isInverted() ? 1 : 0 );
}
else if( subControl == Q::CheckedPanel )
{
const auto r = button->subControlContentsRect( contentsRect, Q::Panel );
return sectionRect( r, button->isInverted() ? 1 : 0 );
return sectionRect( r, button->isInverted() ? 0 : 1 );
}
else if( subControl == Q::CheckedLabel || subControl == Q::CheckedIcon )
else if( subControl == Q::CheckedText || subControl == Q::CheckedGraphic )
{
return button->subControlContentsRect( contentsRect, Q::CheckedPanel );
}
else if( subControl == Q::UncheckedLabel || subControl == Q::UncheckedIcon )
else if( subControl == Q::UncheckedText || subControl == Q::UncheckedGraphic )
{
return button->subControlContentsRect( contentsRect, Q::UncheckedPanel );
}
@ -96,46 +97,36 @@ QSGNode* MyToggleButtonSkinlet::updateSubNode(
case CheckedLabelRole:
{
return updateTextNode(
button, node, button->textAt( 1 ),
button->textOptions(), Q::CheckedLabel );
button, node, button->text( true ),
button->textOptions(), Q::CheckedText );
}
case UncheckedLabelRole:
{
return updateTextNode(
button, node, button->textAt( 0 ),
button->textOptions(), Q::UncheckedLabel );
button, node, button->text( false ),
button->textOptions(), Q::UncheckedText );
}
case CheckedIconRole:
case CheckedGraphicRole:
{
return updateGraphicNode(
button, node, button->graphicAt( 1 ), Q::CheckedIcon );
button, node, button->graphic( true ), Q::CheckedGraphic );
}
case UncheckedIconRole:
case UncheckedGraphicRole:
{
return updateGraphicNode(
button, node, button->graphicAt( 0 ), Q::UncheckedIcon );
}
case CheckedPanelRole:
case UncheckedPanelRole:
{
// not implemented
return nullptr;
button, node, button->graphic( false ), Q::UncheckedGraphic );
}
case CursorRole:
{
return updateBoxNode( button, node, Q::Cursor );
}
default:
{
return nullptr;
}
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
QSizeF MyToggleButtonSkinlet::sizeHint( const QskSkinnable* skinnable,

View File

@ -21,13 +21,11 @@ class MyToggleButtonSkinlet : public QskSkinlet
PanelRole,
CursorRole,
CheckedPanelRole,
CheckedLabelRole,
CheckedIconRole,
CheckedGraphicRole,
UncheckedPanelRole,
UncheckedLabelRole,
UncheckedIconRole
UncheckedGraphicRole
};
Q_INVOKABLE MyToggleButtonSkinlet( QskSkin* = nullptr );

View File

@ -51,35 +51,36 @@ class ContentBox : public QskBox
layout->setDefaultAlignment( Qt::AlignCenter );
layout->setExtraSpacingAt( Qt::BottomEdge );
const QskSizePolicy sizePolicy(
QskSizePolicy::MinimumExpanding, QskSizePolicy::MinimumExpanding );
{
auto button = new MyToggleButton( layout );
button->setSizePolicy( QskSizePolicy::MinimumExpanding,
QskSizePolicy::MinimumExpanding );
button->setTextAt( 0, "On" );
button->setTextAt( 1, "Off" );
button->setSizePolicy( sizePolicy );
button->setText( false, "Off" );
button->setText( true, "On" );
}
{
auto button = new MyToggleButton( layout );
button->setSizePolicy( QskSizePolicy::MinimumExpanding,
QskSizePolicy::MinimumExpanding );
button->setIconAt( 0, "image://shapes/Ring/Khaki" );
button->setIconAt( 1, "image://shapes/Diamond/Khaki" );
button->setSizePolicy( sizePolicy );
button->setIcon( false, "image://shapes/Diamond/Khaki" );
button->setIcon( true, "image://shapes/Ring/Khaki" );
}
}
};
class Window : public QskWindow
{
Q_OBJECT
public:
Window()
{
auto button = new MyToggleButton();
button->setTextAt( 0, "Skin 1" );
button->setTextAt( 1, "Skin 2" );
button->setText( false, alternativeSkin( false ) );
button->setText( true, alternativeSkin( true ) );
button->setLayoutAlignmentHint( Qt::AlignRight );
auto box = new QskLinearBox( Qt::Vertical );
@ -101,13 +102,11 @@ class Window : public QskWindow
private:
void setAlternativeSkin( bool on )
{
const auto skinNames = qskSkinManager->skinNames();
auto oldSkin = qskSetup->skin();
if ( oldSkin->parent() == qskSetup )
oldSkin->setParent( nullptr ); // otherwise setSkin deletes it
auto newSkin = qskSetup->setSkin( skinNames[ on ? 1 : 0 ] );
auto newSkin = qskSetup->setSkin( alternativeSkin( on ) );
QskSkinTransition transition;
@ -120,6 +119,12 @@ class Window : public QskWindow
if ( oldSkin->parent() == nullptr )
delete oldSkin;
}
QString alternativeSkin( bool on ) const
{
const auto skinNames = qskSkinManager->skinNames();
return skinNames[ on ];
}
};
int main( int argc, char* argv[] )
@ -148,5 +153,3 @@ int main( int argc, char* argv[] )
return app.exec();
}
#include "main.moc"