1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Merge pull request #2892 from node-red/view-stack

Add actions to make tab navigation easier
This commit is contained in:
Nick O'Leary 2021-03-31 20:56:15 +01:00 committed by GitHub
commit 8f424c063e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 394 additions and 50 deletions

View File

@ -38,12 +38,14 @@
"backspace": "core:delete-selection", "backspace": "core:delete-selection",
"delete": "core:delete-selection", "delete": "core:delete-selection",
"enter": "core:edit-selected-node", "enter": "core:edit-selected-node",
"ctrl-enter": "core:go-to-selection",
"ctrl-c": "core:copy-selection-to-internal-clipboard", "ctrl-c": "core:copy-selection-to-internal-clipboard",
"ctrl-x": "core:cut-selection-to-internal-clipboard", "ctrl-x": "core:cut-selection-to-internal-clipboard",
"ctrl-v": "core:paste-from-internal-clipboard", "ctrl-v": "core:paste-from-internal-clipboard",
"ctrl-z": "core:undo", "ctrl-z": "core:undo",
"ctrl-y": "core:redo", "ctrl-y": "core:redo",
"ctrl-a": "core:select-all-nodes", "ctrl-a": "core:select-all-nodes",
"escape": "core:select-none",
"alt-s u": "core:select-upstream-nodes", "alt-s u": "core:select-upstream-nodes",
"alt-s d": "core:select-downstream-nodes", "alt-s d": "core:select-downstream-nodes",
"alt-s c": "core:select-connected-nodes", "alt-s c": "core:select-connected-nodes",
@ -56,19 +58,25 @@
"shift-d": "core:step-view-right", "shift-d": "core:step-view-right",
"shift-s": "core:step-view-down", "shift-s": "core:step-view-down",
"shift-a": "core:step-view-left", "shift-a": "core:step-view-left",
"up": "core:move-selection-up", "ctrl-up": "core:move-selection-up",
"right": "core:move-selection-right", "ctrl-right": "core:move-selection-right",
"down": "core:move-selection-down", "ctrl-down": "core:move-selection-down",
"left": "core:move-selection-left", "ctrl-left": "core:move-selection-left",
"shift-up": "core:step-selection-up", "shift-up": "core:step-selection-up",
"shift-right": "core:step-selection-right", "shift-right": "core:step-selection-right",
"shift-down": "core:step-selection-down", "shift-down": "core:step-selection-down",
"shift-left": "core:step-selection-left", "shift-left": "core:step-selection-left",
"ctrl-shift-j": "core:show-previous-tab", "ctrl-[": "core:show-previous-tab",
"ctrl-shift-k": "core:show-next-tab", "ctrl-]": "core:show-next-tab",
"ctrl-shift-left": "core:go-to-previous-location",
"ctrl-shift-right": "core:go-to-next-location",
"ctrl-shift-g": "core:group-selection", "ctrl-shift-g": "core:group-selection",
"ctrl-shift-u": "core:ungroup-selection", "ctrl-shift-u": "core:ungroup-selection",
"ctrl-shift-c": "core:copy-group-style", "ctrl-shift-c": "core:copy-group-style",
"ctrl-shift-v": "core:paste-group-style" "ctrl-shift-v": "core:paste-group-style",
"right": "core:go-to-nearest-node-on-right",
"left": "core:go-to-nearest-node-on-left",
"up": "core:go-to-nearest-node-above",
"down": "core:go-to-nearest-node-below"
} }
} }

View File

