| /** |
| * Copyright (c) 2006-2015, JGraph Ltd |
| * Copyright (c) 2006-2015, Gaudenz Alder |
| */ |
| /** |
| * Class: mxCellHighlight |
| * |
| * A helper class to highlight cells. Here is an example for a given cell. |
| * |
| * (code) |
| * var highlight = new mxCellHighlight(graph, '#ff0000', 2); |
| * highlight.highlight(graph.view.getState(cell))); |
| * (end) |
| * |
| * Constructor: mxCellHighlight |
| * |
| * Constructs a cell highlight. |
| */ |
| function mxCellHighlight(graph, highlightColor, strokeWidth, dashed) |
| { |
| if (graph != null) |
| { |
| this.graph = graph; |
| this.highlightColor = (highlightColor != null) ? highlightColor : mxConstants.DEFAULT_VALID_COLOR; |
| this.strokeWidth = (strokeWidth != null) ? strokeWidth : mxConstants.HIGHLIGHT_STROKEWIDTH; |
| this.dashed = (dashed != null) ? dashed : false; |
| this.opacity = mxConstants.HIGHLIGHT_OPACITY; |
| |
| // Updates the marker if the graph changes |
| this.repaintHandler = mxUtils.bind(this, function() |
| { |
| // Updates reference to state |
| if (this.state != null) |
| { |
| var tmp = this.graph.view.getState(this.state.cell); |
| |
| if (tmp == null) |
| { |
| this.hide(); |
| } |
| else |
| { |
| this.state = tmp; |
| this.repaint(); |
| } |
| } |
| }); |
| |
| this.graph.getView().addListener(mxEvent.SCALE, this.repaintHandler); |
| this.graph.getView().addListener(mxEvent.TRANSLATE, this.repaintHandler); |
| this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.repaintHandler); |
| this.graph.getModel().addListener(mxEvent.CHANGE, this.repaintHandler); |
| |
| // Hides the marker if the current root changes |
| this.resetHandler = mxUtils.bind(this, function() |
| { |
| this.hide(); |
| }); |
| |
| this.graph.getView().addListener(mxEvent.DOWN, this.resetHandler); |
| this.graph.getView().addListener(mxEvent.UP, this.resetHandler); |
| } |
| }; |
| |
| /** |
| * Variable: keepOnTop |
| * |
| * Specifies if the highlights should appear on top of everything |
| * else in the overlay pane. Default is false. |
| */ |
| mxCellHighlight.prototype.keepOnTop = false; |
| |
| /** |
| * Variable: graph |
| * |
| * Reference to the enclosing <mxGraph>. |
| */ |
| mxCellHighlight.prototype.graph = true; |
| |
| /** |
| * Variable: state |
| * |
| * Reference to the <mxCellState>. |
| */ |
| mxCellHighlight.prototype.state = null; |
| |
| /** |
| * Variable: spacing |
| * |
| * Specifies the spacing between the highlight for vertices and the vertex. |
| * Default is 2. |
| */ |
| mxCellHighlight.prototype.spacing = 2; |
| |
| /** |
| * Variable: resetHandler |
| * |
| * Holds the handler that automatically invokes reset if the highlight |
| * should be hidden. |
| */ |
| mxCellHighlight.prototype.resetHandler = null; |
| |
| /** |
| * Function: setHighlightColor |
| * |
| * Sets the color of the rectangle used to highlight drop targets. |
| * |
| * Parameters: |
| * |
| * color - String that represents the new highlight color. |
| */ |
| mxCellHighlight.prototype.setHighlightColor = function(color) |
| { |
| this.highlightColor = color; |
| |
| if (this.shape != null) |
| { |
| this.shape.stroke = color; |
| } |
| }; |
| |
| /** |
| * Function: drawHighlight |
| * |
| * Creates and returns the highlight shape for the given state. |
| */ |
| mxCellHighlight.prototype.drawHighlight = function() |
| { |
| this.shape = this.createShape(); |
| this.repaint(); |
| |
| if (!this.keepOnTop && this.shape.node.parentNode.firstChild != this.shape.node) |
| { |
| this.shape.node.parentNode.insertBefore(this.shape.node, this.shape.node.parentNode.firstChild); |
| } |
| }; |
| |
| /** |
| * Function: createShape |
| * |
| * Creates and returns the highlight shape for the given state. |
| */ |
| mxCellHighlight.prototype.createShape = function() |
| { |
| var shape = this.graph.cellRenderer.createShape(this.state); |
| |
| shape.svgStrokeTolerance = this.graph.tolerance; |
| shape.points = this.state.absolutePoints; |
| shape.apply(this.state); |
| shape.stroke = this.highlightColor; |
| shape.opacity = this.opacity; |
| shape.isDashed = this.dashed; |
| shape.isShadow = false; |
| |
| shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; |
| shape.init(this.graph.getView().getOverlayPane()); |
| mxEvent.redirectMouseEvents(shape.node, this.graph, this.state); |
| |
| if (this.graph.dialect != mxConstants.DIALECT_SVG) |
| { |
| shape.pointerEvents = false; |
| } |
| else |
| { |
| shape.svgPointerEvents = 'stroke'; |
| } |
| |
| return shape; |
| }; |
| |
| /** |
| * Function: repaint |
| * |
| * Updates the highlight after a change of the model or view. |
| */ |
| mxCellHighlight.prototype.getStrokeWidth = function(state) |
| { |
| return this.strokeWidth; |
| }; |
| |
| /** |
| * Function: repaint |
| * |
| * Updates the highlight after a change of the model or view. |
| */ |
| mxCellHighlight.prototype.repaint = function() |
| { |
| if (this.state != null && this.shape != null) |
| { |
| this.shape.scale = this.state.view.scale; |
| |
| if (this.graph.model.isEdge(this.state.cell)) |
| { |
| this.shape.strokewidth = this.getStrokeWidth(); |
| this.shape.points = this.state.absolutePoints; |
| this.shape.outline = false; |
| } |
| else |
| { |
| this.shape.bounds = new mxRectangle(this.state.x - this.spacing, this.state.y - this.spacing, |
| this.state.width + 2 * this.spacing, this.state.height + 2 * this.spacing); |
| this.shape.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0'); |
| this.shape.strokewidth = this.getStrokeWidth() / this.state.view.scale; |
| this.shape.outline = true; |
| } |
| |
| // Uses cursor from shape in highlight |
| if (this.state.shape != null) |
| { |
| this.shape.setCursor(this.state.shape.getCursor()); |
| } |
| |
| // Workaround for event transparency in VML with transparent color |
| // is to use a non-transparent color with near zero opacity |
| if (mxClient.IS_QUIRKS || document.documentMode == 8) |
| { |
| if (this.shape.stroke == 'transparent') |
| { |
| // KNOWN: Quirks mode does not seem to catch events if |
| // we do not force an update of the DOM via a change such |
| // as mxLog.debug. Since IE6 is EOL we do not add a fix. |
| this.shape.stroke = 'white'; |
| this.shape.opacity = 1; |
| } |
| else |
| { |
| this.shape.opacity = this.opacity; |
| } |
| } |
| |
| this.shape.redraw(); |
| } |
| }; |
| |
| /** |
| * Function: hide |
| * |
| * Resets the state of the cell marker. |
| */ |
| mxCellHighlight.prototype.hide = function() |
| { |
| this.highlight(null); |
| }; |
| |
| /** |
| * Function: mark |
| * |
| * Marks the <markedState> and fires a <mark> event. |
| */ |
| mxCellHighlight.prototype.highlight = function(state) |
| { |
| if (this.state != state) |
| { |
| if (this.shape != null) |
| { |
| this.shape.destroy(); |
| this.shape = null; |
| } |
| |
| this.state = state; |
| |
| if (this.state != null) |
| { |
| this.drawHighlight(); |
| } |
| } |
| }; |
| |
| /** |
| * Function: isHighlightAt |
| * |
| * Returns true if this highlight is at the given position. |
| */ |
| mxCellHighlight.prototype.isHighlightAt = function(x, y) |
| { |
| var hit = false; |
| |
| // Quirks mode is currently not supported as it used a different coordinate system |
| if (this.shape != null && document.elementFromPoint != null && !mxClient.IS_QUIRKS) |
| { |
| var elt = document.elementFromPoint(x, y); |
| |
| while (elt != null) |
| { |
| if (elt == this.shape.node) |
| { |
| hit = true; |
| break; |
| } |
| |
| elt = elt.parentNode; |
| } |
| } |
| |
| return hit; |
| }; |
| |
| /** |
| * Function: destroy |
| * |
| * Destroys the handler and all its resources and DOM nodes. |
| */ |
| mxCellHighlight.prototype.destroy = function() |
| { |
| this.graph.getView().removeListener(this.resetHandler); |
| this.graph.getView().removeListener(this.repaintHandler); |
| this.graph.getModel().removeListener(this.repaintHandler); |
| |
| if (this.shape != null) |
| { |
| this.shape.destroy(); |
| this.shape = null; |
| } |
| }; |