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::QskGestureEvent( QskGestureEvent::QskGestureEvent(

View File

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

View File

@ -8,6 +8,7 @@
#include "QskInputGrabber.h" #include "QskInputGrabber.h"
#include "QskQuick.h" #include "QskQuick.h"
#include "QskWindow.h" #include "QskWindow.h"
#include "QskEvent.h"
QSK_QT_PRIVATE_BEGIN QSK_QT_PRIVATE_BEGIN
#include <private/qquickwindow_p.h> #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 namespace
{ {
class InputGrabber final : public QskInputGrabber class InputGrabber final : public QskInputGrabber
@ -86,8 +99,7 @@ class QskPopup::PrivateData
{ {
public: public:
PrivateData() PrivateData()
: inputGrabber( nullptr ) : flags( 0 )
, flags( 0 )
, isModal( false ) , isModal( false )
, isOpen( false ) , isOpen( false )
, autoGrabFocus( true ) , autoGrabFocus( true )
@ -95,7 +107,9 @@ class QskPopup::PrivateData
{ {
} }
InputGrabber* inputGrabber; InputGrabber* inputGrabber = nullptr;
uint priority = 0;
int flags : 4; int flags : 4;
bool isModal : 1; bool isModal : 1;
@ -119,10 +133,13 @@ QskPopup::QskPopup( QQuickItem* parent )
setFlag( ItemIsFocusScope, true ); setFlag( ItemIsFocusScope, true );
setTabFence( true ); setTabFence( true );
setFocusPolicy( Qt::StrongFocus ); setFocusPolicy( Qt::StrongFocus );
qskSendPopupEvent( window(), this, true );
} }
QskPopup::~QskPopup() QskPopup::~QskPopup()
{ {
qskSendPopupEvent( window(), this, false );
} }
void QskPopup::open() 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 ) void QskPopup::setModal( bool on )
{ {
if ( on == m_data->isModal ) 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" #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 modal READ isModal WRITE setModal NOTIFY modalChanged )
Q_PROPERTY( bool overlay READ hasOverlay WRITE setOverlay NOTIFY overlayChanged ) Q_PROPERTY( bool overlay READ hasOverlay WRITE setOverlay NOTIFY overlayChanged )
Q_PROPERTY( uint priority READ priority WRITE setPriority NOTIFY priorityChanged )
using Inherited = QskControl; using Inherited = QskControl;
@ -45,6 +46,10 @@ class QSK_EXPORT QskPopup : public QskControl
void setOverlay( bool on = true ); void setOverlay( bool on = true );
bool hasOverlay() const; bool hasOverlay() const;
// allows for stacking according to priorities
void setPriority( uint );
uint priority() const;
virtual QRectF overlayRect() const; virtual QRectF overlayRect() const;
bool isOpen() const; bool isOpen() const;
@ -57,6 +62,7 @@ class QSK_EXPORT QskPopup : public QskControl
void closed(); void closed();
void modalChanged( bool ); void modalChanged( bool );
void overlayChanged( bool ); void overlayChanged( bool );
void priorityChanged( uint );
protected: protected:
void aboutToShow() override; void aboutToShow() override;
@ -65,6 +71,7 @@ class QSK_EXPORT QskPopup : public QskControl
bool event( QEvent* ) override; bool event( QEvent* ) override;
void focusInEvent( QFocusEvent* ) override; void focusInEvent( QFocusEvent* ) override;
void focusOutEvent( QFocusEvent* ) override; void focusOutEvent( QFocusEvent* ) override;
void windowChangeEvent( QskWindowChangeEvent* ) override;
void itemChange( QQuickItem::ItemChange, void itemChange( QQuickItem::ItemChange,
const QQuickItem::ItemChangeData& ) override; const QQuickItem::ItemChangeData& ) override;

View File

@ -50,13 +50,13 @@ namespace
class ChildListener final : public QQuickItemChangeListener class ChildListener final : public QQuickItemChangeListener
{ {
public: 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; const QQuickItemPrivate::ChangeTypes types = QQuickItemPrivate::Children;
QQuickItemPrivate* p = QQuickItemPrivate::get( item ); QQuickItemPrivate* p = QQuickItemPrivate::get( contentItem );
if ( on ) if ( on )
p->addItemChangeListener( this, types ); p->addItemChangeListener( this, types );
else else
@ -65,16 +65,16 @@ namespace
void itemChildAdded( QQuickItem*, QQuickItem* ) override void itemChildAdded( QQuickItem*, QQuickItem* ) override
{ {
QskWindow* window = static_cast< QskWindow* >( m_item->window() ); QskWindow* window = static_cast< QskWindow* >( m_contentItem->window() );
if ( window->isExposed() ) 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 ) ); QCoreApplication::postEvent( window, new QEvent( QEvent::LayoutRequest ) );
} }
} }
private: private:
QQuickItem* m_item; QQuickItem* m_contentItem;
}; };
} }