QskPopup imoroved to allow for implementing priority based stacking

orders
This commit is contained in:
Uwe Rathmann 2018-10-05 14:15:17 +02:00
parent da0fb28290
commit e13f9eb4db
5 changed files with 90 additions and 9 deletions

View File

@ -82,6 +82,14 @@ QskWindowChangeEvent::QskWindowChangeEvent(
{
}
// -- QskPopupEvent
QskPopupEvent::QskPopupEvent( Type type, QskPopup* popup )
: QskEvent( type )
, m_popup( popup )
{
}
// -- QskGestureEvent
QskGestureEvent::QskGestureEvent(

View File

@ -12,7 +12,9 @@
#include <qrect.h>
class QskGesture;
class QskPopup;
class QQuickWindow;
class QQuickItem;
class QSK_EXPORT QskEvent : public QEvent
{
@ -24,6 +26,13 @@ class QSK_EXPORT QskEvent : public QEvent
GeometryChange,
WindowChange,
/*
Popups indicate their existence to the owning window
to allow for priority based stacking rules
*/
PopupAdded,
PopupRemoved,
Gesture,
Animator,
@ -63,6 +72,17 @@ class QSK_EXPORT QskWindowChangeEvent : public QskEvent
QQuickWindow* const m_window;
};
class QSK_EXPORT QskPopupEvent : public QskEvent
{
public:
QskPopupEvent( Type, QskPopup* );
inline QskPopup* popup() const { return m_popup; }
private:
QskPopup* const m_popup;
};
class QSK_EXPORT QskGestureEvent : public QskEvent
{
public:

View File

@ -8,6 +8,7 @@
#include "QskInputGrabber.h"
#include "QskQuick.h"
#include "QskWindow.h"
#include "QskEvent.h"
QSK_QT_PRIVATE_BEGIN
#include <private/qquickwindow_p.h>
@ -37,6 +38,18 @@ static void qskSetFocus( QQuickItem* item, bool on )
}
}
static inline void qskSendPopupEvent(
QQuickWindow* window, QskPopup* popup, bool on )
{
if ( window )
{
const auto type = on ? QskEvent::PopupAdded : QskEvent::PopupRemoved;
QskPopupEvent event( type, popup );
QCoreApplication::sendEvent( window, &event );
}
}
namespace
{
class InputGrabber final : public QskInputGrabber
@ -86,8 +99,7 @@ class QskPopup::PrivateData
{
public:
PrivateData()
: inputGrabber( nullptr )
, flags( 0 )
: flags( 0 )
, isModal( false )
, isOpen( false )
, autoGrabFocus( true )
@ -95,7 +107,9 @@ class QskPopup::PrivateData
{
}
InputGrabber* inputGrabber;
InputGrabber* inputGrabber = nullptr;
uint priority = 0;
int flags : 4;
bool isModal : 1;
@ -119,10 +133,13 @@ QskPopup::QskPopup( QQuickItem* parent )
setFlag( ItemIsFocusScope, true );
setTabFence( true );
setFocusPolicy( Qt::StrongFocus );
qskSendPopupEvent( window(), this, true );
}
QskPopup::~QskPopup()
{
qskSendPopupEvent( window(), this, false );
}
void QskPopup::open()
@ -193,6 +210,20 @@ void QskPopup::updateInputGrabber()
}
}
void QskPopup::setPriority( uint priority )
{
if ( m_data->priority != priority )
{
m_data->priority = priority;
Q_EMIT priorityChanged( priority );
}
}
uint QskPopup::priority() const
{
return m_data->priority;
}
void QskPopup::setModal( bool on )
{
if ( on == m_data->isModal )
@ -417,6 +448,21 @@ void QskPopup::itemChange( QQuickItem::ItemChange change,
}
}
}
else if ( change == QQuickItem::ItemParentHasChanged )
{
delete m_data->inputGrabber;
m_data->inputGrabber = nullptr;
updateInputGrabber();
}
}
void QskPopup::windowChangeEvent( QskWindowChangeEvent* event )
{
qskSendPopupEvent( event->oldWindow(), this, false );
qskSendPopupEvent( event->window(), this, true );
Inherited::windowChangeEvent( event );
}
#include "moc_QskPopup.cpp"

View File

@ -14,6 +14,7 @@ class QSK_EXPORT QskPopup : public QskControl
Q_PROPERTY( bool modal READ isModal WRITE setModal NOTIFY modalChanged )
Q_PROPERTY( bool overlay READ hasOverlay WRITE setOverlay NOTIFY overlayChanged )
Q_PROPERTY( uint priority READ priority WRITE setPriority NOTIFY priorityChanged )
using Inherited = QskControl;
@ -45,6 +46,10 @@ class QSK_EXPORT QskPopup : public QskControl
void setOverlay( bool on = true );
bool hasOverlay() const;
// allows for stacking according to priorities
void setPriority( uint );
uint priority() const;
virtual QRectF overlayRect() const;
bool isOpen() const;
@ -57,6 +62,7 @@ class QSK_EXPORT QskPopup : public QskControl
void closed();
void modalChanged( bool );
void overlayChanged( bool );
void priorityChanged( uint );
protected:
void aboutToShow() override;
@ -65,6 +71,7 @@ class QSK_EXPORT QskPopup : public QskControl
bool event( QEvent* ) override;
void focusInEvent( QFocusEvent* ) override;
void focusOutEvent( QFocusEvent* ) override;
void windowChangeEvent( QskWindowChangeEvent* ) override;
void itemChange( QQuickItem::ItemChange,
const QQuickItem::ItemChangeData& ) override;

View File

@ -50,13 +50,13 @@ namespace
class ChildListener final : public QQuickItemChangeListener
{
public:
void setEnabled( QQuickItem* item, bool on )
void setEnabled( QQuickItem* contentItem, bool on )
{
m_item = item;
m_contentItem = contentItem;
const QQuickItemPrivate::ChangeTypes types = QQuickItemPrivate::Children;
QQuickItemPrivate* p = QQuickItemPrivate::get( item );
QQuickItemPrivate* p = QQuickItemPrivate::get( contentItem );
if ( on )
p->addItemChangeListener( this, types );
else
@ -65,16 +65,16 @@ namespace
void itemChildAdded( QQuickItem*, QQuickItem* ) override
{
QskWindow* window = static_cast< QskWindow* >( m_item->window() );
QskWindow* window = static_cast< QskWindow* >( m_contentItem->window() );
if ( window->isExposed() )
{
// the child might not be fully constructed, better delay update
// the child is not fully constructed
QCoreApplication::postEvent( window, new QEvent( QEvent::LayoutRequest ) );
}
}
private:
QQuickItem* m_item;
QQuickItem* m_contentItem;
};
}