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

fix touch mode wire linking

This commit is contained in:
Steve-Mcl 2023-07-10 10:24:28 +01:00
parent 8fa1d4def5
commit bd589aa140
2 changed files with 105 additions and 46 deletions

View File

@ -1305,6 +1305,39 @@ RED.view.tools = (function() {
} }
} }
/**
* Determine if a point is within a node
* @param {*} node - A Node or Junction node
* @param {[Number,Number]} mouse_position The x,y position of the mouse
* @param {Number} [marginX=0] - A margin to add or deduct from the x position (to increase the hit area)
* @param {Number} [marginY=0] - A margin to add or deduct from the y position (to increase the hit area)
* @returns
*/
function isPointInNode (node, [x, y], marginX, marginY) {
marginX = marginX || 0
marginY = marginY || 0
let w = node.w || 10 // junctions dont have any w or h value
let h = node.h || 10
let x1, x2, y1, y2
if (node.type === "junction" || node.type === "group") {
// x/y is the top left of the node
x1 = node.x
y1 = node.y
x2 = node.x + w
y2 = node.y + h
} else {
// x/y is the center of the node
const [xMid, yMid] = [w/2, h/2]
x1 = node.x - xMid
y1 = node.y - yMid
x2 = node.x + xMid
y2 = node.y + yMid
}
return (x >= (x1 - marginX) && x <= (x2 + marginX) && y >= (y1 - marginY) && y <= (y2 + marginY))
}
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); })
@ -1387,7 +1420,8 @@ RED.view.tools = (function() {
* @param {Number} dy * @param {Number} dy
*/ */
moveSelection: moveSelection, moveSelection: moveSelection,
calculateGridSnapOffsets: calculateGridSnapOffsets calculateGridSnapOffsets: calculateGridSnapOffsets,
isPointInNode: isPointInNode
} }
})(); })();

View File

