/* * Copyright (C) Yutaka Matsuno 2010-2012 All rights reserved. */ package net.dependableos.dcase.diagram.editor.layout; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.graph.Edge; import org.eclipse.draw2d.graph.EdgeList; import org.eclipse.draw2d.graph.Node; /** * This class locates edges. */ public class LocateEdgeGraphVisitor extends DcaseGraphVisitor { /** * the edge direction - right. */ private static final int LEFT_TO_RIGHT = 1; /** * the edge direction - left. */ private static final int RIGHT_TO_LEFT = 2; /** * the edge direction - top. */ private static final int BOTTOM_TO_TOP = 3; /** * the edge direction - bottom. */ private static final int TOP_TO_BOTTOM = 4; /** * the gap. */ private static final int GAP = 3; /** * Locates the edges. * * @param graph the direct graph. */ @Override protected void visit(DcaseDirectedGraph graph) { super.visit(graph); locateEdge(); } /** * Locates the edges. */ private void locateEdge() { EdgeList list = getGraph().getEdgeList(); for (int i = 0; i < list.size(); i++) { Edge edge = list.getEdge(i); Node source = edge.source; Node target = edge.target; Point start = new Point(); Point end = new Point(); PointList mid = new PointList(); int direction = getDirection(source, target); switch (direction) { case LEFT_TO_RIGHT: start.x = source.x + source.width; start.y = source.y + source.height / 2; end.x = target.x; end.y = target.y + target.height / 2; break; case RIGHT_TO_LEFT: start.x = source.x; start.y = source.y + source.height / 2; end.x = target.x + target.width; end.y = target.y + target.height / 2; break; case BOTTOM_TO_TOP: start.x = source.x + source.width / 2; start.y = source.y; end.x = target.x + target.width / 2; end.y = target.y + target.height; break; default: start.x = source.x + source.width / 2; start.y = source.y + source.height; end.x = target.x + target.width / 2; end.y = target.y; } if (getNodeEx(target).getLooped()) { if (direction == BOTTOM_TO_TOP || direction == RIGHT_TO_LEFT) { if (Math.abs(start.x - end.x) < GAP) { end.x = target.x + target.width / 2; end.y = target.y + target.height; int xPoint = start.x - source.width / 2 - VERTICAL_SPACING; mid.addPoint(xPoint, start.y - HORIZONTAL_SPACING / 2); mid.addPoint(xPoint, end.y + (start.y - end.y) / 2); mid.addPoint(xPoint, end.y + HORIZONTAL_SPACING / 2); } else if (Math.abs(start.y - end.y) < GAP) { end.x = target.x + target.width; end.y = target.y + target.height / 2; int yPoint = start.y - source.height / 2 - HORIZONTAL_SPACING; mid.addPoint(start.x - VERTICAL_SPACING / 2, yPoint); mid.addPoint(end.x + (start.x - end.x) / 2, yPoint); mid.addPoint(end.x + VERTICAL_SPACING / 2, yPoint); } } } edge.getPoints().removeAllPoints(); edge.getPoints().addPoint(start); for (int j = 0; j < mid.size(); j++) { edge.getPoints().addPoint(mid.getPoint(j)); } edge.getPoints().addPoint(end); edge.getPoints(); } } /** * Returns the direction of a link. * * @param source the source. * @param target the target. * @return the direction of a link. */ private int getDirection(Node source, Node target) { int result = 0; if (ArrangeAngle.createInstance().getAngle() == ArrangeAngle.Direction.Vertical) { if (DcaseDirectedGraph.isEast(target)) { if (source.x < target.x) { result = LEFT_TO_RIGHT; } else { result = RIGHT_TO_LEFT; } } else { if (source.y > target.y) { result = BOTTOM_TO_TOP; } else { result = TOP_TO_BOTTOM; } } } else { if (!DcaseDirectedGraph.isEast(target)) { if (source.x < target.x) { result = LEFT_TO_RIGHT; } else { result = RIGHT_TO_LEFT; } } else { if (source.y > target.y) { result = BOTTOM_TO_TOP; } else { result = TOP_TO_BOTTOM; } } } return result; } }