Merge branch 'uwerat-master' into material-theme

This commit is contained in:
Peter Hartmann 2022-06-27 10:35:49 +02:00
commit 879b4144b1
23 changed files with 1311 additions and 628 deletions

View File

@ -8,7 +8,7 @@
#include <QskBoxBorderColors.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxShapeMetrics.h>
#include <QskRgbPalette.h>
#include <QskHctColor.h>
Box::Box( QQuickItem* parentItem )
: QskBox( parentItem )
@ -22,7 +22,7 @@ Box::Box( QQuickItem* parentItem )
setGradientHint( QskBox::Panel, QskGradient() );
}
void Box::setBackground( FillType type, QskRgbPalette::Theme theme, bool inverted )
void Box::setBackground( FillType type, QGradient::Preset preset, bool inverted )
{
if ( type == Unfilled )
{
@ -30,59 +30,85 @@ void Box::setBackground( FillType type, QskRgbPalette::Theme theme, bool inverte
return;
}
const auto pal = QskRgbPalette::palette( theme );
QskGradient gradient( preset );
const QColor light = pal.color( QskRgbPalette::W60 );
const QColor mid = pal.color( QskRgbPalette::W30 );
switch ( type )
if ( type == Solid )
{
case Unfilled:
setGradient( QskGradient() );
break;
const auto& stops = gradient.stops();
case Solid:
setGradient( mid );
break;
const auto color = QskGradientStop::interpolated(
stops.first(), stops.last(), 0.5 );
default:
{
const auto orientation =
static_cast< QskGradient::Orientation >( type - 2 );
setGradient( QskGradient( color ) );
}
else
{
const auto orientation =
static_cast< QskGradient::Orientation >( type - 2 );
if ( inverted )
setGradient( orientation, mid, light );
else
setGradient( orientation, light, mid );
}
gradient.setOrientation( orientation );
if ( inverted )
gradient.reverse();
setGradient( gradient );
}
}
void Box::setBorder( BorderType type, QskRgbPalette::Theme theme )
void Box::setBackground( FillType type, const QRgb base, bool inverted )
{
const auto pal = QskRgbPalette::palette( theme );
if ( type == Unfilled )
{
setGradient( QskGradient() );
return;
}
double hue, chroma;
QskHctColor::getHueAndChroma( base, hue, chroma );
if ( type == Solid )
{
setGradient( QskHctColor::rgb( hue, chroma, 50 ) );
}
else
{
const auto dark = QskHctColor::rgb( hue, chroma, 40 );
const auto light = QskHctColor::rgb( hue, chroma, 70 );
const auto orientation =
static_cast< QskGradient::Orientation >( type - 2 );
if ( inverted )
setGradient( orientation, dark, light );
else
setGradient( orientation, light, dark );
}
}
void Box::setBorder( BorderType type, const QRgb base )
{
setBorderWidth( 5 );
QColor dark = pal.color( QskRgbPalette::W30 );
QColor mid = pal.color( QskRgbPalette::W50 );
QColor light = pal.color( QskRgbPalette::W70 );
#if 0
dark.setAlpha( 100 );
mid.setAlpha( 100 );
light.setAlpha( 100 );
#endif
switch ( type )
switch ( static_cast< int >( type ) )
{
case NoBorder:
setBorderWidth( 0 );
break;
return;
case Flat:
setBorderGradient( mid );
break;
setBorderGradient( base );
return;
}
double hue, chroma;
QskHctColor::getHueAndChroma( base, hue, chroma );
const auto dark = QskHctColor::rgb( hue, chroma, 40 );
const auto mid = QskHctColor::rgb( hue, chroma, 65 );
const auto light = QskHctColor::rgb( hue, chroma, 90 );
switch ( static_cast< int >( type ) )
{
case Raised1:
setBorderGradients( light, light, dark, dark );
break;
@ -178,8 +204,19 @@ void Box::setGradient( const QskGradient& gradient )
}
void Box::setGradient(
const QskGradient::Orientation orientation, QskRgbPalette::Theme theme )
const QskGradient::Orientation orientation, const QRgb base )
{
const auto pal = QskRgbPalette::palette( theme );
setGradient( QskGradient( orientation, pal.colorStops( true ) ) );
double hue, chroma;
QskHctColor::getHueAndChroma( base, hue, chroma );
QVector< QRgb > rgb;
rgb.reserve( 10 );
for ( int i = 0; i < 10; i++ )
{
const auto tone = 90 - i * 7;
rgb += QskHctColor::rgb( hue, chroma, tone );
}
setGradient( QskGradient( orientation, QskGradient::colorStops( rgb, true ) ) );
}

View File

@ -5,7 +5,6 @@
#pragma once
#include <QskRgbPalette.h>
#include <QskBox.h>
class Box : public QskBox
@ -32,8 +31,10 @@ class Box : public QskBox
Box( QQuickItem* parentItem = nullptr );
void setBackground( FillType, QskRgbPalette::Theme, bool inverted = false );
void setBorder( BorderType type, QskRgbPalette::Theme );
void setBackground( FillType, QRgb, bool inverted = false );
void setBackground( FillType, QGradient::Preset, bool inverted = false );
void setBorder( BorderType type, QRgb );
void setShape( const QskBoxShapeMetrics& );
void setShape( qreal radius, Qt::SizeMode );
@ -55,6 +56,6 @@ class Box : public QskBox
void setGradient( QskGradient::Orientation,
const QColor&, const QColor&, const QColor& );
void setGradient( const QskGradient& gradient );
void setGradient( const QskGradient::Orientation, QskRgbPalette::Theme );
void setGradient( const QskGradient& );
void setGradient( const QskGradient::Orientation, QRgb );
};

View File

