added support for MenuItemProperties for addMenuItem, removed some cruft, beginning support for menu item placement

This commit is contained in:
ZappoMan 2014-02-25 10:23:59 -08:00
parent cb01c1ee10
commit 74d48ab239
7 changed files with 239 additions and 90 deletions

View file

@ -14,19 +14,41 @@ function setupMenus() {
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.addCheckableMenuItem("Foo","Foo item 4", "ALT+F", true);
Menu.addCheckableMenuItem("Foo","Foo item 4", true);
Menu.addMenuItem({
menuName: "Foo",
menuItemName: "Foo item 5",
shortcutKey: "ALT+F",
isCheckable: true,
isChecked: true
});
Menu.addSeparator("Foo","Removable Tools");
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.addMenuItem("Bar","Bar item 1", "b");
Menu.addMenuItem({
menuName: "Bar",
menuItemName: "Bar item 2",
shortcutKeyEvent: { text: "B", isControl: true }
});
Menu.addMenu("Bar > Spam");
Menu.addMenuItem("Bar > Spam","Spam item 1");
Menu.addCheckableMenuItem("Bar > Spam","Spam item 2",false);
Menu.addSeparator("Bar > Spam","Other Items");
Menu.addMenuItem("Bar > Spam","Remove Spam item 2");
Menu.addMenuItem("Foo","Remove Spam item 2");
Menu.addMenuItem({ menuName: "Foo",
menuItemName: "Remove Spam item 2"
});
}
function scriptEnding() {

View file

@ -171,6 +171,13 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ClickToFly);
addAvatarCollisionSubMenu(editMenu);
/**
// test insert in middle of edit...
QAction* physics = getMenuAction("Edit>Physics");
QAction* testHack = new QAction("test", editMenu);
editMenu->insertAction(physics, testHack);
**/
QMenu* toolsMenu = addMenu("Tools");
@ -681,7 +688,8 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QKeySequence& shortcut,
const QObject* receiver,
const char* member,
QAction::MenuRole role) {
QAction::MenuRole role,
int menuItemLocation) {
QAction* action;
if (receiver && member) {
@ -702,8 +710,11 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
const QKeySequence& shortcut,
const bool checked,
const QObject* receiver,
const char* member) {
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member);
const char* member,
int menuItemLocation) {
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member,
QAction::NoRole, menuItemLocation);
action->setCheckable(true);
action->setChecked(checked);
@ -1400,44 +1411,33 @@ void Menu::addSeparator(const QString& menuName, const QString& separatorName) {
}
}
void Menu::addMenuItem(const QString& menuName, const QString& menuitem, bool checkable, bool checked) {
QMenu* menuObj = getMenu(menuName);
void Menu::addMenuItem(const MenuItemProperties& properties) {
QMenu* menuObj = getMenu(properties.menuName);
if (menuObj) {
if (checkable) {
addCheckableActionToQMenuAndActionHash(menuObj, menuitem, 0, checked,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
} else {
addActionToQMenuAndActionHash(menuObj, menuitem, 0,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
QShortcut* shortcut = NULL;
if (!properties.shortcutKeySequence.isEmpty()) {
shortcut = new QShortcut(properties.shortcutKey, this);
}
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);
/**
// test insert in middle of menu...
QAction* physics = getMenuAction("Edit>Physics");
QAction* testHack = new QAction("test", editMenu);
editMenu->insertAction(gravity, testHack);
**/
QAction* menuItemAction;
if (checkable) {
menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, menuitem, shortcutKey, checked,
if (properties.isCheckable) {
menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName,
properties.shortcutKeySequence, properties.isChecked,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
} else {
menuItemAction = addActionToQMenuAndActionHash(menuObj, menuitem, shortcutKey,
menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
}
connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger()));
if (shortcut) {
connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger()));
}
QMenuBar::repaint();
}
}
@ -1494,56 +1494,29 @@ void MenuScriptingInterface::addSeparator(const QString& menuName, const QString
Q_ARG(const QString&, separatorName));
}
void MenuScriptingInterface::addMenuItemWithKeyEvent(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem),
Q_ARG(const KeyEvent&, shortcutKey),
Q_ARG(bool, false),
Q_ARG(bool, false));
void MenuScriptingInterface::addMenuItem(const MenuItemProperties& properties) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
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(bool, false),
Q_ARG(bool, false));
MenuItemProperties properties(menu, menuitem, shortcutKey);
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
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(bool, false),
Q_ARG(bool, false));
MenuItemProperties properties(menu, menuitem);
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
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,
const QString& shortcutKey, bool checked) {
MenuItemProperties properties(menu, menuitem, shortcutKey, true, checked);
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
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));
MenuItemProperties properties(menu, menuitem, "", true, checked);
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString& menuitem) {

View file

@ -16,6 +16,7 @@
#include <AbstractMenuInterface.h>
#include <EventTypes.h>
#include <MenuTypes.h>
const float ADJUST_LOD_DOWN_FPS = 40.0;
const float ADJUST_LOD_UP_FPS = 55.0;
@ -53,6 +54,7 @@ class BandwidthDialog;
class LodToolsDialog;
class MetavoxelEditor;
class VoxelStatsDialog;
class MenuItemProperties;
class Menu : public QMenuBar, public AbstractMenuInterface {
Q_OBJECT
@ -96,7 +98,8 @@ public:
const QKeySequence& shortcut = 0,
const QObject* receiver = NULL,
const char* member = NULL,
QAction::MenuRole role = QAction::NoRole);
QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = -1);
virtual void removeAction(QMenu* menu, const QString& actionName);
bool goToDestination(QString destination);
void goToOrientation(QString orientation);
@ -116,13 +119,9 @@ public slots:
QMenu* addMenu(const QString& menuName);
void removeMenu(const QString& menuName);
void addSeparator(const QString& menuName, const QString& separatorName);
void addMenuItem(const QString& menuName, const QString& menuitem, bool checkable, bool checked);
void addMenuItem(const QString& menuName, const QString& menuitem, const KeyEvent& shortcutKey, bool checkable, bool checked);
void addMenuItem(const QString& menuName, const QString& menuitem, const QString& shortcutKey, bool checkable, bool checked);
void addMenuItem(const QString& menuName, const QString& menuitem, const QKeySequence& shortcutKey, bool checkable, bool checked);
void addMenuItem(const MenuItemProperties& properties);
void removeMenuItem(const QString& menuName, const QString& menuitem);
private slots:
void aboutApp();
void login();
@ -159,7 +158,8 @@ private:
const QKeySequence& shortcut = 0,
const bool checked = false,
const QObject* receiver = NULL,
const char* member = NULL);
const char* member = NULL,
int menuItemLocation = -1);
void updateFrustumRenderModeAction();
@ -320,7 +320,6 @@ namespace MenuOption {
const QString VoxelTextures = "Voxel Textures";
}
class MenuScriptingInterface : public QObject {
Q_OBJECT
MenuScriptingInterface() { };
@ -337,12 +336,10 @@ public slots:
void removeMenu(const QString& menuName);
void addSeparator(const QString& menuName, const QString& separatorName);
void addMenuItemWithKeyEvent(const QString& menu, const QString& menuitem, const KeyEvent& shortcutKey);
void addMenuItem(const MenuItemProperties& properties);
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);

