qskinny/src/common/QskGradient.h

220 lines
5.4 KiB
C
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_GRADIENT_H
#define QSK_GRADIENT_H
2021-09-16 10:01:53 +02:00
#include "QskGradientStop.h"
2022-03-18 16:50:34 +01:00
#include <qbrush.h>
2018-08-03 08:15:28 +02:00
#include <qmetatype.h>
2017-07-21 18:21:34 +02:00
2022-10-31 14:42:08 +01:00
class QskLinearGradient;
class QskRadialGradient;
class QskConicGradient;
class QVariant;
2017-07-21 18:21:34 +02:00
/*
Don't use QskGradientStops for definitions seen by moc
Otherwise exporting these interfaces to QML does not work.
*/
2021-09-17 13:35:11 +02:00
2017-07-21 18:21:34 +02:00
class QSK_EXPORT QskGradient
{
Q_GADGET
Q_PROPERTY( QVector< QskGradientStop > stops READ stops WRITE setStops )
2022-11-04 17:16:38 +01:00
// Q_PROPERTY( QQmlListProperty<QQuickGradientStop> stops READ stops )
2017-07-21 18:21:34 +02:00
2019-05-10 08:09:48 +02:00
Q_PROPERTY( bool valid READ isValid )
Q_PROPERTY( bool visible READ isVisible )
Q_PROPERTY( bool monochrome READ isMonochrome )
2022-11-04 17:16:38 +01:00
Q_CLASSINFO( "DefaultProperty", "stops" )
2018-08-03 08:15:28 +02:00
public:
2022-10-31 14:42:08 +01:00
enum Type
2017-07-21 18:21:34 +02:00
{
2022-10-31 14:42:08 +01:00
Stops,
Linear,
Radial,
Conic
2017-07-21 18:21:34 +02:00
};
2022-10-31 14:42:08 +01:00
Q_ENUM( Type )
2017-07-21 18:21:34 +02:00
QskGradient() noexcept = default;
QskGradient( Qt::GlobalColor );
QskGradient( QRgb );
2017-07-21 18:21:34 +02:00
QskGradient( const QColor& );
2022-10-31 14:42:08 +01:00
QskGradient( const QColor&, const QColor& );
2022-03-18 16:50:34 +01:00
QskGradient( QGradient::Preset );
2022-10-31 14:42:08 +01:00
QskGradient( const QVector< QskGradientStop >& );
2022-10-31 14:42:08 +01:00
QskGradient( const QskGradient& ) noexcept;
2017-07-21 18:21:34 +02:00
~QskGradient();
2022-10-31 14:42:08 +01:00
QskGradient& operator=( const QskGradient& ) noexcept;
bool operator==( const QskGradient& ) const noexcept;
bool operator!=( const QskGradient& ) const noexcept;
2017-07-21 18:21:34 +02:00
2022-10-31 14:42:08 +01:00
QskGradient::Type type() const noexcept;
bool isValid() const noexcept;
bool isMonochrome() const noexcept;
bool isVisible() const noexcept;
2017-07-21 18:21:34 +02:00
Q_INVOKABLE void setStops( const QVector< QskGradientStop >& );
Q_INVOKABLE const QVector< QskGradientStop >& stops() const noexcept;
2017-07-21 18:21:34 +02:00
void setStops( const QColor& );
void setStops( const QColor&, const QColor& );
void setStops( QGradient::Preset );
void clearStops();
2017-07-21 18:21:34 +02:00
Q_INVOKABLE bool hasStopAt( qreal value ) const noexcept;
Q_INVOKABLE QColor startColor() const noexcept;
Q_INVOKABLE QColor endColor() const noexcept;
void setAlpha( int alpha );
2017-07-21 18:21:34 +02:00
2022-10-31 14:42:08 +01:00
void setSpread( QGradient::Spread );
QGradient::Spread spread() const noexcept;
2020-07-31 12:42:36 +02:00
void reverse();
QskGradient reversed() const;
QskGradient interpolated( const QskGradient&, qreal value ) const;
static QVariant interpolate( const QskGradient&,
const QskGradient&, qreal progress );
2022-10-24 17:08:48 +02:00
// all stops between [from, to] with positions streched into [0,1]
QskGradient extracted( qreal from, qreal start ) const;
QskHashValue hash( QskHashValue seed ) const;
2022-10-24 16:40:47 +02:00
Q_INVOKABLE qreal stopAt( int index ) const noexcept;
Q_INVOKABLE QColor colorAt( int index ) const noexcept;
int stepCount() const noexcept;
2022-06-25 16:14:08 +02:00
2022-10-31 14:42:08 +01:00
QskLinearGradient& asLinearGradient();
const QskLinearGradient& asLinearGradient() const;
QskRadialGradient& asRadialGradient();
const QskRadialGradient& asRadialGradient() const;
QskConicGradient& asConicGradient();
const QskConicGradient& asConicGradient() const;
2019-04-18 16:11:05 +02:00
private:
2022-10-31 14:42:08 +01:00
friend class QskLinearGradient;
friend class QskRadialGradient;
friend class QskConicGradient;
QskGradient( Type ) noexcept;
QskGradient( Type, qreal, qreal, qreal, qreal ) noexcept;
void updateStatusBits() const;
private:
QVector< QskGradientStop > m_stops;
2022-10-31 14:42:08 +01:00
/*
Linear: x1, y1, x2, y2
Radial: centerX, centerY, radius, n/a
Conic: centerX, centerY, startAngle, spanAngle
*/
qreal m_values[4] = {};
Type m_type = Stops;
QGradient::Spread m_spread = QGradient::PadSpread;
mutable bool m_isDirty = false;
mutable bool m_isValid = false;
mutable bool m_isMonchrome = true;
mutable bool m_isVisible = false;
2017-07-21 18:21:34 +02:00
};
2021-09-16 10:01:53 +02:00
Q_DECLARE_METATYPE( QskGradient )
2022-10-31 14:42:08 +01:00
inline QskGradient::QskGradient( QskGradient::Type type ) noexcept
: m_type( type )
{
}
2022-10-31 14:42:08 +01:00
inline QskGradient::QskGradient( QskGradient::Type type,
qreal v1, qreal v2, qreal v3, qreal v4 ) noexcept
: m_values{ v1, v2, v3, v4 }
, m_type( type )
{
}
2022-10-31 14:42:08 +01:00
inline QskGradient::QskGradient( Qt::GlobalColor color )
: QskGradient( QColor( color ) )
{
}
2022-10-31 14:42:08 +01:00
inline QskGradient::QskGradient( QRgb rgb )
: QskGradient( QColor::fromRgba( rgb ) )
{
}
2022-10-31 14:42:08 +01:00
inline bool QskGradient::operator!=( const QskGradient& other ) const noexcept
{
2022-10-31 14:42:08 +01:00
return !( *this == other );
}
2022-10-31 14:42:08 +01:00
inline QskGradient::Type QskGradient::type() const noexcept
{
2022-10-31 14:42:08 +01:00
return m_type;
}
inline const QskGradientStops& QskGradient::stops() const noexcept
{
#if 1
/*
Returning a const& so that it is possible to write:
for ( const auto& stop : qAsConst( gradient.stops() ) )
Once we have changed QskGradientStop from QColor to QRgb
we should check if there is a better solution possible
*/
#endif
return m_stops;
}
inline QColor QskGradient::startColor() const noexcept
2017-07-21 18:21:34 +02:00
{
return m_stops.isEmpty() ? QColor() : m_stops.first().color();
2017-07-21 18:21:34 +02:00
}
inline QColor QskGradient::endColor() const noexcept
2017-07-21 18:21:34 +02:00
{
return m_stops.isEmpty() ? QColor() : m_stops.last().color();
2017-07-21 18:21:34 +02:00
}
2022-10-31 14:42:08 +01:00
inline QGradient::Spread QskGradient::spread() const noexcept
{
return m_spread;
}
2017-07-21 18:21:34 +02:00
#ifndef QT_NO_DEBUG_STREAM
2021-09-16 10:01:53 +02:00
class QDebug;
2017-07-21 18:21:34 +02:00
QSK_EXPORT QDebug operator<<( QDebug, const QskGradient& );
#endif
#endif