qskinny/playground/parrots/Overlay.cpp

154 lines
3.6 KiB
C++
Raw Normal View History

2023-12-07 10:24:47 +00:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
2023-12-08 14:47:32 +00:00
#include "Overlay.h"
#include "BlurringNode.h"
#include "SceneTexture.h"
2023-12-07 10:24:47 +00:00
#include <QskTreeNode.h>
2023-12-07 10:24:47 +00:00
#include <private/qquickitem_p.h>
2023-12-12 09:55:30 +00:00
#include <private/qquickwindow_p.h>
#include <private/qsgrenderer_p.h>
2023-12-07 10:24:47 +00:00
#include <private/qquickitemchangelistener_p.h>
#include <qpointer.h>
2023-12-08 14:47:32 +00:00
class OverlayPrivate final : public QQuickItemPrivate, public QQuickItemChangeListener
2023-12-07 10:24:47 +00:00
{
public:
void itemGeometryChanged( QQuickItem*,
QQuickGeometryChange change, const QRectF& )
{
if ( change.sizeChange() )
q_func()->update();
}
void setAttached( bool on )
{
if ( grabbedItem )
{
auto d = QQuickItemPrivate::get( grabbedItem );
if ( on )
{
d->refFromEffectItem( false );
2023-12-07 10:24:47 +00:00
d->addItemChangeListener( this, Geometry );
}
else
{
d->removeItemChangeListener( this, Geometry );
d->derefFromEffectItem( false );
2023-12-07 10:24:47 +00:00
}
}
}
QSGRootNode* grabbedNode()
2023-12-07 10:24:47 +00:00
{
2023-12-12 09:55:30 +00:00
if ( grabbedItem )
return grabbedItem ? get( grabbedItem )->rootNode() : nullptr;
2023-12-07 10:24:47 +00:00
2023-12-12 09:55:30 +00:00
if ( auto window = q_func()->window() )
{
if ( auto renderer = QQuickWindowPrivate::get( window )->renderer )
return renderer->rootNode();
}
return nullptr;
2023-12-07 10:24:47 +00:00
}
QSGTransformNode* createTransformNode() override
{
return new QskItemNode();
}
2023-12-07 10:24:47 +00:00
QPointer< QQuickItem > grabbedItem;
2023-12-08 14:47:32 +00:00
Q_DECLARE_PUBLIC(Overlay)
2023-12-07 10:24:47 +00:00
};
2023-12-08 14:47:32 +00:00
Overlay::Overlay( QQuickItem* parent )
: QQuickItem( *new OverlayPrivate(), parent )
2023-12-07 10:24:47 +00:00
{
setFlag( ItemHasContents );
}
2023-12-08 14:47:32 +00:00
Overlay::~Overlay()
2023-12-07 10:24:47 +00:00
{
2023-12-08 14:47:32 +00:00
d_func()->setAttached( false );
2023-12-07 10:24:47 +00:00
}
2023-12-08 14:47:32 +00:00
QQuickItem*Overlay::grabbedItem() const
2023-12-07 10:24:47 +00:00
{
return d_func()->grabbedItem;
}
2023-12-08 14:47:32 +00:00
void Overlay::setGrabbedItem( QQuickItem* item )
2023-12-07 10:24:47 +00:00
{
2023-12-08 14:47:32 +00:00
Q_D( Overlay );
2023-12-07 10:24:47 +00:00
if ( item == d->grabbedItem )
return;
d->setAttached( false );
d->grabbedItem = item;
d->setAttached( true );
update();
}
2023-12-08 14:47:32 +00:00
void Overlay::geometryChange(
2023-12-07 10:24:47 +00:00
const QRectF& newGeometry, const QRectF& oldGeometry )
{
Inherited::geometryChange( newGeometry, oldGeometry );
2023-12-12 09:55:30 +00:00
update();
2023-12-07 10:24:47 +00:00
}
2023-12-08 14:47:32 +00:00
QSGNode* Overlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* )
2023-12-07 10:24:47 +00:00
{
Q_D( Overlay );
2023-12-12 09:55:30 +00:00
auto grabbedNode = d->grabbedNode();
if ( grabbedNode == nullptr )
QMetaObject::invokeMethod( this, &QQuickItem::update );
if ( grabbedNode == nullptr || size().isEmpty() )
2023-12-07 10:24:47 +00:00
{
delete oldNode;
return nullptr;
}
2023-12-08 14:47:32 +00:00
auto node = static_cast< BlurringNode* >( oldNode );
2023-12-07 10:24:47 +00:00
if ( node == nullptr )
{
2023-12-08 14:47:32 +00:00
node = new BlurringNode();
2023-12-07 10:24:47 +00:00
auto texture = new SceneTexture( d->sceneGraphRenderContext() );
texture->setDevicePixelRatio( window()->effectiveDevicePixelRatio() );
2023-12-07 10:24:47 +00:00
node->setTexture( texture );
2023-12-07 10:24:47 +00:00
}
auto texture = static_cast< SceneTexture* >( node->texture() );
2023-12-07 10:24:47 +00:00
if ( !texture->isRendering() )
{
texture->setFiltering( smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
texture->render( grabbedNode, d->itemNode(),
QRectF( x(), y(), width(), height() ) );
QMetaObject::invokeMethod( this, &QQuickItem::update );
}
2023-12-07 10:24:47 +00:00
node->setRect( QRectF( 0, 0, width(), height() ) );
return node;
}
2023-12-08 14:47:32 +00:00
#include "moc_Overlay.cpp"