added checkable menus and sub menus

This commit is contained in:
ZappoMan 2014-02-24 23:42:05 -08:00
parent a3d0c20516
commit 374b12980b
3 changed files with 240 additions and 74 deletions

View file

@ -10,25 +10,44 @@
function setupMenus() {
Menu.addTopMenu("Foo");
Menu.addMenu("Foo");
Menu.addMenuItem("Foo","Foo item 1", "SHIFT+CTRL+F" );
Menu.addMenuItem("Foo","Foo item 2", "SHIFT+F" );
Menu.addMenuItem("Foo","Foo item 3", "META+F" );
Menu.addMenuItem("Foo","Foo item 4", "ALT+F" );
Menu.addTopMenu("Bar");
Menu.addCheckableMenuItem("Foo","Foo item 4", "ALT+F", true);
Menu.addMenuItem("Foo","Remove Foo item 4");
Menu.addMenuItem("Foo","Remove Foo");
Menu.addMenu("Bar");
Menu.addMenuItemWithKeyEvent("Bar","Bar item 1", { text: "b" } );
Menu.addMenuItemWithKeyEvent("Bar","Bar item 2", { text: "B", isControl: true } );
Menu.addMenu("Bar > Spam");
Menu.addMenuItem("Bar > Spam","Spam item 1");
Menu.addCheckableMenuItem("Bar > Spam","Spam item 2",false);
Menu.addMenuItem("Bar > Spam","Remove Spam item 2");
Menu.addMenuItem("Foo","Remove Spam item 2");
}
function scriptEnding() {
print("SCRIPT ENDNG!!!\n");
Menu.removeTopMenu("Foo");
Menu.removeTopMenu("Bar");
Menu.removeMenu("Foo");
Menu.removeMenu("Bar");
}
function menuItemEvent(menuItem) {
print("menuItemEvent() in JS... menuItem=" + menuItem);
if (menuItem == "Foo item 4") {
print(" checked=" + Menu.isOptionChecked("Foo item 4"));
}
if (menuItem == "Remove Foo item 4") {
Menu.removeMenuItem("Foo", "Foo item 4");
}
if (menuItem == "Remove Foo") {
Menu.removeMenu("Foo");
}
if (menuItem == "Remove Spam item 2") {
Menu.removeMenuItem("Bar > Spam", "Spam item 2");
}
}
setupMenus();

View file

