update issues with gradients fixed
This commit is contained in:
parent
a48943e68f
commit
8318ff757b
@ -94,8 +94,8 @@ class GradientBox: public QWidget
|
|||||||
m_qskBox = new BoxQsk();
|
m_qskBox = new BoxQsk();
|
||||||
|
|
||||||
auto layout = new QHBoxLayout( this );
|
auto layout = new QHBoxLayout( this );
|
||||||
layout->addWidget( m_qskBox );
|
|
||||||
layout->addWidget( m_qtBox );
|
layout->addWidget( m_qtBox );
|
||||||
|
layout->addWidget( m_qskBox );
|
||||||
|
|
||||||
showGradient( { Qt::green, Qt::red, Qt::yellow, Qt::cyan, Qt::darkCyan } );
|
showGradient( { Qt::green, Qt::red, Qt::yellow, Qt::cyan, Qt::darkCyan } );
|
||||||
}
|
}
|
||||||
@ -116,7 +116,8 @@ class GradientBox: public QWidget
|
|||||||
stops += { ( i + 1 ) * step, colors[i] };
|
stops += { ( i + 1 ) * step, colors[i] };
|
||||||
}
|
}
|
||||||
|
|
||||||
QLinearGradient gradient( 0.0, 0.0, 0.0, 1.0 );
|
QLinearGradient gradient( 0.0, 0.0, 0.5, 0.5 );
|
||||||
|
gradient.setSpread( QGradient::ReflectSpread );
|
||||||
gradient.setStops( stops );
|
gradient.setStops( stops );
|
||||||
|
|
||||||
showGradient( gradient );
|
showGradient( gradient );
|
||||||
|
@ -50,9 +50,18 @@ class QskBoxFillNodePrivate final : public QSGGeometryNodePrivate
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QskHashValue metricsHash = 0;
|
inline void resetValues()
|
||||||
|
{
|
||||||
|
rect = QRectF();
|
||||||
|
gradientHash = 0;
|
||||||
|
metricsHash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
QRectF rect;
|
QRectF rect;
|
||||||
|
|
||||||
|
QskHashValue gradientHash = 0;
|
||||||
|
QskHashValue metricsHash = 0;
|
||||||
|
|
||||||
QSGGeometry geometry;
|
QSGGeometry geometry;
|
||||||
int gradientType = -1;
|
int gradientType = -1;
|
||||||
};
|
};
|
||||||
@ -75,20 +84,23 @@ void QskBoxFillNode::updateNode(
|
|||||||
|
|
||||||
if ( rect.isEmpty() || !gradient.isVisible() )
|
if ( rect.isEmpty() || !gradient.isVisible() )
|
||||||
{
|
{
|
||||||
d->rect = QRectF();
|
d->resetValues();
|
||||||
d->metricsHash = 0;
|
|
||||||
QskSGNode::resetGeometry( this );
|
QskSGNode::resetGeometry( this );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto metricsHash = qskMetricsHash( shapeMetrics, borderMetrics );
|
const auto metricsHash = qskMetricsHash( shapeMetrics, borderMetrics );
|
||||||
const bool dirtyGeometry = ( metricsHash != d->metricsHash ) || ( rect != d->rect );
|
const auto gradientHash = gradient.hash( 22879 );
|
||||||
|
|
||||||
|
const bool dirtyColors = gradientHash != d->gradientHash;
|
||||||
|
const bool dirtyMetrics = ( metricsHash != d->metricsHash ) || ( rect != d->rect );
|
||||||
|
|
||||||
d->metricsHash = metricsHash;
|
d->metricsHash = metricsHash;
|
||||||
|
d->gradientHash = gradientHash;
|
||||||
d->rect = rect;
|
d->rect = rect;
|
||||||
|
|
||||||
if ( dirtyGeometry )
|
if ( dirtyMetrics )
|
||||||
{
|
{
|
||||||
QskBoxRenderer::renderFill( rect, shapeMetrics, borderMetrics, d->geometry );
|
QskBoxRenderer::renderFill( rect, shapeMetrics, borderMetrics, d->geometry );
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
@ -96,34 +108,42 @@ void QskBoxFillNode::updateNode(
|
|||||||
|
|
||||||
if ( gradient.isMonochrome() )
|
if ( gradient.isMonochrome() )
|
||||||
{
|
{
|
||||||
if ( material() == nullptr || d->gradientType >= 0 )
|
if ( dirtyColors )
|
||||||
{
|
{
|
||||||
setMaterial( new QSGFlatColorMaterial() );
|
if ( material() == nullptr || d->gradientType >= 0 )
|
||||||
d->gradientType = -1;
|
{
|
||||||
}
|
setMaterial( new QSGFlatColorMaterial() );
|
||||||
|
d->gradientType = -1;
|
||||||
|
}
|
||||||
|
|
||||||
const auto color = gradient.startColor().toRgb();
|
const auto color = gradient.startColor().toRgb();
|
||||||
|
|
||||||
auto mat = static_cast< QSGFlatColorMaterial* >( material() );
|
auto mat = static_cast< QSGFlatColorMaterial* >( material() );
|
||||||
if ( mat->color() != color )
|
if ( mat->color() != color )
|
||||||
{
|
{
|
||||||
mat->setColor( color );
|
mat->setColor( color );
|
||||||
markDirty( QSGNode::DirtyMaterial );
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto effectiveGradient = qskEffectiveGradient( gradient );
|
// dirtyMetrics: the shader also depends on the target rectangle !
|
||||||
const auto gradientType = effectiveGradient.type();
|
|
||||||
|
|
||||||
if ( ( material() == nullptr ) || ( gradientType != d->gradientType ) )
|
if ( dirtyColors || dirtyMetrics )
|
||||||
{
|
{
|
||||||
setMaterial( QskGradientMaterial::createMaterial( gradientType ) );
|
const auto effectiveGradient = qskEffectiveGradient( gradient );
|
||||||
d->gradientType = gradientType;
|
const auto gradientType = effectiveGradient.type();
|
||||||
}
|
|
||||||
|
|
||||||
auto mat = static_cast< QskGradientMaterial* >( material() );
|
if ( ( material() == nullptr ) || ( gradientType != d->gradientType ) )
|
||||||
if ( mat->updateGradient( rect, effectiveGradient ) )
|
{
|
||||||
markDirty( QSGNode::DirtyMaterial );
|
setMaterial( QskGradientMaterial::createMaterial( gradientType ) );
|
||||||
|
d->gradientType = gradientType;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mat = static_cast< QskGradientMaterial* >( material() );
|
||||||
|
if ( mat->updateGradient( rect, effectiveGradient ) )
|
||||||
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,32 +43,33 @@ void QskBoxRenderer::renderBox( const QRectF& rect,
|
|||||||
bool QskBoxRenderer::isGradientSupported(
|
bool QskBoxRenderer::isGradientSupported(
|
||||||
const QskBoxShapeMetrics&, const QskGradient& gradient )
|
const QskBoxShapeMetrics&, const QskGradient& gradient )
|
||||||
{
|
{
|
||||||
if ( !gradient.isVisible() || gradient.isMonochrome() )
|
if ( !gradient.isVisible() || gradient.isMonochrome()
|
||||||
return true;
|
|| ( gradient.type() == QskGradient::Stops ) )
|
||||||
|
|
||||||
switch( gradient.type() )
|
|
||||||
{
|
{
|
||||||
case QskGradient::Linear:
|
return true;
|
||||||
{
|
}
|
||||||
auto dir = gradient.linearDirection();
|
|
||||||
|
|
||||||
if ( dir.isTilted() )
|
if ( gradient.type() == QskGradient::Linear )
|
||||||
|
{
|
||||||
|
const auto dir = gradient.linearDirection();
|
||||||
|
|
||||||
|
if ( dir.isTilted() )
|
||||||
|
{
|
||||||
|
if ( dir.x1() == 0.0 && dir.y1() == 0.0
|
||||||
|
&& dir.x2() == 1.0 && dir.y2() == 1.0 )
|
||||||
{
|
{
|
||||||
// only diagonal from topLeft to bottomRight
|
return true;
|
||||||
return ( dir.x1() == 0.0 ) && ( dir.y1() == 0.0 )
|
|
||||||
&& ( dir.x2() == 1.0 ) && ( dir.y2() == 1.0 );
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( dir.x1() == 0.0 && dir.x2() == 1.0 )
|
||||||
|
return true;
|
||||||
|
|
||||||
return true;
|
if ( dir.y1() == 0.0 && dir.y2() == 1.0 )
|
||||||
}
|
return true;
|
||||||
case QskGradient::Radial:
|
|
||||||
case QskGradient::Conic:
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,12 @@ namespace
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
When having a gradient, that does not need spreading
|
||||||
|
we could set QskGradient::PadSpread to potentally reduce
|
||||||
|
the number of color ramps. TODO ...
|
||||||
|
*/
|
||||||
|
|
||||||
if ( gradient.spread() != spread() )
|
if ( gradient.spread() != spread() )
|
||||||
{
|
{
|
||||||
setSpread( gradient.spread() );
|
setSpread( gradient.spread() );
|
||||||
|
@ -188,7 +188,8 @@ void QskRectangleNode::updateNode(
|
|||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dirtyColors )
|
// dirtyMetrics: the shader also depends on the target rectangle !
|
||||||
|
if ( dirtyColors || dirtyMetrics )
|
||||||
{
|
{
|
||||||
const auto gradientType = effectiveGradient.type();
|
const auto gradientType = effectiveGradient.type();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user