1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Overhaul keyboard handling and introduce editor actions

This commit is contained in:
Nick O'Leary 2016-12-04 22:59:43 +00:00
parent f68acca427
commit 16ecb1a9cb
20 changed files with 490 additions and 170 deletions

View File

@ -117,6 +117,7 @@ module.exports = function(grunt) {
"editor/js/ui/common/tabs.js", "editor/js/ui/common/tabs.js",
"editor/js/ui/common/typedInput.js", "editor/js/ui/common/typedInput.js",
"editor/js/ui/utils.js", "editor/js/ui/utils.js",
"editor/js/ui/actions.js",
"editor/js/ui/deploy.js", "editor/js/ui/deploy.js",
"editor/js/ui/keyboard.js", "editor/js/ui/keyboard.js",
"editor/js/ui/workspaces.js", "editor/js/ui/workspaces.js",
@ -194,6 +195,11 @@ module.exports = function(grunt) {
'red/api/locales/en-US/editor.json', 'red/api/locales/en-US/editor.json',
'red/runtime/locales/en-US/runtime.json' 'red/runtime/locales/en-US/runtime.json'
] ]
},
keymaps: {
src: [
'editor/js/keymap.json'
]
} }
}, },
attachCopyright: { attachCopyright: {
@ -230,7 +236,7 @@ module.exports = function(grunt) {
files: [ files: [
'editor/js/**/*.js' 'editor/js/**/*.js'
], ],
tasks: ['concat','uglify','attachCopyright:js'] tasks: ['copy:build','concat','uglify','attachCopyright:js']
}, },
sass: { sass: {
files: [ files: [
@ -246,6 +252,12 @@ module.exports = function(grunt) {
], ],
tasks: ['jsonlint:messages'] tasks: ['jsonlint:messages']
}, },
keymaps: {
files: [
'editor/js/keymap.json'
],
tasks: ['jsonlint:keymaps','copy:build']
},
misc: { misc: {
files: [ files: [
'CHANGELOG.md' 'CHANGELOG.md'
@ -284,6 +296,10 @@ module.exports = function(grunt) {
src: 'editor/js/main.js', src: 'editor/js/main.js',
dest: 'public/red/main.js' dest: 'public/red/main.js'
}, },
{
src: 'editor/js/keymap.json',
dest: 'public/red/keymap.json'
},
{ {
cwd: 'editor/images', cwd: 'editor/images',
src: '**', src: '**',
@ -443,7 +459,7 @@ module.exports = function(grunt) {
grunt.registerTask('build', grunt.registerTask('build',
'Builds editor content', 'Builds editor content',
['clean:build','concat:build','concat:vendor','copy:build','uglify:build','sass:build','jsonlint:messages','attachCopyright']); ['clean:build','jsonlint','concat:build','concat:vendor','copy:build','uglify:build','sass:build','attachCopyright']);
grunt.registerTask('dev', grunt.registerTask('dev',
'Developer mode: run node-red, watch for source changes and build/restart', 'Developer mode: run node-red, watch for source changes and build/restart',

38
editor/js/keymap.json Normal file
View File

@ -0,0 +1,38 @@
{
"*": {
"ctrl-shift-p":"core:manage-palette",
"ctrl-f": "core:search",
"ctrl-=": "core:zoom-in",
"ctrl--": "core:zoom-out",
"ctrl-0": "core:zoom-reset",
"ctrl-enter": "core:confirm-edit-tray",
"ctrl-escape": "core:cancel-edit-tray",
"ctrl-g i": "core:show-info-tab",
"ctrl-g d": "core:show-debug-tab",
"ctrl-g c": "core:show-config-tab"
},
"workspace": {
"ctrl-e": "core:export",
"ctrl-i": "core:import",
"backspace": "core:delete",
"delete": "core:delete",
"enter": "core:edit",
"ctrl-c": "core:copy",
"ctrl-x": "core:cut",
"ctrl-v": "core:paste",
"ctrl-z": "core:undo",
"ctrl-a": "core:select-all",
"shift-?": "core:show-help",
"ctrl-space": "core:toggle-sidebar",
"up": "core:move-selection-up",
"right": "core:move-selection-right",
"down": "core:move-selection-down",
"left": "core:move-selection-left",
"shift-up": "core:step-selection-up",
"shift-right": "core:step-selection-right",
"shift-down": "core:step-selection-down",
"shift-left": "core:step-selection-left",
"ctrl-shift-j": "core:show-previous-tab",
"ctrl-shift-k": "core:show-next-tab"
}
}

View File

@ -15,7 +15,6 @@
**/ **/
(function() { (function() {
function loadNodeList() { function loadNodeList() {
$.ajax({ $.ajax({
headers: { headers: {
@ -170,12 +169,11 @@
} }
function loadEditor() { function loadEditor() {
var menuOptions = []; var menuOptions = [];
menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[ menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[
{id:"menu-item-view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:RED.view.toggleShowGrid}, {id:"menu-item-view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"},
{id:"menu-item-view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:RED.view.toggleSnapGrid}, {id:"menu-item-view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"},
{id:"menu-item-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:toggleStatus, selected: true}, {id:"menu-item-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true},
null, null,
// {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[ // {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[
// {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}}, // {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}},
@ -184,48 +182,46 @@
// {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}} // {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}}
// ]}, // ]},
// null, // null,
{id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:RED.sidebar.toggleSidebar, selected: true} {id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true}
]}); ]});
menuOptions.push(null); menuOptions.push(null);
menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[ menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[
{id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:RED.clipboard.import}, {id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:import"},
{id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]} {id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]}
]}); ]});
menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),disabled:true,options:[ menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),disabled:true,options:[
{id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),disabled:true,onselect:RED.clipboard.export}, {id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),disabled:true,onselect:"core:export"},
{id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:RED.library.export} {id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:"core:library-export"}
]}); ]});
menuOptions.push(null); menuOptions.push(null);
menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:RED.search.show}); menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"});
menuOptions.push(null); menuOptions.push(null);
menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:function() {}}); menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"});
menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[ menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[
{id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:RED.workspaces.add}, {id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"},
{id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:RED.workspaces.edit}, {id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"},
{id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:RED.workspaces.remove} {id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"}
]}); ]});
menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [ menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [
{id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:RED.subflow.createSubflow}, {id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"},
{id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:RED.subflow.convertToSubflow}, {id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"},
]}); ]});
menuOptions.push(null); menuOptions.push(null);
if (RED.settings.theme('palette.editable') !== false) { if (RED.settings.theme('palette.editable') !== false) {
RED.palette.editor.init(); RED.palette.editor.init();
menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:RED.palette.editor.show}); menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"});
menuOptions.push(null); menuOptions.push(null);
} }
menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:RED.keyboard.showHelp}); menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"});
menuOptions.push({id:"menu-item-help", menuOptions.push({id:"menu-item-help",
label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"), label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"),
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs") href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
}); });
menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: showAbout }); menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" });
RED.menu.init({id:"btn-sidemenu",options: menuOptions});
RED.user.init(); RED.user.init();
RED.library.init(); RED.library.init();
RED.palette.init(); RED.palette.init();
RED.sidebar.init(); RED.sidebar.init();
@ -235,15 +231,21 @@
RED.search.init(); RED.search.init();
RED.view.init(); RED.view.init();
RED.editor.init(); RED.editor.init();
RED.keyboard.init();
RED.menu.init({id:"btn-sidemenu",options: menuOptions});
RED.deploy.init(RED.settings.theme("deployButton",null)); RED.deploy.init(RED.settings.theme("deployButton",null));
RED.keyboard.add("workspace", /* ? */ 191,{shift:true},function() {RED.keyboard.showHelp();d3.event.preventDefault();}); RED.actions.add("core:show-about", showAbout);
RED.comms.connect(); RED.comms.connect();
$("#main-container").show(); $("#main-container").show();
$(".header-toolbar").show(); $(".header-toolbar").show();
loadNodeList(); loadNodeList();
} }