@ -1286,63 +1286,162 @@ QString Menu::replaceLastOccurrence(QChar search, QChar replace, QString string)
return string;
}
void Menu::addTopMenu(const QString& menu) {
addMenu(menu);
QMenuBar::repaint();
QList<QAction*> topLevelMenus = actions();
foreach (QAction* topLevelMenuAction, topLevelMenus) {
qDebug() << "menu:" << topLevelMenuAction->text();
QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) {
QList<QAction*> menuActions;
if (menu) {
menuActions = menu->actions();
} else {
menuActions = actions();
}
}
void Menu::removeTopMenu(const QString& menu) {
QList<QAction*> topLevelMenus = actions();
foreach (QAction* topLevelMenuAction, topLevelMenus) {
if (topLevelMenuAction->text() == menu) {
QMenuBar::removeAction(topLevelMenuAction);
foreach (QAction* menuAction, menuActions) {
if (menuName == menuAction->text()) {
return menuAction;
}
}
return NULL;
}
void Menu::addMenuItem(const QString& menu, const QString& menuitem) {
KeyEvent noKey;
addMenuItem(menu, menuitem, noKey);
QMenu* Menu::getSubMenuFromName(const QString& menuName, QMenu* menu) {
QAction* action = getActionFromName(menuName, menu);
if (action) {
return action->menu();
}
return NULL;
}
void Menu::addMenuItem(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey) {
QKeySequence shortcut(shortcutKey);
addMenuItem(menu, menuitem, shortcut);
QMenu* Menu::getMenuParent(const QString& menuName, QString& finalMenuPart) {
QStringList menuTree = menuName.split(">");
QMenu* parent = NULL;
QMenu* menu = NULL;
foreach (QString menuTreePart, menuTree) {
parent = menu;
finalMenuPart = menuTreePart.trimmed();
menu = getSubMenuFromName(finalMenuPart, parent);
if (!menu) {
break;
}
}
return parent;
}
void Menu::addMenuItem(const QString& menu, const QString& menuitem, const QString& shortcutKey) {
QKeySequence shortcut(shortcutKey);
addMenuItem(menu, menuitem, shortcut);
QMenu* Menu::getMenu(const QString& menuName) {
QStringList menuTree = menuName.split(">");
QMenu* parent = NULL;
QMenu* menu = NULL;
int item = 0;
foreach (QString menuTreePart, menuTree) {
menu = getSubMenuFromName(menuTreePart.trimmed(), parent);
if (!menu) {
break;
}
parent = menu;
item++;
}
return menu;
}
void Menu::addMenuItem(const QString& menu, const QString& menuitem, const QKeySequence& shortcutKey) {
QList<QAction*> topLevelMenus = actions();
foreach (QAction* topLevelMenuAction, topLevelMenus) {
if (topLevelMenuAction->text() == menu) {
// add the menu item here...
QMenu* menuObj = topLevelMenuAction->menu();
if (menuObj) {
QShortcut* shortcut = new QShortcut(shortcutKey, this);
QAction* menuItemAction = addActionToQMenuAndActionHash(menuObj, menuitem, shortcutKey,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
QAction* Menu::getMenuAction(const QString& menuName) {
QStringList menuTree = menuName.split(">");
QMenu* parent = NULL;
QAction* action = NULL;
foreach (QString menuTreePart, menuTree) {
action = getActionFromName(menuTreePart.trimmed(), parent);
if (!action) {
break;
}
parent = action->menu();
}
return action;
}
connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger()));
QMenu* Menu::addMenu(const QString& menuName) {
QStringList menuTree = menuName.split(">");
QMenu* addTo = NULL;
QMenu* menu = NULL;
foreach (QString menuTreePart, menuTree) {
menu = getSubMenuFromName(menuTreePart.trimmed(), addTo);
if (!menu) {
if (!addTo) {
menu = QMenuBar::addMenu(menuTreePart.trimmed());
} else {
menu = addTo->addMenu(menuTreePart.trimmed());
}
}
addTo = menu;
}
QMenuBar::repaint();
return menu;
}
void Menu::removeMenu(const QString& menuName) {
QAction* action = getMenuAction(menuName);
// only proceed if the menu actually exists
if (action) {
QString finalMenuPart;
QMenu* parent = getMenuParent(menuName, finalMenuPart);
if (parent) {
removeAction(parent, finalMenuPart);
} else {
QMenuBar::removeAction(action);
}
QMenuBar::repaint();
}
}
void Menu::addMenuItem(const QString& menuName, const QString& menuitem, bool checkable, bool checked) {
QMenu* menuObj = getMenu(menuName);
if (menuObj) {
if (checkable) {
addCheckableActionToQMenuAndActionHash(menuObj, menuitem, 0, checked,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
} else {
addActionToQMenuAndActionHash(menuObj, menuitem, 0,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
}
QMenuBar::repaint();
}
}
void Menu::addMenuItem(const QString& menuName, const QString& menuitem, const KeyEvent& shortcutKey, bool checkable, bool checked) {
QKeySequence shortcut(shortcutKey);
addMenuItem(menuName, menuitem, shortcut, checkable, checked);
}
void Menu::addMenuItem(const QString& menuName, const QString& menuitem, const QString& shortcutKey, bool checkable, bool checked) {
QKeySequence shortcut(shortcutKey);
addMenuItem(menuName, menuitem, shortcut, checkable, checked);
}
void Menu::addMenuItem(const QString& menuName, const QString& menuitem, const QKeySequence& shortcutKey, bool checkable, bool checked) {
QMenu* menuObj = getMenu(menuName);
if (menuObj) {
QShortcut* shortcut = new QShortcut(shortcutKey, this);
QAction* menuItemAction;
if (checkable) {
menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, menuitem, shortcutKey, checked,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
} else {
menuItemAction = addActionToQMenuAndActionHash(menuObj, menuitem, shortcutKey,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
}
connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger()));
QMenuBar::repaint();
}
}
void Menu::removeMenuItem(const QString& menu, const QString& menuitem) {
QMenu* menuObj = getMenu(menu);
if (menuObj) {
removeAction(menuObj, menuitem);
}
QMenuBar::repaint();
};
MenuScriptingInterface* MenuScriptingInterface::_instance = NULL;
QMutex MenuScriptingInterface::_instanceMutex;
@ -1373,34 +1472,64 @@ void MenuScriptingInterface::menuItemTriggered() {
}
}
void MenuScriptingInterface::addTopMenu(const QString& menu) {
QMetaObject::invokeMethod(Menu::getInstance(), "addTopMenu", Q_ARG(const QString&, menu));
void MenuScriptingInterface::addMenu(const QString& menu) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenu", Q_ARG(const QString&, menu));
}
void MenuScriptingInterface::removeTopMenu(const QString& menu) {
QMetaObject::invokeMethod(Menu::getInstance(), "removeTopMenu", Q_ARG(const QString&, menu));
void MenuScriptingInterface::removeMenu(const QString& menu) {
QMetaObject::invokeMethod(Menu::getInstance(), "removeMenu", Q_ARG(const QString&, menu));
}
void MenuScriptingInterface::addMenuItemWithKeyEvent(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem),
Q_ARG(const KeyEvent&, shortcutKey));
Q_ARG(const KeyEvent&, shortcutKey),
Q_ARG(bool, false),
Q_ARG(bool, false));
}
void MenuScriptingInterface::addMenuItem(const QString& menu, const QString& menuitem, const QString& shortcutKey) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem),
Q_ARG(const QString&, shortcutKey));
Q_ARG(const QString&, shortcutKey),
Q_ARG(bool, false),
Q_ARG(bool, false));
}
void MenuScriptingInterface::addMenuItem(const QString& menu, const QString& menuitem) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem));
Q_ARG(const QString&, menuitem),
Q_ARG(bool, false),
Q_ARG(bool, false));
}
void MenuScriptingInterface::addCheckableMenuItemWithKeyEvent(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey, bool checked) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem),
Q_ARG(const KeyEvent&, shortcutKey),
Q_ARG(bool, true),
Q_ARG(bool, checked));
}
void MenuScriptingInterface::addCheckableMenuItem(const QString& menu, const QString& menuitem, const QString& shortcutKey, bool checked) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem),
Q_ARG(const QString&, shortcutKey),
Q_ARG(bool, true),
Q_ARG(bool, checked));
}
void MenuScriptingInterface::addCheckableMenuItem(const QString& menu, const QString& menuitem, bool checked) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem),
Q_ARG(bool, true),
Q_ARG(bool, checked));
}
void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString& menuitem) {
@ -1408,3 +1537,11 @@ void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString&
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem));
};
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
return Menu::getInstance()->isOptionChecked(menuOption);
}
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
return Menu::getInstance()->setIsOptionChecked(menuOption, isChecked);
}

