qskinny/playground/parrots/Overlay.cpp

162 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 <private/qquickitem_p.h>
#include <private/qquickitemchangelistener_p.h>
#include <qpointer.h>
namespace
{
class TransformNode final : public QSGTransformNode
{
public:
bool isSubtreeBlocked() const override
{
return isBlocked || QSGTransformNode::isSubtreeBlocked();
}
bool isBlocked = false;;
};
}
2023-12-08 14:47:32 +00:00
class OverlayPrivate final : public QQuickItemPrivate, public QQuickItemChangeListener
2023-12-07 10:24:47 +00:00
{
public:
QSGTransformNode* createTransformNode() override
{
return new TransformNode();
}
2023-12-07 10:24:47 +00:00
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
{
return grabbedItem ? get( grabbedItem )->rootNode() : nullptr;
2023-12-07 10:24:47 +00:00
}
QSGTransformNode* grabbedItemNode()
2023-12-07 10:24:47 +00:00
{
return grabbedItem ? get( grabbedItem )->itemNode() : nullptr;
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 );
if ( d_func()->grabbedItem )
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 );
if ( d->grabbedItemNode() == 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 itemNode = static_cast< TransformNode* >( d->itemNode() );
2023-12-07 10:24:47 +00:00
if ( !itemNode->isBlocked )
{
itemNode->isBlocked = true;
auto texture = static_cast< SceneTexture* >( node->texture() );
texture->setFiltering( smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
texture->render( d->grabbedNode(), itemNode,
QRectF( x(), y(), width(), height() ) );
itemNode->isBlocked = false;
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"