@ -249,7 +249,7 @@ var RED = (function() {
RED.nodes.dirty(false); RED.nodes.dirty(false);
RED.view.redraw(true); RED.view.redraw(true);
if (/^#flow\/.+$/.test(currentHash)) { if (/^#flow\/.+$/.test(currentHash)) {
RED.workspaces.show(currentHash.substring(6)); RED.workspaces.show(currentHash.substring(6),true);
} }
} catch(err) { } catch(err) {
console.warn(err); console.warn(err);

View File

@ -151,7 +151,6 @@ RED.actionList = (function() {
} }
if (!visible) { if (!visible) {
previousActiveElement = document.activeElement; previousActiveElement = document.activeElement;
RED.keyboard.add("*","escape",function(){hide()});
$("#red-ui-header-shade").show(); $("#red-ui-header-shade").show();
$("#red-ui-editor-shade").show(); $("#red-ui-editor-shade").show();
$("#red-ui-palette-shade").show(); $("#red-ui-palette-shade").show();
@ -185,7 +184,6 @@ RED.actionList = (function() {
function hide() { function hide() {
if (visible) { if (visible) {
RED.keyboard.remove("escape");
visible = false; visible = false;
$("#red-ui-header-shade").hide(); $("#red-ui-header-shade").hide();
$("#red-ui-editor-shade").hide(); $("#red-ui-editor-shade").hide();
@ -215,6 +213,9 @@ RED.actionList = (function() {
RED.events.on("type-search:open",function() { disabled = true; }); RED.events.on("type-search:open",function() { disabled = true; });
RED.events.on("type-search:close",function() { disabled = false; }); RED.events.on("type-search:close",function() { disabled = false; });
RED.keyboard.add("red-ui-actionList","escape",function(){hide()});
$("#red-ui-header-shade").on('mousedown',hide); $("#red-ui-header-shade").on('mousedown',hide);
$("#red-ui-editor-shade").on('mousedown',hide); $("#red-ui-editor-shade").on('mousedown',hide);
$("#red-ui-palette-shade").on('mousedown',hide); $("#red-ui-palette-shade").on('mousedown',hide);

View File

@ -889,7 +889,6 @@ RED.clipboard = (function() {
function hideDropTarget() { function hideDropTarget() {
$("#red-ui-drop-target").hide(); $("#red-ui-drop-target").hide();
RED.keyboard.remove("escape");
} }
function copyText(value,element,msg) { function copyText(value,element,msg) {
var truncated = false; var truncated = false;
@ -1266,11 +1265,12 @@ RED.clipboard = (function() {
$('<div id="red-ui-drop-target"><div data-i18n="[append]workspace.dropFlowHere"><i class="fa fa-download"></i><br></div></div>').appendTo('#red-ui-editor'); $('<div id="red-ui-drop-target"><div data-i18n="[append]workspace.dropFlowHere"><i class="fa fa-download"></i><br></div></div>').appendTo('#red-ui-editor');
RED.keyboard.add("#red-ui-drop-target", "escape" ,hideDropTarget);
$('#red-ui-workspace-chart').on("dragenter",function(event) { $('#red-ui-workspace-chart').on("dragenter",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 || if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 ||
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { $.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
$("#red-ui-drop-target").css({display:'table'}); $("#red-ui-drop-target").css({display:'table'}).focus();
RED.keyboard.add("*", "escape" ,hideDropTarget);
} }
}); });

View File

@ -44,7 +44,11 @@ RED.keyboard = (function() {
"/":191, "/":191,
"\\":220, "\\":220,
"'":222, "'":222,
"?":191 // <- QWERTY specific "?":191, // <- QWERTY specific
"[": 219,
"]": 221,
"{": 219,// <- QWERTY specific
"}": 221 // <- QWERTY specific
} }
var metaKeyCodes = { var metaKeyCodes = {
16: true, 16: true,

View File

@ -357,7 +357,6 @@ RED.search = (function() {
} }
if (!visible) { if (!visible) {
previousActiveElement = document.activeElement; previousActiveElement = document.activeElement;
RED.keyboard.add("*","escape",function(){hide()});
$("#red-ui-header-shade").show(); $("#red-ui-header-shade").show();
$("#red-ui-editor-shade").show(); $("#red-ui-editor-shade").show();
$("#red-ui-palette-shade").show(); $("#red-ui-palette-shade").show();
@ -377,7 +376,6 @@ RED.search = (function() {
function hide() { function hide() {
if (visible) { if (visible) {
RED.keyboard.remove("escape");
visible = false; visible = false;
$("#red-ui-header-shade").hide(); $("#red-ui-header-shade").hide();
$("#red-ui-editor-shade").hide(); $("#red-ui-editor-shade").hide();
@ -429,7 +427,7 @@ RED.search = (function() {
RED.events.on("actionList:open",function() { disabled = true; }); RED.events.on("actionList:open",function() { disabled = true; });
RED.events.on("actionList:close",function() { disabled = false; }); RED.events.on("actionList:close",function() { disabled = false; });
RED.keyboard.add("red-ui-search","escape",hide);
$("#red-ui-header-shade").on('mousedown',hide); $("#red-ui-header-shade").on('mousedown',hide);
$("#red-ui-editor-shade").on('mousedown',hide); $("#red-ui-editor-shade").on('mousedown',hide);

View File

@ -224,14 +224,14 @@ RED.typeSearch = (function() {
} }
function show(opts) { function show(opts) {
if (!visible) { if (!visible) {
RED.keyboard.add("*","escape",function(){
hide();
if (cancelCallback) {
cancelCallback();
}
});
if (dialog === null) { if (dialog === null) {
createDialog(); createDialog();
RED.keyboard.add("red-ui-type-search","escape",function(){
hide();
if (cancelCallback) {
cancelCallback();
}
});
} }
visible = true; visible = true;
} else { } else {
@ -266,11 +266,10 @@ RED.typeSearch = (function() {
if (!opts.disableFocus) { if (!opts.disableFocus) {
searchInput.trigger("focus"); searchInput.trigger("focus");
} }
},100); },200);
} }
function hide(fast) { function hide(fast) {
if (visible) { if (visible) {
RED.keyboard.remove("escape");
visible = false; visible = false;
if (dialog !== null) { if (dialog !== null) {
searchResultsDiv.slideUp(fast?50:200,function() { searchResultsDiv.slideUp(fast?50:200,function() {

View File

@ -201,6 +201,237 @@ RED.view.tools = (function() {
} }
function selectFirstNode() {
var canidates;
var origin = {x:0, y:0};
var activeGroup = RED.view.getActiveGroup();
if (!activeGroup) {
candidates = RED.view.getActiveNodes();
} else {
candidates = RED.group.getNodes(activeGroup,false);
origin = activeGroup;
}
var distances = [];
candidates.forEach(function(node) {
var deltaX = node.x - origin.x;
var deltaY = node.y - origin.x;
var delta = deltaY*deltaY + deltaX*deltaX;
distances.push({node: node, delta: delta})
});
if (distances.length > 0) {
distances.sort(function(A,B) {
return A.delta - B.delta
})
var newNode = distances[0].node;
if (newNode) {
RED.view.select({nodes:[newNode]});
RED.view.reveal(newNode.id,false);
}
}
}
function gotoNextNode() {
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length === 1) {
var origin = selection.nodes[0];
var links = RED.nodes.filterLinks({source:origin});
if (links.length > 0) {
links.sort(function(A,B) {
return Math.abs(A.target.y - origin.y) - Math.abs(B.target.y - origin.y)
})
var newNode = links[0].target;
if (newNode) {
RED.view.select({nodes:[newNode]});
RED.view.reveal(newNode.id,false);
}
}
} else if (RED.workspaces.selection().length === 0) {
selectFirstNode();
}
}
function gotoPreviousNode() {
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length === 1) {
var origin = selection.nodes[0];
var links = RED.nodes.filterLinks({target:origin});
if (links.length > 0) {
links.sort(function(A,B) {
return Math.abs(A.source.y - origin.y) - Math.abs(B.source.y - origin.y)
})
var newNode = links[0].source;
if (newNode) {
RED.view.select({nodes:[newNode]});
RED.view.reveal(newNode.id,false);
}
}
} else if (RED.workspaces.selection().length === 0) {
selectFirstNode();
}
}
function getChildren(node) {
return RED.nodes.filterLinks({source:node}).map(function(l) { return l.target})
}
function getParents(node) {
return RED.nodes.filterLinks({target:node}).map(function(l) { return l.source})
}
function getSiblings(node) {
var siblings = new Set();
var parents = getParents(node);
parents.forEach(function(p) {
getChildren(p).forEach(function(c) { siblings.add(c) })
});
var children = getChildren(node);
children.forEach(function(p) {
getParents(p).forEach(function(c) { siblings.add(c) })
});
siblings.delete(node);
return Array.from(siblings);
}
function gotoNextSibling() {
// 'next' defined as nearest on the y-axis below this node
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length === 1) {
var origin = selection.nodes[0];
var siblings = getSiblings(origin);
if (siblings.length > 0) {
siblings = siblings.filter(function(n) { return n.y > origin. y})
siblings.sort(function(A,B) {
return Math.abs(A.y - origin.y) - Math.abs(B.y - origin.y)
})
var newNode = siblings[0];
if (newNode) {
RED.view.select({nodes:[newNode]});
RED.view.reveal(newNode.id,false);
}
}
} else if (RED.workspaces.selection().length === 0) {
selectFirstNode();
}
}
function gotoPreviousSibling() {
// 'next' defined as nearest on the y-axis above this node
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length === 1) {
var origin = selection.nodes[0];
var siblings = getSiblings(origin);
if (siblings.length > 0) {
siblings = siblings.filter(function(n) { return n.y < origin. y})
siblings.sort(function(A,B) {
return Math.abs(A.y - origin.y) - Math.abs(B.y - origin.y)
})
var newNode = siblings[0];
if (newNode) {
RED.view.select({nodes:[newNode]});
RED.view.reveal(newNode.id,false);
}
}
} else if (RED.workspaces.selection().length === 0) {
selectFirstNode();
}
}
function addNode() {
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length === 1 && selection.nodes[0].outputs > 0) {
var selectedNode = selection.nodes[0];
RED.view.showQuickAddDialog([
selectedNode.x + selectedNode.w + 50,selectedNode.y
])
} else {
RED.view.showQuickAddDialog();
}
}
function gotoNearestNode(direction) {
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length === 1) {
var origin = selection.nodes[0];
var candidates = RED.nodes.filterNodes({z:origin.z});
candidates = candidates.concat(RED.view.getSubflowPorts());
var distances = [];
candidates.forEach(function(node) {
if (node === origin) {
return;
}
var deltaX = node.x - origin.x;
var deltaY = node.y - origin.y;
var delta = deltaY*deltaY + deltaX*deltaX;
var angle = (180/Math.PI)*Math.atan2(deltaY,deltaX);
if (angle < 0) { angle += 360 }
if (angle > 360) { angle -= 360 }
var weight;
// 0 - right
// 270 - above
// 90 - below
// 180 - left
switch(direction) {
case 'up': if (angle < 210 || angle > 330) { return };
weight = Math.max(Math.abs(270 - angle)/60, 0.2);
break;
case 'down': if (angle < 30 || angle > 150) { return };
weight = Math.max(Math.abs(90 - angle)/60, 0.2);
break;
case 'left': if (angle < 140 || angle > 220) { return };
weight = Math.max(Math.abs(180 - angle)/40, 0.1 );
break;
case 'right': if (angle > 40 && angle < 320) { return };
weight = Math.max(Math.abs(angle)/40, 0.1);
break;
}
weight = Math.max(weight,0.1);
distances.push({
node: node,
d: delta,
w: weight,
delta: delta*weight
})
})
if (distances.length > 0) {
distances.sort(function(A,B) {
return A.delta - B.delta
})
var newNode = distances[0].node;
if (newNode) {
RED.view.select({nodes:[newNode]});
RED.view.reveal(newNode.id,false);
}
}
} else if (RED.workspaces.selection().length === 0) {
var candidates = RED.view.getActiveNodes();
var distances = [];
candidates.forEach(function(node) {
var deltaX = node.x;
var deltaY = node.y;
var delta = deltaY*deltaY + deltaX*deltaX;
distances.push({node: node, delta: delta})
});
if (distances.length > 0) {
distances.sort(function(A,B) {
return A.delta - B.delta
})
var newNode = distances[0].node;
if (newNode) {
RED.view.select({nodes:[newNode]});
RED.view.reveal(newNode.id,false);
}
}
}
}
return { return {
init: function() { init: function() {
RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); }) RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); })
@ -231,6 +462,19 @@ RED.view.tools = (function() {
RED.actions.add("core:select-connected-nodes", function() { selectConnected("all") }); RED.actions.add("core:select-connected-nodes", function() { selectConnected("all") });
RED.actions.add("core:select-downstream-nodes", function() { selectConnected("down") }); RED.actions.add("core:select-downstream-nodes", function() { selectConnected("down") });
RED.actions.add("core:select-upstream-nodes", function() { selectConnected("up") }); RED.actions.add("core:select-upstream-nodes", function() { selectConnected("up") });
RED.actions.add("core:go-to-next-node", function() { gotoNextNode() })
RED.actions.add("core:go-to-previous-node", function() { gotoPreviousNode() })
RED.actions.add("core:go-to-next-sibling", function() { gotoNextSibling() })
RED.actions.add("core:go-to-previous-sibling", function() { gotoPreviousSibling() })
RED.actions.add("core:go-to-nearest-node-on-left", function() { gotoNearestNode('left')})
RED.actions.add("core:go-to-nearest-node-on-right", function() { gotoNearestNode('right')})
RED.actions.add("core:go-to-nearest-node-above", function() { gotoNearestNode('up') })
RED.actions.add("core:go-to-nearest-node-below", function() { gotoNearestNode('down') })
// RED.actions.add("core:add-node", function() { addNode() })
}, },
/** /**
* Aligns all selected nodes to the current grid * Aligns all selected nodes to the current grid

View File

@ -86,7 +86,7 @@ RED.view = (function() {
var quickAddLink = null; var quickAddLink = null;
var showAllLinkPorts = -1; var showAllLinkPorts = -1;
var groupNodeSelectPrimed = false; var groupNodeSelectPrimed = false;
var lastClickPosition = [];
var selectNodesOptions; var selectNodesOptions;
var clipboard = ""; var clipboard = "";
@ -503,9 +503,21 @@ RED.view = (function() {
RED.actions.add("core:paste-from-internal-clipboard",function(){importNodes(clipboard,{generateIds: true});}); RED.actions.add("core:paste-from-internal-clipboard",function(){importNodes(clipboard,{generateIds: true});});
RED.actions.add("core:delete-selection",deleteSelection); RED.actions.add("core:delete-selection",deleteSelection);
RED.actions.add("core:edit-selected-node",editSelection); RED.actions.add("core:edit-selected-node",editSelection);
RED.actions.add("core:go-to-selection",function() {
if (movingSet.length() > 0) {
var node = movingSet.get(0).n;
if (/^subflow:/.test(node.type)) {
RED.workspaces.show(node.type.substring(8))
} else if (node.type === 'group') {
enterActiveGroup(node);
redraw();
}
}
});
RED.actions.add("core:undo",RED.history.pop); RED.actions.add("core:undo",RED.history.pop);
RED.actions.add("core:redo",RED.history.redo); RED.actions.add("core:redo",RED.history.redo);
RED.actions.add("core:select-all-nodes",selectAll); RED.actions.add("core:select-all-nodes",selectAll);
RED.actions.add("core:select-none", selectNone);
RED.actions.add("core:zoom-in",zoomIn); RED.actions.add("core:zoom-in",zoomIn);
RED.actions.add("core:zoom-out",zoomOut); RED.actions.add("core:zoom-out",zoomOut);
RED.actions.add("core:zoom-reset",zoomZero); RED.actions.add("core:zoom-reset",zoomZero);
@ -848,7 +860,7 @@ RED.view = (function() {
if (drag_lines.length > 0) { if (drag_lines.length > 0) {
clickedGroup = clickedGroup || RED.nodes.group(drag_lines[0].node.g) clickedGroup = clickedGroup || RED.nodes.group(drag_lines[0].node.g)
} }
showQuickAddDialog(point, null, clickedGroup); showQuickAddDialog({position:point, group:clickedGroup});
} }
} }
if (mouse_mode === 0 && !(d3.event.metaKey || d3.event.ctrlKey)) { if (mouse_mode === 0 && !(d3.event.metaKey || d3.event.ctrlKey)) {
@ -869,7 +881,13 @@ RED.view = (function() {
} }
} }
function showQuickAddDialog(point, spliceLink, targetGroup, touchTrigger) { function showQuickAddDialog(options) {
options = options || {};
var point = options.position || lastClickPosition;
var spliceLink = options.splice;
var targetGroup = options.group;
var touchTrigger = options.touchTrigger;
if (targetGroup && !targetGroup.active) { if (targetGroup && !targetGroup.active) {
selectGroup(targetGroup,false); selectGroup(targetGroup,false);
enterActiveGroup(targetGroup); enterActiveGroup(targetGroup);
@ -1522,6 +1540,7 @@ RED.view = (function() {
} }
function canvasMouseUp() { function canvasMouseUp() {
lastClickPosition = [d3.event.offsetX/scaleFactor,d3.event.offsetY/scaleFactor];
if (RED.view.DEBUG) { console.warn("canvasMouseUp", mouse_mode); } if (RED.view.DEBUG) { console.warn("canvasMouseUp", mouse_mode); }
var i; var i;
var historyEvent; var historyEvent;
@ -1591,7 +1610,6 @@ RED.view = (function() {
if (n.x > x && n.x < x2 && n.y > y && n.y < y2) { if (n.x > x && n.x < x2 && n.y > y && n.y < y2) {
if (!activeGroup || RED.group.contains(activeGroup,n)) { if (!activeGroup || RED.group.contains(activeGroup,n)) {
if (n.g && (!activeGroup || n.g !== activeGroup.id)) { if (n.g && (!activeGroup || n.g !== activeGroup.id)) {
console.log("HERE")
var group = RED.nodes.group(n.g); var group = RED.nodes.group(n.g);
while (group.g && (!activeGroup || group.g !== activeGroup.id)) { while (group.g && (!activeGroup || group.g !== activeGroup.id)) {
group = RED.nodes.group(group.g); group = RED.nodes.group(group.g);
@ -1767,7 +1785,18 @@ RED.view = (function() {
redraw(); redraw();
} }
function selectNone() {
if (mouse_mode === RED.state.IMPORT_DRAGGING) {
clearSelection();
RED.history.pop();
mouse_mode = 0;
} else if (activeGroup) {
exitActiveGroup()
} else {
clearSelection();
}
redraw();
}
function selectAll() { function selectAll() {
if (mouse_mode === RED.state.SELECTING_NODE && selectNodesOptions.single) { if (mouse_mode === RED.state.SELECTING_NODE && selectNodesOptions.single) {
return; return;
@ -2809,7 +2838,11 @@ RED.view = (function() {
if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < dblClickInterval) { if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < dblClickInterval) {
mouse_mode = RED.state.DEFAULT; mouse_mode = RED.state.DEFAULT;
if (d.type != "subflow") { if (d.type != "subflow") {
RED.editor.edit(d); if (/^subflow:/.test(d.type) && (d3.event.ctrlKey || d3.event.metaKey)) {
RED.workspaces.show(d.type.substring(8));
} else {
RED.editor.edit(d);
}
} else { } else {
RED.editor.editSubflow(activeSubflow); RED.editor.editSubflow(activeSubflow);
} }
@ -2874,7 +2907,6 @@ RED.view = (function() {
//var pos = [touch0.pageX,touch0.pageY]; //var pos = [touch0.pageX,touch0.pageY];
//RED.touch.radialMenu.show(d3.select(this),pos); //RED.touch.radialMenu.show(d3.select(this),pos);
if (mouse_mode == RED.state.IMPORT_DRAGGING) { if (mouse_mode == RED.state.IMPORT_DRAGGING) {
RED.keyboard.remove("escape");
var historyEvent = RED.history.peek(); var historyEvent = RED.history.peek();
if (activeSpliceLink) { if (activeSpliceLink) {
// TODO: DRY - droppable/nodeMouseDown/canvasMouseUp // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp
@ -2952,7 +2984,7 @@ RED.view = (function() {
clickTime = now; clickTime = now;
dblClickPrimed = (lastClickNode == mousedown_node && dblClickPrimed = (lastClickNode == mousedown_node &&
(d3.event.touches || d3.event.button === 0) && (d3.event.touches || d3.event.button === 0) &&
!d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey && !d3.event.shiftKey && !d3.event.altKey &&
clickElapsed < dblClickInterval clickElapsed < dblClickInterval
) )
lastClickNode = mousedown_node; lastClickNode = mousedown_node;
@ -3081,7 +3113,7 @@ RED.view = (function() {
// } else // } else
if (d3.event.shiftKey) { if (d3.event.shiftKey) {
clearSelection(); clearSelection();
var clickPosition = (d3.event.offsetX - mousedown_node.x) var clickPosition = (d3.event.offsetX/scaleFactor - mousedown_node.x)
var edgeDelta = (mousedown_node.w/2) - Math.abs(clickPosition); var edgeDelta = (mousedown_node.w/2) - Math.abs(clickPosition);
var cnodes; var cnodes;
var targetEdgeDelta = mousedown_node.w > 30 ? 25 : 8; var targetEdgeDelta = mousedown_node.w > 30 ? 25 : 8;
@ -3245,7 +3277,7 @@ RED.view = (function() {
d3.select(this).classed("red-ui-flow-link-splice",true); d3.select(this).classed("red-ui-flow-link-splice",true);
var point = d3.mouse(this); var point = d3.mouse(this);
var clickedGroup = getGroupAt(point[0],point[1]); var clickedGroup = getGroupAt(point[0],point[1]);
showQuickAddDialog(point, selected_link, clickedGroup); showQuickAddDialog({position:point, splice:selected_link, group:clickedGroup});
} }
} }
function linkTouchStart(d) { function linkTouchStart(d) {
@ -3291,9 +3323,8 @@ RED.view = (function() {
if (d3.event.button === 1) { if (d3.event.button === 1) {
return; return;
} }
if (mouse_mode == RED.state.IMPORT_DRAGGING) {
RED.keyboard.remove("escape"); if (mouse_mode == RED.state.QUICK_JOINING) {
} else if (mouse_mode == RED.state.QUICK_JOINING) {
d3.event.stopPropagation(); d3.event.stopPropagation();
return; return;
} else if (mouse_mode === RED.state.SELECTING_NODE) { } else if (mouse_mode === RED.state.SELECTING_NODE) {
@ -3500,7 +3531,10 @@ RED.view = (function() {
options.push({name:"undo",disabled:(RED.history.depth() === 0),onselect:function() {RED.history.pop();}}); options.push({name:"undo",disabled:(RED.history.depth() === 0),onselect:function() {RED.history.pop();}});
options.push({name:"add",onselect:function() { options.push({name:"add",onselect:function() {
chartPos = chart.offset(); chartPos = chart.offset();
showQuickAddDialog([pos[0]-chartPos.left+chart.scrollLeft(),pos[1]-chartPos.top+chart.scrollTop()],undefined,undefined,true) showQuickAddDialog({
position:[pos[0]-chartPos.left+chart.scrollLeft(),pos[1]-chartPos.top+chart.scrollTop()],
touchTrigger:true
})
}}); }});
RED.touch.radialMenu.show(obj,pos,options); RED.touch.radialMenu.show(obj,pos,options);
@ -4792,12 +4826,7 @@ RED.view = (function() {
} }
} }
RED.keyboard.add("*","escape",function(){
RED.keyboard.remove("escape");
clearSelection();
RED.history.pop();
mouse_mode = 0;
});
} }
var historyEvent = { var historyEvent = {
@ -5125,6 +5154,18 @@ RED.view = (function() {
getActiveNodes: function() { getActiveNodes: function() {
return activeNodes; return activeNodes;
}, },
getSubflowPorts: function() {
var result = [];
if (activeSubflow) {
var subflowOutputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-output").data(activeSubflow.out,function(d,i){ return d.id;});
subflowOutputs.each(function(d,i) { result.push(d) })
var subflowInputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-input").data(activeSubflow.in,function(d,i){ return d.id;});
subflowInputs.each(function(d,i) { result.push(d) })
var subflowStatus = nodeLayer.selectAll(".red-ui-flow-subflow-port-status").data(activeSubflow.status?[activeSubflow.status]:[],function(d,i){ return d.id;});
subflowStatus.each(function(d,i) { result.push(d) })
}
return result;
},
selectNodes: function(options) { selectNodes: function(options) {
$("#red-ui-workspace-tabs-shade").show(); $("#red-ui-workspace-tabs-shade").show();
$("#red-ui-palette-shade").show(); $("#red-ui-palette-shade").show();
@ -5200,6 +5241,7 @@ RED.view = (function() {
clipboard: function() { clipboard: function() {
return clipboard return clipboard
}, },
redrawStatus: redrawStatus redrawStatus: redrawStatus,
showQuickAddDialog:showQuickAddDialog
}; };
})(); })();

View File

@ -20,6 +20,19 @@ RED.workspaces = (function() {
var activeWorkspace = 0; var activeWorkspace = 0;
var workspaceIndex = 0; var workspaceIndex = 0;
var viewStack = [];
var viewStackPos = 0;
function addToViewStack(id) {
if (viewStackPos !== viewStack.length) {
viewStack.splice(viewStackPos);
}
viewStack.push(id);
viewStackPos = viewStack.length;
// console.warn("addToViewStack",id,viewStack);
}
function addWorkspace(ws,skipHistoryEntry,targetIndex) { function addWorkspace(ws,skipHistoryEntry,targetIndex) {
if (ws) { if (ws) {
workspace_tabs.addTab(ws,targetIndex); workspace_tabs.addTab(ws,targetIndex);
@ -245,6 +258,9 @@ RED.workspaces = (function() {
RED.view.focus(); RED.view.focus();
}, },
onclick: function(tab) { onclick: function(tab) {
if (tab.id !== activeWorkspace) {
addToViewStack(activeWorkspace);
}
RED.view.focus(); RED.view.focus();
}, },
ondblclick: function(tab) { ondblclick: function(tab) {
@ -328,8 +344,20 @@ RED.workspaces = (function() {
createWorkspaceTabs(); createWorkspaceTabs();
RED.events.on("sidebar:resize",workspace_tabs.resize); RED.events.on("sidebar:resize",workspace_tabs.resize);
RED.actions.add("core:show-next-tab",workspace_tabs.nextTab); RED.actions.add("core:show-next-tab",function() {
RED.actions.add("core:show-previous-tab",workspace_tabs.previousTab); var oldActive = activeWorkspace;
workspace_tabs.nextTab();
if (oldActive !== activeWorkspace) {
addToViewStack(oldActive)
}
});
RED.actions.add("core:show-previous-tab",function() {
var oldActive = activeWorkspace;
workspace_tabs.previousTab();
if (oldActive !== activeWorkspace) {
addToViewStack(oldActive)
}
});
RED.menu.setAction('menu-item-workspace-delete',function() { RED.menu.setAction('menu-item-workspace-delete',function() {
deleteWorkspace(RED.nodes.workspace(activeWorkspace)); deleteWorkspace(RED.nodes.workspace(activeWorkspace));
@ -349,6 +377,23 @@ RED.workspaces = (function() {
RED.actions.invoke("core:search","type:tab "); RED.actions.invoke("core:search","type:tab ");
}) })
RED.actions.add("core:go-to-previous-location", function() {
if (viewStackPos > 0) {
if (viewStackPos === viewStack.length) {
// We're at the end of the stack. Remember the activeWorkspace
// so we can come back to it.
viewStack.push(activeWorkspace);
}
RED.workspaces.show(viewStack[--viewStackPos],true);
}
})
RED.actions.add("core:go-to-next-location", function() {
if (viewStackPos < viewStack.length - 1) {
RED.workspaces.show(viewStack[++viewStackPos],true);
}
})
hideWorkspace(); hideWorkspace();
} }
@ -444,7 +489,7 @@ RED.workspaces = (function() {
selection: function() { selection: function() {
return workspace_tabs.selection(); return workspace_tabs.selection();
}, },
show: function(id) { show: function(id,skipStack) {
if (!workspace_tabs.contains(id)) { if (!workspace_tabs.contains(id)) {
var sf = RED.nodes.subflow(id); var sf = RED.nodes.subflow(id);
if (sf) { if (sf) {
@ -453,6 +498,9 @@ RED.workspaces = (function() {
return; return;
} }
} }
if (!skipStack && activeWorkspace !== id) {
addToViewStack(activeWorkspace)
}
workspace_tabs.activateTab(id); workspace_tabs.activateTab(id);
}, },
refresh: function() { refresh: function() {