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->setMirrorHorizontal( false );
|
||||
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;
|
||||
}
|
||||
|
@ -100,19 +110,15 @@ class BlurredOverlayPrivate final : public QQuickItemPrivate, public QQuickItemC
|
|||
{
|
||||
Q_Q( BlurredOverlay );
|
||||
|
||||
layer->setLive( live );
|
||||
const auto pixelRatio = q->window()->effectiveDevicePixelRatio();
|
||||
|
||||
layer->setLive( true );
|
||||
layer->setItem( QQuickItemPrivate::get( grabbedItem )->itemNode() );
|
||||
|
||||
auto r = grabRect;
|
||||
if ( r.isEmpty() )
|
||||
r = QRectF(0, 0, grabbedItem->width(), grabbedItem->height() );
|
||||
const auto rect = QRectF( q->position(), q->size() );
|
||||
layer->setRect( rect );
|
||||
|
||||
layer->setRect( r );
|
||||
|
||||
QSize textureSize( qCeil( qAbs( r.width() ) ),
|
||||
qCeil( qAbs( r.height() ) ) );
|
||||
|
||||
const auto pixelRatio = q->window()->effectiveDevicePixelRatio();
|
||||
QSize textureSize( qCeil( rect.width() ), qCeil( rect.height() ) );
|
||||
textureSize *= pixelRatio;
|
||||
|
||||
const QSize minTextureSize = sceneGraphContext()->minimumFBOSize();
|
||||
|
@ -130,10 +136,7 @@ class BlurredOverlayPrivate final : public QQuickItemPrivate, public QQuickItemC
|
|||
}
|
||||
|
||||
QPointer< QQuickItem > grabbedItem;
|
||||
QRectF grabRect;
|
||||
|
||||
const bool live = true;
|
||||
bool covering = true;
|
||||
bool covering = false;
|
||||
|
||||
Q_DECLARE_PUBLIC(BlurredOverlay)
|
||||
};
|
||||
|
@ -169,41 +172,18 @@ void BlurredOverlay::setGrabbedItem( QQuickItem* item )
|
|||
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(
|
||||
const QRectF& newGeometry, const QRectF& oldGeometry )
|
||||
{
|
||||
update();
|
||||
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* )
|
||||
|
@ -229,22 +209,16 @@ QSGNode* BlurredOverlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData*
|
|||
this, &QQuickItem::update );
|
||||
}
|
||||
|
||||
auto layer = static_cast< QSGLayer* >( node->texture() );
|
||||
|
||||
d->updateTexture( layer );
|
||||
auto itemNode = static_cast< TransformNode* >( d->itemNode() );
|
||||
|
||||
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;
|
||||
|
||||
auto layer = static_cast< QSGLayer* >( node->texture() );
|
||||
|
||||
d->updateTexture( layer );
|
||||
|
||||
layer->updateTexture();
|
||||
itemNode->isBlocked = false;
|
||||
}
|
||||
|
|
|
@ -22,10 +22,6 @@ class BlurredOverlay : public QQuickItem
|
|||
QQuickItem* grabbedItem() const;
|
||||
void setGrabbedItem( QQuickItem* );
|
||||
|
||||
QRectF grabRect() const;
|
||||
void setGrabRect( const QRectF& );
|
||||
void resetGrabRect();
|
||||
|
||||
protected:
|
||||
void geometryChange( const QRectF&, const QRectF& ) override;
|
||||
QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override;
|
||||
|
|
|
@ -58,6 +58,10 @@ namespace
|
|||
{
|
||||
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( FragmentStage, ":/shaders/blur.frag.qsb" );
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ class ButtonBox : public QskLinearBox
|
|||
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
label->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||
|
||||
|
||||
auto button = new QskPushButton( "Button", this );
|
||||
button->setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
|
||||
}
|
||||
|
@ -57,33 +56,21 @@ class Overlay : public BlurredOverlay
|
|||
void geometryChange( const QRectF& newRect, const QRectF& oldRect ) override
|
||||
{
|
||||
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
|
||||
{
|
||||
using Inherited = QskControl;
|
||||
|
@ -147,15 +134,10 @@ class MainView : public QskControl
|
|||
|
||||
m_background = new BackgroundItem( this );
|
||||
|
||||
#if 1
|
||||
m_blurredBox = new BlurredBox( this );
|
||||
#else
|
||||
// unsatisfying: see comment in BlurredOverlay::updatePaintNode TODO ...
|
||||
m_blurredBox = new BlurredBox( m_background );
|
||||
#endif
|
||||
m_blurredBox->setGrabbedItem( m_background );
|
||||
m_overlay = new Overlay( m_background );
|
||||
m_overlay->setGrabbedItem( m_background );
|
||||
|
||||
(void )new ButtonBox( m_blurredBox );
|
||||
(void )new ButtonBox( m_overlay );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -166,12 +148,12 @@ class MainView : public QskControl
|
|||
QRectF blurredRect( QPointF(), 0.7 * size() );
|
||||
blurredRect.moveCenter( rect().center() );
|
||||
|
||||
m_blurredBox->setGeometry( blurredRect );
|
||||
qskSetItemGeometry( m_overlay, blurredRect );
|
||||
}
|
||||
|
||||
private:
|
||||
BackgroundItem* m_background;
|
||||
BlurredBox* m_blurredBox;
|
||||
Overlay* m_overlay;
|
||||
};
|
||||
|
||||
int main( int argc, char** argv )
|
||||
|
|
Loading…
Reference in New Issue