QskBoxRectangleNode supports rounded rectangles now.

This commit is contained in:
Uwe Rathmann 2022-12-06 12:12:54 +01:00
parent 9ae7dc2f63
commit 778ed1de9e
5 changed files with 59 additions and 34 deletions

View File

@ -40,7 +40,6 @@ static inline QskHashValue qskColorsHash(
#if 1 #if 1
static inline QskGradient qskEffectiveGradient( const QskGradient& gradient ) static inline QskGradient qskEffectiveGradient( const QskGradient& gradient )
{ {
QskGradient g; QskGradient g;
@ -139,16 +138,10 @@ void QskBoxRectangleNode::updateNode( const QRectF& rect,
Q_D( QskBoxRectangleNode ); Q_D( QskBoxRectangleNode );
/* /*
QskBoxRenderer supports certain linear gradients only. We supports certain linear gradients only.
For everything else we would have to use a QskGradientMaterial instead. Everything else has to be done using QskRectangleNode
As a temporary solution we simply "convert" gradient into a
simple QskLinearGradient so that at least something is happening.
TODO ...
*/ */
#if 1
const auto fillGradient = qskEffectiveGradient( gradient ); const auto fillGradient = qskEffectiveGradient( gradient );
#endif
const auto metricsHash = qskMetricsHash( shape, borderMetrics ); const auto metricsHash = qskMetricsHash( shape, borderMetrics );
const auto colorsHash = qskColorsHash( borderColors, fillGradient ); const auto colorsHash = qskColorsHash( borderColors, fillGradient );

View File

@ -33,9 +33,6 @@ class QSK_EXPORT QskBoxRenderer
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskBoxBorderColors&, const QskGradient&, QSGGeometry& ); const QskBoxBorderColors&, const QskGradient&, QSGGeometry& );
static void renderRect( const QRectF&, const QskGradient&, QSGGeometry& );
static void renderRect( const QRectF&, QSGGeometry& );
static bool isGradientSupported( const QskGradient& ); static bool isGradientSupported( const QskGradient& );
class Quad class Quad

View File

@ -552,18 +552,6 @@ void QskBoxRenderer::renderRectFill( const QRectF& rect,
p[3].set( quad.right, quad.bottom ); p[3].set( quad.right, quad.bottom );
} }
void QskBoxRenderer::renderRect( const QRectF& rect,
const QskGradient& gradient, QSGGeometry& geometry )
{
renderRect( rect, QskBoxBorderMetrics(),
QskBoxBorderColors(), gradient, geometry );
}
void QskBoxRenderer::renderRect( const QRectF& rect, QSGGeometry& geometry )
{
renderRectFill( rect, QskBoxBorderMetrics(), geometry );
}
void QskBoxRenderer::renderRect( const QRectF& rect, void QskBoxRenderer::renderRect( const QRectF& rect,
const QskBoxBorderMetrics& border, const QskBoxBorderColors& borderColors, const QskBoxBorderMetrics& border, const QskBoxBorderColors& borderColors,
const QskGradient& gradient, QSGGeometry& geometry ) const QskGradient& gradient, QSGGeometry& geometry )

View File

@ -9,6 +9,10 @@
#include "QskBoxRenderer.h" #include "QskBoxRenderer.h"
#include "QskGradientMaterial.h" #include "QskGradientMaterial.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h"
#include "QskBoxShapeMetrics.h"
#include <qglobalstatic.h> #include <qglobalstatic.h>
#include <qsgvertexcolormaterial.h> #include <qsgvertexcolormaterial.h>
@ -33,6 +37,21 @@ static inline QskGradient qskEffectiveGradient( const QskGradient& gradient )
return gradient; return gradient;
} }
static inline void qskUpdateColoredPoint2D( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskGradient& gradient,
QSGGeometry& geometry )
{
QskBoxRenderer::renderBox( rect, shape,
QskBoxBorderMetrics(), QskBoxBorderColors(), gradient, geometry );
}
static inline void qskUpdatePoint2D( const QRectF& rect,
const QskBoxShapeMetrics& shape, QSGGeometry& geometry )
{
QskBoxRenderer::renderFill( rect, shape,
QskBoxBorderMetrics(), geometry );
}
class QskRectangleNodePrivate final : public QSGGeometryNodePrivate class QskRectangleNodePrivate final : public QSGGeometryNodePrivate
{ {
public: public:
@ -41,10 +60,21 @@ class QskRectangleNodePrivate final : public QSGGeometryNodePrivate
{ {
} }
inline void resetValues()
{
rect = QRectF();
shape = QskBoxShapeMetrics();
gradientHash = 0;
metricsHash = 0;
}
QSGGeometry geometry; QSGGeometry geometry;
QRectF rect; QRectF rect;
QskBoxShapeMetrics shape;
QskHashValue gradientHash = 0; QskHashValue gradientHash = 0;
QskHashValue metricsHash = 0;
int gradientType = -1; int gradientType = -1;
}; };
@ -64,30 +94,39 @@ QskRectangleNode::~QskRectangleNode()
void QskRectangleNode::updateNode( void QskRectangleNode::updateNode(
const QRectF& rect, const QskGradient& gradient ) const QRectF& rect, const QskGradient& gradient )
{
updateNode( rect, QskBoxShapeMetrics(), gradient );
}
void QskRectangleNode::updateNode(
const QRectF& rect, const QskBoxShapeMetrics& shape, const QskGradient& gradient )
{ {
Q_D( QskRectangleNode ); Q_D( QskRectangleNode );
if ( rect.isEmpty() || !gradient.isVisible() ) if ( rect.isEmpty() || !gradient.isVisible() )
{ {
d->rect = QRectF(); d->resetValues();
d->gradientHash = 0;
QskSGNode::resetGeometry( this ); QskSGNode::resetGeometry( this );
return; return;
} }
const auto effectiveGradient = qskEffectiveGradient( gradient ); const auto effectiveGradient = qskEffectiveGradient( gradient );
const auto effectiveShape = shape.toAbsolute( rect.size() );
const auto gradientHash = effectiveGradient.hash( 54228 ); const auto gradientHash = effectiveGradient.hash( 54228 );
const auto metricsHash = effectiveShape.hash( 44564 );
const bool dirtyGradient = gradientHash != d->gradientHash; const bool dirtyColors = gradientHash != d->gradientHash;
const bool dirtyRect = rect != d->rect; const bool dirtyMetrics = ( rect != d->rect ) || ( metricsHash != d->metricsHash );
if ( !( dirtyGradient || dirtyRect ) ) if ( !( dirtyColors || dirtyMetrics ) )
return; return;
d->gradientHash = gradientHash; d->gradientHash = gradientHash;
d->metricsHash = metricsHash;
d->rect = rect; d->rect = rect;
d->shape = effectiveShape;
if ( QskBoxRenderer::isGradientSupported( effectiveGradient ) ) if ( QskBoxRenderer::isGradientSupported( effectiveGradient ) )
{ {
@ -128,9 +167,10 @@ void QskRectangleNode::updateNode(
Colors are added to the vertices, while the material does Colors are added to the vertices, while the material does
not depend on the gradient at all not depend on the gradient at all
*/ */
if ( dirtyRect || dirtyGradient ) if ( dirtyMetrics || dirtyColors )
{ {
QskBoxRenderer::renderRect( rect, effectiveGradient, d->geometry ); qskUpdateColoredPoint2D( rect, effectiveShape,
effectiveGradient, d->geometry );
markDirty( QSGNode::DirtyGeometry ); markDirty( QSGNode::DirtyGeometry );
} }
} }
@ -142,13 +182,13 @@ void QskRectangleNode::updateNode(
Monochrome gradients or QskGradient::Stops are supported by the Monochrome gradients or QskGradient::Stops are supported by the
QskBoxRenderer. So we don't need to handle them here. QskBoxRenderer. So we don't need to handle them here.
*/ */
if ( dirtyRect ) if ( dirtyMetrics )
{ {
QskBoxRenderer::renderRect( rect, d->geometry ); qskUpdatePoint2D( rect, effectiveShape, d->geometry );
markDirty( QSGNode::DirtyGeometry ); markDirty( QSGNode::DirtyGeometry );
} }
if ( dirtyGradient ) if ( dirtyColors )
{ {
const auto gradientType = effectiveGradient.type(); const auto gradientType = effectiveGradient.type();

View File

@ -10,8 +10,14 @@
#include <qsgnode.h> #include <qsgnode.h>
class QskGradient; class QskGradient;
class QskBoxShapeMetrics;
class QskRectangleNodePrivate; class QskRectangleNodePrivate;
/*
QskRectangleNode is for rounded rectangles without a border.
Depending on the type of gradient it uses a different
material/geometry combination.
*/
class QSK_EXPORT QskRectangleNode : public QSGGeometryNode class QSK_EXPORT QskRectangleNode : public QSGGeometryNode
{ {
public: public:
@ -19,6 +25,7 @@ class QSK_EXPORT QskRectangleNode : public QSGGeometryNode
~QskRectangleNode() override; ~QskRectangleNode() override;
void updateNode( const QRectF&, const QskGradient& ); void updateNode( const QRectF&, const QskGradient& );
void updateNode( const QRectF&, const QskBoxShapeMetrics&, const QskGradient& );
private: private:
Q_DECLARE_PRIVATE( QskRectangleNode ) Q_DECLARE_PRIVATE( QskRectangleNode )