add arc border colors

This commit is contained in:
Peter Hartmann 2021-10-19 12:17:37 +02:00
parent 922d81eddd
commit d5b3fe0dba
12 changed files with 357 additions and 13 deletions

View File

@ -0,0 +1,171 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskArcBorderColors.h"
#include "QskRgbValue.h"
#include <qhashfunctions.h>
#include <qvariant.h>
static void qskRegisterArcBorderColors()
{
qRegisterMetaType< QskArcBorderColors >();
QMetaType::registerConverter< QColor, QskArcBorderColors >(
[]( const QColor& color ) { return QskArcBorderColors( color ); } );
}
Q_CONSTRUCTOR_FUNCTION( qskRegisterArcBorderColors )
static inline bool qskIsVisble( const QColor& c )
{
return c.isValid() && ( c.alpha() > 0 );
}
static inline void qskSetColors( const QColor& c, QColor* colors )
{
colors[ 0 ] = colors[ 1 ] = c.toRgb();
}
static inline void qskSetColors(
const QColor& outer, const QColor& inner, QColor* colors )
{
colors[ Qsk::Outer ] = outer.toRgb();
colors[ Qsk::Inner ] = inner.toRgb();
}
QskArcBorderColors::QskArcBorderColors()
{
}
QskArcBorderColors::QskArcBorderColors(
const QColor& outer, const QColor& inner )
{
qskSetColors( outer, inner, m_colors );
}
QskArcBorderColors::QskArcBorderColors( const QColor& color )
{
qskSetColors( color, m_colors );
}
QskArcBorderColors::~QskArcBorderColors()
{
}
bool QskArcBorderColors::operator==( const QskArcBorderColors& other ) const
{
return ( m_colors[ 0 ] == other.m_colors[ 0 ] ) &&
( m_colors[ 1 ] == other.m_colors[ 1 ] );
}
void QskArcBorderColors::setAlpha( int alpha )
{
for ( int i = 0; i < 2; i++ )
{
if ( m_colors[ i ].isValid() && m_colors[ i ].alpha() )
m_colors[ i ].setAlpha( alpha );
}
}
void QskArcBorderColors::setColors( const QColor& color )
{
qskSetColors( color, m_colors );
}
void QskArcBorderColors::setColors(
const QColor& outer, const QColor& inner )
{
qskSetColors( outer, inner, m_colors );
}
void QskArcBorderColors::setColor(
Qsk::ArcPosition position, const QColor& color )
{
m_colors[ position ] = color.toRgb();
}
bool QskArcBorderColors::isVisible() const
{
if ( qskIsVisble( m_colors[ 0 ] ) )
return true;
if ( qskIsVisble( m_colors[ 1 ] ) )
return true;
return false;
}
bool QskArcBorderColors::isMonochrome() const
{
if ( m_colors[ 1 ] != m_colors[ 0 ] )
return false;
return true;
}
QskArcBorderColors QskArcBorderColors::interpolated(
const QskArcBorderColors& to, qreal ratio ) const
{
QskArcBorderColors colors;
for ( size_t i = 0; i < 2; i++ )
{
colors.m_colors[ i ] = QskRgb::interpolated(
m_colors[ i ], to.m_colors[ i ], ratio );
}
return colors;
}
QVariant QskArcBorderColors::interpolate(
const QskArcBorderColors& from, const QskArcBorderColors& to, qreal ratio )
{
return QVariant::fromValue( from.interpolated( to, ratio ) );
}
uint QskArcBorderColors::hash( uint seed ) const
{
const QRgb rgb[] =
{
m_colors[ 0 ].rgba(),
m_colors[ 1 ].rgba(),
};
return qHashBits( rgb, sizeof( rgb ), seed );
}
#ifndef QT_NO_DEBUG_STREAM
#include <qdebug.h>
static inline void qskDebugColor( QDebug debug, const QColor& c )
{
debug << '('
<< c.red() << ','
<< c.green() << ','
<< c.blue() << ','
<< c.alpha() << ')';
}
QDebug operator<<( QDebug debug, const QskArcBorderColors& colors )
{
QDebugStateSaver saver( debug );
debug.nospace();
debug << "ArcBorderColors" << '(';
debug << " outer";
qskDebugColor( debug, colors.color( Qsk::Outer ) );
debug << ", inner";
qskDebugColor( debug, colors.color( Qsk::Inner ) );
debug << " )";
return debug;
}
#endif

