From 9cef7705d8cb55524279ac2f68cd1c1a3dde4586 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 30 Dec 2021 11:13:48 +0100 Subject: [PATCH] QskMenu::exec added --- examples/qvgviewer/MainWindow.cpp | 20 +++++---- src/controls/QskMenu.cpp | 69 +++++++++++++++++++++++++++++++ src/controls/QskMenu.h | 2 + 3 files changed, 82 insertions(+), 9 deletions(-) diff --git a/examples/qvgviewer/MainWindow.cpp b/examples/qvgviewer/MainWindow.cpp index 14ce76ab..2c220ffc 100644 --- a/examples/qvgviewer/MainWindow.cpp +++ b/examples/qvgviewer/MainWindow.cpp @@ -85,18 +85,20 @@ class GraphicLabel : public QskGraphicLabel protected: void mousePressEvent( QMouseEvent* event ) override { - auto menu = new QskMenu( this ); + QskMenu menu( this ); + menu.setPopupFlag( QskPopup::DeleteOnClose, false ); - menu->addItem( "image://shapes/Rectangle/White", "Print" ); - menu->addItem( "image://shapes/Diamond/Yellow", "Save As" ); - menu->addItem( "image://shapes/Ellipse/Red", "Setup" ); - menu->addItem( "image://shapes/Hexagon/PapayaWhip", "Help" ); + menu.addItem( "image://shapes/Rectangle/White", "Print" ); + menu.addItem( "image://shapes/Diamond/Yellow", "Save As" ); + menu.addItem( "image://shapes/Ellipse/Red", "Setup" ); + menu.addItem( "image://shapes/Hexagon/PapayaWhip", "Help" ); - menu->setOrigin( qskMousePosition( event ) ); - menu->open(); + menu.setOrigin( qskMousePosition( event ) ); - connect( menu, &QskMenu::triggered, - this, []( int index ) { qDebug() << index; } ); + if ( int result = menu.exec() ) + { + qDebug() << result; + } } #endif }; diff --git a/src/controls/QskMenu.cpp b/src/controls/QskMenu.cpp index 31357ba3..746b656d 100644 --- a/src/controls/QskMenu.cpp +++ b/src/controls/QskMenu.cpp @@ -9,6 +9,7 @@ #include #include +#include QSK_SUBCONTROL( QskMenu, Panel ) QSK_SUBCONTROL( QskMenu, Cell ) @@ -37,6 +38,8 @@ class QskMenu::PrivateData QPointF origin; int currentIndex = -1; + int triggeredIndex = -1; + bool isPressed = false; }; @@ -328,7 +331,9 @@ void QskMenu::setSelectedIndex( int index ) if ( index >= 0 ) setCurrentIndex( index ); + m_data->triggeredIndex = index; Q_EMIT triggered( index ); + close(); } @@ -344,4 +349,68 @@ 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; +} + #include "moc_QskMenu.cpp" diff --git a/src/controls/QskMenu.h b/src/controls/QskMenu.h index f56198b9..fcacc858 100644 --- a/src/controls/QskMenu.h +++ b/src/controls/QskMenu.h @@ -66,6 +66,8 @@ class QSK_EXPORT QskMenu : public QskPopup QRectF cellRect( int index ) const; int indexAtPosition( const QPointF& ) const; + Q_INVOKABLE int exec(); + Q_SIGNALS: void cascadingChanged( bool ); void originChanged( const QPointF& );