diff --git a/examples/qvgviewer/MainWindow.cpp b/examples/qvgviewer/MainWindow.cpp index 2c220ffc..5b9d8c55 100644 --- a/examples/qvgviewer/MainWindow.cpp +++ b/examples/qvgviewer/MainWindow.cpp @@ -95,10 +95,9 @@ class GraphicLabel : public QskGraphicLabel menu.setOrigin( qskMousePosition( event ) ); - if ( int result = menu.exec() ) - { - qDebug() << result; - } + const int result = menu.exec(); + if ( result >= 0 ) + qDebug() << "Selected:" << result; } #endif }; diff --git a/src/controls/QskMenu.cpp b/src/controls/QskMenu.cpp index 746b656d..c291f6a0 100644 --- a/src/controls/QskMenu.cpp +++ b/src/controls/QskMenu.cpp @@ -37,8 +37,9 @@ class QskMenu::PrivateData QskTextOptions textOptions; QPointF origin; + // current/selected are not well defined yet, TODO ... int currentIndex = -1; - int triggeredIndex = -1; + int selectedIndex = -1; bool isPressed = false; }; @@ -331,7 +332,7 @@ void QskMenu::setSelectedIndex( int index ) if ( index >= 0 ) setCurrentIndex( index ); - m_data->triggeredIndex = index; + m_data->selectedIndex = index; Q_EMIT triggered( index ); close(); @@ -349,68 +350,11 @@ int QskMenu::indexAtPosition( const QPointF& pos ) const this, contentsRect(), QskMenu::Cell, pos ); } -namespace -{ - class EventLoop : public QEventLoop - { - public: - EventLoop( QskMenu* menu ) - : QEventLoop( menu ) - { - /* - We want menu being the parent, so that the loop can be found - by menu->findChild< QEventLoop* >(). - */ - - connect( menu, &QObject::destroyed, this, &EventLoop::reject ); - connect( menu, &QskMenu::fadingChanged, this, &EventLoop::maybeQuit ); - } - - private: - void reject() - { - setParent( nullptr ); - quit(); - } - - void maybeQuit() - { - auto menu = static_cast< const QskMenu* >( parent() ); - if ( !menu->isOpen() && !menu->isFading() ) - quit(); - } - }; -} - int QskMenu::exec() { - if ( isOpen() || isFading() ) - { - qWarning() << "QskMenu::exec: menu is already opened"; - return -1; - } - - const bool deleteOnClose = popupFlags() & QskPopup::DeleteOnClose; - if ( deleteOnClose ) - setPopupFlag( QskPopup::DeleteOnClose, false ); - - QPointer< QskMenu > menu = this; - menu->open(); - - EventLoop loop( this ); - (void )loop.exec( QEventLoop::DialogExec ); - - int result = -1; - - if ( menu ) - { - result = menu->m_data->triggeredIndex; - - if ( deleteOnClose ) - delete menu; - } - - return result; + m_data->selectedIndex = -1; + (void) execPopup(); + return m_data->selectedIndex; } #include "moc_QskMenu.cpp" diff --git a/src/controls/QskPopup.cpp b/src/controls/QskPopup.cpp index dd203e0d..89f9cef3 100644 --- a/src/controls/QskPopup.cpp +++ b/src/controls/QskPopup.cpp @@ -623,4 +623,72 @@ void QskPopup::windowChangeEvent( QskWindowChangeEvent* event ) Inherited::windowChangeEvent( event ); } +int QskPopup::execPopup() +{ + class EventLoop : public QEventLoop + { + public: + EventLoop( QskPopup* popup ) + : QEventLoop( popup ) + { + /* + We want popup being the parent, so that the loop can be found + by popup->findChild< QEventLoop* >() + */ + + connect( popup, &QObject::destroyed, this, &EventLoop::reject ); + connect( popup, &QskPopup::fadingChanged, this, &EventLoop::maybeQuit ); + connect( popup, &QskPopup::openChanged, this, &EventLoop::maybeQuit ); + } + + private: + void reject() + { + setParent( nullptr ); + QEventLoop::exit( 1 ); + } + + void maybeQuit() + { + if ( auto popup = qobject_cast< const QskPopup* >( parent() ) ) + { + if ( popup->isOpen() || popup->isFading() ) + return; + } + + QEventLoop::exit( 0 ); + } + }; + + if ( isOpen() || isFading() ) + { + qWarning() << "QskPopup::exec: popup is already opened"; + return -1; + } + + if ( priority() > 0 ) + { + qWarning( "QskPopup::exec for a popup with non default priority." ); + } + + open(); + + if ( window() == nullptr ) + { + qWarning( "trying to exec a popup without window." ); + return -1; + } + + if ( auto mouseGrabber = window()->mouseGrabberItem() ) + { + // when being called from QQuickWindow::mouseReleaseEvent + // the mouse grabber has not yet been released. + + if( !qskIsAncestorOf( this, mouseGrabber ) ) + qskUngrabMouse( mouseGrabber ); + } + + return EventLoop( this ).exec( QEventLoop::DialogExec ); +} + #include "moc_QskPopup.cpp" diff --git a/src/controls/QskPopup.h b/src/controls/QskPopup.h index bbd7fb10..4aeb5e40 100644 --- a/src/controls/QskPopup.h +++ b/src/controls/QskPopup.h @@ -91,6 +91,7 @@ class QSK_EXPORT QskPopup : public QskControl protected: void aboutToShow() override; + int execPopup(); bool event( QEvent* ) override; void focusInEvent( QFocusEvent* ) override; diff --git a/src/dialogs/QskDialogSubWindow.cpp b/src/dialogs/QskDialogSubWindow.cpp index 486255da..3113c226 100644 --- a/src/dialogs/QskDialogSubWindow.cpp +++ b/src/dialogs/QskDialogSubWindow.cpp @@ -8,7 +8,6 @@ #include "QskPushButton.h" #include "QskQuick.h" -#include #include #include @@ -237,35 +236,8 @@ QskDialog::DialogCode QskDialogSubWindow::result() const QskDialog::DialogCode QskDialogSubWindow::exec() { - if ( priority() > 0 ) - { - qWarning( "illegal call of QskDialogSubWindow::exec " - "for a subwindow with non default priority." ); - } - - open(); - - //check for window after call to open(), because maybe a popupmanager assigns a window on open. - if ( window() == nullptr ) - { - qWarning( "trying to exec a subwindow without window." ); - return QskDialog::Rejected; - } - - if ( auto mouseGrabber = window()->mouseGrabberItem() ) - { - // when being called from QQuickWindow::mouseReleaseEvent - // the mouse grabber has not yet been released. - - if( !qskIsAncestorOf( this, mouseGrabber ) ) - qskUngrabMouse( mouseGrabber ); - } - - QEventLoop eventLoop; - - connect( this, &QskDialogSubWindow::finished, &eventLoop, &QEventLoop::quit ); - ( void ) eventLoop.exec( QEventLoop::DialogExec ); - + m_data->result = QskDialog::Rejected; + ( void ) execPopup(); return m_data->result; }