View file

@ -0,0 +1,107 @@
//
// MenuTypes.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 1/28/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
// Used to register meta-types with Qt for very various event types so that they can be exposed to our
// scripting engine
#include <QDebug>
#include <RegisteredMetaTypes.h>
#include "MenuTypes.h"
MenuItemProperties::MenuItemProperties() :
menuName(""),
menuItemName(""),
shortcutKey(""),
shortcutKeyEvent(),
shortcutKeySequence(),
position(-1),
beforeItem(""),
afterItem(""),
isCheckable(false),
isChecked(false)
{
};
MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& menuItemName,
const QString& shortcutKey, bool checkable, bool checked) :
menuName(menuName),
menuItemName(menuItemName),
shortcutKey(shortcutKey),
shortcutKeyEvent(),
shortcutKeySequence(shortcutKey),
position(-1),
beforeItem(""),
afterItem(""),
isCheckable(checkable),
isChecked(checked)
{
}
MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& menuItemName,
const KeyEvent& shortcutKeyEvent, bool checkable, bool checked) :
menuName(menuName),
menuItemName(menuItemName),
shortcutKey(""),
shortcutKeyEvent(shortcutKeyEvent),
shortcutKeySequence(shortcutKeyEvent),
position(-1),
beforeItem(""),
afterItem(""),
isCheckable(checkable),
isChecked(checked)
{
qDebug() << "MenuItemProperties::MenuItemProperties(... KeyEvent... )";
qDebug() << "shortcutKeyEvent.text=" << shortcutKeyEvent.text;
qDebug() << "shortcutKeyEvent.key=" << shortcutKeyEvent.key;
qDebug() << "shortcutKeyEvent.isControl=" << shortcutKeyEvent.isControl;
qDebug() << "shortcutKeySequence=" << shortcutKeySequence;
}
void registerMenuTypes(QScriptEngine* engine) {
qScriptRegisterMetaType(engine, menuItemPropertiesToScriptValue, menuItemPropertiesFromScriptValue);
}
QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuItemProperties& properties) {
QScriptValue obj = engine->newObject();
// not supported
return obj;
}
void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemProperties& properties) {
properties.menuName = object.property("menuName").toVariant().toString();
properties.menuItemName = object.property("menuItemName").toVariant().toString();
properties.isCheckable = object.property("isCheckable").toVariant().toBool();
properties.isChecked = object.property("isChecked").toVariant().toBool();
// handle the shortcut key options in order...
QScriptValue shortcutKeyValue = object.property("shortcutKey");
if (shortcutKeyValue.isValid()) {
qDebug() << "got shortcutKey...";
properties.shortcutKey = shortcutKeyValue.toVariant().toString();
properties.shortcutKeySequence = properties.shortcutKey;
} else {
qDebug() << "testing shortcutKeyEvent...";
QScriptValue shortcutKeyEventValue = object.property("shortcutKeyEvent");
if (shortcutKeyEventValue.isValid()) {
qDebug() << "got shortcutKeyEvent...";
keyEventFromScriptValue(shortcutKeyEventValue, properties.shortcutKeyEvent);
qDebug() << "shortcutKeyEvent.text=" << properties.shortcutKeyEvent.text;
qDebug() << "shortcutKeyEvent.key=" << properties.shortcutKeyEvent.key;
qDebug() << "shortcutKeyEvent.isControl=" << properties.shortcutKeyEvent.isControl;
properties.shortcutKeySequence = properties.shortcutKeyEvent;
qDebug() << "shortcutKeySequence=" << properties.shortcutKeySequence;
}
}
properties.position = object.property("position").toVariant().toInt();
properties.beforeItem = object.property("beforeItem").toVariant().toString();
properties.afterItem = object.property("afterItem").toVariant().toString();
}

