diff --git a/editor/js/main.js b/editor/js/main.js index 432ede31a..eddb58fad 100644 --- a/editor/js/main.js +++ b/editor/js/main.js @@ -211,7 +211,7 @@ var RED = (function() { RED.deploy.init(RED.settings.theme("deployButton",null)); - RED.keyboard.add(/* ? */ 191,{shift:true},function(){RED.keyboard.showHelp();d3.event.preventDefault();}); + RED.keyboard.add("workspace", /* ? */ 191,{shift:true},function(){RED.keyboard.showHelp();d3.event.preventDefault();}); RED.comms.connect(); $("#main-container").show(); diff --git a/editor/js/ui/clipboard.js b/editor/js/ui/clipboard.js index 27176a23a..8160276a8 100644 --- a/editor/js/ui/clipboard.js +++ b/editor/js/ui/clipboard.js @@ -58,10 +58,8 @@ RED.clipboard = (function() { ], open: function(e) { $(this).parent().find(".ui-dialog-titlebar-close").hide(); - RED.keyboard.disable(); }, close: function(e) { - RED.keyboard.enable(); } }); @@ -154,13 +152,13 @@ RED.clipboard = (function() { RED.menu.setDisabled("menu-item-export-library",false); } }); - RED.keyboard.add(/* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();}); - RED.keyboard.add(/* i */ 73,{ctrl:true},function(){importNodes();d3.event.preventDefault();}); + 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();}); $('#chart').on("dragenter",function(event) { if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { $("#dropTarget").css({display:'table'}); - RED.keyboard.add(/* ESCAPE */ 27,hideDropTarget); + RED.keyboard.add("*", /* ESCAPE */ 27,hideDropTarget); } }); diff --git a/editor/js/ui/editor.js b/editor/js/ui/editor.js index a6e28abf9..83d577dd1 100644 --- a/editor/js/ui/editor.js +++ b/editor/js/ui/editor.js @@ -639,7 +639,6 @@ RED.editor = (function() { RED.sidebar.info.refresh(editing_node); } var trayBody = tray.find('.editor-tray-body'); - RED.keyboard.disable(); var dialogForm = $('
').appendTo(trayBody); dialogForm.html($("script[data-template-name='"+type+"']").html()); var ns; @@ -670,7 +669,6 @@ RED.editor = (function() { dialogForm.i18n(); }, close: function() { - RED.keyboard.enable(); if (RED.view.state() != RED.state.IMPORT_DRAGGING) { RED.view.state(RED.state.DEFAULT); } @@ -759,8 +757,6 @@ RED.editor = (function() { trayFooter.prepend('
'); trayFooter.append(''); - RED.keyboard.disable(); - var dialogForm = $('
').appendTo(trayBody); dialogForm.html($("script[data-template-name='"+type+"']").html()); dialogForm.find('[data-i18n]').each(function() { @@ -830,9 +826,6 @@ RED.editor = (function() { }, close: function() { - if (RED.view.state() != RED.state.EDITING) { - RED.keyboard.enable(); - } RED.workspaces.refresh(); editStack.pop(); }, @@ -1174,7 +1167,6 @@ RED.editor = (function() { RED.sidebar.info.refresh(editing_node); } var trayBody = tray.find('.editor-tray-body'); - RED.keyboard.disable(); var dialogForm = $('
').appendTo(trayBody); dialogForm.html($("script[data-template-name='subflow-template']").html()); var ns = "node-red"; @@ -1218,8 +1210,6 @@ RED.editor = (function() { dialogForm.i18n(); }, close: function() { - RED.keyboard.enable(); - if (RED.view.state() != RED.state.IMPORT_DRAGGING) { RED.view.state(RED.state.DEFAULT); } diff --git a/editor/js/ui/keyboard.js b/editor/js/ui/keyboard.js index c9a340ee4..05d26a18e 100644 --- a/editor/js/ui/keyboard.js +++ b/editor/js/ui/keyboard.js @@ -15,35 +15,47 @@ **/ RED.keyboard = (function() { - var active = true; var handlers = {}; - d3.select(window).on("keydown",function() { - if (!active) { return; } - var handler = handlers[d3.event.keyCode]; - if (handler && handler.ondown) { - if (!handler.modifiers || - ((!handler.modifiers.shift || d3.event.shiftKey) && - (!handler.modifiers.ctrl || d3.event.ctrlKey || d3.event.metaKey) && - (!handler.modifiers.alt || d3.event.altKey) )) { - handler.ondown(); + function resolveKeyEvent(evt) { + var slot = handlers; + if (evt.ctrlKey || evt.metaKey) { + slot = slot.ctrl; + } + if (slot && evt.shiftKey) { + slot = slot.shift; + } + if (slot && evt.altKey) { + slot = slot.alt; + } + if (slot && slot[evt.keyCode]) { + var handler = slot[evt.keyCode]; + if (handler.scope && handler.scope !== "*") { + var target = evt.target; + while (target.nodeName !== 'BODY' && target.id !== handler.scope) { + target = target.parentElement; + } + if (target.nodeName === 'BODY') { + handler = null; + } } + return handler; + } + } + d3.select(window).on("keydown",function() { + var handler = resolveKeyEvent(d3.event); + if (handler && handler.ondown) { + handler.ondown(); + } + }); + d3.select(window).on("keyup",function() { + var handler = resolveKeyEvent(d3.event); + if (handler && handler.onup) { + handler.onup(); } }); - d3.select(window).on("keyup",function() { - if (!active) { return; } - var handler = handlers[d3.event.keyCode]; - if (handler && handler.onup) { - if (!handler.modifiers || - ((!handler.modifiers.shift || d3.event.shiftKey) && - (!handler.modifiers.ctrl || d3.event.ctrlKey || d3.event.metaKey) && - (!handler.modifiers.alt || d3.event.altKey) )) { - handler.onup(); - } - } - }); - function addHandler(key,modifiers,ondown,onup) { + function addHandler(scope,key,modifiers,ondown,onup) { var mod = modifiers; var cbdown = ondown; var cbup = onup; @@ -52,15 +64,41 @@ RED.keyboard = (function() { cbdown = modifiers; cbup = ondown; } - handlers[key] = {modifiers:mod, ondown:cbdown, onup:cbup}; + var slot = handlers; + 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] = {scope: scope, ondown:cbdown, onup:cbup}; } - function removeHandler(key) { - delete handlers[key]; + + function removeHandler(key,modifiers) { + var mod = modifiers || {}; + var slot = handlers; + if (mod.ctrl) { + slot = slot.ctrl; + } + if (slot && mod.shift) { + slot = slot.shift; + } + if (slot && mod.alt) { + slot = slot.alt; + } + if (slot) { + delete slot[key]; + } } - - + var dialog = null; - + function showKeyboardHelp() { if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) { return; @@ -96,25 +134,16 @@ RED.keyboard = (function() { autoOpen: false, width: "800", title:"Keyboard shortcuts", - resizable: false, - open: function() { - RED.keyboard.disable(); - }, - close: function() { - RED.keyboard.enable(); - } + resizable: false }); } - + dialog.dialog("open"); } - + return { add: addHandler, remove: removeHandler, - disable: function(){ active = false;}, - enable: function(){ active = true; }, - showHelp: showKeyboardHelp } diff --git a/editor/js/ui/library.js b/editor/js/ui/library.js index 0a554b870..e9435317b 100644 --- a/editor/js/ui/library.js +++ b/editor/js/ui/library.js @@ -472,10 +472,8 @@ RED.library = (function() { ], open: function(e) { $(this).parent().find(".ui-dialog-titlebar-close").hide(); - RED.keyboard.disable(); }, close: function(e) { - RED.keyboard.enable(); } }); exportToLibraryDialog.children(".dialog-form").append($( diff --git a/editor/js/ui/palette.js b/editor/js/ui/palette.js index c88cbf6cf..f17889ded 100644 --- a/editor/js/ui/palette.js +++ b/editor/js/ui/palette.js @@ -404,13 +404,6 @@ RED.palette = (function() { }); } - $("#palette-search-input").focus(function(e) { - RED.keyboard.disable(); - }); - $("#palette-search-input").blur(function(e) { - RED.keyboard.enable(); - }); - $("#palette-search-clear").on("click",function(e) { e.preventDefault(); $("#palette-search-input").val(""); diff --git a/editor/js/ui/sidebar.js b/editor/js/ui/sidebar.js index 3b3b2777b..2c1cb259c 100644 --- a/editor/js/ui/sidebar.js +++ b/editor/js/ui/sidebar.js @@ -102,7 +102,7 @@ RED.sidebar = (function() { sidebarSeparator.start = ui.position.left; sidebarSeparator.chartWidth = $("#workspace").width(); sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2; - + if (!RED.menu.isSelected("menu-item-sidebar")) { sidebarSeparator.opening = true; var newChartRight = 7; @@ -196,7 +196,7 @@ RED.sidebar = (function() { } 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.keyboard.add("*",/* SPACE */ 32,{ctrl:true},function(){RED.menu.setSelected("menu-item-sidebar",!RED.menu.isSelected("menu-item-sidebar"));d3.event.preventDefault();}); showSidebar(); RED.sidebar.info.init(); RED.sidebar.config.init(); diff --git a/editor/js/ui/view.js b/editor/js/ui/view.js index 0c1d83691..45b0a926d 100644 --- a/editor/js/ui/view.js +++ b/editor/js/ui/view.js @@ -436,13 +436,26 @@ RED.view = (function() { } }); - RED.keyboard.add(/* z */ 90,{ctrl:true},function(){RED.history.pop();}); - RED.keyboard.add(/* a */ 65,{ctrl:true},function(){selectAll();d3.event.preventDefault();}); - RED.keyboard.add(/* = */ 187,{ctrl:true},function(){zoomIn();d3.event.preventDefault();}); - RED.keyboard.add(/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();}); - RED.keyboard.add(/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();}); - RED.keyboard.add(/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();}); + RED.keyboard.add("workspace",/* backspace */ 8,function(){deleteSelection();d3.event.preventDefault();}); + RED.keyboard.add("workspace",/* delete */ 46,function(){deleteSelection();d3.event.preventDefault();}); + RED.keyboard.add("workspace",/* c */ 67,{ctrl:true},function(){copySelection();d3.event.preventDefault();}); + RED.keyboard.add("workspace",/* x */ 88,{ctrl:true},function(){copySelection();deleteSelection();d3.event.preventDefault();}); + RED.keyboard.add("workspace",/* z */ 90,{ctrl:true},function(){RED.history.pop();}); + RED.keyboard.add("workspace",/* a */ 65,{ctrl:true},function(){selectAll();d3.event.preventDefault();}); + RED.keyboard.add("*",/* = */ 187,{ctrl:true},function(){zoomIn();d3.event.preventDefault();}); + RED.keyboard.add("*",/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();}); + RED.keyboard.add("*",/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();}); + RED.keyboard.add("workspace",/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();}); + + RED.keyboard.add("workspace",/* up */ 38, function() { moveSelection(0,-1);d3.event.preventDefault();},endKeyboardMove); + 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); } function canvasMouseDown() { @@ -868,29 +881,6 @@ RED.view = (function() { } function updateSelection() { - if (moving_set.length === 0 && selected_link == null) { - RED.keyboard.remove(/* backspace */ 8); - RED.keyboard.remove(/* delete */ 46); - RED.keyboard.remove(/* c */ 67); - RED.keyboard.remove(/* x */ 88); - } else { - RED.keyboard.add(/* backspace */ 8,function(){deleteSelection();d3.event.preventDefault();}); - RED.keyboard.add(/* delete */ 46,function(){deleteSelection();d3.event.preventDefault();}); - RED.keyboard.add(/* c */ 67,{ctrl:true},function(){copySelection();d3.event.preventDefault();}); - RED.keyboard.add(/* x */ 88,{ctrl:true},function(){copySelection();deleteSelection();d3.event.preventDefault();}); - } - if (moving_set.length === 0) { - RED.keyboard.remove(/* up */ 38); - RED.keyboard.remove(/* down */ 40); - RED.keyboard.remove(/* left */ 37); - RED.keyboard.remove(/* right*/ 39); - } else { - RED.keyboard.add(/* up */ 38, function() { if(d3.event.shiftKey){moveSelection( 0,-20)}else{moveSelection( 0,-1);}d3.event.preventDefault();},endKeyboardMove); - RED.keyboard.add(/* down */ 40, function() { if(d3.event.shiftKey){moveSelection( 0, 20)}else{moveSelection( 0, 1);}d3.event.preventDefault();},endKeyboardMove); - RED.keyboard.add(/* left */ 37, function() { if(d3.event.shiftKey){moveSelection(-20, 0)}else{moveSelection(-1, 0);}d3.event.preventDefault();},endKeyboardMove); - RED.keyboard.add(/* right*/ 39, function() { if(d3.event.shiftKey){moveSelection( 20, 0)}else{moveSelection( 1, 0);}d3.event.preventDefault();},endKeyboardMove); - } - var selection = {}; if (moving_set.length > 0) { @@ -903,118 +893,124 @@ RED.view = (function() { } function endKeyboardMove() { - var ns = []; - for (var i=0;i 0) { + var ns = []; for (var i=0;i 0) { - result = RED.subflow.removeOutput(removedSubflowOutputs); - if (result) { - removedLinks = removedLinks.concat(result.links); - } - } - // Assume 0/1 inputs - if (removedSubflowInputs.length == 1) { - result = RED.subflow.removeInput(); - if (result) { - removedLinks = removedLinks.concat(result.links); - } - } - var instances = RED.subflow.refresh(true); - if (instances) { - subflowInstances = instances.instances; - } - moving_set = []; - if (removedNodes.length > 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0) { - RED.nodes.dirty(true); - } - } - if (selected_link) { - RED.nodes.removeLink(selected_link); - removedLinks.push(selected_link); + RED.history.push({t:'move',nodes:ns,dirty:RED.nodes.dirty()}); RED.nodes.dirty(true); } - var historyEvent = { - t:'delete', - nodes:removedNodes, - links:removedLinks, - subflowOutputs:removedSubflowOutputs, - subflowInputs:removedSubflowInputs, - subflow: { - instances: subflowInstances - }, - dirty:startDirty - }; - RED.history.push(historyEvent); + } + function moveSelection(dx,dy) { + if (moving_set.length > 0) { + var minX = 0; + var minY = 0; + var node; - selected_link = null; - updateActiveNodes(); - updateSelection(); - redraw(); + for (var i=0;i 0 || selected_link != null) { + var result; + var removedNodes = []; + var removedLinks = []; + var removedSubflowOutputs = []; + var removedSubflowInputs = []; + var subflowInstances = []; + + var startDirty = RED.nodes.dirty(); + var startChanged = false; + if (moving_set.length > 0) { + for (var i=0;i 0) { + result = RED.subflow.removeOutput(removedSubflowOutputs); + if (result) { + removedLinks = removedLinks.concat(result.links); + } + } + // Assume 0/1 inputs + if (removedSubflowInputs.length == 1) { + result = RED.subflow.removeInput(); + if (result) { + removedLinks = removedLinks.concat(result.links); + } + } + var instances = RED.subflow.refresh(true); + if (instances) { + subflowInstances = instances.instances; + } + moving_set = []; + if (removedNodes.length > 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0) { + RED.nodes.dirty(true); + } + } + if (selected_link) { + RED.nodes.removeLink(selected_link); + removedLinks.push(selected_link); + RED.nodes.dirty(true); + } + var historyEvent = { + t:'delete', + nodes:removedNodes, + links:removedLinks, + subflowOutputs:removedSubflowOutputs, + subflowInputs:removedSubflowInputs, + subflow: { + instances: subflowInstances + }, + dirty:startDirty + }; + RED.history.push(historyEvent); + + selected_link = null; + updateActiveNodes(); + updateSelection(); + redraw(); + } } function copySelection() { @@ -2027,7 +2023,7 @@ RED.view = (function() { } } - RED.keyboard.add(/* ESCAPE */ 27,function(){ + RED.keyboard.add("*",/* ESCAPE */ 27,function(){ RED.keyboard.remove(/* ESCAPE */ 27); clearSelection(); RED.history.pop(); diff --git a/editor/js/ui/workspaces.js b/editor/js/ui/workspaces.js index 75e846abe..d16eb8022 100644 --- a/editor/js/ui/workspaces.js +++ b/editor/js/ui/workspaces.js @@ -162,10 +162,8 @@ RED.workspaces = (function() { ], open: function(e) { - RED.keyboard.disable(); }, close: function(e) { - RED.keyboard.enable(); } }); $( "#node-dialog-delete-workspace" ).dialog({ @@ -190,10 +188,8 @@ RED.workspaces = (function() { } ], open: function(e) { - RED.keyboard.disable(); }, close: function(e) { - RED.keyboard.enable(); } });