@ -101,7 +101,7 @@ RED.view = (function() {
// Note: these are the permitted status colour aliases. The actual RGB values // Note: these are the permitted status colour aliases. The actual RGB values
// are set in the CSS - flow.scss/colors.scss // are set in the CSS - flow.scss/colors.scss
var status_colours = { const status_colours = {
"red": "#c00", "red": "#c00",
"green": "#5a8", "green": "#5a8",
"yellow": "#F9DF31", "yellow": "#F9DF31",
@ -110,19 +110,32 @@ RED.view = (function() {
"gray": "#d3d3d3" "gray": "#d3d3d3"
} }
var PORT_TYPE_INPUT = 1; const PORT_TYPE_INPUT = 1;
var PORT_TYPE_OUTPUT = 0; const PORT_TYPE_OUTPUT = 0;
var chart; /**
var outer; * The jQuery object for the workspace chart `#red-ui-workspace-chart` div element
* @type {JQuery<HTMLElement>} #red-ui-workspace-chart HTML Element
*/
let chart;
/**
* The d3 object `#red-ui-workspace-chart` svg element
* @type {d3.Selection<HTMLElement, Any, Any, Any>}
*/
let outer;
/**
* The d3 object `#red-ui-workspace-chart` svg element (specifically for events)
* @type {d3.Selection<d3.BaseType, any, any, any>}
*/
var eventLayer; var eventLayer;
var gridLayer;
var linkLayer; /** @type {SVGGElement} */ let gridLayer;
var junctionLayer; /** @type {SVGGElement} */ let linkLayer;
var dragGroupLayer; /** @type {SVGGElement} */ let junctionLayer;
var groupSelectLayer; /** @type {SVGGElement} */ let dragGroupLayer;
var nodeLayer; /** @type {SVGGElement} */ let groupSelectLayer;
var groupLayer; /** @type {SVGGElement} */ let nodeLayer;
/** @type {SVGGElement} */ let groupLayer;
var drag_lines; var drag_lines;
const movingSet = (function() { const movingSet = (function() {
@ -391,16 +404,6 @@ RED.view = (function() {
touchStartTime = setTimeout(function() { touchStartTime = setTimeout(function() {
touchStartTime = null; touchStartTime = null;
showTouchMenu(obj,pos); showTouchMenu(obj,pos);
//lasso = eventLayer.append("rect")
// .attr("ox",point[0])
// .attr("oy",point[1])
// .attr("rx",2)
// .attr("ry",2)
// .attr("x",point[0])
// .attr("y",point[1])
// .attr("width",0)
// .attr("height",0)
// .attr("class","nr-ui-view-lasso");
},touchLongPressTimeout); },touchLongPressTimeout);
} }
d3.event.preventDefault(); d3.event.preventDefault();
@ -3094,22 +3097,38 @@ RED.view = (function() {
} }
} }
document.body.style.cursor = ""; document.body.style.cursor = "";
if (mouse_mode == RED.state.JOINING || mouse_mode == RED.state.QUICK_JOINING) { if (mouse_mode == RED.state.JOINING || mouse_mode == RED.state.QUICK_JOINING) {
if (typeof TouchEvent != "undefined" && evt instanceof TouchEvent) { if (typeof TouchEvent != "undefined" && evt instanceof TouchEvent) {
var found = false; if (RED.view.DEBUG) { console.warn("portMouseUp: TouchEvent", mouse_mode,d,portType,portIndex); }
RED.nodes.eachNode(function(n) { const direction = drag_lines[0].portType === PORT_TYPE_INPUT ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT
if (n.z == RED.workspaces.active()) { let found = false;
var hw = n.w/2; for (let nodeIdx = 0; nodeIdx < activeNodes.length; nodeIdx++) {
var hh = n.h/2; const n = activeNodes[nodeIdx];
if (n.x-hw<mouse_position[0] && n.x+hw> mouse_position[0] && if (RED.view.tools.isPointInNode(n, mouse_position)) {
n.y-hh<mouse_position[1] && n.y+hh>mouse_position[1]) { found = true;
found = true; mouseup_node = n;
mouseup_node = n; // portType = mouseup_node.inputs > 0 ? PORT_TYPE_INPUT : PORT_TYPE_OUTPUT;
portType = mouseup_node.inputs>0?PORT_TYPE_INPUT:PORT_TYPE_OUTPUT; portType = direction;
portIndex = 0; portIndex = 0;
break
}
}
if (!found && drag_lines.length > 0 && !drag_lines[0].virtualLink) {
for (let juncIdx = 0; juncIdx < activeJunctions.length; juncIdx++) {
// NOTE: a junction is 10px x 10px but the target area is expanded to 30wx20h by adding padding to the bounding box
const jNode = activeJunctions[juncIdx];
if (RED.view.tools.isPointInNode(jNode, mouse_position, 20, 10)) {
found = true;
mouseup_node = jNode;
portType = direction;
portIndex = 0;
break
} }
} }
}); }
if (!found && activeSubflow) { if (!found && activeSubflow) {
var subflowPorts = []; var subflowPorts = [];
if (activeSubflow.status) { if (activeSubflow.status) {
@ -3121,16 +3140,13 @@ RED.view = (function() {
if (activeSubflow.out) { if (activeSubflow.out) {
subflowPorts = subflowPorts.concat(activeSubflow.out) subflowPorts = subflowPorts.concat(activeSubflow.out)
} }
for (var i=0;i<subflowPorts.length;i++) { for (var i = 0; i < subflowPorts.length; i++) {
var n = subflowPorts[i]; const sf = subflowPorts[i];
var hw = n.w/2; if (RED.view.tools.isPointInNode(sf, mouse_position)) {
var hh = n.h/2; found = true;
if (n.x-hw<mouse_position[0] && n.x+hw> mouse_position[0] && mouseup_node = sf;
n.y-hh<mouse_position[1] && n.y+hh>mouse_position[1]) { portType = mouseup_node.direction === "in" ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT;
found = true; portIndex = 0;
mouseup_node = n;
portType = mouseup_node.direction === "in"?PORT_TYPE_OUTPUT:PORT_TYPE_INPUT;
portIndex = 0;
break; break;
} }
} }
@ -5015,16 +5031,25 @@ RED.view = (function() {
contents.appendChild(junctionOutput); contents.appendChild(junctionOutput);
junctionOutput.addEventListener("mouseup", portMouseUpProxy); junctionOutput.addEventListener("mouseup", portMouseUpProxy);
junctionOutput.addEventListener("mousedown", portMouseDownProxy); junctionOutput.addEventListener("mousedown", portMouseDownProxy);
junctionOutput.addEventListener("mouseover", junctionMouseOverProxy); junctionOutput.addEventListener("mouseover", junctionMouseOverProxy);
junctionOutput.addEventListener("mouseout", junctionMouseOutProxy); junctionOutput.addEventListener("mouseout", junctionMouseOutProxy);
junctionOutput.addEventListener("touchmove", junctionMouseOverProxy);
junctionOutput.addEventListener("touchend", portMouseUpProxy);
junctionOutput.addEventListener("touchstart", portMouseDownProxy);
junctionInput.addEventListener("mouseover", junctionMouseOverProxy); junctionInput.addEventListener("mouseover", junctionMouseOverProxy);
junctionInput.addEventListener("mouseout", junctionMouseOutProxy); junctionInput.addEventListener("mouseout", junctionMouseOutProxy);
junctionInput.addEventListener("touchmove", junctionMouseOverProxy);
junctionInput.addEventListener("touchend", portMouseUpProxy);
junctionInput.addEventListener("touchstart", portMouseDownProxy);
junctionBack.addEventListener("mouseover", junctionMouseOverProxy); junctionBack.addEventListener("mouseover", junctionMouseOverProxy);
junctionBack.addEventListener("mouseout", junctionMouseOutProxy); junctionBack.addEventListener("mouseout", junctionMouseOutProxy);
junctionBack.addEventListener("touchmove", junctionMouseOverProxy);
// These handlers expect to be registered as d3 events // These handlers expect to be registered as d3 events
d3.select(junctionBack).on("mousedown", nodeMouseDown).on("mouseup", nodeMouseUp); d3.select(junctionBack).on("mousedown", nodeMouseDown).on("mouseup", nodeMouseUp);
d3.select(junctionBack).on("touchstart", nodeMouseDown).on("touchend", nodeMouseUp);
junction[0][0].appendChild(contents); junction[0][0].appendChild(contents);
}) })