summaryrefslogtreecommitdiff
path: root/muse2/muse/widgets/popupmenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/widgets/popupmenu.cpp')
-rw-r--r--muse2/muse/widgets/popupmenu.cpp243
1 files changed, 238 insertions, 5 deletions
diff --git a/muse2/muse/widgets/popupmenu.cpp b/muse2/muse/widgets/popupmenu.cpp
index 862bda91..263c8475 100644
--- a/muse2/muse/widgets/popupmenu.cpp
+++ b/muse2/muse/widgets/popupmenu.cpp
@@ -6,25 +6,49 @@
// (C) Copyright 1999-2010 Werner Schweer (ws@seh.de)
//
// PopupMenu sub-class of QMenu created by Tim.
+// (C) Copyright 2010-2011 Tim E. Real (terminator356 A T sourceforge D O T net)
//=========================================================
//#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 +56,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,9 +90,14 @@ 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)
+QAction* PopupMenu::findActionFromData(QVariant v) const
{
QList<QAction*> list = actions();
for(int i = 0; i < list.size(); ++i)
@@ -69,8 +115,194 @@ QAction* PopupMenu::findActionFromData(QVariant v)
return 0;
}
+bool PopupMenu::event(QEvent* event)
+{
+ //printf("PopupMenu::event type:%d\n", event->type()); // REMOVE Tim.
+
+ switch(event->type())
+ {
+ #ifndef POPUP_MENU_DISABLE_STAY_OPEN
+ case QEvent::MouseButtonDblClick:
+ {
+ if(_stayOpen)
+ {
+ QMouseEvent* e = static_cast<QMouseEvent*>(event);
+ if(e->modifiers() == Qt::NoModifier)
+ {
+ event->accept();
+ // Convert into a return press, which selects the item and closes the menu.
+ // Note that with double click, it's a press followed by release followed by double click.
+ // That would toggle our item twice eg on->off->on, which is hopefully OK.
+ QKeyEvent ke(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
+ //ke.ignore(); // Pass it on
+ return QMenu::event(&ke);
+ }
+ }
+ }
+ break;
+ case QEvent::KeyPress:
+ {
+ if(_stayOpen)
+ {
+ QKeyEvent* e = static_cast<QKeyEvent*>(event);
+ if(e->modifiers() == Qt::NoModifier && e->key() == Qt::Key_Space)
+ {
+ QAction* act = activeAction();
+ if(act)
+ {
+ act->trigger();
+ event->accept();
+ return true; // We handled it.
+ }
+ }
+ }
+ }
+ break;
+ #endif // POPUP_MENU_DISABLE_STAY_OPEN
+
+ #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL
+ case 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);
+ }
+ break;
+ #endif // POPUP_MENU_DISABLE_AUTO_SCROLL
+
+ default:
+ break;
+ }
+
+ 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 +338,7 @@ void PopupMenu::mouseReleaseEvent(QMouseEvent *e)
// d->hideUpToMenuBar();
// }
QMenu::mouseReleaseEvent(e);
+ #endif // POPUP_MENU_DISABLE_STAY_OPEN
}
/*