From a8e7627184226aaeb3efb952ac83e864cb9de8c5 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 4 Aug 2020 21:01:08 +0100 Subject: [PATCH] Support select-all inside active group --- .../@node-red/editor-client/src/js/ui/view.js | 426 +++++++++++------- 1 file changed, 254 insertions(+), 172 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index 2d6d5bf41..81a5eed10 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -74,7 +74,6 @@ RED.view = (function() { var mouse_position = null; var mouse_mode = 0; var mousedown_group_handle = null; - var moving_set = []; var lasso = null; var ghostNode = null; var showStatus = false; @@ -116,6 +115,49 @@ RED.view = (function() { var groupLayer; var drag_lines; + var movingSet = (function() { + var setIds = new Set(); + var set = []; + var api = { + add: function(node) { + if (Array.isArray(node)) { + for (var i=0;i 0) || (!node.n.hasOwnProperty("inputs") && node.n._def.inputs > 0)) && ((node.n.hasOwnProperty("outputs") && node.n.outputs > 0) || (!node.n.hasOwnProperty("outputs") && node.n._def.outputs > 0)) && @@ -1329,8 +1371,8 @@ RED.view = (function() { var minY = 0; var maxX = space_width; var maxY = space_height; - for (var n = 0; n 0) { + if (snapGrid != d3.event.shiftKey && movingSet.length() > 0) { var i = 0; // Prefer to snap nodes to the grid if there is one in the selection do { - node = moving_set[i++]; - } while(i x && n.x < x2 && n.y > y && n.y < y2); if (n.selected) { n.dirty = true; - moving_set.push({n:n}); + movingSet.add(n); } }); activeSubflow.out.forEach(function(n) { n.selected = (n.x > x && n.x < x2 && n.y > y && n.y < y2); if (n.selected) { n.dirty = true; - moving_set.push({n:n}); + movingSet.add(n); } }); if (activeSubflow.status) { activeSubflow.status.selected = (activeSubflow.status.x > x && activeSubflow.status.x < x2 && activeSubflow.status.y > y && activeSubflow.status.y < y2); if (activeSubflow.status.selected) { activeSubflow.status.dirty = true; - moving_set.push({n:activeSubflow.status}); + movingSet.add(activeSubflow.status); } } } @@ -1594,11 +1638,11 @@ RED.view = (function() { updateSelection(); } if (mouse_mode == RED.state.MOVING_ACTIVE) { - if (moving_set.length > 0) { + if (movingSet.length() > 0) { var addedToGroup = null; if (activeHoverGroup) { - for (var j=0;j 0) { - var node = moving_set[0].n; + if (movingSet.length() > 0) { + var node = movingSet.get(0).n; if (node.type === "subflow") { RED.editor.editSubflow(activeSubflow); } else if (node.type === "group") { @@ -1955,7 +2020,7 @@ RED.view = (function() { updateActiveNodes(); updateSelection(); redraw(); - } else if (moving_set.length > 0 || selected_link != null) { + } else if (movingSet.length() > 0 || selected_link != null) { var result; var node; var removedNodes = []; @@ -1969,10 +2034,10 @@ RED.view = (function() { var startDirty = RED.nodes.dirty(); var startChanged = false; var selectedGroups = []; - if (moving_set.length > 0) { + if (movingSet.length() > 0) { - for (var i=0;i 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0 || removedSubflowStatus || removedGroups.length > 0) { RED.nodes.dirty(true); } @@ -2700,12 +2765,13 @@ RED.view = (function() { function prepareDrag(mouse) { mouse_mode = RED.state.MOVING; - // Called when moving_set should be prepared to be dragged - for (i=0;i= 0; i -= 1) { - if (moving_set[i].n === group) { - moving_set.splice(i,1); - break; - } - } + movingSet.remove(group); } function exitActiveGroup() { if (activeGroup) { @@ -3263,11 +3333,12 @@ RED.view = (function() { } var nodeSet = new Set(g.nodes); nodeSet.add(g); - for (var i = moving_set.length-1; i >= 0; i -= 1) { - if (nodeSet.has(moving_set[i].n) || moving_set[i].n === g) { - moving_set[i].n.selected = false; - moving_set[i].n.dirty = true; - moving_set.splice(i,1); + for (var i = movingSet.length()-1; i >= 0; i -= 1) { + var msn = movingSet.get(i); + if (nodeSet.has(msn.n) || msn.n === g) { + msn.n.selected = false; + msn.n.dirty = true; + movingSet.remove(msn.n,i) } } } @@ -3351,11 +3422,11 @@ RED.view = (function() { function showTouchMenu(obj,pos) { var mdn = mousedown_node; var options = []; - options.push({name:"delete",disabled:(moving_set.length===0 && selected_link === null),onselect:function() {deleteSelection();}}); - options.push({name:"cut",disabled:(moving_set.length===0),onselect:function() {copySelection();deleteSelection();}}); - options.push({name:"copy",disabled:(moving_set.length===0),onselect:function() {copySelection();}}); + options.push({name:"delete",disabled:(movingSet.length()===0 && selected_link === null),onselect:function() {deleteSelection();}}); + options.push({name:"cut",disabled:(movingSet.length()===0),onselect:function() {copySelection();deleteSelection();}}); + options.push({name:"copy",disabled:(movingSet.length()===0),onselect:function() {copySelection();}}); options.push({name:"paste",disabled:(clipboard.length===0),onselect:function() {importNodes(clipboard,false,true);}}); - options.push({name:"edit",disabled:(moving_set.length != 1),onselect:function() { RED.editor.edit(mdn);}}); + options.push({name:"edit",disabled:(movingSet.length() != 1),onselect:function() { RED.editor.edit(mdn);}}); options.push({name:"select",onselect:function() {selectAll();}}); options.push({name:"undo",disabled:(RED.history.depth() === 0),onselect:function() {RED.history.pop();}}); options.push({name:"add",onselect:function() { @@ -4173,7 +4244,7 @@ RED.view = (function() { targets.forEach(function(n) { n.selected = true; n.dirty = true; - moving_set.push({n:n}); + movingSet.add(n); }); updateSelection(); redraw(); @@ -4340,6 +4411,13 @@ RED.view = (function() { d.y = minY; d.w = maxX - minX; d.h = maxY - minY; + // if set explicitly to false, this group has just been + // imported so needed this initial resize calculation. + // Now that's done, delete the flag so the normal + // logic kicks in. + if (d.groupMoved === false) { + delete d.groupMoved; + } } else { delete d.groupMoved; } @@ -4388,12 +4466,12 @@ RED.view = (function() { var selectGroupRect = selectGroup.children[0]; selectGroupRect.setAttribute("width",d.w+8) selectGroupRect.setAttribute("height",d.h+8) - selectGroupRect.style.strokeOpacity = (d.selected || d.highlighted)?0.8:0; + selectGroupRect.style.strokeOpacity = (d.active || d.selected || d.highlighted)?0.8:0; selectGroupRect.style.strokeDasharray = (d.active)?"10 4":""; selectGroupRect = selectGroup.children[1]; selectGroupRect.setAttribute("width",d.w+8) selectGroupRect.setAttribute("height",d.h+8) - selectGroupRect.style.strokeOpacity = (d.selected || d.highlighted)?0.8:0; + selectGroupRect.style.strokeOpacity = (d.active || d.selected || d.highlighted)?0.8:0; selectGroupRect.style.strokeDasharray = (d.active)?"10 4":""; if (d.highlighted) { @@ -4517,21 +4595,25 @@ RED.view = (function() { if (addNewFlow && new_default_workspace) { RED.workspaces.show(new_default_workspace.id); } - var new_ms = new_nodes.filter(function(n) { return n.hasOwnProperty("x") && n.hasOwnProperty("y") && n.z == RED.workspaces.active() }).map(function(n) { return {n:n};}); - new_ms = new_ms.concat(new_groups.filter(function(g) { return g.z === RED.workspaces.active()}).map(function(g) { return {n:g}})) + var new_ms = new_nodes.filter(function(n) { return n.hasOwnProperty("x") && n.hasOwnProperty("y") && n.z == RED.workspaces.active() }); + new_ms = new_ms.concat(new_groups.filter(function(g) { return g.z === RED.workspaces.active()})) var new_node_ids = new_nodes.map(function(n){ n.changed = true; return n.id; }); + + clearSelection(); + movingSet.clear(); + movingSet.add(new_ms); + + // TODO: pick a more sensible root node - if (new_ms.length > 0) { - - + if (movingSet.length() > 0) { if (mouse_position == null) { mouse_position = [0,0]; } var dx = mouse_position[0]; var dy = mouse_position[1]; - if (new_ms.length > 0) { - var root_node = new_ms[0].n; + if (movingSet.length() > 0) { + var root_node = movingSet.get(0).n; dx = root_node.x; dy = root_node.y; } @@ -4540,9 +4622,9 @@ RED.view = (function() { var minY = 0; var i; var node,group; - - for (i=0;i 0) || (!node.n.hasOwnProperty("inputs") && node.n._def.inputs > 0)) && ((node.n.hasOwnProperty("outputs") && node.n.outputs > 0) || (!node.n.hasOwnProperty("outputs") && node.n._def.outputs > 0)) @@ -4594,8 +4677,6 @@ RED.view = (function() { RED.history.pop(); mouse_mode = 0; }); - clearSelection(); - moving_set = new_ms; } var historyEvent = { @@ -4607,7 +4688,7 @@ RED.view = (function() { subflows:new_subflows, dirty:RED.nodes.dirty() }; - if (new_ms.length === 0) { + if (movingSet.length() === 0) { RED.nodes.dirty(true); } if (activeSubflow) { @@ -4692,10 +4773,10 @@ RED.view = (function() { var changed = false; if (workspaceSelection.length > 0) { // TODO: toggle workspace state - } else if (moving_set.length > 0) { + } else if (movingSet.length() > 0) { var historyEvents = []; - for (var i=0;i 0) { - moving_set.forEach(function(n) { + if (movingSet.length() > 0) { + movingSet.forEach(function(n) { if (n.n.type !== 'group') { allNodes.add(n.n); } @@ -4796,12 +4877,13 @@ RED.view = (function() { if (selectedNode) { selectedNode.selected = true; selectedNode.dirty = true; - moving_set = [{n:selectedNode}]; + movingSet.clear(); + movingSet.add(selectedNode); } } else if (selection) { if (selection.nodes) { updateActiveNodes(); - moving_set = []; + movingSet.clear(); // TODO: this selection group span groups // - if all in one group -> activate the group // - if in multiple groups (or group/no-group) @@ -4810,7 +4892,7 @@ RED.view = (function() { if (n.type !== "group") { n.selected = true; n.dirty = true; - moving_set.push({n:n}); + movingSet.add(n); } else { selectGroup(n,true); } @@ -4917,7 +4999,7 @@ RED.view = (function() { if (n) { n.selected = true; n.dirty = true; - moving_set.push({n:n}); + movingSet.add(n); } }) } @@ -4953,7 +5035,7 @@ RED.view = (function() { text: RED._("common.label.done"), class: "primary", click: function(e) { - var selection = moving_set.map(function(n) { return n.n;}); + var selection = movingSet.nodes() selectNodesOptions.done(selection); } });