diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index 91f45db86..27033fceb 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -34,7 +34,8 @@ RED.view = (function() { lineCurveScale = 0.75, scaleFactor = 1, node_width = 100, - node_height = 30; + node_height = 30, + dblClickInterval = 650; var touchLongPressTimeout = 1000, startTouchDistance = 0, @@ -125,6 +126,7 @@ RED.view = (function() { .attr("height", space_height) .attr("pointer-events", "all") .style("cursor","crosshair") + .style("touch-action","none") .on("mousedown", function() { focusView(); }) @@ -159,8 +161,13 @@ RED.view = (function() { } canvasMouseUp.call(this); }) - .on("touchcancel", function() { d3.event.preventDefault(); canvasMouseUp.call(this); }) + .on("touchcancel", function() { + if (RED.view.DEBUG) { console.warn("eventLayer.touchcancel", mouse_mode); } + d3.event.preventDefault(); + canvasMouseUp.call(this); + }) .on("touchstart", function() { + if (RED.view.DEBUG) { console.warn("eventLayer.touchstart", mouse_mode); } var touch0; if (d3.event.touches.length>1) { clearTimeout(touchStartTime); @@ -211,6 +218,7 @@ RED.view = (function() { d3.event.preventDefault(); return; } + if (RED.view.DEBUG) { console.warn("eventLayer.touchmove", mouse_mode, mousedown_node); } var touch0; if (d3.event.touches.length<2) { if (touchStartTime) { @@ -221,6 +229,12 @@ RED.view = (function() { if (d > 64) { clearTimeout(touchStartTime); touchStartTime = null; + if (!mousedown_node && !mousedown_group) { + mouse_mode = RED.state.PANNING; + mouse_position = [touch0.pageX,touch0.pageY] + scroll_position = [chart.scrollLeft(),chart.scrollTop()]; + } + } } else if (lasso) { d3.event.preventDefault(); @@ -1156,8 +1170,11 @@ RED.view = (function() { //console.log(d3.mouse(this),container.offsetWidth,container.offsetHeight,container.scrollLeft,container.scrollTop); if (mouse_mode === RED.state.PANNING) { - var pos = [d3.event.pageX,d3.event.pageY]; + if (d3.event.touches) { + var touch0 = d3.event.touches.item(0); + pos = [touch0.pageX, touch0.pageY]; + } var deltaPos = [ mouse_position[0]-pos[0], mouse_position[1]-pos[1] @@ -1293,7 +1310,7 @@ RED.view = (function() { mousePos = d3.touches(document.body)[0]; } var d = (mouse_offset[0]-mousePos[0])*(mouse_offset[0]-mousePos[0]) + (mouse_offset[1]-mousePos[1])*(mouse_offset[1]-mousePos[1]); - if (d > 3) { + if ((d > 3 && !dblClickPrimed) || (dblClickPrimed && d > 10)) { mouse_mode = RED.state.MOVING_ACTIVE; clickElapsed = 0; spliceActive = false; @@ -1753,7 +1770,7 @@ RED.view = (function() { } function clearSelection() { - if (RED.view.DEBUG) { console.warn("clearSelection", mouse_mode); } + if (RED.view.DEBUG) { console.warn("clearSelection", mouse_mode,"moving_set.length:",moving_set.length); } for (var i=0;i 0 && clickElapsed < 750) { + if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < dblClickInterval) { mouse_mode = RED.state.DEFAULT; if (d.type != "subflow") { RED.editor.edit(d); @@ -2835,10 +2852,11 @@ RED.view = (function() { var now = Date.now(); clickElapsed = now-clickTime; clickTime = now; - dblClickPrimed = (lastClickNode == mousedown_node && - d3.event.button === 0 && - !d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey); + (d3.event.touches || d3.event.button === 0) && + !d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey && + clickElapsed < dblClickInterval + ) lastClickNode = mousedown_node; var i; @@ -3113,7 +3131,7 @@ RED.view = (function() { } function groupMouseUp(g) { - if (dblClickPrimed && mousedown_group == g && clickElapsed > 0 && clickElapsed < 750) { + if (dblClickPrimed && mousedown_group == g && clickElapsed > 0 && clickElapsed < dblClickInterval) { mouse_mode = RED.state.DEFAULT; RED.editor.editGroup(g); d3.event.stopPropagation(); @@ -3150,8 +3168,9 @@ RED.view = (function() { dblClickPrimed = ( lastClickNode == g && - d3.event.button === 0 && - !d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey + (d3.event.touches || d3.event.button === 0) && + !d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey && + clickElapsed < dblClickInterval ); lastClickNode = g; @@ -3805,9 +3824,11 @@ RED.view = (function() { //thisNode.selectAll(".centerDot").attr({"cx":function(d) { return d.w/2;},"cy":function(d){return d.h/2}}); this.setAttribute("transform", "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"); + // This might be the first redraw after a node has been click-dragged to start a move. + // So its selected state might have changed since the last redraw. + this.classList.toggle("red-ui-flow-node-selected", !!d.selected ) if (mouse_mode != RED.state.MOVING_ACTIVE) { this.classList.toggle("red-ui-flow-node-disabled", d.d === true); - this.classList.toggle("red-ui-flow-node-selected", !!d.selected ) this.__mainRect__.setAttribute("width", d.w) this.__mainRect__.setAttribute("height", d.h) this.__mainRect__.classList.toggle("red-ui-flow-node-highlighted",!!d.highlighted ); @@ -4253,6 +4274,8 @@ RED.view = (function() { .attr("y",-4) selectGroup.on("mousedown", function() {groupMouseDown.call(g[0][0],d)}); selectGroup.on("mouseup", function() {groupMouseUp.call(g[0][0],d)}); + selectGroup.on("touchstart", function() {groupMouseDown.call(g[0][0],d); d3.event.preventDefault();}); + selectGroup.on("touchend", function() {groupMouseUp.call(g[0][0],d); d3.event.preventDefault();}); g.append('rect').classed("red-ui-flow-group-outline",true).attr('rx',0.5).attr('ry',0.5); @@ -4262,6 +4285,9 @@ RED.view = (function() { "stroke": d.stroke||"none", }) g.on("mousedown",groupMouseDown).on("mouseup",groupMouseUp) + g.on("touchstart", function() {groupMouseDown.call(g[0][0],d); d3.event.preventDefault();}); + g.on("touchend", function() {groupMouseUp.call(g[0][0],d); d3.event.preventDefault();}); + g.append('svg:text').attr("class","red-ui-flow-group-label"); d.dirty = true; });