Improve material theme

This commit is contained in:
Clemens Manert 2022-02-17 21:54:56 +01:00
parent 9cc840f0f8
commit 6f42dae3e3
No known key found for this signature in database
GPG Key ID: 9197EAE8F85E3A18
5 changed files with 287 additions and 257 deletions

View File

@ -35,7 +35,6 @@
#include <QskBoxBorderMetrics.h> #include <QskBoxBorderMetrics.h>
#include <QskBoxShapeMetrics.h> #include <QskBoxShapeMetrics.h>
#include <QskMargins.h> #include <QskMargins.h>
#include <QskRgbValue.h>
#include <QskNamespace.h> #include <QskNamespace.h>
#include <QskPlatform.h> #include <QskPlatform.h>
@ -58,45 +57,6 @@ static inline QColor qskShadedColor( const QColor color, qreal opacity )
namespace namespace
{ {
class ColorPalette
{
public:
ColorPalette( const QColor base = QColor::fromRgba( QskRgb::Grey100 ),
const QColor& accent = QColor::fromRgba( QskRgb::Blue500 ),
const QColor& contrast = QColor::fromRgba( QskRgb::White ) )
{
baseColor = base;
accentColor = accent;
contrastColor = contrast;
darker125 = baseColor.darker( 125 );
darker150 = baseColor.darker( 150 );
darker200 = baseColor.darker( 200 );
lighter125 = baseColor.lighter( 125 );
lighter150 = baseColor.lighter( 150 );
lighter200 = baseColor.lighter( 200 );
textColor = ( baseColor.value() > 128 )
? QskRgb::Black : QskRgb::White;
}
QColor accentColor;
QColor contrastColor;
QColor baseColor;
QColor lighter125;
QColor lighter150;
QColor lighter200;
QColor darker125;
QColor darker150;
QColor darker200;
QColor textColor;
};
class Editor : private QskSkinHintTableEditor class Editor : private QskSkinHintTableEditor
{ {
public: public:
@ -134,6 +94,7 @@ namespace
void setupTextLabel(); void setupTextLabel();
const ColorPalette& m_pal; const ColorPalette& m_pal;
const uint rippleSize = 30;
}; };
} }
@ -169,20 +130,20 @@ void Editor::setupControl()
using A = QskAspect; using A = QskAspect;
using Q = QskControl; using Q = QskControl;
setPadding( A::Control, 4 ); setPadding( A::Control, 11 );
setGradient( A::Control, m_pal.baseColor ); setGradient( A::Control, m_pal.background );
setColor( A::Control | A::StyleColor, m_pal.textColor ); setColor( A::Control | A::StyleColor, m_pal.onBackground );
setColor( A::Control | A::StyleColor | Q::Disabled, setColor( A::Control | A::StyleColor | Q::Disabled,
qskShadedColor( m_pal.textColor, 0.6 ) ); qskShadedColor( m_pal.onBackground, 0.6 ) );
} }
void Editor::setupBox() void Editor::setupBox()
{ {
using Q = QskBox; using Q = QskBox;
setGradient( Q::Panel, m_pal.baseColor ); setGradient( Q::Panel, m_pal.background );
setBoxShape( Q::Panel, 4 ); setBoxShape( Q::Panel, 14 );
setBoxBorderMetrics( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 0 );
} }
@ -194,7 +155,8 @@ void Editor::setupPopup()
setFlagHint( Q::Overlay | A::Style, true ); setFlagHint( Q::Overlay | A::Style, true );
const QskGradient gradient( QskGradient::Vertical, const QskGradient gradient( QskGradient::Vertical,
qskShadedColor( m_pal.accentColor, 0.45 ), qskShadedColor( m_pal.accentColor, 0.7 ) ); qskShadedColor( m_pal.secondary, 0.45 ),
qskShadedColor( m_pal.secondary, 0.7 ) );
setGradient( Q::Overlay, gradient ); setGradient( Q::Overlay, gradient );
} }
@ -204,60 +166,81 @@ void Editor::setupTextLabel()
using Q = QskTextLabel; using Q = QskTextLabel;
setAlignment( Q::Text, Qt::AlignCenter ); setAlignment( Q::Text, Qt::AlignCenter );
setColor( Q::Text, m_pal.textColor ); setColor( Q::Text, m_pal.onBackground );
setPadding( Q::Panel, 5 ); setPadding( Q::Panel, 5 );
setBoxShape( Q::Panel, 4 ); setBoxShape( Q::Panel, 4 );
setBoxBorderMetrics( Q::Panel, 2 ); setBoxBorderMetrics( Q::Panel, 2 );
setBoxBorderColors( Q::Panel, m_pal.darker125 ); setBoxBorderColors( Q::Panel, m_pal.primaryNoSaturation );
setGradient( Q::Panel, m_pal.baseColor ); setGradient( Q::Panel, m_pal.background );
} }
void Editor::setupTextInput() void Editor::setupTextInput()
{ {
using Q = QskTextInput; using Q = QskTextInput;
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignTop ); setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignTop );
setColor( Q::Text, m_pal.textColor ); setColor( Q::Text, m_pal.onBackground );
setColor( Q::PanelSelected, m_pal.accentColor );
setColor( Q::TextSelected, m_pal.contrastColor );
setPadding( Q::Panel, 5 ); setPadding( Q::Panel, 5 );
setBoxShape( Q::Panel, 4 ); setBoxShape( Q::Panel, 4, 4, 0, 0 );
setBoxBorderMetrics( Q::Panel, 2 ); setBoxBorderMetrics( Q::Panel, 0, 0, 0, 1 );
setBoxBorderColors( Q::Panel, m_pal.darker125 ); setBoxBorderColors( Q::Panel, m_pal.onBackground );
setGradient( Q::Panel, m_pal.baseColor );
setBoxBorderMetrics( Q::Panel | Q::Focused, 0, 0, 0, 2 );
setBoxBorderColors( Q::Panel | Q::Focused, m_pal.primary );
setBoxBorderMetrics( Q::Panel | Q::Editing, 0, 0, 0, 2 );
setBoxBorderColors( Q::Panel | Q::Editing, m_pal.primary );
setBoxBorderColors( Q::Panel | Q::Focused, m_pal.primary );
setColor( Q::Panel,
m_pal.elevated( m_pal.background, 1 ) );
setColor( Q::Panel | Q::Hovered,
m_pal.elevated( m_pal.background, 2 ) );
setColor( Q::Panel | Q::Focused,
m_pal.elevated( m_pal.background, 3 ) );
setColor( Q::Panel | Q::Editing,
m_pal.elevated( m_pal.background, 4 ) );
setColor( Q::Panel | Q::Disabled,
qskShadedColor( m_pal.secondaryVariantNoSaturation, m_pal.disabled ) );
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.onBackground, m_pal.disabled ) );
setBoxBorderColors( Q::Panel,
qskShadedColor( m_pal.onBackground, m_pal.disabled ) );
} }
void Editor::setupProgressBar() void Editor::setupProgressBar()
{ {
using A = QskAspect; using A = QskAspect;
using namespace QskRgb;
using Q = QskProgressBar; using Q = QskProgressBar;
auto size = qskDpiScaled( 5 );
for ( auto subControl : { Q::Groove, Q::Bar } ) for ( auto subControl : { Q::Groove, Q::Bar } )
{ {
setMetric( subControl | A::Size, 5 ); setMetric( subControl | A::Size, size );
setPadding( subControl, 0 ); setPadding( subControl, 0 );
setBoxShape( subControl, 0 ); setBoxShape( subControl, 0 );
setBoxBorderMetrics( subControl, 0 ); setBoxBorderMetrics( subControl, 0 );
} }
setGradient( Q::Groove, Grey ); setGradient( Q::Groove, m_pal.secondaryNoSaturation );
setMetric( Q::Groove | A::Size, 5 ); setMetric( Q::Groove | A::Size, size );
setGradient( Q::Bar, m_pal.accentColor ); setGradient( Q::Bar, m_pal.secondary );
setGradient( Q::Groove | Q::Disabled,
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
setGradient( Q::Bar | Q::Disabled,
qskShadedColor( m_pal.secondary, m_pal.disabled ) );
} }
void Editor::setupFocusIndicator() void Editor::setupFocusIndicator()
{ {
using Q = QskFocusIndicator; using Q = QskFocusIndicator;
setPadding( Q::Panel, 5 );
setBoxShape( Q::Panel, 4 );
setBoxBorderMetrics( Q::Panel, 2 );
setBoxBorderColors( Q::Panel, m_pal.accentColor );
setGradient( Q::Panel, QskGradient() ); setGradient( Q::Panel, QskGradient() );
} }
@ -273,7 +256,7 @@ void Editor::setupSeparator()
setMetric( aspect | A::Size, 4 ); setMetric( aspect | A::Size, 4 );
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 0 );
setGradient( aspect, m_pal.baseColor ); setGradient( aspect, m_pal.background );
} }
} }
@ -288,10 +271,15 @@ void Editor::setupPageIndicator()
setBoxShape( Q::Bullet, 100, Qt::RelativeSize ); setBoxShape( Q::Bullet, 100, Qt::RelativeSize );
setBoxBorderMetrics( Q::Bullet, 0 ); setBoxBorderMetrics( Q::Bullet, 0 );
setGradient( Q::Bullet, m_pal.lighter150 ); setGradient( Q::Bullet, m_pal.secondaryNoSaturation );
setGradient( Q::Bullet | Q::Selected, m_pal.accentColor ); setGradient( Q::Bullet | Q::Selected, m_pal.secondary );
setSpacing( Q::Panel, 5 ); setGradient( Q::Bullet | Q::Disabled,
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
setGradient( Q::Bullet | Q::Selected | Q::Disabled,
qskShadedColor( m_pal.secondary, m_pal.disabled ) );
setSpacing( Q::Panel, qskDpiScaled( 3 ) );
setPadding( Q::Panel, 0 ); setPadding( Q::Panel, 0 );
setGradient( Q::Panel, QskGradient() ); // invisible setGradient( Q::Panel, QskGradient() ); // invisible
} }
@ -303,7 +291,7 @@ void Editor::setupPushButton()
using Q = QskPushButton; using Q = QskPushButton;
setStrutSize( Q::Panel, qskDpiScaled( 75.0 ), qskDpiScaled( 23.0 ) ); setStrutSize( Q::Panel, qskDpiScaled( 75.0 ), qskDpiScaled( 23.0 ) );
setSpacing( Q::Panel, 4 ); setSpacing( Q::Panel, qskDpiScaled( 4 ) );
const QskMargins margin( 4, 3 ); const QskMargins margin( 4, 3 );
const QskMargins padding( 10, 6 ); const QskMargins padding( 10, 6 );
@ -311,42 +299,24 @@ void Editor::setupPushButton()
setMargin( Q::Panel, margin ); setMargin( Q::Panel, margin );
setPadding( Q::Panel, padding ); setPadding( Q::Panel, padding );
const QskBoxBorderColors borderColors( Grey400, Grey300, Grey400, Grey600 ); setBoxShape( Q::Panel, 5 );
QskBoxBorderColors noBorderColors = borderColors;
noBorderColors.setAlpha( 0 );
setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, QskMargins( 1, 2, 1, 2 ) );
setBoxBorderColors( Q::Panel, noBorderColors );
setGradient( Q::Panel, White );
setGradient( Q::Panel | Q::Flat, White & ColorMask ); setGradient( Q::Panel | Q::Flat, White & ColorMask );
setColor( Q::Text, m_pal.textColor ); setColor( Q::Text, m_pal.primary );
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.textColor, 0.6 ) ); setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.primary, 0.6 ) );
setFontRole( Q::Text, ButtonFontRole ); setFontRole( Q::Text, ButtonFontRole );
setAlignment( Q::Text, Qt::AlignCenter ); setAlignment( Q::Text, Qt::AlignCenter );
for ( auto state1 : { A::NoState, Q::Focused } ) setBoxBorderMetrics( Q::Panel, 1 );
{ setBoxBorderColors( Q::Panel, m_pal.primary );
setBoxBorderColors( Q::Panel | Q::Hovered | state1, borderColors );
setBoxBorderColors( Q::Panel | Q::Hovered | Q::Flat | state1, borderColors );
for ( auto state2 : { A::NoState, Q::Hovered } ) setBoxBorderColors( Q::Panel | Q::Disabled, qskShadedColor( m_pal.onBackground, m_pal.disabled ) );
{ setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.onBackground, m_pal.disabled ) );
for ( auto state3 : { Q::Pressed | A::NoState, Q::Checked | A::NoState, Q::Checked | Q::Pressed } )
{
const auto states = state1 | state2 | state3;
setGradient( Q::Panel | states, m_pal.accentColor ); setColor( Q::Panel | Q::Hovered, qskShadedColor( m_pal.primary, m_pal.hover ) );
setColor( Q::Text | states, White ); setColor( Q::Panel | Q::Focused, qskShadedColor( m_pal.primary, m_pal.focused ) );
setColor( Q::Panel | Q::Pressed, qskShadedColor( m_pal.primary, m_pal.pressed ) );
setGradient( Q::Panel | Q::Flat | states, m_pal.accentColor );
setColor( Q::Text | Q::Flat | states, White );
}
}
}
setAnimation( Q::Panel | A::Color, qskDuration ); setAnimation( Q::Panel | A::Color, qskDuration );
setAnimation( Q::Panel | A::Metric, qskDuration ); setAnimation( Q::Panel | A::Metric, qskDuration );
@ -365,33 +335,25 @@ void Editor::setupDialogButton()
setMargin( Q::Panel, QskMargins( 4, 3 ) ); setMargin( Q::Panel, QskMargins( 4, 3 ) );
setPadding( Q::Panel, QskMargins( 10, 6 ) ); setPadding( Q::Panel, QskMargins( 10, 6 ) );
const QskBoxBorderColors borderColors( Grey400, Grey300, Grey400, Grey600 );
QskBoxBorderColors noBorderColors = borderColors;
noBorderColors.setAlpha( 0 );
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, QskMargins( 1, 2, 1, 2 ) );
setBoxBorderColors( Q::Panel, noBorderColors );
setGradient( Q::Panel, White ); setGradient( Q::Panel, m_pal.primary );
setColor( Q::Text, m_pal.textColor ); setColor( Q::Text, m_pal.onBackground );
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.textColor, 0.6 ) ); setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.onPrimary, 0.6 ) );
setFontRole( Q::Text, ButtonFontRole ); setFontRole( Q::Text, ButtonFontRole );
setAlignment( Q::Text, Qt::AlignCenter ); setAlignment( Q::Text, Qt::AlignCenter );
for ( auto state1 : { A::NoState, Q::Focused } ) for ( auto state1 : { A::NoState, Q::Focused } )
{ {
setBoxBorderColors( Q::Panel | Q::Hovered | state1, borderColors );
for ( auto state2 : { A::NoState, Q::Hovered } ) for ( auto state2 : { A::NoState, Q::Hovered } )
{ {
for ( auto state3 : { Q::Pressed | A::NoState, Q::Checked | A::NoState, Q::Checked | Q::Pressed } ) for ( auto state3 : { Q::Pressed | A::NoState,
Q::Checked | A::NoState, Q::Checked | Q::Pressed } )
{ {
const auto states = state1 | state2 | state3; const auto states = state1 | state2 | state3;
setGradient( Q::Panel | states, m_pal.accentColor ); setGradient( Q::Panel | states, m_pal.secondary );
setColor( Q::Text | states, White ); setColor( Q::Text | states, m_pal.onSecondary );
} }
} }
} }
@ -405,7 +367,7 @@ void Editor::setupDialogButtonBox()
{ {
using Q = QskDialogButtonBox; using Q = QskDialogButtonBox;
setGradient( Q::Panel, m_pal.baseColor ); setGradient( Q::Panel, m_pal.background );
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 0 );
} }
@ -423,7 +385,7 @@ void Editor::setupSlider()
setMetric( Q::Panel | A::Size, extent ); setMetric( Q::Panel | A::Size, extent );
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 0 );
setGradient( Q::Panel, QskGradient() ); setGradient( Q::Panel, m_pal.background );
setPadding( Q::Panel | A::Horizontal, QskMargins( 0.5 * extent, 0 ) ); setPadding( Q::Panel | A::Horizontal, QskMargins( 0.5 * extent, 0 ) );
setPadding( Q::Panel | A::Vertical, QskMargins( 0, 0.5 * extent ) ); setPadding( Q::Panel | A::Vertical, QskMargins( 0, 0.5 * extent ) );
@ -432,48 +394,42 @@ void Editor::setupSlider()
for ( auto subControl : { Q::Groove, Q::Fill } ) for ( auto subControl : { Q::Groove, Q::Fill } )
{ {
setMetric( subControl | A::Size, 5 );
setPadding( subControl, 0 ); setPadding( subControl, 0 );
setBoxShape( subControl, 0 ); setBoxShape( subControl, 0 );
setBoxBorderMetrics( subControl, 0 ); setBoxBorderMetrics( subControl, 0 );
} }
setMetric( Q::Groove | A::Size, qskDpiScaled( 4 ) );
setMetric( Q::Fill | A::Size, qskDpiScaled( 6 ) );
setGradient( Q::Groove, Grey );
setGradient( Q::Fill, m_pal.accentColor ); setGradient( Q::Groove, qskShadedColor( m_pal.secondary, .38 ) );
setBoxBorderColors( Q::Fill, m_pal.accentColor ); setGradient( Q::Groove | Q::Disabled,
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
// handle setGradient( Q::Fill, m_pal.secondary );
setGradient( Q::Fill | Q::Disabled,
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
setBoxShape( Q::Handle, 100, Qt::RelativeSize ); setBoxShape( Q::Handle, 100, Qt::RelativeSize );
setBoxBorderMetrics( Q::Handle, 4 ); setBoxBorderMetrics( Q::Handle, 0 );
// handle expanding, when being pressed setStrutSize( Q::Handle, qskDpiScaled( 20 + rippleSize ),
const QSize extentSize( extent, extent ); qskDpiScaled( 20 + rippleSize ) );
setStrutSize( Q::Handle, 0.6 * extentSize );
setStrutSize( Q::Handle | Q::Pressed, extentSize );
setGradient( Q::Handle | Q::Disabled, Grey ); setGradient( Q::Handle | Q::Disabled, m_pal.secondaryNoSaturation );
setBoxBorderColors( Q::Handle | Q::Disabled, Grey );
setGradient( Q::Handle, m_pal.accentColor ); setGradient( Q::Handle, m_pal.secondary );
setGradient( Q::Handle | Q::Pressed, m_pal.accentColor ); setGradient( Q::Handle | Q::Pressed, m_pal.secondary );
for ( auto state : { A::States(), Q::Pressed | A::NoState, Q::Pressed | Q::Hovered } ) setBoxBorderMetrics( Q::Handle, qskDpiScaled( rippleSize / 2 ) );
{
setBoxBorderColors( Q::Handle | state, m_pal.accentColor );
}
for ( auto state : { A::States(), Q::Pressed | A::NoState, Q::Pressed | Q::Hovered } ) setBoxBorderColors( Q::Handle | Q::Hovered,
{ qskShadedColor( m_pal.secondary, m_pal.hover ) );
const auto aspect = Q::Handle | Q::Minimum | state; setBoxBorderColors( Q::Handle | Q::Focused,
setGradient( aspect, Grey300 ); qskShadedColor( m_pal.secondary, m_pal.focused ) );
setBoxBorderColors( aspect, Grey ); setBoxBorderColors( Q::Handle | Q::Pressed,
} qskShadedColor( m_pal.secondary, m_pal.pressed ) );
setAnimation( Q::Handle | A::Metric, qskDuration );
setAnimation( Q::Handle | A::Color, qskDuration );
// move the handle smoothly, when using keys // move the handle smoothly, when using keys
setAnimation( Q::Handle | A::Metric | A::Position, 2 * qskDuration ); setAnimation( Q::Handle | A::Metric | A::Position, 2 * qskDuration );
@ -486,7 +442,6 @@ void Editor::setupSwitchButton()
using Q = QskSwitchButton; using Q = QskSwitchButton;
const qreal radius = qskDpiScaled( 10 ); const qreal radius = qskDpiScaled( 10 );
const qreal handleSize = 2 * radius;
setBoxShape( Q::Groove, 100, Qt::RelativeSize ); setBoxShape( Q::Groove, 100, Qt::RelativeSize );
@ -494,53 +449,46 @@ void Editor::setupSwitchButton()
setStrutSize( Q::Groove | A::Horizontal, grooveSize ); setStrutSize( Q::Groove | A::Horizontal, grooveSize );
setStrutSize( Q::Groove | A::Vertical, grooveSize.transposed() ); setStrutSize( Q::Groove | A::Vertical, grooveSize.transposed() );
setGradient( Q::Groove, m_pal.darker125 ); setColor( Q::Groove, m_pal.secondaryNoSaturation );
setGradient( Q::Groove | Q::Disabled, m_pal.lighter150 ); setGradient( Q::Groove | Q::Disabled,
setGradient( Q::Groove | Q::Checked, m_pal.darker200 ); qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
setGradient( Q::Groove | Q::Checked,
setBoxBorderColors( Q::Groove, m_pal.darker200 ); m_pal.secondaryVariant );
setBoxBorderMetrics( Q::Groove, 2 ); setGradient( Q::Groove | Q::Checked | Q::Disabled,
setBoxBorderColors( Q::Groove | Q::Disabled, m_pal.darker125 ); qskShadedColor( m_pal.secondaryVariant, m_pal.disabledOccupancy ) );
setBoxShape( Q::Handle, 100, Qt::RelativeSize ); setBoxShape( Q::Handle, 100, Qt::RelativeSize );
setStrutSize( Q::Handle, handleSize, handleSize ); setStrutSize( Q::Handle, qskDpiScaled( 2 * radius + rippleSize ),
setBoxBorderMetrics( Q::Handle, 2 ); qskDpiScaled( 2 * radius + rippleSize ) );
setGradient( Q::Handle, QskGradient( Qt::Vertical, m_pal.lighter150, m_pal.lighter125 ) ); setGradient( Q::Handle, m_pal.background.lighter( 900 ) );
setGradient( Q::Handle | Q::Checked, m_pal.accentColor );
setGradient( Q::Handle | Q::Disabled, m_pal.lighter125 ); setGradient( Q::Handle | Q::Checked, m_pal.secondary );
setBoxBorderColors( Q::Handle, m_pal.darker200 );
setBoxBorderColors( Q::Handle | Q::Disabled, m_pal.darker125 );
setBoxShape( Q::Ripple, 100, Qt::RelativeSize ); setGradient( Q::Handle | Q::Disabled,
setStrutSize( Q::Ripple, 2 * handleSize, 2 * handleSize ); m_pal.elevated( m_pal.secondaryNoSaturation, -2 ) );
setGradient( Q::Ripple, QskRgb::Transparent ); setGradient( Q::Handle | Q::Disabled | Q::Checked,
m_pal.elevated( m_pal.secondary, -3 ) );
for ( auto state : { Q::Hovered, Q::Focused, Q::Pressed } ) setBoxBorderMetrics( Q::Handle, qskDpiScaled( rippleSize / 2 ) );
{ setBoxBorderMetrics( Q::Handle, qskDpiScaled( rippleSize / 2 ) );
auto weak = m_pal.darker125;
auto strong = m_pal.accentColor;
if ( state == Q::Hovered ) setBoxBorderColors( Q::Handle | Q::Checked | Q::Hovered,
{ qskShadedColor( m_pal.secondary, m_pal.hover ) );
weak.setAlpha( 100 ); setBoxBorderColors( Q::Handle | Q::Checked | Q::Focused,
strong.setAlpha( 50 ); qskShadedColor( m_pal.secondary, m_pal.focused ) );
} setBoxBorderColors( Q::Handle | Q::Checked | Q::Pressed,
else if ( state == Q::Focused ) qskShadedColor( m_pal.secondary, m_pal.pressed ) );
{
weak.setAlpha( 150 );
strong.setAlpha( 100 );
}
else
{
weak.setAlpha( 200 );
strong.setAlpha( 150 );
}
setGradient( Q::Ripple | state, weak ); setBoxBorderColors( Q::Handle | Q::Hovered,
setGradient( Q::Ripple | Q::Checked | state, strong ); qskShadedColor( m_pal.secondaryVariantNoSaturation,
} m_pal.hover ) );
setBoxBorderColors( Q::Handle | Q::Focused,
qskShadedColor( m_pal.secondaryVariantNoSaturation,
m_pal.focused ) );
setBoxBorderColors( Q::Handle | Q::Pressed,
qskShadedColor( m_pal.secondaryVariantNoSaturation,
m_pal.pressed ) );
for ( auto state : { A::NoState, Q::Disabled } ) for ( auto state : { A::NoState, Q::Disabled } )
{ {
@ -590,7 +538,8 @@ void Editor::setupTabButton()
edge = Qt::Edge( 0 ); // making gcc4 happy edge = Qt::Edge( 0 ); // making gcc4 happy
} }
setGradient( aspect, QskRgb::White ); QskBoxBorderColors borderColors( m_pal.elevated( m_pal.background ) );
auto borderColorsActive = m_pal.primary;
// The highlighted button has a accented bar at one edge // The highlighted button has a accented bar at one edge
setBoxShape( aspect, 0 ); setBoxShape( aspect, 0 );
@ -599,22 +548,28 @@ void Editor::setupTabButton()
border.setWidthAt( edge, 3 ); border.setWidthAt( edge, 3 );
setBoxBorderMetrics( aspect, border ); setBoxBorderMetrics( aspect, border );
QskBoxBorderColors borderColors( QskRgb::White );
setBoxBorderColors( aspect, borderColors ); setBoxBorderColors( aspect, borderColors );
borderColors.setGradientAt( edge, m_pal.accentColor ); borderColors.setGradientAt( edge, borderColorsActive );
for ( auto state : { Q::Checked, Q::Pressed, Q::Hovered } ) setBoxBorderColors( aspect | Q::Checked, borderColors );
setBoxBorderColors( aspect | state, borderColors );
} }
setColor( Q::Text, m_pal.onBackground );
setColor( Q::Text | Q::Disabled,
qskShadedColor( m_pal.onBackground,
m_pal.widgetBackgroundDisabled ) );
setColor( Q::Text | Q::Checked, m_pal.primary );
setColor( Q::Text | Q::Hovered, m_pal.primary );
setColor( Q::Panel, m_pal.elevated( m_pal.background ) );
setColor( Q::Panel | Q::Hovered, qskShadedColor( m_pal.primary, m_pal.hover ) );
setColor( Q::Panel | Q::Focused, qskShadedColor( m_pal.primary, m_pal.focused ) );
setColor( Q::Panel | Q::Pressed, qskShadedColor( m_pal.primary, m_pal.pressed ) );
setAnimation( Q::Panel | A::Color, qskDuration ); setAnimation( Q::Panel | A::Color, qskDuration );
// text
setFontRole( Q::Text, ButtonFontRole ); setFontRole( Q::Text, ButtonFontRole );
setAlignment( Q::Text, Qt::AlignCenter ); setAlignment( Q::Text, Qt::AlignCenter );
setColor( Q::Text, m_pal.textColor );
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.textColor, 0.6 ) );
} }
void Editor::setupTabBar() void Editor::setupTabBar()
@ -624,21 +579,17 @@ void Editor::setupTabBar()
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 0 );
setGradient( Q::Panel, QskGradient() );
setGradient( Q::Panel, m_pal.elevated( m_pal.background ) );
setPadding( Q::Panel, 0 );
// when flicking // when flicking
setAnimation( Q::Panel | A::Metric, QskAnimationHint( 200, QEasingCurve::InCubic ) ); setAnimation( Q::Panel | A::Metric, QskAnimationHint( 200, QEasingCurve::InCubic ) );
} }
void Editor::setupTabView() void Editor::setupTabView() {
{
using Q = QskTabView; using Q = QskTabView;
setBoxShape( Q::Page, 0 );
setBoxBorderMetrics( Q::Page, 0 );
setGradient( Q::Page, m_pal.darker150 );
setBoxBorderColors( Q::Page, m_pal.baseColor );
setAnimation( Q::Page, qskDuration ); setAnimation( Q::Page, qskDuration );
} }
@ -648,8 +599,8 @@ void Editor::setupInputPanel()
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 0 );
setGradient( Q::Panel, m_pal.darker150 ); setGradient( Q::Panel, m_pal.elevated( m_pal.background, 1 ) );
setBoxBorderColors( Q::Panel, m_pal.baseColor ); setBoxBorderColors( Q::Panel, m_pal.background );
} }
void Editor::setupVirtualKeyboard() void Editor::setupVirtualKeyboard()
@ -662,12 +613,11 @@ void Editor::setupVirtualKeyboard()
setBoxShape( Q::ButtonPanel, 20.0, Qt::RelativeSize ); setBoxShape( Q::ButtonPanel, 20.0, Qt::RelativeSize );
setBoxBorderMetrics( Q::ButtonPanel, 2 ); setBoxBorderMetrics( Q::ButtonPanel, 2 );
setBoxBorderColors( Q::ButtonPanel, m_pal.background );
setGradient( Q::ButtonPanel, m_pal.darker125 );
setBoxBorderColors( Q::ButtonPanel, m_pal.baseColor );
for ( auto state : { A::NoState, Q::Focused } ) for ( auto state : { A::NoState, Q::Focused } )
setBoxBorderColors( Q::ButtonPanel | QskPushButton::Pressed | state, m_pal.accentColor ); setBoxBorderColors( Q::ButtonPanel | QskPushButton::Pressed | state,
m_pal.secondary );
setAnimation( Q::ButtonPanel | A::Color, qskDuration ); setAnimation( Q::ButtonPanel | A::Color, qskDuration );
setAnimation( Q::ButtonPanel | A::Metric, qskDuration ); setAnimation( Q::ButtonPanel | A::Metric, qskDuration );
@ -675,8 +625,8 @@ void Editor::setupVirtualKeyboard()
// panel // panel
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 0 );
setGradient( Q::Panel, m_pal.darker150 ); setGradient( Q::Panel, m_pal.elevated( m_pal.background, 1 ) );
setBoxBorderColors( Q::Panel, m_pal.baseColor ); setBoxBorderColors( Q::Panel, m_pal.background );
} }
void Editor::setupScrollView() void Editor::setupScrollView()
@ -684,16 +634,15 @@ void Editor::setupScrollView()
using A = QskAspect; using A = QskAspect;
using Q = QskScrollView; using Q = QskScrollView;
setSpacing( Q::Panel, 2 ); setSpacing( Q::Panel, 5 );
setBoxShape( Q::Viewport, 5 );
setBoxBorderMetrics( Q::Viewport, 1 ); setBoxBorderMetrics( Q::Viewport, 1 );
setGradient( Q::Viewport, QskRgb::White ); setGradient( Q::Viewport, m_pal.background );
setBoxBorderColors( Q::Viewport, Qt::black ); setBoxBorderColors( Q::Viewport, m_pal.onBackground );
for ( auto subControl : { Q::HorizontalScrollBar, Q::VerticalScrollBar } ) for ( auto subControl : { Q::HorizontalScrollBar, Q::VerticalScrollBar } )
{ {
setMetric( subControl | A::Size, 12 ); setMetric( subControl | A::Size, 10 );
setPadding( subControl, 0 ); setPadding( subControl, 0 );
} }
@ -704,10 +653,8 @@ void Editor::setupScrollView()
for ( auto subControl : { Q::HorizontalScrollHandle, Q::VerticalScrollHandle } ) for ( auto subControl : { Q::HorizontalScrollHandle, Q::VerticalScrollHandle } )
{ {
setBoxShape( subControl, 3 ); setBoxShape( subControl, 3 );
setBoxBorderMetrics( subControl, 1 ); setBoxBorderMetrics( subControl, 0 );
setGradient( subControl, m_pal.accentColor ); setColor( subControl, qskShadedColor( m_pal.onBackground, m_pal.hover ) );
setBoxBorderColors( subControl, QskRgb::White );
setAnimation( subControl | A::Color, qskDuration ); setAnimation( subControl | A::Color, qskDuration );
} }
@ -715,8 +662,8 @@ void Editor::setupScrollView()
Q::HorizontalScrollHandle | Q::HorizontalHandlePressed, Q::HorizontalScrollHandle | Q::HorizontalHandlePressed,
Q::VerticalScrollHandle | Q::VerticalHandlePressed } ) Q::VerticalScrollHandle | Q::VerticalHandlePressed } )
{ {
setGradient( subControl, m_pal.accentColor ); setColor( subControl,
setBoxBorderColors( subControl, m_pal.accentColor ); qskShadedColor( m_pal.onBackground, m_pal.pressed ) );
} }
// when changing the position by QskScrollView::scrollTo // when changing the position by QskScrollView::scrollTo
@ -727,14 +674,13 @@ void Editor::setupListView()
{ {
using Q = QskListView; using Q = QskListView;
// padding for each cell setPadding( Q::Cell, 0 );
setPadding( Q::Cell, QskMargins( 4, 8 ) );
setColor( Q::Cell, m_pal.baseColor ); setColor( Q::Cell, m_pal.background );
setColor( Q::Text, m_pal.textColor ); setColor( Q::Text, m_pal.onBackground );
setColor( Q::Cell | Q::Selected, m_pal.accentColor ); setColor( Q::Cell | Q::Selected, qskShadedColor( m_pal.onBackground, m_pal.focused ) );
setColor( Q::Text | Q::Selected, m_pal.contrastColor ); setColor( Q::Text | Q::Selected, m_pal.onBackground );
} }
void Editor::setupSubWindow() void Editor::setupSubWindow()
@ -747,20 +693,16 @@ void Editor::setupSubWindow()
setPadding( Q::Panel, 10 ); setPadding( Q::Panel, 10 );
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
setBoxBorderMetrics( Q::Panel, 2 ); setBoxBorderMetrics( Q::Panel, 2 );
setGradient( Q::Panel, m_pal.baseColor ); setGradient( Q::Panel, m_pal.onBackground );
QskBoxBorderColors colors; setBoxBorderColors( Q::Panel, m_pal.primary );
colors.setGradientAt( Qt::TopEdge | Qt::LeftEdge, m_pal.lighter125 );
colors.setGradientAt( Qt::RightEdge | Qt::BottomEdge, m_pal.darker200 );
setBoxBorderColors( Q::Panel, colors );
// TitleBarPanel // TitleBarPanel
setFlagHint( Q::TitleBarPanel | QskAspect::Style, setFlagHint( Q::TitleBarPanel | QskAspect::Style,
Q::TitleBar | Q::Title | Q::Symbol ); Q::TitleBar | Q::Title | Q::Symbol );
setGradient( Q::TitleBarPanel, m_pal.darker200 ); setGradient( Q::TitleBarPanel, m_pal.primary );
setGradient( Q::TitleBarPanel | Q::Focused, m_pal.accentColor ); setGradient( Q::TitleBarPanel | Q::Focused, m_pal.primaryVariant );
// TitleBarText // TitleBarText
setFontRole( Q::TitleBarText, QskSkin::SmallFont ); setFontRole( Q::TitleBarText, QskSkin::SmallFont );
@ -777,13 +719,10 @@ class QskMaterialSkin::PrivateData
ColorPalette palette; ColorPalette palette;
}; };
QskMaterialSkin::QskMaterialSkin( QObject* parent ) QskMaterialSkin::QskMaterialSkin( ColorPalette colors, QObject* parent )
: Inherited( parent ) : Inherited( parent )
, m_data( new PrivateData() ) , m_data( new PrivateData { colors } )
{ {
m_data->palette = ColorPalette( QskRgb::Grey100,
QskRgb::Blue500, QskRgb::White );
// Default theme colors // Default theme colors
setupFonts( "Roboto" ); setupFonts( "Roboto" );
@ -799,13 +738,4 @@ QskMaterialSkin::~QskMaterialSkin()
{ {
} }
void QskMaterialSkin::resetColors( const QColor& accent )
{
m_data->palette = ColorPalette( m_data->palette.baseColor,
accent, m_data->palette.contrastColor );
Editor editor( &hintTable(), m_data->palette );
editor.setup();
}
#include "moc_QskMaterialSkin.cpp" #include "moc_QskMaterialSkin.cpp"

View File

@ -8,8 +8,89 @@
#include "QskMaterialGlobal.h" #include "QskMaterialGlobal.h"
#include <QskSkin.h> #include <QskSkin.h>
#include <QskRgbValue.h>
#include <memory> #include <memory>
struct ColorPalette
{
enum Lightness { light, dark } lightness;
QColor primary;
QColor primaryVariant;
QColor onPrimary;
QColor secondary;
QColor secondaryVariant;
QColor onSecondary;
QColor background;
QColor onBackground;
QColor error;
QColor onError;
QColor primaryNoSaturation = QColor::fromHsl( primary.hslHue(), 0,
primary.lightness() );
QColor secondaryNoSaturation =
QColor::fromHsl( secondary.hslHue(), 0,
secondary.lightness() );
QColor secondaryVariantNoSaturation =
QColor::fromHsl( secondaryVariant.hslHue(), 0,
secondaryVariant.lightness() +
secondaryVariant.hslSaturation() );
qreal disabledOccupancy = 0.2;
qreal widgetBackgroundDisabled = 0.6;
qreal hover = 0.1;
qreal focused = 0.4;
qreal pressed = 0.5;
qreal disabled = 0.3;
ColorPalette(
Lightness lightness = light,
QColor primary = QColor::fromRgb( 0x6200EE ),
QColor primaryVariant = QColor::fromRgb( 0x3700B3 ),
QColor onPrimary = Qt::white,
QColor secondary = QColor::fromRgb( 0x03DAC6 ),
QColor secondaryVariant = QColor::fromRgb( 0x018786 ),
QColor onSecondary = Qt::white,
QColor background = QColor::fromRgba( QskRgb::Grey100 ),
QColor onBackground = Qt::black,
QColor error = QColor::fromRgb( 0xB00020 ),
QColor onError = Qt::white ):
lightness( lightness ),
primary( primary ),
primaryVariant( primaryVariant ),
onPrimary( onPrimary ),
secondary( secondary ),
secondaryVariant( secondaryVariant ),
onSecondary( onSecondary ),
background( background ),
onBackground( onBackground ),
error( error ),
onError( onError )
{
primaryNoSaturation = QColor::fromHsl( primary.hslHue(), 0,
primary.lightness() );
secondaryNoSaturation = QColor::fromHsl( secondary.hslHue(),
0,
secondary.lightness() );
secondaryVariantNoSaturation =
QColor::fromHsl( secondaryVariant.hslHue(), 0,
secondaryVariant.lightness() );
}
inline QColor elevated( const QColor target, const float level = 1 ) const {
return ( lightness == light ) ? target.darker( 100 + level * 15 )
: target.lighter( 130 + level * 30 );
}
};
class QSK_MATERIAL_EXPORT QskMaterialSkin : public QskSkin class QSK_MATERIAL_EXPORT QskMaterialSkin : public QskSkin
{ {
Q_OBJECT Q_OBJECT
@ -17,12 +98,10 @@ class QSK_MATERIAL_EXPORT QskMaterialSkin : public QskSkin
using Inherited = QskSkin; using Inherited = QskSkin;
public: public:
QskMaterialSkin( QObject* parent = nullptr ); QskMaterialSkin( ColorPalette, QObject* parent = nullptr );
~QskMaterialSkin() override; ~QskMaterialSkin() override;
private: private:
void resetColors( const QColor& accent ) override;
class PrivateData; class PrivateData;
std::unique_ptr< PrivateData > m_data; std::unique_ptr< PrivateData > m_data;
}; };

View File

@ -6,7 +6,8 @@
#include "QskMaterialSkinFactory.h" #include "QskMaterialSkinFactory.h"
#include "QskMaterialSkin.h" #include "QskMaterialSkin.h"
static const QString materialSkinName = QStringLiteral( "material" ); static const QString materialLightSkinName = QStringLiteral( "materialLight" );
static const QString materialDarkSkinName = QStringLiteral( "materialDark" );
QskMaterialSkinFactory::QskMaterialSkinFactory( QObject* parent ) QskMaterialSkinFactory::QskMaterialSkinFactory( QObject* parent )
: QskSkinFactory( parent ) : QskSkinFactory( parent )
@ -19,13 +20,30 @@ QskMaterialSkinFactory::~QskMaterialSkinFactory()
QStringList QskMaterialSkinFactory::skinNames() const QStringList QskMaterialSkinFactory::skinNames() const
{ {
return { materialSkinName }; return { materialLightSkinName, materialDarkSkinName };
} }
QskSkin* QskMaterialSkinFactory::createSkin( const QString& skinName ) QskSkin* QskMaterialSkinFactory::createSkin( const QString& skinName )
{ {
if ( skinName.toLower() == materialSkinName ) if ( QString::compare( skinName, materialLightSkinName, Qt::CaseInsensitive ) )
return new QskMaterialSkin(); return new QskMaterialSkin( ColorPalette() );
if ( QString::compare( skinName, materialDarkSkinName, Qt::CaseInsensitive ) )
{
return new QskMaterialSkin( ColorPalette(
ColorPalette::dark, // lightness
QColor::fromRgb( 0xBB86FC ), // primary
QColor::fromRgb( 0x3700B3 ), // primaryVariant
Qt::black, // onPrimary
QColor::fromRgb( 0x03DAC6 ), // secondary
QColor::fromRgb( 0x018786 ), // secondaryVariant
Qt::black, // onSecondary
QColor::fromRgb( 0x121212 ), // background
Qt::white, // onBackground
QColor::fromRgb( 0xCF6679 ), // error
Qt::black // onError
) );
}
return nullptr; return nullptr;
} }

View File

@ -1,4 +1,4 @@
{ {
"FactoryId": "MaterialFactory", "FactoryId": "MaterialFactory",
"Skins": [ "material" ] "Skins": [ "materialLight", "materialDark" ]
} }

View File

@ -319,6 +319,9 @@ QskTextInput::QskTextInput( QQuickItem* parent )
m_data->textInput->setAcceptedMouseButtons( Qt::NoButton ); m_data->textInput->setAcceptedMouseButtons( Qt::NoButton );
initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Fixed ); initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Fixed );
setAcceptHoverEvents( true );
} }
QskTextInput::QskTextInput( const QString& text, QQuickItem* parent ) QskTextInput::QskTextInput( const QString& text, QQuickItem* parent )