implement support for menu item positioning

This commit is contained in:
ZappoMan 2014-02-25 12:19:30 -08:00
parent 0b6e81b8a6
commit 0048099ff5
8 changed files with 111 additions and 61 deletions

View file

@ -12,67 +12,67 @@
var selectedVoxel = { x: 0, y: 0, z: 0, s: 0 };
var selectedSize = 4;
function printKeyEvent(eventName, event) {
print(eventName);
print(" event.key=" + event.key);
print(" event.text=" + event.text);
print(" event.isShifted=" + event.isShifted);
print(" event.isControl=" + event.isControl);
print(" event.isMeta=" + event.isMeta);
print(" event.isAlt=" + event.isAlt);
print(" event.isKeypad=" + event.isKeypad);
function setupMenus() {
// hook up menus
Menu.menuItemEvent.connect(menuItemEvent);
// delete the standard application menu item
Menu.removeMenuItem("Edit", "Cut");
Menu.removeMenuItem("Edit", "Copy");
Menu.removeMenuItem("Edit", "Paste");
Menu.removeMenuItem("Edit", "Delete");
Menu.removeMenuItem("Edit", "Nudge");
Menu.removeMenuItem("File", "Export Voxels");
Menu.removeMenuItem("File", "Import Voxels");
// delete the standard application menu item
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Cut", shortcutKey: "CTRL+X", afterItem: "Voxels" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Copy", shortcutKey: "CTRL+C", afterItem: "Cut" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Paste", shortcutKey: "CTRL+V", afterItem: "Copy" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Nudge", shortcutKey: "CTRL+N", afterItem: "Paste" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Delete", shortcutKeyEvent: { text: "backspace" }, afterItem: "Nudge" });
Menu.addMenuItem({ menuName: "File", menuItemName: "Export Voxels", shortcutKey: "CTRL+E", afterItem: "Voxels" });
Menu.addMenuItem({ menuName: "File", menuItemName: "Import Voxels", shortcutKey: "CTRL+I", afterItem: "Export Voxels" });
}
function keyPressEvent(event) {
var debug = false;
function menuItemEvent(menuItem) {
var debug = true;
if (debug) {
printKeyEvent("keyPressEvent", event);
}
}
function keyReleaseEvent(event) {
var debug = false;
if (debug) {
printKeyEvent("keyReleaseEvent", event);
print("menuItemEvent " + menuItem);
}
// Note: this sample uses Alt+ as the key codes for these clipboard items
if ((event.key == 199 || event.key == 67 || event.text == "C" || event.text == "c") && event.isAlt) {
print("the Alt+C key was pressed");
if (menuItem == "Copy") {
print("copying...");
Clipboard.copyVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.key == 8776 || event.key == 88 || event.text == "X" || event.text == "x") && event.isAlt) {
print("the Alt+X key was pressed");
if (menuItem == "Cut") {
print("cutting...");
Clipboard.cutVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.key == 8730 || event.key == 86 || event.text == "V" || event.text == "v") && event.isAlt) {
print("the Alt+V key was pressed");
if (menuItem == "Paste") {
print("pasting...");
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (event.text == "DELETE" || event.text == "BACKSPACE") {
print("the DELETE/BACKSPACE key was pressed");
if (menuItem == "Delete") {
print("deleting...");
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.text == "E" || event.text == "e") && event.isMeta) {
print("the Ctl+E key was pressed");
if (menuItem == "Export Voxels") {
print("export");
Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.text == "I" || event.text == "i") && event.isMeta) {
print("the Ctl+I key was pressed");
if (menuItem == "Import Voxels") {
print("import");
Clipboard.importVoxels();
}
if ((event.key == 78 || event.text == "N" || event.text == "n") && event.isMeta) {
print("the Ctl+N key was pressed, nudging to left 1 meter");
if (menuItem == "Nudge") {
print("nudge");
Clipboard.nudgeVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s, { x: -1, y: 0, z: 0 });
}
}
// Map keyPress and mouse move events to our callbacks
Controller.keyPressEvent.connect(keyPressEvent);
Controller.keyReleaseEvent.connect(keyReleaseEvent);
var selectCube = Overlays.addOverlay("cube", {
position: { x: 0, y: 0, z: 0},
size: selectedSize,
@ -149,3 +149,5 @@ function scriptEnding() {
}
Script.scriptEnding.connect(scriptEnding);
setupMenus();

View file

@ -59,6 +59,18 @@ function setupMenus() {
menuItemName: "Remove Spam item 2"
});
Menu.addMenuItem({
menuName: "Edit",
menuItemName: "before Cut",
beforeItem: "Cut"
});
Menu.addMenuItem({
menuName: "Edit",
menuItemName: "after Nudge",
afterItem: "Nudge"
});
}
function scriptEnding() {

View file

@ -70,8 +70,8 @@ void ClipboardScriptingInterface::exportVoxel(float x, float y, float z, float s
z / (float)TREE_SCALE,
s / (float)TREE_SCALE };
// TODO: should we be calling invokeMethod() in all these cases?
Application::getInstance()->exportVoxels(sourceVoxel);
QMetaObject::invokeMethod(Application::getInstance(), "exportVoxels",
Q_ARG(const VoxelDetail&, sourceVoxel));
}
void ClipboardScriptingInterface::importVoxels() {

View file

@ -690,13 +690,28 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
const char* member,
QAction::MenuRole role,
int menuItemLocation) {
QAction* action;
QAction* action = NULL;
QAction* actionBefore = NULL;
if (receiver && member) {
action = destinationMenu->addAction(actionName, receiver, member, shortcut);
if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) {
actionBefore = destinationMenu->actions()[menuItemLocation];
}
if (!actionBefore) {
if (receiver && member) {
action = destinationMenu->addAction(actionName, receiver, member, shortcut);
} else {
action = destinationMenu->addAction(actionName);
action->setShortcut(shortcut);
}
} else {
action = destinationMenu->addAction(actionName);
action = new QAction(actionName, destinationMenu);
action->setShortcut(shortcut);
destinationMenu->insertAction(actionBefore, action);
if (receiver && member) {
connect(action, SIGNAL(triggered()), receiver, member);
}
}
action->setMenuRole(role);
@ -1366,6 +1381,17 @@ QAction* Menu::getMenuAction(const QString& menuName) {
return action;
}
int Menu::findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem) {
int position = 0;
foreach(QAction* action, menu->actions()) {
if (action->text() == searchMenuItem) {
return position;
}
position++;
}
return UNSPECIFIED_POSITION; // not found
}
QMenu* Menu::addMenu(const QString& menuName) {
QStringList menuTree = menuName.split(">");
QMenu* addTo = NULL;
@ -1416,24 +1442,30 @@ void Menu::addMenuItem(const MenuItemProperties& properties) {
if (menuObj) {
QShortcut* shortcut = NULL;
if (!properties.shortcutKeySequence.isEmpty()) {
shortcut = new QShortcut(properties.shortcutKey, this);
shortcut = new QShortcut(properties.shortcutKeySequence, this);
}
/**
// test insert in middle of menu...
QAction* physics = getMenuAction("Edit>Physics");
QAction* testHack = new QAction("test", editMenu);
editMenu->insertAction(gravity, testHack);
**/
// check for positioning requests
int requestedPosition = properties.position;
if (requestedPosition == UNSPECIFIED_POSITION && !properties.beforeItem.isEmpty()) {
requestedPosition = findPositionOfMenuItem(menuObj, properties.beforeItem);
}
if (requestedPosition == UNSPECIFIED_POSITION && !properties.afterItem.isEmpty()) {
int afterPosition = findPositionOfMenuItem(menuObj, properties.afterItem);
if (afterPosition != UNSPECIFIED_POSITION) {
requestedPosition = afterPosition + 1;
}
}
QAction* menuItemAction;
if (properties.isCheckable) {
menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName,
properties.shortcutKeySequence, properties.isChecked,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), requestedPosition);
} else {
menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()));
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()),
QAction::NoRole, requestedPosition);
}
if (shortcut) {
connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger()));

View file

@ -99,7 +99,7 @@ public:
const QObject* receiver = NULL,
const char* member = NULL,
QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = -1);
int menuItemLocation = UNSPECIFIED_POSITION);
virtual void removeAction(QMenu* menu, const QString& actionName);
bool goToDestination(QString destination);
void goToOrientation(QString orientation);
@ -159,7 +159,7 @@ private:
const bool checked = false,
const QObject* receiver = NULL,
const char* member = NULL,
int menuItemLocation = -1);
int menuItemLocation = UNSPECIFIED_POSITION);
void updateFrustumRenderModeAction();
@ -170,6 +170,7 @@ private:
QMenu* getMenuParent(const QString& menuName, QString& finalMenuPart);
QAction* getMenuAction(const QString& menuName);
int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem);
QMenu* getMenu(const QString& menuName);

