QskArcRenderNode stays inside its given rectangle

This commit is contained in:
Uwe Rathmann 2024-07-17 14:19:54 +02:00
parent e937e3941f
commit 0d87964727
4 changed files with 23 additions and 26 deletions

View File

@ -8,6 +8,7 @@
#include "Slider.h"
#include <QskGridBox.h>
#include <QskRgbValue.h>
namespace
{
@ -54,6 +55,9 @@ namespace
public:
Arc()
{
setBackgroundColor( QskRgb::LemonChiffon );
setClip( true ); // for testing if the arc stays inside its bounding rectangle
setStartAngle( 45.0 );
setSpanAngle( 270.0 );
setThickness( 10.0 );
@ -101,7 +105,6 @@ ArcPage::ArcPage( QQuickItem* parent )
: QskLinearBox( Qt::Vertical, parent )
{
auto arc = new Arc();
arc->setMargins( 40 ); // some extra space for testing the offsets
auto panel = new ControlPanel( arc );
panel->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );

View File

@ -56,15 +56,6 @@ static inline QskGradient qskEffectiveGradient(
return gradient;
}
static inline QRectF qskEffectiveRect(
const QRectF& rect, const qreal borderWidth )
{
if ( borderWidth <= 0.0 )
return rect;
return qskValidOrEmptyInnerRect( rect, QskMargins( 0.5 * borderWidth ) );
}
static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
{
static const QVector< quint8 > roles =
@ -114,8 +105,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
auto borderNode = static_cast< BorderNode* >(
QskSGNode::findChildNode( this, BorderRole ) );
const auto arcRect = qskEffectiveRect( rect, borderWidth );
if ( metricsArc.isNull() || arcRect.isEmpty() )
if ( metricsArc.isNull() || rect.isEmpty() )
{
delete shadowNode;
delete pathNode;
@ -125,12 +115,10 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
}
const auto isFillNodeVisible = gradient.isVisible();
const auto isStrokeNodeVisible = ( borderWidth > 0.0 ) && ( borderColor.alpha() > 0 );
const auto isBorderNodeVisible = ( borderWidth > 0.0 ) && ( borderColor.alpha() > 0 );
const auto isShadowNodeVisible = isFillNodeVisible &&
shadowColor.isValid() && ( shadowColor.alpha() > 0.0 );
const auto path = metricsArc.painterPath( arcRect, radial );
if ( isShadowNodeVisible )
{
if ( shadowNode == nullptr )
@ -146,8 +134,8 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
and not only to its radius. TODO ...
*/
const auto sm = shadowMetrics.toAbsolute( arcRect.size() );
const auto shadowRect = sm.shadowRect( arcRect );
const auto sm = shadowMetrics.toAbsolute( rect.size() );
const auto shadowRect = sm.shadowRect( rect );
const auto spreadRadius = sm.spreadRadius() + 0.5 * metricsArc.thickness();
shadowNode->setShadowData( shadowRect, spreadRadius, sm.blurRadius(),
@ -172,7 +160,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
QskSGNode::setNodeRole( arcNode, ArcRole );
}
arcNode->updateNode( arcRect, metricsArc, radial,
arcNode->updateNode( rect, metricsArc, radial,
borderWidth, QColor(), gradient );
}
else
@ -186,7 +174,8 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
QskSGNode::setNodeRole( pathNode, PathRole );
}
pathNode->updateNode( path, QTransform(), arcRect,
const auto path = metricsArc.painterPath( rect, radial );
pathNode->updateNode( path, QTransform(), rect,
qskEffectiveGradient( gradient, metricsArc ) );
}
}
@ -199,7 +188,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
arcNode = nullptr;
}
if ( isStrokeNodeVisible )
if ( isBorderNodeVisible )
{
if ( borderNode == nullptr )
{
@ -208,12 +197,13 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
}
#ifdef ARC_BORDER_NODE
borderNode->updateNode( arcRect, metricsArc, radial,
borderNode->updateNode( rect, metricsArc, radial,
borderWidth, borderColor, QskGradient() );
#else
QPen pen( borderColor, borderWidth );
pen.setCapStyle( Qt::FlatCap );
const auto path = metricsArc.painterPath( rect, radial );
borderNode->updateNode( path, QTransform(), pen );
#endif
}

View File

@ -68,11 +68,15 @@ void QskArcRenderNode::updateNode(
Q_D( QskArcRenderNode );
const auto metrics = arcMetrics.toAbsolute( rect.size() );
const auto borderMax = 0.5 * metrics.thickness();
const auto hasFilling = gradient.isVisible()
&& ( borderWidth < borderMax );
bool visible = !( rect.isEmpty() || metrics.isNull() );
if ( visible )
{
visible = gradient.isVisible();
visible = hasFilling;
if ( !visible )
{
visible = ( borderWidth > 0.0 )
@ -103,11 +107,12 @@ void QskArcRenderNode::updateNode(
if ( borderWidth > 0.0 && borderColor.isValid() )
{
borderWidth = std::min( borderWidth, borderMax );
QskArcRenderer::renderBorder(
rect, metrics, radial, borderWidth, borderColor, *geometry() );
}
if ( gradient.isVisible() )
if ( hasFilling )
{
QskArcRenderer::renderFillGeometry(
rect, metrics, radial, borderWidth, gradient, *geometry() );

View File

@ -378,8 +378,7 @@ void QskArcRenderer::renderFillGeometry( const QRectF& rect,
{
geometry.setDrawingMode( QSGGeometry::DrawTriangleStrip );
const auto b2 = 0.5 * borderWidth;
const auto r = rect.adjusted( b2, b2, -b2, -b2 );
const auto r = rect.adjusted( borderWidth, borderWidth, -borderWidth, -borderWidth );
FillStroker stroker( r, metrics, radial, gradient );
@ -390,7 +389,7 @@ void QskArcRenderer::renderFillGeometry( const QRectF& rect,
return;
const auto effectiveCount = stroker.setLines(
metrics.thickness() - borderWidth, lines );
metrics.thickness() - 2 * borderWidth, lines );
if ( effectiveCount > lineCount )
{