Uing RGB values instead of colors. QskSkinTransition reimplemented.
Ongoing work
This commit is contained in:
parent
5284880eaa
commit
570d3d2d51
@ -4,29 +4,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "Page.h"
|
||||
#include <QskRgbValue.h>
|
||||
|
||||
Page::Page( Qt::Orientation orientation, QQuickItem* parent )
|
||||
: QskLinearBox( orientation, parent )
|
||||
, m_gradient( QskRgb::GhostWhite )
|
||||
{
|
||||
setMargins( 20 );
|
||||
setPadding( 10 );
|
||||
setSpacing( 10 );
|
||||
}
|
||||
|
||||
void Page::setGradient( const QskGradient& gradient )
|
||||
{
|
||||
if ( gradient != m_gradient )
|
||||
{
|
||||
m_gradient = gradient;
|
||||
|
||||
if ( parentItem() && isVisibleToParent() )
|
||||
parentItem()->update();
|
||||
}
|
||||
}
|
||||
|
||||
QskGradient Page::gradient() const
|
||||
{
|
||||
return m_gradient;
|
||||
}
|
||||
|
@ -6,16 +6,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <QskLinearBox.h>
|
||||
#include <QskGradient.h>
|
||||
|
||||
class Page : public QskLinearBox
|
||||
{
|
||||
public:
|
||||
Page( Qt::Orientation, QQuickItem* parent = nullptr );
|
||||
|
||||
void setGradient( const QskGradient& );
|
||||
QskGradient gradient() const;
|
||||
|
||||
private:
|
||||
QskGradient m_gradient;
|
||||
};
|
||||
|
@ -67,7 +67,6 @@ namespace
|
||||
LabelPage::LabelPage( QQuickItem* parent )
|
||||
: Page( Qt::Vertical, parent )
|
||||
{
|
||||
setGradient( QskRgb::AliceBlue );
|
||||
setSpacing( 40 );
|
||||
|
||||
(void) new TextBox( this );
|
||||
|
@ -30,27 +30,6 @@ namespace
|
||||
setMargins( 10 );
|
||||
setTabPosition( Qsk::Left );
|
||||
setAutoFitTabs( true );
|
||||
|
||||
connect( this, &QskTabView::currentIndexChanged,
|
||||
this, &TabView::updateViewPanel );
|
||||
}
|
||||
|
||||
protected:
|
||||
void aboutToShow() override
|
||||
{
|
||||
updateViewPanel();
|
||||
}
|
||||
|
||||
private:
|
||||
void updateViewPanel()
|
||||
{
|
||||
/*
|
||||
We should have a better way to set individual colors
|
||||
for each tab page background
|
||||
*/
|
||||
|
||||
if ( auto page = dynamic_cast< const ::Page* >( currentItem() ) )
|
||||
setGradientHint( QskTabView::Page, page->gradient() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -45,9 +45,7 @@ namespace
|
||||
ProgressBarPage::ProgressBarPage( QQuickItem* parent )
|
||||
: Page( Qt::Horizontal, parent )
|
||||
{
|
||||
setGradient( QskRgb::AliceBlue );
|
||||
setSpacing( 40 );
|
||||
|
||||
populate();
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,6 @@
|
||||
SliderPage::SliderPage( QQuickItem* parentItem )
|
||||
: Page( Qt::Vertical, parentItem )
|
||||
{
|
||||
setGradient( QskRgb::PeachPuff );
|
||||
|
||||
setMargins( 10 );
|
||||
setSpacing( 20 );
|
||||
|
||||
|
@ -15,9 +15,7 @@
|
||||
SwitchButtonPage::SwitchButtonPage( QQuickItem* parent )
|
||||
: Page( Qt::Horizontal, parent )
|
||||
{
|
||||
setGradient( QskRgb::AliceBlue );
|
||||
setSpacing( 40 );
|
||||
|
||||
populate();
|
||||
}
|
||||
|
||||
|
@ -47,20 +47,12 @@ static const int ButtonFontRole = QskSkin::HugeFont + 77;
|
||||
|
||||
static const int qskDuration = 150;
|
||||
|
||||
static inline QColor qskShadedColor( const QColor color, qreal opacity )
|
||||
{
|
||||
QColor c = color;
|
||||
c.setAlphaF( opacity );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class Editor : private QskSkinHintTableEditor
|
||||
{
|
||||
public:
|
||||
Editor( QskSkinHintTable* table, const ColorPalette& palette )
|
||||
Editor( QskSkinHintTable* table, const QskMaterialPalette& palette )
|
||||
: QskSkinHintTableEditor( table )
|
||||
, m_pal( palette )
|
||||
{
|
||||
@ -93,7 +85,7 @@ namespace
|
||||
void setupTextInput();
|
||||
void setupTextLabel();
|
||||
|
||||
const ColorPalette& m_pal;
|
||||
const QskMaterialPalette& m_pal;
|
||||
const uint rippleSize = 30;
|
||||
};
|
||||
}
|
||||
@ -135,7 +127,7 @@ void Editor::setupControl()
|
||||
setGradient( A::Control, m_pal.background );
|
||||
setColor( A::Control | A::StyleColor, m_pal.onBackground );
|
||||
setColor( A::Control | A::StyleColor | Q::Disabled,
|
||||
qskShadedColor( m_pal.onBackground, 0.6 ) );
|
||||
QskRgb::toTransparentF( m_pal.onBackground, 0.6 ) );
|
||||
}
|
||||
|
||||
void Editor::setupBox()
|
||||
@ -155,8 +147,8 @@ void Editor::setupPopup()
|
||||
setFlagHint( Q::Overlay | A::Style, true );
|
||||
|
||||
const QskGradient gradient( QskGradient::Vertical,
|
||||
qskShadedColor( m_pal.secondary, 0.45 ),
|
||||
qskShadedColor( m_pal.secondary, 0.7 ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, 0.45 ),
|
||||
QskRgb::toTransparentF( m_pal.secondary, 0.7 ) );
|
||||
|
||||
setGradient( Q::Overlay, gradient );
|
||||
}
|
||||
@ -196,20 +188,16 @@ void Editor::setupTextInput()
|
||||
|
||||
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, 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 ) );
|
||||
QskRgb::toTransparentF( m_pal.secondaryVariantNoSaturation, m_pal.disabled ) );
|
||||
setColor( Q::Text | Q::Disabled, QskRgb::toTransparentF( m_pal.onBackground, m_pal.disabled ) );
|
||||
setBoxBorderColors( Q::Panel,
|
||||
qskShadedColor( m_pal.onBackground, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.onBackground, m_pal.disabled ) );
|
||||
}
|
||||
|
||||
void Editor::setupProgressBar()
|
||||
@ -233,9 +221,9 @@ void Editor::setupProgressBar()
|
||||
setGradient( Q::Bar, m_pal.secondary );
|
||||
|
||||
setGradient( Q::Groove | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
setGradient( Q::Bar | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondary, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.disabled ) );
|
||||
}
|
||||
|
||||
void Editor::setupFocusIndicator()
|
||||
@ -275,9 +263,9 @@ void Editor::setupPageIndicator()
|
||||
setGradient( Q::Bullet | Q::Selected, m_pal.secondary );
|
||||
|
||||
setGradient( Q::Bullet | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
setGradient( Q::Bullet | Q::Selected | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondary, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.disabled ) );
|
||||
|
||||
setSpacing( Q::Panel, qskDpiScaled( 3 ) );
|
||||
setPadding( Q::Panel, 0 );
|
||||
@ -304,19 +292,19 @@ void Editor::setupPushButton()
|
||||
setGradient( Q::Panel | Q::Flat, White & ColorMask );
|
||||
|
||||
setColor( Q::Text, m_pal.primary );
|
||||
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.primary, 0.6 ) );
|
||||
setColor( Q::Text | Q::Disabled, QskRgb::toTransparentF( m_pal.primary, 0.6 ) );
|
||||
setFontRole( Q::Text, ButtonFontRole );
|
||||
setAlignment( Q::Text, Qt::AlignCenter );
|
||||
|
||||
setBoxBorderMetrics( Q::Panel, 1 );
|
||||
setBoxBorderColors( Q::Panel, m_pal.primary );
|
||||
|
||||
setBoxBorderColors( Q::Panel | Q::Disabled, qskShadedColor( m_pal.onBackground, m_pal.disabled ) );
|
||||
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.onBackground, m_pal.disabled ) );
|
||||
setBoxBorderColors( Q::Panel | Q::Disabled, QskRgb::toTransparentF( m_pal.onBackground, m_pal.disabled ) );
|
||||
setColor( Q::Text | Q::Disabled, QskRgb::toTransparentF( m_pal.onBackground, m_pal.disabled ) );
|
||||
|
||||
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 ) );
|
||||
setColor( Q::Panel | Q::Hovered, QskRgb::toTransparentF( m_pal.primary, m_pal.hover ) );
|
||||
setColor( Q::Panel | Q::Focused, QskRgb::toTransparentF( m_pal.primary, m_pal.focused ) );
|
||||
setColor( Q::Panel | Q::Pressed, QskRgb::toTransparentF( m_pal.primary, m_pal.pressed ) );
|
||||
|
||||
setAnimation( Q::Panel | A::Color, qskDuration );
|
||||
setAnimation( Q::Panel | A::Metric, qskDuration );
|
||||
@ -339,7 +327,7 @@ void Editor::setupDialogButton()
|
||||
|
||||
setGradient( Q::Panel, m_pal.primary );
|
||||
setColor( Q::Text, m_pal.onBackground );
|
||||
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.onPrimary, 0.6 ) );
|
||||
setColor( Q::Text | Q::Disabled, QskRgb::toTransparentF( m_pal.onPrimary, 0.6 ) );
|
||||
setFontRole( Q::Text, ButtonFontRole );
|
||||
setAlignment( Q::Text, Qt::AlignCenter );
|
||||
|
||||
@ -385,7 +373,7 @@ void Editor::setupSlider()
|
||||
setMetric( Q::Panel | A::Size, extent );
|
||||
setBoxShape( Q::Panel, 0 );
|
||||
setBoxBorderMetrics( Q::Panel, 0 );
|
||||
setGradient( Q::Panel, m_pal.background );
|
||||
setGradient( Q::Panel, QskGradient() );
|
||||
|
||||
setPadding( Q::Panel | A::Horizontal, QskMargins( 0.5 * extent, 0 ) );
|
||||
setPadding( Q::Panel | A::Vertical, QskMargins( 0, 0.5 * extent ) );
|
||||
@ -399,17 +387,17 @@ void Editor::setupSlider()
|
||||
setBoxShape( subControl, 0 );
|
||||
setBoxBorderMetrics( subControl, 0 );
|
||||
}
|
||||
|
||||
setMetric( Q::Groove | A::Size, qskDpiScaled( 4 ) );
|
||||
setMetric( Q::Fill | A::Size, qskDpiScaled( 6 ) );
|
||||
|
||||
|
||||
setGradient( Q::Groove, qskShadedColor( m_pal.secondary, .38 ) );
|
||||
setGradient( Q::Groove, QskRgb::toTransparentF( m_pal.secondary, .38 ) );
|
||||
setGradient( Q::Groove | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
|
||||
setGradient( Q::Fill, m_pal.secondary );
|
||||
setGradient( Q::Fill | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
|
||||
setBoxShape( Q::Handle, 100, Qt::RelativeSize );
|
||||
setBoxBorderMetrics( Q::Handle, 0 );
|
||||
@ -425,11 +413,13 @@ void Editor::setupSlider()
|
||||
setBoxBorderMetrics( Q::Handle, qskDpiScaled( rippleSize / 2 ) );
|
||||
|
||||
setBoxBorderColors( Q::Handle | Q::Hovered,
|
||||
qskShadedColor( m_pal.secondary, m_pal.hover ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.hover ) );
|
||||
|
||||
setBoxBorderColors( Q::Handle | Q::Focused,
|
||||
qskShadedColor( m_pal.secondary, m_pal.focused ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.focused ) );
|
||||
|
||||
setBoxBorderColors( Q::Handle | Q::Pressed,
|
||||
qskShadedColor( m_pal.secondary, m_pal.pressed ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.pressed ) );
|
||||
|
||||
// move the handle smoothly, when using keys
|
||||
setAnimation( Q::Handle | A::Metric | A::Position, 2 * qskDuration );
|
||||
@ -451,17 +441,17 @@ void Editor::setupSwitchButton()
|
||||
|
||||
setColor( Q::Groove, m_pal.secondaryNoSaturation );
|
||||
setGradient( Q::Groove | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
QskRgb::toTransparentF( m_pal.secondaryNoSaturation, m_pal.disabled ) );
|
||||
setGradient( Q::Groove | Q::Checked,
|
||||
m_pal.secondaryVariant );
|
||||
setGradient( Q::Groove | Q::Checked | Q::Disabled,
|
||||
qskShadedColor( m_pal.secondaryVariant, m_pal.disabledOccupancy ) );
|
||||
QskRgb::toTransparentF( m_pal.secondaryVariant, m_pal.disabledOccupancy ) );
|
||||
|
||||
setBoxShape( Q::Handle, 100, Qt::RelativeSize );
|
||||
setStrutSize( Q::Handle, qskDpiScaled( 2 * radius + rippleSize ),
|
||||
qskDpiScaled( 2 * radius + rippleSize ) );
|
||||
|
||||
setGradient( Q::Handle, m_pal.background.lighter( 900 ) );
|
||||
setGradient( Q::Handle, QskRgb::lighter( m_pal.background, 900 ) );
|
||||
|
||||
setGradient( Q::Handle | Q::Checked, m_pal.secondary );
|
||||
|
||||
@ -474,20 +464,20 @@ void Editor::setupSwitchButton()
|
||||
setBoxBorderMetrics( Q::Handle, qskDpiScaled( rippleSize / 2 ) );
|
||||
|
||||
setBoxBorderColors( Q::Handle | Q::Checked | Q::Hovered,
|
||||
qskShadedColor( m_pal.secondary, m_pal.hover ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.hover ) );
|
||||
setBoxBorderColors( Q::Handle | Q::Checked | Q::Focused,
|
||||
qskShadedColor( m_pal.secondary, m_pal.focused ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.focused ) );
|
||||
setBoxBorderColors( Q::Handle | Q::Checked | Q::Pressed,
|
||||
qskShadedColor( m_pal.secondary, m_pal.pressed ) );
|
||||
QskRgb::toTransparentF( m_pal.secondary, m_pal.pressed ) );
|
||||
|
||||
setBoxBorderColors( Q::Handle | Q::Hovered,
|
||||
qskShadedColor( m_pal.secondaryVariantNoSaturation,
|
||||
QskRgb::toTransparentF( m_pal.secondaryVariantNoSaturation,
|
||||
m_pal.hover ) );
|
||||
setBoxBorderColors( Q::Handle | Q::Focused,
|
||||
qskShadedColor( m_pal.secondaryVariantNoSaturation,
|
||||
QskRgb::toTransparentF( m_pal.secondaryVariantNoSaturation,
|
||||
m_pal.focused ) );
|
||||
setBoxBorderColors( Q::Handle | Q::Pressed,
|
||||
qskShadedColor( m_pal.secondaryVariantNoSaturation,
|
||||
QskRgb::toTransparentF( m_pal.secondaryVariantNoSaturation,
|
||||
m_pal.pressed ) );
|
||||
|
||||
for ( auto state : { A::NoState, Q::Disabled } )
|
||||
@ -556,15 +546,15 @@ void Editor::setupTabButton()
|
||||
|
||||
setColor( Q::Text, m_pal.onBackground );
|
||||
setColor( Q::Text | Q::Disabled,
|
||||
qskShadedColor( m_pal.onBackground,
|
||||
QskRgb::toTransparentF( 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 ) );
|
||||
setColor( Q::Panel | Q::Hovered, QskRgb::toTransparentF( m_pal.primary, m_pal.hover ) );
|
||||
setColor( Q::Panel | Q::Focused, QskRgb::toTransparentF( m_pal.primary, m_pal.focused ) );
|
||||
setColor( Q::Panel | Q::Pressed, QskRgb::toTransparentF( m_pal.primary, m_pal.pressed ) );
|
||||
|
||||
setAnimation( Q::Panel | A::Color, qskDuration );
|
||||
|
||||
@ -587,9 +577,11 @@ void Editor::setupTabBar()
|
||||
setAnimation( Q::Panel | A::Metric, QskAnimationHint( 200, QEasingCurve::InCubic ) );
|
||||
}
|
||||
|
||||
void Editor::setupTabView() {
|
||||
void Editor::setupTabView()
|
||||
{
|
||||
using Q = QskTabView;
|
||||
|
||||
setGradient( Q::Page, m_pal.background );
|
||||
setAnimation( Q::Page, qskDuration );
|
||||
}
|
||||
|
||||
@ -654,7 +646,7 @@ void Editor::setupScrollView()
|
||||
{
|
||||
setBoxShape( subControl, 3 );
|
||||
setBoxBorderMetrics( subControl, 0 );
|
||||
setColor( subControl, qskShadedColor( m_pal.onBackground, m_pal.hover ) );
|
||||
setColor( subControl, QskRgb::toTransparentF( m_pal.onBackground, m_pal.hover ) );
|
||||
setAnimation( subControl | A::Color, qskDuration );
|
||||
}
|
||||
|
||||
@ -663,7 +655,7 @@ void Editor::setupScrollView()
|
||||
Q::VerticalScrollHandle | Q::VerticalHandlePressed } )
|
||||
{
|
||||
setColor( subControl,
|
||||
qskShadedColor( m_pal.onBackground, m_pal.pressed ) );
|
||||
QskRgb::toTransparentF( m_pal.onBackground, m_pal.pressed ) );
|
||||
}
|
||||
|
||||
// when changing the position by QskScrollView::scrollTo
|
||||
@ -679,7 +671,7 @@ void Editor::setupListView()
|
||||
setColor( Q::Cell, m_pal.background );
|
||||
setColor( Q::Text, m_pal.onBackground );
|
||||
|
||||
setColor( Q::Cell | Q::Selected, qskShadedColor( m_pal.onBackground, m_pal.focused ) );
|
||||
setColor( Q::Cell | Q::Selected, QskRgb::toTransparentF( m_pal.onBackground, m_pal.focused ) );
|
||||
setColor( Q::Text | Q::Selected, m_pal.onBackground );
|
||||
}
|
||||
|
||||
@ -713,15 +705,8 @@ void Editor::setupSubWindow()
|
||||
|
||||
}
|
||||
|
||||
class QskMaterialSkin::PrivateData
|
||||
{
|
||||
public:
|
||||
ColorPalette palette;
|
||||
};
|
||||
|
||||
QskMaterialSkin::QskMaterialSkin( ColorPalette colors, QObject* parent )
|
||||
QskMaterialSkin::QskMaterialSkin( const QskMaterialPalette& palette, QObject* parent )
|
||||
: Inherited( parent )
|
||||
, m_data( new PrivateData { colors } )
|
||||
{
|
||||
// Default theme colors
|
||||
setupFonts( QStringLiteral( "Roboto" ) );
|
||||
@ -730,7 +715,7 @@ QskMaterialSkin::QskMaterialSkin( ColorPalette colors, QObject* parent )
|
||||
buttonFont.setCapitalization( QFont::AllUppercase );
|
||||
setFont( ButtonFontRole, buttonFont );
|
||||
|
||||
Editor editor( &hintTable(), m_data->palette );
|
||||
Editor editor( &hintTable(), palette );
|
||||
editor.setup();
|
||||
}
|
||||
|
||||
|
@ -9,86 +9,56 @@
|
||||
#include "QskMaterialGlobal.h"
|
||||
#include <QskSkin.h>
|
||||
#include <QskRgbValue.h>
|
||||
#include <memory>
|
||||
|
||||
struct ColorPalette
|
||||
class QSK_MATERIAL_EXPORT QskMaterialPalette
|
||||
{
|
||||
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 )
|
||||
public:
|
||||
enum Lightness
|
||||
{
|
||||
primaryNoSaturation = QColor::fromHsl( primary.hslHue(), 0,
|
||||
primary.lightness() );
|
||||
Light,
|
||||
Dark
|
||||
};
|
||||
|
||||
secondaryNoSaturation = QColor::fromHsl( secondary.hslHue(),
|
||||
0,
|
||||
secondary.lightness() );
|
||||
|
||||
secondaryVariantNoSaturation =
|
||||
QColor::fromHsl( secondaryVariant.hslHue(), 0,
|
||||
secondaryVariant.lightness() );
|
||||
QskMaterialPalette( Lightness lightness )
|
||||
: m_lightness( 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 );
|
||||
inline QRgb elevated( const QRgb rgb, const float level = 1 ) const
|
||||
{
|
||||
return ( m_lightness == Light )
|
||||
? QskRgb::darker( rgb, 100 + level * 15 )
|
||||
: QskRgb::lighter( rgb, 130 + level * 30 );
|
||||
}
|
||||
|
||||
public:
|
||||
QRgb primary;
|
||||
QRgb primaryVariant;
|
||||
QRgb onPrimary;
|
||||
|
||||
QRgb secondary;
|
||||
QRgb secondaryVariant;
|
||||
QRgb onSecondary;
|
||||
|
||||
QRgb background;
|
||||
QRgb onBackground;
|
||||
|
||||
QRgb error;
|
||||
QRgb onError;
|
||||
|
||||
QRgb primaryNoSaturation;
|
||||
QRgb secondaryNoSaturation;
|
||||
QRgb secondaryVariantNoSaturation;
|
||||
|
||||
const qreal disabledOccupancy = 0.2;
|
||||
const qreal widgetBackgroundDisabled = 0.6;
|
||||
|
||||
const qreal hover = 0.1;
|
||||
const qreal focused = 0.4;
|
||||
const qreal pressed = 0.5;
|
||||
const qreal disabled = 0.3;
|
||||
|
||||
const Lightness m_lightness;
|
||||
};
|
||||
|
||||
class QSK_MATERIAL_EXPORT QskMaterialSkin : public QskSkin
|
||||
@ -98,12 +68,8 @@ class QSK_MATERIAL_EXPORT QskMaterialSkin : public QskSkin
|
||||
using Inherited = QskSkin;
|
||||
|
||||
public:
|
||||
QskMaterialSkin( ColorPalette, QObject* parent = nullptr );
|
||||
QskMaterialSkin( const QskMaterialPalette&, QObject* parent = nullptr );
|
||||
~QskMaterialSkin() override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -9,6 +9,42 @@
|
||||
static const QString materialLightSkinName = QStringLiteral( "materialLight" );
|
||||
static const QString materialDarkSkinName = QStringLiteral( "materialDark" );
|
||||
|
||||
namespace
|
||||
{
|
||||
inline int lightnessRgb( QRgb rgb )
|
||||
{
|
||||
const int red = qRed( rgb );
|
||||
const int green = qGreen( rgb );
|
||||
const int blue = qBlue( rgb );
|
||||
|
||||
int min, max;
|
||||
|
||||
if ( red > green )
|
||||
{
|
||||
max = qMax( red, blue );
|
||||
min = qMin( green, blue );
|
||||
}
|
||||
else
|
||||
{
|
||||
max = qMax( green, blue );
|
||||
min = qMin( red, blue );
|
||||
}
|
||||
|
||||
return ( max + min ) / 2;
|
||||
}
|
||||
|
||||
inline QRgb toUnsaturated( QRgb rgb )
|
||||
{
|
||||
/*
|
||||
a saturation of 0 results in having the lightness as r,g,b
|
||||
Is this intended ?
|
||||
*/
|
||||
|
||||
const auto l = lightnessRgb( rgb );
|
||||
return qRgba( l, l, l, qAlpha( rgb ) );
|
||||
}
|
||||
}
|
||||
|
||||
QskMaterialSkinFactory::QskMaterialSkinFactory( QObject* parent )
|
||||
: QskSkinFactory( parent )
|
||||
{
|
||||
@ -25,24 +61,48 @@ QStringList QskMaterialSkinFactory::skinNames() const
|
||||
|
||||
QskSkin* QskMaterialSkinFactory::createSkin( const QString& skinName )
|
||||
{
|
||||
if ( QString::compare( skinName, materialLightSkinName, Qt::CaseInsensitive ) )
|
||||
return new QskMaterialSkin( ColorPalette() );
|
||||
|
||||
if ( QString::compare( skinName, materialDarkSkinName, Qt::CaseInsensitive ) )
|
||||
if ( QString::compare( skinName, materialLightSkinName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
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
|
||||
) );
|
||||
QskMaterialPalette pal( QskMaterialPalette::Light );;
|
||||
|
||||
pal.primary = 0xff6200ee;
|
||||
pal.primaryVariant = 0xff3700b3;
|
||||
pal.onPrimary = QskRgb::White;
|
||||
pal.secondary = 0xff03dac6;
|
||||
pal.secondaryVariant = 0xff018786;
|
||||
pal.onSecondary = QskRgb::White;
|
||||
pal.background = QskRgb::Grey100;
|
||||
pal.onBackground = QskRgb::Black;
|
||||
pal.error = 0xffb00020;
|
||||
pal.onError = QskRgb::White;
|
||||
|
||||
pal.primaryNoSaturation = toUnsaturated( pal.primary );
|
||||
pal.secondaryNoSaturation = toUnsaturated( pal.secondary );
|
||||
pal.secondaryVariantNoSaturation = toUnsaturated( pal.secondaryVariant );
|
||||
|
||||
return new QskMaterialSkin( pal );
|
||||
}
|
||||
|
||||
if ( QString::compare( skinName, materialDarkSkinName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
QskMaterialPalette pal( QskMaterialPalette::Dark );
|
||||
|
||||
pal.primary = 0xffbb86fc;
|
||||
pal.primaryVariant = 0xff3700b3;
|
||||
pal.onPrimary = QskRgb::Black;
|
||||
pal.secondary = 0xff03dac6;
|
||||
pal.secondaryVariant = 0xff018786;
|
||||
pal.onSecondary = QskRgb::Black;
|
||||
pal.background = 0xff121212;
|
||||
pal.onBackground = QskRgb::White;
|
||||
pal.error = 0xffcf6679;
|
||||
pal.onError = QskRgb::Black;
|
||||
|
||||
pal.primaryNoSaturation = toUnsaturated( pal.primary );
|
||||
pal.secondaryNoSaturation = toUnsaturated( pal.secondary );
|
||||
pal.secondaryVariantNoSaturation = toUnsaturated( pal.secondaryVariant );
|
||||
|
||||
return new QskMaterialSkin( pal );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -647,51 +647,38 @@ void Editor::setupSlider()
|
||||
|
||||
// Panel
|
||||
|
||||
for ( auto placement : { A::Horizontal, A::Vertical } )
|
||||
{
|
||||
const auto aspect = Q::Panel | placement;
|
||||
|
||||
setMetric( aspect | A::Size, extent );
|
||||
setBoxBorderMetrics( aspect, 0 );
|
||||
setBoxShape( aspect, 0 );
|
||||
setGradient( aspect, QskGradient() );
|
||||
}
|
||||
setMetric( Q::Panel | A::Size, extent );
|
||||
setBoxBorderMetrics( Q::Panel, 0 );
|
||||
setBoxShape( Q::Panel, 0 );
|
||||
setGradient( Q::Panel, QskGradient() );
|
||||
|
||||
setPadding( Q::Panel | A::Horizontal, QskMargins( 0.5 * extent, 0 ) );
|
||||
setPadding( Q::Panel | A::Vertical, QskMargins( 0, 0.5 * extent ) );
|
||||
|
||||
// Groove, Fill
|
||||
|
||||
for ( auto placement : { A::Horizontal, A::Vertical } )
|
||||
for ( auto subControl : { Q::Groove, Q::Fill } )
|
||||
{
|
||||
for ( auto subControl : { Q::Groove, Q::Fill } )
|
||||
{
|
||||
const auto aspect = subControl | placement;
|
||||
const auto aspect = subControl;
|
||||
|
||||
setMetric( aspect | A::Size, 0.3 * extent );
|
||||
setPadding( aspect, 0 );
|
||||
setMetric( aspect | A::Size, 0.3 * extent );
|
||||
setPadding( aspect, 0 );
|
||||
|
||||
setBoxBorderMetrics( aspect, 0 );
|
||||
setBoxShape( aspect, 0.1 * extent );
|
||||
}
|
||||
|
||||
setGradient( Q::Groove | placement, m_pal.darker200 );
|
||||
setGradient( Q::Fill | placement, QskGradient() ); // no filling
|
||||
setBoxBorderMetrics( aspect, 0 );
|
||||
setBoxShape( aspect, 0.1 * extent );
|
||||
}
|
||||
|
||||
setGradient( Q::Groove, m_pal.darker200 );
|
||||
setGradient( Q::Fill, QskGradient() ); // no filling
|
||||
|
||||
// Handle
|
||||
|
||||
for ( auto placement : { A::Horizontal, A::Vertical } )
|
||||
{
|
||||
const auto aspect = Q::Handle | placement;
|
||||
setButton( Q::Handle, Raised, 1 );
|
||||
setBoxShape( Q::Handle, 20.0, Qt::RelativeSize );
|
||||
setButton( Q::Handle | Q::Pressed, Sunken, 1 );
|
||||
|
||||
setButton( aspect, Raised, 1 );
|
||||
setBoxShape( aspect, 20.0, Qt::RelativeSize );
|
||||
setButton( aspect | Q::Pressed, Sunken, 1 );
|
||||
|
||||
const qreal sz = 0.75 * extent;
|
||||
setStrutSize( aspect, sz, sz );
|
||||
}
|
||||
const qreal sz = 0.75 * extent;
|
||||
setStrutSize( Q::Handle, sz, sz );
|
||||
|
||||
setAnimation( Q::Handle | A::Color, qskDuration );
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ QStringList QskSquiekSkinFactory::skinNames() const
|
||||
|
||||
QskSkin* QskSquiekSkinFactory::createSkin( const QString& skinName )
|
||||
{
|
||||
if ( skinName.toLower() == squiekSkinName )
|
||||
if ( QString::compare( skinName, squiekSkinName, Qt::CaseInsensitive ) == 0 )
|
||||
return new QskSquiekSkin();
|
||||
|
||||
return nullptr;
|
||||
|
@ -11,6 +11,10 @@
|
||||
static void qskRegisterArcMetrics()
|
||||
{
|
||||
qRegisterMetaType< QskArcMetrics >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskArcMetrics >();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterArcMetrics )
|
||||
|
@ -109,8 +109,18 @@ class QSK_EXPORT QskAspect
|
||||
constexpr QskAspect operator|( Type ) const noexcept;
|
||||
constexpr QskAspect operator|( Primitive ) const noexcept;
|
||||
constexpr QskAspect operator|( Placement ) const noexcept;
|
||||
|
||||
constexpr QskAspect operator|( State ) const noexcept;
|
||||
QskAspect& operator|=( State ) noexcept;
|
||||
|
||||
constexpr QskAspect operator&( State ) const noexcept;
|
||||
QskAspect& operator&=( State ) noexcept;
|
||||
|
||||
constexpr QskAspect operator|( States ) const noexcept;
|
||||
QskAspect& operator|=( States ) noexcept;
|
||||
|
||||
constexpr QskAspect operator&( States ) const noexcept;
|
||||
QskAspect& operator&=( States ) noexcept;
|
||||
|
||||
constexpr QskAspect stateless() const noexcept;
|
||||
constexpr QskAspect trunk() const noexcept;
|
||||
@ -283,12 +293,48 @@ inline constexpr QskAspect QskAspect::operator|( State state ) const noexcept
|
||||
m_bits.primitive, m_bits.placement, m_bits.states | state );
|
||||
}
|
||||
|
||||
inline QskAspect& QskAspect::operator|=( State state ) noexcept
|
||||
{
|
||||
m_bits.states |= state;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline constexpr QskAspect QskAspect::operator&( State state ) const noexcept
|
||||
{
|
||||
return QskAspect( m_bits.subControl, m_bits.type, m_bits.isAnimator,
|
||||
m_bits.primitive, m_bits.placement, m_bits.states & state );
|
||||
}
|
||||
|
||||
inline QskAspect& QskAspect::operator&=( State state ) noexcept
|
||||
{
|
||||
m_bits.states &= state;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline constexpr QskAspect QskAspect::operator|( States states ) const noexcept
|
||||
{
|
||||
return QskAspect( m_bits.subControl, m_bits.type, m_bits.isAnimator,
|
||||
m_bits.primitive, m_bits.placement, m_bits.states | states );
|
||||
}
|
||||
|
||||
inline QskAspect& QskAspect::operator|=( States states ) noexcept
|
||||
{
|
||||
m_bits.states |= states;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline constexpr QskAspect QskAspect::operator&( States states ) const noexcept
|
||||
{
|
||||
return QskAspect( m_bits.subControl, m_bits.type, m_bits.isAnimator,
|
||||
m_bits.primitive, m_bits.placement, m_bits.states & states );
|
||||
}
|
||||
|
||||
inline QskAspect& QskAspect::operator&=( States states ) noexcept
|
||||
{
|
||||
m_bits.states &= states;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline constexpr QskAspect QskAspect::stateless() const noexcept
|
||||
{
|
||||
return QskAspect( m_bits.subControl, m_bits.type, m_bits.isAnimator,
|
||||
@ -538,6 +584,11 @@ namespace std
|
||||
};
|
||||
}
|
||||
|
||||
inline QskHashValue qHash( const QskAspect aspect, QskHashValue seed = 0 ) noexcept
|
||||
{
|
||||
return qHash( aspect.value(), seed );
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
class QDebug;
|
||||
|
@ -13,6 +13,10 @@ static void qskRegisterBoxBorderColors()
|
||||
{
|
||||
qRegisterMetaType< QskBoxBorderColors >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskBoxBorderColors >();
|
||||
#endif
|
||||
|
||||
QMetaType::registerConverter< QColor, QskBoxBorderColors >(
|
||||
[]( const QColor& color ) { return QskBoxBorderColors( color ); } );
|
||||
|
||||
@ -110,6 +114,26 @@ void QskBoxBorderColors::setGradientAt( Qt::Edges edges, const QskGradient& grad
|
||||
m_gradients[ Qsk::Bottom ] = gradient;
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setLeft( const QskGradient& gradient )
|
||||
{
|
||||
m_gradients[ Qsk::Left ] = gradient;
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setTop( const QskGradient& gradient )
|
||||
{
|
||||
m_gradients[ Qsk::Top ] = gradient;
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setRight( const QskGradient& gradient )
|
||||
{
|
||||
m_gradients[ Qsk::Right ] = gradient;
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setBottom( const QskGradient& gradient )
|
||||
{
|
||||
m_gradients[ Qsk::Bottom ] = gradient;
|
||||
}
|
||||
|
||||
const QskGradient& QskBoxBorderColors::gradientAt( Qt::Edge edge ) const
|
||||
{
|
||||
switch ( edge )
|
||||
@ -165,6 +189,14 @@ bool QskBoxBorderColors::isMonochrome() const
|
||||
&& m_gradients[ 3 ].isMonochrome();
|
||||
}
|
||||
|
||||
bool QskBoxBorderColors::isValid() const
|
||||
{
|
||||
return m_gradients[ 0 ].isValid()
|
||||
|| m_gradients[ 1 ].isValid()
|
||||
|| m_gradients[ 2 ].isValid()
|
||||
|| m_gradients[ 3 ].isValid();
|
||||
}
|
||||
|
||||
QskBoxBorderColors QskBoxBorderColors::interpolated(
|
||||
const QskBoxBorderColors& to, qreal ratio ) const
|
||||
{
|
||||
@ -172,8 +204,14 @@ QskBoxBorderColors QskBoxBorderColors::interpolated(
|
||||
|
||||
for ( size_t i = 0; i < 4; i++ )
|
||||
{
|
||||
colors.m_gradients[ i ] = colors.m_gradients[ i ].interpolated(
|
||||
to.m_gradients[ i ], ratio );
|
||||
#if 1
|
||||
/*
|
||||
When one border has a width of 0 we would prefer to ignore
|
||||
the color and use always use the other color. TODO ...
|
||||
*/
|
||||
#endif
|
||||
auto& gradient = colors.m_gradients[ i ];
|
||||
gradient = gradient.interpolated( to.m_gradients[ i ], ratio );
|
||||
}
|
||||
|
||||
return colors;
|
||||
@ -204,14 +242,44 @@ QDebug operator<<( QDebug debug, const QskBoxBorderColors& colors )
|
||||
QDebugStateSaver saver( debug );
|
||||
debug.nospace();
|
||||
|
||||
debug << "BoxBorderColors" << '(';
|
||||
debug << "BoxBorderColors";
|
||||
|
||||
debug << " L" << colors.gradient( Qsk::Left );
|
||||
debug << ", T" << colors.gradient( Qsk::Top );
|
||||
debug << ", R" << colors.gradient( Qsk::Right );
|
||||
debug << ", B" << colors.gradient( Qsk::Bottom );
|
||||
if ( !colors.isValid() )
|
||||
{
|
||||
debug << "()";
|
||||
}
|
||||
else
|
||||
{
|
||||
debug << "( ";
|
||||
|
||||
debug << " )";
|
||||
if ( colors.isMonochrome() )
|
||||
{
|
||||
const auto& gradient = colors.gradient( Qsk::Left );
|
||||
QskRgb::debugColor( debug, gradient.startColor() );
|
||||
}
|
||||
else
|
||||
{
|
||||
const char prompts[] = { 'L', 'T', 'R', 'B' };
|
||||
|
||||
for ( int i = 0; i <= Qsk::Bottom; i++ )
|
||||
{
|
||||
if ( i != 0 )
|
||||
debug << ", ";
|
||||
|
||||
const auto& gradient = colors.gradient(
|
||||
static_cast< Qsk::Position >( i ) );
|
||||
|
||||
debug << prompts[ i ] << ": ";
|
||||
|
||||
if ( gradient.isValid() && gradient.isMonochrome() )
|
||||
QskRgb::debugColor( debug, gradient.startColor() );
|
||||
else
|
||||
debug << gradient;
|
||||
}
|
||||
}
|
||||
|
||||
debug << " )";
|
||||
}
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
@ -12,10 +12,15 @@
|
||||
#include <qcolor.h>
|
||||
#include <qmetatype.h>
|
||||
|
||||
class QDebug;
|
||||
|
||||
class QSK_EXPORT QskBoxBorderColors
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
Q_PROPERTY( QskGradient left READ left WRITE setLeft )
|
||||
Q_PROPERTY( QskGradient top READ top WRITE setTop )
|
||||
Q_PROPERTY( QskGradient right READ right WRITE setRight )
|
||||
Q_PROPERTY( QskGradient bottom READ bottom WRITE setBottom )
|
||||
|
||||
public:
|
||||
QskBoxBorderColors();
|
||||
|
||||
@ -44,6 +49,18 @@ class QSK_EXPORT QskBoxBorderColors
|
||||
void setGradientAt( Qt::Edges, const QskGradient& );
|
||||
const QskGradient& gradientAt( Qt::Edge ) const;
|
||||
|
||||
void setLeft( const QskGradient& );
|
||||
const QskGradient& left() const;
|
||||
|
||||
void setTop( const QskGradient& );
|
||||
const QskGradient& top() const;
|
||||
|
||||
void setRight( const QskGradient& );
|
||||
const QskGradient& right() const;
|
||||
|
||||
void setBottom( const QskGradient& );
|
||||
const QskGradient& bottom() const;
|
||||
|
||||
QskBoxBorderColors interpolated( const QskBoxBorderColors&, qreal value ) const;
|
||||
|
||||
static QVariant interpolate( const QskBoxBorderColors&,
|
||||
@ -53,6 +70,7 @@ class QSK_EXPORT QskBoxBorderColors
|
||||
|
||||
bool isMonochrome() const;
|
||||
bool isVisible() const;
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
QskGradient m_gradients[ 4 ];
|
||||
@ -78,8 +96,29 @@ inline const QskGradient& QskBoxBorderColors::gradient( Qsk::Position position )
|
||||
return m_gradients[ position ];
|
||||
}
|
||||
|
||||
inline const QskGradient& QskBoxBorderColors::left() const
|
||||
{
|
||||
return m_gradients[ Qsk::Left ];
|
||||
}
|
||||
|
||||
inline const QskGradient& QskBoxBorderColors::top() const
|
||||
{
|
||||
return m_gradients[ Qsk::Top ];
|
||||
}
|
||||
|
||||
inline const QskGradient& QskBoxBorderColors::right() const
|
||||
{
|
||||
return m_gradients[ Qsk::Right ];
|
||||
}
|
||||
|
||||
inline const QskGradient& QskBoxBorderColors::bottom() const
|
||||
{
|
||||
return m_gradients[ Qsk::Bottom ];
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
class QDebug;
|
||||
QSK_EXPORT QDebug operator<<( QDebug, const QskBoxBorderColors& );
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,10 @@ static void qskRegisterBoxBorderMetrics()
|
||||
{
|
||||
qRegisterMetaType< QskBoxBorderMetrics >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskBoxBorderMetrics >();
|
||||
#endif
|
||||
|
||||
QMetaType::registerConverter< QskMargins, QskBoxBorderMetrics >(
|
||||
[]( const QskMargins& margins ) { return QskBoxBorderMetrics( margins ); } );
|
||||
|
||||
@ -109,9 +113,24 @@ QDebug operator<<( QDebug debug, const QskBoxBorderMetrics& metrics )
|
||||
QDebugStateSaver saver( debug );
|
||||
debug.nospace();
|
||||
|
||||
debug << "BoxBorder" << '(';
|
||||
debug << metrics.sizeMode() << ',' << metrics.widths();
|
||||
debug << ')';
|
||||
debug << "BoxBorder" << "( ";
|
||||
|
||||
if ( metrics.sizeMode() != Qt::AbsoluteSize )
|
||||
debug << metrics.sizeMode() << ", ";
|
||||
|
||||
const auto& w = metrics.widths();
|
||||
|
||||
if ( metrics.isEquidistant() )
|
||||
{
|
||||
debug << w.left();
|
||||
}
|
||||
else
|
||||
{
|
||||
const char s[] = ", ";
|
||||
debug << w.left() << s << w.top() << s << w.right() << s << w.bottom();
|
||||
}
|
||||
|
||||
debug << " )";
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ class QSK_EXPORT QskBoxBorderMetrics
|
||||
static QVariant interpolate( const QskBoxBorderMetrics&,
|
||||
const QskBoxBorderMetrics&, qreal progress );
|
||||
|
||||
constexpr bool isEquidistant() const noexcept;
|
||||
|
||||
private:
|
||||
QskMargins m_widths;
|
||||
Qt::SizeMode m_sizeMode;
|
||||
@ -115,6 +117,11 @@ inline constexpr bool QskBoxBorderMetrics::isNull() const noexcept
|
||||
return m_widths.isNull();
|
||||
}
|
||||
|
||||
inline constexpr bool QskBoxBorderMetrics::isEquidistant() const noexcept
|
||||
{
|
||||
return m_widths.isEquidistant();
|
||||
}
|
||||
|
||||
inline constexpr const QskMargins& QskBoxBorderMetrics::widths() const noexcept
|
||||
{
|
||||
return m_widths;
|
||||
|
@ -14,6 +14,10 @@ static void qskRegisterBoxShapeMetrics()
|
||||
{
|
||||
qRegisterMetaType< QskBoxShapeMetrics >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskBoxShapeMetrics >();
|
||||
#endif
|
||||
|
||||
QMetaType::registerConverter< int, QskBoxShapeMetrics >(
|
||||
[]( int radius ) { return QskBoxShapeMetrics( radius ); } );
|
||||
|
||||
|
@ -15,6 +15,10 @@ static void qskRegisterGradient()
|
||||
{
|
||||
qRegisterMetaType< QskGradient >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskGradient >();
|
||||
#endif
|
||||
|
||||
QMetaType::registerConverter< QColor, QskGradient >(
|
||||
[]( const QColor& color ) { return QskGradient( color ); } );
|
||||
}
|
||||
@ -229,6 +233,11 @@ QskGradient::QskGradient( Orientation orientation, const QskGradientStops& stops
|
||||
setStops( stops );
|
||||
}
|
||||
|
||||
QskGradient::QskGradient( Qt::Orientation orientation, QGradient::Preset preset )
|
||||
: QskGradient( qskOrientation( orientation ), preset )
|
||||
{
|
||||
}
|
||||
|
||||
QskGradient::QskGradient( Orientation orientation, QGradient::Preset preset )
|
||||
: QskGradient( orientation )
|
||||
{
|
||||
@ -499,6 +508,14 @@ QskGradient QskGradient::interpolated(
|
||||
return QskGradient( gradient->orientation(), stops );
|
||||
}
|
||||
|
||||
if ( isMonochrome() && to.isMonochrome() )
|
||||
{
|
||||
const auto c = QskRgb::interpolated(
|
||||
m_stops[ 0 ].color(), to.m_stops[ 0 ].color(), value );
|
||||
|
||||
return QskGradient( to.orientation(), c, c );
|
||||
}
|
||||
|
||||
if ( isMonochrome() )
|
||||
{
|
||||
// we can ignore our stops
|
||||
@ -624,7 +641,49 @@ void QskGradient::updateStatusBits() const
|
||||
|
||||
QDebug operator<<( QDebug debug, const QskGradient& gradient )
|
||||
{
|
||||
debug << "GR:" << gradient.orientation() << gradient.stops().count();
|
||||
QDebugStateSaver saver( debug );
|
||||
debug.nospace();
|
||||
|
||||
debug << "Gradient";
|
||||
|
||||
if ( !gradient.isValid() )
|
||||
{
|
||||
debug << "()";
|
||||
}
|
||||
else
|
||||
{
|
||||
debug << "( ";
|
||||
|
||||
if ( gradient.isMonochrome() )
|
||||
{
|
||||
QskRgb::debugColor( debug, gradient.startColor() );
|
||||
}
|
||||
else
|
||||
{
|
||||
const char o[] = { 'H', 'V', 'D' };
|
||||
debug << o[ gradient.orientation() ] << ", ";
|
||||
|
||||
if ( gradient.stops().count() == 2 )
|
||||
{
|
||||
QskRgb::debugColor( debug, gradient.startColor() );
|
||||
debug << ", ";
|
||||
QskRgb::debugColor( debug, gradient.endColor() );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& s = gradient.stops();
|
||||
for ( int i = 0; i < s.count(); i++ )
|
||||
{
|
||||
if ( i != 0 )
|
||||
debug << ", ";
|
||||
|
||||
debug << s[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
debug << " )";
|
||||
}
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ class QSK_EXPORT QskGradient
|
||||
|
||||
QskGradient( Qt::Orientation, const QVector< QskGradientStop >& );
|
||||
QskGradient( Qt::Orientation, const QColor&, const QColor& );
|
||||
QskGradient( Qt::Orientation, QGradient::Preset );
|
||||
|
||||
QskGradient( Orientation, const QVector< QskGradientStop >& );
|
||||
QskGradient( Orientation, const QColor&, const QColor& );
|
||||
|
@ -14,6 +14,10 @@
|
||||
static void qskRegisterGradientStop()
|
||||
{
|
||||
qRegisterMetaType< QskGradientStop >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskGradientStop >();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterGradientStop )
|
||||
@ -78,7 +82,12 @@ QColor QskGradientStop::interpolated(
|
||||
|
||||
QDebug operator<<( QDebug debug, const QskGradientStop& stop )
|
||||
{
|
||||
debug << stop.position() << ": " << stop.color();
|
||||
QDebugStateSaver saver( debug );
|
||||
debug.nospace();
|
||||
|
||||
debug << stop.position() << ": ";
|
||||
QskRgb::debugColor( debug, stop.color() );
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,10 @@
|
||||
static void qskRegisterIntervalF()
|
||||
{
|
||||
qRegisterMetaType< QskIntervalF >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskIntervalF >();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterIntervalF )
|
||||
|
@ -61,6 +61,7 @@ class QSK_EXPORT QskMargins : public QMarginsF
|
||||
QskMargins interpolated( const QskMargins&, qreal progress ) const noexcept;
|
||||
|
||||
constexpr bool isExpanding() const noexcept;
|
||||
constexpr bool isEquidistant() const noexcept;
|
||||
|
||||
static QVariant interpolate( const QskMargins&,
|
||||
const QskMargins&, qreal progress ) noexcept;
|
||||
@ -181,6 +182,11 @@ constexpr inline qreal QskMargins::height() const noexcept
|
||||
return top() + bottom();
|
||||
}
|
||||
|
||||
inline constexpr bool QskMargins::isEquidistant() const noexcept
|
||||
{
|
||||
return ( left() == top() ) && ( left() == right() ) && ( left() == bottom() );
|
||||
}
|
||||
|
||||
Q_DECLARE_TYPEINFO( QskMargins, Q_MOVABLE_TYPE );
|
||||
Q_DECLARE_METATYPE( QskMargins )
|
||||
|
||||
|
@ -172,3 +172,29 @@ QRgb QskRgb::darker( QRgb rgb, int factor ) noexcept
|
||||
return QColor::fromRgba( rgb ).darker( factor ).rgba();
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
void QskRgb::debugColor( QDebug debug, const QColor& color )
|
||||
{
|
||||
debugColor( debug, color.rgba() );
|
||||
}
|
||||
|
||||
void QskRgb::debugColor( QDebug debug, QRgb rgb )
|
||||
{
|
||||
QDebugStateSaver saver( debug );
|
||||
debug.nospace();
|
||||
|
||||
debug << '[';
|
||||
|
||||
debug << qRed( rgb ) << "r," << qGreen( rgb ) << "g,"
|
||||
<< qBlue( rgb ) << 'b';
|
||||
|
||||
if ( qAlpha( rgb ) != 255 )
|
||||
debug << ',' << qAlpha( rgb ) << 'a';
|
||||
|
||||
debug << ']';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -461,23 +461,35 @@ namespace QskRgb
|
||||
return ( rgb & ColorMask ) | ( ( static_cast< uint >( alpha ) & 0xffu ) << 24 );
|
||||
}
|
||||
|
||||
inline QColor toTransparentF( const QColor& color, qreal alpha )
|
||||
inline QColor toTransparentF( const QColor& color, qreal opacity )
|
||||
{
|
||||
return toTransparent( color, qRound( alpha * 255 ) );
|
||||
return toTransparent( color, qRound( opacity * 255 ) );
|
||||
}
|
||||
|
||||
inline QColor toTransparentF( Qt::GlobalColor color, qreal alpha )
|
||||
inline QColor toTransparentF( Qt::GlobalColor color, qreal opacity )
|
||||
{
|
||||
return toTransparent( QColor( color ), qRound( alpha * 255 ) );
|
||||
return toTransparent( QColor( color ), qRound( opacity * 255 ) );
|
||||
}
|
||||
|
||||
inline constexpr QRgb toTransparentF( QRgb rgb, qreal alpha ) noexcept
|
||||
inline constexpr QRgb toTransparentF( QRgb rgb, qreal opacity ) noexcept
|
||||
{
|
||||
return toTransparent( rgb, qRound( alpha * 255 ) );
|
||||
return toTransparent( rgb, qRound( opacity * 255 ) );
|
||||
}
|
||||
|
||||
QSK_EXPORT QRgb lighter( QRgb, int factor = 150 ) noexcept;
|
||||
QSK_EXPORT QRgb darker( QRgb, int factor = 200 ) noexcept;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
class QDebug;
|
||||
|
||||
namespace QskRgb
|
||||
{
|
||||
QSK_EXPORT void debugColor( QDebug, const QColor& );
|
||||
QSK_EXPORT void debugColor( QDebug, QRgb );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -9,6 +9,10 @@
|
||||
static void qskRegisterTickmarks()
|
||||
{
|
||||
qRegisterMetaType< QskScaleTickmarks >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskScaleTickmarks >();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterTickmarks )
|
||||
|
@ -12,6 +12,10 @@
|
||||
static void qskRegisterShadowMetrics()
|
||||
{
|
||||
qRegisterMetaType< QskShadowMetrics >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskShadowMetrics >();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterShadowMetrics )
|
||||
|
@ -1,14 +0,0 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskStateCombination.h"
|
||||
|
||||
static void qskRegisterStateCombination()
|
||||
{
|
||||
qRegisterMetaType< QskStateCombination >();
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterStateCombination )
|
||||
|
@ -21,6 +21,9 @@ class QSK_EXPORT QskStateCombination
|
||||
constexpr QskStateCombination( QskAspect::States = QskAspect::States() ) noexcept;
|
||||
constexpr QskStateCombination( Type, QskAspect::States = QskAspect::States() ) noexcept;
|
||||
|
||||
constexpr bool operator==( QskStateCombination ) const noexcept;
|
||||
constexpr bool operator!=( QskStateCombination ) const noexcept;
|
||||
|
||||
constexpr bool isNull() const noexcept;
|
||||
|
||||
void setType( Type ) noexcept;
|
||||
@ -36,7 +39,6 @@ class QSK_EXPORT QskStateCombination
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO( QskStateCombination, Q_MOVABLE_TYPE );
|
||||
Q_DECLARE_METATYPE( QskStateCombination )
|
||||
|
||||
constexpr inline QskStateCombination::QskStateCombination(
|
||||
QskAspect::State state ) noexcept
|
||||
@ -90,4 +92,14 @@ constexpr inline QskAspect::States QskStateCombination::states() const noexcept
|
||||
return m_states;
|
||||
}
|
||||
|
||||
constexpr bool QskStateCombination::operator==( QskStateCombination other ) const noexcept
|
||||
{
|
||||
return ( m_type == other.m_type ) && ( m_states == other.m_states );
|
||||
}
|
||||
|
||||
constexpr bool QskStateCombination::operator!=( QskStateCombination other ) const noexcept
|
||||
{
|
||||
return !( *this == other );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -128,7 +128,6 @@ class QskSkin::PrivateData
|
||||
std::unordered_map< const QMetaObject*, SkinletData > skinletMap;
|
||||
|
||||
QskSkinHintTable hintTable;
|
||||
QskAspect::States stateMask = QskAspect::AllStates;
|
||||
|
||||
std::unordered_map< int, QFont > fonts;
|
||||
std::unordered_map< int, QskColorFilter > graphicFilters;
|
||||
@ -345,22 +344,6 @@ const int* QskSkin::dialogButtonLayout( Qt::Orientation orientation ) const
|
||||
return QPlatformDialogHelper::buttonLayout( orientation, policy );
|
||||
}
|
||||
|
||||
void QskSkin::setStateMask( QskAspect::States mask )
|
||||
{
|
||||
for ( auto state : { QskControl::Disabled, QskControl::Hovered, QskControl::Focused } )
|
||||
{
|
||||
if ( mask & state )
|
||||
m_data->stateMask |= state;
|
||||
else
|
||||
m_data->stateMask &= ~state;
|
||||
}
|
||||
}
|
||||
|
||||
QskAspect::States QskSkin::stateMask() const
|
||||
{
|
||||
return m_data->stateMask;
|
||||
}
|
||||
|
||||
QskSkinlet* QskSkin::skinlet( const QMetaObject* metaObject )
|
||||
{
|
||||
while ( metaObject )
|
||||
|
@ -77,9 +77,6 @@ class QSK_EXPORT QskSkin : public QObject
|
||||
virtual const int* dialogButtonLayout( Qt::Orientation ) const;
|
||||
virtual QString dialogButtonText( int button ) const;
|
||||
|
||||
void setStateMask( QskAspect::States );
|
||||
QskAspect::States stateMask() const;
|
||||
|
||||
QskSkinlet* skinlet( const QMetaObject* );
|
||||
|
||||
const QskSkinHintTable& hintTable() const;
|
||||
|
@ -64,41 +64,11 @@ QskSkinHintTable::QskSkinHintTable()
|
||||
{
|
||||
}
|
||||
|
||||
QskSkinHintTable::QskSkinHintTable( const QskSkinHintTable& other )
|
||||
: m_hints( nullptr )
|
||||
, m_animatorCount( other.m_animatorCount )
|
||||
, m_statefulCount( other.m_statefulCount )
|
||||
{
|
||||
if ( other.m_hints )
|
||||
m_hints = new HintMap( *( other.m_hints ) );
|
||||
}
|
||||
|
||||
QskSkinHintTable::~QskSkinHintTable()
|
||||
{
|
||||
delete m_hints;
|
||||
}
|
||||
|
||||
QskSkinHintTable& QskSkinHintTable::operator=( const QskSkinHintTable& other )
|
||||
{
|
||||
m_animatorCount = other.m_animatorCount;
|
||||
m_statefulCount = other.m_statefulCount;
|
||||
|
||||
if ( other.m_hints )
|
||||
{
|
||||
if ( m_hints == nullptr )
|
||||
m_hints = new HintMap();
|
||||
|
||||
*m_hints = *other.m_hints;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_hints;
|
||||
m_hints = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::unordered_map< QskAspect, QVariant >& QskSkinHintTable::hints() const
|
||||
{
|
||||
if ( m_hints )
|
||||
@ -126,11 +96,7 @@ bool QskSkinHintTable::setHint( QskAspect aspect, const QVariant& skinHint )
|
||||
QSK_ASSERT_COUNTER( m_animatorCount );
|
||||
}
|
||||
|
||||
if ( aspect.hasStates() )
|
||||
{
|
||||
m_statefulCount++;
|
||||
QSK_ASSERT_COUNTER( m_statefulCount );
|
||||
}
|
||||
m_states |= aspect.states();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -158,8 +124,7 @@ bool QskSkinHintTable::removeHint( QskAspect aspect )
|
||||
if ( aspect.isAnimator() )
|
||||
m_animatorCount--;
|
||||
|
||||
if ( aspect.hasStates() )
|
||||
m_statefulCount--;
|
||||
// how to clear m_states ? TODO ...
|
||||
|
||||
if ( m_hints->empty() )
|
||||
{
|
||||
@ -184,8 +149,7 @@ QVariant QskSkinHintTable::takeHint( QskAspect aspect )
|
||||
if ( aspect.isAnimator() )
|
||||
m_animatorCount--;
|
||||
|
||||
if ( aspect.hasStates() )
|
||||
m_statefulCount--;
|
||||
// how to clear m_states ? TODO ...
|
||||
|
||||
if ( m_hints->empty() )
|
||||
{
|
||||
@ -206,14 +170,14 @@ void QskSkinHintTable::clear()
|
||||
m_hints = nullptr;
|
||||
|
||||
m_animatorCount = 0;
|
||||
m_statefulCount = 0;
|
||||
m_states = QskAspect::NoState;
|
||||
}
|
||||
|
||||
const QVariant* QskSkinHintTable::resolvedHint(
|
||||
QskAspect aspect, QskAspect* resolvedAspect ) const
|
||||
{
|
||||
if ( m_hints != nullptr )
|
||||
return qskResolvedHint( aspect, *m_hints, resolvedAspect );
|
||||
return qskResolvedHint( aspect & m_states, *m_hints, resolvedAspect );
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -223,7 +187,7 @@ QskAspect QskSkinHintTable::resolvedAspect( QskAspect aspect ) const
|
||||
QskAspect a;
|
||||
|
||||
if ( m_hints != nullptr )
|
||||
qskResolvedHint( aspect, *m_hints, &a );
|
||||
qskResolvedHint( aspect & m_states, *m_hints, &a );
|
||||
|
||||
return a;
|
||||
}
|
||||
@ -233,6 +197,8 @@ QskAspect QskSkinHintTable::resolvedAnimator(
|
||||
{
|
||||
if ( m_hints && m_animatorCount > 0 )
|
||||
{
|
||||
aspect &= m_states;
|
||||
|
||||
Q_FOREVER
|
||||
{
|
||||
auto it = m_hints->find( aspect );
|
||||
@ -268,15 +234,16 @@ bool QskSkinHintTable::setAnimation(
|
||||
bool QskSkinHintTable::isResolutionMatching(
|
||||
QskAspect aspect1, QskAspect aspect2 ) const
|
||||
{
|
||||
// remove states we do not have early
|
||||
aspect1 &= m_states;
|
||||
aspect2 &= m_states;
|
||||
|
||||
if ( aspect1 == aspect2 )
|
||||
return true;
|
||||
|
||||
if ( aspect1.trunk() != aspect2.trunk() )
|
||||
return false;
|
||||
|
||||
if ( !hasStates() )
|
||||
return false;
|
||||
|
||||
const auto a1 = aspect1;
|
||||
const auto a2 = aspect2;
|
||||
|
||||
|
@ -17,12 +17,8 @@ class QSK_EXPORT QskSkinHintTable
|
||||
{
|
||||
public:
|
||||
QskSkinHintTable();
|
||||
QskSkinHintTable( const QskSkinHintTable& other );
|
||||
|
||||
~QskSkinHintTable();
|
||||
|
||||
QskSkinHintTable& operator=( const QskSkinHintTable& );
|
||||
|
||||
bool setAnimation( QskAspect, QskAnimationHint );
|
||||
QskAnimationHint animation( QskAspect ) const;
|
||||
|
||||
@ -40,9 +36,10 @@ class QSK_EXPORT QskSkinHintTable
|
||||
const std::unordered_map< QskAspect, QVariant >& hints() const;
|
||||
|
||||
bool hasAnimators() const;
|
||||
bool hasStates() const;
|
||||
bool hasHints() const;
|
||||
|
||||
QskAspect::States states() const;
|
||||
|
||||
void clear();
|
||||
|
||||
const QVariant* resolvedHint( QskAspect,
|
||||
@ -56,13 +53,15 @@ class QSK_EXPORT QskSkinHintTable
|
||||
bool isResolutionMatching( QskAspect, QskAspect ) const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY( QskSkinHintTable )
|
||||
|
||||
static const QVariant invalidHint;
|
||||
|
||||
typedef std::unordered_map< QskAspect, QVariant > HintMap;
|
||||
HintMap* m_hints = nullptr;
|
||||
|
||||
unsigned short m_animatorCount = 0;
|
||||
unsigned short m_statefulCount = 0;
|
||||
QskAspect::States m_states;
|
||||
};
|
||||
|
||||
inline bool QskSkinHintTable::hasHints() const
|
||||
@ -70,9 +69,9 @@ inline bool QskSkinHintTable::hasHints() const
|
||||
return m_hints != nullptr;
|
||||
}
|
||||
|
||||
inline bool QskSkinHintTable::hasStates() const
|
||||
inline QskAspect::States QskSkinHintTable::states() const
|
||||
{
|
||||
return m_statefulCount > 0;
|
||||
return m_states;
|
||||
}
|
||||
|
||||
inline bool QskSkinHintTable::hasAnimators() const
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,17 +38,6 @@ static inline bool qskIsControl( const QskSkinnable* skinnable )
|
||||
return skinnable->metaObject()->inherits( &QskControl::staticMetaObject );
|
||||
}
|
||||
|
||||
static inline QVariant qskTypedNullValue( const QVariant& value )
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
const auto vType = static_cast< QMetaType >( value.userType() );
|
||||
#else
|
||||
const auto vType = value.userType();
|
||||
#endif
|
||||
|
||||
return QVariant( vType, nullptr );
|
||||
}
|
||||
|
||||
static inline bool qskSetFlag( QskSkinnable* skinnable,
|
||||
const QskAspect aspect, int flag )
|
||||
{
|
||||
@ -940,23 +929,12 @@ const QVariant& QskSkinnable::storedHint(
|
||||
{
|
||||
const auto skin = effectiveSkin();
|
||||
|
||||
// clearing all state bits not being handled from the skin
|
||||
aspect.clearStates( ~skin->stateMask() );
|
||||
|
||||
QskAspect resolvedAspect;
|
||||
|
||||
const auto& localTable = m_data->hintTable;
|
||||
if ( localTable.hasHints() )
|
||||
{
|
||||
auto a = aspect;
|
||||
|
||||
if ( !localTable.hasStates() )
|
||||
{
|
||||
// we don't need to clear the state bits stepwise
|
||||
a.clearStates();
|
||||
}
|
||||
|
||||
if ( const QVariant* value = localTable.resolvedHint( a, &resolvedAspect ) )
|
||||
if ( const auto value = localTable.resolvedHint( aspect, &resolvedAspect ) )
|
||||
{
|
||||
if ( status )
|
||||
{
|
||||
@ -972,10 +950,7 @@ const QVariant& QskSkinnable::storedHint(
|
||||
const auto& skinTable = skin->hintTable();
|
||||
if ( skinTable.hasHints() )
|
||||
{
|
||||
auto a = aspect;
|
||||
|
||||
const QVariant* value = skinTable.resolvedHint( a, &resolvedAspect );
|
||||
if ( value )
|
||||
if ( const auto value = skinTable.resolvedHint( aspect, &resolvedAspect ) )
|
||||
{
|
||||
if ( status )
|
||||
{
|
||||
@ -993,8 +968,7 @@ const QVariant& QskSkinnable::storedHint(
|
||||
aspect.setSubControl( QskAspect::Control );
|
||||
aspect.clearStates();
|
||||
|
||||
value = skinTable.resolvedHint( aspect, &resolvedAspect );
|
||||
if ( value )
|
||||
if ( const auto value = skinTable.resolvedHint( aspect, &resolvedAspect ) )
|
||||
{
|
||||
if ( status )
|
||||
{
|
||||
@ -1171,27 +1145,11 @@ void QskSkinnable::startHintTransition( QskAspect aspect,
|
||||
if ( control->window() == nullptr || !isTransitionAccepted( aspect ) )
|
||||
return;
|
||||
|
||||
/*
|
||||
We might be invalid for one of the values, when an aspect
|
||||
has not been defined for all states ( f.e. metrics are expected
|
||||
to fallback to 0.0 ). In this case we create a default one.
|
||||
*/
|
||||
|
||||
auto v1 = from;
|
||||
auto v2 = to;
|
||||
|
||||
if ( !v1.isValid() )
|
||||
{
|
||||
v1 = qskTypedNullValue( v2 );
|
||||
}
|
||||
else if ( !v2.isValid() )
|
||||
{
|
||||
v2 = qskTypedNullValue( v1 );
|
||||
}
|
||||
else if ( v1.userType() != v2.userType() )
|
||||
{
|
||||
if ( !QskVariantAnimator::convertValues( v1, v2 ) )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( aspect.flagPrimitive() == QskAspect::GraphicRole )
|
||||
{
|
||||
@ -1257,7 +1215,8 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates )
|
||||
|
||||
if ( skin )
|
||||
{
|
||||
const auto mask = skin->stateMask();
|
||||
const auto mask = skin->hintTable().states() | m_data->hintTable.states();
|
||||
|
||||
if ( ( newStates & mask ) == ( m_data->skinStates & mask ) )
|
||||
{
|
||||
// the modified bits are not handled by the skin
|
||||
@ -1297,24 +1256,13 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates )
|
||||
const auto primitive = static_cast< QskAspect::Primitive >( i );
|
||||
aspect.setPrimitive( type, primitive );
|
||||
|
||||
auto a1 = aspect | m_data->skinStates;
|
||||
auto a2 = aspect | newStates;
|
||||
const auto a1 = aspect | m_data->skinStates;
|
||||
const auto a2 = aspect | newStates;
|
||||
|
||||
bool doTransition = true;
|
||||
|
||||
if ( !m_data->hintTable.hasStates() )
|
||||
{
|
||||
/*
|
||||
The hints are found by stripping the state bits one by
|
||||
one until a lookup into the hint table is successful.
|
||||
So for deciding whether two aspects lead to the same hint
|
||||
we can stop as soon as the aspects have the same state bits.
|
||||
This way we can reduce the number of lookups significantly
|
||||
for skinnables with many state bits.
|
||||
|
||||
*/
|
||||
if ( m_data->hintTable.states() == QskAspect::NoState )
|
||||
doTransition = !skinTable.isResolutionMatching( a1, a2 );
|
||||
}
|
||||
|
||||
if ( doTransition )
|
||||
{
|
||||
@ -1343,12 +1291,7 @@ QskSkin* QskSkinnable::effectiveSkin() const
|
||||
if ( skin == nullptr )
|
||||
{
|
||||
if ( const auto control = owningControl() )
|
||||
{
|
||||
if ( auto window = qobject_cast< const QskWindow* >( control->window() ) )
|
||||
{
|
||||
skin = window->skin();
|
||||
}
|
||||
}
|
||||
skin = qskEffectiveSkin( control->window() );
|
||||
}
|
||||
|
||||
return skin ? skin : qskSetup->skin();
|
||||
|
@ -230,6 +230,8 @@ class QSK_EXPORT QskSkinnable
|
||||
bool resetGraphicRoleHint( QskAspect );
|
||||
int graphicRoleHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
|
||||
|
||||
const QskSkinHintTable& hintTable() const;
|
||||
|
||||
protected:
|
||||
virtual void updateNode( QSGNode* );
|
||||
virtual bool isTransitionAccepted( QskAspect ) const;
|
||||
@ -237,7 +239,6 @@ class QSK_EXPORT QskSkinnable
|
||||
virtual QskAspect::Subcontrol substitutedSubcontrol( QskAspect::Subcontrol ) const;
|
||||
|
||||
QskSkinHintTable& hintTable();
|
||||
const QskSkinHintTable& hintTable() const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY( QskSkinnable )
|
||||
|
@ -76,6 +76,31 @@ QSK_DECL_INSANE static inline QVariant qskInterpolate(
|
||||
return f( from.constData(), to.constData(), progress );
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
|
||||
using QskMetaType = int;
|
||||
static inline QskMetaType qskMetaType( const QVariant& v ) { return v.userType(); }
|
||||
|
||||
#else
|
||||
|
||||
using QskMetaType = QMetaType;
|
||||
static inline QskMetaType qskMetaType( const QVariant& v ) { return v.metaType(); }
|
||||
|
||||
#endif
|
||||
|
||||
static inline QVariant qskDefaultVariant( QskMetaType type )
|
||||
{
|
||||
return QVariant( type, nullptr );
|
||||
}
|
||||
|
||||
static inline QVariant qskConvertedVariant( const QVariant& from, QskMetaType type )
|
||||
{
|
||||
auto v = from;
|
||||
v.convert( type );
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
QskVariantAnimator::QskVariantAnimator()
|
||||
: m_interpolator( nullptr )
|
||||
{
|
||||
@ -100,16 +125,60 @@ void QskVariantAnimator::setCurrentValue( const QVariant& value )
|
||||
m_currentValue = value;
|
||||
}
|
||||
|
||||
bool QskVariantAnimator::convertValues( QVariant& v1, QVariant& v2 )
|
||||
{
|
||||
if ( !v1.isValid() && !v2.isValid() )
|
||||
return false;
|
||||
|
||||
const auto type1 = qskMetaType( v1 );
|
||||
const auto type2 = qskMetaType( v2 );
|
||||
|
||||
if ( !v1.isValid() )
|
||||
{
|
||||
v1 = qskDefaultVariant( type2 );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !v2.isValid() )
|
||||
{
|
||||
v2 = qskDefaultVariant( type1 );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( type1 != type2 )
|
||||
{
|
||||
if ( v1.canConvert( type2 ) )
|
||||
{
|
||||
v1.convert( type2 );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( v2.canConvert( type1 ) )
|
||||
{
|
||||
v2.convert( type1 );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QskVariantAnimator::setup()
|
||||
{
|
||||
m_interpolator = nullptr;
|
||||
|
||||
const auto type = m_startValue.userType();
|
||||
if ( type == m_endValue.userType() )
|
||||
if ( convertValues( m_startValue, m_endValue ) )
|
||||
{
|
||||
// all what has been registered by qRegisterAnimationInterpolator
|
||||
m_interpolator = reinterpret_cast< void ( * )() >(
|
||||
QVariantAnimationPrivate::getInterpolator( type ) );
|
||||
if ( m_startValue != m_endValue )
|
||||
{
|
||||
const auto id = m_startValue.userType();
|
||||
|
||||
// all what has been registered by qRegisterAnimationInterpolator
|
||||
m_interpolator = reinterpret_cast< void ( * )() >(
|
||||
QVariantAnimationPrivate::getInterpolator( id ) );
|
||||
}
|
||||
}
|
||||
|
||||
m_currentValue = m_interpolator ? m_startValue : m_endValue;
|
||||
@ -131,3 +200,32 @@ void QskVariantAnimator::done()
|
||||
{
|
||||
m_interpolator = nullptr;
|
||||
}
|
||||
|
||||
bool QskVariantAnimator::maybeInterpolate(
|
||||
const QVariant& value1, const QVariant& value2 )
|
||||
{
|
||||
if ( !value1.isValid() && !value2.isValid() )
|
||||
return false;
|
||||
|
||||
const auto type1 = qskMetaType( value1 );
|
||||
const auto type2 = qskMetaType( value2 );
|
||||
|
||||
if ( !value1.isValid() )
|
||||
return value2 != qskDefaultVariant( type2 );
|
||||
|
||||
if ( !value2.isValid() )
|
||||
return value1 != qskDefaultVariant( type1 );
|
||||
|
||||
if ( type1 != type2 )
|
||||
{
|
||||
if ( value1.canConvert( type2 ) )
|
||||
return value2 != qskConvertedVariant( value1, type2 );
|
||||
|
||||
if ( value2.canConvert( type1 ) )
|
||||
return value1 != qskConvertedVariant( value2, type1 );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return value1 != value2;
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ class QSK_EXPORT QskVariantAnimator : public QskAnimator
|
||||
void setEndValue( const QVariant& );
|
||||
QVariant endValue() const;
|
||||
|
||||
static bool maybeInterpolate( const QVariant&, const QVariant& );
|
||||
static bool convertValues( QVariant&, QVariant& );
|
||||
|
||||
protected:
|
||||
void setup() override;
|
||||
void advance( qreal value ) override;
|
||||
|
@ -63,7 +63,6 @@ SOURCES += \
|
||||
common/QskScaleTickmarks.cpp \
|
||||
common/QskShadowMetrics.cpp \
|
||||
common/QskSizePolicy.cpp \
|
||||
common/QskStateCombination.cpp \
|
||||
common/QskTextColors.cpp \
|
||||
common/QskTextOptions.cpp
|
||||
|
||||
|
@ -77,30 +77,31 @@ void SkinnyShortcut::enable( Types types )
|
||||
|
||||
void SkinnyShortcut::rotateSkin()
|
||||
{
|
||||
const QStringList names = qskSkinManager->skinNames();
|
||||
const auto names = qskSkinManager->skinNames();
|
||||
if ( names.size() <= 1 )
|
||||
return;
|
||||
|
||||
int index = names.indexOf( qskSetup->skinName() );
|
||||
index = ( index + 1 ) % names.size();
|
||||
|
||||
QskSkin* oldSkin = qskSetup->skin();
|
||||
auto oldSkin = qskSetup->skin();
|
||||
if ( oldSkin->parent() == qskSetup )
|
||||
oldSkin->setParent( nullptr ); // otherwise setSkin deletes it
|
||||
|
||||
QskSkin* newSkin = qskSetup->setSkin( names[ index ] );
|
||||
if ( auto newSkin = qskSetup->setSkin( names[ index ] ) )
|
||||
{
|
||||
QskSkinTransition transition;
|
||||
|
||||
QskSkinTransition transition;
|
||||
//transition.setMask( QskAspect::Color ); // Metrics are flickering -> TODO
|
||||
transition.setSourceSkin( oldSkin );
|
||||
transition.setTargetSkin( newSkin );
|
||||
transition.setAnimation( 500 );
|
||||
|
||||
//transition.setMask( QskAspect::Color ); // Metrics are flickering -> TODO
|
||||
transition.setSourceSkin( oldSkin );
|
||||
transition.setTargetSkin( newSkin );
|
||||
transition.setAnimation( 500 );
|
||||
transition.process();
|
||||
|
||||
transition.process();
|
||||
|
||||
if ( oldSkin->parent() == nullptr )
|
||||
delete oldSkin;
|
||||
if ( oldSkin->parent() == nullptr )
|
||||
delete oldSkin;
|
||||
}
|
||||
}
|
||||
|
||||
void SkinnyShortcut::showBackground()
|
||||
|
Loading…
x
Reference in New Issue
Block a user