towards improved QskGradient
This commit is contained in:
parent
99132276fc
commit
03ce740b29
@ -205,11 +205,11 @@ void Box::setGradient(
|
||||
{
|
||||
const QskHctColor hctColor( base );
|
||||
|
||||
QVector< QRgb > rgb;
|
||||
rgb.reserve( 10 );
|
||||
QVector< QRgb > colors;
|
||||
colors.reserve( 10 );
|
||||
|
||||
for ( int i = 0; i < 10; i++ )
|
||||
rgb += hctColor.toned( 90 - i * 7 ).rgb();
|
||||
colors += hctColor.toned( 90 - i * 7 ).rgb();
|
||||
|
||||
setGradient( QskGradient( orientation, QskGradient::colorStops( rgb, true ) ) );
|
||||
setGradient( QskGradient( orientation, qskBuildGradientStops( colors, true ) ) );
|
||||
}
|
||||
|
@ -29,15 +29,14 @@ namespace
|
||||
{
|
||||
const QskHctColor hctColor( base );
|
||||
|
||||
QVector< QRgb > rgb;
|
||||
rgb += hctColor.toned( 75 ).rgb();
|
||||
rgb += hctColor.toned( 60 ).rgb();
|
||||
rgb += hctColor.toned( 45 ).rgb();
|
||||
rgb += hctColor.toned( 30 ).rgb();
|
||||
QVector< QRgb > colors;
|
||||
colors += hctColor.toned( 75 ).rgb();
|
||||
colors += hctColor.toned( 60 ).rgb();
|
||||
colors += hctColor.toned( 45 ).rgb();
|
||||
colors += hctColor.toned( 30 ).rgb();
|
||||
|
||||
const auto stops = QskGradient::colorStops( rgb, true );
|
||||
|
||||
setBarGradient( QskGradient( orientation(), stops ) );
|
||||
setBarGradient( QskGradient( orientation(),
|
||||
qskBuildGradientStops( colors, true ) ) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include <qhashfunctions.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
static void qskRegisterGradient()
|
||||
{
|
||||
qRegisterMetaType< QskGradient >();
|
||||
@ -37,9 +35,7 @@ static inline bool qskIsGradientValid( const QskGradientStops& stops )
|
||||
return false;
|
||||
|
||||
if ( stops.first().position() != 0.0 || stops.last().position() != 1.0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !stops.first().color().isValid() )
|
||||
return false;
|
||||
@ -56,29 +52,6 @@ static inline bool qskIsGradientValid( const QskGradientStops& stops )
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool qskIsMonochrome( const QskGradientStops& stops )
|
||||
{
|
||||
for ( int i = 1; i < stops.size(); i++ )
|
||||
{
|
||||
if ( stops[ i ].color() != stops[ 0 ].color() )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool qskIsVisible( const QskGradientStops& stops )
|
||||
{
|
||||
for ( const auto& stop : stops )
|
||||
{
|
||||
const auto& c = stop.color();
|
||||
if ( c.isValid() && c.alpha() > 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline QColor qskInterpolated(
|
||||
const QskGradientStop& s1, const QskGradientStop& s2, qreal pos )
|
||||
{
|
||||
@ -183,53 +156,6 @@ static inline QskGradientStops qskExtractedStops(
|
||||
return extracted;
|
||||
}
|
||||
|
||||
static inline QskGradientStops qskGradientStops( const QGradientStops& qtStops )
|
||||
{
|
||||
QskGradientStops stops;
|
||||
stops.reserve( qtStops.count() );
|
||||
|
||||
for ( const auto& s : qtStops )
|
||||
stops += QskGradientStop( s.first, s.second );
|
||||
|
||||
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 ) noexcept
|
||||
: m_orientation( orientation )
|
||||
, m_isDirty( false )
|
||||
@ -277,7 +203,7 @@ QskGradient::QskGradient( Qt::Orientation orientation, QGradient::Preset preset
|
||||
QskGradient::QskGradient( Orientation orientation, QGradient::Preset preset )
|
||||
: QskGradient( orientation )
|
||||
{
|
||||
setStops( qskGradientStops( QGradient( preset ).stops() ) );
|
||||
setStops( qskBuildGradientStops( QGradient( preset ).stops() ) );
|
||||
}
|
||||
|
||||
QskGradient::~QskGradient()
|
||||
@ -380,20 +306,35 @@ void QskGradient::setStops( const QskGradientStops& stops )
|
||||
m_isDirty = true;
|
||||
}
|
||||
|
||||
int QskGradient::stopCount() const
|
||||
int QskGradient::stopCount() const noexcept
|
||||
{
|
||||
return m_stops.count();
|
||||
}
|
||||
|
||||
qreal QskGradient::stopAt( int index ) const
|
||||
qreal QskGradient::stopAt( int index ) const noexcept
|
||||
{
|
||||
if ( index >= m_stops.size() )
|
||||
if ( index < 0 || index >= m_stops.size() )
|
||||
return -1.0;
|
||||
|
||||
return m_stops[ index ].position();
|
||||
}
|
||||
|
||||
QColor QskGradient::colorAt( int index ) const
|
||||
bool QskGradient::hasStopAt( qreal value ) const noexcept
|
||||
{
|
||||
// better use binary search TODO ...
|
||||
for ( auto& stop : m_stops )
|
||||
{
|
||||
if ( stop.position() == value )
|
||||
return true;
|
||||
|
||||
if ( stop.position() > value )
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QColor QskGradient::colorAt( int index ) const noexcept
|
||||
{
|
||||
if ( index >= m_stops.size() )
|
||||
return QColor();
|
||||
@ -416,21 +357,6 @@ void QskGradient::setAlpha( int alpha )
|
||||
m_isDirty = true;
|
||||
}
|
||||
|
||||
bool QskGradient::hasStopAt( qreal value ) const noexcept
|
||||
{
|
||||
// better use binary search TODO ...
|
||||
for ( auto& stop : m_stops )
|
||||
{
|
||||
if ( stop.position() == value )
|
||||
return true;
|
||||
|
||||
if ( stop.position() > value )
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QskGradient::reverse()
|
||||
{
|
||||
if ( isMonochrome() )
|
||||
@ -611,39 +537,6 @@ QVariant QskGradient::interpolate(
|
||||
return QVariant::fromValue( from.interpolated( to, progress ) );
|
||||
}
|
||||
|
||||
QskGradientStops QskGradient::colorStops(
|
||||
const QVector< QRgb >& rgb, bool discrete )
|
||||
{
|
||||
const int count = rgb.count();
|
||||
|
||||
if ( count == 0 )
|
||||
return QskGradientStops();
|
||||
|
||||
if ( count == 1 )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
QGradientStops QskGradient::qtStops() const
|
||||
{
|
||||
QGradientStops qstops;
|
||||
qstops.reserve( m_stops.count() );
|
||||
|
||||
for ( const auto& stop : m_stops )
|
||||
qstops += { stop.position(), stop.color() };
|
||||
|
||||
return qstops;
|
||||
}
|
||||
|
||||
void QskGradient::clearStops()
|
||||
{
|
||||
if ( !m_stops.isEmpty() )
|
||||
@ -655,9 +548,6 @@ void QskGradient::clearStops()
|
||||
|
||||
QskHashValue QskGradient::hash( QskHashValue seed ) const
|
||||
{
|
||||
if ( m_stops.isEmpty() )
|
||||
return seed;
|
||||
|
||||
const auto o = orientation();
|
||||
|
||||
auto hash = qHashBits( &o, sizeof( o ), seed );
|
||||
@ -667,7 +557,6 @@ QskHashValue QskGradient::hash( QskHashValue seed ) const
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
#include <qdebug.h>
|
||||
@ -704,13 +593,13 @@ QDebug operator<<( QDebug debug, const QskGradient& gradient )
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& s = gradient.stops();
|
||||
for ( int i = 0; i < s.count(); i++ )
|
||||
const auto& stops = gradient.stops();
|
||||
for ( int i = 0; i < stops.count(); i++ )
|
||||
{
|
||||
if ( i != 0 )
|
||||
debug << ", ";
|
||||
|
||||
debug << s[i];
|
||||
debug << stops[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,15 +98,10 @@ class QSK_EXPORT QskGradient
|
||||
|
||||
QskHashValue hash( QskHashValue seed ) const;
|
||||
|
||||
Q_INVOKABLE qreal stopAt( int index ) const;
|
||||
Q_INVOKABLE QColor colorAt( int index ) const;
|
||||
Q_INVOKABLE qreal stopAt( int index ) const noexcept;
|
||||
Q_INVOKABLE QColor colorAt( int index ) const noexcept;
|
||||
|
||||
Q_INVOKABLE int stopCount() const;
|
||||
|
||||
QGradientStops qtStops() const;
|
||||
|
||||
static QskGradientStops colorStops(
|
||||
const QVector< QRgb >&, bool discrete = false );
|
||||
Q_INVOKABLE int stopCount() const noexcept;
|
||||
|
||||
private:
|
||||
void updateStatusBits() const;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <qhashfunctions.h>
|
||||
#include <qvariant.h>
|
||||
#include <qbrush.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -94,3 +95,128 @@ QDebug operator<<( QDebug debug, const QskGradientStop& stop )
|
||||
#endif
|
||||
|
||||
#include "moc_QskGradientStop.cpp"
|
||||
|
||||
// some helper functions around QskGradientStops
|
||||
|
||||
bool qskIsVisible( const QskGradientStops& stops ) noexcept
|
||||
{
|
||||
for ( const auto& stop : stops )
|
||||
{
|
||||
const auto& c = stop.color();
|
||||
if ( c.isValid() && c.alpha() > 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool qskIsMonochrome( const QskGradientStops& stops ) noexcept
|
||||
{
|
||||
for ( int i = 1; i < stops.size(); i++ )
|
||||
{
|
||||
if ( stops[ i ].color() != stops[ 0 ].color() )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QskGradientStops qskTransparentGradientStops( const QskGradientStops& stops, qreal ratio )
|
||||
{
|
||||
auto newStops = stops;
|
||||
|
||||
for ( auto& stop : newStops )
|
||||
{
|
||||
auto c = stop.color();
|
||||
c.setAlpha( c.alpha() * ratio );
|
||||
|
||||
stop.setColor( c );
|
||||
}
|
||||
|
||||
return newStops;
|
||||
}
|
||||
|
||||
QVector< QskGradientStop > qskBuildGradientStops( const QGradientStops& qtStops )
|
||||
{
|
||||
QVector< QskGradientStop > stops;
|
||||
stops.reserve( qtStops.count() );
|
||||
|
||||
for ( const auto& s : qtStops )
|
||||
stops += QskGradientStop( s.first, s.second );
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
static inline QVector< QskGradientStop > qskCreateStops(
|
||||
const QVector< T > colors, bool discrete )
|
||||
{
|
||||
QVector< QskGradientStop > stops;
|
||||
|
||||
const auto count = colors.count();
|
||||
if ( count == 0 )
|
||||
return stops;
|
||||
|
||||
if ( count == 1 )
|
||||
{
|
||||
stops.reserve( 2 );
|
||||
|
||||
stops += QskGradientStop( 0.0, colors[0] );
|
||||
stops += QskGradientStop( 1.0, colors[0] );
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
if ( discrete )
|
||||
{
|
||||
const auto step = 1.0 / count;
|
||||
stops.reserve( 2 * count - 2 );
|
||||
|
||||
stops += QskGradientStop( 0.0, colors[0] );
|
||||
|
||||
for ( int i = 1; i < count; i++ )
|
||||
{
|
||||
const qreal pos = i * step;
|
||||
stops += QskGradientStop( pos, colors[i - 1] );
|
||||
stops += QskGradientStop( pos, colors[i] );
|
||||
}
|
||||
|
||||
stops += QskGradientStop( 1.0, colors[count - 1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto step = 1.0 / ( count - 1 );
|
||||
stops.reserve( count );
|
||||
|
||||
stops += QskGradientStop( 0.0, colors[0] );
|
||||
|
||||
for ( int i = 1; i < count - 1; i++ )
|
||||
stops += QskGradientStop( i * step, colors[i] );
|
||||
|
||||
stops += QskGradientStop( 1.0, colors[count - 1] );
|
||||
}
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
QskGradientStops qskBuildGradientStops( const QVector< QRgb >& colors, bool discrete )
|
||||
{
|
||||
return qskCreateStops( colors, discrete );
|
||||
}
|
||||
|
||||
QskGradientStops qskBuildGradientStops( const QVector< QColor >& colors, bool discrete )
|
||||
{
|
||||
return qskCreateStops( colors, discrete );
|
||||
}
|
||||
|
||||
QGradientStops qskToQGradientStops( const QskGradientStops& stops )
|
||||
{
|
||||
QGradientStops qstops;
|
||||
qstops.reserve( stops.count() );
|
||||
|
||||
for ( const auto& stop : stops )
|
||||
qstops += { stop.position(), stop.color() };
|
||||
|
||||
return qstops;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <qmetatype.h>
|
||||
#include <qvector.h>
|
||||
|
||||
typedef QPair< qreal, QColor > QGradientStop;
|
||||
|
||||
class QSK_EXPORT QskGradientStop
|
||||
{
|
||||
Q_GADGET
|
||||
@ -22,6 +24,7 @@ class QSK_EXPORT QskGradientStop
|
||||
public:
|
||||
constexpr QskGradientStop() noexcept;
|
||||
constexpr QskGradientStop( qreal position, const QColor& ) noexcept;
|
||||
constexpr QskGradientStop( const QGradientStop& ) noexcept;
|
||||
|
||||
QskGradientStop( qreal position, Qt::GlobalColor ) noexcept;
|
||||
QskGradientStop( qreal position, QRgb ) noexcept;
|
||||
@ -57,8 +60,6 @@ class QSK_EXPORT QskGradientStop
|
||||
|
||||
Q_DECLARE_METATYPE( QskGradientStop )
|
||||
|
||||
typedef QVector< QskGradientStop > QskGradientStops;
|
||||
|
||||
inline constexpr QskGradientStop::QskGradientStop() noexcept
|
||||
: m_position( -1.0 )
|
||||
{
|
||||
@ -83,6 +84,11 @@ inline QskGradientStop::QskGradientStop(
|
||||
{
|
||||
}
|
||||
|
||||
inline constexpr QskGradientStop::QskGradientStop( const QGradientStop& qtStop ) noexcept
|
||||
: QskGradientStop( qtStop.first, qtStop.second )
|
||||
{
|
||||
}
|
||||
|
||||
inline constexpr qreal QskGradientStop::position() const noexcept
|
||||
{
|
||||
return m_position;
|
||||
@ -116,4 +122,18 @@ QSK_EXPORT QDebug operator<<( QDebug, const QskGradientStop& );
|
||||
|
||||
#endif
|
||||
|
||||
typedef QVector< QskGradientStop > QskGradientStops;
|
||||
|
||||
QSK_EXPORT bool qskIsMonochrome( const QskGradientStops& ) noexcept;
|
||||
QSK_EXPORT bool qskIsVisible( const QskGradientStops& ) noexcept;
|
||||
|
||||
QSK_EXPORT QskGradientStops qskBuildGradientStops(
|
||||
const QVector< QRgb >&, bool discrete = false );
|
||||
|
||||
QSK_EXPORT QskGradientStops qskBuildGradientStops(
|
||||
const QVector< QColor >&, bool discrete = false );
|
||||
|
||||
QSK_EXPORT QskGradientStops qskBuildGradientStops( const QVector< QGradientStop >& );
|
||||
QSK_EXPORT QVector< QGradientStop > qskToQGradientStops( const QVector< QskGradientStop >& );
|
||||
|
||||
#endif
|
||||
|
@ -23,17 +23,19 @@ void QskArcRenderer::renderArc(const QRectF& rect,
|
||||
|
||||
QBrush brush;
|
||||
|
||||
const auto qStops = qskToQGradientStops( gradient.stops() );
|
||||
|
||||
if( gradient.orientation() == QskGradient::Vertical )
|
||||
{
|
||||
QRadialGradient radial( rect.center(), qMin( rect.width(), rect.height() ) );
|
||||
radial.setStops( gradient.qtStops() );
|
||||
radial.setStops( qStops );
|
||||
|
||||
brush = radial;
|
||||
}
|
||||
else
|
||||
{
|
||||
QConicalGradient conical( rect.center(), metrics.startAngle() );
|
||||
conical.setStops( gradient.qtStops() );
|
||||
conical.setStops( qStops );
|
||||
|
||||
brush = conical;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user