| /** |
| * Copyright (c) 2006-2015, JGraph Ltd |
| * Copyright (c) 2006-2015, Gaudenz Alder |
| */ |
| /** |
| * Class: mxElbowEdgeHandler |
| * |
| * Graph event handler that reconnects edges and modifies control points and |
| * the edge label location. Uses <mxTerminalMarker> for finding and |
| * highlighting new source and target vertices. This handler is automatically |
| * created in <mxGraph.createHandler>. It extends <mxEdgeHandler>. |
| * |
| * Constructor: mxEdgeHandler |
| * |
| * Constructs an edge handler for the specified <mxCellState>. |
| * |
| * Parameters: |
| * |
| * state - <mxCellState> of the cell to be modified. |
| */ |
| function mxElbowEdgeHandler(state) |
| { |
| mxEdgeHandler.call(this, state); |
| }; |
| |
| /** |
| * Extends mxEdgeHandler. |
| */ |
| mxUtils.extend(mxElbowEdgeHandler, mxEdgeHandler); |
| |
| /** |
| * Specifies if a double click on the middle handle should call |
| * <mxGraph.flipEdge>. Default is true. |
| */ |
| mxElbowEdgeHandler.prototype.flipEnabled = true; |
| |
| /** |
| * Variable: doubleClickOrientationResource |
| * |
| * Specifies the resource key for the tooltip to be displayed on the single |
| * control point for routed edges. If the resource for this key does not |
| * exist then the value is used as the error message. Default is |
| * 'doubleClickOrientation'. |
| */ |
| mxElbowEdgeHandler.prototype.doubleClickOrientationResource = |
| (mxClient.language != 'none') ? 'doubleClickOrientation' : ''; |
| |
| /** |
| * Function: createBends |
| * |
| * Overrides <mxEdgeHandler.createBends> to create custom bends. |
| */ |
| mxElbowEdgeHandler.prototype.createBends = function() |
| { |
| var bends = []; |
| |
| // Source |
| var bend = this.createHandleShape(0); |
| this.initBend(bend); |
| bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE); |
| bends.push(bend); |
| |
| // Virtual |
| bends.push(this.createVirtualBend(mxUtils.bind(this, function(evt) |
| { |
| if (!mxEvent.isConsumed(evt) && this.flipEnabled) |
| { |
| this.graph.flipEdge(this.state.cell, evt); |
| mxEvent.consume(evt); |
| } |
| }))); |
| this.points.push(new mxPoint(0,0)); |
| |
| // Target |
| bend = this.createHandleShape(2); |
| this.initBend(bend); |
| bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE); |
| bends.push(bend); |
| |
| return bends; |
| }; |
| |
| /** |
| * Function: createVirtualBend |
| * |
| * Creates a virtual bend that supports double clicking and calls |
| * <mxGraph.flipEdge>. |
| */ |
| mxElbowEdgeHandler.prototype.createVirtualBend = function(dblClickHandler) |
| { |
| var bend = this.createHandleShape(); |
| this.initBend(bend, dblClickHandler); |
| |
| bend.setCursor(this.getCursorForBend()); |
| |
| if (!this.graph.isCellBendable(this.state.cell)) |
| { |
| bend.node.style.display = 'none'; |
| } |
| |
| return bend; |
| }; |
| |
| /** |
| * Function: getCursorForBend |
| * |
| * Returns the cursor to be used for the bend. |
| */ |
| mxElbowEdgeHandler.prototype.getCursorForBend = function() |
| { |
| return (this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.TopToBottom || |
| this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_TOPTOBOTTOM || |
| ((this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.ElbowConnector || |
| this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_ELBOW)&& |
| this.state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL)) ? |
| 'row-resize' : 'col-resize'; |
| }; |
| |
| /** |
| * Function: getTooltipForNode |
| * |
| * Returns the tooltip for the given node. |
| */ |
| mxElbowEdgeHandler.prototype.getTooltipForNode = function(node) |
| { |
| var tip = null; |
| |
| if (this.bends != null && this.bends[1] != null && (node == this.bends[1].node || |
| node.parentNode == this.bends[1].node)) |
| { |
| tip = this.doubleClickOrientationResource; |
| tip = mxResources.get(tip) || tip; // translate |
| } |
| |
| return tip; |
| }; |
| |
| /** |
| * Function: convertPoint |
| * |
| * Converts the given point in-place from screen to unscaled, untranslated |
| * graph coordinates and applies the grid. |
| * |
| * Parameters: |
| * |
| * point - <mxPoint> to be converted. |
| * gridEnabled - Boolean that specifies if the grid should be applied. |
| */ |
| mxElbowEdgeHandler.prototype.convertPoint = function(point, gridEnabled) |
| { |
| var scale = this.graph.getView().getScale(); |
| var tr = this.graph.getView().getTranslate(); |
| var origin = this.state.origin; |
| |
| if (gridEnabled) |
| { |
| point.x = this.graph.snap(point.x); |
| point.y = this.graph.snap(point.y); |
| } |
| |
| point.x = Math.round(point.x / scale - tr.x - origin.x); |
| point.y = Math.round(point.y / scale - tr.y - origin.y); |
| |
| return point; |
| }; |
| |
| /** |
| * Function: redrawInnerBends |
| * |
| * Updates and redraws the inner bends. |
| * |
| * Parameters: |
| * |
| * p0 - <mxPoint> that represents the location of the first point. |
| * pe - <mxPoint> that represents the location of the last point. |
| */ |
| mxElbowEdgeHandler.prototype.redrawInnerBends = function(p0, pe) |
| { |
| var g = this.graph.getModel().getGeometry(this.state.cell); |
| var pts = this.state.absolutePoints; |
| var pt = null; |
| |
| // Keeps the virtual bend on the edge shape |
| if (pts.length > 1) |
| { |
| p0 = pts[1]; |
| pe = pts[pts.length - 2]; |
| } |
| else if (g.points != null && g.points.length > 0) |
| { |
| pt = pts[0]; |
| } |
| |
| if (pt == null) |
| { |
| pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2); |
| } |
| else |
| { |
| pt = new mxPoint(this.graph.getView().scale * (pt.x + this.graph.getView().translate.x + this.state.origin.x), |
| this.graph.getView().scale * (pt.y + this.graph.getView().translate.y + this.state.origin.y)); |
| } |
| |
| // Makes handle slightly bigger if the yellow label handle |
| // exists and intersects this green handle |
| var b = this.bends[1].bounds; |
| var w = b.width; |
| var h = b.height; |
| var bounds = new mxRectangle(Math.round(pt.x - w / 2), Math.round(pt.y - h / 2), w, h); |
| |
| if (this.manageLabelHandle) |
| { |
| this.checkLabelHandle(bounds); |
| } |
| else if (this.handleImage == null && this.labelShape.visible && mxUtils.intersects(bounds, this.labelShape.bounds)) |
| { |
| w = mxConstants.HANDLE_SIZE + 3; |
| h = mxConstants.HANDLE_SIZE + 3; |
| bounds = new mxRectangle(Math.floor(pt.x - w / 2), Math.floor(pt.y - h / 2), w, h); |
| } |
| |
| this.bends[1].bounds = bounds; |
| this.bends[1].redraw(); |
| |
| if (this.manageLabelHandle) |
| { |
| this.checkLabelHandle(this.bends[1].bounds); |
| } |
| }; |