| /** | |
|  * Created by Alex on 2/27/2015. | |
|  * | |
|  */ | |
| 
 | |
| import {SelectionHandler} from "./components/SelectionHandler" | |
| var util = require('../../util'); | |
| 
 | |
| class TouchEventHandler { | |
|   constructor(body) { | |
|     this.body = body; | |
| 
 | |
|     this.body.eventListeners.onTap        = this.onTap.bind(this); | |
|     this.body.eventListeners.onTouch      = this.onTouch.bind(this); | |
|     this.body.eventListeners.onDoubleTap  = this.onDoubleTap.bind(this); | |
|     this.body.eventListeners.onHold       = this.onHold.bind(this); | |
|     this.body.eventListeners.onDragStart  = this.onDragStart.bind(this); | |
|     this.body.eventListeners.onDrag       = this.onDrag.bind(this); | |
|     this.body.eventListeners.onDragEnd    = this.onDragEnd.bind(this); | |
|     this.body.eventListeners.onMouseWheel = this.onMouseWheel.bind(this); | |
|     this.body.eventListeners.onPinch      = this.onPinch.bind(this); | |
|     this.body.eventListeners.onMouseMove  = this.onMouseMove.bind(this); | |
|     this.body.eventListeners.onRelease    = this.onRelease.bind(this); | |
| 
 | |
|     this.touchTime = 0; | |
|     this.drag = {}; | |
|     this.pinch = {}; | |
|     this.pointerPosition = {x:0,y:0}; | |
| 
 | |
|     this.scale = 1.0; | |
|     this.body.emitter.on("_setScale", (scale) => this.scale = scale); | |
| 
 | |
|     this.selectionHandler = new SelectionHandler(body); | |
|   } | |
| 
 | |
|   setCanvas(canvas) { | |
|     this.canvas = canvas; | |
|     this.selectionHandler.setCanvas(canvas); | |
|   } | |
| 
 | |
|   /** | |
|    * Get the pointer location from a touch location | |
|    * @param {{pageX: Number, pageY: Number}} touch | |
|    * @return {{x: Number, y: Number}} pointer | |
|    * @private | |
|    */ | |
|   getPointer(touch) { | |
|     return { | |
|       x: touch.pageX - util.getAbsoluteLeft(this.canvas.frame.canvas), | |
|       y: touch.pageY - util.getAbsoluteTop(this.canvas.frame.canvas) | |
|     }; | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * On start of a touch gesture, store the pointer | |
|    * @param event | |
|    * @private | |
|    */ | |
|   onTouch(event) { | |
|     if (new Date().valueOf() - this.touchTime > 100) { | |
|       this.drag.pointer = this.getPointer(event.gesture.center); | |
|       this.drag.pinched = false; | |
|       this.pinch.scale = this.scale; | |
| 
 | |
|       // to avoid double fireing of this event because we have two hammer instances. (on canvas and on frame) | |
|       this.touchTime = new Date().valueOf(); | |
|     } | |
|   } | |
| 
 | |
|   /** | |
|    * handle tap/click event: select/unselect a node | |
|    * @private | |
|    */ | |
|   onTap(event) { | |
|     console.log("tap",event) | |
|     var pointer = this.getPointer(event.gesture.center); | |
|     this.pointerPosition = pointer; | |
|     this.selectionHandler.selectOnPoint(pointer); | |
|   } | |
| 
 | |
|   /** | |
|    * handle drag start event | |
|    * @private | |
|    */ | |
| 
 | |
|   /** | |
|    * This function is called by onDragStart. | |
|    * It is separated out because we can then overload it for the datamanipulation system. | |
|    * | |
|    * @private | |
|    */ | |
|   onDragStart(event) { | |
|     // in case the touch event was triggered on an external div, do the initial touch now. | |
|     //if (this.drag.pointer === undefined) { | |
|     //  this.onTouch(event); | |
|     //} | |
|     // | |
|     //var node = this._getNodeAt(this.drag.pointer); | |
|     //// note: drag.pointer is set in onTouch to get the initial touch location | |
|     // | |
|     //this.drag.dragging = true; | |
|     //this.drag.selection = []; | |
|     //this.drag.translation = this._getTranslation(); | |
|     //this.drag.nodeId = null; | |
|     //this.draggingNodes = false; | |
|     // | |
|     //if (node != null && this.constants.dragNodes == true) { | |
|     //  this.draggingNodes = true; | |
|     //  this.drag.nodeId = node.id; | |
|     //  // select the clicked node if not yet selected | |
|     //  if (!node.isSelected()) { | |
|     //    this._selectObject(node, false); | |
|     //  } | |
|     // | |
|     //  this.emit("dragStart", {nodeIds: this.getSelection().nodes}); | |
|     // | |
|     //  // create an array with the selected nodes and their original location and status | |
|     //  for (var objectId in this.selectionObj.nodes) { | |
|     //    if (this.selectionObj.nodes.hasOwnProperty(objectId)) { | |
|     //      var object = this.selectionObj.nodes[objectId]; | |
|     //      var s = { | |
|     //        id: object.id, | |
|     //        node: object, | |
|     // | |
|     //        // store original x, y, xFixed and yFixed, make the node temporarily Fixed | |
|     //        x: object.x, | |
|     //        y: object.y, | |
|     //        xFixed: object.xFixed, | |
|     //        yFixed: object.yFixed | |
|     //      }; | |
|     // | |
|     //      object.xFixed = true; | |
|     //      object.yFixed = true; | |
|     // | |
|     //      this.drag.selection.push(s); | |
|     //    } | |
|     //  } | |
|     //} | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * handle drag event | |
|    * @private | |
|    */ | |
|   onDrag(event) { | |
|     //if (this.drag.pinched) { | |
|     //  return; | |
|     //} | |
|     // | |
|     //// remove the focus on node if it is focussed on by the focusOnNode | |
|     //this.releaseNode(); | |
|     // | |
|     //var pointer = this.getPointer(event.gesture.center); | |
|     //var me = this; | |
|     //var drag = this.drag; | |
|     //var selection = drag.selection; | |
|     //if (selection && selection.length && this.constants.dragNodes == true) { | |
|     //  // calculate delta's and new location | |
|     //  var deltaX = pointer.x - drag.pointer.x; | |
|     //  var deltaY = pointer.y - drag.pointer.y; | |
|     // | |
|     //  // update position of all selected nodes | |
|     //  selection.forEach(function (s) { | |
|     //    var node = s.node; | |
|     // | |
|     //    if (!s.xFixed) { | |
|     //      node.x = me._XconvertDOMtoCanvas(me._XconvertCanvasToDOM(s.x) + deltaX); | |
|     //    } | |
|     // | |
|     //    if (!s.yFixed) { | |
|     //      node.y = me._YconvertDOMtoCanvas(me._YconvertCanvasToDOM(s.y) + deltaY); | |
|     //    } | |
|     //  }); | |
|     // | |
|     // | |
|     //  // start _animationStep if not yet running | |
|     //  if (!this.moving) { | |
|     //    this.moving = true; | |
|     //    this.start(); | |
|     //  } | |
|     //} | |
|     //else { | |
|     //  // move the network | |
|     //  if (this.constants.dragNetwork == true) { | |
|     //    // if the drag was not started properly because the click started outside the network div, start it now. | |
|     //    if (this.drag.pointer === undefined) { | |
|     //      this._handleDragStart(event); | |
|     //      return; | |
|     //    } | |
|     //    var diffX = pointer.x - this.drag.pointer.x; | |
|     //    var diffY = pointer.y - this.drag.pointer.y; | |
|     // | |
|     //    this._setTranslation( | |
|     //      this.drag.translation.x + diffX, | |
|     //      this.drag.translation.y + diffY | |
|     //    ); | |
|     //    this._redraw(); | |
|     //  } | |
|     //} | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * handle drag start event | |
|    * @private | |
|    */ | |
|   onDragEnd(event) { | |
|     //this.drag.dragging = false; | |
|     //var selection = this.drag.selection; | |
|     //if (selection && selection.length) { | |
|     //  selection.forEach(function (s) { | |
|     //    // restore original xFixed and yFixed | |
|     //    s.node.xFixed = s.xFixed; | |
|     //    s.node.yFixed = s.yFixed; | |
|     //  }); | |
|     //  this.moving = true; | |
|     //  this.start(); | |
|     //} | |
|     //else { | |
|     //  this._redraw(); | |
|     //} | |
|     //if (this.draggingNodes == false) { | |
|     //  this.emit("dragEnd", {nodeIds: []}); | |
|     //} | |
|     //else { | |
|     //  this.emit("dragEnd", {nodeIds: this.getSelection().nodes}); | |
|     //} | |
|   } | |
| 
 | |
|   /** | |
|    * handle doubletap event | |
|    * @private | |
|    */ | |
|   onDoubleTap(event) { | |
|     //var pointer = this.getPointer(event.gesture.center); | |
|     //this._handleDoubleTap(pointer); | |
|   } | |
| 
 | |
| 
 | |
| 
 | |
|   /** | |
|    * handle long tap event: multi select nodes | |
|    * @private | |
|    */ | |
|   onHold(event) { | |
|     //var pointer = this.getPointer(event.gesture.center); | |
|     //this.pointerPosition = pointer; | |
|     //this._handleOnHold(pointer); | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * handle the release of the screen | |
|    * | |
|    * @private | |
|    */ | |
|   onRelease(event) { | |
|     //var pointer = this.getPointer(event.gesture.center); | |
|     //this._handleOnRelease(pointer); | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * Handle pinch event | |
|    * @param event | |
|    * @private | |
|    */ | |
|   onPinch(event) { | |
|     //var pointer = this.getPointer(event.gesture.center); | |
|     // | |
|     //this.drag.pinched = true; | |
|     //if (!('scale' in this.pinch)) { | |
|     //  this.pinch.scale = 1; | |
|     //} | |
|     // | |
|     //// TODO: enabled moving while pinching? | |
|     //var scale = this.pinch.scale * event.gesture.scale; | |
|     //this._zoom(scale, pointer) | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * Zoom the network in or out | |
|    * @param {Number} scale a number around 1, and between 0.01 and 10 | |
|    * @param {{x: Number, y: Number}} pointer    Position on screen | |
|    * @return {Number} appliedScale    scale is limited within the boundaries | |
|    * @private | |
|    */ | |
|   _zoom(scale, pointer) { | |
|     //if (this.constants.zoomable == true) { | |
|     //  var scaleOld = this._getScale(); | |
|     //  if (scale < 0.00001) { | |
|     //    scale = 0.00001; | |
|     //  } | |
|     //  if (scale > 10) { | |
|     //    scale = 10; | |
|     //  } | |
|     // | |
|     //  var preScaleDragPointer = null; | |
|     //  if (this.drag !== undefined) { | |
|     //    if (this.drag.dragging == true) { | |
|     //      preScaleDragPointer = this.canvas.DOMtoCanvas(this.drag.pointer); | |
|     //    } | |
|     //  } | |
|     //  // + this.canvas.frame.canvas.clientHeight / 2 | |
|     //  var translation = this._getTranslation(); | |
|     // | |
|     //  var scaleFrac = scale / scaleOld; | |
|     //  var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac; | |
|     //  var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac; | |
|     // | |
|     //    this._setScale(scale); | |
|     //  this._setTranslation(tx, ty); | |
|     // | |
|     //  if (preScaleDragPointer != null) { | |
|     //    var postScaleDragPointer = this.canvas.canvasToDOM(preScaleDragPointer); | |
|     //    this.drag.pointer.x = postScaleDragPointer.x; | |
|     //    this.drag.pointer.y = postScaleDragPointer.y; | |
|     //  } | |
|     // | |
|     //  this._redraw(); | |
|     // | |
|     //  if (scaleOld < scale) { | |
|     //    this.emit("zoom", {direction: "+"}); | |
|     //  } | |
|     //  else { | |
|     //    this.emit("zoom", {direction: "-"}); | |
|     //  } | |
|     // | |
|     //  return scale; | |
|     //} | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * Event handler for mouse wheel event, used to zoom the timeline | |
|    * See http://adomas.org/javascript-mouse-wheel/ | |
|    *     https://github.com/EightMedia/hammer.js/issues/256 | |
|    * @param {MouseEvent}  event | |
|    * @private | |
|    */ | |
|   onMouseWheel(event) { | |
|     //// retrieve delta | |
|     //var delta = 0; | |
|     //if (event.wheelDelta) { /* IE/Opera. */ | |
|     //  delta = event.wheelDelta / 120; | |
|     //} else if (event.detail) { /* Mozilla case. */ | |
|     //  // In Mozilla, sign of delta is different than in IE. | |
|     //  // Also, delta is multiple of 3. | |
|     //  delta = -event.detail / 3; | |
|     //} | |
|     // | |
|     //// If delta is nonzero, handle it. | |
|     //// Basically, delta is now positive if wheel was scrolled up, | |
|     //// and negative, if wheel was scrolled down. | |
|     //if (delta) { | |
|     // | |
|     //  // calculate the new scale | |
|     //  var scale = this._getScale(); | |
|     //  var zoom = delta / 10; | |
|     //  if (delta < 0) { | |
|     //    zoom = zoom / (1 - zoom); | |
|     //  } | |
|     //  scale *= (1 + zoom); | |
|     // | |
|     //  // calculate the pointer location | |
|     //  var gesture = hammerUtil.fakeGesture(this, event); | |
|     //  var pointer = this.getPointer(gesture.center); | |
|     // | |
|     //  // apply the new scale | |
|     //  this._zoom(scale, pointer); | |
|     //} | |
|     // | |
|     //// Prevent default actions caused by mouse wheel. | |
|     //event.preventDefault(); | |
|   } | |
| 
 | |
| 
 | |
|   /** | |
|    * Mouse move handler for checking whether the title moves over a node with a title. | |
|    * @param  {Event} event | |
|    * @private | |
|    */ | |
|   onMouseMove(event) { | |
|     //var gesture = hammerUtil.fakeGesture(this, event); | |
|     //var pointer = this.getPointer(gesture.center); | |
|     //var popupVisible = false; | |
|     // | |
|     //// check if the previously selected node is still selected | |
|     //if (this.popup !== undefined) { | |
|     //  if (this.popup.hidden === false) { | |
|     //    this._checkHidePopup(pointer); | |
|     //  } | |
|     // | |
|     //  // if the popup was not hidden above | |
|     //  if (this.popup.hidden === false) { | |
|     //    popupVisible = true; | |
|     //    this.popup.setPosition(pointer.x + 3, pointer.y - 5) | |
|     //    this.popup.show(); | |
|     //  } | |
|     //} | |
|     // | |
|     //// if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over | |
|     //if (this.constants.keyboard.bindToWindow == false && this.constants.keyboard.enabled == true) { | |
|     //  this.canvas.frame.focus(); | |
|     //} | |
|     // | |
|     //// start a timeout that will check if the mouse is positioned above an element | |
|     //if (popupVisible === false) { | |
|     //  var me = this; | |
|     //  var checkShow = function() { | |
|     //    me._checkShowPopup(pointer); | |
|     //  }; | |
|     // | |
|     //  if (this.popupTimer) { | |
|     //    clearInterval(this.popupTimer); // stop any running calculationTimer | |
|     //  } | |
|     //  if (!this.drag.dragging) { | |
|     //    this.popupTimer = setTimeout(checkShow, this.constants.tooltip.delay); | |
|     //  } | |
|     //} | |
|     // | |
|     ///** | |
|     // * Adding hover highlights | |
|     // */ | |
|     //if (this.constants.hover == true) { | |
|     //  // removing all hover highlights | |
|     //  for (var edgeId in this.hoverObj.edges) { | |
|     //    if (this.hoverObj.edges.hasOwnProperty(edgeId)) { | |
|     //      this.hoverObj.edges[edgeId].hover = false; | |
|     //      delete this.hoverObj.edges[edgeId]; | |
|     //    } | |
|     //  } | |
|     // | |
|     //  // adding hover highlights | |
|     //  var obj = this._getNodeAt(pointer); | |
|     //  if (obj == null) { | |
|     //    obj = this._getEdgeAt(pointer); | |
|     //  } | |
|     //  if (obj != null) { | |
|     //    this._hoverObject(obj); | |
|     //  } | |
|     // | |
|     //  // removing all node hover highlights except for the selected one. | |
|     //  for (var nodeId in this.hoverObj.nodes) { | |
|     //    if (this.hoverObj.nodes.hasOwnProperty(nodeId)) { | |
|     //      if (obj instanceof Node && obj.id != nodeId || obj instanceof Edge || obj == null) { | |
|     //        this._blurObject(this.hoverObj.nodes[nodeId]); | |
|     //        delete this.hoverObj.nodes[nodeId]; | |
|     //      } | |
|     //    } | |
|     //  } | |
|     //  this.redraw(); | |
|     //} | |
|   } | |
| } | |
| 
 | |
| export {TouchEventHandler};
 |