mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Support drag-wiring of link nodes
This commit is contained in:
parent
84cc2ad0fa
commit
33dade0584
@ -296,6 +296,7 @@ RED.history = (function() {
|
||||
});
|
||||
|
||||
RED.nodes.dirty(ev.dirty);
|
||||
RED.view.select(null);
|
||||
RED.view.redraw(true);
|
||||
RED.palette.refresh();
|
||||
RED.workspaces.refresh();
|
||||
|
@ -42,6 +42,7 @@ RED.view = (function() {
|
||||
var activeNodes = [];
|
||||
var activeLinks = [];
|
||||
var activeFlowLinks = [];
|
||||
var activeLinkNodes = {};
|
||||
|
||||
var selected_link = null,
|
||||
mousedown_link = null,
|
||||
@ -61,7 +62,8 @@ RED.view = (function() {
|
||||
clickElapsed = 0,
|
||||
scroll_position = [],
|
||||
quickAddActive = false,
|
||||
quickAddLink = null;
|
||||
quickAddLink = null,
|
||||
showAllLinkPorts = -1;
|
||||
|
||||
var clipboard = "";
|
||||
|
||||
@ -263,19 +265,41 @@ RED.view = (function() {
|
||||
"stroke-width" : "1px"
|
||||
});
|
||||
}
|
||||
|
||||
var linkLayer = vis.append("g");
|
||||
var dragGroup = vis.append("g");
|
||||
var nodeLayer = vis.append("g");
|
||||
var drag_lines = [];
|
||||
|
||||
function showDragLines(nodes) {
|
||||
showAllLinkPorts = -1;
|
||||
for (var i=0;i<nodes.length;i++) {
|
||||
var node = nodes[i];
|
||||
node.el = dragGroup.append("svg:path").attr("class", "drag_line");
|
||||
if ((node.node.type === "link out" && node.portType === PORT_TYPE_OUTPUT) ||
|
||||
(node.node.type === "link in" && node.portType === PORT_TYPE_INPUT)) {
|
||||
node.el.attr("class","link_link drag_line");
|
||||
node.virtualLink = true;
|
||||
showAllLinkPorts = (node.portType === PORT_TYPE_OUTPUT)?PORT_TYPE_INPUT:PORT_TYPE_OUTPUT;
|
||||
}
|
||||
drag_lines.push(node);
|
||||
}
|
||||
|
||||
if (showAllLinkPorts !== -1) {
|
||||
activeNodes.forEach(function(n) {
|
||||
if (n.type === "link in" || n.type === "link out") {
|
||||
n.dirty = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
function hideDragLines() {
|
||||
if (showAllLinkPorts !== -1) {
|
||||
activeNodes.forEach(function(n) {
|
||||
if (n.type === "link in" || n.type === "link out") {
|
||||
n.dirty = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
showAllLinkPorts = -1;
|
||||
while(drag_lines.length) {
|
||||
var line = drag_lines.pop();
|
||||
if (line.el) {
|
||||
@ -657,10 +681,21 @@ RED.view = (function() {
|
||||
mouse_mode = RED.state.QUICK_JOINING;
|
||||
$(window).on('keyup',disableQuickJoinEventHandler);
|
||||
}
|
||||
var filter = undefined;
|
||||
if (drag_lines.length > 0) {
|
||||
if (drag_lines[0].virtualLink) {
|
||||
filter = {type:drag_lines[0].node.type === 'link in'?'link out':'link in'}
|
||||
} else if (drag_lines[0].portType === PORT_TYPE_OUTPUT) {
|
||||
filter = {input:true}
|
||||
} else {
|
||||
filter = {output:true}
|
||||
}
|
||||
}
|
||||
quickAddActive = true;
|
||||
RED.typeSearch.show({
|
||||
x:d3.event.clientX-mainPos.left-node_width/2,
|
||||
y:d3.event.clientY-mainPos.top-node_height/2,
|
||||
filter: filter,
|
||||
cancel: function() {
|
||||
quickAddActive = false;
|
||||
resetMouseVars();
|
||||
@ -685,19 +720,54 @@ RED.view = (function() {
|
||||
if (quickAddLink || drag_lines.length > 0) {
|
||||
var drag_line = quickAddLink||drag_lines[0];
|
||||
var src = null,dst,src_port;
|
||||
if (drag_line.portType === PORT_TYPE_OUTPUT && nn.inputs > 0) {
|
||||
if (drag_line.portType === PORT_TYPE_OUTPUT && (nn.inputs > 0 || drag_line.virtualLink) ) {
|
||||
src = drag_line.node;
|
||||
src_port = drag_line.port;
|
||||
dst = nn;
|
||||
} else if (drag_line.portType === PORT_TYPE_INPUT && nn.outputs > 0) {
|
||||
} else if (drag_line.portType === PORT_TYPE_INPUT && (nn.outputs > 0 || drag_line.virtualLink)) {
|
||||
src = nn;
|
||||
dst = drag_line.node;
|
||||
src_port = 0;
|
||||
}
|
||||
|
||||
if (src !== null) {
|
||||
if (drag_line.virtualLink) {
|
||||
historyEvent = {
|
||||
t:'multi',
|
||||
events: [historyEvent]
|
||||
}
|
||||
var oldSrcLinks = $.extend(true,{},{v:src.links}).v
|
||||
var oldDstLinks = $.extend(true,{},{v:dst.links}).v
|
||||
src.links.push(dst.id);
|
||||
dst.links.push(src.id);
|
||||
src.dirty = true;
|
||||
dst.dirty = true;
|
||||
|
||||
historyEvent.events.push({
|
||||
t:'edit',
|
||||
node: src,
|
||||
dirty: RED.nodes.dirty(),
|
||||
changed: src.changed,
|
||||
changes: {
|
||||
links:oldSrcLinks
|
||||
}
|
||||
});
|
||||
historyEvent.events.push({
|
||||
t:'edit',
|
||||
node: dst,
|
||||
dirty: RED.nodes.dirty(),
|
||||
changed: dst.changed,
|
||||
changes: {
|
||||
links:oldDstLinks
|
||||
}
|
||||
});
|
||||
src.changed = true;
|
||||
dst.changed = true;
|
||||
} else {
|
||||
var link = {source: src, sourcePort:src_port, target: dst};
|
||||
RED.nodes.addLink(link);
|
||||
historyEvent.links = [link];
|
||||
}
|
||||
hideDragLines();
|
||||
if (!quickAddLink && drag_line.portType === PORT_TYPE_OUTPUT && nn.outputs > 0) {
|
||||
showDragLines([{node:nn,port:0,portType:PORT_TYPE_OUTPUT}]);
|
||||
@ -1216,9 +1286,15 @@ RED.view = (function() {
|
||||
var currentLinks = activeLinks;
|
||||
var addedLinkLinks = {};
|
||||
activeFlowLinks = [];
|
||||
var activeLinkNodeIds = Object.keys(activeLinkNodes);
|
||||
activeLinkNodeIds.forEach(function(n) {
|
||||
activeLinkNodes[n].dirty = true;
|
||||
})
|
||||
activeLinkNodes = {};
|
||||
for (var i=0;i<moving_set.length;i++) {
|
||||
if (moving_set[i].n.type === "link out" || moving_set[i].n.type === "link in") {
|
||||
var linkNode = moving_set[i].n;
|
||||
activeLinkNodes[linkNode.id] = linkNode;
|
||||
var offFlowLinks = {};
|
||||
linkNode.links.forEach(function(id) {
|
||||
var target = RED.nodes.node(id);
|
||||
@ -1233,6 +1309,9 @@ RED.view = (function() {
|
||||
link: true
|
||||
});
|
||||
addedLinkLinks[linkNode.id+":"+target.id] = true;
|
||||
activeLinkNodes[target.id] = target;
|
||||
target.dirty = true;
|
||||
|
||||
}
|
||||
} else {
|
||||
offFlowLinks[target.z] = offFlowLinks[target.z]||[];
|
||||
@ -1248,6 +1327,8 @@ RED.view = (function() {
|
||||
link: true
|
||||
});
|
||||
addedLinkLinks[target.id+":"+linkNode.id] = true;
|
||||
activeLinkNodes[target.id] = target;
|
||||
target.dirty = true;
|
||||
}
|
||||
} else {
|
||||
offFlowLinks[target.z] = offFlowLinks[target.z]||[];
|
||||
@ -1269,6 +1350,13 @@ RED.view = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (activeFlowLinks.length === 0 && selected_link !== null && selected_link.link) {
|
||||
activeLinks.push(selected_link);
|
||||
activeLinkNodes[selected_link.source.id] = selected_link.source;
|
||||
selected_link.source.dirty = true;
|
||||
activeLinkNodes[selected_link.target.id] = selected_link.target;
|
||||
selected_link.target.dirty = true;
|
||||
}
|
||||
} else {
|
||||
selection.flows = workspaceSelection;
|
||||
}
|
||||
@ -1445,12 +1533,52 @@ RED.view = (function() {
|
||||
RED.nodes.dirty(true);
|
||||
}
|
||||
}
|
||||
var historyEvent;
|
||||
|
||||
if (selected_link && selected_link.link) {
|
||||
var sourceId = selected_link.source.id;
|
||||
var targetId = selected_link.target.id;
|
||||
var sourceIdIndex = selected_link.target.links.indexOf(sourceId);
|
||||
var targetIdIndex = selected_link.source.links.indexOf(targetId);
|
||||
|
||||
historyEvent = {
|
||||
t:"multi",
|
||||
events: [
|
||||
{
|
||||
t: "edit",
|
||||
node: selected_link.source,
|
||||
changed: selected_link.source.changed,
|
||||
changes: {
|
||||
links: $.extend(true,{},{v:selected_link.source.links}).v
|
||||
}
|
||||
},
|
||||
{
|
||||
t: "edit",
|
||||
node: selected_link.target,
|
||||
changed: selected_link.target.changed,
|
||||
changes: {
|
||||
links: $.extend(true,{},{v:selected_link.target.links}).v
|
||||
}
|
||||
}
|
||||
|
||||
],
|
||||
dirty:RED.nodes.dirty()
|
||||
}
|
||||
|
||||
selected_link.source.changed = true;
|
||||
selected_link.target.changed = true;
|
||||
selected_link.target.links.splice(sourceIdIndex,1);
|
||||
selected_link.source.links.splice(targetIdIndex,1);
|
||||
selected_link.source.dirty = true;
|
||||
selected_link.target.dirty = true;
|
||||
|
||||
} else {
|
||||
if (selected_link) {
|
||||
RED.nodes.removeLink(selected_link);
|
||||
removedLinks.push(selected_link);
|
||||
RED.nodes.dirty(true);
|
||||
}
|
||||
var historyEvent = {
|
||||
RED.nodes.dirty(true);
|
||||
historyEvent = {
|
||||
t:"delete",
|
||||
nodes:removedNodes,
|
||||
links:removedLinks,
|
||||
@ -1461,6 +1589,7 @@ RED.view = (function() {
|
||||
},
|
||||
dirty:startDirty
|
||||
};
|
||||
}
|
||||
RED.history.push(historyEvent);
|
||||
|
||||
selected_link = null;
|
||||
@ -1574,6 +1703,7 @@ RED.view = (function() {
|
||||
if (d3.event.ctrlKey || d3.event.metaKey) {
|
||||
mouse_mode = RED.state.QUICK_JOINING;
|
||||
showDragLines([{node:mousedown_node,port:mousedown_port_index,portType:mousedown_port_type}]);
|
||||
quickAddLink = null;
|
||||
$(window).on('keyup',disableQuickJoinEventHandler);
|
||||
}
|
||||
}
|
||||
@ -1585,6 +1715,15 @@ RED.view = (function() {
|
||||
var i;
|
||||
if (mouse_mode === RED.state.QUICK_JOINING && drag_lines.length > 0) {
|
||||
if (drag_lines[0].node === d) {
|
||||
// Cannot quick-join to self
|
||||
return
|
||||
}
|
||||
if (drag_lines[0].virtualLink &&
|
||||
(
|
||||
(drag_lines[0].node.type === 'link in' && d.type !== 'link out') ||
|
||||
(drag_lines[0].node.type === 'link out' && d.type !== 'link in')
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -1608,12 +1747,17 @@ RED.view = (function() {
|
||||
}
|
||||
var addedLinks = [];
|
||||
var removedLinks = [];
|
||||
var modifiedNodes = []; // joining link nodes
|
||||
|
||||
var select_link = null;
|
||||
|
||||
for (i=0;i<drag_lines.length;i++) {
|
||||
if (drag_lines[i].link) {
|
||||
removedLinks.push(drag_lines[i].link)
|
||||
}
|
||||
}
|
||||
var linkEditEvents = [];
|
||||
|
||||
for (i=0;i<drag_lines.length;i++) {
|
||||
if (portType != drag_lines[i].portType && mouseup_node !== drag_lines[i].node) {
|
||||
var drag_line = drag_lines[i];
|
||||
@ -1627,21 +1771,75 @@ RED.view = (function() {
|
||||
dst = drag_line.node;
|
||||
src_port = portIndex;
|
||||
}
|
||||
var link = {source: src, sourcePort:src_port, target: dst};
|
||||
if (drag_line.virtualLink) {
|
||||
if (/^link (in|out)$/.test(src.type) && /^link (in|out)$/.test(dst.type)) {
|
||||
if (src.links.indexOf(dst.id) === -1 && dst.links.indexOf(src.id) === -1) {
|
||||
var oldSrcLinks = $.extend(true,{},{v:src.links}).v
|
||||
var oldDstLinks = $.extend(true,{},{v:dst.links}).v
|
||||
src.links.push(dst.id);
|
||||
dst.links.push(src.id);
|
||||
src.dirty = true;
|
||||
dst.dirty = true;
|
||||
modifiedNodes.push(src);
|
||||
modifiedNodes.push(dst);
|
||||
|
||||
link.link = true;
|
||||
activeLinks.push(link);
|
||||
activeLinkNodes[src.id] = src;
|
||||
activeLinkNodes[dst.id] = dst;
|
||||
select_link = link;
|
||||
|
||||
linkEditEvents.push({
|
||||
t:'edit',
|
||||
node: src,
|
||||
dirty: RED.nodes.dirty(),
|
||||
changed: src.changed,
|
||||
changes: {
|
||||
links:oldSrcLinks
|
||||
}
|
||||
});
|
||||
linkEditEvents.push({
|
||||
t:'edit',
|
||||
node: dst,
|
||||
dirty: RED.nodes.dirty(),
|
||||
changed: dst.changed,
|
||||
changes: {
|
||||
links:oldDstLinks
|
||||
}
|
||||
});
|
||||
src.changed = true;
|
||||
dst.changed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var existingLink = RED.nodes.filterLinks({source:src,target:dst,sourcePort: src_port}).length !== 0;
|
||||
if (!existingLink) {
|
||||
var link = {source: src, sourcePort:src_port, target: dst};
|
||||
RED.nodes.addLink(link);
|
||||
addedLinks.push(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addedLinks.length > 0 || removedLinks.length > 0) {
|
||||
var historyEvent = {
|
||||
}
|
||||
if (addedLinks.length > 0 || removedLinks.length > 0 || modifiedNodes.length > 0) {
|
||||
// console.log(addedLinks);
|
||||
// console.log(removedLinks);
|
||||
// console.log(modifiedNodes);
|
||||
var historyEvent;
|
||||
if (modifiedNodes.length > 0) {
|
||||
historyEvent = {
|
||||
t:"multi",
|
||||
events: linkEditEvents,
|
||||
dirty:RED.nodes.dirty()
|
||||
};
|
||||
} else {
|
||||
historyEvent = {
|
||||
t:"add",
|
||||
links:addedLinks,
|
||||
removedLinks: removedLinks,
|
||||
dirty:RED.nodes.dirty()
|
||||
};
|
||||
}
|
||||
if (activeSubflow) {
|
||||
var subflowRefresh = RED.subflow.refresh(true);
|
||||
if (subflowRefresh) {
|
||||
@ -1657,7 +1855,7 @@ RED.view = (function() {
|
||||
RED.nodes.dirty(true);
|
||||
}
|
||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
||||
if (addedLinks.length > 0) {
|
||||
if (addedLinks.length > 0 || modifiedNodes.length > 0) {
|
||||
hideDragLines();
|
||||
if (portType === PORT_TYPE_INPUT && d.outputs > 0) {
|
||||
showDragLines([{node:d,port:0,portType:PORT_TYPE_OUTPUT}]);
|
||||
@ -1666,6 +1864,11 @@ RED.view = (function() {
|
||||
} else {
|
||||
resetMouseVars();
|
||||
}
|
||||
selected_link = select_link;
|
||||
mousedown_link = select_link;
|
||||
if (select_link) {
|
||||
updateSelection();
|
||||
}
|
||||
}
|
||||
redraw();
|
||||
return;
|
||||
@ -1673,7 +1876,11 @@ RED.view = (function() {
|
||||
|
||||
resetMouseVars();
|
||||
hideDragLines();
|
||||
selected_link = null;
|
||||
selected_link = select_link;
|
||||
mousedown_link = select_link;
|
||||
if (select_link) {
|
||||
updateSelection();
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
@ -1772,9 +1979,20 @@ RED.view = (function() {
|
||||
});
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
function portMouseOver(port,d,portType,portIndex) {
|
||||
clearTimeout(portLabelHoverTimeout);
|
||||
var active = (mouse_mode!=RED.state.JOINING || (drag_lines.length > 0 && drag_lines[0].portType !== portType));
|
||||
var active = (mouse_mode!=RED.state.JOINING && mouse_mode != RED.state.QUICK_JOINING) || // Not currently joining - all ports active
|
||||
(
|
||||
drag_lines.length > 0 && // Currently joining
|
||||
drag_lines[0].portType !== portType && // INPUT->OUTPUT OUTPUT->INPUT
|
||||
(
|
||||
!drag_lines[0].virtualLink || // Not a link wire
|
||||
(drag_lines[0].node.type === 'link in' && d.type === 'link out') ||
|
||||
(drag_lines[0].node.type === 'link out' && d.type === 'link in')
|
||||
)
|
||||
)
|
||||
|
||||
if (active && ((portType === PORT_TYPE_INPUT && ((d._def && d._def.inputLabels)||d.inputLabels)) || (portType === PORT_TYPE_OUTPUT && ((d._def && d._def.outputLabels)||d.outputLabels)))) {
|
||||
portLabelHoverTimeout = setTimeout(function() {
|
||||
var tooltip = getPortLabel(d,portType,portIndex);
|
||||
@ -1815,6 +2033,18 @@ RED.view = (function() {
|
||||
return;
|
||||
}
|
||||
var direction = d._def? (d.inputs > 0 ? 1: 0) : (d.direction == "in" ? 0: 1)
|
||||
|
||||
if (mouse_mode === RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) {
|
||||
if (drag_lines.length > 0) {
|
||||
if (drag_lines[0].virtualLink) {
|
||||
if (d.type === 'link in') {
|
||||
direction = 1;
|
||||
} else if (d.type === 'link out') {
|
||||
direction = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
portMouseUp(d, direction, 0);
|
||||
}
|
||||
|
||||
@ -2033,12 +2263,12 @@ RED.view = (function() {
|
||||
outer.attr("width", space_width*scaleFactor).attr("height", space_height*scaleFactor);
|
||||
|
||||
// Don't bother redrawing nodes if we're drawing links
|
||||
if (mouse_mode != RED.state.JOINING) {
|
||||
if (showAllLinkPorts !== -1 || mouse_mode != RED.state.JOINING) {
|
||||
|
||||
var dirtyNodes = {};
|
||||
|
||||
if (activeSubflow) {
|
||||
var subflowOutputs = vis.selectAll(".subflowoutput").data(activeSubflow.out,function(d,i){ return d.id;});
|
||||
var subflowOutputs = nodeLayer.selectAll(".subflowoutput").data(activeSubflow.out,function(d,i){ return d.id;});
|
||||
subflowOutputs.exit().remove();
|
||||
var outGroup = subflowOutputs.enter().insert("svg:g").attr("class","node subflowoutput").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"});
|
||||
outGroup.each(function(d,i) {
|
||||
@ -2081,7 +2311,7 @@ RED.view = (function() {
|
||||
outGroup.append("svg:text").attr("class","port_label").attr("x",20).attr("y",8).style("font-size","10px").text("output");
|
||||
outGroup.append("svg:text").attr("class","port_label port_index").attr("x",20).attr("y",24).text(function(d,i){ return i+1});
|
||||
|
||||
var subflowInputs = vis.selectAll(".subflowinput").data(activeSubflow.in,function(d,i){ return d.id;});
|
||||
var subflowInputs = nodeLayer.selectAll(".subflowinput").data(activeSubflow.in,function(d,i){ return d.id;});
|
||||
subflowInputs.exit().remove();
|
||||
var inGroup = subflowInputs.enter().insert("svg:g").attr("class","node subflowinput").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"});
|
||||
inGroup.each(function(d,i) {
|
||||
@ -2143,11 +2373,11 @@ RED.view = (function() {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
vis.selectAll(".subflowoutput").remove();
|
||||
vis.selectAll(".subflowinput").remove();
|
||||
nodeLayer.selectAll(".subflowoutput").remove();
|
||||
nodeLayer.selectAll(".subflowinput").remove();
|
||||
}
|
||||
|
||||
var node = vis.selectAll(".nodegroup").data(activeNodes,function(d){return d.id});
|
||||
var node = nodeLayer.selectAll(".nodegroup").data(activeNodes,function(d){return d.id});
|
||||
node.exit().remove();
|
||||
|
||||
var nodeEnter = node.enter().insert("svg:g")
|
||||
@ -2157,10 +2387,11 @@ RED.view = (function() {
|
||||
|
||||
nodeEnter.each(function(d,i) {
|
||||
var node = d3.select(this);
|
||||
var isLink = d.hasOwnProperty('l')?!d.l : (d.type === "link in" || d.type === "link out")
|
||||
var isLink = (d.type === "link in" || d.type === "link out")
|
||||
var hideLabel = d.hasOwnProperty('l')?!d.l : isLink;
|
||||
node.attr("id",d.id);
|
||||
var l = RED.utils.getNodeLabel(d);
|
||||
if (isLink) {
|
||||
if (hideLabel) {
|
||||
d.w = node_height;
|
||||
} else {
|
||||
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "node_label", 50)+(d._def.inputs>0?7:0))/20)) );
|
||||
@ -2332,7 +2563,7 @@ RED.view = (function() {
|
||||
.attr("x", 38)
|
||||
.attr("dy", ".35em")
|
||||
.attr("text-anchor","start")
|
||||
.classed("hidden",isLink);
|
||||
.classed("hidden",hideLabel);
|
||||
|
||||
if (d._def.align) {
|
||||
text.attr("class","node_label node_label_"+d._def.align);
|
||||
@ -2360,13 +2591,14 @@ RED.view = (function() {
|
||||
|
||||
node.each(function(d,i) {
|
||||
if (d.dirty) {
|
||||
var isLink = d.hasOwnProperty('l')?!d.l : (d.type === "link in" || d.type === "link out")
|
||||
var isLink = (d.type === "link in" || d.type === "link out")
|
||||
var hideLabel = d.hasOwnProperty('l')?!d.l : isLink;
|
||||
dirtyNodes[d.id] = d;
|
||||
//if (d.x < -50) deleteSelection(); // Delete nodes if dragged back to palette
|
||||
if (/*!isLink &&*/ d.resize) {
|
||||
if (d.resize) {
|
||||
var l = RED.utils.getNodeLabel(d);
|
||||
var ow = d.w;
|
||||
if (isLink) {
|
||||
if (hideLabel) {
|
||||
d.w = node_height;
|
||||
} else {
|
||||
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "node_label", 50)+(d._def.inputs>0?7:0))/20)) );
|
||||
@ -2396,13 +2628,24 @@ RED.view = (function() {
|
||||
//thisNode.selectAll(".node_icon_shade_border_right").attr("d",function(d){return "M "+(d.w-30)+" 1 l 0 "+(d.h-2)});
|
||||
|
||||
var inputPorts = thisNode.selectAll(".port_input");
|
||||
if (d.inputs === 0 && !inputPorts.empty()) {
|
||||
if (isLink && showAllLinkPorts === -1 && !activeLinkNodes[d.id] && d.inputs === 0 && !inputPorts.empty()) {
|
||||
inputPorts.remove();
|
||||
//nodeLabel.attr("x",30);
|
||||
} else if (d.inputs === 1 && inputPorts.empty()) {
|
||||
} else if (((isLink && (showAllLinkPorts===PORT_TYPE_INPUT||activeLinkNodes[d.id]))|| d.inputs === 1) && inputPorts.empty()) {
|
||||
var inputGroup = thisNode.append("g").attr("class","port_input");
|
||||
inputGroup.append("rect").attr("class","port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
|
||||
.on("mousedown",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);})
|
||||
var inputGroupPorts;
|
||||
|
||||
if (d.type === "link in") {
|
||||
inputGroupPorts = inputGroup.append("circle")
|
||||
.attr("cx",-1).attr("cy",5)
|
||||
.attr("r",5)
|
||||
.attr("class","port link_port")
|
||||
// inputGroupPorts = inputGroup.append("path")
|
||||
// .attr("d","M 4 -1 h -3 a 6 6 0 1 0 0 12 h 3")
|
||||
// .attr("class","port link_port")
|
||||
} else {
|
||||
inputGroupPorts = inputGroup.append("rect").attr("class","port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
|
||||
}
|
||||
inputGroupPorts.on("mousedown",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);})
|
||||
.on("touchstart",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);})
|
||||
.on("mouseup",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);} )
|
||||
.on("touchend",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);} )
|
||||
@ -2411,13 +2654,38 @@ RED.view = (function() {
|
||||
}
|
||||
|
||||
var numOutputs = d.outputs;
|
||||
if (isLink && d.type === "link out") {
|
||||
if (showAllLinkPorts===PORT_TYPE_OUTPUT || activeLinkNodes[d.id]) {
|
||||
d.ports = [0];
|
||||
numOutputs = 1;
|
||||
} else {
|
||||
d.ports = [];
|
||||
numOutputs = 0;
|
||||
}
|
||||
}
|
||||
var y = (d.h/2)-((numOutputs-1)/2)*13;
|
||||
d.ports = d.ports || d3.range(numOutputs);
|
||||
d._ports = thisNode.selectAll(".port_output").data(d.ports);
|
||||
var output_group = d._ports.enter().append("g").attr("class","port_output");
|
||||
var output_group_ports;
|
||||
|
||||
output_group.append("rect").attr("class","port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
|
||||
.on("mousedown",(function(){var node = d; return function(d,i){portMouseDown(node,PORT_TYPE_OUTPUT,i);}})() )
|
||||
if (d.type === "link out") {
|
||||
output_group_ports = output_group.append("circle")
|
||||
.attr("cx",11).attr("cy",5)
|
||||
.attr("r",5)
|
||||
.attr("class","port link_port")
|
||||
// output_group_ports = output_group.append("path")
|
||||
// .attr("d","M 6 -1 h 3 a 6 6 0 1 1 0 12 h -3")
|
||||
// .attr("class","port link_port")
|
||||
} else {
|
||||
output_group_ports = output_group.append("rect")
|
||||
.attr("class","port")
|
||||
.attr("rx",3).attr("ry",3)
|
||||
.attr("width",10)
|
||||
.attr("height",10)
|
||||
}
|
||||
|
||||
output_group_ports.on("mousedown",(function(){var node = d; return function(d,i){portMouseDown(node,PORT_TYPE_OUTPUT,i);}})() )
|
||||
.on("touchstart",(function(){var node = d; return function(d,i){portMouseDown(node,PORT_TYPE_OUTPUT,i);}})() )
|
||||
.on("mouseup",(function(){var node = d; return function(d,i){portMouseUp(node,PORT_TYPE_OUTPUT,i);}})() )
|
||||
.on("touchend",(function(){var node = d; return function(d,i){portMouseUp(node,PORT_TYPE_OUTPUT,i);}})() )
|
||||
@ -2464,7 +2732,7 @@ RED.view = (function() {
|
||||
}
|
||||
return "node_label"+
|
||||
(d._def.align?" node_label_"+d._def.align:"")+s;
|
||||
}).classed("hidden",isLink);
|
||||
}).classed("hidden",hideLabel);
|
||||
if (d._def.icon) {
|
||||
var icon = thisNode.select(".node_icon");
|
||||
var faIcon = thisNode.select(".fa-lg");
|
||||
@ -2592,7 +2860,7 @@ RED.view = (function() {
|
||||
}
|
||||
});
|
||||
|
||||
var link = vis.selectAll(".link").data(
|
||||
var link = linkLayer.selectAll(".link").data(
|
||||
activeLinks,
|
||||
function(d) {
|
||||
return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i;
|
||||
@ -2638,7 +2906,7 @@ RED.view = (function() {
|
||||
});
|
||||
|
||||
link.exit().remove();
|
||||
var links = vis.selectAll(".link_path");
|
||||
var links = linkLayer.selectAll(".link_path");
|
||||
links.each(function(d) {
|
||||
var link = d3.select(this);
|
||||
if (d.added || d===selected_link || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) {
|
||||
@ -2666,7 +2934,7 @@ RED.view = (function() {
|
||||
delete d.added;
|
||||
return d.target.type == "unknown" || d.source.type == "unknown"
|
||||
});
|
||||
var offLinks = vis.selectAll(".link_flow_link_g").data(
|
||||
var offLinks = linkLayer.selectAll(".link_flow_link_g").data(
|
||||
activeFlowLinks,
|
||||
function(d) {
|
||||
return d.node.id+":"+d.refresh
|
||||
@ -2697,10 +2965,13 @@ RED.view = (function() {
|
||||
var y = -(flows.length-1)*h/2;
|
||||
var linkGroups = g.selectAll(".link_group").data(flows);
|
||||
var enterLinkGroups = linkGroups.enter().append("g").attr("class","link_group")
|
||||
.on('mouseover', function() { d3.select(this).classed('link_group_active',true)})
|
||||
.on('mouseout', function() { d3.select(this).classed('link_group_active',false)})
|
||||
.on('mouseover', function() { if (mouse_mode !== 0) { return } d3.select(this).classed('link_group_active',true)})
|
||||
.on('mouseout', function() {if (mouse_mode !== 0) { return } d3.select(this).classed('link_group_active',false)})
|
||||
.on('mousedown', function() { d3.event.preventDefault(); d3.event.stopPropagation(); })
|
||||
.on('mouseup', function(f) {
|
||||
if (mouse_mode !== 0) {
|
||||
return
|
||||
}
|
||||
d3.event.stopPropagation();
|
||||
var targets = d.links[f];
|
||||
RED.workspaces.show(f);
|
||||
@ -2772,7 +3043,7 @@ RED.view = (function() {
|
||||
linkGroups.exit().remove();
|
||||
});
|
||||
offLinks.exit().remove();
|
||||
offLinks = vis.selectAll(".link_flow_link_g");
|
||||
offLinks = linkLayer.selectAll(".link_flow_link_g");
|
||||
offLinks.each(function(d) {
|
||||
var s = 1;
|
||||
if (d.node.type === "link in") {
|
||||
@ -2785,7 +3056,7 @@ RED.view = (function() {
|
||||
|
||||
} else {
|
||||
// JOINING - unselect any selected links
|
||||
vis.selectAll(".link_selected").data(
|
||||
linkLayer.selectAll(".link_selected").data(
|
||||
activeLinks,
|
||||
function(d) {
|
||||
return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i;
|
||||
|
@ -194,8 +194,8 @@
|
||||
}
|
||||
|
||||
.port_hovered {
|
||||
stroke: $port-selected-color;
|
||||
fill: $port-selected-color;
|
||||
stroke: $port-selected-color !important;
|
||||
fill: $port-selected-color !important;
|
||||
}
|
||||
|
||||
.port_quick_link {
|
||||
@ -211,7 +211,7 @@
|
||||
}
|
||||
|
||||
.drag_line {
|
||||
stroke: $node-selected-color;
|
||||
stroke: $node-selected-color !important;
|
||||
stroke-width: 3;
|
||||
fill: none;
|
||||
pointer-events: none;
|
||||
@ -236,10 +236,10 @@
|
||||
stroke: $link-link-color;
|
||||
fill: none;
|
||||
stroke-dasharray: 15,2;
|
||||
pointer-events: none;
|
||||
// pointer-events: none;
|
||||
}
|
||||
.link_port {
|
||||
fill: #fff;
|
||||
fill: #eee;
|
||||
stroke: $link-link-color;
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user