changeset 1587:2108af725460

Add context menus to property box controls
author Chris Cannam
date Fri, 27 Mar 2020 14:36:11 +0000
parents bbc3f537564c
children 0f36e0eca6b0
files widgets/MenuTitle.h widgets/PropertyBox.cpp widgets/PropertyBox.h
diffstat 3 files changed, 64 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/widgets/MenuTitle.h	Fri Mar 27 11:04:56 2020 +0000
+++ b/widgets/MenuTitle.h	Fri Mar 27 14:36:11 2020 +0000
@@ -21,6 +21,7 @@
 #include <QWidgetAction>
 #include <QLabel>
 #include <QApplication>
+#include <QMenu>
 
 class MenuTitle
 {
--- a/widgets/PropertyBox.cpp	Fri Mar 27 11:04:56 2020 +0000
+++ b/widgets/PropertyBox.cpp	Fri Mar 27 14:36:11 2020 +0000
@@ -29,6 +29,7 @@
 #include "LevelPanWidget.h"
 #include "LevelPanToolButton.h"
 #include "WidgetScale.h"
+#include "MenuTitle.h"
 
 #include "NotifyingCheckBox.h"
 #include "NotifyingComboBox.h"
@@ -48,6 +49,7 @@
 #include <QColorDialog>
 #include <QInputDialog>
 #include <QDir>
+#include <QMenu>
 
 #include <cassert>
 #include <iostream>
@@ -58,7 +60,8 @@
 PropertyBox::PropertyBox(PropertyContainer *container) :
     m_container(container),
     m_showButton(nullptr),
-    m_playButton(nullptr)
+    m_playButton(nullptr),
+    m_lastContextMenu(nullptr)
 {
 #ifdef DEBUG_PROPERTY_BOX
     SVDEBUG << "PropertyBox[" << this << "(\"" <<
@@ -118,6 +121,7 @@
 #ifdef DEBUG_PROPERTY_BOX
     SVDEBUG << "PropertyBox[" << this << "]::~PropertyBox" << endl;
 #endif
+    delete m_lastContextMenu;
 }
 
 void
@@ -328,6 +332,10 @@
                     this, SLOT(mouseLeftWidget()));
             button->setToolTip(propertyLabel);
 
+            button->setContextMenuPolicy(Qt::CustomContextMenu);
+            connect(button, SIGNAL(customContextMenuRequested(const QPoint &)),
+                    this, SLOT(contextMenuRequested(const QPoint &)));
+
             if (existing) {
                 groupLayout->replaceWidget(existing, button);
                 delete existing;
@@ -422,6 +430,10 @@
 
             cb->setToolTip(propertyLabel);
 
+            cb->setContextMenuPolicy(Qt::CustomContextMenu);
+            connect(cb, SIGNAL(customContextMenuRequested(const QPoint &)),
+                    this, SLOT(contextMenuRequested(const QPoint &)));
+
             if (existing) {
                 groupLayout->replaceWidget(existing, cb);
                 delete existing;
@@ -535,6 +547,11 @@
                     this, SLOT(mouseLeftWidget()));
 
             cb->setToolTip(propertyLabel);
+
+            cb->setContextMenuPolicy(Qt::CustomContextMenu);
+            connect(cb, SIGNAL(customContextMenuRequested(const QPoint &)),
+                    this, SLOT(contextMenuRequested(const QPoint &)));
+            
             groupLayout->addWidget(cb, 0, groupLayout->columnCount());
             m_propertyControllers[name] = cb;
         } else if (existing != cb) {
@@ -667,6 +684,47 @@
 }
 
 void
+PropertyBox::contextMenuRequested(const QPoint &pos)
+{
+    QObject *obj = sender();
+    QString name = obj->objectName();
+    
+    PropertyContainer::PropertyType type = m_container->getPropertyType(name);
+    QString label = m_container->getPropertyLabel(name);
+    int min = 0, max = 0, value = 0, deflt = 0;
+    value = m_container->getPropertyRangeAndValue(name, &min, &max, &deflt);
+
+    delete m_lastContextMenu;
+    QMenu *m = new QMenu;
+    m_lastContextMenu = m;
+
+    if (auto button = qobject_cast<QAbstractButton *>(obj)) {
+        if (value > 0) {
+            MenuTitle::addTitle(m, tr("%1: On").arg(label));
+        } else {
+            MenuTitle::addTitle(m, tr("%1: Off").arg(label));
+        }
+
+        m->addAction(tr("&Reset to Default"),
+                     [=]() {
+                         button->setChecked(deflt > 0);
+                     });
+
+    } else if (auto cb = qobject_cast<QComboBox *>(obj)) {
+        MenuTitle::addTitle(m, tr("%1: %2").arg(label).arg(cb->itemText(value)));
+        m->addAction(tr("&Reset to Default"),
+                     [=]() {
+                         cb->setCurrentIndex(deflt);
+                     });
+    } else {
+        // AudioDial has its own context menu, we don't handle it here
+        return;
+    }
+        
+    m->popup(qobject_cast<QWidget *>(sender())->mapToGlobal(pos));
+}
+
+void
 PropertyBox::playAudibleChanged(bool audible)
 {
     m_playButton->setChecked(audible);
--- a/widgets/PropertyBox.h	Fri Mar 27 11:04:56 2020 +0000
+++ b/widgets/PropertyBox.h	Fri Mar 27 14:36:11 2020 +0000
@@ -29,6 +29,7 @@
 class LEDButton;
 class QToolButton;
 class NotifyingPushButton;
+class QMenu;
 
 class PropertyBox : public QFrame
 {
@@ -68,6 +69,8 @@
     void mouseEnteredWidget();
     void mouseLeftWidget();
 
+    void contextMenuRequested(const QPoint &);
+
 protected:
     void updatePropertyEditor(PropertyContainer::PropertyName,
                               bool rangeChanged = false);
@@ -81,6 +84,7 @@
     QVBoxLayout *m_mainBox;
     LEDButton *m_showButton;
     QToolButton *m_playButton;
+    QMenu *m_lastContextMenu;
     std::map<QString, QGridLayout *> m_groupLayouts;
     std::map<QString, QWidget *> m_propertyControllers;
 };