qskinny/src/common/QskGradient.h

285 lines
7.1 KiB
C
Raw Normal View History

2017-07-21 16:21:34 +00:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
2023-04-06 07:23:37 +00:00
* SPDX-License-Identifier: BSD-3-Clause
2017-07-21 16:21:34 +00:00
*****************************************************************************/
#ifndef QSK_GRADIENT_H
#define QSK_GRADIENT_H
2021-09-16 08:01:53 +00:00
#include "QskGradientStop.h"
2022-03-18 15:50:34 +00:00
#include <qbrush.h>
2018-08-03 06:15:28 +00:00
#include <qmetatype.h>
2017-07-21 16:21:34 +00:00
class QskLinearDirection;
class QskRadialDirection;
class QskConicDirection;
2022-10-31 13:42:08 +00:00
class QVariant;
class QGradient;
2017-07-21 16:21:34 +00:00
class QSK_EXPORT QskGradient
{
Q_GADGET
Q_PROPERTY( Type type READ type )
Q_PROPERTY( QskLinearDirection linear READ linearDirection WRITE setLinearDirection )
Q_PROPERTY( QskConicDirection conic READ conicDirection WRITE setConicDirection )
Q_PROPERTY( QskRadialDirection radial READ radialDirection WRITE setRadialDirection )
Q_PROPERTY( QskGradientStops stops READ stops WRITE setStops )
Q_PROPERTY( SpreadMode spreadMode READ spreadMode WRITE setSpreadMode )
2022-12-22 11:38:44 +00:00
Q_PROPERTY( StretchMode stretchMode READ stretchMode WRITE setStretchMode )
2017-07-21 16:21:34 +00:00
2019-05-10 06:09:48 +00:00
Q_PROPERTY( bool valid READ isValid )
Q_PROPERTY( bool visible READ isVisible )
Q_PROPERTY( bool monochrome READ isMonochrome )
2022-11-04 16:16:38 +00:00
Q_CLASSINFO( "DefaultProperty", "stops" )
2018-08-03 06:15:28 +00:00
public:
2022-10-31 13:42:08 +00:00
enum Type
2017-07-21 16:21:34 +00:00
{
2022-10-31 13:42:08 +00:00
Stops,
Linear,
Radial,
Conic
2017-07-21 16:21:34 +00:00
};
2022-10-31 13:42:08 +00:00
Q_ENUM( Type )
2017-07-21 16:21:34 +00:00
enum SpreadMode
{
PadSpread,
ReflectSpread,
RepeatSpread
};
Q_ENUM( SpreadMode )
2022-12-22 11:38:44 +00:00
enum StretchMode
{
NoStretch,
StretchToSize
};
Q_ENUM( StretchMode )
QskGradient() noexcept;
QskGradient( Qt::GlobalColor );
QskGradient( QRgb );
2017-07-21 16:21:34 +00:00
QskGradient( const QColor& );
2022-10-31 13:42:08 +00:00
QskGradient( const QColor&, const QColor& );
2022-03-18 15:50:34 +00:00
QskGradient( QGradient::Preset );
QskGradient( const QskGradientStops& );
2022-12-09 10:23:32 +00:00
QskGradient( const QGradient& );
2022-10-31 13:42:08 +00:00
QskGradient( const QskGradient& ) noexcept;
2017-07-21 16:21:34 +00:00
~QskGradient();
2022-10-31 13:42:08 +00:00
QskGradient& operator=( const QskGradient& ) noexcept;
bool operator==( const QskGradient& ) const noexcept;
bool operator!=( const QskGradient& ) const noexcept;
2017-07-21 16:21:34 +00:00
2022-10-31 13:42:08 +00:00
QskGradient::Type type() const noexcept;
void setLinearDirection( const QskLinearDirection& );
void setLinearDirection( qreal, qreal, qreal, qreal );
void setLinearDirection( Qt::Orientation );
QskLinearDirection linearDirection() const;
void setRadialDirection( const QskRadialDirection& );
void setRadialDirection( const qreal x, qreal y, qreal radius );
void setRadialDirection( const qreal x, qreal y, qreal radiusX, qreal radiusY );
QskRadialDirection radialDirection() const;
void setConicDirection( qreal, qreal );
void setConicDirection( qreal, qreal, qreal, qreal = 360.0 );
void setConicDirection( const QskConicDirection& );
QskConicDirection conicDirection() const;
2022-11-29 09:59:09 +00:00
void setDirection( Type );
void resetDirection();
bool isValid() const noexcept;
bool isMonochrome() const noexcept;
bool isVisible() const noexcept;
2017-07-21 16:21:34 +00:00
void setStops( const QskGradientStops& );
const QskGradientStops& stops() const noexcept;
2017-07-21 16:21:34 +00:00
2022-11-16 15:19:19 +00:00
void setStops( const QRgb );
void setStops( Qt::GlobalColor );
void setStops( const QColor& );
2022-11-16 15:19:19 +00:00
void setStops( const QColor&, const QColor& );
void setStops( QGradient::Preset );
void clearStops();
2017-07-21 16:21:34 +00:00
Q_INVOKABLE bool hasStopAt( qreal value ) const noexcept;
Q_INVOKABLE QColor startColor() const noexcept;
Q_INVOKABLE QColor endColor() const noexcept;
QRgb rgbStart() const;
QRgb rgbEnd() const;
void setAlpha( int alpha );
2017-07-21 16:21:34 +00:00
void setSpreadMode( SpreadMode );
SpreadMode spreadMode() const noexcept;
2022-10-31 13:42:08 +00:00
2022-12-22 11:38:44 +00:00
void setStretchMode( StretchMode );
StretchMode stretchMode() const noexcept;
2020-07-31 10:42:36 +00:00
void reverse();
QskGradient reversed() const;
QskGradient interpolated( const QskGradient&, qreal value ) const;
2022-12-22 11:38:44 +00:00
void stretchTo( const QRectF& );
QskGradient stretchedTo( const QSizeF& ) const;
QskGradient stretchedTo( const QRectF& ) const;
2022-12-22 19:13:45 +00:00
QskGradient effectiveGradient() const;
static QVariant interpolate( const QskGradient&,
const QskGradient&, qreal progress );
2022-10-24 15:08:48 +00:00
// all stops between [from, to] with positions streched into [0,1]
QskGradient extracted( qreal from, qreal start ) const;
2022-12-20 14:42:36 +00:00
QskHashValue hash( QskHashValue seed = 0 ) const;
2022-10-24 14:40:47 +00:00
Q_INVOKABLE qreal stopAt( int index ) const noexcept;
Q_INVOKABLE QColor colorAt( int index ) const noexcept;
int stepCount() const noexcept;
2022-06-25 14:14:08 +00:00
2022-12-09 10:23:32 +00:00
QGradient toQGradient() const;
2019-04-18 14:11:05 +00:00
private:
void updateStatusBits() const;
private:
QskGradientStops m_stops;
2022-10-31 13:42:08 +00:00
/*
Linear: x1, y1, x2, y2
Radial: centerX, centerY, radiusX, radiusY
2022-10-31 13:42:08 +00:00
Conic: centerX, centerY, startAngle, spanAngle
*/
qreal m_values[4] = {};
unsigned int m_type : 3;
unsigned int m_spreadMode : 3;
unsigned int m_stretchMode : 3;
mutable bool m_isDirty : 1;
mutable bool m_isValid : 1;
mutable bool m_isMonchrome : 1;
mutable bool m_isVisible : 1;
2017-07-21 16:21:34 +00:00
};
2021-09-16 08:01:53 +00:00
Q_DECLARE_METATYPE( QskGradient )
inline QskGradient::QskGradient() noexcept
: m_type( Stops )
, m_spreadMode( PadSpread )
, m_stretchMode( StretchToSize )
, m_isDirty( false )
, m_isValid( false )
, m_isMonchrome( true )
, m_isVisible( false )
{
}
2022-10-31 13:42:08 +00:00
inline QskGradient::QskGradient( Qt::GlobalColor color )
: QskGradient( QColor( color ) )
{
}
2022-10-31 13:42:08 +00:00
inline QskGradient::QskGradient( QRgb rgb )
: QskGradient( QColor::fromRgba( rgb ) )
{
}
2022-10-31 13:42:08 +00:00
inline bool QskGradient::operator!=( const QskGradient& other ) const noexcept
{
2022-10-31 13:42:08 +00:00
return !( *this == other );
}
2022-10-31 13:42:08 +00:00
inline QskGradient::Type QskGradient::type() const noexcept
{
return static_cast< Type >( 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;
}
2022-11-16 15:19:19 +00:00
inline void QskGradient::setStops( QRgb rgb )
{
setStops( QColor::fromRgba( rgb ) );
}
inline void QskGradient::setStops( Qt::GlobalColor color )
{
setStops( QColor( color ) );
}
inline QColor QskGradient::startColor() const noexcept
2017-07-21 16:21:34 +00:00
{
return m_stops.isEmpty() ? QColor() : m_stops.first().color();
2017-07-21 16:21:34 +00:00
}
inline QColor QskGradient::endColor() const noexcept
2017-07-21 16:21:34 +00:00
{
return m_stops.isEmpty() ? QColor() : m_stops.last().color();
2017-07-21 16:21:34 +00:00
}
inline QRgb QskGradient::rgbStart() const
{
return m_stops.isEmpty() ? qRgba( 0, 0, 0, 255 ) : m_stops.first().rgb();
}
inline QRgb QskGradient::rgbEnd() const
{
return m_stops.isEmpty() ? qRgba( 0, 0, 0, 255 ) : m_stops.last().rgb();
}
inline QskGradient::SpreadMode QskGradient::spreadMode() const noexcept
2022-10-31 13:42:08 +00:00
{
return static_cast< SpreadMode >( m_spreadMode );
2022-10-31 13:42:08 +00:00
}
2022-12-22 11:38:44 +00:00
inline QskGradient::StretchMode QskGradient::stretchMode() const noexcept
{
return static_cast< StretchMode >( m_stretchMode );
2022-12-22 11:38:44 +00:00
}
2017-07-21 16:21:34 +00:00
#ifndef QT_NO_DEBUG_STREAM
2021-09-16 08:01:53 +00:00
class QDebug;
2017-07-21 16:21:34 +00:00
QSK_EXPORT QDebug operator<<( QDebug, const QskGradient& );
#endif
#endif