View File

@ -0,0 +1,90 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_ARC_BORDER_COLORS_H
#define QSK_ARC_BORDER_COLORS_H
#include "QskNamespace.h"
#include <qcolor.h>
#include <qmetatype.h>
class QDebug;
class QSK_EXPORT QskArcBorderColors
{
public:
QskArcBorderColors();
QskArcBorderColors( const QColor& outer, const QColor& inner );
QskArcBorderColors( Qt::GlobalColor );
QskArcBorderColors( QRgb );
QskArcBorderColors( const QColor& );
~QskArcBorderColors();
bool operator==( const QskArcBorderColors& ) const;
bool operator!=( const QskArcBorderColors& ) const;
void setAlpha( int alpha );
void setColors( const QColor& );
void setColors( const QColor& outer, const QColor& inner );
void setColor( Qsk::ArcPosition, const QColor& );
QColor color( Qsk::ArcPosition ) const;
QRgb rgb( Qsk::ArcPosition ) const;
QskArcBorderColors interpolated( const QskArcBorderColors&, qreal value ) const;
static QVariant interpolate( const QskArcBorderColors&,
const QskArcBorderColors&, qreal ratio );
uint hash( uint seed = 0 ) const;
bool isMonochrome() const;
bool isVisible() const;
private:
// should be stored as QRgb
QColor m_colors[ 2 ];
};
inline QskArcBorderColors::QskArcBorderColors( Qt::GlobalColor color )
: QskArcBorderColors( QColor( color ) )
{
}
inline QskArcBorderColors::QskArcBorderColors( QRgb rgb )
: QskArcBorderColors( QColor::fromRgba( rgb ) )
{
}
inline bool QskArcBorderColors::operator!=( const QskArcBorderColors& other ) const
{
return !( *this == other );
}
inline QColor QskArcBorderColors::color( Qsk::ArcPosition position ) const
{
return m_colors[ position ];
}
inline QRgb QskArcBorderColors::rgb( Qsk::ArcPosition position ) const
{
return m_colors[ position ].rgba();
}
#ifndef QT_NO_DEBUG_STREAM
QSK_EXPORT QDebug operator<<( QDebug, const QskArcBorderColors& );
#endif
Q_DECLARE_METATYPE( QskArcBorderColors )
#endif

View File

@ -6,6 +6,7 @@
#include "QskSkinHintTableEditor.h"
#include "QskSkinHintTable.h"
#include "QskArcBorderColors.h"
#include "QskArcBorderMetrics.h"
#include "QskArcMetrics.h"
#include "QskMargins.h"
@ -519,3 +520,30 @@ QskArcBorderMetrics QskSkinHintTableEditor::arcBorderMetrics( QskAspect aspect )
{
return metricHint< QskArcBorderMetrics >( aspectBorder( aspect ) );
}
void QskSkinHintTableEditor::setArcBorderColors(
QskAspect aspect, const QskArcBorderColors& borderColors,
QskStateCombination combination )
{
setColorHint( aspectBorder( aspect ), borderColors, combination );
}
void QskSkinHintTableEditor::setArcBorderColors( QskAspect aspect,
const QColor& outer, const QColor& inner,
QskStateCombination combination )
{
setColorHint( aspectBorder( aspect ),
QskArcBorderColors( outer, inner ),
combination );
}
void QskSkinHintTableEditor::removeArcBorderColors(
QskAspect aspect, QskStateCombination combination )
{
return removeColorHint( aspectBorder( aspect ), combination );
}
QskArcBorderColors QskSkinHintTableEditor::arcBorderColors( QskAspect aspect ) const
{
return colorHint< QskArcBorderColors >( aspectBorder( aspect ) );
}

View File

@ -14,6 +14,7 @@
#include <qcolor.h>
#include <qvariant.h>
class QskArcBorderColors;
class QskArcBorderMetrics;
class QskArcMetrics;
class QskMargins;
@ -245,6 +246,18 @@ class QSK_EXPORT QskSkinHintTableEditor
QskArcBorderMetrics arcBorderMetrics( QskAspect ) const;
// arcBorderColors
void setArcBorderColors( QskAspect,
const QskArcBorderColors&, QskStateCombination = QskStateCombination() );
void setArcBorderColors( QskAspect,
const QColor&, const QColor&,
QskStateCombination = QskStateCombination() );
void removeArcBorderColors( QskAspect, QskStateCombination = QskStateCombination() );
QskArcBorderColors arcBorderColors( QskAspect ) const;
private:
QskSkinHintTable* m_table = nullptr;
};