@ -21,6 +21,18 @@
#include <QGuiApplication>
namespace
{
// Some leftover definitions from M(aterial)2. TODO ...
constexpr const QRgb Grey400 = 0xffbdbdbd;
constexpr const QRgb Grey500 = 0xff9e9e9e;
constexpr const QRgb Lime200 = 0xffe6ee9c;
constexpr const QRgb Lime300 = 0xffdce775;
constexpr const QRgb Lime600 = 0xffc0ca33;
}
class MyRectangle : public Box
{
public:
@ -55,7 +67,7 @@ static void addTestRectangle( QskLinearBox* parent )
auto box = new Box( parent );
box->setMargins( 50 );
box->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialPrimary );
box->setBorder( Box::Flat, QskRgb::OrangeRed );
box->setBorderWidth( 10, 20, 40, 20 );
QskBoxShapeMetrics shape( 50, Qt::RelativeSize );
@ -63,7 +75,7 @@ static void addTestRectangle( QskLinearBox* parent )
shape.setRadius( Qt::TopRightCorner, 70 );
box->setShape( shape );
box->setGradient( QskGradient::Diagonal, QskRgbPalette::DefaultMaterialSecondary );
box->setGradient( QskGradient::Diagonal, QskRgb::DodgerBlue );
}
static void addRectangles1( QskLinearBox* parent )
@ -72,7 +84,7 @@ static void addRectangles1( QskLinearBox* parent )
Box::Horizontal, Box::Vertical, Box::Diagonal } )
{
auto* rectangle = new MyRectangle( parent );
rectangle->setBackground( type, QskRgbPalette::DefaultMaterialTertiary );
rectangle->setBackground( type, QskRgb::Teal );
}
}
@ -82,8 +94,8 @@ static void addRectangles2( QskLinearBox* parent )
Box::Horizontal, Box::Vertical, Box::Diagonal } )
{
auto* rectangle = new MyRectangle( parent );
rectangle->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialPrimary );
rectangle->setBackground( type, QskRgbPalette::DefaultMaterialSecondary );
rectangle->setBorder( Box::Flat, QskRgb::SaddleBrown );
rectangle->setBackground( type, QGradient::SunnyMorning );
}
}
@ -91,8 +103,7 @@ static void addRectangles3( QskLinearBox* parent )
{
using namespace QskRgb;
const auto borderTheme = QskRgbPalette::DefaultMaterialPrimary;
const auto fillTheme = QskRgbPalette::DefaultMaterialSecondary;
const auto borderTheme = QskRgb::LightGray;
Box* box;
@ -110,11 +121,11 @@ static void addRectangles3( QskLinearBox* parent )
box = new MyRectangle( parent );
box->setBorder( Box::Raised2, borderTheme );
box->setBackground( Box::Vertical, fillTheme, false );
box->setBackground( Box::Vertical, QGradient::RiverCity, true );
box = new MyRectangle( parent );
box->setBorder( Box::Sunken2, borderTheme );
box->setBackground( Box::Vertical, fillTheme, true );
box->setBackground( Box::Vertical, QGradient::RiverCity, false );
}
static void addRectangles4( QskLinearBox* parent )
@ -123,7 +134,7 @@ static void addRectangles4( QskLinearBox* parent )
Box::Horizontal, Box::Vertical, Box::Diagonal } )
{
auto* box = new MyRoundedRectangle( parent );
box->setBackground( type, QskRgbPalette::DefaultMaterialError );
box->setBackground( type, QskRgb::OrangeRed );
}
}
@ -133,8 +144,8 @@ static void addRectangles5( QskLinearBox* parent )
Box::Horizontal, Box::Vertical, Box::Diagonal } )
{
auto* box = new MyRoundedRectangle( parent );
box->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialPrimary );
box->setBackground( type, QskRgbPalette::DefaultMaterialSecondary );
box->setBorder( Box::Flat, QskRgb::RoyalBlue );
box->setBackground( type, QskRgb::DeepPink );
}
}
@ -142,8 +153,7 @@ static void addRectangles6( QskLinearBox* parent )
{
using namespace QskRgb;
const auto borderTheme = QskRgbPalette::DefaultMaterialPrimary;
const auto fillTheme = QskRgbPalette::DefaultMaterialSecondary;
const auto borderTheme = QskRgb::LightGrey;
Box* box;
@ -161,11 +171,11 @@ static void addRectangles6( QskLinearBox* parent )
box = new MyRoundedRectangle( parent );
box->setBorder( Box::Raised2, borderTheme );
box->setBackground( Box::Vertical, fillTheme, false );
box->setGradient( QskGradient::Vertical, Lime300, Lime600 );
box = new MyRoundedRectangle( parent );
box->setBorder( Box::Sunken2, borderTheme );
box->setBackground( Box::Vertical, fillTheme, true );
box->setGradient( QskGradient::Vertical, Lime600, Lime300 );
}
static void addRectangles7( QskLinearBox* parent )
@ -174,7 +184,7 @@ static void addRectangles7( QskLinearBox* parent )
Box::Horizontal, Box::Vertical, Box::Diagonal } )
{
auto* box = new MyEllipse( parent );
box->setBackground( type, QskRgbPalette::DefaultMaterialNeutralVariant );
box->setBackground( type, QskRgb::SlateGrey );
}
}
@ -184,8 +194,8 @@ static void addRectangles8( QskLinearBox* parent )
Box::Horizontal, Box::Vertical, Box::Diagonal } )
{
auto* box = new MyEllipse( parent );
box->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialPrimary );
box->setBackground( type, QskRgbPalette::DefaultMaterialError );
box->setBorder( Box::Flat, QskRgb::RoyalBlue );
box->setBackground( type, QskRgb::FireBrick );
}
}
@ -193,8 +203,7 @@ static void addRectangles9( QskLinearBox* parent )
{
using namespace QskRgb;
const auto borderTheme = QskRgbPalette::DefaultMaterialNeutral;
const auto fillTheme = QskRgbPalette::DefaultMaterialPrimary;
const auto borderTheme = QskRgb::LightGrey;
Box* box;
@ -212,11 +221,11 @@ static void addRectangles9( QskLinearBox* parent )
box = new MyEllipse( parent );
box->setBorder( Box::Raised2, borderTheme );
box->setBackground( Box::Vertical, fillTheme, false );
box->setGradient( QskGradient::Vertical, Lime200, Lime600 );
box = new MyEllipse( parent );
box->setBorder( Box::Sunken2, borderTheme );
box->setBackground( Box::Vertical, fillTheme, true );
box->setGradient( QskGradient::Vertical, Lime600, Lime200 );
}
static void addRectangles10( QskLinearBox* parent )
@ -263,14 +272,14 @@ static void addRectangles11( QskLinearBox* parent )
{
auto box = new MyRectangle( parent );
box->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialTertiary );
box->setBorder( Box::Flat, QskRgb::Teal );
qreal bw[ 4 ] = { border, border, border, border };
if ( i != 0 )
bw[ i - 1 ] = 0;
box->setBorderWidth( bw[ 0 ], bw[ 1 ], bw[ 2 ], bw[ 3 ] );
box->setBackground( fillType[ i ], QskRgbPalette::DefaultMaterialSecondary, i >= 3 );
box->setBackground( fillType[ i ], QskRgb::Sienna, i >= 3 );
}
}
@ -281,14 +290,14 @@ static void addRectangles12( QskLinearBox* parent )
{
auto* box = new Box( parent );
box->setBorderWidth( 0 );
box->setGradient( orientation, QskRgbPalette::DefaultMaterialSecondary );
box->setGradient( orientation, QskRgb::LightSlateGray );
}
for ( auto orientation : { QskGradient::Vertical, QskGradient::Diagonal } )
{
auto* box = new Box( parent );
box->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialPrimary );
box->setGradient( orientation, QskRgbPalette::DefaultMaterialTertiary );
box->setBorder( Box::Flat, QskRgb::OrangeRed );
box->setGradient( orientation, QskRgb::DodgerBlue );
}
for ( auto orientation : { QskGradient::Vertical,
@ -297,15 +306,15 @@ static void addRectangles12( QskLinearBox* parent )
auto* box = new Box( parent );
box->setBorderWidth( 0 );
box->setShape( 30, 40, Qt::RelativeSize );
box->setGradient( orientation, QskRgbPalette::DefaultMaterialTertiary );
box->setGradient( orientation, QskRgb::LightSlateGray );
}
for ( auto orientation : { QskGradient::Vertical, QskGradient::Diagonal } )
{
auto* box = new Box( parent );
box->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialPrimary );
box->setBorder( Box::Flat, QskRgb::OrangeRed );
box->setShape( 30, 40, Qt::RelativeSize );
box->setGradient( orientation, QskRgbPalette::DefaultMaterialSecondary );
box->setGradient( orientation, QskRgb::DodgerBlue );
}
for ( auto orientation : { QskGradient::Vertical,
@ -314,15 +323,15 @@ static void addRectangles12( QskLinearBox* parent )
auto* box = new Box( parent );
box->setBorderWidth( 0 );
box->setShape( 100, 100, Qt::RelativeSize );
box->setGradient( orientation, QskRgbPalette::DefaultMaterialTertiary );
box->setGradient( orientation, QskRgb::LightSlateGray );
}
for ( auto orientation : { QskGradient::Vertical, QskGradient::Diagonal } )
{
auto* box = new Box( parent );
box->setBorder( Box::Flat, QskRgbPalette::DefaultMaterialPrimary );
box->setBorder( Box::Flat, QskRgb::OrangeRed );
box->setShape( 100, 100, Qt::RelativeSize );
box->setGradient( orientation, QskRgbPalette::DefaultMaterialSecondary );
box->setGradient( orientation, QskRgb::DodgerBlue );
}
}
@ -374,7 +383,7 @@ static void addColoredBorderRectangles1( QskLinearBox* parent, bool rounded, Box
box->setBorderGradients( gradient1, gradient2, gradient3, gradient4 );
if( fillType != Box::Unfilled )
box->setBackground( fillType, QskRgbPalette::DefaultMaterialPrimary );
box->setBackground( fillType, QskRgb::CornflowerBlue );
if( rounded )
box->setShape( 30, Qt::AbsoluteSize );
@ -387,7 +396,7 @@ static void addColoredBorderRectangles2( QskLinearBox* parent, bool rounded, Box
box->setBorderGradients( Qt::red, Qt::green, Qt::blue, Qt::yellow );
if( fillType != Box::Unfilled )
box->setBackground( fillType, QskRgbPalette::DefaultMaterialPrimary );
box->setBackground( fillType, QskRgb::CornflowerBlue );
if( rounded )
box->setShape( 30, Qt::AbsoluteSize );
@ -416,7 +425,7 @@ static void addColoredBorderRectangles3( QskLinearBox* parent, bool rounded, Box
box->setBorderGradients( gradient3, gradient3, gradient3, gradient3 );
if( fillType != Box::Unfilled )
box->setBackground( fillType, QskRgbPalette::DefaultMaterialPrimary );
box->setBackground( fillType, QskRgb::CornflowerBlue );
if( rounded )
box->setShape( 30, Qt::AbsoluteSize );
@ -430,7 +439,7 @@ static void addColoredBorderRectangles4( QskLinearBox* parent, bool rounded, Box
box->setBorderGradients( gradient, gradient, gradient, gradient );
if( fillType != Box::Unfilled )
box->setBackground( fillType, QskRgbPalette::DefaultMaterialPrimary );
box->setBackground( fillType, QskRgb::CornflowerBlue );
if( rounded )
box->setShape( 30, Qt::AbsoluteSize );
@ -447,7 +456,7 @@ static void addColoredBorderRectangles5( QskLinearBox* parent, bool rounded, Box
box->setBorderGradients( gradient, gradient, gradient, gradient );
if( fillType != Box::Unfilled )
box->setBackground( fillType, QskRgbPalette::DefaultMaterialPrimary );
box->setBackground( fillType, QskRgb::CornflowerBlue );
if( rounded )
box->setShape( { 10, 20, 20, 40 } );

View File

@ -5,15 +5,15 @@ Qsk.PushButton
{
sizePolicy
{
// long texts, should not have an effect
// avoid the effect of long texts
horizontalPolicy: Qsk.SizePolicy.Ignored
verticalPolicy: Qsk.SizePolicy.Ignored
}
minimumSize
{
minimumSize
{
width: 80
height: 60
height: 60
}
shape

View File

@ -11,14 +11,14 @@ Qsk.Window
height: 600
color: "Beige"
Component.onCompleted:
{
// very much standard: we should find a better way
Component.onCompleted:
{
// very much standard: we should find a better way
var hint = sizeConstraint();
setMinimumWidth( hint.width )
setMinimumHeight( hint.height )
}
var hint = sizeConstraint();
setMinimumWidth( hint.width )
setMinimumHeight( hint.height )
}
Qsk.Shortcut
{

View File

@ -8,7 +8,7 @@
#include <QskGraphicProvider.h>
#include <QskGraphic.h>
#include <QskGradient.h>
#include <QskRgbPalette.h>
#include <QskHctColor.h>
#include <QskRgbValue.h>
namespace
@ -25,17 +25,18 @@ namespace
setBoundaries( 0, 100 );
}
void setTheme( QskRgbPalette::Theme theme )
void setTheme( const QRgb base )
{
const auto pal = QskRgbPalette::palette( theme );
double hue, chroma;
QskHctColor::getHueAndChroma( base, hue, chroma );
QVector< QRgb > rgb;
rgb += pal.rgb( QskRgbPalette::W90 );
rgb += pal.rgb( QskRgbPalette::W60 );
rgb += pal.rgb( QskRgbPalette::W40 );
rgb += pal.rgb( QskRgbPalette::W20 );
rgb += QskHctColor::rgb( hue, chroma, 75 );
rgb += QskHctColor::rgb( hue, chroma, 60 );
rgb += QskHctColor::rgb( hue, chroma, 45 );
rgb += QskHctColor::rgb( hue, chroma, 30 );
const auto stops = QskRgbPalette::colorStops( rgb, true );
const auto stops = QskGradient::colorStops( rgb, true );
setBarGradient( QskGradient( orientation(), stops ) );
}
@ -62,19 +63,19 @@ void ProgressBarPage::populate()
{
auto bar = new ProgressBar( hBox );
bar->setTheme( QskRgbPalette::DefaultMaterialPrimary );
bar->setTheme( QskRgb::LightSteelBlue );
bar->setValue( 100 );
}
{
auto bar = new ProgressBar( hBox );
bar->setTheme( QskRgbPalette::DefaultMaterialSecondary );
bar->setTheme( QskRgb::DodgerBlue );
bar->setValue( 75 );
}
{
auto bar = new ProgressBar( hBox );
bar->setTheme( QskRgbPalette::DefaultMaterialSecondary );
bar->setTheme( QskRgb::DodgerBlue );
bar->setOrigin( 60 );
bar->setValue( 25 );
}
@ -90,20 +91,20 @@ void ProgressBarPage::populate()
{
auto bar = new ProgressBar( vBox );
bar->setTheme( QskRgbPalette::DefaultMaterialPrimary );
bar->setTheme( QskRgb::OrangeRed );
bar->setValue( 100 );
}
{
auto bar = new ProgressBar( vBox );
bar->setTheme( QskRgbPalette::DefaultMaterialSecondary );
bar->setTheme( QskRgb::DeepPink );
bar->setMaximum( 40 );
bar->setValue( 25 );
}
{
auto bar = new ProgressBar( vBox );
bar->setTheme( QskRgbPalette::DefaultMaterialSecondary );
bar->setTheme( QskRgb::DeepPink );
bar->setOrigin( 40 );
bar->setValue( 10 );
}

View File

@ -26,17 +26,17 @@ CustomSlider::CustomSlider( QQuickItem* parentItem )
QskSkinHintTableEditor ed( &hintTable() );
ed.setBoxShape( Fill, 0 );
ed.setGradient( Fill, DefaultMaterialPrimary40 );
ed.setGradient( Fill, QskRgb::DimGray );
ed.setColor( Scale, qRgb( 178, 178, 178 ) ); // for the ticks
ed.setStrutSize( Handle, 80, 80 );
ed.setColor( Handle, DefaultMaterialNeutral30 );
ed.setColor( Handle, QskRgb::DimGray );
ed.setColor( Handle | Pressed, DefaultMaterialPrimary30 );
ed.setColor( Handle | Pressed, QskRgb::Orange );
const auto combinationMask = Focused | Hovered;
ed.setColor( Handle, 0xfffb8c00, combinationMask );
ed.setColor( Handle, QskRgb::Orange, combinationMask );
ed.setAnimation( Handle | QskAspect::Color, 300, combinationMask );
ed.setAnimation( Handle | QskAspect::Color, 1000 );

View File

@ -307,7 +307,7 @@ QSGNode* CustomSliderSkinlet::updateDecorationNode(
labelNode = QskSkinlet::updateTextNode( slider, labelNode,
QRectF( x - 0.5 * w, y, w, h ), Qt::AlignHCenter, text, qskLabelFont,
QskTextOptions(), QskTextColors( QskRgb::DefaultMaterialNeutral30 ), Qsk::Normal );
QskTextOptions(), QskTextColors( QskRgb::DimGray ), Qsk::Normal );
if ( labelNode )
{

View File

@ -37,8 +37,8 @@ OtherSlider::OtherSlider( QQuickItem* parentItem )
ed.setMetric( aspect | A::Size, h );
ed.setBoxShape( aspect, 4 );
ed.setBoxBorderMetrics( aspect, 1 );
ed.setBoxBorderColors( aspect, DefaultMaterialNeutral10 );
ed.setGradient( aspect, DefaultMaterialNeutral60 );
ed.setBoxBorderColors( aspect, DimGray );
ed.setGradient( aspect, Silver );
if ( placement == A::Horizontal )
ed.setPadding( aspect, QskMargins( paddingW, 0 ) );
@ -84,8 +84,8 @@ OtherSlider::OtherSlider( QQuickItem* parentItem )
for ( auto state : { A::NoState, Pressed } )
{
ed.setBoxBorderColors( aspect | state, DefaultMaterialNeutral40 );
ed.setGradient( aspect | state, DefaultMaterialPrimary60 );
ed.setBoxBorderColors( aspect | state, SlateGrey );
ed.setGradient( aspect | state, DodgerBlue );
}
}
}

View File

@ -7,7 +7,6 @@
#include "QskLayoutQml.h"
#include "QskShortcutQml.h"
#include "QskMainQml.h"
#include "QskRgbValueQml.h"
#include <QskBoxBorderMetrics.h>
#include <QskBoxShapeMetrics.h>
@ -192,7 +191,6 @@ void QskQml::registerTypes()
WarningBlocker warningBlocker;
#endif
QSK_REGISTER_GADGET( QskRgbValueQml, "RgbValue" );
QSK_REGISTER_GADGET( QskBoxBorderMetrics, "BorderMetrics" );
QSK_REGISTER_GADGET( QskBoxShapeMetrics, "Shape" );
QSK_REGISTER_GADGET( QskShadowMetrics, "ShadowMetrics" );

View File

@ -1,28 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_RGBVALUE_QML_H
#define QSK_RGBVALUE_QML_H
#include "QskQmlGlobal.h"
#include <QskRgbValue.h>
#include <qmetatype.h>
class QskRgbValueQml
{
Q_GADGET
public:
enum Enum
{
#define RGBVALUE( name, value ) name = value,
QSK_RGB_VALUES
#undef RGBVALUE
};
Q_ENUM( Enum )
};
#endif

View File

@ -10,7 +10,6 @@ HEADERS += \
QskQmlGlobal.h \
QskShortcutQml.h \
QskLayoutQml.h \
QskRgbValueQml.h \
QskMainQml.h \
QskQml.h

View File

@ -47,6 +47,16 @@ static const int qskDuration = 150;
namespace
{
#if 1
// temporary definitions, will be removed when moving to M(aterial)3
constexpr const QRgb Grey100 = 0xfff5f5f5;
constexpr const QRgb Grey300 = 0xffe0e0e0;
constexpr const QRgb Grey400 = 0xffbdbdbd;
constexpr const QRgb Grey500 = 0xff9e9e9e;
constexpr const QRgb Grey600 = 0xff757575;
constexpr const QRgb Blue500 = 0xff2196f3;
#endif
class Editor : private QskSkinHintTableEditor
{
public:

View File

@ -89,7 +89,7 @@ namespace
contrasted = DarkGrey;
contrastedText = White;
highlighted = 0xff607d8b;
highlighted = SlateGrey;
highlightedText = White;
base = Black;

View File

@ -194,6 +194,42 @@ static inline QskGradientStops qskGradientStops( const QGradientStops& qtStops )
return stops;
}
static inline QskGradientStops qskColorStops(
const QRgb* rgb, int count, bool discrete )
{
QskGradientStops stops;
if ( discrete )
stops.reserve( 2 * count - 2 );
else
stops.reserve( count );
stops += QskGradientStop( 0.0, rgb[0] );
if ( discrete )
{
const auto step = 1.0 / count;
for ( int i = 1; i < count; i++ )
{
const qreal pos = i * step;
stops += QskGradientStop( pos, rgb[i - 1] );
stops += QskGradientStop( pos, rgb[i] );
}
}
else
{
const auto step = 1.0 / ( count - 1 );
for ( int i = 1; i < count - 1; i++ )
stops += QskGradientStop( i * step, rgb[i] );
}
stops += QskGradientStop( 1.0, rgb[count - 1] );
return stops;
}
QskGradient::QskGradient( Orientation orientation )
: m_orientation( orientation )
, m_isDirty( false )
@ -635,6 +671,28 @@ void QskGradient::updateStatusBits() const
m_isDirty = false;
}
QskGradientStops QskGradient::colorStops(
const QVector< QRgb >& rgb, bool discrete )
{
const int count = rgb.count();
if ( count == 0 )
return QskGradientStops();
if ( count == 0 )
{
QskGradientStops stops;
stops.reserve( 2 );
stops += QskGradientStop( 0.0, rgb[0] );
stops += QskGradientStop( 1.0, rgb[0] );
return stops;
}
return qskColorStops( rgb.constData(), count, discrete );
}
#ifndef QT_NO_DEBUG_STREAM
#include <qdebug.h>

View File

@ -103,6 +103,9 @@ class QSK_EXPORT QskGradient
Q_INVOKABLE QColor colorAt( int index ) const;
Q_INVOKABLE int stopCount() const;
static QskGradientStops colorStops(
const QVector< QRgb >&, bool discrete = false );
private:
void setStopAt( int index, qreal stop );
void setColorAt( int index, const QColor& color );

835
src/common/QskHctColor.cpp Normal file
View File

@ -0,0 +1,835 @@
#include "QskHctColor.h"
#include <qmath.h>
#include <cmath>
/*
Code has been copied, rearranged and translated to C++ without trying
to understand the implemented algorithms. All credits go to the authors of
https://github.com/material-foundation/material-color-utilities.
*/
/*
Copyright 2021 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
namespace
{
class XYZ
{
public:
constexpr XYZ() noexcept = default;
constexpr XYZ( double x, double y, double z ) noexcept
: x( x )
, y( y )
, z( z )
{
}
double value( int axis ) const
{
switch( axis )
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
}
return 0.0;
}
double x = 0.0;
double y = 0.0;
double z = 0.0;
};
class ViewingConditions
{
public:
const double backgroundYTowhitePointY = 0.18418651851244416;
const double aw = 29.980997194447337;
const double nbb = 1.0169191804458755;
const double z = 1.909169568483652;
const double fl = 0.38848145378003529;
const XYZ rgbD = { 1.02117770275752, 0.98630772942801237, 0.93396050828022992 };
};
}
static const XYZ Y_FROM_LINRGB = { 0.2126, 0.7152, 0.0722 };
static double planes[] =
{
0.015176349177441876,
0.045529047532325624,
0.07588174588720938,
0.10623444424209313,
0.13658714259697685,
0.16693984095186062,
0.19729253930674434,
0.2276452376616281,
0.2579979360165119,
0.28835063437139563,
0.3188300904430532,
0.350925934958123,
0.3848314933096426,
0.42057480301049466,
0.458183274052838,
0.4976837250274023,
0.5391024159806381,
0.5824650784040898,
0.6277969426914107,
0.6751227633498623,
0.7244668422128921,
0.775853049866786,
0.829304845476233,
0.8848452951698498,
0.942497089126609,
1.0022825574869039,
1.0642236851973577,
1.1283421258858297,
1.1946592148522128,
1.2631959812511864,
1.3339731595349034,
1.407011200216447,
1.4823302800086415,
1.5599503113873272,
1.6398909516233677,
1.7221716113234105,
1.8068114625156377,
1.8938294463134073,
1.9832442801866852,
2.075074464868551,
2.1693382909216234,
2.2660538449872063,
2.36523901573795,
2.4669114995532007,
2.5710888059345764,
2.6777882626779785,
2.7870270208169257,
2.898822059350997,
3.0131901897720907,
3.1301480604002863,
3.2497121605402226,
3.3718988244681087,
3.4967242352587946,
3.624204428461639,
3.754355295633311,
3.887192587735158,
4.022731918402185,
4.160988767090289,
4.301978482107941,
4.445716283538092,
4.592217266055746,
4.741496401646282,
4.893568542229298,
5.048448422192488,
5.20615066083972,
5.3666897647573375,
5.5300801301023865,
5.696336044816294,
5.865471690767354,
6.037501145825082,
6.212438385869475,
6.390297286737924,
6.571091626112461,
6.7548350853498045,
6.941541251256611,
7.131223617812143,
7.323895587840543,
7.5195704746346665,
7.7182615035334345,
7.919981813454504,
8.124744458384042,
8.332562408825165,
8.543448553206703,
8.757415699253682,
8.974476575321063,
9.194643831691977,
9.417930041841839,
9.644347703669503,
9.873909240696694,
10.106627003236781,
10.342513269534024,
10.58158024687427,
10.8238400726681,
11.069304815507364,
11.317986476196008,
11.569896988756009,
11.825048221409341,
12.083451977536606,
12.345119996613247,
12.610063955123938,
12.878295467455942,
13.149826086772048,
13.42466730586372,
13.702830557985108,
13.984327217668513,
14.269168601521828,
14.55736596900856,
14.848930523210871,
15.143873411576273,
15.44220572664832,
15.743938506781891,
16.04908273684337,
16.35764934889634,
16.66964922287304,
16.985093187232053,
17.30399201960269,
17.62635644741625,
17.95219714852476,
18.281524751807332,
18.614349837764564,
18.95068293910138,
19.290534541298456,
19.633915083172692,
19.98083495742689,
20.331304511189067,
20.685334046541502,
21.042933821039977,
21.404114048223256,
21.76888489811322,
22.137256497705877,
22.50923893145328,
22.884842241736916,
23.264076429332462,
23.6469514538663,
24.033477234264016,
24.42366364919083,
24.817520537484558,
25.21505769858089,
25.61628489293138,
26.021211842414342,
26.429848230738664,
26.842203703840827,
27.258287870275353,
27.678110301598522,
28.10168053274597,
28.529008062403893,
28.96010235337422,
29.39497283293396,
29.83362889318845,
30.276079891419332,
30.722335150426627,
31.172403958865512,
31.62629557157785,
32.08401920991837,
32.54558406207592,
33.010999283389665,
33.4802739966603,
33.953417292456834,
34.430438229418264,
34.911345834551085,
35.39614910352207,
35.88485700094671,
36.37747846067349,
36.87402238606382,
37.37449765026789,
37.87891309649659,
38.38727753828926,
38.89959975977785,
39.41588851594697,
39.93615253289054,
40.460400508064545,
40.98864111053629,
41.520882981230194,
42.05713473317016,
42.597404951718396,
43.141702194811224,
43.6900349931913,
44.24241185063697,
44.798841244188324,
45.35933162437017,
45.92389141541209,
46.49252901546552,
47.065252796817916,
47.64207110610409,
48.22299226451468,
48.808024568002054,
49.3971762874833,
49.9904556690408,
50.587870934119984,
51.189430279724725,
51.79514187861014,
52.40501387947288,
53.0190544071392,
53.637271562750364,
54.259673423945976,
54.88626804504493,
55.517063457223934,
56.15206766869424,
56.79128866487574,
57.43473440856916,
58.08241284012621,
58.734331877617365,
59.39049941699807,
60.05092333227251,
60.715611475655585,
61.38457167773311,
62.057811747619894,
62.7353394731159,
63.417162620860914,
64.10328893648692,
64.79372614476921,
65.48848194977529,
66.18756403501224,
66.89098006357258,
67.59873767827808,
68.31084450182222,
69.02730813691093,
69.74813616640164,
70.47333615344107,
71.20291564160104,
71.93688215501312,
72.67524319850172,
73.41800625771542,
74.16517879925733,
74.9167682708136,
75.67278210128072,
76.43322770089146,
77.1981124613393,
77.96744375590167,
78.74122893956174,
79.51947534912904,
80.30219030335869,
81.08938110306934,
81.88105503125999,
82.67721935322541,
83.4778813166706,
84.28304815182372,
85.09272707154808,
85.90692527145302,
86.72564993000343,
87.54890820862819,
88.3767072518277,
89.2090541872801,
90.04595612594655,
90.88742016217518,
91.73345337380438,
92.58406282226491,
93.43925555268066,
94.29903859396902,
95.16341895893969,
96.03240364439274,
96.9059996312159,
97.78421388448044,
98.6670533535366,
99.55452497210776,
};
static inline int delinearized( double rgbComponent )
{
const double normalized = rgbComponent / 100.0;
double v = 0.0;
if ( normalized <= 0.0031308 )
v = normalized * 12.92;
else
v = 1.055 * pow( normalized, 1.0 / 2.4 ) - 0.055;
return qBound( 0, qRound( v * 255 ), 255 );
}
static inline double labInvf( double ft )
{
const double e = 216.0 / 24389.0;
const double kappa = 24389.0 / 27.0;
const double ft3 = ft * ft * ft;
if ( ft3 > e )
return ft3;
return ( 116 * ft - 16 ) / kappa;
}
static inline double sanitizeDegreesDouble( double degrees )
{
degrees = fmod( degrees, 360.0 );
if (degrees < 0)
degrees = degrees + 360.0;
return degrees;
}
static inline double yFromLstar( double lstar )
{
return 100.0 * labInvf( ( lstar + 16.0 ) / 116.0 );
}
static inline QRgb argbFromLstar( double lstar )
{
const double y = yFromLstar(lstar);
const int component = delinearized(y);
return qRgb( component, component, component );
}
static inline QRgb argbFromLinrgb( const XYZ& linrgb )
{
const int r = delinearized( linrgb.x );
const int g = delinearized( linrgb.y );
const int b = delinearized( linrgb.z );
return qRgb( r, g, b );
}
static inline double sanitizeRadians( double angle )
{
return fmod( angle + M_PI * 8, M_PI * 2 );
}
static inline double trueDelinearized( double rgbComponent )
{
const double normalized = rgbComponent / 100.0;
double v = 0.0;
if ( normalized <= 0.0031308 )
v = normalized * 12.92;
else
v = 1.055 * pow( normalized, 1.0 / 2.4 ) - 0.055;
return v * 255.0;
}
static inline int signum( double num )
{
if (num == 0)
return 0;
return ( num < 0 ) ? -1 : 1;
}
static inline XYZ matrixMultiply( const XYZ& row, const XYZ matrix[3] )
{
XYZ r;
r.x = row.x * matrix[0].x + row.y * matrix[0].y + row.z * matrix[0].z;
r.y = row.x * matrix[1].x + row.y * matrix[1].y + row.z * matrix[1].z;
r.z = row.x * matrix[2].x + row.y * matrix[2].y + row.z * matrix[2].z;
return r;
}
static inline double chromaticAdaptation( double component )
{
const double af = pow( abs( component ), 0.42);
return signum(component) * 400.0 * af / ( af + 27.13 );
}
static inline double hueOf( const XYZ& linrgb )
{
constexpr XYZ matrix[3] =
{
{ 0.001200833568784504, 0.002389694492170889, 0.0002795742885861124 },
{ 0.0005891086651375999, 0.0029785502573438758, 0.0003270666104008398 },
{ 0.00010146692491640572, 0.0005364214359186694, 0.0032979401770712076 }
};
const XYZ scaledDiscount = matrixMultiply( linrgb, matrix );
const double rA = chromaticAdaptation( scaledDiscount.x );
const double gA = chromaticAdaptation( scaledDiscount.y );
const double bA = chromaticAdaptation( scaledDiscount.z );
const double a = ( 11.0 * rA + -12.0 * gA + bA ) / 11.0;
const double b = ( rA + gA - 2.0 * bA ) / 9.0;
return atan2( b, a );
}
static bool areInCyclicOrder( double a, double b, double c )
{
const double deltaAB = sanitizeRadians( b - a );
const double deltaAC = sanitizeRadians( c - a );
return deltaAB < deltaAC;
}
static inline double intercept( double source, double mid, double target )
{
return ( mid - source ) / ( target - source );
}
static inline XYZ setCoordinate( const XYZ& source,
double coordinate, const XYZ& target, int axis )
{
const double t = intercept( source.value(axis), coordinate, target.value(axis) );
XYZ r;
r.x = source.x + ( target.x - source.x ) * t;
r.y = source.y + ( target.y - source.y ) * t;
r.z = source.z + ( target.z - source.z ) * t;
return r;
}
static bool isBounded( double x )
{
return 0.0 <= x && x <= 100.0;
}
static XYZ nthVertex( double y, int n )
{
const double kR = Y_FROM_LINRGB.x;
const double kG = Y_FROM_LINRGB.y;
const double kB = Y_FROM_LINRGB.z;
const double coordA = ( n % 4 <= 1 ) ? 0.0 : 100.0;
const double coordB = ( n % 2 == 0 ) ? 0.0 : 100.0;
if ( n < 4 )
{
const double g = coordA;
const double b = coordB;
const double r = ( y - g * kG - b * kB ) / kR;
if ( isBounded(r) )
return XYZ( r, g, b );
}
else if ( n < 8 )
{
const double b = coordA;
const double r = coordB;
const double g = ( y - r * kR - b * kB ) / kG;
if ( isBounded(g) )
return XYZ( r, g, b );
}
else
{
const double r = coordA;
const double g = coordB;
const double b = ( y - r * kR - g * kG ) / kB;
if ( isBounded(b) )
return XYZ( r, g, b );
}
return { -1.0, -1.0, -1.0 };
}
void bisectToSegment( double y, double targetHue, XYZ& left, XYZ& right )
{
left = { -1.0, -1.0, -1.0 };
right = left;
double leftHue = 0.0;
double rightHue = 0.0;
bool initialized = false;
bool uncut = true;
for ( int n = 0; n < 12; n++ )
{
XYZ mid = nthVertex(y, n);
if ( mid.x < 0 )
continue;
const double midHue = hueOf( mid );
if ( !initialized )
{
left = mid;
right = mid;
leftHue = midHue;
rightHue = midHue;
initialized = true;
continue;
}
if ( uncut || areInCyclicOrder( leftHue, midHue, rightHue ) )
{
uncut = false;
if ( areInCyclicOrder( leftHue, targetHue, midHue ) )
{
right = mid;
rightHue = midHue;
}
else
{
left = mid;
leftHue = midHue;
}
}
}
}
static XYZ midpoint( const XYZ& a, const XYZ& b )
{
XYZ r;
r.x = ( a.x + b.x ) / 2;
r.y = ( a.y + b.y ) / 2;
r.z = ( a.z + b.z ) / 2;
return r;
}
static int planeBelow( double x )
{
return qFloor( x - 0.5 );
}
static int planeAbove( double x )
{
return qCeil( x - 0.5 );
}
static XYZ bisectToLimit( double y, double targetHue )
{
XYZ left, right;
bisectToSegment( y, targetHue, left, right );
double leftHue = hueOf(left);
for ( int axis = 0; axis < 3; axis++ )
{
const double l = left.value(axis);
const double r = right.value(axis);
if ( l != r )
{
int lPlane = -1;
int rPlane = 255;
if ( l < r )
{
lPlane = planeBelow( trueDelinearized( l ) );
rPlane = planeAbove( trueDelinearized( r ) );
}
else
{
lPlane = planeAbove( trueDelinearized( l ) );
rPlane = planeBelow( trueDelinearized( r ) );
}
for ( int i = 0; i < 8; i++ )
{
if ( abs( rPlane - lPlane ) <= 1 )
break;
const int mPlane = qFloor( ( lPlane + rPlane ) / 2.0 );
const double midPlaneCoordinate = planes[mPlane];
const XYZ mid = setCoordinate(left, midPlaneCoordinate, right, axis);
const double midHue = hueOf( mid );
if ( areInCyclicOrder( leftHue, targetHue, midHue ) )
{
right = mid;
rPlane = mPlane;
}
else
{
left = mid;
leftHue = midHue;
lPlane = mPlane;
}
}
}
}
return midpoint( left, right );
}
static double inverseChromaticAdaptation( double adapted )
{
const double adaptedAbs = abs( adapted );
double base = 27.13 * adaptedAbs / ( 400.0 - adaptedAbs );
if ( base < 0.0 )
base = 0.0;
return signum(adapted) * pow( base, 1.0 / 0.42 );
}
static QRgb findResultByJ( double hueRadians, double chroma, double y )
{
double j = sqrt(y) * 11.0;
constexpr ViewingConditions vc;
const double tInnerCoeff = 1.0 / pow( 1.64 - pow( 0.29, vc.backgroundYTowhitePointY ), 0.73 );
const double eHue = 0.25 * ( cos( hueRadians + 2.0 ) + 3.8 );
const double p1 = eHue * ( 50000.0 / 13.0 ) * vc.nbb;
const double hSin = sin(hueRadians);
const double hCos = cos(hueRadians);
for ( int i = 0; i < 5; i++ )
{
const double jNormalized = j / 100.0;
const double alpha = ( chroma == 0.0 || j == 0.0 ) ? 0.0 : chroma / sqrt(jNormalized);
const double t = pow( alpha * tInnerCoeff, 1.0 / 0.9 );
const double ac = vc.aw * pow( jNormalized, 1.0 / 0.69 / vc.z );
const double p2 = ac / vc.nbb;
const double gamma = 23.0 * ( p2 + 0.305 ) * t /
( 23.0 * p1 + 11 * t * hCos + 108.0 * t * hSin );
const double a = gamma * hCos;
const double b = gamma * hSin;
const double rA = ( 460.0 * p2 + 451.0 * a + 288.0 * b ) / 1403.0;
const double gA = ( 460.0 * p2 - 891.0 * a - 261.0 * b ) / 1403.0;
const double bA = ( 460.0 * p2 - 220.0 * a - 6300.0 * b ) / 1403.0;
XYZ rgbScaled;
rgbScaled.x = inverseChromaticAdaptation( rA );
rgbScaled.y = inverseChromaticAdaptation( gA );
rgbScaled.z = inverseChromaticAdaptation( bA );
constexpr XYZ matrix[3] =
{
{ 1373.2198709594231, -1100.4251190754821, -7.278681089101213, },
{ -271.815969077903, 559.6580465940733, -32.46047482791194 },
{ 1.9622899599665666, -57.173814538844006, 308.7233197812385 }
};
const XYZ linrgb = matrixMultiply( rgbScaled, matrix );
if ( linrgb.x < 0 || linrgb.y < 0 || linrgb.z < 0 )
return 0;
const double kR = Y_FROM_LINRGB.x;
const double kG = Y_FROM_LINRGB.y;
const double kB = Y_FROM_LINRGB.z;
const double fnj = kR * linrgb.x + kG * linrgb.y + kB * linrgb.z;
if ( fnj <= 0 )
return 0;
if ( i == 4 || abs(fnj - y) < 0.002 )
{
if ( linrgb.x > 100.01 || linrgb.y > 100.01 || linrgb.z > 100.01 )
return 0;
return argbFromLinrgb( linrgb );
}
j = j - ( fnj - y ) * j / ( 2 * fnj );
}
return 0;
}
QRgb QskHctColor::rgb( double hue, double chroma, double tone )
{
if ( chroma < 0.0001 || tone < 0.0001 || tone > 99.9999 )
return argbFromLstar( tone );
hue = sanitizeDegreesDouble( hue );
const double hueRadians = hue / 180.0 * M_PI;
const double y = yFromLstar( tone );
const QRgb rgb = findResultByJ( hueRadians, chroma, y );
if ( rgb != 0 )
return rgb;
const XYZ linrgb = bisectToLimit( y, hueRadians );
return argbFromLinrgb( linrgb );
}
static const XYZ SRGB_TO_XYZ[3] =
{
{ 0.41233895, 0.35762064, 0.18051042 },
{ 0.2126, 0.7152, 0.0722 },
{ 0.01932141, 0.11916382, 0.95034478 }
};
static double linearized( int rgbComponent )
{
const double normalized = rgbComponent / 255.0;
if ( normalized <= 0.040449936 )
return normalized / 12.92 * 100.0;
else
return pow( ( normalized + 0.055 ) / 1.055, 2.4) * 100.0;
}
static XYZ xyzFromArgb( QRgb rgb)
{
XYZ xyz;
xyz.x = linearized( qRed(rgb) );
xyz.y = linearized( qGreen(rgb) );
xyz.z = linearized( qBlue(rgb) );
return matrixMultiply( xyz, SRGB_TO_XYZ );
}
void QskHctColor::getHueAndChroma( QRgb rgb, double& hue, double& chroma )
{
ViewingConditions vc;
const XYZ xyz = xyzFromArgb( rgb );
const double x = xyz.x;
const double y = xyz.y;
const double z = xyz.z;
const double rC = 0.401288 * x + 0.650173 * y - 0.051461 * z;
const double gC = -0.250268 * x + 1.204414 * y + 0.045854 * z;
const double bC = -0.002079 * x + 0.048952 * y + 0.953127 * z;
const double rD = vc.rgbD.x * rC;
const double gD = vc.rgbD.y * gC;
const double bD = vc.rgbD.z * bC;
const double rAF = pow( vc.fl * fabs( rD ) / 100.0, 0.42 );
const double gAF = pow( vc.fl * fabs( gD ) / 100.0, 0.42 );
const double bAF = pow( vc.fl * fabs( bD ) / 100.0, 0.42);
const double rA = signum(rD) * 400.0 * rAF / ( rAF + 27.13 );
const double gA = signum(gD) * 400.0 * gAF / ( gAF + 27.13 );
const double bA = signum(bD) * 400.0 * bAF / ( bAF + 27.13 );
const double a = ( 11.0 * rA + -12.0 * gA + bA ) / 11.0;
const double b = ( rA + gA - 2.0 * bA ) / 9.0;
const double u = ( 20.0 * rA + 20.0 * gA + 21.0 * bA ) / 20.0;
const double p2 = ( 40.0 * rA + 20.0 * gA + bA ) / 20.0;
// hue
const double atanDegrees = atan2(b, a) * 180.0 / M_PI;
// fmod ???
hue = ( atanDegrees < 0 ) ? atanDegrees + 360.0 : atanDegrees >=
360 ? atanDegrees - 360 : atanDegrees;
{
const double ac = p2 * vc.nbb;
const double J = 100.0 * pow( ac / vc.aw, 0.69 * vc.z );
const double huePrime = ( hue < 20.14 ) ? hue + 360 : hue;
const double eHue = ( 1.0 / 4.0 ) * ( cos( huePrime * M_PI / 180.0 + 2.0 ) + 3.8 );
const double p1 = 50000.0 / 13.0 * eHue * vc.nbb;
const double t = p1 * sqrt(a * a + b * b) / ( u + 0.305 );
const double alpha =
pow(t, 0.9) * pow( 1.64 - pow(0.29, vc.backgroundYTowhitePointY), 0.73);
chroma = alpha * sqrt(J / 100.0);
}
}

45
src/common/QskHctColor.h Normal file
View File

@ -0,0 +1,45 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_HCT_COLOR_H
#define QSK_HCT_COLOR_H
#include "QskGlobal.h"
#include <qcolor.h>
/*
For M(aterial)3 the new HTC color system has been created, that
is based on H(ue), (C)hroma, (T)one:
https://material.io/blog/science-of-color-design
This system allows to create color palettes by varying the tone
for given hue/chroma values.
https://material-foundation.github.io/material-theme-builder/#/custom
shows how to create a tonal palette from a given RGB color.
The methods in QskHctColor allow to do the same:
QVector palette( const QRgb rgb )
{
double hue, chroma;
QskHctColor::getHueAndChroma( rgb, hue, chroma );
QVector< QRgb > pal;
for ( int tone = 0; tone <= 100; tone += 10 )
pal += QskHctColor::rgb( hue, chroma, tone );
return pal;
}
*/
namespace QskHctColor
{
QSK_EXPORT QRgb rgb( double hue, double chroma, double tone );
QSK_EXPORT void getHueAndChroma( QRgb rgb, double& hue, double& chroma );
}
#endif

View File

@ -1,118 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskRgbPalette.h"
#include "QskRgbValue.h"
#include "QskGradient.h"
#define RGB( color, weight ) color ## weight
#define RGBTABLE( c ) \
{ \
RGB( c, 0 ), RGB( c, 10 ), RGB( c, 20 ), RGB( c, 30 ), RGB( c, 40 ), \
RGB( c, 50 ), RGB( c, 60 ), RGB( c, 70 ), RGB( c, 80 ), RGB( c, 90 ), \
RGB( c, 95 ), RGB( c, 99 ), RGB( c, 100 ) \
}
namespace
{
class Palette : public QskRgbPalette
{
public:
Palette( int index )
{
using namespace QskRgb;
static constexpr QRgb table[][ Palette::NumWeights ] =
{
RGBTABLE( DefaultMaterialPrimary ),
RGBTABLE( DefaultMaterialSecondary ),
RGBTABLE( DefaultMaterialTertiary ),
RGBTABLE( DefaultMaterialError ),
RGBTABLE( DefaultMaterialNeutral ),
RGBTABLE( DefaultMaterialNeutralVariant ),
};
const int count = sizeof( table ) / sizeof( table[ 0 ] );
m_rgb = table[ qBound( 0, index, count ) ];
}
};
}
QskRgbPalette QskRgbPalette::palette( Theme theme )
{
return Palette( static_cast< int >( theme ) );
}
static QskGradientStops qskColorStops(
const QRgb* rgb, int count, bool discrete )
{
QskGradientStops stops;
if ( discrete )
stops.reserve( 2 * count - 2 );
else
stops.reserve( count );
stops += QskGradientStop( 0.0, rgb[0] );
if ( discrete )
{
const auto step = 1.0 / count;
for ( int i = 1; i < count; i++ )
{
const qreal pos = i * step;
stops += QskGradientStop( pos, rgb[i - 1] );
stops += QskGradientStop( pos, rgb[i] );
}
}
else
{
const auto step = 1.0 / ( count - 1 );
for ( int i = 1; i < count - 1; i++ )
stops += QskGradientStop( i * step, rgb[i] );
}
stops += QskGradientStop( 1.0, rgb[count - 1] );
return stops;
}
QskGradientStops QskRgbPalette::colorStops( bool discrete ) const
{
return qskColorStops( m_rgb, NumWeights, discrete );
}
QskGradientStops QskRgbPalette::colorStops( Theme theme, bool discrete )
{
const auto pal = QskRgbPalette::palette( theme );
return pal.colorStops( discrete );
}
QskGradientStops QskRgbPalette::colorStops(
const QVector< QRgb >& rgb, bool discrete )
{
const int count = rgb.count();
if ( count == 0 )
return QskGradientStops();
if ( count == 0 )
{
QskGradientStops stops;
stops.reserve( 2 );
stops += QskGradientStop( 0.0, rgb[0] );
stops += QskGradientStop( 1.0, rgb[0] );
return stops;
}
return qskColorStops( rgb.constData(), count, discrete );
}
#include "moc_QskRgbPalette.cpp"

View File

@ -1,79 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_RGB_PALETTE_H
#define QSK_RGB_PALETTE_H
#include "QskGlobal.h"
#include "QskGradient.h"
#include <qmetaobject.h>
#include <qcolor.h>
class QSK_EXPORT QskRgbPalette
{
Q_GADGET
public:
enum Weight
{
W0,
W10,
W20,
W30,
W40,
W50,
W60,
W70,
W80,
W90,
W95,
W99,
W100,
NumWeights
};
Q_ENUM( Weight )
enum Theme
{
DefaultMaterialPrimary,
DefaultMaterialSecondary,
DefaultMaterialTertiary,
DefaultMaterialError,
DefaultMaterialNeutral,
DefaultMaterialNeutralVariant,
NumThemes
};
Q_ENUM( Theme )
static QskRgbPalette palette( Theme );
inline QRgb rgb( Weight weight ) const
{
if ( weight < 0 || weight >= NumWeights )
return 0;
return m_rgb[ weight ];
}
inline QColor color( Weight weight ) const
{
return QColor::fromRgba( rgb( weight ) );
}
QskGradientStops colorStops( bool discrete = false ) const;
static QskGradientStops colorStops( Theme, bool discrete = false );
static QskGradientStops colorStops(
const QVector< QRgb >&, bool discrete = false );
protected:
const QRgb* m_rgb;
};
#endif

View File

@ -9,251 +9,174 @@
#include "QskGlobal.h"
#include <qcolor.h>
#define QSK_RGB_VALUES \
/* Web colors */ \
RGBVALUE( AliceBlue, 0xfff0f8ff ) \
RGBVALUE( AntiqueWhite, 0xfffaebd7 ) \
RGBVALUE( Aqua, 0xff00ffff ) \
RGBVALUE( Aquamarine, 0xff7fffd4 ) \
RGBVALUE( Azure, 0xfff0ffff ) \
RGBVALUE( Beige, 0xfff5f5dc ) \
RGBVALUE( Bisque, 0xffffe4c4 ) \
RGBVALUE( Black, 0xff000000 ) \
RGBVALUE( BlanchedAlmond, 0xffffebcd ) \
RGBVALUE( Blue, 0xff0000ff ) \
RGBVALUE( BlueViolet, 0xff8a2be2 ) \
RGBVALUE( Brown, 0xffa52a2a ) \
RGBVALUE( Burlywood, 0xffdeb887 ) \
RGBVALUE( CadetBlue, 0xff5f9ea0 ) \
RGBVALUE( Chartreuse, 0xff7fff00 ) \
RGBVALUE( Chocolate, 0xffd2691e ) \
RGBVALUE( Coral, 0xffff7f50 ) \
RGBVALUE( CornflowerBlue, 0xff6495ed ) \
RGBVALUE( Cornsilk, 0xfffff8dc ) \
RGBVALUE( Crimson, 0xffdc143c ) \
RGBVALUE( Cyan, 0xff00ffff ) \
RGBVALUE( DarkBlue, 0xff00008b ) \
RGBVALUE( DarkCyan, 0xff008b8b ) \
RGBVALUE( DarkGoldenrod, 0xffb8860b ) \
RGBVALUE( DarkGray, 0xffa9a9a9 ) \
RGBVALUE( DarkGreen, 0xff006400 ) \
RGBVALUE( DarkGrey, 0xffa9a9a9 ) \
RGBVALUE( DarkKhaki, 0xffbdb76b ) \
RGBVALUE( DarkMagenta, 0xff8b008b ) \
RGBVALUE( DarkOliveGreen, 0xff556b2f ) \
RGBVALUE( DarkOrange, 0xffff8c00 ) \
RGBVALUE( DarkOrchid, 0xff9932cc ) \
RGBVALUE( DarkRed, 0xff8b0000 ) \
RGBVALUE( DarkSalmon, 0xffe9967a ) \
RGBVALUE( DarkSeaGreen, 0xff8fbc8f ) \
RGBVALUE( DarkSlateBlue, 0xff483d8b ) \
RGBVALUE( DarkSlateGray, 0xff2f4f4f ) \
RGBVALUE( DarkSlateGrey, 0xff2f4f4f ) \
RGBVALUE( DarkTurquoise, 0xff00ced1 ) \
RGBVALUE( DarkViolet, 0xff9400d3 ) \
RGBVALUE( DeepPink, 0xffff1493 ) \
RGBVALUE( DeepSkyBlue, 0xff00bfff ) \
RGBVALUE( DimGray, 0xff696969 ) \
RGBVALUE( DimGrey, 0xff696969 ) \
RGBVALUE( DodgerBlue, 0xff1e90ff ) \
RGBVALUE( FireBrick, 0xffb22222 ) \
RGBVALUE( FloralWhite, 0xfffffaf0 ) \
RGBVALUE( ForestGreen, 0xff228b22 ) \
RGBVALUE( Fuchsia, 0xffff00ff ) \
RGBVALUE( Gainsboro, 0xffdcdcdc ) \
RGBVALUE( GhostWhite, 0xfff8f8ff ) \
RGBVALUE( Gold, 0xffffd700 ) \
RGBVALUE( Goldenrod, 0xffdaa520 ) \
RGBVALUE( Gray, 0xff808080 ) \
RGBVALUE( Green, 0xff008000 ) \
RGBVALUE( GreenYellow, 0xffadff2f ) \
RGBVALUE( Grey, 0xff808080 ) \
RGBVALUE( Honeydew, 0xfff0fff0 ) \
RGBVALUE( HotPink, 0xffff69b4 ) \
RGBVALUE( IndianRed, 0xffcd5c5c ) \
RGBVALUE( Indigo, 0xff4b0082 ) \
RGBVALUE( Ivory, 0xfffffff0 ) \
RGBVALUE( Khaki, 0xfff0e68c ) \
RGBVALUE( Lavender, 0xffe6e6fa ) \
RGBVALUE( LavenderBlush, 0xfffff0f5 ) \
RGBVALUE( LawnGreen, 0xff7cfc00 ) \
RGBVALUE( LemonChiffon, 0xfffffacd ) \
RGBVALUE( LightBlue, 0xffadd8e6 ) \
RGBVALUE( LightCoral, 0xfff08080 ) \
RGBVALUE( LightCyan, 0xffe0ffff ) \
RGBVALUE( LightGoldenrodYellow, 0xfffafad2 ) \
RGBVALUE( LightGray, 0xffd3d3d3 ) \
RGBVALUE( LightGreen, 0xff90ee90 ) \
RGBVALUE( LightGrey, 0xffd3d3d3 ) \
RGBVALUE( LightPink, 0xffffb6c1 ) \
RGBVALUE( LightSalmon, 0xffffa07a ) \
RGBVALUE( LightSeaGreen, 0xff20b2aa ) \
RGBVALUE( LightSkyBlue, 0xff87cefa ) \
RGBVALUE( LightSlateGray, 0xff778899 ) \
RGBVALUE( LightSlateGrey, 0xff778899 ) \
RGBVALUE( LightSteelBlue, 0xffb0c4de ) \
RGBVALUE( LightYellow, 0xffffffe0 ) \
RGBVALUE( Lime, 0xff00ff00 ) \
RGBVALUE( Limegreen, 0xff32cd32 ) \
RGBVALUE( Linen, 0xfffaf0e6 ) \
RGBVALUE( Magenta, 0xffff00ff ) \
RGBVALUE( Maroon, 0xff800000 ) \
RGBVALUE( MediumAquamarine, 0xff66cdaa ) \
RGBVALUE( MediumBlue, 0xff0000cd ) \
RGBVALUE( MediumOrchid, 0xffba55d3 ) \
RGBVALUE( MediumPurple, 0xff9370db ) \
RGBVALUE( MediumSeaGreen, 0xff3cb371 ) \
RGBVALUE( MediumSlateBlue, 0xff7b68ee ) \
RGBVALUE( MediumSpringGreen, 0xff00fa9a ) \
RGBVALUE( MediumTurquoise, 0xff48d1cc ) \
RGBVALUE( MediumVioletRed, 0xffc71585 ) \
RGBVALUE( MidnightBlue, 0xff191970 ) \
RGBVALUE( MintCream, 0xfff5fffa ) \
RGBVALUE( MistyRose, 0xffffe4e1 ) \
RGBVALUE( Moccasin, 0xffffe4b5 ) \
RGBVALUE( NavajoWhite, 0xffffdead ) \
RGBVALUE( Navy, 0xff000080 ) \
RGBVALUE( OldLace, 0xfffdf5e6 ) \
RGBVALUE( Olive, 0xff808000 ) \
RGBVALUE( OliveDrab, 0xff6b8e23 ) \
RGBVALUE( Orange, 0xffffa500 ) \
RGBVALUE( OrangeRed, 0xffff4500 ) \
RGBVALUE( Orchid, 0xffda70d6 ) \
RGBVALUE( PaleGoldenrod, 0xffeee8aa ) \
RGBVALUE( PaleGreen, 0xff98fb98 ) \
RGBVALUE( PaleTurquoise, 0xffafeeee ) \
RGBVALUE( PaleVioletRed, 0xffdb7093 ) \
RGBVALUE( PapayaWhip, 0xffffefd5 ) \
RGBVALUE( PeachPuff, 0xffffdab9 ) \
RGBVALUE( Peru, 0xffcd853f ) \
RGBVALUE( Pink, 0xffffc0cb ) \
RGBVALUE( Plum, 0xffdda0dd ) \
RGBVALUE( PowderBlue, 0xffb0e0e6 ) \
RGBVALUE( Purple, 0xff800080 ) \
RGBVALUE( Red, 0xffff0000 ) \
RGBVALUE( RosyBrown, 0xffbc8f8f ) \
RGBVALUE( RoyalBlue, 0xff4169e1 ) \
RGBVALUE( SaddleBown, 0xff8b4513 ) \
RGBVALUE( Salmon, 0xfffa8072 ) \
RGBVALUE( SandyBrown, 0xfff4a460 ) \
RGBVALUE( SeaGreen, 0xff2e8b57 ) \
RGBVALUE( Seashell, 0xfffff5ee ) \
RGBVALUE( Sienna, 0xffa0522d ) \
RGBVALUE( Silver, 0xffc0c0c0 ) \
RGBVALUE( SkyBlue, 0xff87ceeb ) \
RGBVALUE( SlateBlue, 0xff6a5acd ) \
RGBVALUE( SlateGrey, 0xff708090 ) \
RGBVALUE( Snow, 0xfffffafa ) \
RGBVALUE( SpringGreen, 0xff00ff7f ) \
RGBVALUE( SteelBlue, 0xff4682b4 ) \
RGBVALUE( Tan, 0xffd2b48c ) \
RGBVALUE( Teal, 0xff008080 ) \
RGBVALUE( Thistle, 0xffd8bfd8 ) \
RGBVALUE( Tomato, 0xffff6347 ) \
RGBVALUE( Turquoise, 0xff40e0d0 ) \
RGBVALUE( Violet, 0xffee82ee ) \
RGBVALUE( Wheat, 0xfff5deb3 ) \
RGBVALUE( WhiteSmoke, 0xfff5f5f5 ) \
RGBVALUE( Yellow, 0xffffff00 ) \
RGBVALUE( YellowGreen, 0xff9acd32 ) \
RGBVALUE( White, 0xffffffff ) \
\
/* Material colors from https://www.figma.com/file/TxkOtbaB4VoXta4ccRNi3b/Material-3-Design-Kit-(Community)?node-id=49823%3A12142 */ \
\
RGBVALUE( DefaultMaterialPrimary0, 0xff000000 ) \
RGBVALUE( DefaultMaterialPrimary10, 0xff21005D ) \
RGBVALUE( DefaultMaterialPrimary20, 0xff381E72 ) \
RGBVALUE( DefaultMaterialPrimary30, 0xff4F378B ) \
RGBVALUE( DefaultMaterialPrimary40, 0xff6750A4 ) \
RGBVALUE( DefaultMaterialPrimary50, 0xff7F67BE ) \
RGBVALUE( DefaultMaterialPrimary60, 0xffB69DF8 ) \
RGBVALUE( DefaultMaterialPrimary70, 0xffB69DF8 ) \
RGBVALUE( DefaultMaterialPrimary80, 0xffD0BCFF ) \
RGBVALUE( DefaultMaterialPrimary90, 0xffEADDFF ) \
RGBVALUE( DefaultMaterialPrimary95, 0xffF6EDFF ) \
RGBVALUE( DefaultMaterialPrimary99, 0xffFFFBFE ) \
RGBVALUE( DefaultMaterialPrimary100, 0xffFFFFFF ) \
\
RGBVALUE( DefaultMaterialSecondary0, 0xff000000 ) \
RGBVALUE( DefaultMaterialSecondary10, 0xff1D192B ) \
RGBVALUE( DefaultMaterialSecondary20, 0xff332D41 ) \
RGBVALUE( DefaultMaterialSecondary30, 0xff4A4458 ) \
RGBVALUE( DefaultMaterialSecondary40, 0xff625B71 ) \
RGBVALUE( DefaultMaterialSecondary50, 0xff7A7289 ) \
RGBVALUE( DefaultMaterialSecondary60, 0xff958DA5 ) \
RGBVALUE( DefaultMaterialSecondary70, 0xffB0A7C0 ) \
RGBVALUE( DefaultMaterialSecondary80, 0xffCCC2DC ) \
RGBVALUE( DefaultMaterialSecondary90, 0xffE8DEF8 ) \
RGBVALUE( DefaultMaterialSecondary95, 0xffF6EDFF ) \
RGBVALUE( DefaultMaterialSecondary99, 0xffFFFBFE ) \
RGBVALUE( DefaultMaterialSecondary100, 0xffFFFFFF ) \
\
RGBVALUE( DefaultMaterialTertiary0, 0xff000000 ) \
RGBVALUE( DefaultMaterialTertiary10, 0xff31111D ) \
RGBVALUE( DefaultMaterialTertiary20, 0xff492532 ) \
RGBVALUE( DefaultMaterialTertiary30, 0xff633B48 ) \
RGBVALUE( DefaultMaterialTertiary40, 0xff7D5260 ) \
RGBVALUE( DefaultMaterialTertiary50, 0xff986977 ) \
RGBVALUE( DefaultMaterialTertiary60, 0xffB58392 ) \
RGBVALUE( DefaultMaterialTertiary70, 0xffD29DAC ) \
RGBVALUE( DefaultMaterialTertiary80, 0xffEFB8C8 ) \
RGBVALUE( DefaultMaterialTertiary90, 0xffFFD8E4 ) \
RGBVALUE( DefaultMaterialTertiary95, 0xffFFECF1 ) \
RGBVALUE( DefaultMaterialTertiary99, 0xffFFFBFA ) \
RGBVALUE( DefaultMaterialTertiary100, 0xffFFFFFF ) \
\
RGBVALUE( DefaultMaterialError0, 0xff000000 ) \
RGBVALUE( DefaultMaterialError10, 0xff410E0B ) \
RGBVALUE( DefaultMaterialError20, 0xff601410 ) \
RGBVALUE( DefaultMaterialError30, 0xff8C1D18 ) \
RGBVALUE( DefaultMaterialError40, 0xffB3261E ) \
RGBVALUE( DefaultMaterialError50, 0xffDC362E ) \
RGBVALUE( DefaultMaterialError60, 0xffE46962 ) \
RGBVALUE( DefaultMaterialError70, 0xffEC928E ) \
RGBVALUE( DefaultMaterialError80, 0xffF2B8B5 ) \
RGBVALUE( DefaultMaterialError90, 0xffF9DEDC ) \
RGBVALUE( DefaultMaterialError95, 0xffFCEEEE ) \
RGBVALUE( DefaultMaterialError99, 0xffFFFBF9 ) \
RGBVALUE( DefaultMaterialError100, 0xffFFFFFF ) \
\
RGBVALUE( DefaultMaterialNeutral0, 0xff000000 ) \
RGBVALUE( DefaultMaterialNeutral10, 0xff1C1B1F ) \
RGBVALUE( DefaultMaterialNeutral20, 0xff313033 ) \
RGBVALUE( DefaultMaterialNeutral30, 0xff484649 ) \
RGBVALUE( DefaultMaterialNeutral40, 0xff605D62 ) \
RGBVALUE( DefaultMaterialNeutral50, 0xff787579 ) \
RGBVALUE( DefaultMaterialNeutral60, 0xff939094 ) \
RGBVALUE( DefaultMaterialNeutral70, 0xffAEAAAE ) \
RGBVALUE( DefaultMaterialNeutral80, 0xffC9C5CA ) \
RGBVALUE( DefaultMaterialNeutral90, 0xffE6E1E5 ) \
RGBVALUE( DefaultMaterialNeutral95, 0xffF4EFF4 ) \
RGBVALUE( DefaultMaterialNeutral99, 0xffFFFBFE ) \
RGBVALUE( DefaultMaterialNeutral100, 0xffFFFFFF ) \
\
RGBVALUE( DefaultMaterialNeutralVariant0, 0xff000000 ) \
RGBVALUE( DefaultMaterialNeutralVariant10, 0xff1D1A22 ) \
RGBVALUE( DefaultMaterialNeutralVariant20, 0xff322F37 ) \
RGBVALUE( DefaultMaterialNeutralVariant30, 0xff49454F ) \
RGBVALUE( DefaultMaterialNeutralVariant40, 0xff605D66 ) \
RGBVALUE( DefaultMaterialNeutralVariant50, 0xff79747E ) \
RGBVALUE( DefaultMaterialNeutralVariant60, 0xff938F99 ) \
RGBVALUE( DefaultMaterialNeutralVariant70, 0xffAEA9B4 ) \
RGBVALUE( DefaultMaterialNeutralVariant80, 0xffCAC4D0 ) \
RGBVALUE( DefaultMaterialNeutralVariant90, 0xffE7E0EC ) \
RGBVALUE( DefaultMaterialNeutralVariant95, 0xffF5EEFA ) \
RGBVALUE( DefaultMaterialNeutralVariant99, 0xffFFFBFE ) \
RGBVALUE( DefaultMaterialNeutralVariant100, 0xffFFFFFF ) \
\
RGBVALUE( Transparent, 0x00000000 ) \
RGBVALUE( AlphaMask, 0xff000000 ) \
RGBVALUE( ColorMask, 0x00ffffff )
namespace QskRgb
{
/* Web colors */
constexpr const QRgb AliceBlue = 0xfff0f8ff;
constexpr const QRgb AntiqueWhite = 0xfffaebd7;
constexpr const QRgb Aqua = 0xff00ffff;
constexpr const QRgb Aquamarine = 0xff7fffd4;
constexpr const QRgb Azure = 0xfff0ffff;
constexpr const QRgb Beige = 0xfff5f5dc;
constexpr const QRgb Bisque = 0xffffe4c4;
constexpr const QRgb Black = 0xff000000;
constexpr const QRgb BlanchedAlmond = 0xffffebcd;
constexpr const QRgb Blue = 0xff0000ff;
constexpr const QRgb BlueViolet = 0xff8a2be2;
constexpr const QRgb Brown = 0xffa52a2a;
constexpr const QRgb Burlywood = 0xffdeb887;
constexpr const QRgb CadetBlue = 0xff5f9ea0;
constexpr const QRgb Chartreuse = 0xff7fff00;
constexpr const QRgb Chocolate = 0xffd2691e;
constexpr const QRgb Coral = 0xffff7f50;
constexpr const QRgb CornflowerBlue = 0xff6495ed;
constexpr const QRgb Cornsilk = 0xfffff8dc;
constexpr const QRgb Crimson = 0xffdc143c;
constexpr const QRgb Cyan = 0xff00ffff;
constexpr const QRgb DarkBlue = 0xff00008b;
constexpr const QRgb DarkCyan = 0xff008b8b;
constexpr const QRgb DarkGoldenrod = 0xffb8860b;
constexpr const QRgb DarkGray = 0xffa9a9a9;
constexpr const QRgb DarkGreen = 0xff006400;
constexpr const QRgb DarkGrey = 0xffa9a9a9;
constexpr const QRgb DarkKhaki = 0xffbdb76b;
constexpr const QRgb DarkMagenta = 0xff8b008b;
constexpr const QRgb DarkOliveGreen = 0xff556b2f;
constexpr const QRgb DarkOrange = 0xffff8c00;
constexpr const QRgb DarkOrchid = 0xff9932cc;
constexpr const QRgb DarkRed = 0xff8b0000;
constexpr const QRgb DarkSalmon = 0xffe9967a;
constexpr const QRgb DarkSeaGreen = 0xff8fbc8f;
constexpr const QRgb DarkSlateBlue = 0xff483d8b;
constexpr const QRgb DarkSlateGray = 0xff2f4f4f;
constexpr const QRgb DarkSlateGrey = 0xff2f4f4f;
constexpr const QRgb DarkTurquoise = 0xff00ced1;
constexpr const QRgb DarkViolet = 0xff9400d3;
constexpr const QRgb DeepPink = 0xffff1493;
constexpr const QRgb DeepSkyBlue = 0xff00bfff;
constexpr const QRgb DimGray = 0xff696969;
constexpr const QRgb DimGrey = 0xff696969;
constexpr const QRgb DodgerBlue = 0xff1e90ff;
constexpr const QRgb FireBrick = 0xffb22222;
constexpr const QRgb FloralWhite = 0xfffffaf0;
constexpr const QRgb ForestGreen = 0xff228b22;
constexpr const QRgb Fuchsia = 0xffff00ff;
constexpr const QRgb Gainsboro = 0xffdcdcdc;
constexpr const QRgb GhostWhite = 0xfff8f8ff;
constexpr const QRgb Gold = 0xffffd700;
constexpr const QRgb Goldenrod = 0xffdaa520;
constexpr const QRgb Gray = 0xff808080;
constexpr const QRgb Green = 0xff008000;
constexpr const QRgb GreenYellow = 0xffadff2f;
constexpr const QRgb Grey = 0xff808080;
constexpr const QRgb Honeydew = 0xfff0fff0;
constexpr const QRgb HotPink = 0xffff69b4;
constexpr const QRgb IndianRed = 0xffcd5c5c;
constexpr const QRgb Indigo = 0xff4b0082;
constexpr const QRgb Ivory = 0xfffffff0;
constexpr const QRgb Khaki = 0xfff0e68c;
constexpr const QRgb Lavender = 0xffe6e6fa;
constexpr const QRgb LavenderBlush = 0xfffff0f5;
constexpr const QRgb LawnGreen = 0xff7cfc00;
constexpr const QRgb LemonChiffon = 0xfffffacd;
constexpr const QRgb LightBlue = 0xffadd8e6;
constexpr const QRgb LightCoral = 0xfff08080;
constexpr const QRgb LightCyan = 0xffe0ffff;
constexpr const QRgb LightGoldenrodYellow = 0xfffafad2;
constexpr const QRgb LightGray = 0xffd3d3d3;
constexpr const QRgb LightGreen = 0xff90ee90;
constexpr const QRgb LightGrey = 0xffd3d3d3;
constexpr const QRgb LightPink = 0xffffb6c1;
constexpr const QRgb LightSalmon = 0xffffa07a;
constexpr const QRgb LightSeaGreen = 0xff20b2aa;
constexpr const QRgb LightSkyBlue = 0xff87cefa;
constexpr const QRgb LightSlateGray = 0xff778899;
constexpr const QRgb LightSlateGrey = 0xff778899;
constexpr const QRgb LightSteelBlue = 0xffb0c4de;
constexpr const QRgb LightYellow = 0xffffffe0;
constexpr const QRgb Lime = 0xff00ff00;
constexpr const QRgb Limegreen = 0xff32cd32;
constexpr const QRgb Linen = 0xfffaf0e6;
constexpr const QRgb Magenta = 0xffff00ff;
constexpr const QRgb Maroon = 0xff800000;
constexpr const QRgb MediumAquamarine = 0xff66cdaa;
constexpr const QRgb MediumBlue = 0xff0000cd;
constexpr const QRgb MediumOrchid = 0xffba55d3;
constexpr const QRgb MediumPurple = 0xff9370db;
constexpr const QRgb MediumSeaGreen = 0xff3cb371;
constexpr const QRgb MediumSlateBlue = 0xff7b68ee;
constexpr const QRgb MediumSpringGreen = 0xff00fa9a;
constexpr const QRgb MediumTurquoise = 0xff48d1cc;
constexpr const QRgb MediumVioletRed = 0xffc71585;
constexpr const QRgb MidnightBlue = 0xff191970;
constexpr const QRgb MintCream = 0xfff5fffa;
constexpr const QRgb MistyRose = 0xffffe4e1;
constexpr const QRgb Moccasin = 0xffffe4b5;
constexpr const QRgb NavajoWhite = 0xffffdead;
constexpr const QRgb Navy = 0xff000080;
constexpr const QRgb OldLace = 0xfffdf5e6;
constexpr const QRgb Olive = 0xff808000;
constexpr const QRgb OliveDrab = 0xff6b8e23;
constexpr const QRgb Orange = 0xffffa500;
constexpr const QRgb OrangeRed = 0xffff4500;
constexpr const QRgb Orchid = 0xffda70d6;
constexpr const QRgb PaleGoldenrod = 0xffeee8aa;
constexpr const QRgb PaleGreen = 0xff98fb98;
constexpr const QRgb PaleTurquoise = 0xffafeeee;
constexpr const QRgb PaleVioletRed = 0xffdb7093;
constexpr const QRgb PapayaWhip = 0xffffefd5;
constexpr const QRgb PeachPuff = 0xffffdab9;
constexpr const QRgb Peru = 0xffcd853f;
constexpr const QRgb Pink = 0xffffc0cb;
constexpr const QRgb Plum = 0xffdda0dd;
constexpr const QRgb PowderBlue = 0xffb0e0e6;
constexpr const QRgb Purple = 0xff800080;
constexpr const QRgb Red = 0xffff0000;
constexpr const QRgb RosyBrown = 0xffbc8f8f;
constexpr const QRgb RoyalBlue = 0xff4169e1;
constexpr const QRgb SaddleBrown = 0xff8b4513;
constexpr const QRgb Salmon = 0xfffa8072;
constexpr const QRgb SandyBrown = 0xfff4a460;
constexpr const QRgb SeaGreen = 0xff2e8b57;
constexpr const QRgb Seashell = 0xfffff5ee;
constexpr const QRgb Sienna = 0xffa0522d;
constexpr const QRgb Silver = 0xffc0c0c0;
constexpr const QRgb SkyBlue = 0xff87ceeb;
constexpr const QRgb SlateBlue = 0xff6a5acd;
constexpr const QRgb SlateGrey = 0xff708090;
constexpr const QRgb Snow = 0xfffffafa;
constexpr const QRgb SpringGreen = 0xff00ff7f;
constexpr const QRgb SteelBlue = 0xff4682b4;
constexpr const QRgb Tan = 0xffd2b48c;
constexpr const QRgb Teal = 0xff008080;
constexpr const QRgb Thistle = 0xffd8bfd8;
constexpr const QRgb Tomato = 0xffff6347;
constexpr const QRgb Turquoise = 0xff40e0d0;
constexpr const QRgb Violet = 0xffee82ee;
constexpr const QRgb Wheat = 0xfff5deb3;
constexpr const QRgb WhiteSmoke = 0xfff5f5f5;
constexpr const QRgb Yellow = 0xffffff00;
constexpr const QRgb YellowGreen = 0xff9acd32;
constexpr const QRgb White = 0xffffffff;
// others
constexpr const QRgb Transparent = 0x00000000;
constexpr const QRgb AlphaMask = 0xff000000;
constexpr const QRgb ColorMask = 0x00ffffff;
}
namespace QskRgb
{
#define RGBVALUE( name, value ) static constexpr const QRgb name = value;
QSK_RGB_VALUES
#undef RGBVALUE
QSK_EXPORT QRgb rgb( Qt::GlobalColor );
QSK_EXPORT QRgb interpolated( QRgb rgb1, QRgb rgb2, qreal ratio );
QSK_EXPORT QColor interpolated( const QColor& c1, const QColor& c2, qreal ratio );

View File

@ -8,6 +8,7 @@
#include "QskGraphic.h"
#include "QskTextOptions.h"
#include "QskFunctions.h"
#include <qfontmetrics.h>
#include <qmath.h>
@ -87,22 +88,25 @@ QRectF QskPushButtonSkinlet::textRect(
using Q = QskPushButton;
auto r = button->subControlContentsRect( contentsRect, Q::Panel );
if ( r.isEmpty() || !button->hasGraphic() )
return r;
if ( button->hasGraphic() )
/*
For horizontal layouts Text depends on Graphic, while
for vertical Graphic depends on Text. Confusing ...
*/
if ( qskOrientation( button ) == Qt::Horizontal )
{
if ( qskOrientation( button ) == Qt::Horizontal )
{
const auto graphicsRect = subControlRect( button, contentsRect, Q::Graphic );
const auto spacing = button->spacingHint( Q::Panel );
const auto graphicsRect = subControlRect( button, contentsRect, Q::Graphic );
const auto spacing = button->spacingHint( Q::Panel );
r.setX( r.x() + graphicsRect.width() + spacing );
}
else
{
const qreal h = button->effectiveFontHeight( Q::Text );
if ( h < r.height() )
r.setTop( r.bottom() - h );
}
r.setX( r.x() + graphicsRect.width() + spacing );
}
else
{
const qreal h = button->effectiveFontHeight( Q::Text );
if ( h < r.height() )
r.setTop( r.bottom() - h );
}
return r;
@ -114,18 +118,20 @@ QRectF QskPushButtonSkinlet::graphicRect(
using Q = QskPushButton;
auto r = button->subControlContentsRect( contentsRect, Q::Panel );
if ( r.isEmpty() || button->text().isEmpty() )
return r;
const auto orientation = qskOrientation( button );
if ( !button->text().isEmpty() && orientation == Qt::Vertical )
if ( orientation == Qt::Vertical )
{
const auto textRect = subControlRect( button, contentsRect, Q::Text );
qreal h = textRect.height() + button->spacingHint( Q::Panel );
const auto h = textRect.height() + button->spacingHint( Q::Panel );
if ( h < r.height() )
r.setBottom( r.bottom() - h );
else
r.setHeight( 0 );
if ( h > r.height() )
return QRectF();
r.setBottom( r.bottom() - h );
}
const auto maxSize = button->graphicSourceSize();
@ -149,37 +155,20 @@ QRectF QskPushButtonSkinlet::graphicRect(
}
}
const auto sz = button->graphic().defaultSize();
r = r.marginsRemoved( button->paddingHint( Q::Graphic ) );
if ( !( r.isEmpty() || sz.isEmpty() ) )
if ( !r.isEmpty() )
{
// inner rectangle according to the aspect ratio
const double scaleFactor =
qMin( r.width() / sz.width(), r.height() / sz.height() );
const int w = qFloor( scaleFactor * sz.width() );
const int h = qFloor( scaleFactor * sz.height() );
int x, y;
if ( orientation == Qt::Horizontal )
auto sz = button->graphic().defaultSize();
if ( !sz.isEmpty() )
{
x = r.left();
y = r.top();
sz.scale( r.size(), Qt::KeepAspectRatio );
const auto align = ( orientation == Qt::Horizontal )
? ( Qt::AlignLeft | Qt::AlignTop ) : Qt::AlignCenter;
r = qskAlignedRectF( r, sz.width(), sz.height(), align );
}
else
{
// early aligning to avoid pointless operations, that finally will
// have no effect, when drawing to an integer based paint device
x = qFloor( r.center().x() - 0.5 * w );
y = qFloor( r.center().y() - 0.5 * h );
}
r = QRectF( x, y, w, h );
const auto padding = button->paddingHint( Q::Graphic );
r = r.marginsRemoved( padding );
}
return r;

View File

@ -27,6 +27,7 @@ HEADERS += \
common/QskGlobal.h \
common/QskGradient.h \
common/QskGradientStop.h \
common/QskHctColor.h \
common/QskIntervalF.h \
common/QskMargins.h \
common/QskMetaFunction.h \
@ -37,7 +38,6 @@ HEADERS += \
common/QskPlacementPolicy.h \
common/QskPlatform.h \
common/QskRgbValue.h \
common/QskRgbPalette.h \
common/QskScaleEngine.h \
common/QskScaleTickmarks.h \
common/QskShadowMetrics.h \
@ -56,6 +56,7 @@ SOURCES += \
common/QskFunctions.cpp \
common/QskGradient.cpp \
common/QskGradientStop.cpp \
common/QskHctColor.cpp \
common/QskIntervalF.cpp \
common/QskMargins.cpp \
common/QskMetaFunction.cpp \
@ -64,7 +65,6 @@ SOURCES += \
common/QskPlatform.cpp \
common/QskPlacementPolicy.cpp \
common/QskRgbValue.cpp \
common/QskRgbPalette.cpp \
common/QskScaleEngine.cpp \
common/QskScaleTickmarks.cpp \
common/QskShadowMetrics.cpp \