c9-core/plugins/c9.ide.local/nativemenus.js

368 wiersze
12 KiB
JavaScript

/*global nativeRequire nwDispatcher*/
define(function(require, exports, module) {
main.consumes = [
"Plugin", "menus", "layout", "preferences", "settings", "ui"
];
main.provides = ["nativeMenus"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var menus = imports.menus;
var layout = imports.layout;
var ui = imports.ui;
var settings = imports.settings;
var prefs = imports.preferences;
// Some require magic to get nw.gui
var nw = nativeRequire("nw.gui");
var keys = require("ace/lib/keys");
// Ref to window
var win = nw.Window.get();
var server = window.server;
var windowManager = server.windowManager;
var specialKeys = {
" ": 32,
"delete": 0x7F,
"backspace": 0x08,
"down": 63233,
"up": 63232,
"left": 63234,
"right": 63235,
"f1": 63236,
"f2": 63237,
"f3": 63238,
"f4": 63239,
"f5": 63240,
"f6": 63241,
"f7": 63242,
"f8": 63243,
"f9": 63244,
"f10": 63245,
"f11": 63246,
"f12": 63247,
"home": 63273,
"end": 63275,
"pagedown": 63277,
"pageup": 63276
};
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
// var emit = plugin.getEmitter();
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
prefs.add({
"General": {
"User Interface": {
"Use Native Menus (restart required)": {
type: "checkbox",
path: "user/local/@nativeMenus",
position: 50
}
}
}
}, plugin);
settings.on("read", function() {
settings.setDefaults("user/local", [["nativeMenus", true]]);
init();
});
}
var inited;
function init() {
if (inited) return;
inited = true;
// Only do this for OSX
if (process.platform != "darwin"
|| !settings.getBool("user/local/@nativeMenus")) {
// Create Root Menus
menus.init();
// Create Built In Menus
windowManager.connection.send(0, {
type: "builtin"
});
return;
}
function decorateMenu(menu, basename) {
menu.native = true;
menu.on("DOMNodeInserted", function(e) {
var node = e.currentTarget;
if (node.nodeType != 1 || node.native) return;
createMenuItem({
name: basename + "/" + (node.caption || "~" + node.$position),
parent: menu,
item: node,
index: node.$position
});
});
menu.on("DOMNodeRemoved", function(e) {
var node = e.currentTarget;
windowManager.connection.send(0, {
type: "remove",
id: node.$uniqueId // @todo path
});
});
}
menus.on("root", function(e) {
if (e.index < 1000) {
// @todo move to when native menu is shown
if (!e.menu.$ext)
apf.document.documentElement.appendChild(e.menu);
windowManager.connection.send(0, {
type: "setRoot",
name: e.name,
index: e.index
});
decorateMenu(e.menu, e.name);
return false;
}
});
menus.on("submenu", function(e) {
if (e.parent.native && e.index) {
// @todo move to when native menu is shown
if (!e.parent.$ext)
apf.document.documentElement.appendChild(e.parent);
if (!e.menu.$ext)
apf.document.documentElement.appendChild(e.menu);
windowManager.connection.send(0, {
type: "setSubMenu",
name: e.name,
index: e.index
});
decorateMenu(e.menu, e.name);
}
});
menus.on("menuitem", createMenuItem);
// Create Root Menus
menus.init();
// Click Dispatcher
win.on("menuClick", function(e) {
var item = findMenuItem(e.name);
if (!item) throw new Error();
var type = item.getAttribute("type");
if (type == "check")
item[item.checked ? "uncheck" : "check"]();
else if (type == "radio")
item.select();
item.dispatchEvent("click");
item.parentNode.dispatchEvent("itemclick", {
value: item.getAttribute("value")
});
});
// Show Dispatcher
win.on("menuShow", function(msg) {
var menu = menus.get(msg.name).menu;
if (!menu) debugger;
if (!menu.$ext)
apf.document.documentElement.appendChild(menu);
// Update AML Menu
menu.dispatchEvent("prop.visible", { value: true });
// Collect State
var items = [];
var nodes = menu.childNodes;
for (var n, i = nodes.length - 1; i >= 0; i--) {
n = nodes[i];
var caption = n.getAttribute("caption");
if (n.localName != "item" && n.localName != "divider")
continue;
if (!n.originalName)
n.originalName = msg.name + "/" + (caption || "~" + n.$position);
var data = {
name: n.originalName,
index: n.$position,
visible: n.visible,
caption: caption,
key: n.key,
submenu: n.submenu ? true : false,
modifiers: n.modifiers,
checked: n.checked || n.selected || n.selectedItem == n,
disabled: n.disabled
};
if (!n.key && n.hotkey)
setHotkey(data, n.hotkey);
items.push(data);
}
// Send to Root window
windowManager.connection.send(0, {
type: "showMenu",
name: msg.name,
items: items
});
});
// Update Toolbar
var barTools = layout.getElement("barTools");
barTools.$ext.style.marginLeft = "-10px";
barTools.$ext.firstElementChild.style.display = "none";
// Menu items
var appName = "Cloud9";
var c = 1400;
menus.addItemByPath("Cloud9/~", new ui.divider(), c, plugin);
menus.addItemByPath("Cloud9/" +
nwDispatcher.getNSStringFWithFixup("IDS_HIDE_APP_MAC", appName),
new ui.item({
selector: "hide:",
key: "h"
}), c += 100, plugin);
menus.addItemByPath("Cloud9/" +
nwDispatcher.getNSStringFWithFixup("IDS_HIDE_OTHERS_MAC", appName),
new ui.item({
selector: "hideOtherApplications:",
key: "h",
modifiers: "cmd-alt"
}), c += 100, plugin);
menus.addItemByPath("Cloud9/" +
nwDispatcher.getNSStringWithFixup("IDS_SHOW_ALL_MAC"),
new ui.item({
selector: "unhideAllApplications:"
}), c += 100, plugin);
}
/***** Methods *****/
function findMenuItem(name) {
var item = menus.get(name).item;
if (!item) {
var p = name.split("/");
var f = p.pop();
var parent = menus.get(p.join("/")).menu;
parent.childNodes.some(function(node) {
if (node.caption == f) {
item = node;
return true;
}
});
}
return item;
}
function createMenuItem(e) {
var item = e.item;
if (e.parent.native && (item.localName == "item"
|| item.localName == "divider")) {
item.native = true; // Prevent re-entry
item.originalName = e.name; // Used as an item id
var index = e.index;
if (!index && item.parentNode)
index = item.parentNode.childNodes.indexOf(item);
var data = {
type: "setMenuItem",
name: e.name,
index: index,
disabled: item.disabled,
itemtype: item.type,
selector: item.selector,
key: item.key,
modifiers: item.modifiers
// hotkey: item.hotkey
};
if (!item.key && item.hotkey)
setHotkey(data, item.hotkey);
windowManager.connection.send(0, data);
}
}
function setHotkey(item, hotkey) {
// item.cached = hotkey;
hotkey = hotkey.split("|")[0];
var isUpper = ~hotkey.indexOf("Shift");
hotkey = hotkey.replace(/Shift[- ]?/, "").split(/[- ]/);
item.key = hotkey.pop().toLowerCase() || "-";
if (specialKeys[item.key]) {
item.key = String.fromCharCode(specialKeys[item.key]);
if (isUpper) hotkey.push("shift");
}
else if (item.key.length > 1) {
item.key = String.fromCharCode(keys[item.key]);
if (isUpper) hotkey.push("shift");
}
else if (isUpper)
item.key = item.key.toUpperCase();
item.modifiers = hotkey.map(function(key) {
if (key == "Command") return "cmd";
if (key == "Option") return "alt";
if (key == "Alt") return "alt";
if (key == "Ctrl") return "ctrl";
return key;
}).join("-");
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
**/
plugin.freezePublicAPI({
});
register(null, {
nativeMenus: plugin
});
}
});