started to improve QskPopup and friends
This commit is contained in:
parent
c752ee547f
commit
5e6d5ebceb
|
@ -50,43 +50,44 @@ namespace
|
||||||
{
|
{
|
||||||
setObjectName( QStringLiteral( "QskPopupInputGrabber" ) );
|
setObjectName( QStringLiteral( "QskPopupInputGrabber" ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
We want to receive those events to stop them
|
||||||
|
from being propagated any further
|
||||||
|
*/
|
||||||
setAcceptedMouseButtons( Qt::AllButtons );
|
setAcceptedMouseButtons( Qt::AllButtons );
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||||
|
setAcceptTouchEvents( true );
|
||||||
|
#endif
|
||||||
setAcceptHoverEvents( true );
|
setAcceptHoverEvents( true );
|
||||||
|
|
||||||
QQuickItemPrivate::get( this )->setTransparentForPositioner( true );
|
QQuickItemPrivate::get( this )->setTransparentForPositioner( true );
|
||||||
|
|
||||||
setFlag( QQuickItem::ItemHasContents, false );
|
setFlag( QQuickItem::ItemHasContents, false );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The grabber has to be adjusted to the geometry of
|
The grabber has to be adjusted to the geometry of
|
||||||
the layoutItem, but being a child of he popup its
|
the parent of the popup, but being a child of the popup its
|
||||||
coordinate system is relative to it and needs to be adjusted
|
coordinate system is relative to it and needs to be adjusted
|
||||||
when the position of the popup changes.
|
when the position of the popup changes too.
|
||||||
|
Using a QQuickItemChangeListener instead of connections
|
||||||
|
doesn't make the code much better as we need to deal with
|
||||||
|
how to remove the listener when the grand parent has changed then.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
auto method = &InputGrabber::updateGeometry;
|
auto method = &InputGrabber::updateGeometry;
|
||||||
|
|
||||||
connect( popup, &QQuickItem::xChanged, this, method );
|
connect( popup, &QQuickItem::xChanged, this, method );
|
||||||
connect( popup, &QQuickItem::yChanged, this, method );
|
connect( popup, &QQuickItem::yChanged, this, method );
|
||||||
|
|
||||||
resetGeometryConnection();
|
|
||||||
updateGeometry();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetGeometryConnection()
|
|
||||||
{
|
|
||||||
// maybe using QQuickItemChangeListener instead ???
|
|
||||||
|
|
||||||
for ( int i = 0; i < 4; i++ )
|
|
||||||
disconnect( m_connections[i] );
|
|
||||||
|
|
||||||
if ( QQuickItem* item = parentItem()->parentItem() )
|
if ( QQuickItem* item = parentItem()->parentItem() )
|
||||||
{
|
{
|
||||||
auto method = &InputGrabber::updateGeometry;
|
connect( item, &QQuickItem::xChanged, this, method );
|
||||||
|
connect( item, &QQuickItem::yChanged, this, method );
|
||||||
m_connections[0] = connect( item, &QQuickItem::xChanged, this, method );
|
connect( item, &QQuickItem::widthChanged, this, method );
|
||||||
m_connections[1] = connect( item, &QQuickItem::yChanged, this, method );
|
connect( item, &QQuickItem::heightChanged, this, method );
|
||||||
m_connections[2] = connect( item, &QQuickItem::widthChanged, this, method );
|
|
||||||
m_connections[3] = connect( item, &QQuickItem::heightChanged, this, method );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -94,48 +95,33 @@ namespace
|
||||||
{
|
{
|
||||||
bool doSwallow = false;
|
bool doSwallow = false;
|
||||||
|
|
||||||
switch ( event->type() )
|
switch ( static_cast<int>( event->type() ) )
|
||||||
{
|
{
|
||||||
case QEvent::KeyPress:
|
case QEvent::MouseButtonPress:
|
||||||
case QEvent::KeyRelease:
|
case QEvent::MouseMove:
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
{
|
{
|
||||||
doSwallow = true;
|
doSwallow = handleMouseEvent( static_cast< QMouseEvent* > ( event ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::TouchBegin:
|
||||||
|
case QEvent::TouchUpdate:
|
||||||
|
case QEvent::TouchCancel:
|
||||||
|
{
|
||||||
|
doSwallow = handleTouchEvent( static_cast< QTouchEvent* > ( event ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QEvent::MouseButtonPress:
|
|
||||||
case QEvent::MouseButtonRelease:
|
|
||||||
case QEvent::MouseMove:
|
|
||||||
case QEvent::Wheel:
|
case QEvent::Wheel:
|
||||||
|
{
|
||||||
|
doSwallow = handleWheelEvent( static_cast< QWheelEvent* > ( event ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
case QEvent::HoverEnter:
|
case QEvent::HoverEnter:
|
||||||
case QEvent::HoverLeave:
|
case QEvent::HoverLeave:
|
||||||
{
|
{
|
||||||
// swallow all events of the parent of the popup
|
doSwallow = handleHoverEvent( static_cast< QHoverEvent* > ( event ) );
|
||||||
// but not being seen by the popup itself
|
|
||||||
|
|
||||||
QPointF pos;
|
|
||||||
if ( event->type() == QEvent::Wheel )
|
|
||||||
{
|
|
||||||
pos = static_cast< QWheelEvent* >( event )->pos();
|
|
||||||
}
|
|
||||||
else if ( ( event->type() == QEvent::HoverEnter ) ||
|
|
||||||
( event->type() == QEvent::HoverLeave ) )
|
|
||||||
{
|
|
||||||
pos = static_cast< QHoverEvent* >( event )->posF();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos = static_cast< QMouseEvent* >( event )->localPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
QQuickItem* popup = parentItem();
|
|
||||||
doSwallow = !qskItemRect( popup ).contains(
|
|
||||||
popup->mapFromItem( this, pos ) );
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( doSwallow )
|
if ( doSwallow )
|
||||||
|
@ -152,23 +138,50 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline bool handleMouseEvent( const QMouseEvent* event )
|
||||||
|
{
|
||||||
|
return !isInsidePopup( event->localPos() );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool handleWheelEvent( const QWheelEvent* event )
|
||||||
|
{
|
||||||
|
return !isInsidePopup( event->posF() );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool handleTouchEvent( const QTouchEvent* )
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
return true; // TODO
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool handleHoverEvent( const QHoverEvent* event )
|
||||||
|
{
|
||||||
|
return !isInsidePopup( event->posF() );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isInsidePopup( const QPointF& pos ) const
|
||||||
|
{
|
||||||
|
if ( const auto item = parentItem() )
|
||||||
|
return item->contains( position() + pos );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void updateGeometry()
|
void updateGeometry()
|
||||||
{
|
{
|
||||||
if ( QskPopup* popup = qobject_cast< QskPopup* >( parentItem() ) )
|
if ( auto popup = static_cast< QskPopup* >( parentItem() ) )
|
||||||
{
|
{
|
||||||
const QRectF r = popup->overlayRect();
|
const QRectF rect = popup->grabberRect();
|
||||||
if ( r != qskItemGeometry( this ) )
|
if ( rect != qskItemGeometry( this ) )
|
||||||
{
|
{
|
||||||
setPosition( r.topLeft() );
|
qskSetItemGeometry( this, rect );
|
||||||
setSize( r.size() );
|
|
||||||
|
|
||||||
// the overlay needs to be repainted
|
if ( popup->hasOverlay() )
|
||||||
popup->update();
|
popup->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QMetaObject::Connection m_connections[4];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,9 +200,10 @@ public:
|
||||||
InputGrabber* inputGrabber;
|
InputGrabber* inputGrabber;
|
||||||
|
|
||||||
bool isModal : 1;
|
bool isModal : 1;
|
||||||
bool isOpen : 1;
|
bool isOpen : 1;
|
||||||
bool autoGrabFocus : 1;
|
|
||||||
bool handoverFocus : 1;
|
const bool autoGrabFocus : 1;
|
||||||
|
const bool handoverFocus : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
QskPopup::QskPopup( QQuickItem* parent ):
|
QskPopup::QskPopup( QQuickItem* parent ):
|
||||||
|
@ -214,12 +228,18 @@ QskPopup::~QskPopup()
|
||||||
|
|
||||||
QRectF QskPopup::overlayRect() const
|
QRectF QskPopup::overlayRect() const
|
||||||
{
|
{
|
||||||
const auto item = parentItem();
|
if ( hasOverlay() )
|
||||||
|
return grabberRect();
|
||||||
|
|
||||||
if ( item && isVisible() && m_data->isModal && hasOverlay() )
|
return QRectF();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskPopup::grabberRect() const
|
||||||
|
{
|
||||||
|
if ( const auto item = parentItem() )
|
||||||
{
|
{
|
||||||
const QPointF pos = mapFromItem( item, QPointF() );
|
if ( isVisible() && m_data->isModal )
|
||||||
return QRectF( pos, QSizeF( item->width(), item->height() ) );
|
return QRectF( -position(), QSizeF( item->width(), item->height() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return QRectF();
|
return QRectF();
|
||||||
|
@ -227,13 +247,13 @@ QRectF QskPopup::overlayRect() const
|
||||||
|
|
||||||
void QskPopup::updateInputGrabber()
|
void QskPopup::updateInputGrabber()
|
||||||
{
|
{
|
||||||
if ( parentItem() && isVisible() && m_data->isModal )
|
if ( window() && parentItem() && isVisible() && isModal() )
|
||||||
{
|
{
|
||||||
if ( m_data->inputGrabber == nullptr )
|
if ( m_data->inputGrabber == nullptr )
|
||||||
{
|
{
|
||||||
const auto children = childItems();
|
|
||||||
|
|
||||||
m_data->inputGrabber = new InputGrabber( this );
|
m_data->inputGrabber = new InputGrabber( this );
|
||||||
|
|
||||||
|
const auto children = childItems();
|
||||||
if ( !children.isEmpty() )
|
if ( !children.isEmpty() )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -261,7 +281,7 @@ void QskPopup::setModal( bool on )
|
||||||
m_data->isModal = on;
|
m_data->isModal = on;
|
||||||
updateInputGrabber();
|
updateInputGrabber();
|
||||||
|
|
||||||
Q_EMIT modalChanged();
|
Q_EMIT modalChanged( on );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskPopup::isModal() const
|
bool QskPopup::isModal() const
|
||||||
|
@ -277,7 +297,7 @@ void QskPopup::setOverlay( bool on )
|
||||||
setFlagHint( subControl | QskAspect::Style, on );
|
setFlagHint( subControl | QskAspect::Style, on );
|
||||||
|
|
||||||
update();
|
update();
|
||||||
Q_EMIT overlayChanged();
|
Q_EMIT overlayChanged( on );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,12 +343,19 @@ bool QskPopup::event( QEvent* event )
|
||||||
|
|
||||||
switch( event->type() )
|
switch( event->type() )
|
||||||
{
|
{
|
||||||
|
case QEvent::KeyPress:
|
||||||
|
case QEvent::KeyRelease:
|
||||||
|
|
||||||
case QEvent::Wheel:
|
case QEvent::Wheel:
|
||||||
|
|
||||||
case QEvent::MouseButtonPress:
|
case QEvent::MouseButtonPress:
|
||||||
case QEvent::MouseMove:
|
case QEvent::MouseMove:
|
||||||
case QEvent::MouseButtonRelease:
|
case QEvent::MouseButtonRelease:
|
||||||
case QEvent::KeyPress:
|
|
||||||
case QEvent::KeyRelease:
|
case QEvent::TouchBegin:
|
||||||
|
case QEvent::TouchCancel:
|
||||||
|
case QEvent::TouchUpdate:
|
||||||
|
|
||||||
case QEvent::HoverEnter:
|
case QEvent::HoverEnter:
|
||||||
case QEvent::HoverLeave:
|
case QEvent::HoverLeave:
|
||||||
{
|
{
|
||||||
|
@ -403,7 +430,7 @@ QQuickItem* QskPopup::focusSuccessor() const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskPopup::updateLayout()
|
void QskPopup::aboutToShow()
|
||||||
{
|
{
|
||||||
if ( !m_data->isOpen )
|
if ( !m_data->isOpen )
|
||||||
{
|
{
|
||||||
|
@ -413,7 +440,7 @@ void QskPopup::updateLayout()
|
||||||
m_data->isOpen = true;
|
m_data->isOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Inherited::updateLayout();
|
Inherited::aboutToShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskPopup::itemChange( QQuickItem::ItemChange change,
|
void QskPopup::itemChange( QQuickItem::ItemChange change,
|
||||||
|
@ -426,6 +453,7 @@ void QskPopup::itemChange( QQuickItem::ItemChange change,
|
||||||
case QQuickItem::ItemVisibleHasChanged:
|
case QQuickItem::ItemVisibleHasChanged:
|
||||||
{
|
{
|
||||||
updateInputGrabber();
|
updateInputGrabber();
|
||||||
|
|
||||||
if ( !value.boolValue )
|
if ( !value.boolValue )
|
||||||
{
|
{
|
||||||
m_data->isOpen = false;
|
m_data->isOpen = false;
|
||||||
|
@ -435,6 +463,7 @@ void QskPopup::itemChange( QQuickItem::ItemChange change,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QQuickItem::ItemParentHasChanged:
|
case QQuickItem::ItemParentHasChanged:
|
||||||
|
case QQuickItem::ItemSceneChange:
|
||||||
{
|
{
|
||||||
delete m_data->inputGrabber;
|
delete m_data->inputGrabber;
|
||||||
m_data->inputGrabber = nullptr;
|
m_data->inputGrabber = nullptr;
|
||||||
|
|
|
@ -24,20 +24,22 @@ public:
|
||||||
QskPopup( QQuickItem* parent = nullptr );
|
QskPopup( QQuickItem* parent = nullptr );
|
||||||
virtual ~QskPopup();
|
virtual ~QskPopup();
|
||||||
|
|
||||||
Q_INVOKABLE void setModal( bool on = true );
|
void setModal( bool on = true );
|
||||||
Q_INVOKABLE bool isModal() const;
|
bool isModal() const;
|
||||||
|
|
||||||
void setOverlay( bool on = true );
|
void setOverlay( bool on = true );
|
||||||
bool hasOverlay() const;
|
bool hasOverlay() const;
|
||||||
|
|
||||||
virtual QRectF overlayRect() const;
|
virtual QRectF overlayRect() const;
|
||||||
|
virtual QRectF grabberRect() const;
|
||||||
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void modalChanged();
|
void modalChanged( bool );
|
||||||
void overlayChanged();
|
void overlayChanged( bool );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void updateLayout() override;
|
virtual void aboutToShow() override;
|
||||||
|
|
||||||
virtual bool event( QEvent* ) override;
|
virtual bool event( QEvent* ) override;
|
||||||
virtual void focusInEvent( QFocusEvent * ) override;
|
virtual void focusInEvent( QFocusEvent * ) override;
|
||||||
|
|
|
@ -104,9 +104,9 @@ void QskDialogSubWindow::keyPressEvent( QKeyEvent* event )
|
||||||
Inherited::keyPressEvent( event );
|
Inherited::keyPressEvent( event );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskDialogSubWindow::updateLayout()
|
void QskDialogSubWindow::aboutToShow()
|
||||||
{
|
{
|
||||||
if ( !isInitiallyPainted() && size().isEmpty() )
|
if ( size().isEmpty() )
|
||||||
{
|
{
|
||||||
// setting an initial size from the hint, centered inside the window
|
// setting an initial size from the hint, centered inside the window
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ void QskDialogSubWindow::updateLayout()
|
||||||
setGeometry( rect );
|
setGeometry( rect );
|
||||||
}
|
}
|
||||||
|
|
||||||
Inherited::updateLayout();
|
Inherited::aboutToShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_QskDialogSubWindow.cpp"
|
#include "moc_QskDialogSubWindow.cpp"
|
||||||
|
|
|
@ -40,7 +40,7 @@ protected:
|
||||||
void setResult( QskDialog::DialogCode r );
|
void setResult( QskDialog::DialogCode r );
|
||||||
virtual void keyPressEvent( QKeyEvent* ) override;
|
virtual void keyPressEvent( QKeyEvent* ) override;
|
||||||
|
|
||||||
virtual void updateLayout() override;
|
virtual void aboutToShow() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QskDialog::DialogCode m_result;
|
QskDialog::DialogCode m_result;
|
||||||
|
|
Loading…
Reference in New Issue