shapes example improved, linear/radial/conic gradients shown
This commit is contained in:
parent
f175f2b721
commit
b1bf367fa6
238
playground/shapes/Gradient.cpp
Normal file
238
playground/shapes/Gradient.cpp
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* This file may be used under the terms of the 3-clause BSD License
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "Gradient.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
bool Gradient::operator==( const Gradient& other ) const noexcept
|
||||||
|
{
|
||||||
|
if ( m_type != other.m_type )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if ( m_type == QGradient::NoGradient )
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ( m_spread == other.m_spread )
|
||||||
|
&& ( m_values[0] == other.m_values[0] )
|
||||||
|
&& ( m_values[1] == other.m_values[1] )
|
||||||
|
&& ( m_values[2] == other.m_values[2] )
|
||||||
|
&& ( m_values[3] == other.m_values[3] )
|
||||||
|
&& ( m_values[4] == other.m_values[4] )
|
||||||
|
&& ( m_values[5] == other.m_values[5] )
|
||||||
|
&& ( m_stops == other.m_stops );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gradient::setStops( QGradient::Preset preset )
|
||||||
|
{
|
||||||
|
setStops( QGradient( preset ).stops() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gradient::setStops( const QGradientStops &stops )
|
||||||
|
{
|
||||||
|
m_stops.resize( stops.count() );
|
||||||
|
|
||||||
|
for ( int i = 0; i < stops.count(); i++ )
|
||||||
|
m_stops[i] = { stops[i].first, stops[i].second };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gradient::setStops( const QVector< QskGradientStop >& stops )
|
||||||
|
{
|
||||||
|
m_stops = stops;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gradient::setStops( const QColor& c1, const QColor& c2 )
|
||||||
|
{
|
||||||
|
m_stops.resize( 2 );
|
||||||
|
m_stops[0] = QskGradientStop( 0.0, c1 );
|
||||||
|
m_stops[1] = QskGradientStop( 1.0, c2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
QGradientStops Gradient::qtStops() const
|
||||||
|
{
|
||||||
|
QGradientStops qstops;
|
||||||
|
qstops.reserve( m_stops.count() );
|
||||||
|
|
||||||
|
for ( const auto& stop : m_stops )
|
||||||
|
qstops += { stop.position(), stop.color() };
|
||||||
|
|
||||||
|
return qstops;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gradient::setSpread( QGradient::Spread spread )
|
||||||
|
{
|
||||||
|
m_spread = spread;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Gradient::isMonochrome() const
|
||||||
|
{
|
||||||
|
if ( m_type != QGradient::NoGradient )
|
||||||
|
{
|
||||||
|
for ( int i = 1; i < m_stops.size(); i++ )
|
||||||
|
{
|
||||||
|
if ( m_stops[ i ].color() != m_stops[ 0 ].color() )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Gradient::isVisible() const
|
||||||
|
{
|
||||||
|
if ( m_type != QGradient::NoGradient )
|
||||||
|
{
|
||||||
|
for ( const auto& stop : m_stops )
|
||||||
|
{
|
||||||
|
const auto& c = stop.color();
|
||||||
|
if ( c.isValid() && c.alpha() > 0 )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
|
||||||
|
#include <qdebug.h>
|
||||||
|
|
||||||
|
QDebug operator<<( QDebug debug, const Gradient& gradient )
|
||||||
|
{
|
||||||
|
QDebugStateSaver saver( debug );
|
||||||
|
debug.nospace();
|
||||||
|
|
||||||
|
debug << "Gradient";
|
||||||
|
|
||||||
|
if ( !gradient.isValid() )
|
||||||
|
{
|
||||||
|
debug << "()";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug << "( ";
|
||||||
|
|
||||||
|
debug << gradient.type();
|
||||||
|
// ...
|
||||||
|
|
||||||
|
debug << " )";
|
||||||
|
}
|
||||||
|
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LinearGradient& Gradient::asLinearGradient()
|
||||||
|
{
|
||||||
|
assert( m_type == QGradient::LinearGradient );
|
||||||
|
return *reinterpret_cast< LinearGradient* >( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
const LinearGradient& Gradient::asLinearGradient() const
|
||||||
|
{
|
||||||
|
assert( m_type == QGradient::LinearGradient );
|
||||||
|
return *reinterpret_cast< const LinearGradient* >( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
RadialGradient& Gradient::asRadialGradient()
|
||||||
|
{
|
||||||
|
assert( m_type == QGradient::RadialGradient );
|
||||||
|
return *reinterpret_cast< RadialGradient* >( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
const RadialGradient& Gradient::asRadialGradient() const
|
||||||
|
{
|
||||||
|
assert( m_type == QGradient::RadialGradient );
|
||||||
|
return *reinterpret_cast< const RadialGradient* >( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
ConicGradient& Gradient::asConicGradient()
|
||||||
|
{
|
||||||
|
assert( m_type == QGradient::ConicalGradient );
|
||||||
|
return *reinterpret_cast< ConicGradient* >( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConicGradient& Gradient::asConicGradient() const
|
||||||
|
{
|
||||||
|
assert( m_type == QGradient::ConicalGradient );
|
||||||
|
return *reinterpret_cast< const ConicGradient* >( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearGradient::setStart( const QPointF& pos ) noexcept
|
||||||
|
{
|
||||||
|
m_values[0] = pos.x();
|
||||||
|
m_values[1] = pos.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearGradient::setStart( qreal x, qreal y ) noexcept
|
||||||
|
{
|
||||||
|
m_values[0] = x;
|
||||||
|
m_values[1] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearGradient::setStop( const QPointF& pos ) noexcept
|
||||||
|
{
|
||||||
|
m_values[2] = pos.x();
|
||||||
|
m_values[3] = pos.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearGradient::setStop( qreal x, qreal y ) noexcept
|
||||||
|
{
|
||||||
|
m_values[2] = x;
|
||||||
|
m_values[3] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadialGradient::setCenter( const QPointF& center ) noexcept
|
||||||
|
{
|
||||||
|
m_values[0] = center.x();
|
||||||
|
m_values[1] = center.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadialGradient::setCenter( qreal x, qreal y ) noexcept
|
||||||
|
{
|
||||||
|
m_values[0] = x;
|
||||||
|
m_values[1] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadialGradient::setFocalPoint( const QPointF& focalPoint ) noexcept
|
||||||
|
{
|
||||||
|
m_values[3] = focalPoint.x();
|
||||||
|
m_values[4] = focalPoint.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadialGradient::setFocalPoint( qreal x, qreal y ) noexcept
|
||||||
|
{
|
||||||
|
m_values[3] = x;
|
||||||
|
m_values[4] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void RadialGradient::setCenterRadius( qreal radius ) noexcept
|
||||||
|
{
|
||||||
|
m_values[2] = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void RadialGradient::setFocalRadius( qreal radius ) noexcept
|
||||||
|
{
|
||||||
|
m_values[5] = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConicGradient::setCenter( const QPointF& center ) noexcept
|
||||||
|
{
|
||||||
|
m_values[0] = center.x();
|
||||||
|
m_values[1] = center.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConicGradient::setCenter( qreal x, qreal y ) noexcept
|
||||||
|
{
|
||||||
|
m_values[0] = x;
|
||||||
|
m_values[1] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConicGradient::setDegrees( qreal degrees ) noexcept
|
||||||
|
{
|
||||||
|
m_values[2] = degrees;
|
||||||
|
}
|
290
playground/shapes/Gradient.h
Normal file
290
playground/shapes/Gradient.h
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* This file may be used under the terms of the 3-clause BSD License
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
These definitions will be somehow adjusted and merged with QskGradient
|
||||||
|
and moved to the lib then.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QskControl.h>
|
||||||
|
#include <QskGradientStop.h>
|
||||||
|
#include <qbrush.h>
|
||||||
|
#include <qpoint.h>
|
||||||
|
|
||||||
|
class LinearGradient;
|
||||||
|
class RadialGradient;
|
||||||
|
class ConicGradient;
|
||||||
|
|
||||||
|
class Gradient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr Gradient() noexcept = default;
|
||||||
|
Gradient( const Gradient& ) noexcept = default;
|
||||||
|
|
||||||
|
bool operator==( const Gradient& ) const noexcept;
|
||||||
|
bool operator!=( const Gradient& ) const noexcept;
|
||||||
|
|
||||||
|
constexpr QGradient::Type type() const noexcept;
|
||||||
|
|
||||||
|
constexpr bool isValid() const noexcept;
|
||||||
|
|
||||||
|
bool isMonochrome() const;
|
||||||
|
bool isVisible() const;
|
||||||
|
|
||||||
|
void setStops( const QVector< QskGradientStop >& );
|
||||||
|
const QVector< QskGradientStop >& stops() const noexcept;
|
||||||
|
|
||||||
|
void setStops( QGradient::Preset );
|
||||||
|
void setStops( const QGradientStops& );
|
||||||
|
void setStops( const QColor&, const QColor& );
|
||||||
|
QGradientStops qtStops() const;
|
||||||
|
|
||||||
|
void setSpread( QGradient::Spread );
|
||||||
|
constexpr QGradient::Spread spread() const noexcept;
|
||||||
|
|
||||||
|
LinearGradient& asLinearGradient();
|
||||||
|
const LinearGradient& asLinearGradient() const;
|
||||||
|
|
||||||
|
RadialGradient& asRadialGradient();
|
||||||
|
const RadialGradient& asRadialGradient() const;
|
||||||
|
|
||||||
|
ConicGradient& asConicGradient();
|
||||||
|
const ConicGradient& asConicGradient() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class LinearGradient;
|
||||||
|
friend class RadialGradient;
|
||||||
|
friend class ConicGradient;
|
||||||
|
|
||||||
|
constexpr Gradient( QGradient::Type ) noexcept;
|
||||||
|
constexpr Gradient( QGradient::Type,
|
||||||
|
qreal, qreal, qreal, qreal, qreal, qreal ) noexcept;
|
||||||
|
|
||||||
|
QVector< QskGradientStop > m_stops;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Linear: x1, y1, x2, y2, n/a, n/a
|
||||||
|
Radial: centerX, centerY, centerRadius, focalX, focalY, focalRadius
|
||||||
|
Conic: centerX, centerY, degrees, n/a, n/a, n/a
|
||||||
|
*/
|
||||||
|
qreal m_values[6] = {};
|
||||||
|
|
||||||
|
QGradient::Type m_type = QGradient::NoGradient;
|
||||||
|
QGradient::Spread m_spread = QGradient::PadSpread;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LinearGradient : public Gradient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr LinearGradient() noexcept;
|
||||||
|
constexpr LinearGradient( const QPointF&, const QPointF& ) noexcept;
|
||||||
|
constexpr LinearGradient( qreal x1, qreal y1, qreal x2, qreal y2 ) noexcept;
|
||||||
|
|
||||||
|
void setStart(const QPointF& start) noexcept;
|
||||||
|
void setStart( qreal x, qreal y ) noexcept;
|
||||||
|
|
||||||
|
void setStop(const QPointF& start) noexcept;
|
||||||
|
void setStop( qreal x, qreal y ) noexcept;
|
||||||
|
|
||||||
|
constexpr QPointF start() const noexcept;
|
||||||
|
constexpr QPointF stop() const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
|
||||||
|
class QDebug;
|
||||||
|
QDebug operator<<( QDebug, const Gradient& );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class RadialGradient : public Gradient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr RadialGradient() noexcept;
|
||||||
|
|
||||||
|
constexpr RadialGradient( const QPointF& center, qreal radius ) noexcept;
|
||||||
|
constexpr RadialGradient( qreal cx, qreal cy, qreal radius ) noexcept;
|
||||||
|
|
||||||
|
constexpr RadialGradient( const QPointF& center, qreal centerRadius,
|
||||||
|
const QPointF& focalPoint, qreal focalRadius = 0.0 ) noexcept;
|
||||||
|
|
||||||
|
constexpr RadialGradient(qreal cx, qreal cy, qreal centerRadius,
|
||||||
|
qreal fx, qreal fy, qreal focalRadius = 0.0 ) noexcept;
|
||||||
|
|
||||||
|
constexpr QPointF center() const noexcept;
|
||||||
|
void setCenter(const QPointF& center) noexcept;
|
||||||
|
void setCenter(qreal x, qreal y) noexcept;
|
||||||
|
|
||||||
|
constexpr QPointF focalPoint() const noexcept;
|
||||||
|
void setFocalPoint( const QPointF& focalPoint ) noexcept;
|
||||||
|
void setFocalPoint( qreal x, qreal y ) noexcept;
|
||||||
|
|
||||||
|
constexpr qreal centerRadius() const noexcept;
|
||||||
|
constexpr void setCenterRadius( qreal radius ) noexcept;
|
||||||
|
|
||||||
|
constexpr qreal focalRadius() const noexcept;
|
||||||
|
constexpr void setFocalRadius( qreal radius ) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConicGradient : public Gradient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr ConicGradient() noexcept;
|
||||||
|
constexpr ConicGradient( const QPointF&, qreal degrees ) noexcept;
|
||||||
|
constexpr ConicGradient( qreal cx, qreal cy, qreal degrees ) noexcept;
|
||||||
|
|
||||||
|
constexpr QPointF center() const noexcept;
|
||||||
|
void setCenter(const QPointF& center) noexcept;
|
||||||
|
void setCenter(qreal x, qreal y) noexcept;
|
||||||
|
|
||||||
|
constexpr qreal degrees() const noexcept;
|
||||||
|
void setDegrees(qreal ) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Gradient::Gradient( QGradient::Type type ) noexcept
|
||||||
|
: m_type( type )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Gradient::Gradient( QGradient::Type type,
|
||||||
|
qreal v1, qreal v2, qreal v3,
|
||||||
|
qreal v4 = 0.0, qreal v5 = 0.0, qreal v6 = 0.0 ) noexcept
|
||||||
|
: m_values{ v1, v2, v3, v4, v5, v6 }
|
||||||
|
, m_type( type )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Gradient::operator!=( const Gradient& other ) const noexcept
|
||||||
|
{
|
||||||
|
return !( *this == other );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr QGradient::Type Gradient::type() const noexcept
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool Gradient::isValid() const noexcept
|
||||||
|
{
|
||||||
|
return m_type != QGradient::NoGradient;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const QVector< QskGradientStop >& Gradient::stops() const noexcept
|
||||||
|
{
|
||||||
|
return m_stops;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr QGradient::Spread Gradient::spread() const noexcept
|
||||||
|
{
|
||||||
|
return m_spread;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr LinearGradient::LinearGradient() noexcept
|
||||||
|
: Gradient( QGradient::LinearGradient, 0.0, 0.0, 1.0, 1.0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr LinearGradient::LinearGradient(
|
||||||
|
const QPointF& start, const QPointF& stop ) noexcept
|
||||||
|
: LinearGradient( start.x(), start.y(), stop.x(), stop.y() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr LinearGradient::LinearGradient(
|
||||||
|
qreal x1, qreal y1, qreal x2, qreal y2 ) noexcept
|
||||||
|
: Gradient( QGradient::LinearGradient, x1, y1, x2, y2 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr QPointF LinearGradient::start() const noexcept
|
||||||
|
{
|
||||||
|
return QPointF( m_values[0], m_values[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr QPointF LinearGradient::stop() const noexcept
|
||||||
|
{
|
||||||
|
return QPointF( m_values[2], m_values[3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr RadialGradient::RadialGradient() noexcept
|
||||||
|
: Gradient( QGradient::RadialGradient, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr RadialGradient::RadialGradient(
|
||||||
|
const QPointF& center, qreal radius,
|
||||||
|
const QPointF& focalPoint, qreal focalRadius ) noexcept
|
||||||
|
: RadialGradient( center.x(), center.y(), radius,
|
||||||
|
focalPoint.x(), focalPoint.y(), focalRadius )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr RadialGradient::RadialGradient(
|
||||||
|
const QPointF& center, qreal radius ) noexcept
|
||||||
|
: RadialGradient( center.x(), center.y(), radius )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr RadialGradient::RadialGradient(
|
||||||
|
qreal cx, qreal cy, qreal radius ) noexcept
|
||||||
|
: RadialGradient( cx, cy, radius, cx, cy, 0.0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr RadialGradient::RadialGradient(
|
||||||
|
qreal cx, qreal cy, qreal radius,
|
||||||
|
qreal fx, qreal fy, qreal focalRadius ) noexcept
|
||||||
|
: Gradient( QGradient::RadialGradient, cx, cy, radius, fx, fy, focalRadius )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr QPointF RadialGradient::center() const noexcept
|
||||||
|
{
|
||||||
|
return QPointF( m_values[0], m_values[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr qreal RadialGradient::centerRadius() const noexcept
|
||||||
|
{
|
||||||
|
return m_values[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr QPointF RadialGradient::focalPoint() const noexcept
|
||||||
|
{
|
||||||
|
return QPointF( m_values[3], m_values[4] );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr qreal RadialGradient::focalRadius() const noexcept
|
||||||
|
{
|
||||||
|
return m_values[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr ConicGradient::ConicGradient() noexcept
|
||||||
|
: Gradient( QGradient::ConicalGradient, 0.0, 0.0, 0.0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr ConicGradient::ConicGradient(
|
||||||
|
const QPointF& center, qreal degrees ) noexcept
|
||||||
|
: ConicGradient( center.x(), center.y(), degrees )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr ConicGradient::ConicGradient(
|
||||||
|
qreal cx, qreal cy, qreal degrees ) noexcept
|
||||||
|
: Gradient( QGradient::ConicalGradient, cx, cy, degrees )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr QPointF ConicGradient::center() const noexcept
|
||||||
|
{
|
||||||
|
return QPointF( m_values[0], m_values[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr qreal ConicGradient::degrees() const noexcept
|
||||||
|
{
|
||||||
|
return m_values[2];
|
||||||
|
}
|
@ -42,10 +42,93 @@ static inline qreal effectivePenWidth(
|
|||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class ShapeNode : public QskShapeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void updateShape( const QPainterPath& path,
|
||||||
|
const QTransform& transform, const QRectF& rect, const Gradient& gradient )
|
||||||
|
{
|
||||||
|
if ( gradient.isMonochrome() )
|
||||||
|
{
|
||||||
|
updateNode( path, transform, gradient.stops().first().color() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Stupid code to map Gradient -> QGradient
|
||||||
|
Can be removed once Gradient has been merged into QskGradient.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch( static_cast<int>( gradient.type() ) )
|
||||||
|
{
|
||||||
|
case QGradient::LinearGradient:
|
||||||
|
{
|
||||||
|
const auto& g = gradient.asLinearGradient();
|
||||||
|
|
||||||
|
const qreal x1 = rect.left() + g.start().x() * rect.width();
|
||||||
|
const qreal y1 = rect.top() + g.start().y() * rect.height();
|
||||||
|
|
||||||
|
const qreal x2 = rect.left() + g.stop().x() * rect.width();
|
||||||
|
const qreal y2 = rect.top() + g.stop().y() * rect.height();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
QTransform t2( rect.width(), 0, 0, rect.height(), rect.x(), rect.y());
|
||||||
|
#endif
|
||||||
|
QLinearGradient qgradient( x1, y1, x2, y2 );
|
||||||
|
qgradient.setSpread( g.spread() );
|
||||||
|
qgradient.setStops( g.qtStops() );
|
||||||
|
|
||||||
|
updateNode( path, transform, &qgradient );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QGradient::RadialGradient:
|
||||||
|
{
|
||||||
|
const auto& g = gradient.asRadialGradient();
|
||||||
|
|
||||||
|
const qreal x = rect.left() + g.center().x() * rect.width();
|
||||||
|
const qreal y = rect.top() + g.center().y() * rect.height();
|
||||||
|
const qreal r = g.centerRadius() * qMin( rect.width(), rect.height() );
|
||||||
|
|
||||||
|
const qreal fx = rect.left() + g.focalPoint().x() * rect.width();
|
||||||
|
const qreal fy = rect.top() + g.focalPoint().y() * rect.height();
|
||||||
|
const qreal fr = g.focalRadius() * qMin( rect.width(), rect.height() );
|
||||||
|
|
||||||
|
QRadialGradient qgradient( x, y, r, fx, fy, fr );
|
||||||
|
qgradient.setSpread( g.spread() );
|
||||||
|
qgradient.setStops( g.qtStops() );
|
||||||
|
|
||||||
|
updateNode( path, transform, &qgradient );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QGradient::ConicalGradient:
|
||||||
|
{
|
||||||
|
const auto& g = gradient.asConicGradient();
|
||||||
|
|
||||||
|
const qreal x = rect.left() + g.center().x() * rect.width();
|
||||||
|
const qreal y = rect.top() + g.center().y() * rect.height();
|
||||||
|
|
||||||
|
QConicalGradient qgradient( x, y, g.degrees() );
|
||||||
|
//qgradient.setSpread( g.spread() );
|
||||||
|
qgradient.setStops( g.qtStops() );
|
||||||
|
|
||||||
|
updateNode( path, transform, &qgradient );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ShapeItem::ShapeItem( QQuickItem* parent )
|
ShapeItem::ShapeItem( QQuickItem* parent )
|
||||||
: QskControl( parent )
|
: QskControl( parent )
|
||||||
{
|
{
|
||||||
setMargins( 20 );
|
setMargins( 20 );
|
||||||
|
setSizePolicy( QskSizePolicy::Ignored, QskSizePolicy::Ignored );
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeItem::~ShapeItem()
|
ShapeItem::~ShapeItem()
|
||||||
@ -66,25 +149,18 @@ QPen ShapeItem::pen() const
|
|||||||
return m_pen;
|
return m_pen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapeItem::setGradient( const QColor& c1, const QColor& c2 )
|
void ShapeItem::setGradient( const Gradient& gradient )
|
||||||
{
|
{
|
||||||
if ( c1 != m_fillColor[0] || c2 != m_fillColor[1] )
|
if ( gradient != m_gradient )
|
||||||
{
|
{
|
||||||
m_fillColor[0] = c1;
|
m_gradient = gradient;
|
||||||
m_fillColor[1] = c2;
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapeItem::setGradient( QGradient::Preset preset )
|
const Gradient& ShapeItem::gradient() const
|
||||||
{
|
{
|
||||||
const auto stops = QGradient( preset ).stops();
|
return m_gradient;
|
||||||
if ( !stops.isEmpty() )
|
|
||||||
{
|
|
||||||
// gradients with more than 2 clors do not work TODO ...
|
|
||||||
setGradient( stops.first().second, stops.last().second );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapeItem::setPath( const QPainterPath& path )
|
void ShapeItem::setPath( const QPainterPath& path )
|
||||||
@ -112,7 +188,7 @@ void ShapeItem::updateNode( QSGNode* parentNode )
|
|||||||
const auto rect = contentsRect();
|
const auto rect = contentsRect();
|
||||||
const auto pathRect = m_path.controlPointRect();
|
const auto pathRect = m_path.controlPointRect();
|
||||||
|
|
||||||
auto fillNode = static_cast< QskShapeNode* >(
|
auto fillNode = static_cast< ShapeNode* >(
|
||||||
QskSGNode::findChildNode( parentNode, FillRole ) );
|
QskSGNode::findChildNode( parentNode, FillRole ) );
|
||||||
|
|
||||||
auto borderNode = static_cast< QskStrokeNode* >(
|
auto borderNode = static_cast< QskStrokeNode* >(
|
||||||
@ -126,11 +202,11 @@ void ShapeItem::updateNode( QSGNode* parentNode )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ::isVisible( m_fillColor[0] ) || ::isVisible( m_fillColor[1] ) )
|
if ( m_gradient.isVisible() )
|
||||||
{
|
{
|
||||||
if ( fillNode == nullptr )
|
if ( fillNode == nullptr )
|
||||||
{
|
{
|
||||||
fillNode = new QskShapeNode;
|
fillNode = new ShapeNode;
|
||||||
QskSGNode::setNodeRole( fillNode, FillRole );
|
QskSGNode::setNodeRole( fillNode, FillRole );
|
||||||
|
|
||||||
parentNode->prependChildNode( fillNode );
|
parentNode->prependChildNode( fillNode );
|
||||||
@ -144,21 +220,7 @@ void ShapeItem::updateNode( QSGNode* parentNode )
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto transform = ::transformForRects( pathRect, fillRect );
|
const auto transform = ::transformForRects( pathRect, fillRect );
|
||||||
|
fillNode->updateShape( m_path, transform, fillRect, m_gradient );
|
||||||
if ( m_fillColor[0] != m_fillColor[1] )
|
|
||||||
{
|
|
||||||
QLinearGradient gradient;
|
|
||||||
gradient.setStart( rect.topLeft() );
|
|
||||||
gradient.setFinalStop( rect.bottomRight() );
|
|
||||||
gradient.setColorAt( 0.0, m_fillColor[0] );
|
|
||||||
gradient.setColorAt( 1.0, m_fillColor[1] );
|
|
||||||
|
|
||||||
fillNode->updateNode( m_path, transform, &gradient );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fillNode->updateNode( m_path, transform, m_fillColor[0] );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Gradient.h"
|
||||||
#include <QskControl.h>
|
#include <QskControl.h>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
#include <QGradient>
|
|
||||||
|
class Gradient;
|
||||||
|
|
||||||
class ShapeItem : public QskControl
|
class ShapeItem : public QskControl
|
||||||
{
|
{
|
||||||
@ -21,8 +23,8 @@ class ShapeItem : public QskControl
|
|||||||
void setPen( const QPen& );
|
void setPen( const QPen& );
|
||||||
QPen pen() const;
|
QPen pen() const;
|
||||||
|
|
||||||
void setGradient( const QColor&, const QColor& );
|
void setGradient( const Gradient& );
|
||||||
void setGradient( QGradient::Preset );
|
const Gradient& gradient() const;
|
||||||
|
|
||||||
void setPath( const QPainterPath& );
|
void setPath( const QPainterPath& );
|
||||||
QPainterPath path() const;
|
QPainterPath path() const;
|
||||||
@ -34,6 +36,6 @@ class ShapeItem : public QskControl
|
|||||||
QPainterPath scaledPath( const QRectF& ) const;
|
QPainterPath scaledPath( const QRectF& ) const;
|
||||||
|
|
||||||
QPen m_pen;
|
QPen m_pen;
|
||||||
QColor m_fillColor[2];
|
Gradient m_gradient;
|
||||||
QPainterPath m_path;
|
QPainterPath m_path;
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <QskObjectCounter.h>
|
#include <QskObjectCounter.h>
|
||||||
#include <QskWindow.h>
|
#include <QskWindow.h>
|
||||||
#include <QskRgbValue.h>
|
#include <QskRgbValue.h>
|
||||||
|
#include <QskLinearBox.h>
|
||||||
|
|
||||||
#include <SkinnyShortcut.h>
|
#include <SkinnyShortcut.h>
|
||||||
#include <SkinnyShapeFactory.h>
|
#include <SkinnyShapeFactory.h>
|
||||||
@ -42,6 +43,68 @@ namespace
|
|||||||
setColor( QskRgb::toTransparent( color(), alpha ) );
|
setColor( QskRgb::toTransparent( color(), alpha ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Box : public QskLinearBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Box( QQuickItem* parent = nullptr )
|
||||||
|
: QskLinearBox( Qt::Horizontal, 2, parent )
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto shapeItem = new ShapeItem( this );
|
||||||
|
|
||||||
|
shapeItem->setPath( path( SkinnyShapeFactory::Hexagon ) );
|
||||||
|
shapeItem->setPen( Pen( QColorConstants::Svg::indigo ) );
|
||||||
|
|
||||||
|
LinearGradient gradient( 0.0, 0.0, 0.2, 0.5 );
|
||||||
|
gradient.setSpread( QGradient::ReflectSpread );
|
||||||
|
gradient.setStops( QGradient::PhoenixStart );
|
||||||
|
|
||||||
|
shapeItem->setGradient( gradient );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto shapeItem = new ShapeItem( this );
|
||||||
|
|
||||||
|
shapeItem->setPath( path( SkinnyShapeFactory::Ellipse ) );
|
||||||
|
|
||||||
|
RadialGradient gradient( 0.5, 0.5, 0.5 );
|
||||||
|
gradient.setSpread( QGradient::RepeatSpread );
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
QVector< QskGradientStop > stops;
|
||||||
|
|
||||||
|
stops += QskGradientStop( 0.0, Qt::green );
|
||||||
|
stops += QskGradientStop( 0.2, Qt::green );
|
||||||
|
stops += QskGradientStop( 0.201, Qt::red );
|
||||||
|
stops += QskGradientStop( 0.4, Qt::red );
|
||||||
|
stops += QskGradientStop( 0.401, Qt::yellow );
|
||||||
|
stops += QskGradientStop( 0.6, Qt::yellow );
|
||||||
|
stops += QskGradientStop( 0.601, Qt::cyan );
|
||||||
|
stops += QskGradientStop( 0.8, Qt::cyan );
|
||||||
|
stops += QskGradientStop( 0.801, Qt::darkCyan );
|
||||||
|
stops += QskGradientStop( 1.0, Qt::darkCyan );
|
||||||
|
|
||||||
|
gradient.setStops( stops );
|
||||||
|
#else
|
||||||
|
gradient.setStops( QGradient::DirtyBeauty );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shapeItem->setGradient( gradient );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto shapeItem = new ShapeItem( this );
|
||||||
|
|
||||||
|
shapeItem->setPath( path( SkinnyShapeFactory::Arc ) );
|
||||||
|
|
||||||
|
ConicGradient gradient( 0.5, 0.5, -60.0 );
|
||||||
|
gradient.setStops( QGradient::BurningSpring );
|
||||||
|
|
||||||
|
shapeItem->setGradient( gradient );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
int main( int argc, char* argv[] )
|
int main( int argc, char* argv[] )
|
||||||
@ -56,16 +119,8 @@ int main( int argc, char* argv[] )
|
|||||||
|
|
||||||
QskWindow window;
|
QskWindow window;
|
||||||
window.setColor( Qt::gray );
|
window.setColor( Qt::gray );
|
||||||
|
window.addItem( new Box() );
|
||||||
auto shapeItem = new ShapeItem();
|
window.resize( 800, 600 );
|
||||||
|
|
||||||
shapeItem->setPath( path( SkinnyShapeFactory::Hexagon ) );
|
|
||||||
|
|
||||||
shapeItem->setPen( Pen( QColorConstants::Svg::indigo ) );
|
|
||||||
shapeItem->setGradient( QGradient::PhoenixStart );
|
|
||||||
|
|
||||||
window.addItem( shapeItem );
|
|
||||||
window.resize( 600, 600 );
|
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
CONFIG += qskexample
|
CONFIG += qskexample
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
Gradient.h \
|
||||||
ShapeItem.h \
|
ShapeItem.h \
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
Gradient.cpp \
|
||||||
ShapeItem.cpp \
|
ShapeItem.cpp \
|
||||||
main.cpp
|
main.cpp
|
||||||
|
Loading…
x
Reference in New Issue
Block a user