Overlay as QskControl

This commit is contained in:
Uwe Rathmann 2023-12-17 12:33:23 +01:00
parent e0acd82619
commit e75445e17d
4 changed files with 77 additions and 132 deletions

View File

@ -63,7 +63,7 @@ namespace
to the quickeffects module. to the quickeffects module.
*/ */
setShaderFileName( VertexStage, ":/shaders/blur.vert.qsb" ); setShaderFileName( VertexStage, ":/shaders/blur.vert.qsb" );
#if 0 #if 1
setShaderFileName( FragmentStage, ":/shaders/blur.frag.qsb" ); setShaderFileName( FragmentStage, ":/shaders/blur.frag.qsb" );
#else #else
setShaderFileName( FragmentStage, ":/shaders/rgbswap.frag.qsb" ); setShaderFileName( FragmentStage, ":/shaders/rgbswap.frag.qsb" );

View File

@ -6,97 +6,94 @@
#include "Overlay.h" #include "Overlay.h"
#include "BlurringNode.h" #include "BlurringNode.h"
#include <QskSkinlet.h>
#include <QskSceneTexture.h> #include <QskSceneTexture.h>
#include <QskTreeNode.h> #include <QskQuick.h>
#include <QskBoxShapeMetrics.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskGradient.h>
#include <private/qquickitem_p.h> namespace
#include <private/qquickwindow_p.h>
#include <private/qsgrenderer_p.h>
#include <private/qquickitemchangelistener_p.h>
#include <qpointer.h>
class OverlayPrivate final : public QQuickItemPrivate, public QQuickItemChangeListener
{ {
public: class Skinlet : public QskSkinlet
void itemGeometryChanged( QQuickItem*,
QQuickGeometryChange change, const QRectF& )
{ {
if ( change.sizeChange() ) using Inherited = QskSkinlet;
q_func()->update();
}
void setAttached( bool on ) public:
{ enum NodeRole { EffectRole, BorderRole };
if ( grabbedItem )
Skinlet()
{ {
auto d = QQuickItemPrivate::get( grabbedItem ); setNodeRoles( { EffectRole, BorderRole } );
if ( on )
{
d->refFromEffectItem( false );
d->addItemChangeListener( this, Geometry );
}
else
{
d->removeItemChangeListener( this, Geometry );
d->derefFromEffectItem( false );
}
}
}
QSGRootNode* grabbedNode()
{
if ( grabbedItem )
return grabbedItem ? get( grabbedItem )->rootNode() : nullptr;
if ( auto window = q_func()->window() )
{
if ( auto renderer = QQuickWindowPrivate::get( window )->renderer )
return renderer->rootNode();
} }
return nullptr; QSGNode* updateSubNode(
} const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
{
const auto overlay = static_cast< const Overlay* >( skinnable );
QSGTransformNode* createTransformNode() override switch ( nodeRole )
{ {
return new QskItemNode(); case EffectRole:
} return updateEffectNode( overlay, node );
QPointer< QQuickItem > grabbedItem; case BorderRole:
return updateBoxNode( overlay, node, overlay->contentsRect(),
QskBoxShapeMetrics(), 1, Qt::darkGray, QskGradient() );
break;
};
Q_DECLARE_PUBLIC(Overlay) return nullptr;
}; }
private:
QSGNode* updateEffectNode( const Overlay* overlay, QSGNode* node ) const
{
const auto window = overlay->window();
if ( overlay->size().isEmpty() )
return nullptr;
auto rootNode = qskScenegraphAnchorNode( window );
if ( rootNode == nullptr )
return nullptr;
auto effectNode = static_cast< BlurringNode* >( node );
if ( effectNode == nullptr )
{
auto texture = new QskSceneTexture( window );
QObject::connect( texture, &QskSceneTexture::updateRequested,
overlay, &QQuickItem::update );
effectNode = new BlurringNode();
effectNode->setTexture( texture );
}
auto texture = qobject_cast< QskSceneTexture* >( effectNode->texture() );
Q_ASSERT( texture );
texture->setFiltering( overlay->smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
auto finalNode = const_cast< QSGTransformNode* >( qskItemNode( overlay ) );
texture->render( rootNode, finalNode, overlay->geometry() );
effectNode->setRect( overlay->rect() );
return effectNode;
}
};
}
Overlay::Overlay( QQuickItem* parent ) Overlay::Overlay( QQuickItem* parent )
: QQuickItem( *new OverlayPrivate(), parent ) : Inherited( parent )
{ {
setFlag( ItemHasContents ); setSkinlet( new Skinlet() );
} }
Overlay::~Overlay() Overlay::~Overlay()
{ {
d_func()->setAttached( false );
}
QQuickItem*Overlay::grabbedItem() const
{
return d_func()->grabbedItem;
}
void Overlay::setGrabbedItem( QQuickItem* item )
{
Q_D( Overlay );
if ( item == d->grabbedItem )
return;
d->setAttached( false );
d->grabbedItem = item;
d->setAttached( true );
update();
} }
void Overlay::geometryChange( void Overlay::geometryChange(
@ -106,49 +103,4 @@ void Overlay::geometryChange(
update(); update();
} }
QSGNode* Overlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* )
{
Q_D( Overlay );
auto grabbedNode = d->grabbedNode();
if ( grabbedNode == nullptr || size().isEmpty() )
{
delete oldNode;
return nullptr;
}
auto node = static_cast< BlurringNode* >( oldNode );
if ( node == nullptr )
{
node = new BlurringNode();
auto texture = new QskSceneTexture( d->sceneGraphRenderContext() );
texture->setDevicePixelRatio( window()->effectiveDevicePixelRatio() );
connect( texture, &QskSceneTexture::updateRequested,
this, &QQuickItem::update );
node->setTexture( texture );
}
auto texture = qobject_cast< QskSceneTexture* >( node->texture() );
Q_ASSERT( texture );
texture->setFiltering( smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
texture->render( grabbedNode, d->itemNode(),
QRectF( x(), y(), width(), height() ) );
node->setRect( QRectF( 0, 0, width(), height() ) );
#if 0
// always updating ...
QMetaObject::invokeMethod( this, &QQuickItem::update );
#endif
return node;
}
#include "moc_Overlay.cpp" #include "moc_Overlay.cpp"

View File

@ -5,27 +5,18 @@
#pragma once #pragma once
#include <qquickitem.h> #include <QskControl.h>
class OverlayPrivate; class Overlay : public QskControl
class Overlay : public QQuickItem
{ {
Q_OBJECT Q_OBJECT
using Inherited = QQuickItem; using Inherited = QskControl;
public: public:
Overlay( QQuickItem* = nullptr ); Overlay( QQuickItem* = nullptr );
~Overlay() override; ~Overlay() override;
QQuickItem* grabbedItem() const;
void setGrabbedItem( QQuickItem* );
protected: protected:
void geometryChange( const QRectF&, const QRectF& ) override; void geometryChange( const QRectF&, const QRectF& ) override;
QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override;
private:
Q_DECLARE_PRIVATE( Overlay )
}; };

View File

@ -42,7 +42,7 @@ class ForegroundItem : public QskLinearBox
{ {
setMargins( 20 ); setMargins( 20 );
#if 1 #if 0
auto label = new Image( this ); auto label = new Image( this );
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
label->setLayoutAlignmentHint( Qt::AlignCenter ); label->setLayoutAlignmentHint( Qt::AlignCenter );
@ -103,7 +103,9 @@ class BackgroundItem : public QskControl
m_label->setObjectName( "parrots" ); m_label->setObjectName( "parrots" );
#endif #endif
#if 1
startTimer( 20 ); startTimer( 20 );
#endif
} }
protected: protected: