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;
|
var mousePos;
|
||||||
if (mouse_mode === RED.state.GROUP_RESIZE) {
|
// if (mouse_mode === RED.state.GROUP_RESIZE) {
|
||||||
mousePos = mouse_position;
|
// mousePos = mouse_position;
|
||||||
var nx = mousePos[0] + mousedown_group.dx;
|
// var nx = mousePos[0] + mousedown_group.dx;
|
||||||
var ny = mousePos[1] + mousedown_group.dy;
|
// var ny = mousePos[1] + mousedown_group.dy;
|
||||||
switch(mousedown_group.activeHandle) {
|
// switch(mousedown_group.activeHandle) {
|
||||||
case 0: mousedown_group.pos.x0 = nx; mousedown_group.pos.y0 = ny; break;
|
// 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 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 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;
|
// case 3: mousedown_group.pos.x0 = nx; mousedown_group.pos.y1 = ny; break;
|
||||||
}
|
// }
|
||||||
mousedown_group.dirty = true;
|
// mousedown_group.dirty = true;
|
||||||
} else if (mouse_mode == RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) {
|
// }
|
||||||
|
if (mouse_mode == RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) {
|
||||||
// update drag line
|
// update drag line
|
||||||
if (drag_lines.length === 0 && mousedown_port_type !== null) {
|
if (drag_lines.length === 0 && mousedown_port_type !== null) {
|
||||||
if (d3.event.shiftKey) {
|
if (d3.event.shiftKey) {
|
||||||
@ -1253,13 +1254,11 @@ if (DEBUG_EVENTS) { console.warn("canvasMouseDown", mouse_mode); }
|
|||||||
node.n.y -= (maxY - space_height);
|
node.n.y -= (maxY - space_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mousedown_group) {
|
// if (mousedown_group) {
|
||||||
mousedown_group.pos.x0 = mousePos[0] + mousedown_group.dx0;
|
// mousedown_group.x = mousePos[0] + mousedown_group.dx;
|
||||||
mousedown_group.pos.y0 = mousePos[1] + mousedown_group.dy0;
|
// mousedown_group.y = mousePos[1] + mousedown_group.dy;
|
||||||
mousedown_group.pos.x1 = mousePos[0] + mousedown_group.dx1;
|
// mousedown_group.dirty = true;
|
||||||
mousedown_group.pos.y1 = mousePos[1] + mousedown_group.dy1;
|
// }
|
||||||
mousedown_group.dirty = true;
|
|
||||||
}
|
|
||||||
if (snapGrid != d3.event.shiftKey && moving_set.length > 0) {
|
if (snapGrid != d3.event.shiftKey && moving_set.length > 0) {
|
||||||
var gridOffset = [0,0];
|
var gridOffset = [0,0];
|
||||||
node = moving_set[0];
|
node = moving_set[0];
|
||||||
@ -1327,20 +1326,15 @@ if (DEBUG_EVENTS) { console.warn("canvasMouseDown", mouse_mode); }
|
|||||||
if (!node.n.g && activeGroups) {
|
if (!node.n.g && activeGroups) {
|
||||||
if (!groupHoverTimer) {
|
if (!groupHoverTimer) {
|
||||||
groupHoverTimer = setTimeout(function() {
|
groupHoverTimer = setTimeout(function() {
|
||||||
activeHoverGroup = null;
|
activeHoverGroup = getGroupAt(node.n.x,node.n.y);
|
||||||
for (var i=0;i<activeGroups.length;i++) {
|
for (var i=0;i<activeGroups.length;i++) {
|
||||||
var g = activeGroups[i];
|
var g = activeGroups[i];
|
||||||
if ( !activeHoverGroup &&
|
if (g === 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;
|
|
||||||
g.hovered = true;
|
g.hovered = true;
|
||||||
activeHoverGroup = g;
|
g.dirty = true;
|
||||||
} else {
|
} else if (g.hovered) {
|
||||||
// Mark dirty if it is selected
|
|
||||||
g.dirty = g.hovered;
|
|
||||||
g.hovered = false;
|
g.hovered = false;
|
||||||
|
g.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
groupHoverTimer = null;
|
groupHoverTimer = null;
|
||||||
@ -1972,7 +1966,7 @@ if (DEBUG_EVENTS) { console.warn("clearSelection", mouse_mode); }
|
|||||||
RED.notify(RED._("clipboard.nodeCopied",{count:nns.length}),{id:"clipboard"});
|
RED.notify(RED._("clipboard.nodeCopied",{count:nns.length}),{id:"clipboard"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateTextWidth(str, className, offset) {
|
function calculateTextWidth(str, className, offset) {
|
||||||
var result=convertLineBreakCharacter(str);
|
var result=convertLineBreakCharacter(str);
|
||||||
var width = 0;
|
var width = 0;
|
||||||
@ -2714,11 +2708,12 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function groupMouseDown(g) {
|
function groupMouseDown(g) {
|
||||||
var mouse = d3.touches(this.parentNode)[0]||d3.mouse(this.parentNode);
|
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) ) {
|
// 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
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
focusView();
|
focusView();
|
||||||
if (d3.event.button === 1) {
|
if (d3.event.button === 1) {
|
||||||
@ -2768,10 +2763,8 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|||||||
if (d3.event.button != 2) {
|
if (d3.event.button != 2) {
|
||||||
var d = g.nodes[0];
|
var d = g.nodes[0];
|
||||||
prepareDrag(mouse);
|
prepareDrag(mouse);
|
||||||
mousedown_group.dx0 = mousedown_group.pos.x0 - mouse[0];
|
mousedown_group.dx = mousedown_group.x - mouse[0];
|
||||||
mousedown_group.dy0 = mousedown_group.pos.y0 - mouse[1];
|
mousedown_group.dy = mousedown_group.y - mouse[1];
|
||||||
mousedown_group.dx1 = mousedown_group.pos.x1 - mouse[0];
|
|
||||||
mousedown_group.dy1 = mousedown_group.pos.y1 - mouse[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2787,7 +2780,8 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|||||||
}
|
}
|
||||||
if (includeNodes) {
|
if (includeNodes) {
|
||||||
var currentSet = new Set(moving_set.map(function(n) { return n.n }));
|
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)) {
|
if (!currentSet.has(n)) {
|
||||||
moving_set.push({n:n})
|
moving_set.push({n:n})
|
||||||
// n.selected = true;
|
// n.selected = true;
|
||||||
@ -2820,48 +2814,62 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getGroupAt(x,y) {
|
function getGroupAt(x,y) {
|
||||||
|
var candidateGroups = {};
|
||||||
for (var i=0;i<activeGroups.length;i++) {
|
for (var i=0;i<activeGroups.length;i++) {
|
||||||
var g = activeGroups[i];
|
var g = activeGroups[i];
|
||||||
if (x >= g.pos.x0 && x <= g.pos.x1 && y >= g.pos.y0 && y <= g.pos.y1) {
|
if (x >= g.x && x <= g.x + g.w && y >= g.y && y <= g.y + g.h) {
|
||||||
return g;
|
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) {
|
// function groupHandleMouseDown(group, groupEl, handle,handleIndex) {
|
||||||
d3.event.stopPropagation();
|
// d3.event.stopPropagation();
|
||||||
console.log("GHANDLE MD");
|
// console.log("GHANDLE MD");
|
||||||
if (d3.event.button != 2) {
|
// if (d3.event.button != 2) {
|
||||||
mousedown_group = group;
|
// mousedown_group = group;
|
||||||
group.activeHandle = handleIndex;
|
// group.activeHandle = handleIndex;
|
||||||
var mouse = d3.touches(handle.parentNode.parentNode)[0]||d3.mouse(handle.parentNode.parentNode);
|
// var mouse = d3.touches(handle.parentNode.parentNode)[0]||d3.mouse(handle.parentNode.parentNode);
|
||||||
switch(handleIndex) {
|
// switch(handleIndex) {
|
||||||
case 0: group.ox = group.pos.x0; group.oy = group.pos.y0; break;
|
// 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 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 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;
|
// case 3: group.ox = group.pos.x0; group.oy = group.pos.y1; break;
|
||||||
}
|
// }
|
||||||
group.dx = group.ox - mouse[0];
|
// group.dx = group.ox - mouse[0];
|
||||||
group.dy = group.oy - mouse[1];
|
// group.dy = group.oy - mouse[1];
|
||||||
console.log("START",group.ox, group.oy);
|
// console.log("START",group.ox, group.oy);
|
||||||
mouse_offset = d3.mouse(document.body);
|
// mouse_offset = d3.mouse(document.body);
|
||||||
if (isNaN(mouse_offset[0])) {
|
// if (isNaN(mouse_offset[0])) {
|
||||||
mouse_offset = d3.touches(document.body)[0];
|
// mouse_offset = d3.touches(document.body)[0];
|
||||||
}
|
// }
|
||||||
mouse_mode = RED.state.GROUP_RESIZE;
|
// mouse_mode = RED.state.GROUP_RESIZE;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
function groupHandleMouseUp(group,groupEl,handle,handleIndex) {
|
// function groupHandleMouseUp(group,groupEl,handle,handleIndex) {
|
||||||
console.log("GHANDLE MU");
|
// console.log("GHANDLE MU");
|
||||||
d3.event.stopPropagation();
|
// d3.event.stopPropagation();
|
||||||
delete group.ox;
|
// delete group.ox;
|
||||||
delete group.oy;
|
// delete group.oy;
|
||||||
delete group.dx;
|
// delete group.dx;
|
||||||
delete group.dy;
|
// delete group.dy;
|
||||||
resetMouseVars();
|
// resetMouseVars();
|
||||||
mouse_mode = RED.state.DEFAULT;
|
// mouse_mode = RED.state.DEFAULT;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function isButtonEnabled(d) {
|
function isButtonEnabled(d) {
|
||||||
var buttonEnabled = true;
|
var buttonEnabled = true;
|
||||||
@ -3712,18 +3720,19 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|||||||
}
|
}
|
||||||
|
|
||||||
d.dirty = false;
|
d.dirty = false;
|
||||||
|
|
||||||
if (d.g) {
|
if (d.g) {
|
||||||
if (!dirtyGroups[d.g]) {
|
if (!dirtyGroups[d.g]) {
|
||||||
dirtyGroups[d.g] = RED.nodes.group(d.g);
|
var gg = d.g;
|
||||||
}
|
while (gg && !dirtyGroups[gg]) {
|
||||||
var group = dirtyGroups[d.g];
|
dirtyGroups[gg] = RED.nodes.group(gg);
|
||||||
group.pos = {
|
gg = dirtyGroups[gg].g;
|
||||||
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 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({
|
.attr('rx',1).attr('ry',1).style({
|
||||||
"fill":"none",
|
"fill":"none",
|
||||||
"stroke": "#ff7f0e",
|
"stroke": "#ff7f0e",
|
||||||
|
"pointer-events": "stroke",
|
||||||
"stroke-opacity": 0,
|
"stroke-opacity": 0,
|
||||||
"stroke-width": 15
|
"stroke-width": 15
|
||||||
})
|
})
|
||||||
|
|
||||||
g.append('rect').classed("red-ui-flow-group-body",true)
|
g.append('rect').classed("red-ui-flow-group-body",true)
|
||||||
.attr('rx',1).attr('ry',1).style({
|
.attr('rx',1).attr('ry',1).style({
|
||||||
|
"pointer-events": "none",
|
||||||
"fill":d.fill||"none",
|
"fill":d.fill||"none",
|
||||||
"stroke": d.stroke||"none",
|
"stroke": d.stroke||"none",
|
||||||
"stroke-width": 2
|
"stroke-width": 2
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
d.dirty = true;
|
|
||||||
g.on("mousedown",groupMouseDown).on("mouseup",groupMouseUp)
|
g.on("mousedown",groupMouseDown).on("mouseup",groupMouseUp)
|
||||||
|
|
||||||
|
d.dirty = true;
|
||||||
});
|
});
|
||||||
group.each(function(d,i) {
|
group.each(function(d,i) {
|
||||||
if (d.dirty || dirtyGroups[d.id]) {
|
if (d.dirty || dirtyGroups[d.id]) {
|
||||||
@ -4004,26 +4014,33 @@ if (DEBUG_EVENTS) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|||||||
var maxX = 0;
|
var maxX = 0;
|
||||||
var maxY = 0;
|
var maxY = 0;
|
||||||
d.nodes.forEach(function(n) {
|
d.nodes.forEach(function(n) {
|
||||||
minX = Math.min(minX,n.x-n.w/2-25-((n._def.button && n._def.align!=="right")?20:0));
|
if (n.type !== "group") {
|
||||||
minY = Math.min(minY,n.y-n.h/2-25);
|
minX = Math.min(minX,n.x-n.w/2-25-((n._def.button && n._def.align!=="right")?20:0));
|
||||||
maxX = Math.max(maxX,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);
|
||||||
maxY = Math.max(maxY,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 = {
|
d.x = minX;
|
||||||
x0: minX, y0: minY,
|
d.y = minY;
|
||||||
x1: maxX, y1: maxY
|
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")
|
g.selectAll(".red-ui-flow-group-outline")
|
||||||
.attr("width",d.pos.x1-d.pos.x0)
|
.attr("width",d.w)
|
||||||
.attr("height",d.pos.y1-d.pos.y0)
|
.attr("height",d.h)
|
||||||
.style("stroke-opacity",function(d) { if (d.selected) { return 0.3 } return 0});
|
.style("stroke-opacity",function(d) { if (d.selected) { return 0.3 } return 0});
|
||||||
|
|
||||||
g.selectAll(".red-ui-flow-group-body")
|
g.selectAll(".red-ui-flow-group-body")
|
||||||
.attr("width",d.pos.x1-d.pos.x0)
|
.attr("width",d.w)
|
||||||
.attr("height",d.pos.y1-d.pos.y0)
|
.attr("height",d.h)
|
||||||
.style("stroke",function(d) { /*if (d.selected) { return "#ff7f0e" } */return d.style.stroke || "none"})
|
.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("stroke-dasharray", function(d) { return (d.active||d.hovered)?"10 4":"none"})
|
||||||
.style("fill", function(d) { return d.style.fill || "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() {
|
selection: function() {
|
||||||
var selection = {};
|
var selection = {};
|
||||||
|
|
||||||
|
var allNodes = new Set();
|
||||||
|
|
||||||
if (moving_set.length > 0) {
|
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) {
|
if (selected_link != null) {
|
||||||
selection.link = selected_link;
|
selection.link = selected_link;
|
||||||
}
|
}
|
||||||
selection.groups = activeGroups.filter(function(g) { return g.selected })
|
|
||||||
if (selection.groups.length === 0) {
|
|
||||||
delete selection.groups;
|
|
||||||
}
|
|
||||||
return selection;
|
return selection;
|
||||||
},
|
},
|
||||||
scale: function() {
|
scale: function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user