View file

@ -113,12 +113,12 @@ public slots:
void goTo();
void pasteToVoxel();
void addTopMenu(const QString& menu);
void removeTopMenu(const QString& menu);
void addMenuItem(const QString& menu, const QString& menuitem);
void addMenuItem(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey);
void addMenuItem(const QString& menu, const QString& menuitem, const QString& shortcutKey);
void addMenuItem(const QString& topMenuName, const QString& menuitem, const QKeySequence& shortcutKey);
QMenu* addMenu(const QString& menu);
void removeMenu(const QString& menu);
void addMenuItem(const QString& menu, const QString& menuitem, bool checkable, bool checked);
void addMenuItem(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey, bool checkable, bool checked);
void addMenuItem(const QString& menu, const QString& menuitem, const QString& shortcutKey, bool checkable, bool checked);
void addMenuItem(const QString& topMenuName, const QString& menuitem, const QKeySequence& shortcutKey, bool checkable, bool checked);
void removeMenuItem(const QString& menu, const QString& menuitem);
@ -164,6 +164,14 @@ private:
void addAvatarCollisionSubMenu(QMenu* overMenu);
QAction* getActionFromName(const QString& menuName, QMenu* menu);
QMenu* getSubMenuFromName(const QString& menuName, QMenu* menu);
QMenu* getMenuParent(const QString& menuName, QString& finalMenuPart);
QAction* getMenuAction(const QString& menuName);
QMenu* getMenu(const QString& menuName);
QHash<QString, QAction*> _actionHash;
int _audioJitterBufferSamples; /// number of extra samples to wait before starting audio playback
BandwidthDialog* _bandwidthDialog;
@ -318,27 +326,29 @@ class MenuScriptingInterface : public QObject {
public:
static MenuScriptingInterface* getInstance();
static void deleteLaterIfExists();
public slots:
void addTopMenu(const QString& topMenuName);
void removeTopMenu(const QString& topMenuName);
// TODO: how should we expose general nested sub menus to JS
// we could use a string qualifier, like "Developer > Voxel Options" but that has the side effect of
// preventing use of whatever stop character we pick.
//
// we could use a string array, but that makes things a little harder for the JS user
//
//void addSubMenu(const QString& topMenuName, const QString& menuitem);
//void removeSubMenu(const QString& topMenuName, const QString& menuitem);
void addMenuItemWithKeyEvent(const QString& topMenuName, const QString& menuitem, const KeyEvent& shortcutKey);
void addMenuItem(const QString& topMenuName, const QString& menuitem, const QString& shortcutKey);
void addMenuItem(const QString& topMenuName, const QString& menuitem);
void removeMenuItem(const QString& topMenuName, const QString& menuitem);
private slots:
friend class Menu;
void menuItemTriggered();
public slots:
void addMenu(const QString& menuName);
void removeMenu(const QString& menuName);
void addMenuItemWithKeyEvent(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey);
void addMenuItem(const QString& menuName, const QString& menuitem, const QString& shortcutKey);
void addMenuItem(const QString& menuName, const QString& menuitem);
void addCheckableMenuItemWithKeyEvent(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey, bool checked);
void addCheckableMenuItem(const QString& menuName, const QString& menuitem, const QString& shortcutKey, bool checked);
void addCheckableMenuItem(const QString& menuName, const QString& menuitem, bool checked);
void removeMenuItem(const QString& menuName, const QString& menuitem);
bool isOptionChecked(const QString& menuOption);
void setIsOptionChecked(const QString& menuOption, bool isChecked);
signals:
//void keyPressEvent(const KeyEvent& event);
void menuItemEvent(const QString& menuItem);
private: