/**
* $Id: mxGeometry.java,v 1.1 2012/11/15 13:26:47 gaudenz Exp $
* Copyright (c) 2007, Gaudenz Alder
*/
package com.mxgraph.model;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import java.util.ArrayList;
import java.util.List;
/**
* Represents the geometry of a cell. For vertices, the geometry consists
* of the x- and y-location, as well as the width and height. For edges,
* the geometry either defines the source- and target-terminal, or it
* defines the respective terminal points.
* <p/>
* For edges, if the geometry is relative (default), then the x-coordinate
* is used to describe the distance from the center of the edge from -1 to 1
* with 0 being the center of the edge and the default value, and the
* y-coordinate is used to describe the absolute, orthogonal distance in
* pixels from that point. In addition, the offset is used as an absolute
* offset vector from the resulting point.
*/
public class mxGeometry extends mxRectangle {
/**
*
*/
private static final long serialVersionUID = 2649828026610336589L;
/**
* Global switch to translate the points in translate. Default is true.
*/
public static transient boolean TRANSLATE_CONTROL_POINTS = true;
/**
* Stores alternate values for x, y, width and height in a rectangle.
* Default is null.
*/
protected mxRectangle alternateBounds;
/**
* Defines the source- and target-point of the edge. This is used if the
* corresponding edge does not have a source vertex. Otherwise it is
* ignored. Default is null.
*/
protected mxPoint sourcePoint, targetPoint;
/**
* List of mxPoints which specifies the control points along the edge.
* These points are the intermediate points on the edge, for the endpoints
* use targetPoint and sourcePoint or set the terminals of the edge to
* a non-null value. Default is null.
*/
protected List<mxPoint> points;
/**
* Holds the offset of the label for edges. This is the absolute vector
* between the center of the edge and the top, left point of the label.
* Default is null.
*/
protected mxPoint offset;
/**
* Specifies if the coordinates in the geometry are to be interpreted as
* relative coordinates. Default is false. This is used to mark a geometry
* with an x- and y-coordinate that is used to describe an edge label
* position, or a relative location with respect to a parent cell's
* width and height.
*/
protected boolean relative = false;
/**
* Constructs a new geometry at (0, 0) with the width and height set to 0.
*/
public mxGeometry() {
this(0, 0, 0, 0);
}
/**
* Constructs a geometry using the given parameters.
*
* @param x X-coordinate of the new geometry.
* @param y Y-coordinate of the new geometry.
* @param width Width of the new geometry.
* @param height Height of the new geometry.
*/
public mxGeometry(double x, double y, double width, double height) {
super(x, y, width, height);
}
/**
* Returns the alternate bounds.
*/
public mxRectangle getAlternateBounds() {
return alternateBounds;
}
/**
* Sets the alternate bounds to the given rectangle.
*
* @param rect Rectangle to be used for the alternate bounds.
*/
public void setAlternateBounds(mxRectangle rect) {
alternateBounds = rect;
}
/**
* Returns the source point.
*
* @return Returns the source point.
*/
public mxPoint getSourcePoint() {
return sourcePoint;
}
/**
* Sets the source point.
*
* @param sourcePoint Source point to be used.
*/
public void setSourcePoint(mxPoint sourcePoint) {
this.sourcePoint = sourcePoint;
}
/**
* Returns the target point.
*
* @return Returns the target point.
*/
public mxPoint getTargetPoint() {
return targetPoint;
}
/**
* Sets the target point.
*
* @param targetPoint Target point to be used.
*/
public void setTargetPoint(mxPoint targetPoint) {
this.targetPoint = targetPoint;
}
/**
* Returns the list of control points.
*/
public List<mxPoint> getPoints() {
return points;
}
/**
* Sets the list of control points to the given list.
*
* @param value List that contains the new control points.
*/
public void setPoints(List<mxPoint> value) {
points = value;
}
/**
* Returns the offset.
*/
public mxPoint getOffset() {
return offset;
}
/**
* Sets the offset to the given point.
*
* @param offset Point to be used for the offset.
*/
public void setOffset(mxPoint offset) {
this.offset = offset;
}
/**
* Returns true of the geometry is relative.
*/
public boolean isRelative() {
return relative;
}
/**
* Sets the relative state of the geometry.
*
* @param value Boolean value to be used as the new relative state.
*/
public void setRelative(boolean value) {
relative = value;
}
/**
* Swaps the x, y, width and height with the values stored in
* alternateBounds and puts the previous values into alternateBounds as
* a rectangle. This operation is carried-out in-place, that is, using the
* existing geometry instance. If this operation is called during a graph
* model transactional change, then the geometry should be cloned before
* calling this method and setting the geometry of the cell using
* mxGraphModel.setGeometry.
*/
public void swap() {
if (alternateBounds != null) {
mxRectangle old = new mxRectangle(getX(), getY(), getWidth(), getHeight());
x = alternateBounds.getX();
y = alternateBounds.getY();
width = alternateBounds.getWidth();
height = alternateBounds.getHeight();
alternateBounds = old;
}
}
/**
* Returns the point representing the source or target point of this edge.
* This is only used if the edge has no source or target vertex.
*
* @param isSource Boolean that specifies if the source or target point
* should be returned.
* @return Returns the source or target point.
*/
public mxPoint getTerminalPoint(boolean isSource) {
return (isSource) ? sourcePoint : targetPoint;
}
/**
* Sets the sourcePoint or targetPoint to the given point and returns the
* new point.
*
* @param point Point to be used as the new source or target point.
* @param isSource Boolean that specifies if the source or target point
* should be set.
* @return Returns the new point.
*/
public mxPoint setTerminalPoint(mxPoint point, boolean isSource) {
if (isSource) {
sourcePoint = point;
}
else {
targetPoint = point;
}
return point;
}
/**
* Translates the geometry by the specified amount. That is, x and y of the
* geometry, the sourcePoint, targetPoint and all elements of points are
* translated by the given amount. X and y are only translated if the
* geometry is not relative. If TRANSLATE_CONTROL_POINTS is false, then
* are not modified by this function.
*
* @param dx Integer that specifies the x-coordinate of the translation.
* @param dy Integer that specifies the y-coordinate of the translation.
*/
public void translate(double dx, double dy) {
// Translates the geometry
if (!isRelative()) {
x += dx;
y += dy;
}
// Translates the source point
if (sourcePoint != null) {
sourcePoint.setX(sourcePoint.getX() + dx);
sourcePoint.setY(sourcePoint.getY() + dy);
}
// Translates the target point
if (targetPoint != null) {
targetPoint.setX(targetPoint.getX() + dx);
targetPoint.setY(targetPoint.getY() + dy);
}
// Translate the control points
if (TRANSLATE_CONTROL_POINTS && points != null) {
int count = points.size();
for (int i = 0; i < count; i++) {
mxPoint pt = points.get(i);
pt.setX(pt.getX() + dx);
pt.setY(pt.getY() + dy);
}
}
}
/**
* Returns a clone of the cell.
*/
public Object clone() {
mxGeometry clone = (mxGeometry)super.clone();
clone.setX(getX());
clone.setY(getY());
clone.setWidth(getWidth());
clone.setHeight(getHeight());
clone.setRelative(isRelative());
List<mxPoint> pts = getPoints();
if (pts != null) {
clone.points = new ArrayList<mxPoint>(pts.size());
for (int i = 0; i < pts.size(); i++) {
clone.points.add((mxPoint)pts.get(i).clone());
}
}
mxPoint tp = getTargetPoint();
if (tp != null) {
clone.setTargetPoint((mxPoint)tp.clone());
}
mxPoint sp = getSourcePoint();
if (sp != null) {
setSourcePoint((mxPoint)sp.clone());
}
mxPoint off = getOffset();
if (off != null) {
clone.setOffset((mxPoint)off.clone());
}
mxRectangle alt = getAlternateBounds();
if (alt != null) {
setAlternateBounds((mxRectangle)alt.clone());
}
return clone;
}
}