View file

@ -0,0 +1,48 @@
//
// MenuTypes.h
// hifi
//
// Created by Brad Hefta-Gaub on 1/28/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
#ifndef __hifi_MenuTypes_h__
#define __hifi_MenuTypes_h__
#include <QtScript/QScriptEngine>
#include "EventTypes.h"
class MenuItemProperties {
public:
MenuItemProperties();
MenuItemProperties(const QString& menuName, const QString& menuItemName,
const QString& shortcutKey = QString(""), bool checkable = false, bool checked = false);
MenuItemProperties(const QString& menuName, const QString& menuItemName,
const KeyEvent& shortcutKeyEvent, bool checkable = false, bool checked = false);
QString menuName;
QString menuItemName;
// Shortcut key items: in order of priority
QString shortcutKey;
KeyEvent shortcutKeyEvent;
QKeySequence shortcutKeySequence; // this is what we actually use, it's set from one of the above
// location related items: in order of priority
int position;
QString beforeItem;
QString afterItem;
// other properties
bool isCheckable;
bool isChecked;
};
Q_DECLARE_METATYPE(MenuItemProperties)
QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuItemProperties& props);
void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemProperties& props);
void registerMenuTypes(QScriptEngine* engine);
#endif // __hifi_MenuTypes_h__

View file

@ -24,6 +24,7 @@
#include <Sound.h>
#include "MenuTypes.h"
#include "ScriptEngine.h"
const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
@ -136,8 +137,8 @@ void ScriptEngine::init() {
// register various meta-types
registerMetaTypes(&_engine);
registerVoxelMetaTypes(&_engine);
//registerParticleMetaTypes(&_engine);
registerEventTypes(&_engine);
registerMenuTypes(&_engine);
qScriptRegisterMetaType(&_engine, ParticlePropertiesToScriptValue, ParticlePropertiesFromScriptValue);
qScriptRegisterMetaType(&_engine, ParticleIDtoScriptValue, ParticleIDfromScriptValue);

View file

@ -25,7 +25,8 @@ public:
const QKeySequence& shortcut = 0,
const QObject* receiver = NULL,
const char* member = NULL,
QAction::MenuRole role = QAction::NoRole) = 0;
QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = -1) = 0;
virtual void removeAction(QMenu* menu, const QString& actionName) = 0;
};