package iiuf.swing.graph;
import java.awt.Component;
import java.awt.Stroke;
import java.awt.BasicStroke;
import java.awt.Point;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Polygon;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import iiuf.awt.Awt;
/**
Graph edge encapsulation.<p>
(c) 2000, 2001, IIUF, DIUF<p>
@author $Author: ohitz $
@version $Name: $ $Revision: 1.1 $
*/
public class GraphEdge {
private static final EdgeMarker[] MDFLT = new EdgeMarker[0];
private static final double[] PDFLT = new double[0];
private static final Stroke SDFLT = new BasicStroke();
public EdgeMarker[] markers = MDFLT;
public double[] markerpos = PDFLT;
public int[] markerwidth;
public Stroke stroke = SDFLT;
public Color color = Color.black;
public Component startcmp;
public GraphNodePort startport;
public Component endcmp;
public GraphNodePort endport;
public Polygon polyline;
public AffineTransform[] mtrans;
public GraphEdge(Component startcmp,
GraphNodePort startport,
Component endcmp,
GraphNodePort endport) {
setStart(startcmp, startport);
setEnd(endcmp, endport);
}
public GraphEdge(Component startcmp,
GraphNodePort startport,
Component endcmp,
GraphNodePort endport,
EdgeMarker[] markers, double[] markerpos) {
this(startcmp, startport, endcmp, endport);
setMarkers(markers, markerpos);
}
public GraphEdge(Component startcmp,
GraphNodePort startport,
Component endcmp,
GraphNodePort endport,
EdgeMarker[] markers, double[] markerpos, Stroke stroke, Color color) {
this(startcmp, startport, endcmp, endport);
setMarkers(markers, markerpos);
setStroke(stroke);
setColor(color);
}
public void setStart(Component cmp, GraphNodePort port) {
startcmp = cmp;
startport = port;
}
public void setEnd(Component cmp, GraphNodePort port) {
endcmp = cmp;
endport = port;
}
public void setAdjacent(Component cmpRef, Component cmpToSet, GraphNodePort portToSet) {
if(cmpRef == startcmp)
setEnd(cmpToSet, portToSet);
else
setStart(cmpToSet, portToSet);
}
public void setStroke(Stroke stroke_) {
stroke = stroke_;
}
public Stroke getStroke() {
return stroke;
}
public void setMarkers(EdgeMarker[] markers_, double[] markerpos_) {
markers = markers_;
markerpos = markerpos_;
markerwidth = new int[markerpos.length];
mtrans = new AffineTransform[markerpos.length];
}
public void setColor(Color color_) {
color = color_;
}
public Color getColor() {
return color;
}
private Rectangle polyRect;
private Rectangle boundsCache;
public Rectangle getBounds() {
Rectangle pbounds = polyline.getBounds();
if(polyRect != pbounds) {
polyRect = pbounds;
boundsCache = (Rectangle)pbounds.clone();
boundsCache.width++;
boundsCache.height++;
}
return boundsCache;
}
public Rectangle getBounds(Rectangle result) {
Rectangle tmp = polyline.getBounds();
result.x = tmp.x;
result.y = tmp.y;
result.width = tmp.width + 1;
result.height = tmp.height + 1;
return result;
}
public void paint(Graphics g) {
if(polyline == null) return;
g.setColor(color);
((Graphics2D)g).setStroke(stroke);
g.drawPolyline(polyline.xpoints, polyline.ypoints, polyline.npoints);
}
public void paintMarkers(Graphics g) {
if(polyline != null && markers.length > 0) {
Graphics2D g2 = (Graphics2D)g;
AffineTransform svTrans = g2.getTransform();
for(int i = 0; i < markers.length; i++) {
g2.transform(mtrans[i]);
markers[i].paint(g, markerwidth[i]);
g2.setTransform(svTrans);
}
}
}
public boolean pointIsNear(int x, int y, int tolerance) {
if(polyline == null) return false;
for(int j = 0; j < polyline.npoints - 1; j++)
if(Awt.near(x, y, polyline.xpoints[j], polyline.ypoints[j], polyline.xpoints[j + 1], polyline.ypoints[j + 1], tolerance))
return true;
return false;
}
public boolean containedIn(Rectangle r) {
return r.contains(getBounds());
}
private int siam(int p0x, int p0y, int p1x, int p1y, int p2x, int p2y) {
int dx1 = p1x - p0x;
int dy1 = p1y - p0y;
int dx2 = p2x - p0x;
int dy2 = p2y - p0y;
if(dx1 * dy2 > dy1 * dx2) return 1;
if(dx1 * dy2 < dy1 * dx2) return -1;
if((dx1 * dx2 < 0) || (dy1 * dy2 <0)) return -1;
if((dx1 * dx1 + dy1 * dy1) < (dx2 * dx2 + dy2 * dy2)) return 1;
return 0;
}
private boolean intersects(int s1x0, int s1y0, int s1x1, int s1y1, int s2x0, int s2y0, int s2x1, int s2y1) {
return
((siam(s1x0, s1y0, s1x1, s1y1, s2x0, s2y0) * siam(s1x0, s1y0, s1x1, s1y1, s2x1, s2y1)) <= 0) &&
((siam(s2x0, s2y0, s2x1, s2y1, s1x0, s1y0) * siam(s2x0, s2y0, s2x1, s2y1, s1x1, s1y1)) <= 0);
}
public boolean intersectsWith(Rectangle r) {
if(r.intersects(getBounds())) {
if(r.contains(polyline.xpoints[0], polyline.ypoints[0]))
return true;
for(int j = 0; j < polyline.npoints - 1; j++) {
if(r.contains(polyline.xpoints[j + 1], polyline.ypoints[j + 1]))
return true;
if(intersects(r.x, r.y, r.x + r.width, r.y,
polyline.xpoints[j], polyline.ypoints[j], polyline.xpoints[j + 1], polyline.ypoints[j + 1]))
return true;
if(intersects(r.x, r.y + r.height, r.x + r.width, r.y + r.height,
polyline.xpoints[j], polyline.ypoints[j], polyline.xpoints[j + 1], polyline.ypoints[j + 1]))
return true;
if(intersects(r.x, r.y, r.x, r.y + r.height,
polyline.xpoints[j], polyline.ypoints[j], polyline.xpoints[j + 1], polyline.ypoints[j + 1]))
return true;
if(intersects(r.x + r.width, r.y, r.x + r.width, r.y + r.height,
polyline.xpoints[j], polyline.ypoints[j], polyline.xpoints[j + 1], polyline.ypoints[j + 1]))
return true;
}
}
return false;
}
public String toString() {
return "(" + startport.x + "," + startport.y + "),(" + endport.x + "," + endport.y + ")";
}
}
/*
$Log: GraphEdge.java,v $
Revision 1.1 2002/07/11 12:09:52 ohitz
Initial checkin
Revision 1.5 2001/03/11 17:59:38 schubige
Fixed various soundium and iiuf.swing.graph bugs
Revision 1.4 2001/03/09 15:30:51 schubige
Added markers to graph panel
Revision 1.3 2001/03/07 17:36:28 schubige
soundium properties panel beta
Revision 1.2 2001/02/19 15:10:38 schubige
Fixed graph edge port location bug
Revision 1.1 2001/02/17 09:54:21 schubige
moved graph stuff to iiuf.swing.graph, started work on rotatable GraphNodeComponents
Revision 1.7 2001/02/16 13:47:38 schubige
Adapted soundium to new rtsp version
Revision 1.6 2001/02/15 16:00:43 schubige
Improved graph panel, fixed some soundium bugs
Revision 1.5 2001/02/13 14:49:06 schubige
started work on gui - engine connection
Revision 1.4 2001/01/04 16:28:38 schubige
Header update for 2001 and DIUF
Revision 1.3 2000/12/29 08:03:55 schubige
SourceWatch beta debug iter 1
Revision 1.2 2000/12/18 12:39:09 schubige
Added ports to iiuf.util.graph
Revision 1.1 2000/08/17 16:22:14 schubige
Swing cleanup & TreeView added
Revision 1.2 2000/07/28 12:06:54 schubige
Graph stuff update
Revision 1.1 2000/07/14 13:56:20 schubige
Added graph view stuff
*/