Qt::ColorScheme handling added to QskSkin - no more multiple skins for

dark/light.
This commit is contained in:
Uwe Rathmann 2024-01-30 14:52:40 +01:00
parent 3873e07765
commit 5aa46b3ccc
30 changed files with 366 additions and 400 deletions

View File

@ -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" ) );

View File

@ -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 );

View File

@ -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"

View File

@ -1,5 +1,4 @@
{
"FactoryId": "Fluent2Factory",
"Skins": [ { "Name": "Fluent2 Light", "Scheme": "Light" },
{ "Name": "Fluent2 Dark", "Scheme": "Dark" } ]
"Skins": [ "Fluent2" ]
}

View File

@ -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;

View File

@ -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 );
};

View File

@ -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;
}

View File

@ -1,5 +1,4 @@
{
"FactoryId": "FusionFactory",
"Skins": [ { "Name": "Fusion Light", "Scheme": "Light" },
{ "Name": "Fusion Dark", "Scheme": "Dark" } ]
"Skins": [ "Fusion" ]
}

View File

@ -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"

View File

@ -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& );

View File

@ -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;
}

View File

@ -1,5 +1,4 @@
{
"FactoryId": "Material3Factory",
"Skins": [ { "Name": "Material3 Light", "Scheme": "Light" },
{ "Name": "Material3 Dark", "Scheme": "Dark" } ]
"Skins": [ "Material3" ]
}

View File

@ -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
};
}
}

View File

@ -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& );
};

View File

@ -11,50 +11,15 @@
#include <SkinnyShortcut.h>
#endif
#include <QskSkinManager.h>
#include <QskSetup.h>
#include <QskShortcutMap.h>
#include <QskSkinFactory.h>
#include <QskSkinManager.h>
#include <QskWindow.h>
#include <QskObjectCounter.h>
#include <QGuiApplication>
#include <QTimer>
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"

View File

@ -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;

View File

@ -17,8 +17,9 @@
#include <QskSkinManager.h>
#include <QskAnimationHint.h>
#include <QskSkinTransition.h>
#include <QskSetup.h>
#include <QskSkinManager.h>
#include <QskSkin.h>
#include <QskSetup.h>
#include <QGuiApplication>

View File

@ -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

70
playground/dials/Skin.cpp Normal file
View File

@ -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 <QskBoxBorderColors.h>
#include <QskTextLabel.h>
#include <QskSkinHintTableEditor.h>
#include <QskRgbValue.h>
#include <QskPlatform.h>
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 );
}
}

View File

@ -5,13 +5,12 @@
#pragma once
#include <QskSkinFactory.h>
#include <QskSkin.h>
class SkinFactory : public QskSkinFactory
class Skin : public QskSkin
{
Q_OBJECT
public:
QStringList skinNames() const override;
QskSkin* createSkin( const QString& ) override;
Skin();
void initHints() override;
};

View File

@ -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 <QskBoxBorderColors.h>
#include <QskTextLabel.h>
#include <QskSkinHintTableEditor.h>
#include <QskSkin.h>
#include <QskPlatform.h>
#include <QskRgbValue.h>
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"

View File

@ -4,7 +4,7 @@
*****************************************************************************/
#include "Dashboard.h"
#include "SkinFactory.h"
#include "Skin.h"
#include <SkinnyShortcut.h>
@ -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();

View File

@ -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();

View File

@ -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 );

View File

@ -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;

View File

@ -7,11 +7,11 @@
#define QSK_SKIN_MANAGER_H
#include "QskGlobal.h"
#include "QskSkin.h"
#include <qobject.h>
#include <memory>
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& );

View File

@ -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();

View File

@ -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();

View File

@ -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 ),

View File

@ -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 )