Rework subflow edit process

This commit is contained in:
Nick O'Leary 2014-11-13 12:59:28 +00:00
parent 5cb9a5b7eb
commit 426fcc2fdd
5 changed files with 145 additions and 90 deletions

View File

@ -51,7 +51,9 @@
<div id="workspace-add-tab"><a id="btn-workspace-add-tab" href="#"><i class="fa fa-plus"></i></a></div> <div id="workspace-add-tab"><a id="btn-workspace-add-tab" href="#"><i class="fa fa-plus"></i></a></div>
<div id="chart"></div> <div id="chart"></div>
<div id="workspace-toolbar"> <div id="workspace-toolbar">
<a class="button" id="workspace-edit-subflow" href="#"><i class="fa fa-pencil"></i> edit subflow properties</a> <a class="button" id="workspace-subflow-edit" href="#"><i class="fa fa-pencil"></i> edit subflow name</a>
<a class="button disabled" id="workspace-subflow-add-input" href="#"><i class="fa fa-plus"></i> input</a>
<a class="button" id="workspace-subflow-add-output" href="#"><i class="fa fa-plus"></i> output</a>
</div> </div>
</div> </div>
@ -82,12 +84,6 @@
<div class="form-row"> <div class="form-row">
<label>Name</label><input type="text" id="subflow-input-name"> <label>Name</label><input type="text" id="subflow-input-name">
</div> </div>
<div class="form-row">
<label>Inputs</label><input style="width: 60px; height: 1.7em;" id="subflow-input-inCount">
</div>
<div class="form-row">
<label>Outputs</label><input style="width: 60px; height: 1.7em;" id="subflow-input-outCount">
</div>
</form> </form>
<div class="form-tips" id="subflow-dialog-user-count"></div> <div class="form-tips" id="subflow-dialog-user-count"></div>
</div> </div>

View File

