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.nodes.dirty(ev.dirty);
|
||||||
|
RED.view.select(null);
|
||||||
RED.view.redraw(true);
|
RED.view.redraw(true);
|
||||||
RED.palette.refresh();
|
RED.palette.refresh();
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
|
@ -42,6 +42,7 @@ RED.view = (function() {
|
|||||||
var activeNodes = [];
|
var activeNodes = [];
|
||||||
var activeLinks = [];
|
var activeLinks = [];
|
||||||
var activeFlowLinks = [];
|
var activeFlowLinks = [];
|
||||||
|
var activeLinkNodes = {};
|
||||||
|
|
||||||
var selected_link = null,
|
var selected_link = null,
|
||||||
mousedown_link = null,
|
mousedown_link = null,
|
||||||
@ -61,7 +62,8 @@ RED.view = (function() {
|
|||||||
clickElapsed = 0,
|
clickElapsed = 0,
|
||||||
scroll_position = [],
|
scroll_position = [],
|
||||||
quickAddActive = false,
|
quickAddActive = false,
|
||||||
quickAddLink = null;
|
quickAddLink = null,
|
||||||
|
showAllLinkPorts = -1;
|
||||||
|
|
||||||
var clipboard = "";
|
var clipboard = "";
|
||||||
|
|
||||||
@ -263,19 +265,41 @@ RED.view = (function() {
|
|||||||
"stroke-width" : "1px"
|
"stroke-width" : "1px"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
var linkLayer = vis.append("g");
|
||||||
var dragGroup = vis.append("g");
|
var dragGroup = vis.append("g");
|
||||||
|
var nodeLayer = vis.append("g");
|
||||||
var drag_lines = [];
|
var drag_lines = [];
|
||||||
|
|
||||||
function showDragLines(nodes) {
|
function showDragLines(nodes) {
|
||||||
|
showAllLinkPorts = -1;
|
||||||
for (var i=0;i<nodes.length;i++) {
|
for (var i=0;i<nodes.length;i++) {
|
||||||
var node = nodes[i];
|
var node = nodes[i];
|
||||||
node.el = dragGroup.append("svg:path").attr("class", "drag_line");
|
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);
|
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() {
|
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) {
|
while(drag_lines.length) {
|
||||||
var line = drag_lines.pop();
|
var line = drag_lines.pop();
|
||||||
if (line.el) {
|
if (line.el) {
|
||||||
@ -657,10 +681,21 @@ RED.view = (function() {
|
|||||||
mouse_mode = RED.state.QUICK_JOINING;
|
mouse_mode = RED.state.QUICK_JOINING;
|
||||||
$(window).on('keyup',disableQuickJoinEventHandler);
|
$(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;
|
quickAddActive = true;
|
||||||
RED.typeSearch.show({
|
RED.typeSearch.show({
|
||||||
x:d3.event.clientX-mainPos.left-node_width/2,
|
x:d3.event.clientX-mainPos.left-node_width/2,
|
||||||
y:d3.event.clientY-mainPos.top-node_height/2,
|
y:d3.event.clientY-mainPos.top-node_height/2,
|
||||||
|
filter: filter,
|
||||||
cancel: function() {
|
cancel: function() {
|
||||||
quickAddActive = false;
|
quickAddActive = false;
|
||||||
resetMouseVars();
|
resetMouseVars();
|
||||||
@ -685,19 +720,54 @@ RED.view = (function() {
|
|||||||
if (quickAddLink || drag_lines.length > 0) {
|
if (quickAddLink || drag_lines.length > 0) {
|
||||||
var drag_line = quickAddLink||drag_lines[0];
|
var drag_line = quickAddLink||drag_lines[0];
|
||||||
var src = null,dst,src_port;
|
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 = drag_line.node;
|
||||||
src_port = drag_line.port;
|
src_port = drag_line.port;
|
||||||
dst = nn;
|
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;
|
src = nn;
|
||||||
dst = drag_line.node;
|
dst = drag_line.node;
|
||||||
src_port = 0;
|
src_port = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src !== null) {
|
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};
|
var link = {source: src, sourcePort:src_port, target: dst};
|
||||||
RED.nodes.addLink(link);
|
RED.nodes.addLink(link);
|
||||||
historyEvent.links = [link];
|
historyEvent.links = [link];
|
||||||
|
}
|
||||||
hideDragLines();
|
hideDragLines();
|
||||||
if (!quickAddLink && drag_line.portType === PORT_TYPE_OUTPUT && nn.outputs > 0) {
|
if (!quickAddLink && drag_line.portType === PORT_TYPE_OUTPUT && nn.outputs > 0) {
|
||||||
showDragLines([{node:nn,port:0,portType:PORT_TYPE_OUTPUT}]);
|
showDragLines([{node:nn,port:0,portType:PORT_TYPE_OUTPUT}]);
|
||||||
@ -1216,9 +1286,15 @@ RED.view = (function() {
|
|||||||
var currentLinks = activeLinks;
|
var currentLinks = activeLinks;
|
||||||
var addedLinkLinks = {};
|
var addedLinkLinks = {};
|
||||||
activeFlowLinks = [];
|
activeFlowLinks = [];
|
||||||
|
var activeLinkNodeIds = Object.keys(activeLinkNodes);
|
||||||
|
activeLinkNodeIds.forEach(function(n) {
|
||||||
|
activeLinkNodes[n].dirty = true;
|
||||||
|
})
|
||||||
|
activeLinkNodes = {};
|
||||||
for (var i=0;i<moving_set.length;i++) {
|
for (var i=0;i<moving_set.length;i++) {
|
||||||
if (moving_set[i].n.type === "link out" || moving_set[i].n.type === "link in") {
|
if (moving_set[i].n.type === "link out" || moving_set[i].n.type === "link in") {
|
||||||
var linkNode = moving_set[i].n;
|
var linkNode = moving_set[i].n;
|
||||||
|
activeLinkNodes[linkNode.id] = linkNode;
|
||||||
var offFlowLinks = {};
|
var offFlowLinks = {};
|
||||||
linkNode.links.forEach(function(id) {
|
linkNode.links.forEach(function(id) {
|
||||||
var target = RED.nodes.node(id);
|
var target = RED.nodes.node(id);
|
||||||
@ -1233,6 +1309,9 @@ RED.view = (function() {
|
|||||||
link: true
|
link: true
|
||||||
});
|
});
|
||||||
addedLinkLinks[linkNode.id+":"+target.id] = true;
|
addedLinkLinks[linkNode.id+":"+target.id] = true;
|
||||||
|
activeLinkNodes[target.id] = target;
|
||||||
|
target.dirty = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offFlowLinks[target.z] = offFlowLinks[target.z]||[];
|
offFlowLinks[target.z] = offFlowLinks[target.z]||[];
|
||||||
@ -1248,6 +1327,8 @@ RED.view = (function() {
|
|||||||
link: true
|
link: true
|
||||||
});
|
});
|
||||||
addedLinkLinks[target.id+":"+linkNode.id] = true;
|
addedLinkLinks[target.id+":"+linkNode.id] = true;
|
||||||
|
activeLinkNodes[target.id] = target;
|
||||||
|
target.dirty = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offFlowLinks[target.z] = offFlowLinks[target.z]||[];
|
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 {
|
} else {
|
||||||
selection.flows = workspaceSelection;
|
selection.flows = workspaceSelection;
|
||||||
}
|
}
|
||||||
@ -1445,12 +1533,52 @@ RED.view = (function() {
|
|||||||
RED.nodes.dirty(true);
|
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) {
|
if (selected_link) {
|
||||||
RED.nodes.removeLink(selected_link);
|
RED.nodes.removeLink(selected_link);
|
||||||
removedLinks.push(selected_link);
|
removedLinks.push(selected_link);
|
||||||
RED.nodes.dirty(true);
|
|
||||||
}
|
}
|
||||||
var historyEvent = {
|
RED.nodes.dirty(true);
|
||||||
|
historyEvent = {
|
||||||
t:"delete",
|
t:"delete",
|
||||||
nodes:removedNodes,
|
nodes:removedNodes,
|
||||||
links:removedLinks,
|
links:removedLinks,
|
||||||
@ -1461,6 +1589,7 @@ RED.view = (function() {
|
|||||||
},
|
},
|
||||||
dirty:startDirty
|
dirty:startDirty
|
||||||
};
|
};
|
||||||
|
}
|
||||||
RED.history.push(historyEvent);
|
RED.history.push(historyEvent);
|
||||||
|
|
||||||
selected_link = null;
|
selected_link = null;
|
||||||
@ -1574,6 +1703,7 @@ RED.view = (function() {
|
|||||||
if (d3.event.ctrlKey || d3.event.metaKey) {
|
if (d3.event.ctrlKey || d3.event.metaKey) {
|
||||||
mouse_mode = RED.state.QUICK_JOINING;
|
mouse_mode = RED.state.QUICK_JOINING;
|
||||||
showDragLines([{node:mousedown_node,port:mousedown_port_index,portType:mousedown_port_type}]);
|
showDragLines([{node:mousedown_node,port:mousedown_port_index,portType:mousedown_port_type}]);
|
||||||
|
quickAddLink = null;
|
||||||
$(window).on('keyup',disableQuickJoinEventHandler);
|
$(window).on('keyup',disableQuickJoinEventHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1585,6 +1715,15 @@ RED.view = (function() {
|
|||||||
var i;
|
var i;
|
||||||
if (mouse_mode === RED.state.QUICK_JOINING && drag_lines.length > 0) {
|
if (mouse_mode === RED.state.QUICK_JOINING && drag_lines.length > 0) {
|
||||||
if (drag_lines[0].node === d) {
|
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
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1608,12 +1747,17 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
var addedLinks = [];
|
var addedLinks = [];
|
||||||
var removedLinks = [];
|
var removedLinks = [];
|
||||||
|
var modifiedNodes = []; // joining link nodes
|
||||||
|
|
||||||
|
var select_link = null;
|
||||||
|
|
||||||
for (i=0;i<drag_lines.length;i++) {
|
for (i=0;i<drag_lines.length;i++) {
|
||||||
if (drag_lines[i].link) {
|
if (drag_lines[i].link) {
|
||||||
removedLinks.push(drag_lines[i].link)
|
removedLinks.push(drag_lines[i].link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var linkEditEvents = [];
|
||||||
|
|
||||||
for (i=0;i<drag_lines.length;i++) {
|
for (i=0;i<drag_lines.length;i++) {
|
||||||
if (portType != drag_lines[i].portType && mouseup_node !== drag_lines[i].node) {
|
if (portType != drag_lines[i].portType && mouseup_node !== drag_lines[i].node) {
|
||||||
var drag_line = drag_lines[i];
|
var drag_line = drag_lines[i];
|
||||||
@ -1627,21 +1771,75 @@ RED.view = (function() {
|
|||||||
dst = drag_line.node;
|
dst = drag_line.node;
|
||||||
src_port = portIndex;
|
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;
|
var existingLink = RED.nodes.filterLinks({source:src,target:dst,sourcePort: src_port}).length !== 0;
|
||||||
if (!existingLink) {
|
if (!existingLink) {
|
||||||
var link = {source: src, sourcePort:src_port, target: dst};
|
|
||||||
RED.nodes.addLink(link);
|
RED.nodes.addLink(link);
|
||||||
addedLinks.push(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",
|
t:"add",
|
||||||
links:addedLinks,
|
links:addedLinks,
|
||||||
removedLinks: removedLinks,
|
removedLinks: removedLinks,
|
||||||
dirty:RED.nodes.dirty()
|
dirty:RED.nodes.dirty()
|
||||||
};
|
};
|
||||||
|
}
|
||||||
if (activeSubflow) {
|
if (activeSubflow) {
|
||||||
var subflowRefresh = RED.subflow.refresh(true);
|
var subflowRefresh = RED.subflow.refresh(true);
|
||||||
if (subflowRefresh) {
|
if (subflowRefresh) {
|
||||||
@ -1657,7 +1855,7 @@ RED.view = (function() {
|
|||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
}
|
}
|
||||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
if (mouse_mode === RED.state.QUICK_JOINING) {
|
||||||
if (addedLinks.length > 0) {
|
if (addedLinks.length > 0 || modifiedNodes.length > 0) {
|
||||||
hideDragLines();
|
hideDragLines();
|
||||||
if (portType === PORT_TYPE_INPUT && d.outputs > 0) {
|
if (portType === PORT_TYPE_INPUT && d.outputs > 0) {
|
||||||
showDragLines([{node:d,port:0,portType:PORT_TYPE_OUTPUT}]);
|
showDragLines([{node:d,port:0,portType:PORT_TYPE_OUTPUT}]);
|
||||||
@ -1666,6 +1864,11 @@ RED.view = (function() {
|
|||||||
} else {
|
} else {
|
||||||
resetMouseVars();
|
resetMouseVars();
|
||||||
}
|
}
|
||||||
|
selected_link = select_link;
|
||||||
|
mousedown_link = select_link;
|
||||||
|
if (select_link) {
|
||||||
|
updateSelection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
redraw();
|
redraw();
|
||||||
return;
|
return;
|
||||||
@ -1673,7 +1876,11 @@ RED.view = (function() {
|
|||||||
|
|
||||||
resetMouseVars();
|
resetMouseVars();
|
||||||
hideDragLines();
|
hideDragLines();
|
||||||
selected_link = null;
|
selected_link = select_link;
|
||||||
|
mousedown_link = select_link;
|
||||||
|
if (select_link) {
|
||||||
|
updateSelection();
|
||||||
|
}
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1772,9 +1979,20 @@ RED.view = (function() {
|
|||||||
});
|
});
|
||||||
return tooltip;
|
return tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
function portMouseOver(port,d,portType,portIndex) {
|
function portMouseOver(port,d,portType,portIndex) {
|
||||||
clearTimeout(portLabelHoverTimeout);
|
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)))) {
|
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() {
|
portLabelHoverTimeout = setTimeout(function() {
|
||||||
var tooltip = getPortLabel(d,portType,portIndex);
|
var tooltip = getPortLabel(d,portType,portIndex);
|
||||||
@ -1815,6 +2033,18 @@ RED.view = (function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var direction = d._def? (d.inputs > 0 ? 1: 0) : (d.direction == "in" ? 0: 1)
|
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);
|
portMouseUp(d, direction, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2033,12 +2263,12 @@ RED.view = (function() {
|
|||||||
outer.attr("width", space_width*scaleFactor).attr("height", space_height*scaleFactor);
|
outer.attr("width", space_width*scaleFactor).attr("height", space_height*scaleFactor);
|
||||||
|
|
||||||
// Don't bother redrawing nodes if we're drawing links
|
// 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 = {};
|
var dirtyNodes = {};
|
||||||
|
|
||||||
if (activeSubflow) {
|
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();
|
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)+")"});
|
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) {
|
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").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});
|
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();
|
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)+")"});
|
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) {
|
inGroup.each(function(d,i) {
|
||||||
@ -2143,11 +2373,11 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
vis.selectAll(".subflowoutput").remove();
|
nodeLayer.selectAll(".subflowoutput").remove();
|
||||||
vis.selectAll(".subflowinput").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();
|
node.exit().remove();
|
||||||
|
|
||||||
var nodeEnter = node.enter().insert("svg:g")
|
var nodeEnter = node.enter().insert("svg:g")
|
||||||
@ -2157,10 +2387,11 @@ RED.view = (function() {
|
|||||||
|
|
||||||
nodeEnter.each(function(d,i) {
|
nodeEnter.each(function(d,i) {
|
||||||
var node = d3.select(this);
|
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);
|
node.attr("id",d.id);
|
||||||
var l = RED.utils.getNodeLabel(d);
|
var l = RED.utils.getNodeLabel(d);
|
||||||
if (isLink) {
|
if (hideLabel) {
|
||||||
d.w = node_height;
|
d.w = node_height;
|
||||||
} else {
|
} else {
|
||||||
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "node_label", 50)+(d._def.inputs>0?7:0))/20)) );
|
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("x", 38)
|
||||||
.attr("dy", ".35em")
|
.attr("dy", ".35em")
|
||||||
.attr("text-anchor","start")
|
.attr("text-anchor","start")
|
||||||
.classed("hidden",isLink);
|
.classed("hidden",hideLabel);
|
||||||
|
|
||||||
if (d._def.align) {
|
if (d._def.align) {
|
||||||
text.attr("class","node_label node_label_"+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) {
|
node.each(function(d,i) {
|
||||||
if (d.dirty) {
|
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;
|
dirtyNodes[d.id] = d;
|
||||||
//if (d.x < -50) deleteSelection(); // Delete nodes if dragged back to palette
|
//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 l = RED.utils.getNodeLabel(d);
|
||||||
var ow = d.w;
|
var ow = d.w;
|
||||||
if (isLink) {
|
if (hideLabel) {
|
||||||
d.w = node_height;
|
d.w = node_height;
|
||||||
} else {
|
} else {
|
||||||
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "node_label", 50)+(d._def.inputs>0?7:0))/20)) );
|
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)});
|
//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");
|
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();
|
inputPorts.remove();
|
||||||
//nodeLabel.attr("x",30);
|
} else if (((isLink && (showAllLinkPorts===PORT_TYPE_INPUT||activeLinkNodes[d.id]))|| d.inputs === 1) && inputPorts.empty()) {
|
||||||
} else if (d.inputs === 1 && inputPorts.empty()) {
|
|
||||||
var inputGroup = thisNode.append("g").attr("class","port_input");
|
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)
|
var inputGroupPorts;
|
||||||
.on("mousedown",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);})
|
|
||||||
|
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("touchstart",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);})
|
||||||
.on("mouseup",function(d){portMouseUp(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);} )
|
.on("touchend",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);} )
|
||||||
@ -2411,13 +2654,38 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var numOutputs = d.outputs;
|
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;
|
var y = (d.h/2)-((numOutputs-1)/2)*13;
|
||||||
d.ports = d.ports || d3.range(numOutputs);
|
d.ports = d.ports || d3.range(numOutputs);
|
||||||
d._ports = thisNode.selectAll(".port_output").data(d.ports);
|
d._ports = thisNode.selectAll(".port_output").data(d.ports);
|
||||||
var output_group = d._ports.enter().append("g").attr("class","port_output");
|
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)
|
if (d.type === "link out") {
|
||||||
.on("mousedown",(function(){var node = d; return function(d,i){portMouseDown(node,PORT_TYPE_OUTPUT,i);}})() )
|
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("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("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);}})() )
|
.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"+
|
return "node_label"+
|
||||||
(d._def.align?" node_label_"+d._def.align:"")+s;
|
(d._def.align?" node_label_"+d._def.align:"")+s;
|
||||||
}).classed("hidden",isLink);
|
}).classed("hidden",hideLabel);
|
||||||
if (d._def.icon) {
|
if (d._def.icon) {
|
||||||
var icon = thisNode.select(".node_icon");
|
var icon = thisNode.select(".node_icon");
|
||||||
var faIcon = thisNode.select(".fa-lg");
|
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,
|
activeLinks,
|
||||||
function(d) {
|
function(d) {
|
||||||
return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i;
|
return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i;
|
||||||
@ -2638,7 +2906,7 @@ RED.view = (function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
link.exit().remove();
|
link.exit().remove();
|
||||||
var links = vis.selectAll(".link_path");
|
var links = linkLayer.selectAll(".link_path");
|
||||||
links.each(function(d) {
|
links.each(function(d) {
|
||||||
var link = d3.select(this);
|
var link = d3.select(this);
|
||||||
if (d.added || d===selected_link || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) {
|
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;
|
delete d.added;
|
||||||
return d.target.type == "unknown" || d.source.type == "unknown"
|
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,
|
activeFlowLinks,
|
||||||
function(d) {
|
function(d) {
|
||||||
return d.node.id+":"+d.refresh
|
return d.node.id+":"+d.refresh
|
||||||
@ -2697,10 +2965,13 @@ RED.view = (function() {
|
|||||||
var y = -(flows.length-1)*h/2;
|
var y = -(flows.length-1)*h/2;
|
||||||
var linkGroups = g.selectAll(".link_group").data(flows);
|
var linkGroups = g.selectAll(".link_group").data(flows);
|
||||||
var enterLinkGroups = linkGroups.enter().append("g").attr("class","link_group")
|
var enterLinkGroups = linkGroups.enter().append("g").attr("class","link_group")
|
||||||
.on('mouseover', function() { d3.select(this).classed('link_group_active',true)})
|
.on('mouseover', function() { if (mouse_mode !== 0) { return } d3.select(this).classed('link_group_active',true)})
|
||||||
.on('mouseout', function() { d3.select(this).classed('link_group_active',false)})
|
.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('mousedown', function() { d3.event.preventDefault(); d3.event.stopPropagation(); })
|
||||||
.on('mouseup', function(f) {
|
.on('mouseup', function(f) {
|
||||||
|
if (mouse_mode !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
d3.event.stopPropagation();
|
d3.event.stopPropagation();
|
||||||
var targets = d.links[f];
|
var targets = d.links[f];
|
||||||
RED.workspaces.show(f);
|
RED.workspaces.show(f);
|
||||||
@ -2772,7 +3043,7 @@ RED.view = (function() {
|
|||||||
linkGroups.exit().remove();
|
linkGroups.exit().remove();
|
||||||
});
|
});
|
||||||
offLinks.exit().remove();
|
offLinks.exit().remove();
|
||||||
offLinks = vis.selectAll(".link_flow_link_g");
|
offLinks = linkLayer.selectAll(".link_flow_link_g");
|
||||||
offLinks.each(function(d) {
|
offLinks.each(function(d) {
|
||||||
var s = 1;
|
var s = 1;
|
||||||
if (d.node.type === "link in") {
|
if (d.node.type === "link in") {
|
||||||
@ -2785,7 +3056,7 @@ RED.view = (function() {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// JOINING - unselect any selected links
|
// JOINING - unselect any selected links
|
||||||
vis.selectAll(".link_selected").data(
|
linkLayer.selectAll(".link_selected").data(
|
||||||
activeLinks,
|
activeLinks,
|
||||||
function(d) {
|
function(d) {
|
||||||
return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i;
|
return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i;
|
||||||
|
@ -194,8 +194,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.port_hovered {
|
.port_hovered {
|
||||||
stroke: $port-selected-color;
|
stroke: $port-selected-color !important;
|
||||||
fill: $port-selected-color;
|
fill: $port-selected-color !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.port_quick_link {
|
.port_quick_link {
|
||||||
@ -211,7 +211,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.drag_line {
|
.drag_line {
|
||||||
stroke: $node-selected-color;
|
stroke: $node-selected-color !important;
|
||||||
stroke-width: 3;
|
stroke-width: 3;
|
||||||
fill: none;
|
fill: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@ -236,10 +236,10 @@
|
|||||||
stroke: $link-link-color;
|
stroke: $link-link-color;
|
||||||
fill: none;
|
fill: none;
|
||||||
stroke-dasharray: 15,2;
|
stroke-dasharray: 15,2;
|
||||||
pointer-events: none;
|
// pointer-events: none;
|
||||||
}
|
}
|
||||||
.link_port {
|
.link_port {
|
||||||
fill: #fff;
|
fill: #eee;
|
||||||
stroke: $link-link-color;
|
stroke: $link-link-color;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user