SceneTexture is blocking trailing nodes
This commit is contained in:
parent
728dffd1df
commit
7837ff6c8c
|
@ -7,6 +7,8 @@
|
||||||
#include "BlurringNode.h"
|
#include "BlurringNode.h"
|
||||||
#include "SceneTexture.h"
|
#include "SceneTexture.h"
|
||||||
|
|
||||||
|
#include <QskTreeNode.h>
|
||||||
|
|
||||||
#include <private/qquickitem_p.h>
|
#include <private/qquickitem_p.h>
|
||||||
#include <private/qquickwindow_p.h>
|
#include <private/qquickwindow_p.h>
|
||||||
#include <private/qsgrenderer_p.h>
|
#include <private/qsgrenderer_p.h>
|
||||||
|
@ -14,29 +16,9 @@
|
||||||
|
|
||||||
#include <qpointer.h>
|
#include <qpointer.h>
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class TransformNode final : public QSGTransformNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool isSubtreeBlocked() const override
|
|
||||||
{
|
|
||||||
return isBlocked || QSGTransformNode::isSubtreeBlocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isBlocked = false;;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class OverlayPrivate final : public QQuickItemPrivate, public QQuickItemChangeListener
|
class OverlayPrivate final : public QQuickItemPrivate, public QQuickItemChangeListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
QSGTransformNode* createTransformNode() override
|
|
||||||
{
|
|
||||||
return new TransformNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void itemGeometryChanged( QQuickItem*,
|
void itemGeometryChanged( QQuickItem*,
|
||||||
QQuickGeometryChange change, const QRectF& )
|
QQuickGeometryChange change, const QRectF& )
|
||||||
{
|
{
|
||||||
|
@ -77,6 +59,11 @@ class OverlayPrivate final : public QQuickItemPrivate, public QQuickItemChangeLi
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSGTransformNode* createTransformNode() override
|
||||||
|
{
|
||||||
|
return new QskItemNode();
|
||||||
|
}
|
||||||
|
|
||||||
QPointer< QQuickItem > grabbedItem;
|
QPointer< QQuickItem > grabbedItem;
|
||||||
|
|
||||||
Q_DECLARE_PUBLIC(Overlay)
|
Q_DECLARE_PUBLIC(Overlay)
|
||||||
|
@ -146,19 +133,15 @@ QSGNode* Overlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* )
|
||||||
node->setTexture( texture );
|
node->setTexture( texture );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto itemNode = static_cast< TransformNode* >( d->itemNode() );
|
|
||||||
|
|
||||||
if ( !itemNode->isBlocked )
|
|
||||||
{
|
|
||||||
itemNode->isBlocked = true;
|
|
||||||
|
|
||||||
auto texture = static_cast< SceneTexture* >( node->texture() );
|
auto texture = static_cast< SceneTexture* >( node->texture() );
|
||||||
|
|
||||||
|
if ( !texture->isRendering() )
|
||||||
|
{
|
||||||
texture->setFiltering( smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
|
texture->setFiltering( smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
|
||||||
|
|
||||||
texture->render( grabbedNode, itemNode,
|
texture->render( grabbedNode, d->itemNode(),
|
||||||
QRectF( x(), y(), width(), height() ) );
|
QRectF( x(), y(), width(), height() ) );
|
||||||
|
|
||||||
itemNode->isBlocked = false;
|
|
||||||
QMetaObject::invokeMethod( this, &QQuickItem::update );
|
QMetaObject::invokeMethod( this, &QQuickItem::update );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "SceneTexture.h"
|
#include "SceneTexture.h"
|
||||||
|
|
||||||
|
#include <QskTreeNode.h>
|
||||||
#include <private/qsgbatchrenderer_p.h>
|
#include <private/qsgbatchrenderer_p.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -29,7 +31,6 @@ namespace
|
||||||
if ( node != m_finalNode )
|
if ( node != m_finalNode )
|
||||||
{
|
{
|
||||||
m_finalNode = node;
|
m_finalNode = node;
|
||||||
m_renderPassData.setDirty();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,21 +72,47 @@ namespace
|
||||||
|
|
||||||
void render() override
|
void render() override
|
||||||
{
|
{
|
||||||
prepareRenderPass( &m_renderPassData );
|
setNodesBlocked( m_finalNode, true );
|
||||||
m_renderPassData.postPrepare( rootNode(), m_finalNode );
|
#if 0
|
||||||
|
qDebug() << "===================";
|
||||||
beginRenderPass( &m_renderPassData );
|
QSGNodeDumper::dump( rootNode() );
|
||||||
recordRenderPass( &m_renderPassData );
|
#endif
|
||||||
endRenderPass( &m_renderPassData );
|
Inherited::render();
|
||||||
|
setNodesBlocked( m_finalNode, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void nodeChanged( QSGNode* node, QSGNode::DirtyState state ) override
|
void setNodesBlocked( QSGNode* node, bool on )
|
||||||
{
|
{
|
||||||
if ( state & ( QSGNode::DirtyNodeAdded | QSGNode::DirtyNodeRemoved ) )
|
setSubtreeBlocked( node, on );
|
||||||
m_renderPassData.setDirty();
|
|
||||||
|
|
||||||
Inherited::nodeChanged( node, state );
|
for ( auto sibling = node->nextSibling();
|
||||||
|
sibling != nullptr; sibling = sibling->nextSibling() )
|
||||||
|
{
|
||||||
|
setSubtreeBlocked( sibling, on );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( node != rootNode() )
|
||||||
|
{
|
||||||
|
if ( auto upperNode = node->parent() )
|
||||||
|
{
|
||||||
|
upperNode = upperNode->nextSibling();
|
||||||
|
if ( upperNode )
|
||||||
|
setNodesBlocked( upperNode, on );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSubtreeBlocked( QSGNode* node, bool on )
|
||||||
|
{
|
||||||
|
if ( qskTrySubtreeBlocked( node, on, false ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for ( auto child = node->firstChild();
|
||||||
|
child != nullptr; child = child->nextSibling() )
|
||||||
|
{
|
||||||
|
setSubtreeBlocked( child, on );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createTarget( const QSize& size )
|
void createTarget( const QSize& size )
|
||||||
|
@ -135,83 +162,6 @@ namespace
|
||||||
|
|
||||||
QRhiTexture* m_rhiTexture = nullptr;
|
QRhiTexture* m_rhiTexture = nullptr;
|
||||||
QSGTransformNode* m_finalNode = nullptr;
|
QSGTransformNode* m_finalNode = nullptr;
|
||||||
|
|
||||||
class RenderPassData : public RenderPassContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void setDirty()
|
|
||||||
{
|
|
||||||
m_nodesDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void postPrepare( const QSGNode* rootNode, const QSGNode* finalNode )
|
|
||||||
{
|
|
||||||
using namespace QSGBatchRenderer;;
|
|
||||||
|
|
||||||
if ( m_nodesDirty )
|
|
||||||
{
|
|
||||||
m_blockedNodes.clear();
|
|
||||||
|
|
||||||
for ( auto node = finalNode;
|
|
||||||
node && node != rootNode; node = node->parent() )
|
|
||||||
{
|
|
||||||
for ( auto sibling = node->nextSibling();
|
|
||||||
sibling != nullptr; sibling = sibling->nextSibling() )
|
|
||||||
{
|
|
||||||
markNodesAsBlocked( sibling );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nodesDirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( const auto& renderBatch : opaqueRenderBatches )
|
|
||||||
{
|
|
||||||
auto batch = const_cast< Batch* >( renderBatch.batch );
|
|
||||||
removeBlockedNodes( batch );
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto& renderBatch : alphaRenderBatches )
|
|
||||||
{
|
|
||||||
auto batch = const_cast< Batch* >( renderBatch.batch );
|
|
||||||
removeBlockedNodes( batch );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void markNodesAsBlocked( const QSGNode* node )
|
|
||||||
{
|
|
||||||
if ( node->type() == QSGNode::GeometryNodeType )
|
|
||||||
{
|
|
||||||
auto n = static_cast< const QSGGeometryNode* >( node );
|
|
||||||
m_blockedNodes.insert( n );
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto child = node->firstChild();
|
|
||||||
child != nullptr; child = child->nextSibling() )
|
|
||||||
{
|
|
||||||
markNodesAsBlocked( child );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeBlockedNodes( QSGBatchRenderer::Batch* batch )
|
|
||||||
{
|
|
||||||
QSGBatchRenderer::Element** elementRef = &batch->first;
|
|
||||||
|
|
||||||
while( auto element = *elementRef )
|
|
||||||
{
|
|
||||||
if ( m_blockedNodes.contains( element->node ) )
|
|
||||||
*elementRef = element->nextInBatch;
|
|
||||||
else
|
|
||||||
elementRef = &element->nextInBatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool m_nodesDirty = true;
|
|
||||||
QSet< const QSGGeometryNode* > m_blockedNodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
RenderPassData m_renderPassData;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,6 +178,8 @@ class SceneTexturePrivate final : public QSGTexturePrivate
|
||||||
|
|
||||||
Renderer* renderer = nullptr;
|
Renderer* renderer = nullptr;
|
||||||
QSGDefaultRenderContext* context = nullptr;
|
QSGDefaultRenderContext* context = nullptr;
|
||||||
|
|
||||||
|
bool isRendering = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
SceneTexture::SceneTexture( QSGRenderContext* context )
|
SceneTexture::SceneTexture( QSGRenderContext* context )
|
||||||
|
@ -289,7 +241,15 @@ void SceneTexture::render( QSGRootNode* rootNode,
|
||||||
d->renderer->setFinalNode( finalNode );
|
d->renderer->setFinalNode( finalNode );
|
||||||
d->renderer->setProjection( d->rect );
|
d->renderer->setProjection( d->rect );
|
||||||
d->renderer->setTextureSize( pixelSize );
|
d->renderer->setTextureSize( pixelSize );
|
||||||
|
|
||||||
|
d->isRendering = true;
|
||||||
d->renderer->renderScene();
|
d->renderer->renderScene();
|
||||||
|
d->isRendering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneTexture::isRendering() const
|
||||||
|
{
|
||||||
|
return d_func()->isRendering;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneTexture::setDevicePixelRatio( qreal ratio )
|
void SceneTexture::setDevicePixelRatio( qreal ratio )
|
||||||
|
|
|
@ -31,6 +31,8 @@ class SceneTexture : public QSGTexture
|
||||||
|
|
||||||
QRectF normalizedTextureSubRect() const override;
|
QRectF normalizedTextureSubRect() const override;
|
||||||
|
|
||||||
|
bool isRendering() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// satisfy the QSGTexture API
|
// satisfy the QSGTexture API
|
||||||
bool hasAlphaChannel() const override { return false; }
|
bool hasAlphaChannel() const override { return false; }
|
||||||
|
|
|
@ -30,17 +30,19 @@ class ForegroundItem : public QskLinearBox
|
||||||
{
|
{
|
||||||
setMargins( 20 );
|
setMargins( 20 );
|
||||||
|
|
||||||
|
#if 1
|
||||||
auto label = new QskGraphicLabel( this );
|
auto label = new QskGraphicLabel( this );
|
||||||
|
|
||||||
const QImage image( ":/images/parrots.jpg" );
|
const QImage image( ":/images/parrots.jpg" );
|
||||||
label->setGraphic( QskGraphic::fromImage( image ) );
|
label->setGraphic( QskGraphic::fromImage( image ) );
|
||||||
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||||
label->setLayoutAlignmentHint( Qt::AlignCenter );
|
label->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||||
|
label->setObjectName( "miniParrots" );
|
||||||
|
#endif
|
||||||
|
|
||||||
auto button = new QskPushButton( "Button", this );
|
auto button = new QskPushButton( "Button", this );
|
||||||
button->setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
|
button->setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
|
||||||
|
|
||||||
label->setObjectName( "miniParrots" );
|
|
||||||
button->setObjectName( "button" );
|
button->setObjectName( "button" );
|
||||||
setObjectName( "foreground" );
|
setObjectName( "foreground" );
|
||||||
}
|
}
|
||||||
|
@ -141,15 +143,24 @@ class MainView : public QskControl
|
||||||
setPolishOnResize( true );
|
setPolishOnResize( true );
|
||||||
|
|
||||||
m_background = new BackgroundItem( this );
|
m_background = new BackgroundItem( this );
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
auto box = new QskBox( m_background );
|
||||||
|
box->setGeometry( 0, 0, 600, 400 );
|
||||||
|
box->setFillGradient( Qt::darkRed );
|
||||||
|
box->setObjectName( "redBox" );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
m_overlay = new OverlayBox( m_background );
|
m_overlay = new OverlayBox( m_background );
|
||||||
(void )new ForegroundItem( m_overlay );
|
(void )new ForegroundItem( m_overlay );
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
{
|
||||||
auto box = new QskBox( m_background );
|
auto box = new QskBox( m_background );
|
||||||
box->setGeometry( 50, 50, 400, 200 );
|
box->setGeometry( 50, 50, 400, 200 );
|
||||||
box->setFillGradient( Qt::darkBlue );
|
box->setFillGradient( Qt::darkBlue );
|
||||||
box->setObjectName( "blueBox" );
|
box->setObjectName( "blueBox" );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
setObjectName( "mainView" );
|
setObjectName( "mainView" );
|
||||||
}
|
}
|
||||||
|
@ -157,17 +168,19 @@ class MainView : public QskControl
|
||||||
protected:
|
protected:
|
||||||
void updateLayout()
|
void updateLayout()
|
||||||
{
|
{
|
||||||
|
if ( m_background )
|
||||||
m_background->setGeometry( rect() );
|
m_background->setGeometry( rect() );
|
||||||
|
|
||||||
QRectF blurredRect( QPointF(), 0.7 * size() );
|
QRectF blurredRect( QPointF(), 0.7 * size() );
|
||||||
blurredRect.moveCenter( rect().center() );
|
blurredRect.moveCenter( rect().center() );
|
||||||
|
|
||||||
|
if ( m_overlay )
|
||||||
qskSetItemGeometry( m_overlay, blurredRect );
|
qskSetItemGeometry( m_overlay, blurredRect );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BackgroundItem* m_background;
|
BackgroundItem* m_background = nullptr;
|
||||||
Overlay* m_overlay;
|
Overlay* m_overlay = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
int main( int argc, char** argv )
|
||||||
|
|
|
@ -115,6 +115,7 @@ list(APPEND HEADERS
|
||||||
nodes/QskGraduationNode.h
|
nodes/QskGraduationNode.h
|
||||||
nodes/QskGraduationRenderer.h
|
nodes/QskGraduationRenderer.h
|
||||||
nodes/QskGraphicNode.h
|
nodes/QskGraphicNode.h
|
||||||
|
nodes/QskTreeNode.h
|
||||||
nodes/QskLinesNode.h
|
nodes/QskLinesNode.h
|
||||||
nodes/QskPaintedNode.h
|
nodes/QskPaintedNode.h
|
||||||
nodes/QskPlainTextRenderer.h
|
nodes/QskPlainTextRenderer.h
|
||||||
|
@ -123,6 +124,7 @@ list(APPEND HEADERS
|
||||||
nodes/QskStrokeNode.h
|
nodes/QskStrokeNode.h
|
||||||
nodes/QskStippledLineRenderer.h
|
nodes/QskStippledLineRenderer.h
|
||||||
nodes/QskShapeNode.h
|
nodes/QskShapeNode.h
|
||||||
|
nodes/QskTreeNode.h
|
||||||
nodes/QskGradientMaterial.h
|
nodes/QskGradientMaterial.h
|
||||||
nodes/QskTextNode.h
|
nodes/QskTextNode.h
|
||||||
nodes/QskTextRenderer.h
|
nodes/QskTextRenderer.h
|
||||||
|
@ -160,6 +162,7 @@ list(APPEND SOURCES
|
||||||
nodes/QskStrokeNode.cpp
|
nodes/QskStrokeNode.cpp
|
||||||
nodes/QskStippledLineRenderer.cpp
|
nodes/QskStippledLineRenderer.cpp
|
||||||
nodes/QskShapeNode.cpp
|
nodes/QskShapeNode.cpp
|
||||||
|
nodes/QskTreeNode.cpp
|
||||||
nodes/QskGradientMaterial.cpp
|
nodes/QskGradientMaterial.cpp
|
||||||
nodes/QskTextNode.cpp
|
nodes/QskTextNode.cpp
|
||||||
nodes/QskTextRenderer.cpp
|
nodes/QskTextRenderer.cpp
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "QskSkinlet.h"
|
#include "QskSkinlet.h"
|
||||||
#include "QskSkinHintTable.h"
|
#include "QskSkinHintTable.h"
|
||||||
#include "QskMargins.h"
|
#include "QskMargins.h"
|
||||||
|
#include "QskTreeNode.h"
|
||||||
|
|
||||||
#include <qlocale.h>
|
#include <qlocale.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
@ -977,7 +978,7 @@ void QskControl::updateItemPolish()
|
||||||
QSGNode* QskControl::updateItemPaintNode( QSGNode* node )
|
QSGNode* QskControl::updateItemPaintNode( QSGNode* node )
|
||||||
{
|
{
|
||||||
if ( node == nullptr )
|
if ( node == nullptr )
|
||||||
node = new QSGNode;
|
node = new QskTreeNode();
|
||||||
|
|
||||||
updateNode( node );
|
updateNode( node );
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "QskQuickItemPrivate.h"
|
#include "QskQuickItemPrivate.h"
|
||||||
|
#include "QskTreeNode.h"
|
||||||
#include "QskSetup.h"
|
#include "QskSetup.h"
|
||||||
|
|
||||||
static inline void qskSendEventTo( QObject* object, QEvent::Type type )
|
static inline void qskSendEventTo( QObject* object, QEvent::Type type )
|
||||||
|
@ -240,11 +241,13 @@ void QskQuickItemPrivate::cleanupNodes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSGTransformNode* QskQuickItemPrivate::createTransformNode()
|
||||||
|
{
|
||||||
|
return new QskItemNode();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Can we do something useful with overloading:
|
Can we do something useful with overloading:
|
||||||
|
|
||||||
- QQuickItemPrivate::createTransformNode
|
|
||||||
- QQuickItemPrivate::transformChanged
|
- QQuickItemPrivate::transformChanged
|
||||||
|
|
||||||
TODO ...
|
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,13 +23,13 @@ class QskQuickItemPrivate : public QQuickItemPrivate
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void applyUpdateFlags( QskQuickItem::UpdateFlags );
|
void applyUpdateFlags( QskQuickItem::UpdateFlags );
|
||||||
|
QSGTransformNode* createTransformNode() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void layoutConstraintChanged();
|
virtual void layoutConstraintChanged();
|
||||||
virtual void implicitSizeChanged();
|
virtual void implicitSizeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void cleanupNodes();
|
void cleanupNodes();
|
||||||
void mirrorChange() override;
|
void mirrorChange() override;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskTreeNode.h"
|
||||||
|
|
||||||
|
static constexpr auto extraFlag =
|
||||||
|
static_cast< QSGNode::Flag >( QSGNode::IsVisitableNode << 1 );
|
||||||
|
|
||||||
|
static inline QSGNode* qskCheckedNode( const QSGNode* node, QSGNode::NodeType type )
|
||||||
|
{
|
||||||
|
return node && ( node->type() == type ) && ( node->flags() & extraFlag )
|
||||||
|
? const_cast< QSGNode* >( node ) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTreeNode::QskTreeNode()
|
||||||
|
{
|
||||||
|
setFlag( extraFlag, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTreeNode::QskTreeNode( QSGNodePrivate& d )
|
||||||
|
: QSGNode( d, QSGNode::BasicNodeType )
|
||||||
|
{
|
||||||
|
setFlag( extraFlag, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTreeNode::~QskTreeNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTreeNode::setSubtreeBlocked( bool on, bool notify )
|
||||||
|
{
|
||||||
|
if ( on == m_isBlocked )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_isBlocked = on;
|
||||||
|
|
||||||
|
if ( notify )
|
||||||
|
markDirty( DirtySubtreeBlocked );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTreeNode::isSubtreeBlocked() const
|
||||||
|
{
|
||||||
|
return m_isBlocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTreeNode* qskTreeNodeCast( QSGNode* node )
|
||||||
|
{
|
||||||
|
return static_cast< QskTreeNode* >(
|
||||||
|
qskCheckedNode( node, QSGNode::BasicNodeType ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const QskTreeNode* qskTreeNodeCast( const QSGNode* node )
|
||||||
|
{
|
||||||
|
return static_cast< QskTreeNode* >(
|
||||||
|
qskCheckedNode( node, QSGNode::BasicNodeType ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// == QskItemNode
|
||||||
|
|
||||||
|
QskItemNode::QskItemNode()
|
||||||
|
{
|
||||||
|
setFlag( extraFlag, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskItemNode::~QskItemNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskItemNode::setSubtreeBlocked( bool on, bool notify )
|
||||||
|
{
|
||||||
|
if ( on == m_isBlocked )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_isBlocked = on;
|
||||||
|
|
||||||
|
if ( notify )
|
||||||
|
markDirty( DirtySubtreeBlocked );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskItemNode::isSubtreeBlocked() const
|
||||||
|
{
|
||||||
|
return m_isBlocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
QskItemNode* qskItemNodeCast( QSGNode* node )
|
||||||
|
{
|
||||||
|
return static_cast< QskItemNode* >(
|
||||||
|
qskCheckedNode( node, QSGNode::TransformNodeType ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const QskItemNode* qskItemNodeCast( const QSGNode* node )
|
||||||
|
{
|
||||||
|
return static_cast< QskItemNode* >(
|
||||||
|
qskCheckedNode( node, QSGNode::TransformNodeType ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool qskIsNodeBlockable( const QSGNode* node )
|
||||||
|
{
|
||||||
|
switch( node->type() )
|
||||||
|
{
|
||||||
|
case QSGNode::BasicNodeType:
|
||||||
|
case QSGNode::TransformNodeType:
|
||||||
|
return node->flags() & extraFlag;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool qskTrySubtreeBlocked( QSGNode* node, bool on, bool notify )
|
||||||
|
{
|
||||||
|
if ( node && ( node->flags() & extraFlag ) )
|
||||||
|
{
|
||||||
|
if ( node->type() == QSGNode::BasicNodeType )
|
||||||
|
{
|
||||||
|
static_cast< QskTreeNode* >( node )->setSubtreeBlocked( on, notify );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( node->type() == QSGNode::TransformNodeType )
|
||||||
|
{
|
||||||
|
static_cast< QskItemNode* >( node )->setSubtreeBlocked( on, notify );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_TREE_NODE_H
|
||||||
|
#define QSK_TREE_NODE_H
|
||||||
|
|
||||||
|
#include "QskGlobal.h"
|
||||||
|
#include <qsgnode.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used as paintNode in all QskControls ( see QskControl::updateItemPaintNode )
|
||||||
|
*/
|
||||||
|
class QSK_EXPORT QskTreeNode final : public QSGNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QskTreeNode();
|
||||||
|
virtual ~QskTreeNode();
|
||||||
|
|
||||||
|
void setSubtreeBlocked( bool on, bool notify = true );
|
||||||
|
bool isSubtreeBlocked() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QskTreeNode( QSGNodePrivate& );
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isBlocked = false;;
|
||||||
|
};
|
||||||
|
|
||||||
|
QSK_EXPORT QskTreeNode* qskTreeNodeCast( QSGNode* );
|
||||||
|
QSK_EXPORT const QskTreeNode* qskTreeNodeCast( const QSGNode* );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used by all QskQuickItem as root node ( = itemNode ) of its subtree
|
||||||
|
( see qskItemNode in QskQuick.h )
|
||||||
|
*/
|
||||||
|
class QSK_EXPORT QskItemNode final : public QSGTransformNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QskItemNode();
|
||||||
|
virtual ~QskItemNode();
|
||||||
|
|
||||||
|
void setSubtreeBlocked( bool on, bool notify = true );
|
||||||
|
bool isSubtreeBlocked() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isBlocked = false;;
|
||||||
|
};
|
||||||
|
|
||||||
|
QSK_EXPORT QskItemNode* qskItemNodeCast( QSGNode* );
|
||||||
|
QSK_EXPORT const QskItemNode* qskItemNodeCast( const QSGNode* );
|
||||||
|
|
||||||
|
QSK_EXPORT bool qskIsNodeBlockable( const QSGNode* );
|
||||||
|
QSK_EXPORT bool qskTrySubtreeBlocked( QSGNode*, bool on, bool notify = true );
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue