using the clip node of the drawer ( instead the one of the parentItem() )

This commit is contained in:
Uwe Rathmann 2023-10-18 09:30:01 +02:00
parent aa9235166a
commit 8015580f55
2 changed files with 60 additions and 17 deletions

View File

@ -241,6 +241,15 @@ namespace
class QskDrawer::PrivateData class QskDrawer::PrivateData
{ {
public: public:
inline void resetListener( QskDrawer* drawer )
{
delete listener;
listener = nullptr;
if ( drawer->parentItem() && drawer->isVisible() )
listener = new GeometryListener( drawer->parentItem(), drawer );
}
Qt::Edge edge = Qt::LeftEdge; Qt::Edge edge = Qt::LeftEdge;
GestureRecognizer* gestureRecognizer = nullptr; GestureRecognizer* gestureRecognizer = nullptr;
GeometryListener* listener = nullptr; GeometryListener* listener = nullptr;
@ -268,18 +277,10 @@ QskDrawer::QskDrawer( QQuickItem* parentItem )
the layout updates manually. the layout updates manually.
*/ */
setPlacementPolicy( QskPlacementPolicy::Ignore ); setPlacementPolicy( QskPlacementPolicy::Ignore );
if ( parentItem ) m_data->resetListener( this );
m_data->listener = new GeometryListener( parentItem, this );
connect( this, &QskPopup::openChanged, this, &QskDrawer::setFading ); connect( this, &QskPopup::openChanged, this, &QskDrawer::setFading );
connect( this, &QskPopup::fadingChanged, this, &QQuickItem::setClip );
/*
When the content of the parentItem does not fit we will have
a difference between fading and normal state. To overcome this problem
we need to expand the rectangle of the QQuickDefaultClipNode manually to
the window borders: TODO ...
*/
connect( this, &QskPopup::fadingChanged, parentItem, &QQuickItem::setClip );
} }
QskDrawer::~QskDrawer() QskDrawer::~QskDrawer()
@ -395,16 +396,12 @@ void QskDrawer::itemChange( QQuickItem::ItemChange change,
if ( parentItem() && isInteractive() ) if ( parentItem() && isInteractive() )
qskCatchMouseEvents( parentItem() ); qskCatchMouseEvents( parentItem() );
Q_FALLTHROUGH(); m_data->resetListener( this );
break;
} }
case QQuickItem::ItemVisibleHasChanged: case QQuickItem::ItemVisibleHasChanged:
{ {
delete m_data->listener; m_data->resetListener( this );
m_data->listener = nullptr;
if ( parentItem() && isVisible() )
m_data->listener = new GeometryListener( parentItem(), this );
break; break;
} }
} }
@ -423,4 +420,47 @@ void QskDrawer::setFading( bool on )
startTransition( aspect, hint, from, to ); startTransition( aspect, hint, from, to );
} }
QRectF QskDrawer::clipRect() const
{
if ( !isFading() )
return Inherited::clipRect();
/*
When fading we want to clip against the edge, where the drawer
slides in/out. However the size of the drawer is often smaller than the
one of the parent and we would clip the overlay node
and all content, that is located outside the drawer geometry.
So we expand the clip rectangle to "unbounded" at the other edges.
Note, that clipping against "rounded" rectangles can't be done
properly by overloading clipRect. We would have to manipulate the clip node
manually - like it is done in QskScrollArea. TODO ..
*/
constexpr qreal d = std::numeric_limits< short >::max();
QRectF r( -d, -d, 2.0 * d, 2.0 * d );
switch( m_data->edge )
{
case Qt::LeftEdge:
r.setLeft( 0.0 );
break;
case Qt::RightEdge:
r.setRight( width() );
break;
case Qt::TopEdge:
r.setTop( 0.0 );
break;
case Qt::BottomEdge:
r.setBottom( height() );
break;
}
return r;
}
#include "moc_QskDrawer.cpp" #include "moc_QskDrawer.cpp"

View File

@ -41,6 +41,8 @@ class QSK_EXPORT QskDrawer : public QskPopup
QRectF layoutRectForSize( const QSizeF& ) const override; QRectF layoutRectForSize( const QSizeF& ) const override;
QRectF clipRect() const override;
Q_SIGNALS: Q_SIGNALS:
void edgeChanged( Qt::Edge ); void edgeChanged( Qt::Edge );
void dragMarginChanged( qreal ); void dragMarginChanged( qreal );
@ -52,6 +54,7 @@ class QSK_EXPORT QskDrawer : public QskPopup
private: private:
void setFading( bool ); void setFading( bool );
void setFadingClip( bool );
class PrivateData; class PrivateData;
std::unique_ptr< PrivateData > m_data; std::unique_ptr< PrivateData > m_data;