summaryrefslogtreecommitdiff
path: root/muse2/muse/widgets/popupmenu.cpp
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2011-05-19 07:43:06 +0000
committerTim E. Real <termtech@rogers.com>2011-05-19 07:43:06 +0000
commit0f3ed66e83d6639452a5aa219b9a6bf2bfd54897 (patch)
tree950c324e7301f657cba543d8ccbb268ca40e418f /muse2/muse/widgets/popupmenu.cpp
parent0792c2ec66dacfff10899cbe171cb661871617f1 (diff)
Popup menus now auto-scroll if too large to fit on desktop.
Midi track info patch popup now stays open for auditioning patches. Editor 'ctrl' controller popups: Split instrument/other (+ common controls!) + show ctrl numbers.
Diffstat (limited to 'muse2/muse/widgets/popupmenu.cpp')
-rw-r--r--muse2/muse/widgets/popupmenu.cpp221
1 files changed, 217 insertions, 4 deletions
diff --git a/muse2/muse/widgets/popupmenu.cpp b/muse2/muse/widgets/popupmenu.cpp
index 862bda91..b59e8d43 100644
--- a/muse2/muse/widgets/popupmenu.cpp
+++ b/muse2/muse/widgets/popupmenu.cpp
@@ -10,21 +10,44 @@
//#include <stdio.h>
#include <QMouseEvent>
+#include <QHoverEvent>
#include <QAction>
+#include <QPoint>
+#include <QDesktopWidget>
+#include <QApplication>
+//#include <QTimer>
+
#include <stdio.h>
//#include <QStandardItemModel>
#include "popupmenu.h"
+
//======================
// PopupMenu
//======================
-PopupMenu::PopupMenu(QWidget* parent)
- : QMenu(parent)
+//PopupMenu::PopupMenu()
+//{
+// init();
+//}
+
+PopupMenu::PopupMenu(bool stayOpen)
+ : _stayOpen(stayOpen)
{
- // Menus will trigger! Set to make sure our trigger handlers ignore menus.
- menuAction()->setData(-1);
+ init();
+}
+
+PopupMenu::PopupMenu(QWidget* parent, bool stayOpen)
+ : QMenu(parent), _stayOpen(stayOpen)
+{
+ init();
+}
+
+PopupMenu::PopupMenu(const QString& title, QWidget* parent, bool stayOpen)
+ : QMenu(title, parent), _stayOpen(stayOpen)
+{
+ init();
}
PopupMenu::~PopupMenu()
@@ -32,6 +55,23 @@ PopupMenu::~PopupMenu()
//printf("PopupMenu::~PopupMenu\n");
}
+void PopupMenu::init()
+{
+ // Menus will trigger! Set to make sure our trigger handlers ignore menus.
+ menuAction()->setData(-1);
+
+ //_stayOpen = false;
+ moveDelta = 0;
+
+ #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL
+ timer = new QTimer(this);
+ timer->setInterval(100);
+ timer->setSingleShot(false);
+ connect(this, SIGNAL(hovered(QAction*)), SLOT(popHovered(QAction*)));
+ connect(timer, SIGNAL(timeout()), SLOT(timerHandler()));
+ #endif // POPUP_MENU_DISABLE_AUTO_SCROLL
+}
+
void PopupMenu::clear()
{
QList<QAction*> list = actions();
@@ -49,6 +89,11 @@ void PopupMenu::clear()
// Now let QT remove and delete this menu's actions.
QMenu::clear();
+
+ #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL
+ connect(this, SIGNAL(hovered(QAction*)), SLOT(popHovered(QAction*)));
+ connect(timer, SIGNAL(timeout()), SLOT(timerHandler()));
+ #endif // POPUP_MENU_DISABLE_AUTO_SCROLL
}
QAction* PopupMenu::findActionFromData(QVariant v)
@@ -69,8 +114,175 @@ QAction* PopupMenu::findActionFromData(QVariant v)
return 0;
}
+bool PopupMenu::event(QEvent* event)
+{
+ //printf("PopupMenu::event type:%d\n", event->type()); // REMOVE Tim.
+
+ #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL
+ if(event->type() == QEvent::MouseMove)
+ {
+ QMouseEvent* e = static_cast<QMouseEvent*>(event);
+ QPoint globPos = e->globalPos();
+ //QPoint pos = e->pos();
+ int dw = QApplication::desktop()->width(); // We want the whole thing if multiple monitors.
+
+ //printf("PopupMenu::event MouseMove: pos x:%d y:%d globPos x:%d y:%d\n",
+ // pos.x(), pos.y(), globPos.x(), globPos.y()); // REMOVE Tim.
+
+ /*
+ //QAction* action = actionAt(globPos);
+ QAction* action = actionAt(pos);
+ if(action)
+ {
+ QRect r = actionGeometry(action);
+ //printf(" act x:%d y:%d w:%d h:%d popup px:%d py:%d pw:%d ph:%d\n",
+ // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height()); // REMOVE Tim.
+
+ //action->hover();
+ }
+ */
+
+ if(x() < 0 && globPos.x() <= 0) // If on the very first pixel (or beyond)
+ {
+ moveDelta = 32;
+ if(!timer->isActive())
+ timer->start();
+ event->accept();
+ return true;
+ }
+ else
+ if(x() + width() >= dw && globPos.x() >= (dw -1)) // If on the very last pixel (or beyond)
+ {
+ moveDelta = -32;
+ if(!timer->isActive())
+ timer->start();
+ event->accept();
+ return true;
+ }
+
+ if(timer->isActive())
+ timer->stop();
+
+ //event->accept();
+ //return true;
+
+ event->ignore(); // Pass it on
+ //return QMenu::event(event);
+ }
+ #endif // POPUP_MENU_DISABLE_AUTO_SCROLL
+ /*
+ else
+ if(event->type() == QEvent::HoverEnter)
+ {
+ // Nope! Hovering over menu items did not invoke this.
+ printf("PopupMenu::event hover\n"); // REMOVE Tim.
+ QHoverEvent* he = static_cast<QHoverEvent*>(event);
+ QPoint oldPos = he->oldPos();
+ QPoint pos = he->pos();
+
+ QAction* action = actionAt(pos);
+
+ if(action)
+ {
+ QRect r = actionGeometry(action);
+ printf("PopupMenu::event hover: act x:%d y:%d w:%d h:%d popup px:%d py:%d pw:%d ph:%d\n",
+ r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height()); // REMOVE Tim.
+ printf(" pos x:%d y:%d oldPos px:%d py:%d\n",
+ pos.x(), pos.y(), oldPos.x(), oldPos.y()); // REMOVE Tim.
+
+
+ }
+
+
+ //return true;
+ }
+ */
+
+ return QMenu::event(event);
+}
+
+#ifndef POPUP_MENU_DISABLE_AUTO_SCROLL
+void PopupMenu::timerHandler()
+{
+ // printf("PopupMenu::timerHandler\n"); // REMOVE Tim.
+
+ //if(!isVisible() || !hasFocus())
+ if(!isVisible())
+ {
+ timer->stop();
+ return;
+ }
+
+ int dw = QApplication::desktop()->width(); // We want the whole thing if multiple monitors.
+ int nx = x() + moveDelta;
+ if(moveDelta < 0 && nx + width() < dw)
+ {
+ timer->stop();
+ nx = dw - width();
+ }
+ else
+ if(moveDelta > 0 && nx > 0)
+ {
+ timer->stop();
+ nx = 0;
+ }
+
+ move(nx, y());
+}
+
+void PopupMenu::popHovered(QAction* action)
+{
+ //timer->stop();
+
+ //moveDelta = 0;
+ if(action)
+ {
+ int dw = QApplication::desktop()->width(); // We want the whole thing if multiple monitors.
+
+ QRect r = actionGeometry(action);
+ //printf("PopupMenu::popHovered x:%d y:%d w:%d h:%d px:%d py:%d pw:%d ph:%d\n",
+ // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height()); // REMOVE Tim.
+ //printf("PopupMenu::popHovered x:%d y:%d w:%d h:%d px:%d py:%d pw:%d ph:%d dtw:%d\n",
+ // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height(), dw); // REMOVE Tim.
+ //int x = r.x() + ctrlSubPop->x();
+ if(x() + r.x() < 0)
+ //setGeometry(0, y(), width(), height());
+ //scroll(-x, 0);
+ //move(-r.x() + 32, y()); // Allow some of left column to show so that mouse can move over it.
+ //move(-r.x() + r.width(), y()); // Allow some of left column to show so that mouse can move over it.
+ //moveDelta = x() - r.x() + 32;
+ move(-r.x(), y());
+ else
+ if(r.x() + r.width() + x() > dw)
+ //setGeometry(1200 - r.x() - r.width(), y(), width(), height());
+ //scroll(-x + 1200, 0);
+ //move(dw - r.x() - r.width() - 32, y()); // Allow some of right column to show so that mouse can move over it.
+ //move(dw - r.x(), y()); // Allow some of right column to show so that mouse can move over it.
+ //moveDelta = x() + dw - r.x() - r.width() - 32;
+ move(dw - r.x() - r.width(), y());
+ }
+
+ //if(moveDelta == 0)
+ // timer->stop();
+
+}
+#endif // POPUP_MENU_DISABLE_AUTO_SCROLL
+
void PopupMenu::mouseReleaseEvent(QMouseEvent *e)
{
+ #ifdef POPUP_MENU_DISABLE_STAY_OPEN
+ QMenu::mouseReleaseEvent(e);
+ return;
+
+ #else
+ if(!_stayOpen)
+ {
+ QMenu::mouseReleaseEvent(e);
+ return;
+ }
+
+ //printf("PopupMenu::mouseReleaseEvent\n"); // REMOVE Tim.
+
//Q_D(QMenu);
//if (d->mouseEventTaken(e))
// return;
@@ -106,6 +318,7 @@ void PopupMenu::mouseReleaseEvent(QMouseEvent *e)
// d->hideUpToMenuBar();
// }
QMenu::mouseReleaseEvent(e);
+ #endif // POPUP_MENU_DISABLE_STAY_OPEN
}
/*