View File

@ -89,10 +89,10 @@ static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics,
static inline bool qskIsArcVisible( const QskArcMetrics& arcMetrics,
const QskArcBorderMetrics& borderMetrics,
const QskGradient& gradient )
const QskArcBorderColors& borderColors, const QskGradient& gradient )
{
return ( !arcMetrics.isNull() && gradient.isVisible() )
|| !borderMetrics.isNull();
|| ( !borderMetrics.isNull() && borderColors.isVisible() );
}
static inline QskTextColors qskTextColors(
@ -365,7 +365,10 @@ QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
auto arcBorderMetrics = skinnable->arcBorderMetricsHint( subControl );
arcBorderMetrics = arcBorderMetrics.toAbsolute( arcRect.size() );
if ( !qskIsArcVisible( arcMetrics, arcBorderMetrics, fillGradient ) )
const auto arcBorderColors = skinnable->arcBorderColorsHint( subControl );
if ( !qskIsArcVisible( arcMetrics, arcBorderMetrics, arcBorderColors,
fillGradient ) )
return nullptr;
auto arcNode = static_cast< QskArcNode* >( node );
@ -374,7 +377,7 @@ QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
arcNode = new QskArcNode();
arcNode->setArcData( rect, absoluteArcMetrics, arcBorderMetrics,
fillGradient, control->window() );
arcBorderColors, fillGradient, control->window() );
return arcNode;
}

View File

@ -6,6 +6,7 @@
#include "QskSkinnable.h"
#include "QskAnimationHint.h"
#include "QskArcBorderColors.h"
#include "QskArcBorderMetrics.h"
#include "QskArcMetrics.h"
#include "QskAspect.h"
@ -559,6 +560,24 @@ QskArcBorderMetrics QskSkinnable::arcBorderMetricsHint(
this, aspect | QskAspect::Border, status );
}
bool QskSkinnable::setArcBorderColorsHint(
const QskAspect aspect, const QskArcBorderColors& colors )
{
return qskSetColor( this, aspect | QskAspect::Border, colors );
}
bool QskSkinnable::resetArcBorderColorsHint( const QskAspect aspect )
{
return resetColor( aspect | QskAspect::Border );
}
QskArcBorderColors QskSkinnable::arcBorderColorsHint(
const QskAspect aspect, QskSkinHintStatus* status ) const
{
return qskColor< QskArcBorderColors >(
this, aspect | QskAspect::Border, status );
}
bool QskSkinnable::setSpacingHint( const QskAspect aspect, qreal spacing )
{
return qskSetMetric( this, aspect | QskAspect::Spacing, spacing );

View File

@ -21,6 +21,7 @@ class QDebug;
class QSGNode;
class QskArcBorderColors;
class QskArcBorderMetrics;
class QskArcMetrics;
class QskControl;
@ -199,6 +200,10 @@ class QSK_EXPORT QskSkinnable
bool resetArcBorderMetricsHint( QskAspect );
QskArcBorderMetrics arcBorderMetricsHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setArcBorderColorsHint( QskAspect, const QskArcBorderColors& );
bool resetArcBorderColorsHint( QskAspect );
QskArcBorderColors arcBorderColorsHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setSpacingHint( QskAspect, qreal );
bool resetSpacingHint( QskAspect );
qreal spacingHint( QskAspect, QskSkinHintStatus* = nullptr ) const;

View File

@ -15,11 +15,13 @@ QskArcNode::~QskArcNode()
}
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& metrics,
const QskArcBorderMetrics& borderMetrics, const QskGradient &gradient,
const QskArcBorderMetrics& borderMetrics,
const QskArcBorderColors& borderColors, const QskGradient &gradient,
QQuickWindow* window )
{
m_metrics = metrics;
m_borderMetrics = borderMetrics;
m_borderColors = borderColors;
m_gradient = gradient;
if ( rect.isEmpty() )
@ -37,8 +39,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& metrics,
effect - even if not being visible. TODO ...
*/
// ### implement border colors
// hasBorder = borderColors.isVisible();
hasBorder = borderColors.isVisible();
}
if ( !hasBorder && !hasFill )
@ -56,7 +57,8 @@ void QskArcNode::paint( QPainter* painter, const QSizeF &size )
QskArcRenderer renderer;
renderer.renderArc( rect, m_metrics, m_borderMetrics, m_gradient, painter );
renderer.renderArc( rect, m_metrics, m_borderMetrics, m_borderColors,
m_gradient, painter );
}
uint QskArcNode::hash() const

