/*
* @(#)DefaultEdge.java 1.0 03-JUL-04 Copyright (c) 2001-2004 Gaudenz Alder
*/
// MODIFYBEGIN
package de.unisiegen.gtitool.ui.jgraph;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import org.jgraph.graph.AbstractCellView;
import org.jgraph.graph.AttributeMap;
import org.jgraph.graph.CellView;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.Edge;
import org.jgraph.graph.EdgeView;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.GraphLayoutCache;
import org.jgraph.graph.PortView;
import de.unisiegen.gtitool.core.entities.State;
/**
* A simple implementation for an edge.
*
* @version 1.0 1/1/02
* @author Gaudenz Alder
*/
@SuppressWarnings ( "all" )
public class DefaultEdge extends DefaultGraphCell implements Edge
{
public static class DefaultRouting extends LoopRouting
{
protected List routeEdge ( GraphLayoutCache cache, EdgeView edge )
{
List newPoints = new ArrayList ();
int n = edge.getPointCount ();
Point2D from = edge.getPoint ( 0 );
newPoints.add ( from );
if ( edge.getSource () instanceof PortView )
{
newPoints.set ( 0, edge.getSource () );
from = ( ( PortView ) edge.getSource () ).getLocation ();
}
else if ( edge.getSource () != null )
{
Rectangle2D b = edge.getSource ().getBounds ();
from = edge.getAttributes ().createPoint ( b.getCenterX (),
b.getCenterY () );
}
Point2D to = edge.getPoint ( n - 1 );
CellView target = edge.getTarget ();
if ( target instanceof PortView )
{
to = ( ( PortView ) target ).getLocation ();
}
else if ( target != null )
{
Rectangle2D b = target.getBounds ();
to = edge.getAttributes ().createPoint ( b.getCenterX (),
b.getCenterY () );
}
if ( ( from != null ) && ( to != null ) )
{
Point2D [] routed;
double dx = Math.abs ( from.getX () - to.getX () );
double dy = Math.abs ( from.getY () - to.getY () );
double x2 = from.getX () + ( ( to.getX () - from.getX () ) / 2 );
double y2 = from.getY () + ( ( to.getY () - from.getY () ) / 2 );
routed = new Point2D [ 2 ];
Rectangle2D targetBounds = null;
Rectangle2D sourceBounds = null;
if ( ( ( edge.getTarget () != null ) && ( edge.getTarget ()
.getParentView () != null ) )
&& ( ( edge.getSource () != null ) && ( edge.getSource ()
.getParentView () != null ) ) )
{
targetBounds = edge.getTarget ().getParentView ().getBounds ();
sourceBounds = edge.getSource ().getParentView ().getBounds ();
}
if ( ( targetBounds != null ) && ( sourceBounds != null ) )
{
if ( dx > dy )
{
routed [ 0 ] = edge.getAttributes ()
.createPoint ( x2, from.getY () );
routed [ 1 ] = edge.getAttributes ().createPoint ( x2, to.getY () );
if ( targetBounds.contains ( routed [ 0 ] )
|| ( sourceBounds.contains ( routed [ 0 ] ) )
|| targetBounds.contains ( routed [ 1 ] )
|| ( sourceBounds.contains ( routed [ 1 ] ) ) )
{
routed [ 0 ] = edge.getAttributes ().createPoint ( from.getX (),
y2 );
routed [ 1 ] = edge.getAttributes ()
.createPoint ( to.getX (), y2 );
}
}
else
{
routed [ 0 ] = edge.getAttributes ()
.createPoint ( from.getX (), y2 );
routed [ 1 ] = edge.getAttributes ().createPoint ( to.getX (), y2 );
if ( targetBounds.contains ( routed [ 0 ] )
|| ( sourceBounds.contains ( routed [ 0 ] ) )
|| targetBounds.contains ( routed [ 1 ] )
|| ( sourceBounds.contains ( routed [ 1 ] ) ) )
{
routed [ 0 ] = edge.getAttributes ().createPoint ( x2,
from.getY () );
routed [ 1 ] = edge.getAttributes ()
.createPoint ( x2, to.getY () );
}
}
// Set/Add Points
for ( int i = 0 ; i < routed.length ; i++ )
{
if ( !targetBounds.contains ( routed [ i ] )
&& ( !sourceBounds.contains ( routed [ i ] ) ) )
{
newPoints.add ( routed [ i ] );
}
}
}
// Add target point
if ( target != null )
{
newPoints.add ( target );
}
else
{
newPoints.add ( to );
}
return newPoints;
}
return null;
}
}
public static class LoopRouting implements Edge.Routing
{
protected int getEdgeStyle ()
{
return NO_PREFERENCE;
}
protected int getLoopStyle ()
{
return GraphConstants.STYLE_BEZIER;
}
public int getPreferredLineStyle ( EdgeView edge )
{
if ( edge.isLoop () )
{
return getLoopStyle ();
}
return getEdgeStyle ();
}
public List route ( GraphLayoutCache cache, EdgeView edge )
{
if ( edge.isLoop () )
{
return routeLoop ( cache, edge );
}
return routeEdge ( cache, edge );
}
protected List routeEdge ( GraphLayoutCache cache, EdgeView edge )
{
return null;
}
protected List routeLoop ( GraphLayoutCache cache, EdgeView edge )
{
List newPoints = new ArrayList ();
newPoints.add ( edge.getSource () );
CellView sourceParent = ( edge.getSource () != null ) ? edge.getSource ()
.getParentView () : edge.getSourceParentView ();
if ( sourceParent != null )
{
// MODIFYBEGIN
int offsetX = 0;
int offsetY = 0;
if ( sourceParent instanceof StateView )
{
StateView stateView = ( StateView ) sourceParent;
if ( stateView.getCell () instanceof DefaultStateView )
{
DefaultStateView defaultStateView = ( DefaultStateView ) stateView
.getCell ();
State state = defaultStateView.getState ();
if ( state.isStartState () )
{
offsetX = StateView.START_OFFSET;
}
if ( state.isLoopTransition () )
{
offsetY = StateView.LOOP_TRANSITION_OFFSET;
}
}
}
Point2D from = AbstractCellView.getCenterPoint ( sourceParent );
Rectangle2D rect = sourceParent.getBounds ();
double width = rect.getWidth () - offsetX;
double height2 = ( rect.getHeight () - offsetY ) / 2;
double loopWidth = 10;
double loopHeight = 15;
newPoints.add ( edge.getAttributes ().createPoint (
from.getX () + offsetX / 2 - loopWidth,
from.getY () + offsetY / 2 - height2 - loopHeight * 1.2 ) );
newPoints.add ( edge.getAttributes ().createPoint (
from.getX () + offsetX / 2,
from.getY () + offsetY / 2 - height2 - 1.5 * loopHeight ) );
newPoints.add ( edge.getAttributes ().createPoint (
from.getX () + offsetX / 2 + loopWidth,
from.getY () + offsetY / 2 - height2 - loopHeight * 1.2 ) );
newPoints.add ( edge.getTarget () );
// MODIFYEND
return newPoints;
}
return null;
}
}
/** Source and target of the edge. */
protected Object source, target;
/**
* Constructs an empty edge.
*/
public DefaultEdge ()
{
this ( null );
}
/**
* Constructs an edge that holds a reference to the specified user object.
*
* @param userObject reference to the user object
*/
public DefaultEdge ( Object userObject )
{
this ( userObject, null );
}
/**
* Constructs an edge that holds a reference to the specified user object and
* sets default values for points and the label position.
*
* @param userObject reference to the user object
*/
public DefaultEdge ( Object userObject, AttributeMap storageMap )
{
super ( userObject, storageMap );
}
/**
* Create a clone of the cell. The cloning of the user object is deferred to
* the cloneUserObject() method. The source and target references are set to
* null.
*
* @return Object a clone of this object.
*/
public Object clone ()
{
DefaultEdge edge = ( DefaultEdge ) super.clone ();
edge.source = null;
edge.target = null;
return edge;
}
/**
* Returns the source of the edge.
*/
public Object getSource ()
{
return this.source;
}
/**
* Returns the target of the edge.
*/
public Object getTarget ()
{
return this.target;
}
//
// Default Routing
//
/**
* Sets the source of the edge.
*/
public void setSource ( Object port )
{
this.source = port;
}
/**
* Returns the target of <code>edge</code>.
*/
public void setTarget ( Object port )
{
this.target = port;
}
}