/*
* PIPELineWithTextEdgePainter.java
*/
package pipe.gui.reachability;
import net.sourceforge.jpowergraph.SubGraphHighlighter;
import net.sourceforge.jpowergraph.painters.edge.LineEdgePainter;
import net.sourceforge.jpowergraph.pane.JGraphPane;
import net.sourceforge.jpowergraph.swtswinginteraction.JPowerGraphGraphics;
import net.sourceforge.jpowergraph.swtswinginteraction.color.JPowerGraphColor;
import net.sourceforge.jpowergraph.swtswinginteraction.geometry.JPowerGraphPoint;
import java.awt.geom.Point2D;
//REMARK: this class extends a jpowergraph's class which is LGPL
/**
* This class defines the edge painter for edges with text used in the reachability graph
*/
public class PIPELineWithTextEdgePainter<T extends DirectedTextEdge> extends LineEdgePainter<T> {
/**
* Constructor
* @param dragging dragging
* @param normal normal
* @param isDashedLine true if dashed
*/
public PIPELineWithTextEdgePainter(JPowerGraphColor dragging, JPowerGraphColor normal, boolean isDashedLine) {
super(dragging, normal, isDashedLine);
}
/**
* Displays the edge and text on the graph
* @param graphPane graph pane
* @param g graphics
* @param edge edge
* @param theSubGraphHighlighter highlighter
*/
@Override
public void paintEdge(JGraphPane graphPane, JPowerGraphGraphics g, T edge,
SubGraphHighlighter theSubGraphHighlighter) {
JPowerGraphPoint from = graphPane.getScreenPointForNode(edge.getFrom());
JPowerGraphPoint to = graphPane.getScreenPointForNode(edge.getTo());
JPowerGraphColor oldFGColor = g.getForeground();
JPowerGraphColor oldBGColor = g.getBackground();
g.setForeground(getEdgeColor(edge, graphPane, false, theSubGraphHighlighter));
g.setBackground(getEdgeColor(edge, graphPane, false, theSubGraphHighlighter));
paintArrow(g, from.x, from.y, to.x, to.y, false);
g.setForeground(oldFGColor);
g.setBackground(oldBGColor);
String text = edge.getText();
Point2D midpoint = new Point2D.Double((from.x + 2 * to.x) / 3, (from.y + 2 * to.y) / 3);
double slopeTop = from.y - to.y;
double slopeBottom = from.x - to.x;
double slope = Double.POSITIVE_INFINITY;
if (slopeBottom != 0) {
slope = slopeTop / slopeBottom;
}
int stringWidth = g.getStringWidth(text);
if (slope > 2.0) {
double xDiff = -(stringWidth + 10);
double yDiff = -10;
if (from.y < to.y) {
yDiff = -5;
}
midpoint.setLocation(midpoint.getX() + xDiff, midpoint.getY() + yDiff);
} else if (slope < -2.0) {
double xDiff = 10;
double yDiff = -10;
if (from.y < to.y) {
yDiff = -5;
}
midpoint.setLocation(midpoint.getX() + xDiff, midpoint.getY() + yDiff);
} else if (slope > 0.4 || slope < -0.4) {
double xDiff = 10;
double yDiff = -10;
if (from.x > to.x) {
xDiff = -(stringWidth + 10);
}
if (from.y < to.y) {
yDiff = -5;
}
midpoint.setLocation(midpoint.getX() + xDiff, midpoint.getY() + yDiff);
} else {
double xDiff = -stringWidth / 2;
double yDiff = -20;
midpoint.setLocation(midpoint.getX() + xDiff, midpoint.getY() + yDiff);
}
g.setForeground(getEdgeColor(edge, graphPane, false, theSubGraphHighlighter));
g.drawString(text, (int) midpoint.getX(), (int) midpoint.getY(), 1);
g.setForeground(oldFGColor);
}
/**
* Paints an arrow in the correct direction
* @param g graphics
* @param x1 coordinate
* @param y1 coordinate
* @param x2 coordinate
* @param y2 coordinate
* @param isDashedLine true if dashed
*/
public static void paintArrow(JPowerGraphGraphics g, int x1, int y1, int x2, int y2, boolean isDashedLine) {
double middleX = (x1 + 2 * x2) / 3;
double middleY = (y1 + 2 * y2) / 3;
double slope = Math.atan2(y2 - y1, x2 - x1);
double pinnacleX = middleX + SQUARE_ROOT_OF_3_OVER_2 * ARROW_BASE_LENGTH * Math.cos(slope);
double pinnacleY = middleY + SQUARE_ROOT_OF_3_OVER_2 * ARROW_BASE_LENGTH * Math.sin(slope);
double backwardX = pinnacleX + ARROW_BASE_LENGTH * Math.cos(slope + Math.PI + Math.PI / 6.0);
double backwardY = pinnacleY + ARROW_BASE_LENGTH * Math.sin(slope + Math.PI + Math.PI / 6.0);
double forwardX = pinnacleX + ARROW_BASE_LENGTH * Math.cos(slope + Math.PI - Math.PI / 6.0);
double forwardY = pinnacleY + ARROW_BASE_LENGTH * Math.sin(slope + Math.PI - Math.PI / 6.0);
double baseX = (forwardX + backwardX) / 2.0;
double baseY = (forwardY + backwardY) / 2.0;
g.setLineDashed(isDashedLine);
g.drawLine(x1, y1, (int) baseX, (int) baseY);
g.drawLine((int) pinnacleX, (int) pinnacleY, x2, y2);
g.setLineDashed(false);
g.fillPolygon(new int[]{(int) backwardX, (int) backwardY, (int) pinnacleX, (int) pinnacleY, (int) forwardX,
(int) forwardY});
}
}