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

View File

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

View File

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

View File

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

View File

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

View File

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