View file

@ -129,7 +129,7 @@ bool KeyEvent::operator==(const KeyEvent& other) const {
KeyEvent::operator QKeySequence() const {
int resultCode = 0;
if (text >= "a" && text <= "z") {
if (text.size() == 1 && text >= "a" && text <= "z") {
resultCode = text.toUpper().at(0).unicode();
} else {
resultCode = key;

View file

@ -12,14 +12,13 @@
#include <RegisteredMetaTypes.h>
#include "MenuTypes.h"
MenuItemProperties::MenuItemProperties() :
menuName(""),
menuItemName(""),
shortcutKey(""),
shortcutKeyEvent(),
shortcutKeySequence(),
position(-1),
position(UNSPECIFIED_POSITION),
beforeItem(""),
afterItem(""),
isCheckable(false),
@ -34,7 +33,7 @@ MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& m
shortcutKey(shortcutKey),
shortcutKeyEvent(),
shortcutKeySequence(shortcutKey),
position(-1),
position(UNSPECIFIED_POSITION),
beforeItem(""),
afterItem(""),
isCheckable(checkable),
@ -49,7 +48,7 @@ MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& m
shortcutKey(""),
shortcutKeyEvent(shortcutKeyEvent),
shortcutKeySequence(shortcutKeyEvent),
position(-1),
position(UNSPECIFIED_POSITION),
beforeItem(""),
afterItem(""),
isCheckable(checkable),
@ -86,7 +85,9 @@ void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemPrope
}
}
properties.position = object.property("position").toVariant().toInt();
if (object.property("position").isValid()) {
properties.position = object.property("position").toVariant().toInt();
}
properties.beforeItem = object.property("beforeItem").toVariant().toString();
properties.afterItem = object.property("afterItem").toVariant().toString();
}

View file

@ -13,6 +13,8 @@
#include "EventTypes.h"
const int UNSPECIFIED_POSITION = -1;
class MenuItemProperties {
public:
MenuItemProperties();