seems to work now - even when being a child
This commit is contained in:
parent
725500fdaf
commit
ff1b479938
|
@ -91,7 +91,17 @@ class BlurredOverlayPrivate final : public QQuickItemPrivate, public QQuickItemC
|
||||||
layer->setHasMipmaps( false );
|
layer->setHasMipmaps( false );
|
||||||
layer->setMirrorHorizontal( false );
|
layer->setMirrorHorizontal( false );
|
||||||
layer->setMirrorVertical( true );
|
layer->setMirrorVertical( true );
|
||||||
layer->setSamples( 0 );
|
|
||||||
|
if ( q_func()->window()->format().samples() > 2 )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We want to disable multisampling as it doesn't make any sense
|
||||||
|
in combination with blurring afterwards. Unfortunately
|
||||||
|
QSGLayer uses the samples from the window when setting samples
|
||||||
|
below 2 here.
|
||||||
|
*/
|
||||||
|
layer->setSamples( 2 );
|
||||||
|
}
|
||||||
|
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
@ -100,19 +110,15 @@ class BlurredOverlayPrivate final : public QQuickItemPrivate, public QQuickItemC
|
||||||
{
|
{
|
||||||
Q_Q( BlurredOverlay );
|
Q_Q( BlurredOverlay );
|
||||||
|
|
||||||
layer->setLive( live );
|
const auto pixelRatio = q->window()->effectiveDevicePixelRatio();
|
||||||
|
|
||||||
|
layer->setLive( true );
|
||||||
layer->setItem( QQuickItemPrivate::get( grabbedItem )->itemNode() );
|
layer->setItem( QQuickItemPrivate::get( grabbedItem )->itemNode() );
|
||||||
|
|
||||||
auto r = grabRect;
|
const auto rect = QRectF( q->position(), q->size() );
|
||||||
if ( r.isEmpty() )
|
layer->setRect( rect );
|
||||||
r = QRectF(0, 0, grabbedItem->width(), grabbedItem->height() );
|
|
||||||
|
|
||||||
layer->setRect( r );
|
QSize textureSize( qCeil( rect.width() ), qCeil( rect.height() ) );
|
||||||
|
|
||||||
QSize textureSize( qCeil( qAbs( r.width() ) ),
|
|
||||||
qCeil( qAbs( r.height() ) ) );
|
|
||||||
|
|
||||||
const auto pixelRatio = q->window()->effectiveDevicePixelRatio();
|
|
||||||
textureSize *= pixelRatio;
|
textureSize *= pixelRatio;
|
||||||
|
|
||||||
const QSize minTextureSize = sceneGraphContext()->minimumFBOSize();
|
const QSize minTextureSize = sceneGraphContext()->minimumFBOSize();
|
||||||
|
@ -130,10 +136,7 @@ class BlurredOverlayPrivate final : public QQuickItemPrivate, public QQuickItemC
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointer< QQuickItem > grabbedItem;
|
QPointer< QQuickItem > grabbedItem;
|
||||||
QRectF grabRect;
|
bool covering = false;
|
||||||
|
|
||||||
const bool live = true;
|
|
||||||
bool covering = true;
|
|
||||||
|
|
||||||
Q_DECLARE_PUBLIC(BlurredOverlay)
|
Q_DECLARE_PUBLIC(BlurredOverlay)
|
||||||
};
|
};
|
||||||
|
@ -169,41 +172,18 @@ void BlurredOverlay::setGrabbedItem( QQuickItem* item )
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF BlurredOverlay::grabRect() const
|
|
||||||
{
|
|
||||||
return d_func()->grabRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlurredOverlay::setGrabRect( const QRectF& rect )
|
|
||||||
{
|
|
||||||
Q_D( BlurredOverlay );
|
|
||||||
|
|
||||||
QRectF r;
|
|
||||||
if ( !rect.isEmpty() )
|
|
||||||
r = rect;
|
|
||||||
|
|
||||||
if ( r == d->grabRect )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( r.isEmpty() != d->grabRect.isEmpty() )
|
|
||||||
d->setCovering( r.isEmpty() );
|
|
||||||
|
|
||||||
d->grabRect = r;
|
|
||||||
|
|
||||||
if ( d->grabbedItem )
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlurredOverlay::resetGrabRect()
|
|
||||||
{
|
|
||||||
setGrabRect( QRectF() );
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlurredOverlay::geometryChange(
|
void BlurredOverlay::geometryChange(
|
||||||
const QRectF& newGeometry, const QRectF& oldGeometry )
|
const QRectF& newGeometry, const QRectF& oldGeometry )
|
||||||
{
|
{
|
||||||
update();
|
|
||||||
Inherited::geometryChange( newGeometry, oldGeometry );
|
Inherited::geometryChange( newGeometry, oldGeometry );
|
||||||
|
|
||||||
|
/*
|
||||||
|
When newGeometry covers the grabbedItem completely we could
|
||||||
|
set covering to true. TODO ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( d_func()->grabbedItem )
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGNode* BlurredOverlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* )
|
QSGNode* BlurredOverlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* )
|
||||||
|
@ -229,22 +209,16 @@ QSGNode* BlurredOverlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData*
|
||||||
this, &QQuickItem::update );
|
this, &QQuickItem::update );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto layer = static_cast< QSGLayer* >( node->texture() );
|
auto itemNode = static_cast< TransformNode* >( d->itemNode() );
|
||||||
|
|
||||||
d->updateTexture( layer );
|
|
||||||
|
|
||||||
|
if ( !itemNode->isBlocked )
|
||||||
{
|
{
|
||||||
auto itemNode = static_cast< TransformNode* >( d->itemNode() );
|
|
||||||
|
|
||||||
/*
|
|
||||||
When we are a child of grabbedItem we end up in a recursion
|
|
||||||
that fails when initializing the texture twice. No problem
|
|
||||||
as we explicitly do not want to become part of it.
|
|
||||||
|
|
||||||
Disabling our subtree avoids the problem with the initialization
|
|
||||||
- the texture contains some artifacts from our own children. TODO ...
|
|
||||||
*/
|
|
||||||
itemNode->isBlocked = true;
|
itemNode->isBlocked = true;
|
||||||
|
|
||||||
|
auto layer = static_cast< QSGLayer* >( node->texture() );
|
||||||
|
|
||||||
|
d->updateTexture( layer );
|
||||||
|
|
||||||
layer->updateTexture();
|
layer->updateTexture();
|
||||||
itemNode->isBlocked = false;
|
itemNode->isBlocked = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,6 @@ class BlurredOverlay : public QQuickItem
|
||||||
QQuickItem* grabbedItem() const;
|
QQuickItem* grabbedItem() const;
|
||||||
void setGrabbedItem( QQuickItem* );
|
void setGrabbedItem( QQuickItem* );
|
||||||
|
|
||||||
QRectF grabRect() const;
|
|
||||||
void setGrabRect( const QRectF& );
|
|
||||||
void resetGrabRect();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void geometryChange( const QRectF&, const QRectF& ) override;
|
void geometryChange( const QRectF&, const QRectF& ) override;
|
||||||
QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override;
|
QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override;
|
||||||
|
|
|
@ -58,6 +58,10 @@ namespace
|
||||||
{
|
{
|
||||||
setFlag( UpdatesGraphicsPipelineState, true );
|
setFlag( UpdatesGraphicsPipelineState, true );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Using our own shaders - we do not want to add a dependency
|
||||||
|
to the quickeffects module.
|
||||||
|
*/
|
||||||
setShaderFileName( VertexStage, ":/shaders/blur.vert.qsb" );
|
setShaderFileName( VertexStage, ":/shaders/blur.vert.qsb" );
|
||||||
setShaderFileName( FragmentStage, ":/shaders/blur.frag.qsb" );
|
setShaderFileName( FragmentStage, ":/shaders/blur.frag.qsb" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ class ButtonBox : public QskLinearBox
|
||||||
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||||
label->setLayoutAlignmentHint( Qt::AlignCenter );
|
label->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||||
|
|
||||||
|
|
||||||
auto button = new QskPushButton( "Button", this );
|
auto button = new QskPushButton( "Button", this );
|
||||||
button->setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
|
button->setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
|
||||||
}
|
}
|
||||||
|
@ -57,33 +56,21 @@ class Overlay : public BlurredOverlay
|
||||||
void geometryChange( const QRectF& newRect, const QRectF& oldRect ) override
|
void geometryChange( const QRectF& newRect, const QRectF& oldRect ) override
|
||||||
{
|
{
|
||||||
Inherited::geometryChange( newRect, oldRect );
|
Inherited::geometryChange( newRect, oldRect );
|
||||||
setGrabRect( grabbedItem()->mapRectFromItem( this, newRect ) );
|
|
||||||
|
const auto rect = qskItemRect( this );
|
||||||
|
|
||||||
|
const auto children = childItems();
|
||||||
|
for ( auto child : children )
|
||||||
|
{
|
||||||
|
if ( qskIsAdjustableByLayout( child ) )
|
||||||
|
{
|
||||||
|
const auto r = qskConstrainedItemRect( child, rect );
|
||||||
|
qskSetItemGeometry( child, r );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlurredBox : public QskControl
|
|
||||||
{
|
|
||||||
using Inherited = QskControl;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BlurredBox( QQuickItem* parent = nullptr )
|
|
||||||
: QskControl( parent )
|
|
||||||
{
|
|
||||||
setFlag( QQuickItem::ItemHasContents, false );
|
|
||||||
setAutoLayoutChildren( true );
|
|
||||||
|
|
||||||
m_overlay = new Overlay( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
void setGrabbedItem( QQuickItem* item )
|
|
||||||
{
|
|
||||||
m_overlay->setGrabbedItem( item );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Overlay* m_overlay;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BackgroundItem : public QskControl
|
class BackgroundItem : public QskControl
|
||||||
{
|
{
|
||||||
using Inherited = QskControl;
|
using Inherited = QskControl;
|
||||||
|
@ -147,15 +134,10 @@ class MainView : public QskControl
|
||||||
|
|
||||||
m_background = new BackgroundItem( this );
|
m_background = new BackgroundItem( this );
|
||||||
|
|
||||||
#if 1
|
m_overlay = new Overlay( m_background );
|
||||||
m_blurredBox = new BlurredBox( this );
|
m_overlay->setGrabbedItem( m_background );
|
||||||
#else
|
|
||||||
// unsatisfying: see comment in BlurredOverlay::updatePaintNode TODO ...
|
|
||||||
m_blurredBox = new BlurredBox( m_background );
|
|
||||||
#endif
|
|
||||||
m_blurredBox->setGrabbedItem( m_background );
|
|
||||||
|
|
||||||
(void )new ButtonBox( m_blurredBox );
|
(void )new ButtonBox( m_overlay );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -166,12 +148,12 @@ class MainView : public QskControl
|
||||||
QRectF blurredRect( QPointF(), 0.7 * size() );
|
QRectF blurredRect( QPointF(), 0.7 * size() );
|
||||||
blurredRect.moveCenter( rect().center() );
|
blurredRect.moveCenter( rect().center() );
|
||||||
|
|
||||||
m_blurredBox->setGeometry( blurredRect );
|
qskSetItemGeometry( m_overlay, blurredRect );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BackgroundItem* m_background;
|
BackgroundItem* m_background;
|
||||||
BlurredBox* m_blurredBox;
|
Overlay* m_overlay;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
int main( int argc, char** argv )
|
||||||
|
|
Loading…
Reference in New Issue