mxElbowEdgeHandler.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. /**
  6. * Class: mxElbowEdgeHandler
  7. *
  8. * Graph event handler that reconnects edges and modifies control points and
  9. * the edge label location. Uses <mxTerminalMarker> for finding and
  10. * highlighting new source and target vertices. This handler is automatically
  11. * created in <mxGraph.createHandler>. It extends <mxEdgeHandler>.
  12. *
  13. * Constructor: mxEdgeHandler
  14. *
  15. * Constructs an edge handler for the specified <mxCellState>.
  16. *
  17. * Parameters:
  18. *
  19. * state - <mxCellState> of the cell to be modified.
  20. */
  21. function mxElbowEdgeHandler(state)
  22. {
  23. mxEdgeHandler.call(this, state);
  24. };
  25. /**
  26. * Extends mxEdgeHandler.
  27. */
  28. mxUtils.extend(mxElbowEdgeHandler, mxEdgeHandler);
  29. /**
  30. * Specifies if a double click on the middle handle should call
  31. * <mxGraph.flipEdge>. Default is true.
  32. */
  33. mxElbowEdgeHandler.prototype.flipEnabled = true;
  34. /**
  35. * Variable: doubleClickOrientationResource
  36. *
  37. * Specifies the resource key for the tooltip to be displayed on the single
  38. * control point for routed edges. If the resource for this key does not
  39. * exist then the value is used as the error message. Default is
  40. * 'doubleClickOrientation'.
  41. */
  42. mxElbowEdgeHandler.prototype.doubleClickOrientationResource =
  43. (mxClient.language != 'none') ? 'doubleClickOrientation' : '';
  44. /**
  45. * Function: createBends
  46. *
  47. * Overrides <mxEdgeHandler.createBends> to create custom bends.
  48. */
  49. mxElbowEdgeHandler.prototype.createBends = function()
  50. {
  51. var bends = [];
  52. // Source
  53. var bend = this.createHandleShape(0);
  54. this.initBend(bend);
  55. bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
  56. bends.push(bend);
  57. // Virtual
  58. bends.push(this.createVirtualBend(mxUtils.bind(this, function(evt)
  59. {
  60. if (!mxEvent.isConsumed(evt) && this.flipEnabled)
  61. {
  62. this.graph.flipEdge(this.state.cell, evt);
  63. mxEvent.consume(evt);
  64. }
  65. })));
  66. this.points.push(new mxPoint(0,0));
  67. // Target
  68. bend = this.createHandleShape(2);
  69. this.initBend(bend);
  70. bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
  71. bends.push(bend);
  72. return bends;
  73. };
  74. /**
  75. * Function: createVirtualBend
  76. *
  77. * Creates a virtual bend that supports double clicking and calls
  78. * <mxGraph.flipEdge>.
  79. */
  80. mxElbowEdgeHandler.prototype.createVirtualBend = function(dblClickHandler)
  81. {
  82. var bend = this.createHandleShape();
  83. this.initBend(bend, dblClickHandler);
  84. bend.setCursor(this.getCursorForBend());
  85. if (!this.graph.isCellBendable(this.state.cell))
  86. {
  87. bend.node.style.display = 'none';
  88. }
  89. return bend;
  90. };
  91. /**
  92. * Function: getCursorForBend
  93. *
  94. * Returns the cursor to be used for the bend.
  95. */
  96. mxElbowEdgeHandler.prototype.getCursorForBend = function()
  97. {
  98. return (this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.TopToBottom ||
  99. this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_TOPTOBOTTOM ||
  100. ((this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.ElbowConnector ||
  101. this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_ELBOW)&&
  102. this.state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL)) ?
  103. 'row-resize' : 'col-resize';
  104. };
  105. /**
  106. * Function: getTooltipForNode
  107. *
  108. * Returns the tooltip for the given node.
  109. */
  110. mxElbowEdgeHandler.prototype.getTooltipForNode = function(node)
  111. {
  112. var tip = null;
  113. if (this.bends != null && this.bends[1] != null && (node == this.bends[1].node ||
  114. node.parentNode == this.bends[1].node))
  115. {
  116. tip = this.doubleClickOrientationResource;
  117. tip = mxResources.get(tip) || tip; // translate
  118. }
  119. return tip;
  120. };
  121. /**
  122. * Function: convertPoint
  123. *
  124. * Converts the given point in-place from screen to unscaled, untranslated
  125. * graph coordinates and applies the grid.
  126. *
  127. * Parameters:
  128. *
  129. * point - <mxPoint> to be converted.
  130. * gridEnabled - Boolean that specifies if the grid should be applied.
  131. */
  132. mxElbowEdgeHandler.prototype.convertPoint = function(point, gridEnabled)
  133. {
  134. var scale = this.graph.getView().getScale();
  135. var tr = this.graph.getView().getTranslate();
  136. var origin = this.state.origin;
  137. if (gridEnabled)
  138. {
  139. point.x = this.graph.snap(point.x);
  140. point.y = this.graph.snap(point.y);
  141. }
  142. point.x = Math.round(point.x / scale - tr.x - origin.x);
  143. point.y = Math.round(point.y / scale - tr.y - origin.y);
  144. return point;
  145. };
  146. /**
  147. * Function: redrawInnerBends
  148. *
  149. * Updates and redraws the inner bends.
  150. *
  151. * Parameters:
  152. *
  153. * p0 - <mxPoint> that represents the location of the first point.
  154. * pe - <mxPoint> that represents the location of the last point.
  155. */
  156. mxElbowEdgeHandler.prototype.redrawInnerBends = function(p0, pe)
  157. {
  158. var g = this.graph.getModel().getGeometry(this.state.cell);
  159. var pts = this.state.absolutePoints;
  160. var pt = null;
  161. // Keeps the virtual bend on the edge shape
  162. if (pts.length > 1)
  163. {
  164. p0 = pts[1];
  165. pe = pts[pts.length - 2];
  166. }
  167. else if (g.points != null && g.points.length > 0)
  168. {
  169. pt = pts[0];
  170. }
  171. if (pt == null)
  172. {
  173. pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2);
  174. }
  175. else
  176. {
  177. pt = new mxPoint(this.graph.getView().scale * (pt.x + this.graph.getView().translate.x + this.state.origin.x),
  178. this.graph.getView().scale * (pt.y + this.graph.getView().translate.y + this.state.origin.y));
  179. }
  180. // Makes handle slightly bigger if the yellow label handle
  181. // exists and intersects this green handle
  182. var b = this.bends[1].bounds;
  183. var w = b.width;
  184. var h = b.height;
  185. var bounds = new mxRectangle(Math.round(pt.x - w / 2), Math.round(pt.y - h / 2), w, h);
  186. if (this.manageLabelHandle)
  187. {
  188. this.checkLabelHandle(bounds);
  189. }
  190. else if (this.handleImage == null && this.labelShape.visible && mxUtils.intersects(bounds, this.labelShape.bounds))
  191. {
  192. w = mxConstants.HANDLE_SIZE + 3;
  193. h = mxConstants.HANDLE_SIZE + 3;
  194. bounds = new mxRectangle(Math.floor(pt.x - w / 2), Math.floor(pt.y - h / 2), w, h);
  195. }
  196. this.bends[1].bounds = bounds;
  197. this.bends[1].redraw();
  198. if (this.manageLabelHandle)
  199. {
  200. this.checkLabelHandle(this.bends[1].bounds);
  201. }
  202. };
  203. __mxOutput.mxElbowEdgeHandler = typeof mxElbowEdgeHandler !== 'undefined' ? mxElbowEdgeHandler : undefined;