QskLinesNode derived from QskBasicLinesNode
This commit is contained in:
parent
dc64f21901
commit
e31c063937
|
@ -9,17 +9,9 @@
|
||||||
#include "QskStippledLineRenderer.h"
|
#include "QskStippledLineRenderer.h"
|
||||||
#include "QskSGNode.h"
|
#include "QskSGNode.h"
|
||||||
|
|
||||||
#include <qsgflatcolormaterial.h>
|
|
||||||
#include <qsgvertexcolormaterial.h>
|
|
||||||
#include <qtransform.h>
|
#include <qtransform.h>
|
||||||
#include <qquickitem.h>
|
|
||||||
#include <qquickwindow.h>
|
|
||||||
#include <qline.h>
|
#include <qline.h>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
|
||||||
#include <private/qsgnode_p.h>
|
|
||||||
QSK_QT_PRIVATE_END
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
inline qreal mapX( const QTransform& t, qreal x )
|
inline qreal mapX( const QTransform& t, qreal x )
|
||||||
|
@ -114,115 +106,14 @@ static QSGGeometry::Point2D* qskAddLines( const QTransform& transform,
|
||||||
return reinterpret_cast< QSGGeometry::Point2D* >( vlines );
|
return reinterpret_cast< QSGGeometry::Point2D* >( vlines );
|
||||||
}
|
}
|
||||||
|
|
||||||
class QskLinesNodePrivate final : public QSGGeometryNodePrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QskLinesNodePrivate()
|
|
||||||
: geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
|
||||||
{
|
|
||||||
geometry.setDrawingMode( QSGGeometry::DrawLines );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline qreal round( bool isHorizontal, qreal v ) const
|
|
||||||
{
|
|
||||||
if ( !doRound )
|
|
||||||
return v;
|
|
||||||
|
|
||||||
const auto r2 = 2.0 * devicePixelRatio;
|
|
||||||
const qreal v0 = isHorizontal ? p0.x() : p0.y();
|
|
||||||
|
|
||||||
const int d = qRound( r2 * ( v + v0 ) );
|
|
||||||
const auto f = ( d % 2 ? d : d - 1 ) / r2;
|
|
||||||
|
|
||||||
return f / devicePixelRatio - v0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setLineAttributes( QskLinesNode* node,
|
|
||||||
const QColor& color, float lineWidth )
|
|
||||||
{
|
|
||||||
if ( color != material.color() )
|
|
||||||
{
|
|
||||||
material.setColor( color );
|
|
||||||
node->markDirty( QSGNode::DirtyMaterial );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( lineWidth != geometry.lineWidth() )
|
|
||||||
geometry.setLineWidth( lineWidth );
|
|
||||||
}
|
|
||||||
|
|
||||||
QSGGeometry geometry;
|
|
||||||
QSGFlatColorMaterial material;
|
|
||||||
|
|
||||||
// position of [0,0] in device coordinates
|
|
||||||
QPointF p0;
|
|
||||||
qreal devicePixelRatio = 1.0;
|
|
||||||
|
|
||||||
QskHashValue hash = 0.0;
|
|
||||||
|
|
||||||
bool dirty = true;
|
|
||||||
bool doRound = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
QskLinesNode::QskLinesNode()
|
QskLinesNode::QskLinesNode()
|
||||||
: QSGGeometryNode( *new QskLinesNodePrivate )
|
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
setGeometry( &d->geometry );
|
|
||||||
setMaterial( &d->material );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QskLinesNode::~QskLinesNode()
|
QskLinesNode::~QskLinesNode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::setGlobalPosition( const QQuickItem* item )
|
|
||||||
{
|
|
||||||
QPointF p0;
|
|
||||||
qreal devicePixelRatio = 1.0;
|
|
||||||
|
|
||||||
if ( item )
|
|
||||||
{
|
|
||||||
p0 = item->mapToGlobal( QPointF() );
|
|
||||||
|
|
||||||
if ( auto w = item->window() )
|
|
||||||
devicePixelRatio = w->devicePixelRatio();
|
|
||||||
}
|
|
||||||
|
|
||||||
setGlobalPosition( p0, devicePixelRatio );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskLinesNode::setGlobalPosition(
|
|
||||||
const QPointF& pos, qreal devicePixelRatio )
|
|
||||||
{
|
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( d->doRound == false )
|
|
||||||
{
|
|
||||||
d->doRound = true;
|
|
||||||
d->dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( pos != d->p0 || devicePixelRatio != d->devicePixelRatio )
|
|
||||||
{
|
|
||||||
d->p0 = pos;
|
|
||||||
d->devicePixelRatio = devicePixelRatio;
|
|
||||||
|
|
||||||
d->dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskLinesNode::resetGlobalPosition()
|
|
||||||
{
|
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( d->doRound == true )
|
|
||||||
{
|
|
||||||
d->doRound = false;
|
|
||||||
d->dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskLinesNode::updateRect( const QColor& color,
|
void QskLinesNode::updateRect( const QColor& color,
|
||||||
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
||||||
const QTransform& transform, const QRectF& rect )
|
const QTransform& transform, const QRectF& rect )
|
||||||
|
@ -272,8 +163,6 @@ void QskLinesNode::updateLines( const QColor& color,
|
||||||
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
||||||
const QTransform& transform, int count, const QLineF* lines )
|
const QTransform& transform, int count, const QLineF* lines )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( !stippleMetrics.isValid() || !color.isValid()
|
if ( !stippleMetrics.isValid() || !color.isValid()
|
||||||
|| color.alpha() == 0 || count == 0 )
|
|| color.alpha() == 0 || count == 0 )
|
||||||
{
|
{
|
||||||
|
@ -287,22 +176,18 @@ void QskLinesNode::updateLines( const QColor& color,
|
||||||
hash = qHash( transform, hash );
|
hash = qHash( transform, hash );
|
||||||
hash = qHashBits( lines, count * sizeof( QLineF ) );
|
hash = qHashBits( lines, count * sizeof( QLineF ) );
|
||||||
|
|
||||||
if ( hash != d->hash )
|
if ( hash != m_hash )
|
||||||
{
|
{
|
||||||
d->dirty = true;
|
m_hash = hash;
|
||||||
d->hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( d->dirty )
|
|
||||||
{
|
|
||||||
updateGeometry( stippleMetrics, transform, count, lines );
|
updateGeometry( stippleMetrics, transform, count, lines );
|
||||||
|
|
||||||
d->geometry.markVertexDataDirty();
|
geometry()->markVertexDataDirty();
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
d->dirty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d->setLineAttributes( this, color, lineWidth );
|
setLineWidth( lineWidth );
|
||||||
|
setColor( color );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::updateGrid( const QColor& color,
|
void QskLinesNode::updateGrid( const QColor& color,
|
||||||
|
@ -310,8 +195,6 @@ void QskLinesNode::updateGrid( const QColor& color,
|
||||||
const QTransform& transform, const QRectF& rect,
|
const QTransform& transform, const QRectF& rect,
|
||||||
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( !stippleMetrics.isValid() || !color.isValid() || color.alpha() == 0 )
|
if ( !stippleMetrics.isValid() || !color.isValid() || color.alpha() == 0 )
|
||||||
{
|
{
|
||||||
QskSGNode::resetGeometry( this );
|
QskSGNode::resetGeometry( this );
|
||||||
|
@ -326,30 +209,24 @@ void QskLinesNode::updateGrid( const QColor& color,
|
||||||
hash = qHash( xValues, hash );
|
hash = qHash( xValues, hash );
|
||||||
hash = qHash( yValues, hash );
|
hash = qHash( yValues, hash );
|
||||||
|
|
||||||
if ( hash != d->hash )
|
if ( hash != m_hash )
|
||||||
{
|
{
|
||||||
d->dirty = true;
|
m_hash = hash;
|
||||||
d->hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( d->dirty )
|
|
||||||
{
|
|
||||||
updateGeometry( stippleMetrics, transform, rect, xValues, yValues );
|
updateGeometry( stippleMetrics, transform, rect, xValues, yValues );
|
||||||
|
|
||||||
d->geometry.markVertexDataDirty();
|
geometry()->markVertexDataDirty();
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
d->dirty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d->setLineAttributes( this, color, lineWidth );
|
setLineWidth( lineWidth );
|
||||||
|
setColor( color );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::updateGeometry( const QskStippleMetrics& stippleMetrics,
|
void QskLinesNode::updateGeometry( const QskStippleMetrics& stippleMetrics,
|
||||||
const QTransform& transform, int count, const QLineF* lines )
|
const QTransform& transform, int count, const QLineF* lines )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
auto& geom = *geometry();
|
||||||
|
|
||||||
auto& geom = d->geometry;
|
|
||||||
|
|
||||||
QSGGeometry::Point2D* points = nullptr;
|
QSGGeometry::Point2D* points = nullptr;
|
||||||
|
|
||||||
|
@ -382,8 +259,8 @@ void QskLinesNode::updateGeometry( const QskStippleMetrics& stippleMetrics,
|
||||||
lineCount += renderer.dashCount( p1, p2 );
|
lineCount += renderer.dashCount( p1, p2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
d->geometry.allocate( 2 * lineCount );
|
geometry()->allocate( 2 * lineCount );
|
||||||
points = d->geometry.vertexDataAsPoint2D();
|
points = geometry()->vertexDataAsPoint2D();
|
||||||
|
|
||||||
points = qskAddDashes( transform,
|
points = qskAddDashes( transform,
|
||||||
count, lines, stippleMetrics, points );
|
count, lines, stippleMetrics, points );
|
||||||
|
@ -397,9 +274,7 @@ void QskLinesNode::updateGeometry(
|
||||||
const QTransform& transform, const QRectF& rect,
|
const QTransform& transform, const QRectF& rect,
|
||||||
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
auto& geom = *geometry();
|
||||||
|
|
||||||
auto& geom = d->geometry;
|
|
||||||
|
|
||||||
const auto y1 = mapY( transform, rect.top() );
|
const auto y1 = mapY( transform, rect.top() );
|
||||||
const auto y2 = mapY( transform, rect.bottom() );
|
const auto y2 = mapY( transform, rect.bottom() );
|
||||||
|
@ -430,8 +305,8 @@ void QskLinesNode::updateGeometry(
|
||||||
const auto countY = renderer.dashCount( x1, 0.0, x2, 0.0 );
|
const auto countY = renderer.dashCount( x1, 0.0, x2, 0.0 );
|
||||||
const auto count = xValues.count() * countX + yValues.count() * countY;
|
const auto count = xValues.count() * countX + yValues.count() * countY;
|
||||||
|
|
||||||
d->geometry.allocate( 2 * count );
|
geometry()->allocate( 2 * count );
|
||||||
points = d->geometry.vertexDataAsPoint2D();
|
points = geometry()->vertexDataAsPoint2D();
|
||||||
|
|
||||||
points = setStippledLines( Qt::Vertical, y1, y2,
|
points = setStippledLines( Qt::Vertical, y1, y2,
|
||||||
transform, xValues.count(), xValues.constData(),
|
transform, xValues.count(), xValues.constData(),
|
||||||
|
@ -450,8 +325,6 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
const QTransform& transform, int count, const qreal* values,
|
const QTransform& transform, int count, const qreal* values,
|
||||||
const QskStippleMetrics& stippleMetrics, QSGGeometry::Point2D* points ) const
|
const QskStippleMetrics& stippleMetrics, QSGGeometry::Point2D* points ) const
|
||||||
{
|
{
|
||||||
Q_D( const QskLinesNode );
|
|
||||||
|
|
||||||
if ( count <= 0 )
|
if ( count <= 0 )
|
||||||
return points;
|
return points;
|
||||||
|
|
||||||
|
@ -464,16 +337,14 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
|
|
||||||
if ( orientation == Qt::Vertical )
|
if ( orientation == Qt::Vertical )
|
||||||
{
|
{
|
||||||
auto x = mapX( transform, values[0] );
|
const auto x = mapX( transform, values[0] );
|
||||||
x = d->round( true, x );
|
|
||||||
|
|
||||||
points = renderer.addDashes( points, x, v1, x, v2 );
|
points = renderer.addDashes( points, x, v1, x, v2 );
|
||||||
dashCount = points - line0;
|
dashCount = points - line0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto y = mapY( transform, values[0] );
|
const auto y = mapY( transform, values[0] );
|
||||||
y = d->round( false, y );
|
|
||||||
|
|
||||||
points = renderer.addDashes( points, v1, y, v2, y );
|
points = renderer.addDashes( points, v1, y, v2, y );
|
||||||
dashCount = points - line0;
|
dashCount = points - line0;
|
||||||
|
@ -485,8 +356,7 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
{
|
{
|
||||||
for ( int i = 1; i < count; i++ )
|
for ( int i = 1; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto x = mapX( transform, values[i] );
|
const auto x = mapX( transform, values[i] );
|
||||||
x = d->round( true, x );
|
|
||||||
|
|
||||||
for ( int j = 0; j < dashCount; j++ )
|
for ( int j = 0; j < dashCount; j++ )
|
||||||
points++->set( x, line0[j].y );
|
points++->set( x, line0[j].y );
|
||||||
|
@ -496,8 +366,7 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
{
|
{
|
||||||
for ( int i = 1; i < count; i++ )
|
for ( int i = 1; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto y = mapY( transform, values[i] );
|
const auto y = mapY( transform, values[i] );
|
||||||
y = d->round( false, y );
|
|
||||||
|
|
||||||
for ( int j = 0; j < dashCount; j++ )
|
for ( int j = 0; j < dashCount; j++ )
|
||||||
points++->set( line0[j].x, y );
|
points++->set( line0[j].x, y );
|
||||||
|
@ -512,8 +381,6 @@ QSGGeometry::Point2D* QskLinesNode::setSolidLines(
|
||||||
const QTransform& transform, int count, const qreal* values,
|
const QTransform& transform, int count, const qreal* values,
|
||||||
QSGGeometry::Point2D* points ) const
|
QSGGeometry::Point2D* points ) const
|
||||||
{
|
{
|
||||||
Q_D( const QskLinesNode );
|
|
||||||
|
|
||||||
if ( count <= 0 )
|
if ( count <= 0 )
|
||||||
return points;
|
return points;
|
||||||
|
|
||||||
|
@ -523,9 +390,7 @@ QSGGeometry::Point2D* QskLinesNode::setSolidLines(
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < count; i++ )
|
for ( int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto x = mapX( transform, values[i] );
|
const auto x = mapX( transform, values[i] );
|
||||||
x = d->round( true, x );
|
|
||||||
|
|
||||||
lines++->setVLine( x, v1, v2 );
|
lines++->setVLine( x, v1, v2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,9 +398,7 @@ QSGGeometry::Point2D* QskLinesNode::setSolidLines(
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < count; i++ )
|
for ( int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto y = mapY( transform, values[i] );
|
const auto y = mapY( transform, values[i] );
|
||||||
y = d->round( false, y );
|
|
||||||
|
|
||||||
lines++->setHLine( v1, v2, y );
|
lines++->setHLine( v1, v2, y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,13 +415,11 @@ void QskLinesNode::updatePolygon( const QColor& color, qreal lineWidth,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( true ) // for the moment we always update the geometry. TODO ...
|
if ( true ) // for the moment we always update the geometry. TODO ...
|
||||||
{
|
{
|
||||||
d->geometry.allocate( polygon.count() + 1 );
|
geometry()->allocate( polygon.count() + 1 );
|
||||||
|
|
||||||
auto points = d->geometry.vertexDataAsPoint2D();
|
auto points = geometry()->vertexDataAsPoint2D();
|
||||||
|
|
||||||
if ( transform.isIdentity() )
|
if ( transform.isIdentity() )
|
||||||
{
|
{
|
||||||
|
@ -579,9 +440,10 @@ void QskLinesNode::updatePolygon( const QColor& color, qreal lineWidth,
|
||||||
|
|
||||||
points[ polygon.count() ] = points[0];
|
points[ polygon.count() ] = points[0];
|
||||||
|
|
||||||
d->geometry.markVertexDataDirty();
|
geometry()->markVertexDataDirty();
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
}
|
}
|
||||||
|
|
||||||
d->setLineAttributes( this, color, lineWidth );
|
setLineWidth( lineWidth );
|
||||||
|
setColor( color );
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
#ifndef QSK_LINES_NODE_H
|
#ifndef QSK_LINES_NODE_H
|
||||||
#define QSK_LINES_NODE_H
|
#define QSK_LINES_NODE_H
|
||||||
|
|
||||||
#include "QskGlobal.h"
|
#include "QskBasicLinesNode.h"
|
||||||
|
|
||||||
#include <qsgnode.h>
|
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
|
||||||
class QskIntervalF;
|
class QskIntervalF;
|
||||||
|
@ -17,26 +15,19 @@ class QTransform;
|
||||||
class QPointF;
|
class QPointF;
|
||||||
class QLineF;
|
class QLineF;
|
||||||
class QPolygonF;
|
class QPolygonF;
|
||||||
class QQuickItem;
|
|
||||||
|
|
||||||
class QskLinesNodePrivate;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A node for stippled or solid lines.
|
A node for stippled or solid lines.
|
||||||
For the moment limited to horizontal/vertical lines: TODO
|
For the moment limited to horizontal/vertical lines: TODO
|
||||||
*/
|
*/
|
||||||
class QSK_EXPORT QskLinesNode : public QSGGeometryNode
|
class QSK_EXPORT QskLinesNode : public QskBasicLinesNode
|
||||||
{
|
{
|
||||||
using Inherited = QSGGeometryNode;
|
using Inherited = QskBasicLinesNode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QskLinesNode();
|
QskLinesNode();
|
||||||
~QskLinesNode() override;
|
~QskLinesNode() override;
|
||||||
|
|
||||||
void setGlobalPosition( const QPointF&, qreal devicePixelRatio );
|
|
||||||
void setGlobalPosition( const QQuickItem* );
|
|
||||||
void resetGlobalPosition();
|
|
||||||
|
|
||||||
void updateGrid( const QColor&, qreal lineWidth,
|
void updateGrid( const QColor&, qreal lineWidth,
|
||||||
const QskStippleMetrics&, const QTransform&, const QRectF&,
|
const QskStippleMetrics&, const QTransform&, const QRectF&,
|
||||||
const QVector< qreal >&, const QVector< qreal >& );
|
const QVector< qreal >&, const QVector< qreal >& );
|
||||||
|
@ -80,7 +71,7 @@ class QSK_EXPORT QskLinesNode : public QSGGeometryNode
|
||||||
const QTransform&, int count, const qreal* values,
|
const QTransform&, int count, const qreal* values,
|
||||||
const QskStippleMetrics&, QSGGeometry::Point2D* ) const;
|
const QskStippleMetrics&, QSGGeometry::Point2D* ) const;
|
||||||
|
|
||||||
Q_DECLARE_PRIVATE( QskLinesNode )
|
QskHashValue m_hash = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue