package org.xmind.ui.internal.decorations;
import org.eclipse.draw2d.IFigure;
import org.xmind.gef.draw2d.geometry.Geometry;
import org.xmind.gef.draw2d.geometry.PrecisionPoint;
import org.xmind.gef.draw2d.graphics.Path;
import org.xmind.ui.decorations.AbstractRelationshipDecoration;
public class ZigzagRelationshipDecoration extends
AbstractRelationshipDecoration {
public ZigzagRelationshipDecoration() {
super();
}
public ZigzagRelationshipDecoration(String id) {
super(id);
}
protected void route(IFigure figure, Path shape) {
PrecisionPoint sp = getSourcePosition(figure);
PrecisionPoint tp = getTargetPosition(figure);
PrecisionPoint scp = new PrecisionPoint(getSourceControlPoint(figure));
PrecisionPoint tcp = new PrecisionPoint(getTargetControlPoint(figure));
if (Math.abs(tcp.x - tp.x) <= Math.abs(tcp.y - tp.y)) { //target
tcp.x = tp.x; // 1,3
} else {
tcp.y = tp.y; // 2,4
}
if (Math.abs(scp.x - sp.x) <= Math.abs(scp.y - sp.y)) { //source
scp.x = sp.x; // 1,3
} else {
scp.y = sp.y; // 2,4
}
if (tcp.x == tp.x) {
if (scp.x == sp.x) {
tcp.y = scp.y = (scp.y + tcp.y) / 2;
} else if (scp.y == sp.y) {
tcp.y = scp.y = sp.y;
scp.x = tp.x;
}
} else if (tcp.y == tp.y) {
if (scp.y == sp.y) {
tcp.x = scp.x = (tcp.x + scp.x) / 2;
// tcp.x = scp.x = (tp.x + sp.x) / 2;
// tcp.y = scp.y = sp.y;
} else if (scp.x == sp.x) {
tcp.x = scp.x = sp.x;
scp.y = tp.y;
}
}
shape.moveTo(sp);
shape.lineTo(scp);
shape.lineTo(tcp);
shape.lineTo(tp);
}
protected double getSourceAnchorAngle(IFigure figure) {
PrecisionPoint sp = getSourcePosition(figure);
PrecisionPoint tp = getTargetPosition(figure);
PrecisionPoint scp = new PrecisionPoint(getSourceControlPoint(figure));
PrecisionPoint tcp = getTargetControlPoint(figure);
PrecisionPoint p1 = new PrecisionPoint(0.0, 0.0);
PrecisionPoint p2 = new PrecisionPoint(0.0, 0.0);
if (Math.abs(scp.x - sp.x) <= Math.abs(scp.y - sp.y)) {
if (tp.y < sp.y) { //3
p1 = new PrecisionPoint(0, 1);
p2 = new PrecisionPoint(0, 0);
if ((tcp.y + scp.y) / 2 > sp.y) {
p1 = new PrecisionPoint(0, -1);
p2 = new PrecisionPoint(0, 0);
}
} else if (tp.y > sp.y) { // 1
p1 = new PrecisionPoint(0, -1);
p2 = new PrecisionPoint(0, 0);
if ((tcp.y + scp.y) / 2 < sp.y) {
p1 = new PrecisionPoint(0, 1);
p2 = new PrecisionPoint(0, 0);
}
}
} else {
if (tp.x < sp.x) { //4
p1 = new PrecisionPoint(1, 0);
p2 = new PrecisionPoint(0, 0);
if ((tcp.x + scp.x) / 2 > sp.x) {
p1 = new PrecisionPoint(0, 0);
p2 = new PrecisionPoint(0, 0);
}
} else if (tp.x > sp.x) { //2
p1 = new PrecisionPoint(0, 0);
p2 = new PrecisionPoint(0, 0);
if ((tcp.x + scp.x) / 2 < sp.x) {
p1 = new PrecisionPoint(1, 0);
p2 = new PrecisionPoint(0, 0);
}
}
}
return Geometry.getAngle(p2, p1);
}
protected double getTargetAnchorAngle(IFigure figure) {
PrecisionPoint sp = getSourcePosition(figure);
PrecisionPoint tp = getTargetPosition(figure);
PrecisionPoint tcp = getTargetControlPoint(figure);
PrecisionPoint scp = getSourceControlPoint(figure);
PrecisionPoint p1 = new PrecisionPoint(0.0, 0.0);
PrecisionPoint p2 = new PrecisionPoint(0.0, 0.0);
if (Math.abs(tcp.x - tp.x) <= Math.abs(tcp.y - tp.y)) {
if (tp.y > sp.y) { // 3
p1 = new PrecisionPoint(0, 1);
p2 = new PrecisionPoint(0, 0);
if ((tcp.y + scp.y) / 2 > tp.y) {
p1 = new PrecisionPoint(0, -1);
p2 = new PrecisionPoint(0, 0);
}
} else if (tp.y < sp.y) {// 1
p1 = new PrecisionPoint(0, -1);
p2 = new PrecisionPoint(0, 0);
if ((tcp.y + scp.y) / 2 < tp.y) {
p1 = new PrecisionPoint(0, 1);
p2 = new PrecisionPoint(0, 0);
}
}
} else {
if (tp.x < sp.x) { // 2
p1 = new PrecisionPoint(-1, 0);
p2 = new PrecisionPoint(0, 0);
if ((tcp.x + scp.x) / 2 < tp.x) {
p1 = new PrecisionPoint(1, 0);
p2 = new PrecisionPoint(0, 0);
}
} else if (tp.x > sp.x) { // 4
p1 = new PrecisionPoint(1, 0);
p2 = new PrecisionPoint(0, 0);
if ((tcp.x + scp.x) / 2 > tp.x) {
p1 = new PrecisionPoint(-1, 0);
p2 = new PrecisionPoint(0, 0);
}
}
}
return Geometry.getAngle(p2, p1);
}
protected void calcTitlePosition(IFigure figure, PrecisionPoint titlePos,
PrecisionPoint sourcePos, PrecisionPoint targetPos,
PrecisionPoint sourceCP, PrecisionPoint targetCP) {
double x = 0.0, y = 0.0;
double targetXOffset = Math.abs(targetCP.x - targetPos.x);
double targetYOffset = Math.abs(targetCP.y - targetPos.y);
double sourceXOffset = Math.abs(sourceCP.x - sourcePos.x);
double sourceYOffset = Math.abs(sourceCP.y - sourcePos.y);
if (targetXOffset <= targetYOffset && sourceXOffset <= sourceYOffset) {
x = (sourcePos.x + targetPos.x) / 2;
y = (sourceCP.y + targetCP.y) / 2;
} else if (targetXOffset <= targetYOffset
&& sourceXOffset > sourceYOffset) {
x = targetPos.x;
y = sourcePos.y;
} else if (targetXOffset > targetYOffset
&& sourceXOffset <= sourceYOffset) {
x = sourcePos.x;
y = targetPos.y;
} else if (targetXOffset > targetYOffset
&& sourceXOffset > sourceYOffset) {
x = (sourceCP.x + targetCP.x) / 2;
y = (sourcePos.y + targetPos.y) / 2;
}
titlePos.setLocation(x, y);
}
}