View File

@ -6,6 +6,7 @@
#ifndef QSK_ARC_NODE_H
#define QSK_ARC_NODE_H
#include "QskArcBorderColors.h"
#include "QskArcBorderMetrics.h"
#include "QskArcMetrics.h"
#include "QskGradient.h"
@ -18,7 +19,8 @@ class QSK_EXPORT QskArcNode : public QskPaintedNode
~QskArcNode() override;
void setArcData( const QRectF&, const QskArcMetrics&,
const QskArcBorderMetrics&, const QskGradient&, QQuickWindow* );
const QskArcBorderMetrics&, const QskArcBorderColors&,
const QskGradient&, QQuickWindow* );
void paint( QPainter* painter, const QSizeF& size ) override;
uint hash() const override;
@ -26,6 +28,7 @@ class QSK_EXPORT QskArcNode : public QskPaintedNode
private:
QskArcMetrics m_metrics;
QskArcBorderMetrics m_borderMetrics;
QskArcBorderColors m_borderColors;
QskGradient m_gradient;
};

View File

@ -5,6 +5,7 @@
#include "QskArcRenderer.h"
#include "QskArcBorderColors.h"
#include "QskArcBorderMetrics.h"
#include "QskArcMetrics.h"
#include "QskGradient.h"
@ -14,7 +15,8 @@
void QskArcRenderer::renderArc( const QRectF& rect,
const QskArcMetrics& metrics, const QskArcBorderMetrics &borderMetrics,
const QskGradient& gradient, QPainter* painter )
const QskArcBorderColors& borderColors, const QskGradient& gradient,
QPainter* painter )
{
painter->setRenderHint( QPainter::Antialiasing, true );
@ -56,7 +58,9 @@ void QskArcRenderer::renderArc( const QRectF& rect,
// draw inner border:
const qreal i = metrics.width() / 2;
const auto innerRect = rect.marginsRemoved( { i, i, i, i } );
painter->setPen( QPen( Qt::black, borderMetrics.width( Qsk::Inner ),
const QColor innerColor = borderColors.color( Qsk::Inner );
painter->setPen( QPen( innerColor, borderMetrics.width( Qsk::Inner ),
Qt::SolidLine, Qt::FlatCap ) );
painter->drawArc( innerRect, metrics.startAngle(), metrics.spanAngle() );
}
@ -66,7 +70,9 @@ void QskArcRenderer::renderArc( const QRectF& rect,
// draw outer border:
const qreal o = ( metrics.width() - borderMetrics.width( Qsk::Outer ) ) / 2;
const auto outerRect = rect.marginsAdded( { o, o, o, o } );
painter->setPen( QPen( Qt::black, borderMetrics.width( Qsk::Outer ),
const QColor outerColor = borderColors.color( Qsk::Outer );
painter->setPen( QPen( outerColor, borderMetrics.width( Qsk::Outer ),
Qt::SolidLine, Qt::FlatCap ) );
painter->drawArc( outerRect, metrics.startAngle(), metrics.spanAngle() );
}

View File

@ -8,6 +8,7 @@
#include "QskGlobal.h"
class QskArcBorderColors;
class QskArcBorderMetrics;
class QskArcMetrics;
class QskGradient;
@ -19,7 +20,8 @@ class QSK_EXPORT QskArcRenderer
{
public:
void renderArc( const QRectF&, const QskArcMetrics&,
const QskArcBorderMetrics&, const QskGradient&, QPainter* );
const QskArcBorderMetrics&, const QskArcBorderColors&,
const QskGradient&, QPainter* );
};
#endif

View File

@ -12,6 +12,7 @@ DEPENDPATH *= $${QSK_SUBDIRS}
# DEFINES += QSK_LAYOUT_COMPAT
HEADERS += \
common/QskArcBorderColors.h \
common/QskArcBorderMetrics.h \
common/QskArcMetrics.h \
common/QskAspect.h \
@ -40,6 +41,7 @@ HEADERS += \
common/QskTextOptions.h
SOURCES += \
common/QskArcBorderColors.cpp \
common/QskArcBorderMetrics.cpp \
common/QskArcMetrics.cpp \
common/QskAspect.cpp \