From 5aa46b3ccc30c2462fdf344246b22584f2c6412d Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 30 Jan 2024 14:52:40 +0100 Subject: [PATCH] Qt::ColorScheme handling added to QskSkin - no more multiple skins for dark/light. --- designsystems/fluent2/QskFluent2Skin.cpp | 41 +++++++++ designsystems/fluent2/QskFluent2Skin.h | 8 +- .../fluent2/QskFluent2SkinFactory.cpp | 76 +--------------- designsystems/fluent2/metadata.json | 3 +- designsystems/fusion/QskFusionSkin.cpp | 18 ++-- designsystems/fusion/QskFusionSkin.h | 5 +- designsystems/fusion/QskFusionSkinFactory.cpp | 12 +-- designsystems/fusion/metadata.json | 3 +- designsystems/material3/QskMaterial3Skin.cpp | 40 ++++---- designsystems/material3/QskMaterial3Skin.h | 5 +- .../material3/QskMaterial3SkinFactory.cpp | 17 +--- designsystems/material3/metadata.json | 3 +- examples/iotdashboard/Skin.cpp | 80 ++++++++-------- examples/iotdashboard/Skin.h | 31 +------ examples/iotdashboard/main.cpp | 60 +----------- examples/mycontrols/MySkin.cpp | 8 +- examples/mycontrols/main.cpp | 3 +- playground/dials/CMakeLists.txt | 2 +- playground/dials/Skin.cpp | 70 ++++++++++++++ playground/dials/{SkinFactory.h => Skin.h} | 11 +-- playground/dials/SkinFactory.cpp | 91 ------------------- playground/dials/main.cpp | 9 +- src/controls/QskSkin.cpp | 31 +++++++ src/controls/QskSkin.h | 12 +++ src/controls/QskSkinManager.cpp | 82 +++++++++-------- src/controls/QskSkinManager.h | 6 +- support/SkinnyNamespace.cpp | 17 ++++ support/SkinnyNamespace.h | 1 + support/SkinnyShortcut.cpp | 7 ++ support/SkinnyShortcut.h | 14 +-- 30 files changed, 366 insertions(+), 400 deletions(-) create mode 100644 playground/dials/Skin.cpp rename playground/dials/{SkinFactory.h => Skin.h} (61%) delete mode 100644 playground/dials/SkinFactory.cpp diff --git a/designsystems/fluent2/QskFluent2Skin.cpp b/designsystems/fluent2/QskFluent2Skin.cpp index 240c23d7..4ba40a5a 100644 --- a/designsystems/fluent2/QskFluent2Skin.cpp +++ b/designsystems/fluent2/QskFluent2Skin.cpp @@ -1965,6 +1965,47 @@ QskFluent2Skin::~QskFluent2Skin() { } +void QskFluent2Skin::initHints() +{ + struct + { + QskFluent2Theme::BaseColors baseColors; + QskFluent2Theme::AccentColors accentColors; + } colors[2]; + + if( colorScheme() != QskSkin::DarkScheme ) + { + colors[0].baseColors = { rgbGray( 243 ), rgbGray( 249 ), rgbGray( 238 ) }; + colors[0].accentColors = { 0xff0078d4, 0xff005eb7, 0xff003d92, 0xff001968 }; + + colors[1].baseColors = { rgbGray( 249 ), rgbGray( 249 ), rgbGray( 238 ) }; + colors[1].accentColors = colors[0].accentColors; + } + else + { + colors[0].baseColors = { rgbGray( 32 ), rgbGray( 40 ), rgbGray( 28 ) }; + colors[0].accentColors = { 0xff0078d4, 0xff0093f9, 0xff60ccfe, 0xff98ecfe }; + + colors[1].baseColors = { rgbGray( 40 ), rgbGray( 44 ), rgbGray( 28 ) }; + colors[1].accentColors = colors[0].accentColors; + } + + setupFonts(); + + Editor editor( &hintTable() ); + editor.setupMetrics(); + + const QskFluent2Theme themeBody( colorScheme(), + colors[0].baseColors, colors[0].accentColors ); + + const QskFluent2Theme themeHeader( colorScheme(), + colors[1].baseColors, colors[1].accentColors ); + + addTheme( QskAspect::Body, themeBody ); + addTheme( QskAspect::Header, themeHeader ); + addTheme( QskAspect::Footer, themeHeader ); +} + void QskFluent2Skin::setupFonts() { static QString fontName( QStringLiteral( "Segoe UI Variable" ) ); diff --git a/designsystems/fluent2/QskFluent2Skin.h b/designsystems/fluent2/QskFluent2Skin.h index c0be6488..239a73a8 100644 --- a/designsystems/fluent2/QskFluent2Skin.h +++ b/designsystems/fluent2/QskFluent2Skin.h @@ -21,9 +21,6 @@ class QSK_FLUENT2_EXPORT QskFluent2Skin : public QskSkin QskFluent2Skin( QObject* parent = nullptr ); ~QskFluent2Skin() override; - void addTheme( QskAspect::Section, const QskFluent2Theme& ); - void setup(); - enum GraphicRole { GraphicRoleFillColorTextDisabled, @@ -49,7 +46,12 @@ class QSK_FLUENT2_EXPORT QskFluent2Skin : public QskSkin static constexpr QskAspect::Variation Standard = QskAspect::NoVariation; static constexpr QskAspect::Variation Accent = QskAspect::Large; + protected: + void initHints() override; + private: + void addTheme( QskAspect::Section, const QskFluent2Theme& ); + void setupFonts(); void setupGraphicFilters( const QskFluent2Theme& ); void setGraphicColor( GraphicRole, QRgb ); diff --git a/designsystems/fluent2/QskFluent2SkinFactory.cpp b/designsystems/fluent2/QskFluent2SkinFactory.cpp index b9beb18d..10331b83 100644 --- a/designsystems/fluent2/QskFluent2SkinFactory.cpp +++ b/designsystems/fluent2/QskFluent2SkinFactory.cpp @@ -5,18 +5,8 @@ #include "QskFluent2SkinFactory.h" #include "QskFluent2Skin.h" -#include "QskFluent2Theme.h" -static const QString nameLight = QStringLiteral( "Fluent2 Light" ); -static const QString nameDark = QStringLiteral( "Fluent2 Dark" ); - -namespace -{ - inline constexpr QRgb rgbGray( int value ) - { - return qRgba( value, value, value, 255 ); - } -} +static const QString name = QStringLiteral( "Fluent2" ); QskFluent2SkinFactory::QskFluent2SkinFactory( QObject* parent ) : QskSkinFactory( parent ) @@ -29,71 +19,15 @@ QskFluent2SkinFactory::~QskFluent2SkinFactory() QStringList QskFluent2SkinFactory::skinNames() const { - return { nameLight, nameDark }; + return { name }; } QskSkin* QskFluent2SkinFactory::createSkin( const QString& skinName ) { - QskSkin::ColorScheme colorScheme; + if ( QString::compare( skinName, name, Qt::CaseInsensitive ) == 0 ) + return new QskFluent2Skin(); - if ( QString::compare( skinName, nameLight, Qt::CaseInsensitive ) == 0 ) - { - colorScheme = QskSkin::LightScheme; - } - else if ( QString::compare( skinName, nameDark, Qt::CaseInsensitive ) == 0 ) - { - colorScheme = QskSkin::DarkScheme; - } - else - { - return nullptr; - } - - struct - { - QskSkin::ColorScheme scheme; - QskFluent2Theme::BaseColors baseColors; - QskFluent2Theme::AccentColors accentColors; - - QskFluent2Theme theme() const { return { scheme, baseColors, accentColors }; } - } colors[2]; - - switch( colorScheme ) - { - case QskSkin::LightScheme: - { - colors[0].scheme = colorScheme; - colors[0].baseColors = { rgbGray( 243 ), rgbGray( 249 ), rgbGray( 238 ) }; - colors[0].accentColors = { 0xff0078d4, 0xff005eb7, 0xff003d92, 0xff001968 }; - - colors[1].scheme = colorScheme; - colors[1].baseColors = { rgbGray( 249 ), rgbGray( 249 ), rgbGray( 238 ) }; - colors[1].accentColors = colors[0].accentColors; - - break; - } - case QskSkin::DarkScheme: - { - colors[0].scheme = colorScheme; - colors[0].baseColors = { rgbGray( 32 ), rgbGray( 40 ), rgbGray( 28 ) }; - colors[0].accentColors = { 0xff0078d4, 0xff0093f9, 0xff60ccfe, 0xff98ecfe }; - - colors[1].scheme = colorScheme; - colors[1].baseColors = { rgbGray( 40 ), rgbGray( 44 ), rgbGray( 28 ) }; - colors[1].accentColors = colors[0].accentColors; - - break; - } - default:; - } - - auto skin = new QskFluent2Skin(); - - skin->addTheme( QskAspect::Body, colors[0].theme() ); - skin->addTheme( QskAspect::Header, colors[1].theme() ); - skin->addTheme( QskAspect::Footer, colors[1].theme() ); - - return skin; + return nullptr; } #include "moc_QskFluent2SkinFactory.cpp" diff --git a/designsystems/fluent2/metadata.json b/designsystems/fluent2/metadata.json index 6eb6982c..26b35df1 100644 --- a/designsystems/fluent2/metadata.json +++ b/designsystems/fluent2/metadata.json @@ -1,5 +1,4 @@ { "FactoryId": "Fluent2Factory", - "Skins": [ { "Name": "Fluent2 Light", "Scheme": "Light" }, - { "Name": "Fluent2 Dark", "Scheme": "Dark" } ] + "Skins": [ "Fluent2" ] } diff --git a/designsystems/fusion/QskFusionSkin.cpp b/designsystems/fusion/QskFusionSkin.cpp index d356e59d..c26e4215 100644 --- a/designsystems/fusion/QskFusionSkin.cpp +++ b/designsystems/fusion/QskFusionSkin.cpp @@ -1297,14 +1297,24 @@ void Editor::setupSubWindow() setAnimation( Q::Panel | A::Position, 100, QEasingCurve::OutCubic ); } -QskFusionSkin::QskFusionSkin( QskSkin::ColorScheme colorScheme, QObject* parent ) +QskFusionSkin::QskFusionSkin( QObject* parent ) : Inherited( parent ) { +} + +QskFusionSkin::~QskFusionSkin() +{ +} + +void QskFusionSkin::initHints() +{ + clearHints(); + using P = QPalette; setupFonts( QStringLiteral( "Roboto" ) ); - const QskFusionPalette palette( colorScheme ); + const QskFusionPalette palette( colorScheme() ); setGraphicColor( GraphicNormal, palette.active( P::Text ) ); setGraphicColor( GraphicDisabled, palette.disabled( P::Text ) ); @@ -1316,10 +1326,6 @@ QskFusionSkin::QskFusionSkin( QskSkin::ColorScheme colorScheme, QObject* parent editor.setup(); } -QskFusionSkin::~QskFusionSkin() -{ -} - void QskFusionSkin::setGraphicColor( GraphicRole role, QRgb rgb ) { QskColorFilter colorFilter; diff --git a/designsystems/fusion/QskFusionSkin.h b/designsystems/fusion/QskFusionSkin.h index 479127c7..c3feb9e7 100644 --- a/designsystems/fusion/QskFusionSkin.h +++ b/designsystems/fusion/QskFusionSkin.h @@ -16,7 +16,7 @@ class QSK_FUSION_EXPORT QskFusionSkin : public QskSkin using Inherited = QskSkin; public: - QskFusionSkin( QskSkin::ColorScheme, QObject* parent = nullptr ); + QskFusionSkin( QObject* parent = nullptr ); ~QskFusionSkin() override; enum GraphicRole @@ -27,6 +27,9 @@ class QSK_FUSION_EXPORT QskFusionSkin : public QskSkin GraphicError }; + protected: + void initHints() override; + private: void setGraphicColor( GraphicRole, QRgb ); }; diff --git a/designsystems/fusion/QskFusionSkinFactory.cpp b/designsystems/fusion/QskFusionSkinFactory.cpp index 87f0ab56..5962e2f4 100644 --- a/designsystems/fusion/QskFusionSkinFactory.cpp +++ b/designsystems/fusion/QskFusionSkinFactory.cpp @@ -6,8 +6,7 @@ #include "QskFusionSkinFactory.h" #include "QskFusionSkin.h" -static const QStringList fusionSkinNames = - { QStringLiteral( "Fusion Light" ), QStringLiteral( "Fusion Dark" ) }; +static const QString name = QStringLiteral( "Fusion" ); QskFusionSkinFactory::QskFusionSkinFactory( QObject* parent ) : QskSkinFactory( parent ) @@ -20,16 +19,13 @@ QskFusionSkinFactory::~QskFusionSkinFactory() QStringList QskFusionSkinFactory::skinNames() const { - return fusionSkinNames; + return { name }; } QskSkin* QskFusionSkinFactory::createSkin( const QString& skinName ) { - if ( QString::compare( skinName, fusionSkinNames[0], Qt::CaseInsensitive ) == 0 ) - return new QskFusionSkin( QskSkin::LightScheme ); - - if ( QString::compare( skinName, fusionSkinNames[1], Qt::CaseInsensitive ) == 0 ) - return new QskFusionSkin( QskSkin::DarkScheme ); + if ( QString::compare( skinName, name, Qt::CaseInsensitive ) == 0 ) + return new QskFusionSkin(); return nullptr; } diff --git a/designsystems/fusion/metadata.json b/designsystems/fusion/metadata.json index 9c2912d4..3071216f 100644 --- a/designsystems/fusion/metadata.json +++ b/designsystems/fusion/metadata.json @@ -1,5 +1,4 @@ { "FactoryId": "FusionFactory", - "Skins": [ { "Name": "Fusion Light", "Scheme": "Light" }, - { "Name": "Fusion Dark", "Scheme": "Dark" } ] + "Skins": [ "Fusion" ] } diff --git a/designsystems/material3/QskMaterial3Skin.cpp b/designsystems/material3/QskMaterial3Skin.cpp index c9b868d5..2f3ac9e0 100644 --- a/designsystems/material3/QskMaterial3Skin.cpp +++ b/designsystems/material3/QskMaterial3Skin.cpp @@ -76,9 +76,9 @@ namespace Q_GADGET public: - Editor( QskSkinHintTable* table, const QskMaterial3Theme& palette ) + Editor( QskSkinHintTable* table, const QskMaterial3Theme& theme ) : QskSkinHintTableEditor( table ) - , m_pal( palette ) + , m_pal( theme ) { } @@ -1393,14 +1393,9 @@ QskMaterial3Theme::QskMaterial3Theme( QskSkin::ColorScheme colorScheme, shapeExtraSmallTop = QskBoxShapeMetrics( 4_dp, 4_dp, 0, 0 ); } -QskMaterial3Skin::QskMaterial3Skin( const QskMaterial3Theme& palette, QObject* parent ) +QskMaterial3Skin::QskMaterial3Skin( QObject* parent ) : Inherited( parent ) { - setupFonts(); - setupGraphicFilters( palette ); - - Editor editor( &hintTable(), palette ); - editor.setup(); } QskMaterial3Skin::~QskMaterial3Skin() @@ -1429,16 +1424,27 @@ void QskMaterial3Skin::setGraphicColor( GraphicRole role, QRgb rgb ) setGraphicFilter( role, colorFilter ); } -void QskMaterial3Skin::setupGraphicFilters( const QskMaterial3Theme& palette ) +void QskMaterial3Skin::setupGraphicFilters( const QskMaterial3Theme& theme ) { - setGraphicColor( GraphicRoleOnPrimary, palette.onPrimary ); - setGraphicColor( GraphicRoleOnSecondaryContainer, palette.onSecondaryContainer ); - setGraphicColor( GraphicRoleOnError, palette.onError ); - setGraphicColor( GraphicRoleOnSurface, palette.onSurface ); - setGraphicColor( GraphicRoleOnSurface38, palette.onSurface38 ); - setGraphicColor( GraphicRoleOnSurfaceVariant, palette.onSurfaceVariant ); - setGraphicColor( GraphicRolePrimary, palette.primary ); - setGraphicColor( GraphicRoleSurface, palette.surface ); + setGraphicColor( GraphicRoleOnPrimary, theme.onPrimary ); + setGraphicColor( GraphicRoleOnSecondaryContainer, theme.onSecondaryContainer ); + setGraphicColor( GraphicRoleOnError, theme.onError ); + setGraphicColor( GraphicRoleOnSurface, theme.onSurface ); + setGraphicColor( GraphicRoleOnSurface38, theme.onSurface38 ); + setGraphicColor( GraphicRoleOnSurfaceVariant, theme.onSurfaceVariant ); + setGraphicColor( GraphicRolePrimary, theme.primary ); + setGraphicColor( GraphicRoleSurface, theme.surface ); +} + +void QskMaterial3Skin::initHints() +{ + const QskMaterial3Theme theme( colorScheme() ); + + setupFonts(); + setupGraphicFilters( theme ); + + Editor editor( &hintTable(), theme ); + editor.setup(); } #include "moc_QskMaterial3Skin.cpp" diff --git a/designsystems/material3/QskMaterial3Skin.h b/designsystems/material3/QskMaterial3Skin.h index bcdf3325..95a89310 100644 --- a/designsystems/material3/QskMaterial3Skin.h +++ b/designsystems/material3/QskMaterial3Skin.h @@ -103,7 +103,7 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin using Inherited = QskSkin; public: - QskMaterial3Skin( const QskMaterial3Theme&, QObject* parent = nullptr ); + QskMaterial3Skin( QObject* parent = nullptr ); ~QskMaterial3Skin() override; enum GraphicRole @@ -132,6 +132,9 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin static constexpr QskAspect::Variation Outlined = QskAspect::Small; static constexpr QskAspect::Variation Text = QskAspect::Tiny; + protected: + void initHints() override; + private: void setupFonts(); void setupGraphicFilters( const QskMaterial3Theme& ); diff --git a/designsystems/material3/QskMaterial3SkinFactory.cpp b/designsystems/material3/QskMaterial3SkinFactory.cpp index 16c2f6dd..3f3e6653 100644 --- a/designsystems/material3/QskMaterial3SkinFactory.cpp +++ b/designsystems/material3/QskMaterial3SkinFactory.cpp @@ -6,8 +6,7 @@ #include "QskMaterial3SkinFactory.h" #include "QskMaterial3Skin.h" -static const QString materialLightSkinName = QStringLiteral( "Material3 Light" ); -static const QString materialDarkSkinName = QStringLiteral( "Material3 Dark" ); +static const QString name = QStringLiteral( "Material3" ); QskMaterial3SkinFactory::QskMaterial3SkinFactory( QObject* parent ) : QskSkinFactory( parent ) @@ -20,21 +19,13 @@ QskMaterial3SkinFactory::~QskMaterial3SkinFactory() QStringList QskMaterial3SkinFactory::skinNames() const { - return { materialLightSkinName, materialDarkSkinName }; + return { name }; } QskSkin* QskMaterial3SkinFactory::createSkin( const QString& skinName ) { - if ( QString::compare( skinName, materialLightSkinName, Qt::CaseInsensitive ) == 0 ) - { - QskMaterial3Theme theme( QskSkin::LightScheme ); - return new QskMaterial3Skin( theme ); - } - else if ( QString::compare( skinName, materialDarkSkinName, Qt::CaseInsensitive ) == 0 ) - { - QskMaterial3Theme theme( QskSkin::DarkScheme ); - return new QskMaterial3Skin( theme ); - } + if ( QString::compare( skinName, name, Qt::CaseInsensitive ) == 0 ) + return new QskMaterial3Skin(); return nullptr; } diff --git a/designsystems/material3/metadata.json b/designsystems/material3/metadata.json index ef789842..8fc2ab9d 100644 --- a/designsystems/material3/metadata.json +++ b/designsystems/material3/metadata.json @@ -1,5 +1,4 @@ { "FactoryId": "Material3Factory", - "Skins": [ { "Name": "Material3 Light", "Scheme": "Light" }, - { "Name": "Material3 Dark", "Scheme": "Dark" } ] + "Skins": [ "Material3" ] } diff --git a/examples/iotdashboard/Skin.cpp b/examples/iotdashboard/Skin.cpp index f369c58f..24392fe6 100644 --- a/examples/iotdashboard/Skin.cpp +++ b/examples/iotdashboard/Skin.cpp @@ -57,23 +57,27 @@ namespace } } -Skin::Skin( const Palette& palette, QObject* parent ) +Skin::Skin( QObject* parent ) : QskSkin( parent ) { + setObjectName( "iot" ); + declareSkinlet< CircularProgressBar, CircularProgressBarSkinlet >(); declareSkinlet< Diagram, DiagramSkinlet >(); declareSkinlet< LightDisplay, LightDisplaySkinlet >(); declareSkinlet< StorageBar, StorageBarSkinlet >(); - initHints( palette ); + setColorScheme( LightScheme ); } Skin::~Skin() { } -void Skin::initHints( const Palette& palette ) +void Skin::initHints() { + const auto palette = Skin::palette( colorScheme() ); + QFontDatabase db; db.addApplicationFont( ":/fonts/ProximaNova-Regular.otf" ); // ### use fontconfig @@ -311,39 +315,41 @@ void Skin::initHints( const Palette& palette ) } } -Skin::Palette DaytimeSkin::palette() const +Skin::Palette Skin::palette( QskSkin::ColorScheme colorScheme ) const { - return { - 0xff6d7bfb, - 0xfffbfbfb, - Qt::white, - 0xfff7f7f7, - 0xffe5e5e5, - 0xfff4f4f4, - Qt::black, - 0xffe5e5e5, - 0xffc4c4c4, - { { { 0.0, 0xffff3122 }, { 0.2, 0xfffeeeb7 }, { 0.3, 0xffa7b0ff }, { 0.5, 0xff6776ff }, - { 1.0, Qt::black } } }, - 0x10000000, - 0xffdddddd - }; -} - -Skin::Palette NighttimeSkin::palette() const -{ - return { - 0xff2937A7, - 0xff040404, - Qt::black, - 0xff0a0a0a, - 0xff1a1a1a, - 0xff0c0c0c, - Qt::white, - 0xff4a4a4a, - 0xff555555, - { { { 0.0, 0xff991100 }, { 0.2, 0xff9a7a57 }, { 0.5, 0xff3726af }, { 1.0, Qt::black } } }, - 0x10ffffff, - 0xff222222 - }; + if ( colorScheme == DarkScheme ) + { + return { + 0xff2937A7, + 0xff040404, + Qt::black, + 0xff0a0a0a, + 0xff1a1a1a, + 0xff0c0c0c, + Qt::white, + 0xff4a4a4a, + 0xff555555, + { { { 0.0, 0xff991100 }, { 0.2, 0xff9a7a57 }, { 0.5, 0xff3726af }, { 1.0, Qt::black } } }, + 0x10ffffff, + 0xff222222 + }; + } + else + { + return { + 0xff6d7bfb, + 0xfffbfbfb, + Qt::white, + 0xfff7f7f7, + 0xffe5e5e5, + 0xfff4f4f4, + Qt::black, + 0xffe5e5e5, + 0xffc4c4c4, + { { { 0.0, 0xffff3122 }, { 0.2, 0xfffeeeb7 }, { 0.3, 0xffa7b0ff }, { 0.5, 0xff6776ff }, + { 1.0, Qt::black } } }, + 0x10000000, + 0xffdddddd + }; + } } diff --git a/examples/iotdashboard/Skin.h b/examples/iotdashboard/Skin.h index b692f2e0..1b0d18d1 100644 --- a/examples/iotdashboard/Skin.h +++ b/examples/iotdashboard/Skin.h @@ -27,7 +27,7 @@ class Skin : public QskSkin QRgb deviceGraphic; }; - Skin( const Palette& palette, QObject* parent = nullptr ); + Skin( QObject* parent = nullptr ); ~Skin() override; enum SkinFontRole @@ -36,29 +36,8 @@ class Skin : public QskSkin }; private: - void initHints( const Palette& palette ); -}; - -class DaytimeSkin : public Skin -{ - public: - DaytimeSkin( QObject* parent = nullptr ) - : Skin( palette(), parent ) - { - } - - private: - Palette palette() const; -}; - -class NighttimeSkin : public Skin -{ - public: - NighttimeSkin( QObject* parent = nullptr ) - : Skin( palette(), parent ) - { - } - - private: - Palette palette() const; + void initHints() override; + + Palette palette( ColorScheme ) const; + void initHints( const Palette& ); }; diff --git a/examples/iotdashboard/main.cpp b/examples/iotdashboard/main.cpp index 46410360..bbd0ddaa 100644 --- a/examples/iotdashboard/main.cpp +++ b/examples/iotdashboard/main.cpp @@ -11,50 +11,15 @@ #include #endif +#include #include #include -#include -#include #include #include #include #include -namespace -{ - class SkinFactory : public QskSkinFactory - { - Q_OBJECT - - public: - SkinFactory( QObject* parent = nullptr ) - : QskSkinFactory( parent ) - { - } - - QStringList skinNames() const override - { - return { "DaytimeSkin", "NighttimeSkin" }; - } - - QskSkin* createSkin( const QString& skinName ) override - { - if( skinName == "DaytimeSkin" ) - { - return new DaytimeSkin; - } - - if( skinName == "NighttimeSkin" ) - { - return new NighttimeSkin; - } - - return nullptr; - } - }; -} - int main( int argc, char* argv[] ) { #ifdef ITEM_STATISTICS @@ -64,27 +29,14 @@ int main( int argc, char* argv[] ) QGuiApplication app( argc, argv ); qskSetup->setItemUpdateFlag( QskQuickItem::PreferRasterForTextures, true ); + qskSkinManager->setSkin( new Skin() ); Qsk::addGraphicProvider( QString(), new GraphicProvider() ); - // disable default skins - qskSkinManager->setPluginPaths( QStringList() ); // no plugins -#if 1 - // we should find a better way: TODO ... - qskSkinManager->unregisterFactory( "material3factory" ); - qskSkinManager->unregisterFactory( "fusionfactory" ); - qskSkinManager->unregisterFactory( "fluent2factory" ); -#endif - - qskSkinManager->registerFactory( - QStringLiteral( "SampleSkinFactory" ), new SkinFactory() ); - - qskSkinManager->setSkin( "DaytimeSkin" ); - #ifdef USE_SHORTCUTS - // With CTRL-B you can rotate a couple of visual debug modes - SkinnyShortcut::enable( SkinnyShortcut::RotateSkin | SkinnyShortcut::DebugBackground | - SkinnyShortcut::DebugStatistics | SkinnyShortcut::Quit ); + SkinnyShortcut::enable( SkinnyShortcut::ChangeColorScheme + | SkinnyShortcut::DebugBackground | SkinnyShortcut::DebugStatistics + | SkinnyShortcut::Quit ); #endif MainWindow window; @@ -103,5 +55,3 @@ int main( int argc, char* argv[] ) return app.exec(); } - -#include "main.moc" diff --git a/examples/mycontrols/MySkin.cpp b/examples/mycontrols/MySkin.cpp index fadc8d79..eb0f6176 100644 --- a/examples/mycontrols/MySkin.cpp +++ b/examples/mycontrols/MySkin.cpp @@ -179,8 +179,8 @@ namespace { class SkinBlue : public MySkin { - public: - SkinBlue() + protected: + void initHints() override { using namespace QskRgb; @@ -201,8 +201,8 @@ namespace class SkinPink : public MySkin { - public: - SkinPink() + protected: + void initHints() override { using namespace QskRgb; diff --git a/examples/mycontrols/main.cpp b/examples/mycontrols/main.cpp index 216ce3be..425c953c 100644 --- a/examples/mycontrols/main.cpp +++ b/examples/mycontrols/main.cpp @@ -17,8 +17,9 @@ #include #include #include -#include +#include #include +#include #include diff --git a/playground/dials/CMakeLists.txt b/playground/dials/CMakeLists.txt index a7da047e..6af239ad 100644 --- a/playground/dials/CMakeLists.txt +++ b/playground/dials/CMakeLists.txt @@ -4,7 +4,7 @@ ############################################################################ set(SOURCES - SkinFactory.h SkinFactory.cpp + Skin.h Skin.cpp Dial.h Dial.cpp DialSkinlet.h DialSkinlet.cpp Dashboard.h Dashboard.cpp diff --git a/playground/dials/Skin.cpp b/playground/dials/Skin.cpp new file mode 100644 index 00000000..7a0e79f9 --- /dev/null +++ b/playground/dials/Skin.cpp @@ -0,0 +1,70 @@ +/****************************************************************************** + * QSkinny - Copyright (C) The authors + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#include "Skin.h" +#include "Dial.h" +#include "DialSkinlet.h" + +#include +#include +#include +#include +#include + +static inline QFont qskFont( qreal pointSize ) +{ + QFont font( "Roboto" ); + font.setPointSizeF( pointSize / qskDpToPixels( 1.0 ) ); + return font; +} + +Skin::Skin() +{ + declareSkinlet< Dial, DialSkinlet >(); + initHints(); +} + +void Skin::initHints() +{ + using namespace QskRgb; + + setFont( QskSkin::DefaultFont, qskFont( 13 ) ); + setFont( QskSkin::LargeFont, qskFont( 20 ) ); + + const auto rgb1 = qRgb( 1, 16, 27 ); // Maastricht blue + const auto rgb2 = qRgb( 255, 0, 22 ); // Ruddy + const auto rgb3 = qRgb( 41, 234, 212 ); // Turquoise + const auto rgb4 = qRgb( 253, 255, 252 ); // baby powder + + QskSkinHintTableEditor ed( &hintTable() ); + + ed.setColor( QskTextLabel::Text, rgb4 ); + + { + using Q = Dial; + + ed.setBoxBorderMetrics( Q::Panel, 2 ); + ed.setBoxShape( Q::Panel, 100, Qt::RelativeSize ); + ed.setGradient( Q::Panel, rgb1 ); + ed.setBoxBorderColors( Q::Panel, rgb3 ); + + ed.setBoxBorderMetrics( Q::Knob, 2 ); + ed.setStrutSize( Q::Knob, 30, 30 ); + ed.setBoxShape( Q::Knob, 100, Qt::RelativeSize ); + + QskGradient gradient( rgb2, rgb1 ); + gradient.setLinearDirection( 0.0, 0.0, 1.0, 1.0 ); + ed.setGradient( Q::Knob, gradient ); + + ed.setMetric( Q::Needle | QskAspect::Size, 2 ); + ed.setMetric( Q::Needle | QskAspect::Margin, 10 ); + ed.setColor( Q::Needle, rgb2 ); + + ed.setSpacing( Q::TickLabels, 4 ); + ed.setStrutSize( Q::TickLabels, 2, 15 ); + ed.setColor( Q::TickLabels, rgb4 ); + ed.setFontRole( Q::TickLabels, QskSkin::SmallFont ); + } +} diff --git a/playground/dials/SkinFactory.h b/playground/dials/Skin.h similarity index 61% rename from playground/dials/SkinFactory.h rename to playground/dials/Skin.h index 8d6209df..b874f037 100644 --- a/playground/dials/SkinFactory.h +++ b/playground/dials/Skin.h @@ -5,13 +5,12 @@ #pragma once -#include +#include -class SkinFactory : public QskSkinFactory +class Skin : public QskSkin { - Q_OBJECT - public: - QStringList skinNames() const override; - QskSkin* createSkin( const QString& ) override; + Skin(); + + void initHints() override; }; diff --git a/playground/dials/SkinFactory.cpp b/playground/dials/SkinFactory.cpp deleted file mode 100644 index c03ef792..00000000 --- a/playground/dials/SkinFactory.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************** - * QSkinny - Copyright (C) The authors - * SPDX-License-Identifier: BSD-3-Clause - *****************************************************************************/ - -#include "SkinFactory.h" - -#include "Dial.h" -#include "DialSkinlet.h" - -#include -#include -#include -#include -#include -#include - -namespace -{ - inline QFont qskFont( qreal pointSize ) - { - QFont font( "Roboto" ); - font.setPointSizeF( pointSize / qskDpToPixels( 1.0 ) ); - return font; - } - - class Skin : public QskSkin - { - public: - Skin() - { - using namespace QskRgb; - - declareSkinlet< Dial, DialSkinlet >(); - - setFont( QskSkin::DefaultFont, qskFont( 13 ) ); - setFont( QskSkin::LargeFont, qskFont( 20 ) ); - - const auto rgb1 = qRgb( 1, 16, 27 ); // Maastricht blue - const auto rgb2 = qRgb( 255, 0, 22 ); // Ruddy - const auto rgb3 = qRgb( 41, 234, 212 ); // Turquoise - const auto rgb4 = qRgb( 253, 255, 252 ); // baby powder - - QskSkinHintTableEditor ed( &hintTable() ); - - ed.setColor( QskTextLabel::Text, rgb4 ); - - { - using Q = Dial; - - ed.setBoxBorderMetrics( Q::Panel, 2 ); - ed.setBoxShape( Q::Panel, 100, Qt::RelativeSize ); - ed.setGradient( Q::Panel, rgb1 ); - ed.setBoxBorderColors( Q::Panel, rgb3 ); - - ed.setBoxBorderMetrics( Q::Knob, 2 ); - ed.setStrutSize( Q::Knob, 30, 30 ); - ed.setBoxShape( Q::Knob, 100, Qt::RelativeSize ); - - QskGradient gradient( rgb2, rgb1 ); - gradient.setLinearDirection( 0.0, 0.0, 1.0, 1.0 ); - ed.setGradient( Q::Knob, gradient ); - - ed.setMetric( Q::Needle | QskAspect::Size, 2 ); - ed.setMetric( Q::Needle | QskAspect::Margin, 10 ); - ed.setColor( Q::Needle, rgb2 ); - - ed.setSpacing( Q::TickLabels, 4 ); - ed.setStrutSize( Q::TickLabels, 2, 15 ); - ed.setColor( Q::TickLabels, rgb4 ); - ed.setFontRole( Q::TickLabels, QskSkin::SmallFont ); - } - } - }; - -} - -QStringList SkinFactory::skinNames() const -{ - return { "Skin" }; -} - -QskSkin* SkinFactory::createSkin( const QString& skinName ) -{ - if ( skinName == "Skin" ) - return new Skin(); - - return nullptr; -} - -#include "moc_SkinFactory.cpp" diff --git a/playground/dials/main.cpp b/playground/dials/main.cpp index be866f01..3b214049 100644 --- a/playground/dials/main.cpp +++ b/playground/dials/main.cpp @@ -4,7 +4,7 @@ *****************************************************************************/ #include "Dashboard.h" -#include "SkinFactory.h" +#include "Skin.h" #include @@ -44,12 +44,11 @@ int main( int argc, char** argv ) QskObjectCounter counter( true ); #endif - qskSkinManager->setPluginPaths( QStringList() ); // no skin plugins - qskSkinManager->registerFactory( QStringLiteral( "sample" ), new SkinFactory() ); - QGuiApplication app( argc, argv ); + qskSkinManager->setSkin( new Skin() ); - SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts ); + SkinnyShortcut::enable( SkinnyShortcut::DebugBackground | + SkinnyShortcut::DebugStatistics | SkinnyShortcut::Quit ); Window window; window.show(); diff --git a/src/controls/QskSkin.cpp b/src/controls/QskSkin.cpp index 1d9952bc..7961d541 100644 --- a/src/controls/QskSkin.cpp +++ b/src/controls/QskSkin.cpp @@ -153,6 +153,8 @@ class QskSkin::PrivateData QHash< int, QskColorFilter > graphicFilters; QskGraphicProviderMap graphicProviders; + + int colorScheme = -1; // uninitialized }; QskSkin::QskSkin( QObject* parent ) @@ -213,6 +215,27 @@ QskSkin::~QskSkin() { } +QskSkin::ColorScheme QskSkin::colorScheme() const +{ + if ( m_data->colorScheme < 0 ) + return QskSkin::UnknownScheme; + + return static_cast< QskSkin::ColorScheme >( m_data->colorScheme ); +} + +void QskSkin::setColorScheme( ColorScheme colorScheme ) +{ + if ( colorScheme == m_data->colorScheme ) + return; + + m_data->colorScheme = colorScheme; + + clearHints(); + initHints(); + + Q_EMIT colorSchemeChanged( colorScheme ); +} + void QskSkin::setSkinHint( QskAspect aspect, const QVariant& skinHint ) { m_data->hintTable.setHint( aspect, skinHint ); @@ -344,6 +367,14 @@ bool QskSkin::hasGraphicProvider() const return m_data->graphicProviders.size() > 0; } +void QskSkin::clearHints() +{ + m_data->hintTable.clear(); + m_data->fonts.clear(); + m_data->graphicFilters.clear(); + m_data->graphicProviders.clear(); +} + QString QskSkin::dialogButtonText( int action ) const { const auto theme = qskPlatformTheme(); diff --git a/src/controls/QskSkin.h b/src/controls/QskSkin.h index 95b1cbfe..f70636b4 100644 --- a/src/controls/QskSkin.h +++ b/src/controls/QskSkin.h @@ -94,6 +94,18 @@ class QSK_EXPORT QskSkin : public QObject const QHash< int, QFont >& fonts() const; const QHash< int, QskColorFilter >& graphicFilters() const; + ColorScheme colorScheme() const; + + public Q_SLOTS: + void setColorScheme( ColorScheme ); + + Q_SIGNALS: + void colorSchemeChanged( ColorScheme ); + + protected: + void clearHints(); + virtual void initHints() = 0; + private: void declareSkinlet( const QMetaObject* metaObject, const QMetaObject* skinletMetaObject ); diff --git a/src/controls/QskSkinManager.cpp b/src/controls/QskSkinManager.cpp index c3c4d92c..24f3d003 100644 --- a/src/controls/QskSkinManager.cpp +++ b/src/controls/QskSkinManager.cpp @@ -74,8 +74,6 @@ namespace const QLatin1String TokenData( "MetaData" ); const QLatin1String TokenFactoryId( "FactoryId" ); const QLatin1String TokenSkins( "Skins" ); - const QLatin1String TokenName( "Name" ); - const QLatin1String TokenScheme( "Scheme" ); const QLatin1String InterfaceId( QskSkinFactoryIID ); @@ -95,42 +93,7 @@ namespace const auto skins = factoryData.value( TokenSkins ).toArray(); for ( const auto& skin : skins ) - { - const auto& skinObject = skin.toObject(); - const auto& name = skinObject.value( TokenName ).toString(); - -#if QT_VERSION >= QT_VERSION_CHECK( 6, 5, 0 ) - const auto& schemeString = skinObject.value( TokenScheme ).toString(); - Qt::ColorScheme scheme; - - if( schemeString == QStringLiteral( "Light" ) ) - { - scheme = Qt::ColorScheme::Light; - } - else if( schemeString == QStringLiteral( "Dark" ) ) - { - scheme = Qt::ColorScheme::Dark; - } - else - { - scheme = Qt::ColorScheme::Unknown; - } - - const auto systemScheme = QGuiApplication::styleHints()->colorScheme(); - - if( scheme == systemScheme ) - { - m_skinNames.prepend( name ); - } - else - { - m_skinNames.append( name ); - } -#else - Q_UNUSED( TokenScheme ) - m_skinNames += name; -#endif - } + m_skinNames += skin.toString(); } return !m_skinNames.isEmpty(); @@ -518,7 +481,8 @@ QStringList QskSkinManager::skinNames() const return m_data->factoryMap.skinNames(); } -QskSkin* QskSkinManager::createSkin( const QString& skinName ) const +QskSkin* QskSkinManager::createSkin( + const QString& skinName, QskSkin::ColorScheme colorScheme ) const { m_data->ensurePlugins(); @@ -543,18 +507,56 @@ QskSkin* QskSkinManager::createSkin( const QString& skinName ) const { skin = factory->createSkin( name ); if ( skin ) + { skin->setObjectName( name ); + + if ( colorScheme == QskSkin::UnknownScheme ) + { +#if QT_VERSION >= QT_VERSION_CHECK( 6, 5, 0 ) + colorScheme = static_cast< QskSkin::ColorScheme >( + QGuiApplication::styleHints()->colorScheme() ); +#else + colorScheme = QskSkin::LightScheme; +#endif + } + + skin->setColorScheme( colorScheme ); + } } return skin; } +void QskSkinManager::setSkin( QskSkin* skin ) +{ + if ( m_data->skin == skin ) + return; + + if ( skin && skin->parent() == nullptr ) + skin->setParent( this ); + + const auto oldSkin = m_data->skin; + m_data->skin = skin; + + if ( oldSkin ) + { + if ( oldSkin->parent() == this ) + delete oldSkin; + } + + Q_EMIT skinChanged( skin ); +} + QskSkin* QskSkinManager::setSkin( const QString& name ) { if ( m_data->skin && ( m_data->skin->objectName() == name ) ) return m_data->skin; - auto skin = createSkin( name ); + auto colorScheme = QskSkin::UnknownScheme; + if ( m_data->skin ) + colorScheme = m_data->skin->colorScheme(); + + auto skin = createSkin( name, colorScheme ); if ( skin == nullptr ) return nullptr; diff --git a/src/controls/QskSkinManager.h b/src/controls/QskSkinManager.h index 8a3d1b63..d3992293 100644 --- a/src/controls/QskSkinManager.h +++ b/src/controls/QskSkinManager.h @@ -7,11 +7,11 @@ #define QSK_SKIN_MANAGER_H #include "QskGlobal.h" +#include "QskSkin.h" #include #include -class QskSkin; class QskSkinFactory; #if defined( qskSkinManager ) @@ -39,8 +39,10 @@ class QSK_EXPORT QskSkinManager : public QObject QStringList skinNames() const; - QskSkin* createSkin( const QString& name ) const; + QskSkin* createSkin( const QString& skinName, + QskSkin::ColorScheme = QskSkin::UnknownScheme ) const; + void setSkin( QskSkin* ); QskSkin* skin(); QskSkin* setSkin( const QString& ); diff --git a/support/SkinnyNamespace.cpp b/support/SkinnyNamespace.cpp index 1fd93d00..ae84756c 100644 --- a/support/SkinnyNamespace.cpp +++ b/support/SkinnyNamespace.cpp @@ -162,6 +162,23 @@ void Skinny::setSkin( int index, QskAnimationHint hint ) } } +void Skinny::changeColorScheme( QskAnimationHint hint ) +{ + auto skin = qskSkinManager->skin(); + + QskSkinTransition transition; + transition.setMask( QskSkinTransition::Color ); + transition.setSourceSkin( skin ); + + const auto colorScheme = ( skin->colorScheme() == QskSkin::LightScheme ) + ? QskSkin::DarkScheme : QskSkin::LightScheme; + + skin->setColorScheme( colorScheme ); + + transition.setTargetSkin( skin ); + transition.run( hint ); +} + void Skinny::changeFonts( int increment ) { auto skin = qskSkinManager->skin(); diff --git a/support/SkinnyNamespace.h b/support/SkinnyNamespace.h index 0aeda789..1ee27fc6 100644 --- a/support/SkinnyNamespace.h +++ b/support/SkinnyNamespace.h @@ -11,6 +11,7 @@ namespace Skinny { SKINNY_EXPORT void changeSkin( QskAnimationHint hint = 500 ); + SKINNY_EXPORT void changeColorScheme( QskAnimationHint hint = 500 ); SKINNY_EXPORT void setSkin( int index, QskAnimationHint hint = 500 ); SKINNY_EXPORT void changeFonts( int increment ); SKINNY_EXPORT void init(); diff --git a/support/SkinnyShortcut.cpp b/support/SkinnyShortcut.cpp index d7bbff01..006a69bd 100644 --- a/support/SkinnyShortcut.cpp +++ b/support/SkinnyShortcut.cpp @@ -38,6 +38,13 @@ void SkinnyShortcut::enable( Types types ) cout << "CTRL-S to change the skin." << endl; } + if ( types & ChangeColorScheme ) + { + QskShortcutMap::addShortcut( QKeySequence( Qt::CTRL | Qt::Key_L ), + false, &s_shortcut, [] { Skinny::changeColorScheme(); } ); + cout << "CTRL-L to change the color scheme." << endl; + } + if ( types & ChangeFonts ) { QskShortcutMap::addShortcut( QKeySequence( Qt::CTRL | Qt::Key_F ), diff --git a/support/SkinnyShortcut.h b/support/SkinnyShortcut.h index 84587d7e..4de823a6 100644 --- a/support/SkinnyShortcut.h +++ b/support/SkinnyShortcut.h @@ -15,14 +15,16 @@ class SKINNY_EXPORT SkinnyShortcut : public QObject public: enum Type { - Quit = 1 << 0, - RotateSkin = 1 << 1, - ChangeFonts = 1 << 2, - DebugBackground = 1 << 3, - DebugStatistics = 1 << 4, + Quit = 1 << 0, + RotateSkin = 1 << 1, + ChangeColorScheme = 1 << 2, + ChangeFonts = 1 << 3, + DebugBackground = 1 << 4, + DebugStatistics = 1 << 5, DebugShortcuts = DebugBackground | DebugStatistics, - AllShortcuts = Quit | RotateSkin | ChangeFonts | DebugBackground | DebugStatistics + AllShortcuts = Quit | RotateSkin | ChangeColorScheme + | ChangeFonts | DebugBackground | DebugStatistics }; Q_ENUM( Type )