mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
[groups] Support nested groups in editor
This commit is contained in:
parent
86ce5c591b
commit
97d58e34f2
217
packages/node_modules/@node-red/editor-client/src/js/ui/group.js
vendored
Normal file
217
packages/node_modules/@node-red/editor-client/src/js/ui/group.js
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
RED.group = (function() {
|
||||
|
||||
var _groupEditTemplate = '<script type="text/x-red" data-template-name="group">'+
|
||||
'<div class="form-row">'+
|
||||
'<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+
|
||||
'<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+
|
||||
'</div>'+
|
||||
|
||||
'<div class="form-row">'+
|
||||
'<label for="node-input-style-stroke" data-i18n="[append]editor:group.label.stroke">Stroke</label>'+
|
||||
'<input type="text" id="node-input-style-stroke">'+
|
||||
'</div>'+
|
||||
|
||||
'<div class="form-row">'+
|
||||
'<label for="node-input-style-fill" data-i18n="[append]editor:group.label.fill">Fill</label>'+
|
||||
'<input type="text" id="node-input-style-fill">'+
|
||||
'</div>'+
|
||||
|
||||
'</script>';
|
||||
|
||||
var groupDef = {
|
||||
defaults:{
|
||||
name:{value:""},
|
||||
style:{value:{}}
|
||||
},
|
||||
category: "config",
|
||||
oneditprepare: function() {
|
||||
var style = this.style || {};
|
||||
$("#node-input-style-stroke").val(style.stroke || "#eeeeee")
|
||||
$("#node-input-style-fill").val(style.fill || "none")
|
||||
},
|
||||
oneditresize: function(size) {
|
||||
},
|
||||
oneditsave: function() {
|
||||
this.style.stroke = $("#node-input-style-stroke").val();
|
||||
this.style.fill = $("#node-input-style-fill").val();
|
||||
},
|
||||
set:{
|
||||
module: "node-red"
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
RED.actions.add("core:group-selection", function() { groupSelection() })
|
||||
|
||||
$(_groupEditTemplate).appendTo("#red-ui-editor-node-configs");
|
||||
|
||||
}
|
||||
|
||||
function groupSelection() {
|
||||
var selection = RED.view.selection();
|
||||
// var groupNodes = new Set();
|
||||
//
|
||||
// if (selection.groups) {
|
||||
// selection.groups.forEach(function(g) {
|
||||
// g.nodes.forEach()
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// if (selection.nodes) {
|
||||
//
|
||||
// }
|
||||
|
||||
if (selection.nodes) {
|
||||
var group = createGroup(selection.nodes);
|
||||
if (group) {
|
||||
RED.view.select({groups:[group]})
|
||||
}
|
||||
}
|
||||
}
|
||||
function createGroup(nodes) {
|
||||
if (nodes.length === 0) {
|
||||
return;
|
||||
}
|
||||
// nodes is an array
|
||||
// each node must be on the same tab (z)
|
||||
var group = {
|
||||
id: RED.nodes.id(),
|
||||
type: 'group',
|
||||
nodes: [],
|
||||
style: {
|
||||
stroke: "#999",
|
||||
fill: "none"
|
||||
},
|
||||
x: Number.POSITIVE_INFINITY,
|
||||
y: Number.POSITIVE_INFINITY,
|
||||
w: 0,
|
||||
h: 0,
|
||||
_def: RED.group.def
|
||||
}
|
||||
try {
|
||||
addToGroup(group,nodes);
|
||||
} catch(err) {
|
||||
RED.notify(err,"error");
|
||||
return;
|
||||
}
|
||||
group.z = nodes[0].z;
|
||||
|
||||
RED.nodes.addGroup(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
function addToGroup(group,nodes) {
|
||||
if (!Array.isArray(nodes)) {
|
||||
nodes = [nodes];
|
||||
}
|
||||
var i,n,z;
|
||||
var g;
|
||||
// First pass - validate we can safely add these nodes to the group
|
||||
for (i=0;i<nodes.length;i++) {
|
||||
n = nodes[i]
|
||||
if (!n.z) {
|
||||
throw new Error("Cannot add node without a z property to a group")
|
||||
}
|
||||
if (!z) {
|
||||
z = n.z;
|
||||
} else if (z !== n.z) {
|
||||
throw new Error("Cannot create group using nodes with different z properties")
|
||||
}
|
||||
if (n.g) {
|
||||
// This is already in a group.
|
||||
// - check they are all in the same group
|
||||
if (!g) {
|
||||
if (i!==0) {
|
||||
// TODO: this might be ok when merging groups
|
||||
throw new Error("Cannot create group using nodes from different groups")
|
||||
}
|
||||
g = n.g
|
||||
}
|
||||
}
|
||||
if (g !== n.g) {
|
||||
throw new Error("Cannot create group using nodes from different groups")
|
||||
}
|
||||
}
|
||||
if (g) {
|
||||
g = RED.nodes.group(g);
|
||||
g.nodes.push(group);
|
||||
group.g = g.id;
|
||||
}
|
||||
// Second pass - add them to the group
|
||||
for (i=0;i<nodes.length;i++) {
|
||||
n = nodes[i];
|
||||
if (g && n.g === g.id) {
|
||||
var ni = g.nodes.indexOf(n);
|
||||
if (ni > -1) {
|
||||
g.nodes.splice(ni,1)
|
||||
}
|
||||
}
|
||||
n.g = group.id;
|
||||
group.nodes.push(n);
|
||||
group.x = Math.min(group.x,n.x-n.w/2-25-((n._def.button && n._def.align!=="right")?20:0));
|
||||
group.y = Math.min(group.y,n.y-n.h/2-25);
|
||||
group.w = Math.max(group.w,n.x+n.w/2+25+((n._def.button && n._def.align=="right")?20:0) - group.x),
|
||||
group.h = Math.max(group.h,n.y+n.h/2+25-group.y);
|
||||
}
|
||||
}
|
||||
|
||||
function getNodes(group,recursive) {
|
||||
var nodes = [];
|
||||
group.nodes.forEach(function(n) {
|
||||
if (!recursive || n.type !== 'group') {
|
||||
nodes.push(n);
|
||||
} else {
|
||||
nodes = nodes.concat(getNodes(n,recursive))
|
||||
}
|
||||
})
|
||||
return nodes;
|
||||
}
|
||||
|
||||
function groupContains(group,item) {
|
||||
if (item.g === group.id) {
|
||||
return true;
|
||||
}
|
||||
for (var i=0;i<group.nodes.length;i++) {
|
||||
if (group.nodes[i].type === "group") {
|
||||
if (groupContains(group.nodes[i],item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function getRootGroup(group) {
|
||||
if (!group.g) {
|
||||
return group;
|
||||
}
|
||||
return getRootGroup(RED.nodes.group(group.g))
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
def: groupDef,
|
||||
init: init,
|
||||
createGroup: createGroup,
|
||||
addToGroup: addToGroup,
|
||||
getNodes: getNodes,
|
||||
contains: groupContains
|
||||
}
|
||||
})();
|
@ -1122,18 +1122,19 @@ if (DEBUG_EVENTS) { console.warn("canvasMouseDown", mouse_mode); }
|
||||
}
|
||||
|
||||
var mousePos;
|
||||
if (mouse_mode === RED.state.GROUP_RESIZE) {
|
||||
mousePos = mouse_position;
|
||||
var nx = mousePos[0] + mousedown_group.dx;
|
||||
var ny = mousePos[1] + mousedown_group.dy;
|
||||
switch(mousedown_group.activeHandle) {
|
||||
case 0: mousedown_group.pos.x0 = nx; mousedown_group.pos.y0 = ny; break;
|
||||
case 1: mousedown_group.pos.x1 = nx; mousedown_group.pos.y0 = ny; break;
|
||||
case 2: mousedown_group.pos.x1 = nx; mousedown_group.pos.y1 = ny; break;
|
||||
case 3: mousedown_group.pos.x0 = nx; mousedown_group.pos.y1 = ny; break;
|
||||
}
|
||||
mousedown_group.dirty = true;
|
||||
} else if (mouse_mode == RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) {
|
||||
// if (mouse_mode === RED.state.GROUP_RESIZE) {
|
||||
// mousePos = mouse_position;
|
||||
// var nx = mousePos[0] + mousedown_group.dx;
|
||||
// var ny = mousePos[1] + mousedown_group.dy;
|
||||
// switch(mousedown_group.activeHandle) {
|
||||
// case 0: mousedown_group.pos.x0 = nx; mousedown_group.pos.y0 = ny; break;
|
||||
// case 1: mousedown_group.pos.x1 = nx; mousedown_group.pos.y0 = ny; break;
|
||||
// case 2: mousedown_group.pos.x1 = nx; mousedown_group.pos.y1 = ny; break;
|
||||
// case 3: mousedown_group.pos.x0 = nx; mousedown_group.pos.y1 = ny; break;
|
||||
// }
|
||||
// mousedown_group.dirty = true;
|
||||
// }
|
||||
if (mouse_mode == RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) {
|
||||
// update drag line
|
||||
if (drag_lines.length === 0 && mousedown_port_type !== null) {
|
||||
if (d3.event.shiftKey) {
|
||||
@ -1253,13 +1254,11 @@ if (DEBUG_EVENTS) { console.warn("canvasMouseDown", mouse_mode); }
|
||||
node.n.y -= (maxY - space_height);
|
||||
}
|
||||
}
|
||||
if (mousedown_group) {
|
||||
mousedown_group.pos.x0 = mousePos[0] + mousedown_group.dx0;
|
||||
mousedown_group.pos.y0 = mousePos[1] + mousedown_group.dy0;
|
||||
mousedown_group.pos.x1 = mousePos[0] + mousedown_group.dx1;
|
||||
mousedown_group.pos.y1 = mousePos[1] + mousedown_group.dy1;
|
||||
mousedown_group.dirty = true;
|
||||
}
|
||||
// if (mousedown_group) {
|
||||
// mousedown_group.x = mousePos[0] + mousedown_group.dx;
|
||||
// mousedown_group.y = mousePos[1] + mousedown_group.dy;
|
||||
// mousedown_group.dirty = true;
|
||||
// }
|
||||
if (snapGrid != d3.event.shiftKey && moving_set.length > 0) {
|
||||
var gridOffset = [0,0];
|
||||
node = moving_set[0];
|
||||
@ -1327,20 +1326,15 @@ if (DEBUG_EVENTS) { console.warn("canvasMouseDown", mouse_mode); }
|
||||
if (!node.n.g && activeGroups) {
|
||||
if (!groupHoverTimer) {
|
||||
groupHoverTimer = setTimeout(function() {
|
||||
activeHoverGroup = null;
|
||||
activeHoverGroup = getGroupAt(node.n.x,node.n.y);
|
||||
for (var i=0;i<activeGroups.length;i++) {
|
||||
var g = activeGroups[i];
|
||||
if ( !activeHoverGroup &&
|
||||
node.n.x >= g.pos.x0 && node.n.x <= g.pos.x1 &&
|
||||
node.n.y >= g.pos.y0 && node.n.y <= g.pos.y1
|
||||
) {
|
||||
g.dirty = !g.hovered;
|
||||
if (g === activeHoverGroup) {
|
||||
g.hovered = true;
|
||||
activeHoverGroup = g;
|
||||
} else {
|
||||
// Mark dirty if it is selected
|
||||
g.dirty = g.hovered;
|
||||
g.dirty = true;
|
||||
} else if (g.hovered) {
|
||||
g.hovered = false;
|
||||
g.dirty = true;
|
||||
}
|
||||
}
|
||||
groupHoverTimer = null;
|
||||
@ -1972,7 +1966,7 @@ if (DEBUG_EVENTS) { console.warn("clearSelection", mouse_mode); }
|
||||
RED.notify(RED._("clipboard.nodeCopied",{count:nns.length}),{id:"clipboard"});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function calculateTextWidth(str, className, offset) {
|
||||
var result=convertLineBreakCharacter(str);
|
||||
var width = 0;
|
||||
@ -2714,11 +2708,12 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function groupMouseDown(g) {
|
||||
var mouse = d3.touches(this.parentNode)[0]||d3.mouse(this.parentNode);
|
||||
if (! (mouse[0] < g.pos.x0+10 || mouse[0] > g.pos.x1-10 || mouse[1] < g.pos.y0+10 || mouse[1] > g.pos.y1-10) ) {
|
||||
return
|
||||
}
|
||||
// if (! (mouse[0] < g.x+10 || mouse[0] > g.x+g.w-10 || mouse[1] < g.y+10 || mouse[1] > g.y+g.h-10) ) {
|
||||
// return
|
||||
// }
|
||||
|
||||
focusView();
|
||||
if (d3.event.button === 1) {
|
||||
@ -2768,10 +2763,8 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
if (d3.event.button != 2) {
|
||||
var d = g.nodes[0];
|
||||
prepareDrag(mouse);
|
||||
mousedown_group.dx0 = mousedown_group.pos.x0 - mouse[0];
|
||||
mousedown_group.dy0 = mousedown_group.pos.y0 - mouse[1];
|
||||
mousedown_group.dx1 = mousedown_group.pos.x1 - mouse[0];
|
||||
mousedown_group.dy1 = mousedown_group.pos.y1 - mouse[1];
|
||||
mousedown_group.dx = mousedown_group.x - mouse[0];
|
||||
mousedown_group.dy = mousedown_group.y - mouse[1];
|
||||
}
|
||||
}
|
||||
|
||||
@ -2787,7 +2780,8 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
}
|
||||
if (includeNodes) {
|
||||
var currentSet = new Set(moving_set.map(function(n) { return n.n }));
|
||||
g.nodes.forEach(function(n) {
|
||||
var allNodes = RED.group.getNodes(g,true);
|
||||
allNodes.forEach(function(n) {
|
||||
if (!currentSet.has(n)) {
|
||||
moving_set.push({n:n})
|
||||
// n.selected = true;
|
||||
@ -2820,48 +2814,62 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
}
|
||||
}
|
||||
function getGroupAt(x,y) {
|
||||
var candidateGroups = {};
|
||||
for (var i=0;i<activeGroups.length;i++) {
|
||||
var g = activeGroups[i];
|
||||
if (x >= g.pos.x0 && x <= g.pos.x1 && y >= g.pos.y0 && y <= g.pos.y1) {
|
||||
return g;
|
||||
if (x >= g.x && x <= g.x + g.w && y >= g.y && y <= g.y + g.h) {
|
||||
candidateGroups[g.id] = g;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
var ids = Object.keys(candidateGroups);
|
||||
if (ids.length > 1) {
|
||||
ids.forEach(function(id) {
|
||||
if (candidateGroups[id] && candidateGroups[id].g) {
|
||||
delete candidateGroups[candidateGroups[id].g]
|
||||
}
|
||||
})
|
||||
ids = Object.keys(candidateGroups);
|
||||
}
|
||||
if (ids.length === 0) {
|
||||
return null;
|
||||
} else {
|
||||
return candidateGroups[ids[0]]
|
||||
}
|
||||
}
|
||||
|
||||
function groupHandleMouseDown(group, groupEl, handle,handleIndex) {
|
||||
d3.event.stopPropagation();
|
||||
console.log("GHANDLE MD");
|
||||
if (d3.event.button != 2) {
|
||||
mousedown_group = group;
|
||||
group.activeHandle = handleIndex;
|
||||
var mouse = d3.touches(handle.parentNode.parentNode)[0]||d3.mouse(handle.parentNode.parentNode);
|
||||
switch(handleIndex) {
|
||||
case 0: group.ox = group.pos.x0; group.oy = group.pos.y0; break;
|
||||
case 1: group.ox = group.pos.x1; group.oy = group.pos.y0; break;
|
||||
case 2: group.ox = group.pos.x1; group.oy = group.pos.y1; break;
|
||||
case 3: group.ox = group.pos.x0; group.oy = group.pos.y1; break;
|
||||
}
|
||||
group.dx = group.ox - mouse[0];
|
||||
group.dy = group.oy - mouse[1];
|
||||
console.log("START",group.ox, group.oy);
|
||||
mouse_offset = d3.mouse(document.body);
|
||||
if (isNaN(mouse_offset[0])) {
|
||||
mouse_offset = d3.touches(document.body)[0];
|
||||
}
|
||||
mouse_mode = RED.state.GROUP_RESIZE;
|
||||
}
|
||||
}
|
||||
function groupHandleMouseUp(group,groupEl,handle,handleIndex) {
|
||||
console.log("GHANDLE MU");
|
||||
d3.event.stopPropagation();
|
||||
delete group.ox;
|
||||
delete group.oy;
|
||||
delete group.dx;
|
||||
delete group.dy;
|
||||
resetMouseVars();
|
||||
mouse_mode = RED.state.DEFAULT;
|
||||
}
|
||||
// function groupHandleMouseDown(group, groupEl, handle,handleIndex) {
|
||||
// d3.event.stopPropagation();
|
||||
// console.log("GHANDLE MD");
|
||||
// if (d3.event.button != 2) {
|
||||
// mousedown_group = group;
|
||||
// group.activeHandle = handleIndex;
|
||||
// var mouse = d3.touches(handle.parentNode.parentNode)[0]||d3.mouse(handle.parentNode.parentNode);
|
||||
// switch(handleIndex) {
|
||||
// case 0: group.ox = group.pos.x0; group.oy = group.pos.y0; break;
|
||||
// case 1: group.ox = group.pos.x1; group.oy = group.pos.y0; break;
|
||||
// case 2: group.ox = group.pos.x1; group.oy = group.pos.y1; break;
|
||||
// case 3: group.ox = group.pos.x0; group.oy = group.pos.y1; break;
|
||||
// }
|
||||
// group.dx = group.ox - mouse[0];
|
||||
// group.dy = group.oy - mouse[1];
|
||||
// console.log("START",group.ox, group.oy);
|
||||
// mouse_offset = d3.mouse(document.body);
|
||||
// if (isNaN(mouse_offset[0])) {
|
||||
// mouse_offset = d3.touches(document.body)[0];
|
||||
// }
|
||||
// mouse_mode = RED.state.GROUP_RESIZE;
|
||||
// }
|
||||
// }
|
||||
// function groupHandleMouseUp(group,groupEl,handle,handleIndex) {
|
||||
// console.log("GHANDLE MU");
|
||||
// d3.event.stopPropagation();
|
||||
// delete group.ox;
|
||||
// delete group.oy;
|
||||
// delete group.dx;
|
||||
// delete group.dy;
|
||||
// resetMouseVars();
|
||||
// mouse_mode = RED.state.DEFAULT;
|
||||
// }
|
||||
|
||||
function isButtonEnabled(d) {
|
||||
var buttonEnabled = true;
|
||||
@ -3712,18 +3720,19 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
}
|
||||
|
||||
d.dirty = false;
|
||||
|
||||
if (d.g) {
|
||||
if (!dirtyGroups[d.g]) {
|
||||
dirtyGroups[d.g] = RED.nodes.group(d.g);
|
||||
}
|
||||
var group = dirtyGroups[d.g];
|
||||
group.pos = {
|
||||
x0: Math.min(group.pos.x0,d.x-d.w/2-25-((d._def.button && d._def.align!=="right")?20:0)),
|
||||
y0: Math.min(group.pos.y0,d.y-d.h/2-25),
|
||||
x1: Math.max(group.pos.x1,d.x+d.w/2+25+((d._def.button && d._def.align=="right")?20:0)),
|
||||
y1: Math.max(group.pos.y1,d.y+d.h/2+25)
|
||||
var gg = d.g;
|
||||
while (gg && !dirtyGroups[gg]) {
|
||||
dirtyGroups[gg] = RED.nodes.group(gg);
|
||||
gg = dirtyGroups[gg].g;
|
||||
}
|
||||
}
|
||||
// var group = dirtyGroups[d.g];
|
||||
// group.x = Math.min(group.x,d.x-d.w/2-25-((d._def.button && d._def.align!=="right")?20:0));
|
||||
// group.y = Math.min(group.y,d.y-d.h/2-25),
|
||||
// group.w = Math.max(group.w, d.x+d.w/2+25+((d._def.button && d._def.align=="right")?20:0) - group.x),
|
||||
// group.h = Math.max(group.h, d.y+d.h/2+25 - group.y)
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -3981,20 +3990,21 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
.attr('rx',1).attr('ry',1).style({
|
||||
"fill":"none",
|
||||
"stroke": "#ff7f0e",
|
||||
"pointer-events": "stroke",
|
||||
"stroke-opacity": 0,
|
||||
"stroke-width": 15
|
||||
})
|
||||
|
||||
g.append('rect').classed("red-ui-flow-group-body",true)
|
||||
.attr('rx',1).attr('ry',1).style({
|
||||
"pointer-events": "none",
|
||||
"fill":d.fill||"none",
|
||||
"stroke": d.stroke||"none",
|
||||
"stroke-width": 2
|
||||
})
|
||||
|
||||
|
||||
d.dirty = true;
|
||||
g.on("mousedown",groupMouseDown).on("mouseup",groupMouseUp)
|
||||
|
||||
d.dirty = true;
|
||||
});
|
||||
group.each(function(d,i) {
|
||||
if (d.dirty || dirtyGroups[d.id]) {
|
||||
@ -4004,26 +4014,33 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
var maxX = 0;
|
||||
var maxY = 0;
|
||||
d.nodes.forEach(function(n) {
|
||||
minX = Math.min(minX,n.x-n.w/2-25-((n._def.button && n._def.align!=="right")?20:0));
|
||||
minY = Math.min(minY,n.y-n.h/2-25);
|
||||
maxX = Math.max(maxX,n.x+n.w/2+25+((n._def.button && n._def.align=="right")?20:0));
|
||||
maxY = Math.max(maxY,n.y+n.h/2+25);
|
||||
if (n.type !== "group") {
|
||||
minX = Math.min(minX,n.x-n.w/2-25-((n._def.button && n._def.align!=="right")?20:0));
|
||||
minY = Math.min(minY,n.y-n.h/2-25);
|
||||
maxX = Math.max(maxX,n.x+n.w/2+25+((n._def.button && n._def.align=="right")?20:0));
|
||||
maxY = Math.max(maxY,n.y+n.h/2+25);
|
||||
} else {
|
||||
minX = Math.min(minX,n.x-25)
|
||||
minY = Math.min(minY,n.y-25)
|
||||
maxX = Math.max(maxX,n.x+n.w+25)
|
||||
maxY = Math.max(maxY,n.y+n.h+25)
|
||||
}
|
||||
});
|
||||
|
||||
d.pos = {
|
||||
x0: minX, y0: minY,
|
||||
x1: maxX, y1: maxY
|
||||
}
|
||||
d.x = minX;
|
||||
d.y = minY;
|
||||
d.w = maxX - minX;
|
||||
d.h = maxY - minY;
|
||||
|
||||
g.attr("transform","translate("+d.pos.x0+","+d.pos.y0+")");
|
||||
g.attr("transform","translate("+d.x+","+d.y+")");
|
||||
g.selectAll(".red-ui-flow-group-outline")
|
||||
.attr("width",d.pos.x1-d.pos.x0)
|
||||
.attr("height",d.pos.y1-d.pos.y0)
|
||||
.attr("width",d.w)
|
||||
.attr("height",d.h)
|
||||
.style("stroke-opacity",function(d) { if (d.selected) { return 0.3 } return 0});
|
||||
|
||||
g.selectAll(".red-ui-flow-group-body")
|
||||
.attr("width",d.pos.x1-d.pos.x0)
|
||||
.attr("height",d.pos.y1-d.pos.y0)
|
||||
.attr("width",d.w)
|
||||
.attr("height",d.h)
|
||||
.style("stroke",function(d) { /*if (d.selected) { return "#ff7f0e" } */return d.style.stroke || "none"})
|
||||
.style("stroke-dasharray", function(d) { return (d.active||d.hovered)?"10 4":"none"})
|
||||
.style("fill", function(d) { return d.style.fill || "none"})
|
||||
@ -4338,16 +4355,34 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
||||
},
|
||||
selection: function() {
|
||||
var selection = {};
|
||||
|
||||
var allNodes = new Set();
|
||||
|
||||
if (moving_set.length > 0) {
|
||||
selection.nodes = moving_set.map(function(n) { return n.n;});
|
||||
moving_set.forEach(function(n) {
|
||||
allNodes.add(n.n);
|
||||
});
|
||||
}
|
||||
var selectedGroups = activeGroups.filter(function(g) { return g.selected });
|
||||
if (selectedGroups.length > 0) {
|
||||
if (selectedGroups.length === 1 && selectedGroups[0].active) {
|
||||
// Let nodes be nodes
|
||||
} else {
|
||||
selectedGroups.forEach(function(g) {
|
||||
var groupNodes = RED.group.getNodes(g,true);
|
||||
groupNodes.forEach(function(n) {
|
||||
allNodes.delete(n);
|
||||
});
|
||||
allNodes.add(g);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (allNodes.size > 0) {
|
||||
selection.nodes = Array.from(allNodes);
|
||||
}
|
||||
if (selected_link != null) {
|
||||
selection.link = selected_link;
|
||||
}
|
||||
selection.groups = activeGroups.filter(function(g) { return g.selected })
|
||||
if (selection.groups.length === 0) {
|
||||
delete selection.groups;
|
||||
}
|
||||
return selection;
|
||||
},
|
||||
scale: function() {
|
||||
|
Loading…
Reference in New Issue
Block a user