35
editor/js/ui/actions.js Normal file
View File

@ -0,0 +1,35 @@
RED.actions = (function() {
var actions = {
}
function addAction(name,handler) {
actions[name] = handler;
}
function removeAction(name) {
delete actions[name];
}
function getAction(name) {
return actions[name];
}
function invokeAction(name) {
if (actions.hasOwnProperty(name)) {
actions[name]();
}
}
function listActions() {
var result = [];
Object.keys(actions).forEach(function(action) {
var shortcut = RED.keyboard.getShortcut(action);
result.push({id:action,scope:shortcut?shortcut.scope:undefined,key:shortcut?shortcut.key:undefined})
})
return result;
}
return {
add: addAction,
remove: removeAction,
get: getAction,
invoke: invokeAction,
list: listActions
}
})();

View File

@ -257,7 +257,7 @@ RED.clipboard = (function() {
function hideDropTarget() { function hideDropTarget() {
$("#dropTarget").hide(); $("#dropTarget").hide();
RED.keyboard.remove(/* ESCAPE */ 27); RED.keyboard.remove("escape");
} }
return { return {
@ -274,13 +274,15 @@ RED.clipboard = (function() {
RED.menu.setDisabled("menu-item-export-library",false); RED.menu.setDisabled("menu-item-export-library",false);
} }
}); });
RED.keyboard.add("workspace", /* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
RED.keyboard.add("workspace", /* i */ 73,{ctrl:true},function(){importNodes();d3.event.preventDefault();}); RED.actions.add("core:export",exportNodes);
RED.actions.add("core:import",importNodes);
$('#chart').on("dragenter",function(event) { $('#chart').on("dragenter",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
$("#dropTarget").css({display:'table'}); $("#dropTarget").css({display:'table'});
RED.keyboard.add("*", /* ESCAPE */ 27,hideDropTarget); RED.keyboard.add("*", "escape" ,hideDropTarget);
} }
}); });

View File

