mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Use cursor keys to change selection in workspace
This commit is contained in:
		| @@ -38,13 +38,14 @@ | ||||
|         "backspace": "core:delete-selection", | ||||
|         "delete": "core:delete-selection", | ||||
|         "enter": "core:edit-selected-node", | ||||
|         "ctrl-enter": "core:go-to-selected-subflow", | ||||
|         "ctrl-enter": "core:go-to-selection", | ||||
|         "ctrl-c": "core:copy-selection-to-internal-clipboard", | ||||
|         "ctrl-x": "core:cut-selection-to-internal-clipboard", | ||||
|         "ctrl-v": "core:paste-from-internal-clipboard", | ||||
|         "ctrl-z": "core:undo", | ||||
|         "ctrl-y": "core:redo", | ||||
|         "ctrl-a": "core:select-all-nodes", | ||||
|         "escape": "core:select-none", | ||||
|         "alt-s u": "core:select-upstream-nodes", | ||||
|         "alt-s d": "core:select-downstream-nodes", | ||||
|         "alt-s c": "core:select-connected-nodes", | ||||
| @@ -57,21 +58,25 @@ | ||||
|         "shift-d": "core:step-view-right", | ||||
|         "shift-s": "core:step-view-down", | ||||
|         "shift-a": "core:step-view-left", | ||||
|         "up": "core:move-selection-up", | ||||
|         "right": "core:move-selection-right", | ||||
|         "down": "core:move-selection-down", | ||||
|         "left": "core:move-selection-left", | ||||
|         "ctrl-up": "core:move-selection-up", | ||||
|         "ctrl-right": "core:move-selection-right", | ||||
|         "ctrl-down": "core:move-selection-down", | ||||
|         "ctrl-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", | ||||
|         "ctrl-[": "core:show-previous-tab", | ||||
|         "ctrl-]": "core:show-next-tab", | ||||
|         "ctrl-shift-left": "core:go-to-previous-location", | ||||
|         "ctrl-shift-right": "core:go-to-next-location", | ||||
|         "ctrl-shift-g": "core:group-selection", | ||||
|         "ctrl-shift-u": "core:ungroup-selection", | ||||
|         "ctrl-shift-c": "core:copy-group-style", | ||||
|         "ctrl-shift-v": "core:paste-group-style" | ||||
|         "ctrl-shift-v": "core:paste-group-style", | ||||
|         "right": "core:go-to-nearest-node-on-right", | ||||
|         "left": "core:go-to-nearest-node-on-left", | ||||
|         "up": "core:go-to-nearest-node-above", | ||||
|         "down": "core:go-to-nearest-node-below" | ||||
|      } | ||||
| } | ||||
|   | ||||
| @@ -151,7 +151,6 @@ RED.actionList = (function() { | ||||
|         } | ||||
|         if (!visible) { | ||||
|             previousActiveElement = document.activeElement; | ||||
|             RED.keyboard.add("*","escape",function(){hide()}); | ||||
|             $("#red-ui-header-shade").show(); | ||||
|             $("#red-ui-editor-shade").show(); | ||||
|             $("#red-ui-palette-shade").show(); | ||||
| @@ -185,7 +184,6 @@ RED.actionList = (function() { | ||||
|  | ||||
|     function hide() { | ||||
|         if (visible) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|             visible = false; | ||||
|             $("#red-ui-header-shade").hide(); | ||||
|             $("#red-ui-editor-shade").hide(); | ||||
| @@ -215,6 +213,9 @@ RED.actionList = (function() { | ||||
|         RED.events.on("type-search:open",function() { disabled = true; }); | ||||
|         RED.events.on("type-search:close",function() { disabled = false; }); | ||||
|  | ||||
|         RED.keyboard.add("red-ui-actionList","escape",function(){hide()}); | ||||
|  | ||||
|  | ||||
|         $("#red-ui-header-shade").on('mousedown',hide); | ||||
|         $("#red-ui-editor-shade").on('mousedown',hide); | ||||
|         $("#red-ui-palette-shade").on('mousedown',hide); | ||||
|   | ||||
| @@ -889,7 +889,6 @@ RED.clipboard = (function() { | ||||
|  | ||||
|     function hideDropTarget() { | ||||
|         $("#red-ui-drop-target").hide(); | ||||
|         RED.keyboard.remove("escape"); | ||||
|     } | ||||
|     function copyText(value,element,msg) { | ||||
|         var truncated = false; | ||||
| @@ -1266,11 +1265,12 @@ RED.clipboard = (function() { | ||||
|  | ||||
|             $('<div id="red-ui-drop-target"><div data-i18n="[append]workspace.dropFlowHere"><i class="fa fa-download"></i><br></div></div>').appendTo('#red-ui-editor'); | ||||
|  | ||||
|             RED.keyboard.add("#red-ui-drop-target", "escape" ,hideDropTarget); | ||||
|  | ||||
|             $('#red-ui-workspace-chart').on("dragenter",function(event) { | ||||
|                 if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 || | ||||
|                      $.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { | ||||
|                     $("#red-ui-drop-target").css({display:'table'}); | ||||
|                     RED.keyboard.add("*", "escape" ,hideDropTarget); | ||||
|                     $("#red-ui-drop-target").css({display:'table'}).focus(); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|   | ||||
| @@ -44,7 +44,11 @@ RED.keyboard = (function() { | ||||
|         "/":191, | ||||
|         "\\":220, | ||||
|         "'":222, | ||||
|         "?":191 // <- QWERTY specific | ||||
|         "?":191, // <- QWERTY specific | ||||
|         "[": 219, | ||||
|         "]": 221, | ||||
|         "{": 219,// <- QWERTY specific | ||||
|         "}": 221 // <- QWERTY specific | ||||
|     } | ||||
|     var metaKeyCodes = { | ||||
|         16: true, | ||||
|   | ||||
| @@ -357,7 +357,6 @@ RED.search = (function() { | ||||
|         } | ||||
|         if (!visible) { | ||||
|             previousActiveElement = document.activeElement; | ||||
|             RED.keyboard.add("*","escape",function(){hide()}); | ||||
|             $("#red-ui-header-shade").show(); | ||||
|             $("#red-ui-editor-shade").show(); | ||||
|             $("#red-ui-palette-shade").show(); | ||||
| @@ -377,7 +376,6 @@ RED.search = (function() { | ||||
|  | ||||
|     function hide() { | ||||
|         if (visible) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|             visible = false; | ||||
|             $("#red-ui-header-shade").hide(); | ||||
|             $("#red-ui-editor-shade").hide(); | ||||
| @@ -429,7 +427,7 @@ RED.search = (function() { | ||||
|         RED.events.on("actionList:open",function() { disabled = true; }); | ||||
|         RED.events.on("actionList:close",function() { disabled = false; }); | ||||
|  | ||||
|  | ||||
|         RED.keyboard.add("red-ui-search","escape",hide); | ||||
|  | ||||
|         $("#red-ui-header-shade").on('mousedown',hide); | ||||
|         $("#red-ui-editor-shade").on('mousedown',hide); | ||||
|   | ||||
| @@ -224,14 +224,14 @@ RED.typeSearch = (function() { | ||||
|     } | ||||
|     function show(opts) { | ||||
|         if (!visible) { | ||||
|             RED.keyboard.add("*","escape",function(){ | ||||
|                 hide(); | ||||
|                 if (cancelCallback) { | ||||
|                     cancelCallback(); | ||||
|                 } | ||||
|             }); | ||||
|             if (dialog === null) { | ||||
|                 createDialog(); | ||||
|                 RED.keyboard.add("red-ui-type-search","escape",function(){ | ||||
|                     hide(); | ||||
|                     if (cancelCallback) { | ||||
|                         cancelCallback(); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             visible = true; | ||||
|         } else { | ||||
| @@ -266,11 +266,10 @@ RED.typeSearch = (function() { | ||||
|             if (!opts.disableFocus) { | ||||
|                 searchInput.trigger("focus"); | ||||
|             } | ||||
|         },100); | ||||
|         },200); | ||||
|     } | ||||
|     function hide(fast) { | ||||
|         if (visible) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|             visible = false; | ||||
|             if (dialog !== null) { | ||||
|                 searchResultsDiv.slideUp(fast?50:200,function() { | ||||
|   | ||||
| @@ -201,6 +201,237 @@ RED.view.tools = (function() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function selectFirstNode() { | ||||
|         var canidates; | ||||
|         var origin = {x:0, y:0}; | ||||
|  | ||||
|         var activeGroup = RED.view.getActiveGroup(); | ||||
|  | ||||
|         if (!activeGroup) { | ||||
|             candidates = RED.view.getActiveNodes(); | ||||
|         } else { | ||||
|             candidates = RED.group.getNodes(activeGroup,false); | ||||
|             origin = activeGroup; | ||||
|         } | ||||
|  | ||||
|         var distances = []; | ||||
|         candidates.forEach(function(node) { | ||||
|             var deltaX = node.x - origin.x; | ||||
|             var deltaY = node.y - origin.x; | ||||
|             var delta = deltaY*deltaY + deltaX*deltaX; | ||||
|             distances.push({node: node, delta: delta}) | ||||
|         }); | ||||
|         if (distances.length > 0) { | ||||
|             distances.sort(function(A,B) { | ||||
|                 return A.delta - B.delta | ||||
|             }) | ||||
|             var newNode = distances[0].node; | ||||
|             if (newNode) { | ||||
|                 RED.view.select({nodes:[newNode]}); | ||||
|                 RED.view.reveal(newNode.id,false); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function gotoNextNode() { | ||||
|         var selection = RED.view.selection(); | ||||
|         if (selection.nodes && selection.nodes.length === 1) { | ||||
|             var origin = selection.nodes[0]; | ||||
|             var links = RED.nodes.filterLinks({source:origin}); | ||||
|             if (links.length > 0) { | ||||
|                 links.sort(function(A,B) { | ||||
|                     return Math.abs(A.target.y - origin.y) - Math.abs(B.target.y - origin.y) | ||||
|                 }) | ||||
|                 var newNode = links[0].target; | ||||
|                 if (newNode) { | ||||
|                     RED.view.select({nodes:[newNode]}); | ||||
|                     RED.view.reveal(newNode.id,false); | ||||
|                 } | ||||
|             } | ||||
|         } else if (RED.workspaces.selection().length === 0) { | ||||
|             selectFirstNode(); | ||||
|         } | ||||
|     } | ||||
|     function gotoPreviousNode() { | ||||
|         var selection = RED.view.selection(); | ||||
|         if (selection.nodes && selection.nodes.length === 1) { | ||||
|             var origin = selection.nodes[0]; | ||||
|             var links = RED.nodes.filterLinks({target:origin}); | ||||
|             if (links.length > 0) { | ||||
|                 links.sort(function(A,B) { | ||||
|                     return Math.abs(A.source.y - origin.y) - Math.abs(B.source.y - origin.y) | ||||
|                 }) | ||||
|                 var newNode = links[0].source; | ||||
|                 if (newNode) { | ||||
|                     RED.view.select({nodes:[newNode]}); | ||||
|                     RED.view.reveal(newNode.id,false); | ||||
|                 } | ||||
|             } | ||||
|         } else if (RED.workspaces.selection().length === 0) { | ||||
|             selectFirstNode(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function getChildren(node) { | ||||
|         return RED.nodes.filterLinks({source:node}).map(function(l) { return l.target}) | ||||
|     } | ||||
|     function getParents(node) { | ||||
|         return RED.nodes.filterLinks({target:node}).map(function(l) { return l.source}) | ||||
|     } | ||||
|  | ||||
|     function getSiblings(node) { | ||||
|         var siblings = new Set(); | ||||
|         var parents = getParents(node); | ||||
|         parents.forEach(function(p) { | ||||
|             getChildren(p).forEach(function(c) { siblings.add(c) }) | ||||
|         }); | ||||
|         var children = getChildren(node); | ||||
|         children.forEach(function(p) { | ||||
|             getParents(p).forEach(function(c) { siblings.add(c) }) | ||||
|         }); | ||||
|         siblings.delete(node); | ||||
|         return Array.from(siblings); | ||||
|     } | ||||
|     function gotoNextSibling() { | ||||
|         // 'next' defined as nearest on the y-axis below this node | ||||
|         var selection = RED.view.selection(); | ||||
|         if (selection.nodes && selection.nodes.length === 1) { | ||||
|             var origin = selection.nodes[0]; | ||||
|             var siblings = getSiblings(origin); | ||||
|             if (siblings.length > 0) { | ||||
|                 siblings = siblings.filter(function(n) { return n.y > origin. y}) | ||||
|                 siblings.sort(function(A,B) { | ||||
|                     return Math.abs(A.y - origin.y) - Math.abs(B.y - origin.y) | ||||
|                 }) | ||||
|                 var newNode = siblings[0]; | ||||
|                 if (newNode) { | ||||
|                     RED.view.select({nodes:[newNode]}); | ||||
|                     RED.view.reveal(newNode.id,false); | ||||
|                 } | ||||
|             } | ||||
|         } else if (RED.workspaces.selection().length === 0) { | ||||
|             selectFirstNode(); | ||||
|         } | ||||
|     } | ||||
|     function gotoPreviousSibling() { | ||||
|         // 'next' defined as nearest on the y-axis above this node | ||||
|         var selection = RED.view.selection(); | ||||
|         if (selection.nodes && selection.nodes.length === 1) { | ||||
|             var origin = selection.nodes[0]; | ||||
|             var siblings = getSiblings(origin); | ||||
|             if (siblings.length > 0) { | ||||
|                 siblings = siblings.filter(function(n) { return n.y < origin. y}) | ||||
|                 siblings.sort(function(A,B) { | ||||
|                     return Math.abs(A.y - origin.y) - Math.abs(B.y - origin.y) | ||||
|                 }) | ||||
|                 var newNode = siblings[0]; | ||||
|                 if (newNode) { | ||||
|                     RED.view.select({nodes:[newNode]}); | ||||
|                     RED.view.reveal(newNode.id,false); | ||||
|                 } | ||||
|             } | ||||
|         } else if (RED.workspaces.selection().length === 0) { | ||||
|             selectFirstNode(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function addNode() { | ||||
|         var selection = RED.view.selection(); | ||||
|         if (selection.nodes && selection.nodes.length === 1 && selection.nodes[0].outputs > 0) { | ||||
|             var selectedNode = selection.nodes[0]; | ||||
|             RED.view.showQuickAddDialog([ | ||||
|                 selectedNode.x + selectedNode.w + 50,selectedNode.y | ||||
|             ]) | ||||
|         } else { | ||||
|             RED.view.showQuickAddDialog(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function gotoNearestNode(direction) { | ||||
|         var selection = RED.view.selection(); | ||||
|         if (selection.nodes && selection.nodes.length === 1) { | ||||
|             var origin = selection.nodes[0]; | ||||
|  | ||||
|             var candidates = RED.nodes.filterNodes({z:origin.z}); | ||||
|             candidates = candidates.concat(RED.view.getSubflowPorts()); | ||||
|             var distances = []; | ||||
|             candidates.forEach(function(node) { | ||||
|                 if (node === origin) { | ||||
|                     return; | ||||
|                 } | ||||
|                 var deltaX = node.x - origin.x; | ||||
|                 var deltaY = node.y - origin.y; | ||||
|                 var delta = deltaY*deltaY + deltaX*deltaX; | ||||
|                 var angle = (180/Math.PI)*Math.atan2(deltaY,deltaX); | ||||
|                 if (angle < 0) { angle += 360 } | ||||
|                 if (angle > 360) { angle -= 360 } | ||||
|  | ||||
|                 var weight; | ||||
|  | ||||
|                 // 0 - right | ||||
|                 // 270 - above | ||||
|                 // 90 - below | ||||
|                 // 180 - left | ||||
|                 switch(direction) { | ||||
|                     case 'up': if (angle < 210 || angle > 330) { return }; | ||||
|                         weight = Math.max(Math.abs(270 - angle)/60, 0.2); | ||||
|                         break; | ||||
|                     case 'down': if (angle < 30 || angle > 150) { return }; | ||||
|                         weight = Math.max(Math.abs(90 - angle)/60, 0.2); | ||||
|                         break; | ||||
|                     case 'left': if (angle < 140 || angle > 220) { return }; | ||||
|                         weight = Math.max(Math.abs(180 - angle)/40, 0.1 ); | ||||
|                         break; | ||||
|                     case 'right': if (angle > 40 && angle < 320) { return }; | ||||
|                         weight = Math.max(Math.abs(angle)/40, 0.1); | ||||
|                         break; | ||||
|                 } | ||||
|                 weight = Math.max(weight,0.1); | ||||
|                 distances.push({ | ||||
|                     node: node, | ||||
|                     d: delta, | ||||
|                     w: weight, | ||||
|                     delta: delta*weight | ||||
|                 }) | ||||
|             }) | ||||
|             if (distances.length > 0) { | ||||
|                 distances.sort(function(A,B) { | ||||
|                     return A.delta - B.delta | ||||
|                 }) | ||||
|                 var newNode = distances[0].node; | ||||
|                 if (newNode) { | ||||
|                     RED.view.select({nodes:[newNode]}); | ||||
|                     RED.view.reveal(newNode.id,false); | ||||
|                 } | ||||
|             } | ||||
|         } else if (RED.workspaces.selection().length === 0) { | ||||
|             var candidates = RED.view.getActiveNodes(); | ||||
|  | ||||
|             var distances = []; | ||||
|             candidates.forEach(function(node) { | ||||
|                 var deltaX = node.x; | ||||
|                 var deltaY = node.y; | ||||
|                 var delta = deltaY*deltaY + deltaX*deltaX; | ||||
|                 distances.push({node: node, delta: delta}) | ||||
|             }); | ||||
|             if (distances.length > 0) { | ||||
|                 distances.sort(function(A,B) { | ||||
|                     return A.delta - B.delta | ||||
|                 }) | ||||
|                 var newNode = distances[0].node; | ||||
|                 if (newNode) { | ||||
|                     RED.view.select({nodes:[newNode]}); | ||||
|                     RED.view.reveal(newNode.id,false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
|             RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); }) | ||||
| @@ -231,6 +462,19 @@ RED.view.tools = (function() { | ||||
|             RED.actions.add("core:select-connected-nodes", function() { selectConnected("all") }); | ||||
|             RED.actions.add("core:select-downstream-nodes", function() { selectConnected("down") }); | ||||
|             RED.actions.add("core:select-upstream-nodes", function() { selectConnected("up") }); | ||||
|  | ||||
|  | ||||
|             RED.actions.add("core:go-to-next-node", function() { gotoNextNode() }) | ||||
|             RED.actions.add("core:go-to-previous-node", function() { gotoPreviousNode() }) | ||||
|             RED.actions.add("core:go-to-next-sibling", function() { gotoNextSibling() }) | ||||
|             RED.actions.add("core:go-to-previous-sibling", function() { gotoPreviousSibling() }) | ||||
|  | ||||
|  | ||||
|             RED.actions.add("core:go-to-nearest-node-on-left", function() { gotoNearestNode('left')}) | ||||
|             RED.actions.add("core:go-to-nearest-node-on-right", function() { gotoNearestNode('right')}) | ||||
|             RED.actions.add("core:go-to-nearest-node-above", function() { gotoNearestNode('up') }) | ||||
|             RED.actions.add("core:go-to-nearest-node-below", function() { gotoNearestNode('down') }) | ||||
|             // RED.actions.add("core:add-node", function() { addNode() }) | ||||
|         }, | ||||
|         /** | ||||
|          * Aligns all selected nodes to the current grid | ||||
|   | ||||
| @@ -86,7 +86,7 @@ RED.view = (function() { | ||||
|     var quickAddLink = null; | ||||
|     var showAllLinkPorts = -1; | ||||
|     var groupNodeSelectPrimed = false; | ||||
|  | ||||
|     var lastClickPosition = []; | ||||
|     var selectNodesOptions; | ||||
|  | ||||
|     var clipboard = ""; | ||||
| @@ -503,10 +503,21 @@ RED.view = (function() { | ||||
|         RED.actions.add("core:paste-from-internal-clipboard",function(){importNodes(clipboard,{generateIds: true});}); | ||||
|         RED.actions.add("core:delete-selection",deleteSelection); | ||||
|         RED.actions.add("core:edit-selected-node",editSelection); | ||||
|         RED.actions.add("core:go-to-selected-subflow",editSelectedSubflow); | ||||
|         RED.actions.add("core:go-to-selection",function() { | ||||
|             if (movingSet.length() > 0) { | ||||
|                 var node = movingSet.get(0).n; | ||||
|                 if (/^subflow:/.test(node.type)) { | ||||
|                     RED.workspaces.show(node.type.substring(8)) | ||||
|                 } else if (node.type === 'group') { | ||||
|                     enterActiveGroup(node); | ||||
|                     redraw(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         RED.actions.add("core:undo",RED.history.pop); | ||||
|         RED.actions.add("core:redo",RED.history.redo); | ||||
|         RED.actions.add("core:select-all-nodes",selectAll); | ||||
|         RED.actions.add("core:select-none", selectNone); | ||||
|         RED.actions.add("core:zoom-in",zoomIn); | ||||
|         RED.actions.add("core:zoom-out",zoomOut); | ||||
|         RED.actions.add("core:zoom-reset",zoomZero); | ||||
| @@ -849,7 +860,7 @@ RED.view = (function() { | ||||
|                 if (drag_lines.length > 0) { | ||||
|                     clickedGroup = clickedGroup || RED.nodes.group(drag_lines[0].node.g) | ||||
|                 } | ||||
|                 showQuickAddDialog(point, null, clickedGroup); | ||||
|                 showQuickAddDialog({position:point, group:clickedGroup}); | ||||
|             } | ||||
|         } | ||||
|         if (mouse_mode === 0 && !(d3.event.metaKey || d3.event.ctrlKey)) { | ||||
| @@ -870,7 +881,13 @@ RED.view = (function() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function showQuickAddDialog(point, spliceLink, targetGroup, touchTrigger) { | ||||
|     function showQuickAddDialog(options) { | ||||
|         options = options || {}; | ||||
|         var point = options.position || lastClickPosition; | ||||
|         var spliceLink = options.splice; | ||||
|         var targetGroup = options.group; | ||||
|         var touchTrigger = options.touchTrigger; | ||||
|  | ||||
|         if (targetGroup && !targetGroup.active) { | ||||
|             selectGroup(targetGroup,false); | ||||
|             enterActiveGroup(targetGroup); | ||||
| @@ -1523,6 +1540,7 @@ RED.view = (function() { | ||||
|     } | ||||
|  | ||||
|     function canvasMouseUp() { | ||||
|         lastClickPosition = [d3.event.offsetX/scaleFactor,d3.event.offsetY/scaleFactor]; | ||||
|         if (RED.view.DEBUG) { console.warn("canvasMouseUp", mouse_mode); } | ||||
|         var i; | ||||
|         var historyEvent; | ||||
| @@ -1767,7 +1785,18 @@ RED.view = (function() { | ||||
|         redraw(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function selectNone() { | ||||
|         if (mouse_mode === RED.state.IMPORT_DRAGGING) { | ||||
|             clearSelection(); | ||||
|             RED.history.pop(); | ||||
|             mouse_mode = 0; | ||||
|         } else if (activeGroup) { | ||||
|             exitActiveGroup() | ||||
|         } else { | ||||
|             clearSelection(); | ||||
|         } | ||||
|         redraw(); | ||||
|     } | ||||
|     function selectAll() { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE && selectNodesOptions.single) { | ||||
|             return; | ||||
| @@ -2206,15 +2235,6 @@ RED.view = (function() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function editSelectedSubflow() { | ||||
|         if (movingSet.length() > 0) { | ||||
|             var node = movingSet.get(0).n; | ||||
|             if (/^subflow:/.test(node.type)) { | ||||
|                 RED.workspaces.show(node.type.substring(8)) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function copySelection() { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             return; | ||||
| @@ -2887,7 +2907,6 @@ RED.view = (function() { | ||||
|         //var pos = [touch0.pageX,touch0.pageY]; | ||||
|         //RED.touch.radialMenu.show(d3.select(this),pos); | ||||
|         if (mouse_mode == RED.state.IMPORT_DRAGGING) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|             var historyEvent = RED.history.peek(); | ||||
|             if (activeSpliceLink) { | ||||
|                 // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp | ||||
| @@ -3258,7 +3277,7 @@ RED.view = (function() { | ||||
|              d3.select(this).classed("red-ui-flow-link-splice",true); | ||||
|              var point = d3.mouse(this); | ||||
|              var clickedGroup = getGroupAt(point[0],point[1]); | ||||
|              showQuickAddDialog(point, selected_link, clickedGroup); | ||||
|              showQuickAddDialog({position:point, splice:selected_link, group:clickedGroup}); | ||||
|          } | ||||
|     } | ||||
|     function linkTouchStart(d) { | ||||
| @@ -3304,9 +3323,8 @@ RED.view = (function() { | ||||
|         if (d3.event.button === 1) { | ||||
|             return; | ||||
|         } | ||||
|         if (mouse_mode == RED.state.IMPORT_DRAGGING) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|         } else if (mouse_mode == RED.state.QUICK_JOINING) { | ||||
|  | ||||
|         if (mouse_mode == RED.state.QUICK_JOINING) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } else if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
| @@ -3513,7 +3531,10 @@ RED.view = (function() { | ||||
|         options.push({name:"undo",disabled:(RED.history.depth() === 0),onselect:function() {RED.history.pop();}}); | ||||
|         options.push({name:"add",onselect:function() { | ||||
|             chartPos = chart.offset(); | ||||
|             showQuickAddDialog([pos[0]-chartPos.left+chart.scrollLeft(),pos[1]-chartPos.top+chart.scrollTop()],undefined,undefined,true) | ||||
|             showQuickAddDialog({ | ||||
|                 position:[pos[0]-chartPos.left+chart.scrollLeft(),pos[1]-chartPos.top+chart.scrollTop()], | ||||
|                 touchTrigger:true | ||||
|             }) | ||||
|         }}); | ||||
|  | ||||
|         RED.touch.radialMenu.show(obj,pos,options); | ||||
| @@ -4805,12 +4826,7 @@ RED.view = (function() { | ||||
|  | ||||
|                         } | ||||
|                     } | ||||
|                     RED.keyboard.add("*","escape",function(){ | ||||
|                             RED.keyboard.remove("escape"); | ||||
|                             clearSelection(); | ||||
|                             RED.history.pop(); | ||||
|                             mouse_mode = 0; | ||||
|                     }); | ||||
|  | ||||
|                 } | ||||
|  | ||||
|                 var historyEvent = { | ||||
| @@ -5138,6 +5154,18 @@ RED.view = (function() { | ||||
|         getActiveNodes: function() { | ||||
|             return activeNodes; | ||||
|         }, | ||||
|         getSubflowPorts: function() { | ||||
|             var result = []; | ||||
|             if (activeSubflow) { | ||||
|                 var subflowOutputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-output").data(activeSubflow.out,function(d,i){ return d.id;}); | ||||
|                 subflowOutputs.each(function(d,i) { result.push(d) }) | ||||
|                 var subflowInputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-input").data(activeSubflow.in,function(d,i){ return d.id;}); | ||||
|                 subflowInputs.each(function(d,i) { result.push(d) }) | ||||
|                 var subflowStatus = nodeLayer.selectAll(".red-ui-flow-subflow-port-status").data(activeSubflow.status?[activeSubflow.status]:[],function(d,i){ return d.id;}); | ||||
|                 subflowStatus.each(function(d,i) { result.push(d) }) | ||||
|             } | ||||
|             return result; | ||||
|         }, | ||||
|         selectNodes: function(options) { | ||||
|             $("#red-ui-workspace-tabs-shade").show(); | ||||
|             $("#red-ui-palette-shade").show(); | ||||
| @@ -5213,6 +5241,7 @@ RED.view = (function() { | ||||
|         clipboard: function() { | ||||
|             return clipboard | ||||
|         }, | ||||
|         redrawStatus: redrawStatus | ||||
|         redrawStatus: redrawStatus, | ||||
|         showQuickAddDialog:showQuickAddDialog | ||||
|     }; | ||||
| })(); | ||||
|   | ||||
| @@ -23,6 +23,16 @@ RED.workspaces = (function() { | ||||
|     var viewStack = []; | ||||
|     var viewStackPos = 0; | ||||
|  | ||||
|  | ||||
|     function addToViewStack(id) { | ||||
|         if (viewStackPos !== viewStack.length) { | ||||
|             viewStack.splice(viewStackPos); | ||||
|         } | ||||
|         viewStack.push(id); | ||||
|         viewStackPos = viewStack.length; | ||||
|         // console.warn("addToViewStack",id,viewStack); | ||||
|     } | ||||
|  | ||||
|     function addWorkspace(ws,skipHistoryEntry,targetIndex) { | ||||
|         if (ws) { | ||||
|             workspace_tabs.addTab(ws,targetIndex); | ||||
| @@ -248,11 +258,9 @@ RED.workspaces = (function() { | ||||
|                 RED.view.focus(); | ||||
|             }, | ||||
|             onclick: function(tab) { | ||||
|                 if (viewStackPos !== viewStack.length) { | ||||
|                     viewStack.splice(viewStackPos); | ||||
|                 if (tab.id !== activeWorkspace) { | ||||
|                     addToViewStack(activeWorkspace); | ||||
|                 } | ||||
|                 viewStack.push(activeWorkspace); | ||||
|                 viewStackPos = viewStack.length; | ||||
|                 RED.view.focus(); | ||||
|             }, | ||||
|             ondblclick: function(tab) { | ||||
| @@ -336,8 +344,20 @@ RED.workspaces = (function() { | ||||
|         createWorkspaceTabs(); | ||||
|         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.actions.add("core:show-next-tab",function() { | ||||
|             var oldActive = activeWorkspace; | ||||
|             workspace_tabs.nextTab(); | ||||
|             if (oldActive !== activeWorkspace) { | ||||
|                 addToViewStack(oldActive) | ||||
|             } | ||||
|         }); | ||||
|         RED.actions.add("core:show-previous-tab",function() { | ||||
|             var oldActive = activeWorkspace; | ||||
|             workspace_tabs.previousTab(); | ||||
|             if (oldActive !== activeWorkspace) { | ||||
|                 addToViewStack(oldActive) | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         RED.menu.setAction('menu-item-workspace-delete',function() { | ||||
|             deleteWorkspace(RED.nodes.workspace(activeWorkspace)); | ||||
| @@ -360,6 +380,8 @@ RED.workspaces = (function() { | ||||
|         RED.actions.add("core:go-to-previous-location", function() { | ||||
|             if (viewStackPos > 0) { | ||||
|                 if (viewStackPos === viewStack.length) { | ||||
|                     // We're at the end of the stack. Remember the activeWorkspace | ||||
|                     // so we can come back to it. | ||||
|                     viewStack.push(activeWorkspace); | ||||
|                 } | ||||
|                 RED.workspaces.show(viewStack[--viewStackPos],true); | ||||
| @@ -476,12 +498,8 @@ RED.workspaces = (function() { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             if (!skipStack) { | ||||
|                 if (viewStackPos !== viewStack.length) { | ||||
|                     viewStack.splice(viewStackPos); | ||||
|                 } | ||||
|                 viewStack.push(activeWorkspace); | ||||
|                 viewStackPos = viewStack.length; | ||||
|             if (!skipStack && activeWorkspace !== id) { | ||||
|                 addToViewStack(activeWorkspace) | ||||
|             } | ||||
|             workspace_tabs.activateTab(id); | ||||
|         }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user