@ -129,15 +129,19 @@ RED.history = (function() {
} }
} }
if (ev.subflow) { if (ev.subflow) {
if (ev.node.in.length > ev.subflow.inputCount) { if (ev.subflow.hasOwnProperty('inputCount')) {
ev.node.in.splice(ev.subflow.inputCount); if (ev.node.in.length > ev.subflow.inputCount) {
} else if (ev.subflow.inputs.length > 0) { ev.node.in.splice(ev.subflow.inputCount);
ev.node.in = ev.node.in.concat(ev.subflow.inputs); } else if (ev.subflow.inputs.length > 0) {
ev.node.in = ev.node.in.concat(ev.subflow.inputs);
}
} }
if (ev.node.out.length > ev.subflow.outputCount) { if (ev.subflow.hasOwnProperty('outputCount')) {
ev.node.out.splice(ev.subflow.outputCount); if (ev.node.out.length > ev.subflow.outputCount) {
} else if (ev.subflow.outputs.length > 0) { ev.node.out.splice(ev.subflow.outputCount);
ev.node.out = ev.node.out.concat(ev.subflow.outputs); } else if (ev.subflow.outputs.length > 0) {
ev.node.out = ev.node.out.concat(ev.subflow.outputs);
}
} }
RED.nodes.eachNode(function(n) { RED.nodes.eachNode(function(n) {
if (n.type == "subflow:"+ev.node.id) { if (n.type == "subflow:"+ev.node.id) {
@ -148,8 +152,6 @@ RED.history = (function() {
} }
}); });
RED.palette.refresh(); RED.palette.refresh();
} else { } else {
RED.editor.updateNodeProperties(ev.node); RED.editor.updateNodeProperties(ev.node);

View File

@ -750,74 +750,21 @@ RED.editor = (function() {
var wasDirty = RED.view.dirty(); var wasDirty = RED.view.dirty();
var newName = $("#subflow-input-name").val(); var newName = $("#subflow-input-name").val();
var newInCount = Number($("#subflow-input-inCount").val())||0;
var newOutCount = Number($("#subflow-input-outCount").val())||0;
var oldInCount = editing_node.in.length;
var oldOutCount = editing_node.out.length;
if (newName != editing_node.name) { if (newName != editing_node.name) {
changes['name'] = editing_node.name; changes['name'] = editing_node.name;
editing_node.name = newName; editing_node.name = newName;
changed = true; changed = true;
$("#btn-workspace-menu-"+editing_node.id.replace(".","-")).text("Subflow: "+newName); $("#btn-workspace-menu-"+editing_node.id.replace(".","-")).text("Subflow: "+newName);
} }
var xpos = 40;
var addedOutputs = [];
var removedOutputs = [];
var addedInputs = [];
var removedInputs = [];
var removedLinks = [];
if (editing_node.in.length < newInCount) {
var l = editing_node.in.length;
for (i=l;i<newInCount;i++) {
var newInput = {type:"subflow",direction:"in",z:editing_node.id,i:i,x:xpos,y:70,id:RED.node.id()};
addedInputs.push(newInput);
editing_node.in.push(newInput);
xpos += 55;
}
changed = true;
} else if (editing_node.in.length > newInCount) {
removedInputs = editing_node.in.splice(newInCount);
changed = true;
}
if (editing_node.out.length < newOutCount) {
for (i=editing_node.out.length;i<newOutCount;i++) {
var newOutput = {type:"subflow",direction:"out",z:editing_node.id,i:i,x:xpos,y:70,id:RED.node.id()};
addedOutputs.push(newOutput);
editing_node.out.push(newOutput);
xpos += 55;
}
changed = true;
} else if (editing_node.out.length > newOutCount) {
removedOutputs = editing_node.out.splice(newOutCount);
changed = true;
}
if (removedOutputs.length > 0 || removedInputs.length > 0) {
RED.nodes.eachLink(function(l) {
if (newInCount === 0 && l.source.type == "subflow" && l.source.z == editing_node.id) {
removedLinks.push(l);
return;
}
if (l.target.type == "subflow" && l.target.z == editing_node.id && l.target.i >= newOutCount) {
removedLinks.push(l);
return;
}
});
removedLinks.forEach(function(l) { RED.nodes.removeLink(l)});
}
RED.palette.refresh(); RED.palette.refresh();
if (changed) { if (changed) {
RED.nodes.eachNode(function(n) { RED.nodes.eachNode(function(n) {
if (n.type == "subflow:"+editing_node.id) { if (n.type == "subflow:"+editing_node.id) {
n.changed = true; n.changed = true;
n.inputs = editing_node.in.length; updateNodeProperties(n);
n.outputs = editing_node.out.length;
removedLinks = removedLinks.concat(updateNodeProperties(n));
} }
}); });
var wasChanged = editing_node.changed; var wasChanged = editing_node.changed;
@ -827,15 +774,8 @@ RED.editor = (function() {
t:'edit', t:'edit',
node:editing_node, node:editing_node,
changes:changes, changes:changes,
links:removedLinks,
dirty:wasDirty, dirty:wasDirty,
changed:wasChanged, changed:wasChanged
subflow: {
outputCount: oldOutCount,
inputCount: oldInCount,
outputs: removedOutputs,
inputs: removedInputs
}
}; };
RED.history.push(historyEvent); RED.history.push(historyEvent);
@ -873,8 +813,6 @@ RED.editor = (function() {
editing_node = subflow; editing_node = subflow;
RED.view.state(RED.state.EDITING); RED.view.state(RED.state.EDITING);
$("#subflow-input-name").val(subflow.name); $("#subflow-input-name").val(subflow.name);
$("#subflow-input-inCount").spinner({ min:0, max:1 }).val(subflow.in.length);
$("#subflow-input-outCount").spinner({ min:0 }).val(subflow.out.length);
var userCount = 0; var userCount = 0;
var subflowType = "subflow:"+editing_node.id; var subflowType = "subflow:"+editing_node.id;
@ -884,7 +822,6 @@ RED.editor = (function() {
} }
}); });
$("#subflow-dialog-user-count").html("There "+(userCount==1?"is":"are")+" "+userCount+" instance"+(userCount==1?" ":"s")+" of this subflow").show(); $("#subflow-dialog-user-count").html("There "+(userCount==1?"is":"are")+" "+userCount+" instance"+(userCount==1?" ":"s")+" of this subflow").show();
$("#subflow-dialog").dialog("option","title","Edit flow "+subflow.name).dialog( "open" ); $("#subflow-dialog").dialog("option","title","Edit flow "+subflow.name).dialog( "open" );
} }

View File

@ -227,10 +227,24 @@ RED.view = (function() {
var drag_line = vis.append("svg:path").attr("class", "drag_line"); var drag_line = vis.append("svg:path").attr("class", "drag_line");
$("#workspace-edit-subflow").click(function(event) { $("#workspace-subflow-edit").click(function(event) {
showSubflowDialog(activeSubflow.id); showSubflowDialog(activeSubflow.id);
event.preventDefault(); event.preventDefault();
}); });
$("#workspace-subflow-add-input").click(function(event) {
event.preventDefault();
if ($(this).hasClass("disabled")) {
return;
}
addSubflowInput(activeSubflow.id);
});
$("#workspace-subflow-add-output").click(function(event) {
event.preventDefault();
if ($(this).hasClass("disabled")) {
return;
}
addSubflowOutput(activeSubflow.id);
});
var workspace_tabs = RED.tabs.create({ var workspace_tabs = RED.tabs.create({
id: "workspace-tabs", id: "workspace-tabs",
@ -252,7 +266,9 @@ RED.view = (function() {
activeWorkspace = tab.id; activeWorkspace = tab.id;
activeSubflow = RED.nodes.subflow(activeWorkspace); activeSubflow = RED.nodes.subflow(activeWorkspace);
if (activeSubflow) {
$("#workspace-subflow-add-input").toggleClass("disabled",activeSubflow.in.length > 0);
}
if (workspaceScrollPositions[activeWorkspace]) { if (workspaceScrollPositions[activeWorkspace]) {
chart.scrollLeft(workspaceScrollPositions[activeWorkspace].left); chart.scrollLeft(workspaceScrollPositions[activeWorkspace].left);
chart.scrollTop(workspaceScrollPositions[activeWorkspace].top); chart.scrollTop(workspaceScrollPositions[activeWorkspace].top);
@ -853,14 +869,15 @@ RED.view = (function() {
var subflowRemovedInputLinks = []; var subflowRemovedInputLinks = [];
RED.nodes.eachLink(function(l) { RED.nodes.eachLink(function(l) {
if (l.source.type == "subflow" && l.source.z == activeSubflow.id && l.source.i == input.i) { if (l.source.type == "subflow" && l.source.z == activeSubflow.id && l.source.i == input.i) {
subflowRemovedLinks.push(l); subflowRemovedInputLinks.push(l);
} else if (l.target.type == "subflow:"+activeSubflow.id) { } else if (l.target.type == "subflow:"+activeSubflow.id) {
subflowRemovedLinks.push(l); subflowRemovedInputLinks.push(l);
} }
}); });
subflowRemovedInputLinks.forEach(function(l) { RED.nodes.removeLink(l)}); subflowRemovedInputLinks.forEach(function(l) { RED.nodes.removeLink(l)});
removedLinks = removedLinks.concat(subflowRemovedInputLinks); removedLinks = removedLinks.concat(subflowRemovedInputLinks);
activeSubflow.in = []; activeSubflow.in = [];
$("#workspace-subflow-add-input").toggleClass("disabled",false);
} }
RED.nodes.eachNode(function(n) { RED.nodes.eachNode(function(n) {
@ -1817,7 +1834,104 @@ RED.view = (function() {
function showSubflowDialog(id) { function showSubflowDialog(id) {
RED.editor.editSubflow(RED.nodes.subflow(id)); RED.editor.editSubflow(RED.nodes.subflow(id));
}
function findAvailableSubflowIOPosition(subflow) {
var pos = {x:70,y:70};
for (var i=0;i<subflow.out.length+subflow.in.length;i++) {
var port;
if (i < subflow.out.length) {
port = subflow.out[i];
} else {
port = subflow.in[i-subflow.out.length];
}
if (port.x == pos.x && port.y == pos.y) {
pos.x += 55;
i=0;
}
}
return pos;
}
function addSubflowInput(id) {
var subflow = RED.nodes.subflow(id);
var position = findAvailableSubflowIOPosition(subflow);
var newInput = {
type:"subflow",
direction:"in",
z:subflow.id,
i:subflow.in.length,
x:position.x,
y:position.y,
id:RED.nodes.id()
};
var oldInCount = subflow.in.length;
subflow.in.push(newInput);
subflow.dirty = true;
var wasDirty = RED.view.dirty();
var wasChanged = subflow.changed;
subflow.changed = true;
RED.nodes.eachNode(function(n) {
if (n.type == "subflow:"+subflow.id) {
n.changed = true;
n.inputs = subflow.in.length;
RED.editor.updateNodeProperties(n);
}
});
var historyEvent = {
t:'edit',
node:subflow,
dirty:wasDirty,
changed:wasChanged,
subflow: {
inputCount: oldInCount
}
};
RED.history.push(historyEvent);
$("#workspace-subflow-add-input").toggleClass("disabled",true);
updateSelection();
RED.view.redraw();
}
function addSubflowOutput(id) {
var subflow = RED.nodes.subflow(id);
var position = findAvailableSubflowIOPosition(subflow);
var newOutput = {
type:"subflow",
direction:"out",
z:subflow.id,
i:subflow.out.length,
x:position.x,
y:position.y,
id:RED.nodes.id()
};
var oldOutCount = subflow.out.length;
subflow.out.push(newOutput);
subflow.dirty = true;
var wasDirty = RED.view.dirty();
var wasChanged = subflow.changed;
subflow.changed = true;
RED.nodes.eachNode(function(n) {
if (n.type == "subflow:"+subflow.id) {
n.changed = true;
n.outputs = subflow.out.length;
RED.editor.updateNodeProperties(n);
}
});
var historyEvent = {
t:'edit',
node:subflow,
dirty:wasDirty,
changed:wasChanged,
subflow: {
outputCount: oldOutCount
}
};
RED.history.push(historyEvent);
updateSelection();
RED.view.redraw();
} }
$("#node-dialog-rename-workspace form" ).submit(function(e) { e.preventDefault();}); $("#node-dialog-rename-workspace form" ).submit(function(e) { e.preventDefault();});

View File

@ -137,12 +137,18 @@ span.logo img {
background: #f6f6f6; background: #f6f6f6;
vertical-align: middle; vertical-align: middle;
box-shadow: 0 0 2px #888; box-shadow: 0 0 2px #888;
margin-right: 5px;
} }
#workspace-toolbar .button:hover { #workspace-toolbar .button.disabled {
box-shadow: 0 0 2px #bbb;
color: #aaa;
cursor: default;
}
#workspace-toolbar .button:not(.disabled):hover {
background: #e6e6e6; background: #e6e6e6;
box-shadow: 0 0 2px #666; box-shadow: 0 0 2px #666;
} }
#workspace-toolbar .button:active { #workspace-toolbar .button:not(.disabled):active {
background: #e0e0e0; background: #e0e0e0;
box-shadow: 0 0 2px #444; box-shadow: 0 0 2px #444;
} }