@ -13,9 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
RED.menu = (function() { RED.menu = (function() {
var menuItems = {}; var menuItems = {};
@ -34,17 +31,17 @@ RED.menu = (function() {
var savedStateActive = isSavedStateActive(opt.id); var savedStateActive = isSavedStateActive(opt.id);
if (savedStateActive) { if (savedStateActive) {
link.addClass("active"); link.addClass("active");
opt.onselect.call(opt, true); triggerAction(opt.id,true);
} else if (savedStateActive === false) { } else if (savedStateActive === false) {
link.removeClass("active"); link.removeClass("active");
opt.onselect.call(opt, false); triggerAction(opt.id,false);
} else if (opt.hasOwnProperty("selected")) { } else if (opt.hasOwnProperty("selected")) {
if (opt.selected) { if (opt.selected) {
link.addClass("active"); link.addClass("active");
} else { } else {
link.removeClass("active"); link.removeClass("active");
} }
opt.onselect.call(opt, opt.selected); triggerAction(opt.id,opt.selected);
} }
} }
@ -107,10 +104,12 @@ RED.menu = (function() {
setSelected(opt.id, !selected); setSelected(opt.id, !selected);
} }
} else { } else {
opt.onselect.call(opt); triggerAction(opt.id);
} }
}); });
setInitialState(); if (opt.toggle) {
setInitialState();
}
} else if (opt.href) { } else if (opt.href) {
link.attr("target","_blank").attr("href",opt.href); link.attr("target","_blank").attr("href",opt.href);
} else if (!opt.options) { } else if (!opt.options) {
@ -164,6 +163,19 @@ RED.menu = (function() {
} }
} }
function triggerAction(id, args) {
var opt = menuItems[id];
var callback = opt.onselect;
if (typeof opt.onselect === 'string') {
callback = RED.actions.get(opt.onselect);
}
if (callback) {
callback.call(opt,args);
} else {
console.log("No callback for",id,opt.onselect);
}
}
function isSavedStateActive(id) { function isSavedStateActive(id) {
return RED.settings.get("menu-" + id); return RED.settings.get("menu-" + id);
} }
@ -187,11 +199,15 @@ RED.menu = (function() {
$("#"+id).removeClass("active"); $("#"+id).removeClass("active");
} }
if (opt && opt.onselect) { if (opt && opt.onselect) {
opt.onselect.call(opt,state); triggerAction(opt.id,state);
} }
setSavedState(id, state); setSavedState(id, state);
} }
function toggleSelected(id) {
setSelected(id,!isSelected(id));
}
function setDisabled(id,state) { function setDisabled(id,state) {
if (state) { if (state) {
$("#"+id).parent().addClass("disabled"); $("#"+id).parent().addClass("disabled");
@ -231,16 +247,6 @@ RED.menu = (function() {
var opt = menuItems[id]; var opt = menuItems[id];
if (opt) { if (opt) {
opt.onselect = action; opt.onselect = action;
// $("#"+id).click(function() {
// if ($(this).parent().hasClass("disabled")) {
// return;
// }
// if (menuItems[id].toggle) {
// setSelected(id,!isSelected(id));
// } else {
// menuItems[id].onselect.call(menuItems[id]);
// }
// });
} }
} }
@ -248,6 +254,7 @@ RED.menu = (function() {
init: createMenu, init: createMenu,
setSelected: setSelected, setSelected: setSelected,
isSelected: isSelected, isSelected: isSelected,
toggleSelected: toggleSelected,
setDisabled: setDisabled, setDisabled: setDisabled,
addItem: addItem, addItem: addItem,
removeItem: removeItem, removeItem: removeItem,

View File

@ -126,6 +126,18 @@ RED.tabs = (function() {
},100); },100);
} }
} }
function activatePreviousTab() {
var previous = ul.find("li.active").prev();
if (previous.length > 0) {
activateTab(previous.find("a"));
}
}
function activateNextTab() {
var next = ul.find("li.active").next();
if (next.length > 0) {
activateTab(next.find("a"));
}
}
function updateTabWidths() { function updateTabWidths() {
var tabs = ul.find("li.red-ui-tab"); var tabs = ul.find("li.red-ui-tab");
@ -303,6 +315,8 @@ RED.tabs = (function() {
}, },
removeTab: removeTab, removeTab: removeTab,
activateTab: activateTab, activateTab: activateTab,
nextTab: activateNextTab,
previousTab: activatePreviousTab,
resize: updateTabWidths, resize: updateTabWidths,
count: function() { count: function() {
return ul.find("li.red-ui-tab").size(); return ul.find("li.red-ui-tab").size();

View File

@ -1532,14 +1532,13 @@ RED.editor = (function() {
return { return {
init: function() { init: function() {
RED.tray.init(); RED.tray.init();
$(window).on('keydown', function(evt) { RED.actions.add("core:confirm-edit-tray", function() {
if (evt.keyCode === $.ui.keyCode.ESCAPE && (evt.metaKey || evt.ctrlKey)) { $("#node-dialog-ok").click();
$("#node-dialog-cancel").click(); $("#node-config-dialog-ok").click();
$("#node-config-dialog-cancel").click(); });
} else if (evt.keyCode === $.ui.keyCode.ENTER && (evt.metaKey || evt.ctrlKey)) { RED.actions.add("core:cancel-edit-tray", function() {
$("#node-dialog-ok").click(); $("#node-dialog-cancel").click();
$("#node-config-dialog-ok").click(); $("#node-config-dialog-cancel").click();
}
}); });
}, },
edit: showEditDialog, edit: showEditDialog,

View File

@ -16,9 +16,98 @@
RED.keyboard = (function() { RED.keyboard = (function() {
var handlers = {}; var handlers = {};
var partialState;
var keyMap = {
"left":37,
"up":38,
"right":39,
"down":40,
"escape":27,
"enter": 13,
"backspace": 8,
"delete": 46,
"space": 32,
";":186,
"=":187,
",":188,
"-":189,
".":190,
"/":191,
"\\":220,
"'":222,
"?":191 // <- QWERTY specific
}
var metaKeyCodes = {
16:true,
17:true,
18: true,
91:true,
93: true
}
var actionToKeyMap = {}
// FF generates some different keycodes because reasons.
var firefoxKeyCodeMap = {
59:186,
61:187,
173:189
}
function init() {
$.getJSON("red/keymap.json",function(data) {
for (var scope in data) {
if (data.hasOwnProperty(scope)) {
var keys = data[scope];
for (var key in keys) {
if (keys.hasOwnProperty(key)) {
addHandler(scope,key,keys[key]);
}
}
}
}
})
RED.actions.add("core:show-help", showKeyboardHelp);
}
function parseKeySpecifier(key) {
var parts = key.toLowerCase().split("-");
var modifiers = {};
var keycode;
var blank = 0;
for (var i=0;i<parts.length;i++) {
switch(parts[i]) {
case "ctrl":
case "cmd":
modifiers.ctrl = true;
modifiers.meta = true;
break;
case "alt":
modifiers.alt = true;
break;
case "shift":
modifiers.shift = true;
break;
case "":
blank++;
keycode = keyMap["-"];
break;
default:
if (keyMap.hasOwnProperty(parts[i])) {
keycode = keyMap[parts[i]];
} else if (parts[i].length > 1) {
return null;
} else {
keycode = parts[i].toUpperCase().charCodeAt(0);
}
break;
}
}
return [keycode,modifiers];
}
function resolveKeyEvent(evt) { function resolveKeyEvent(evt) {
var slot = handlers; var slot = partialState||handlers;
if (evt.ctrlKey || evt.metaKey) { if (evt.ctrlKey || evt.metaKey) {
slot = slot.ctrl; slot = slot.ctrl;
} }
@ -28,9 +117,19 @@ RED.keyboard = (function() {
if (slot && evt.altKey) { if (slot && evt.altKey) {
slot = slot.alt; slot = slot.alt;
} }
if (slot && slot[evt.keyCode]) { var keyCode = firefoxKeyCodeMap[evt.keyCode] || evt.keyCode;
var handler = slot[evt.keyCode]; if (slot && slot[keyCode]) {
if (handler.scope && handler.scope !== "*") { var handler = slot[keyCode];
if (!handler.scope) {
if (partialState) {
partialState = null;
return resolveKeyEvent(evt);
} else {
partialState = handler;
evt.preventDefault();
return null;
}
} else if (handler.scope && handler.scope !== "*") {
var target = evt.target; var target = evt.target;
while (target.nodeName !== 'BODY' && target.id !== handler.scope) { while (target.nodeName !== 'BODY' && target.id !== handler.scope) {
target = target.parentElement; target = target.parentElement;
@ -39,66 +138,124 @@ RED.keyboard = (function() {
handler = null; handler = null;
} }
} }
partialState = null;
return handler; return handler;
} else if (partialState) {
partialState = null;
return resolveKeyEvent(evt);
} }
} }
d3.select(window).on("keydown",function() { d3.select(window).on("keydown",function() {
if (metaKeyCodes[d3.event.keyCode]) {
return;
}
var handler = resolveKeyEvent(d3.event); var handler = resolveKeyEvent(d3.event);
if (handler && handler.ondown) { if (handler && handler.ondown) {
handler.ondown(); if (typeof handler.ondown === "string") {
} RED.actions.invoke(handler.ondown);
}); } else {
d3.select(window).on("keyup",function() { handler.ondown();
var handler = resolveKeyEvent(d3.event); }
if (handler && handler.onup) { d3.event.preventDefault();
handler.onup();
} }
}); });
function addHandler(scope,key,modifiers,ondown,onup) { function addHandler(scope,key,modifiers,ondown) {
var mod = modifiers; var mod = modifiers;
var cbdown = ondown; var cbdown = ondown;
var cbup = onup; if (typeof modifiers == "function" || typeof modifiers === "string") {
if (typeof modifiers == "function") {
mod = {}; mod = {};
cbdown = modifiers; cbdown = modifiers;
cbup = ondown; }
var keys = [];
var i=0;
if (typeof key === 'string') {
if (typeof cbdown === 'string') {
actionToKeyMap[cbdown] = {scope:scope,key:key};
}
var parts = key.split(" ");
for (i=0;i<parts.length;i++) {
var parsedKey = parseKeySpecifier(parts[i]);
if (parsedKey) {
keys.push(parsedKey);
} else {
console.log("Unrecognised key specifier:",key)
return;
}
}
} else {
keys.push([key,mod])
} }
var slot = handlers; var slot = handlers;
if (mod.ctrl) { for (i=0;i<keys.length;i++) {
slot.ctrl = slot.ctrl||{}; key = keys[i][0];
slot = slot.ctrl; mod = keys[i][1];
if (mod.ctrl) {
slot.ctrl = slot.ctrl||{};
slot = slot.ctrl;
}
if (mod.shift) {
slot.shift = slot.shift||{};
slot = slot.shift;
}
if (mod.alt) {
slot.alt = slot.alt||{};
slot = slot.alt;
}
slot[key] = slot[key] || {};
slot = slot[key];
//slot[key] = {scope: scope, ondown:cbdown};
} }
if (mod.shift) { slot.scope = scope;
slot.shift = slot.shift||{}; slot.ondown = cbdown;
slot = slot.shift;
}
if (mod.alt) {
slot.alt = slot.alt||{};
slot = slot.alt;
}
slot[key] = {scope: scope, ondown:cbdown, onup:cbup};
} }
function removeHandler(key,modifiers) { function removeHandler(key,modifiers) {
var mod = modifiers || {}; var mod = modifiers || {};
var keys = [];
var i=0;
if (typeof key === 'string') {
delete actionToKeyMap[key];
var parts = key.split(" ");
for (i=0;i<parts.length;i++) {
var parsedKey = parseKeySpecifier(parts[i]);
if (parsedKey) {
keys.push(parsedKey);
} else {
console.log("Unrecognised key specifier:",key)
return;
}
}
} else {
keys.push([key,mod])
}
var slot = handlers; var slot = handlers;
if (mod.ctrl) { for (i=0;i<keys.length;i++) {
slot = slot.ctrl; key = keys[i][0];
} mod = keys[i][1];
if (slot && mod.shift) { if (mod.ctrl) {
slot = slot.shift; slot = slot.ctrl;
} }
if (slot && mod.alt) { if (slot && mod.shift) {
slot = slot.alt; slot = slot.shift;
} }
if (slot) { if (slot && mod.alt) {
delete slot[key]; slot = slot.alt;
}
if (!slot[key]) {
return;
}
slot = slot[key];
} }
delete slot.scope;
delete slot.ondown;
} }
var dialog = null; var dialog = null;
var isMac = /Mac/i.test(window.navigator.platform);
var cmdCtrlKey = '<span class="help-key">'+(isMac?'&#8984;':'Ctrl')+'</span>';
function showKeyboardHelp() { function showKeyboardHelp() {
if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) { if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) {
return; return;
@ -107,30 +264,30 @@ RED.keyboard = (function() {
dialog = $('<div id="keyboard-help-dialog" class="hide">'+ dialog = $('<div id="keyboard-help-dialog" class="hide">'+
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+ '<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
'<table class="keyboard-shortcuts">'+ '<table class="keyboard-shortcuts">'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">a</span></td><td>'+RED._("keyboard.selectAll")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">a</span></td><td>'+RED._("keyboard.selectAll")+'</td></tr>'+
'<tr><td><span class="help-key">Shift</span> + <span class="help-key">Click</span></td><td>'+RED._("keyboard.selectAllConnected")+'</td></tr>'+ '<tr><td><span class="help-key">Shift</span> + <span class="help-key">Click</span></td><td>'+RED._("keyboard.selectAllConnected")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">Click</span></td><td>'+RED._("keyboard.addRemoveNode")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">Click</span></td><td>'+RED._("keyboard.addRemoveNode")+'</td></tr>'+
'<tr><td>&nbsp;</td><td></td></tr>'+ '<tr><td>&nbsp;</td><td></td></tr>'+
'<tr><td><span class="help-key">Enter</span></td><td>'+RED._("keyboard.editSelected")+'</td></tr>'+ '<tr><td><span class="help-key">Enter</span></td><td>'+RED._("keyboard.editSelected")+'</td></tr>'+
'<tr><td><span class="help-key">Delete</span> / <span class="help-key">Backspace</span></td><td>'+RED._("keyboard.deleteSelected")+'</td></tr>'+ '<tr><td><span class="help-key">Delete</span> / <span class="help-key">Backspace</span></td><td>'+RED._("keyboard.deleteSelected")+'</td></tr>'+
'<tr><td>&nbsp;</td><td></td></tr>'+ '<tr><td>&nbsp;</td><td></td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">i</span></td><td>'+RED._("keyboard.importNode")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">i</span></td><td>'+RED._("keyboard.importNode")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">e</span></td><td>'+RED._("keyboard.exportNode")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">e</span></td><td>'+RED._("keyboard.exportNode")+'</td></tr>'+
'</table>'+ '</table>'+
'</div>'+ '</div>'+
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+ '<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
'<table class="keyboard-shortcuts">'+ '<table class="keyboard-shortcuts">'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">Space</span></td><td>'+RED._("keyboard.toggleSidebar")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">Space</span></td><td>'+RED._("keyboard.toggleSidebar")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">.</span></td><td>'+RED._("keyboard.searchBox")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">f</span></td><td>'+RED._("keyboard.searchBox")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">Shift</span> + <span class="help-key">p</span></td><td>'+RED._("keyboard.managePalette")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">Shift</span> + <span class="help-key">p</span></td><td>'+RED._("keyboard.managePalette")+'</td></tr>'+
'<tr><td>&nbsp;</td><td></td></tr>'+ '<tr><td>&nbsp;</td><td></td></tr>'+
'<tr><td><span class="help-key">&#x2190;</span> <span class="help-key">&#x2191;</span> <span class="help-key">&#x2192;</span> <span class="help-key">&#x2193;</span></td><td>'+RED._("keyboard.nudgeNode")+'</td></tr>'+ '<tr><td><span class="help-key">&#x2190;</span> <span class="help-key">&#x2191;</span> <span class="help-key">&#x2192;</span> <span class="help-key">&#x2193;</span></td><td>'+RED._("keyboard.nudgeNode")+'</td></tr>'+
'<tr><td><span class="help-key">Shift</span> + <span class="help-key">&#x2190;</span> <span class="help-key">&#x2191;</span> <span class="help-key">&#x2192;</span> <span class="help-key">&#x2193;</span></td><td>'+RED._("keyboard.moveNode")+'</td></tr>'+ '<tr><td><span class="help-key">Shift</span> + <span class="help-key">&#x2190;</span> <span class="help-key">&#x2191;</span> <span class="help-key">&#x2192;</span> <span class="help-key">&#x2193;</span></td><td>'+RED._("keyboard.moveNode")+'</td></tr>'+
'<tr><td>&nbsp;</td><td></td></tr>'+ '<tr><td>&nbsp;</td><td></td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">c</span></td><td>'+RED._("keyboard.copyNode")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">c</span></td><td>'+RED._("keyboard.copyNode")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">x</span></td><td>'+RED._("keyboard.cutNode")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">x</span></td><td>'+RED._("keyboard.cutNode")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">v</span></td><td>'+RED._("keyboard.pasteNode")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">v</span></td><td>'+RED._("keyboard.pasteNode")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">z</span></td><td>'+RED._("keyboard.undoChange")+'</td></tr>'+ '<tr><td>'+cmdCtrlKey+' + <span class="help-key">z</span></td><td>'+RED._("keyboard.undoChange")+'</td></tr>'+
'</table>'+ '</table>'+
'</div>'+ '</div>'+
'</div>') '</div>')
@ -148,9 +305,12 @@ RED.keyboard = (function() {
} }
return { return {
init: init,
add: addHandler, add: addHandler,
remove: removeHandler, remove: removeHandler,
showHelp: showKeyboardHelp getShortcut: function(actionName) {
return actionToKeyMap[actionName];
}
} }
})(); })();

View File

@ -410,6 +410,9 @@ RED.library = (function() {
return { return {
init: function() { init: function() {
RED.actions.add("core:library-export",exportFlow);
RED.events.on("view:selection-changed",function(selection) { RED.events.on("view:selection-changed",function(selection) {
if (!selection.nodes) { if (!selection.nodes) {
RED.menu.setDisabled("menu-item-export",true); RED.menu.setDisabled("menu-item-export",true);

View File

@ -302,10 +302,10 @@ RED.palette.editor = (function() {
filterInput.focus(); filterInput.focus();
},250); },250);
RED.events.emit("palette-editor:open"); RED.events.emit("palette-editor:open");
RED.keyboard.add("*",/* ESCAPE */ 27,function(){hidePaletteEditor();d3.event.preventDefault();}); RED.keyboard.add("*","escape",function(){hidePaletteEditor()});
} }
function hidePaletteEditor() { function hidePaletteEditor() {
RED.keyboard.remove("*"); RED.keyboard.remove("escape");
$("#main-container").removeClass("palette-expanded"); $("#main-container").removeClass("palette-expanded");
$("#header-shade").hide(); $("#header-shade").hide();
$("#editor-shade").hide(); $("#editor-shade").hide();
@ -425,7 +425,7 @@ RED.palette.editor = (function() {
RED.events.on("type-search:open",function() { disabled = true; }); RED.events.on("type-search:open",function() { disabled = true; });
RED.events.on("type-search:close",function() { disabled = false; }); RED.events.on("type-search:close",function() { disabled = false; });
RED.keyboard.add("*", /* p */ 80,{shift:true,ctrl:true},function() {RED.palette.editor.show();d3.event.preventDefault();}); RED.actions.add("core:manage-palette",RED.palette.editor.show);
editorTabs = RED.tabs.create({ editorTabs = RED.tabs.create({
id:"palette-editor-tabs", id:"palette-editor-tabs",

View File

@ -238,8 +238,11 @@ RED.search = (function() {
} }
function show() { function show() {
if (disabled) {
return;
}
if (!visible) { if (!visible) {
RED.keyboard.add("*",/* ESCAPE */ 27,function(){hide();d3.event.preventDefault();}); RED.keyboard.add("*","escape",function(){hide()});
$("#header-shade").show(); $("#header-shade").show();
$("#editor-shade").show(); $("#editor-shade").show();
$("#palette-shade").show(); $("#palette-shade").show();
@ -257,7 +260,7 @@ RED.search = (function() {
} }
function hide() { function hide() {
if (visible) { if (visible) {
RED.keyboard.remove(/* ESCAPE */ 27); RED.keyboard.remove("escape");
visible = false; visible = false;
$("#header-shade").hide(); $("#header-shade").hide();
$("#editor-shade").hide(); $("#editor-shade").hide();
@ -274,7 +277,8 @@ RED.search = (function() {
} }
function init() { function init() {
RED.keyboard.add("*",/* . */ 190,{ctrl:true},function(){if (!disabled) { show(); } d3.event.preventDefault();}); RED.actions.add("core:search",show);
RED.events.on("editor:open",function() { disabled = true; }); RED.events.on("editor:open",function() { disabled = true; });
RED.events.on("editor:close",function() { disabled = false; }); RED.events.on("editor:close",function() { disabled = false; });
RED.events.on("palette-editor:open",function() { disabled = true; }); RED.events.on("palette-editor:open",function() { disabled = true; });

View File

@ -202,12 +202,18 @@ RED.sidebar = (function() {
} }
function init () { function init () {
RED.keyboard.add("*",/* SPACE */ 32,{ctrl:true},function(){RED.menu.setSelected("menu-item-sidebar",!RED.menu.isSelected("menu-item-sidebar"));d3.event.preventDefault();}); RED.actions.add("core:toggle-sidebar",function(state){
if (state === undefined) {
RED.menu.toggleSelected("menu-item-sidebar");
} else {
toggleSidebar(state);
}
});
showSidebar(); showSidebar();
RED.sidebar.info.init(); RED.sidebar.info.init();
RED.sidebar.config.init(); RED.sidebar.config.init();
// hide info bar at start if screen rather narrow... // hide info bar at start if screen rather narrow...
if ($(window).width() < 600) { toggleSidebar(); } if ($(window).width() < 600) { RED.menu.setSelected("menu-item-sidebar",false); }
} }
return { return {

View File

@ -380,6 +380,8 @@ RED.subflow = (function() {
} }
}); });
RED.actions.add("core:create-subflow",createSubflow);
RED.actions.add("core:convert-to-subflow",convertToSubflow);
} }
function createSubflow() { function createSubflow() {

View File

@ -236,10 +236,7 @@ RED.sidebar.config = (function() {
visible: false, visible: false,
onchange: function() { refreshConfigNodeList(); } onchange: function() { refreshConfigNodeList(); }
}); });
RED.actions.add("core:show-config-tab",function() {RED.sidebar.show('config')});
RED.menu.setAction('menu-item-config-nodes',function() {
RED.sidebar.show('config');
})
$("#workspace-config-node-collapse-all").on("click", function(e) { $("#workspace-config-node-collapse-all").on("click", function(e) {
e.preventDefault(); e.preventDefault();

View File

@ -42,7 +42,7 @@ RED.sidebar.info = (function() {
content: content, content: content,
enableOnEdit: true enableOnEdit: true
}); });
RED.actions.add("core:show-info-tab",show);
} }
function show() { function show() {

View File

@ -168,7 +168,7 @@ RED.typeSearch = (function() {
} }
function show(opts) { function show(opts) {
if (!visible) { if (!visible) {
RED.keyboard.add("*",/* ESCAPE */ 27,function(){hide();d3.event.preventDefault();}); RED.keyboard.add("*","escape",function(){hide()});
if (dialog === null) { if (dialog === null) {
createDialog(); createDialog();
} }
@ -195,7 +195,7 @@ RED.typeSearch = (function() {
} }
function hide(fast) { function hide(fast) {
if (visible) { if (visible) {
RED.keyboard.remove(/* ESCAPE */ 27); RED.keyboard.remove("escape");
visible = false; visible = false;
if (dialog !== null) { if (dialog !== null) {
searchResultsDiv.slideUp(fast?50:200,function() { searchResultsDiv.slideUp(fast?50:200,function() {

View File

@ -267,6 +267,7 @@ RED.view = (function() {
} }
function init() { function init() {
RED.events.on("workspace:change",function(event) { RED.events.on("workspace:change",function(event) {
var chart = $("#chart"); var chart = $("#chart");
if (event.old !== 0) { if (event.old !== 0) {
@ -384,28 +385,47 @@ RED.view = (function() {
} }
}); });
RED.keyboard.add("workspace",/* backspace */ 8,function(){deleteSelection();d3.event.preventDefault();}); RED.actions.add("core:copy",copySelection);
RED.keyboard.add("workspace",/* delete */ 46,function(){deleteSelection();d3.event.preventDefault();}); RED.actions.add("core:cut",function(){copySelection();deleteSelection();});
RED.keyboard.add("workspace",/* enter */ 13, function() { editSelection(); d3.event.preventDefault();}); RED.actions.add("core:paste",function(){importNodes(clipboard);});
RED.actions.add("core:delete",deleteSelection);
RED.actions.add("core:edit",editSelection);
RED.actions.add("core:undo",RED.history.pop);
RED.actions.add("core:select-all",selectAll);
RED.actions.add("core:zoom-in",zoomIn);
RED.actions.add("core:zoom-out",zoomOut);
RED.actions.add("core:zoom-reset",zoomZero);
RED.keyboard.add("workspace",/* c */ 67,{ctrl:true},function(){copySelection();d3.event.preventDefault();}); RED.actions.add("core:toggle-show-grid",function(state) {
RED.keyboard.add("workspace",/* x */ 88,{ctrl:true},function(){copySelection();deleteSelection();d3.event.preventDefault();}); if (state === undefined) {
RED.menu.toggleSelected("menu-item-view-show-grid");
} else {
toggleShowGrid(state);
}
});
RED.actions.add("core:toggle-snap-grid",function(state) {
if (state === undefined) {
RED.menu.toggleSelected("menu-item-view-snap-grid");
} else {
toggleSnapGrid(state);
}
});
RED.actions.add("core:toggle-status",function(state) {
if (state === undefined) {
RED.menu.toggleSelected("menu-item-status");
} else {
toggleStatus(state);
}
});
RED.keyboard.add("workspace",/* z */ 90,{ctrl:true},function(){RED.history.pop();}); RED.actions.add("core:move-selection-up", function() { moveSelection(0,-1);});
RED.keyboard.add("workspace",/* a */ 65,{ctrl:true},function(){selectAll();d3.event.preventDefault();}); RED.actions.add("core:step-selection-up", function() { moveSelection(0,-20);});
RED.keyboard.add("*",/* = */ 187,{ctrl:true},function(){zoomIn();d3.event.preventDefault();}); RED.actions.add("core:move-selection-right", function() { moveSelection(1,0);});
RED.keyboard.add("*",/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();}); RED.actions.add("core:step-selection-right", function() { moveSelection(20,0);});
RED.keyboard.add("*",/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();}); RED.actions.add("core:move-selection-down", function() { moveSelection(0,1);});
RED.keyboard.add("workspace",/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();}); RED.actions.add("core:step-selection-down", function() { moveSelection(0,20);});
RED.actions.add("core:move-selection-left", function() { moveSelection(-1,0);});
RED.keyboard.add("workspace",/* up */ 38, function() { moveSelection(0,-1);d3.event.preventDefault();},endKeyboardMove); RED.actions.add("core:step-selection-left", function() { moveSelection(-20,0);});
RED.keyboard.add("workspace",/* up */ 38, {shift:true}, function() { moveSelection(0,-20); d3.event.preventDefault();},endKeyboardMove);
RED.keyboard.add("workspace",/* down */ 40, function() { moveSelection(0,1);d3.event.preventDefault();},endKeyboardMove);
RED.keyboard.add("workspace",/* down */ 40, {shift:true}, function() { moveSelection(0,20); d3.event.preventDefault();},endKeyboardMove);
RED.keyboard.add("workspace",/* left */ 37, function() { moveSelection(-1,0);d3.event.preventDefault();},endKeyboardMove);
RED.keyboard.add("workspace",/* left */ 37, {shift:true}, function() { moveSelection(-20,0); d3.event.preventDefault();},endKeyboardMove);
RED.keyboard.add("workspace",/* right */ 39, function() { moveSelection(1,0);d3.event.preventDefault();},endKeyboardMove);
RED.keyboard.add("workspace",/* right */ 39, {shift:true}, function() { moveSelection(20,0); d3.event.preventDefault();},endKeyboardMove);
} }
@ -959,7 +979,7 @@ RED.view = (function() {
} }
} }
if (mouse_mode == RED.state.IMPORT_DRAGGING) { if (mouse_mode == RED.state.IMPORT_DRAGGING) {
RED.keyboard.remove(/* ESCAPE */ 27); RED.keyboard.remove("escape");
updateActiveNodes(); updateActiveNodes();
RED.nodes.dirty(true); RED.nodes.dirty(true);
} }
@ -1103,6 +1123,7 @@ RED.view = (function() {
} }
function endKeyboardMove() { function endKeyboardMove() {
endMoveSet = false;
if (moving_set.length > 0) { if (moving_set.length > 0) {
var ns = []; var ns = [];
for (var i=0;i<moving_set.length;i++) { for (var i=0;i<moving_set.length;i++) {
@ -1117,14 +1138,21 @@ RED.view = (function() {
RED.nodes.dirty(true); RED.nodes.dirty(true);
} }
} }
var endMoveSet = false;
function moveSelection(dx,dy) { function moveSelection(dx,dy) {
if (moving_set.length > 0) { if (moving_set.length > 0) {
if (!endMoveSet) {
$(document).one('keyup',endKeyboardMove);
endMoveSet = true;
}
var minX = 0; var minX = 0;
var minY = 0; var minY = 0;
var node; var node;
for (var i=0;i<moving_set.length;i++) { for (var i=0;i<moving_set.length;i++) {
node = moving_set[i]; node = moving_set[i];
node.n.changed = true;
node.n.dirty = true;
if (node.ox == null && node.oy == null) { if (node.ox == null && node.oy == null) {
node.ox = node.n.x; node.ox = node.n.x;
node.oy = node.n.y; node.oy = node.n.y;
@ -1440,7 +1468,7 @@ RED.view = (function() {
//var pos = [touch0.pageX,touch0.pageY]; //var pos = [touch0.pageX,touch0.pageY];
//RED.touch.radialMenu.show(d3.select(this),pos); //RED.touch.radialMenu.show(d3.select(this),pos);
if (mouse_mode == RED.state.IMPORT_DRAGGING) { if (mouse_mode == RED.state.IMPORT_DRAGGING) {
RED.keyboard.remove(/* ESCAPE */ 27); RED.keyboard.remove("escape");
if (activeSpliceLink) { if (activeSpliceLink) {
// TODO: DRY - droppable/nodeMouseDown/canvasMouseUp // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp
@ -2437,8 +2465,8 @@ RED.view = (function() {
node.n._def.outputs > 0; node.n._def.outputs > 0;
} }
} }
RED.keyboard.add("*",/* ESCAPE */ 27,function(){ RED.keyboard.add("*","escape",function(){
RED.keyboard.remove(/* ESCAPE */ 27); RED.keyboard.remove("escape");
clearSelection(); clearSelection();
RED.history.pop(); RED.history.pop();
mouse_mode = 0; mouse_mode = 0;
@ -2483,6 +2511,24 @@ RED.view = (function() {
} }
} }
function toggleShowGrid(state) {
if (state) {
grid.style("visibility","visible");
} else {
grid.style("visibility","hidden");
}
}
function toggleSnapGrid(state) {
snapGrid = state;
redraw();
}
function toggleStatus(s) {
showStatus = s;
RED.nodes.eachNode(function(n) { n.dirty = true;});
//TODO: subscribe/unsubscribe here
redraw();
}
return { return {
init: init, init: init,
state:function(state) { state:function(state) {
@ -2502,16 +2548,6 @@ RED.view = (function() {
}, },
focus: focusView, focus: focusView,
importNodes: importNodes, importNodes: importNodes,
status: function(s) {
if (s == null) {
return showStatus;
} else {
showStatus = s;
RED.nodes.eachNode(function(n) { n.dirty = true;});
//TODO: subscribe/unsubscribe here
redraw();
}
},
calculateTextWidth: calculateTextWidth, calculateTextWidth: calculateTextWidth,
select: function(selection) { select: function(selection) {
if (typeof selection !== "undefined") { if (typeof selection !== "undefined") {
@ -2538,17 +2574,6 @@ RED.view = (function() {
} }
return selection; return selection;
}, },
toggleShowGrid: function(state) {
if (state) {
grid.style("visibility","visible");
} else {
grid.style("visibility","hidden");
}
},
toggleSnapGrid: function(state) {
snapGrid = state;
redraw();
},
scale: function() { scale: function() {
return scaleFactor; return scaleFactor;
}, },

View File

@ -170,6 +170,9 @@ RED.workspaces = (function() {
createWorkspaceTabs(); createWorkspaceTabs();
RED.events.on("sidebar:resize",workspace_tabs.resize); RED.events.on("sidebar:resize",workspace_tabs.resize);
RED.actions.add("core:show-next-tab",workspace_tabs.nextTab);
RED.actions.add("core:show-previous-tab",workspace_tabs.previousTab);
RED.menu.setAction('menu-item-workspace-delete',function() { RED.menu.setAction('menu-item-workspace-delete',function() {
deleteWorkspace(RED.nodes.workspace(activeWorkspace)); deleteWorkspace(RED.nodes.workspace(activeWorkspace));
}); });
@ -177,6 +180,14 @@ RED.workspaces = (function() {
$(window).resize(function() { $(window).resize(function() {
workspace_tabs.resize(); workspace_tabs.resize();
}); });
RED.actions.add("core:add-flow",addWorkspace);
RED.actions.add("core:edit-flow",editWorkspace);
RED.actions.add("core:remove-flow",removeWorkspace);
}
function editWorkspace(id) {
showRenameWorkspaceDialog(id||activeWorkspace);
} }
function removeWorkspace(ws) { function removeWorkspace(ws) {
@ -201,9 +212,7 @@ RED.workspaces = (function() {
add: addWorkspace, add: addWorkspace,
remove: removeWorkspace, remove: removeWorkspace,
order: setWorkspaceOrder, order: setWorkspaceOrder,
edit: function(id) { edit: editWorkspace,
showRenameWorkspaceDialog(id||activeWorkspace);
},
contains: function(id) { contains: function(id) {
return workspace_tabs.contains(id); return workspace_tabs.contains(id);
}, },

View File

@ -144,8 +144,7 @@
toolbar: uiComponents.footer, toolbar: uiComponents.footer,
enableOnEdit: true enableOnEdit: true
}); });
RED.actions.add("core:show-debug-tab",function() { RED.sidebar.show('debug')});
var that = this; var that = this;
RED._debug = function(msg) { RED._debug = function(msg) {
@ -222,6 +221,8 @@
RED.sidebar.removeTab("debug"); RED.sidebar.removeTab("debug");
RED.events.off("workspace:change", this.refreshMessageList); RED.events.off("workspace:change", this.refreshMessageList);
window.removeEventListener("message",this.handleWindowMessage); window.removeEventListener("message",this.handleWindowMessage);
RED.actions.remove("core:show-debug");
delete RED._debug; delete RED._debug;
}, },
oneditprepare: function() { oneditprepare: function() {