From: lempinen Date: Tue, 1 Dec 2009 15:50:56 +0000 (+0000) Subject: Arrowheads X-Git-Tag: simantics-1.0~115 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=b0e44c5a8cbc5e13fe504cce4c1fe4e0cfc95a6c;p=simantics%2Fsysdyn.git Arrowheads git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@13205 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java index 2642aa52..2675900c 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java @@ -1,6 +1,5 @@ package org.simantics.sysdyn.ui.elements; -import java.awt.Shape; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; @@ -17,167 +16,214 @@ import org.simantics.scenegraph.g2d.G2DParentNode; @GraphType("http://www.simantics.org/Sysdyn#Flow") public class FlowElement extends Element implements IElementListener { - public static double ARROW_LENGTH1 = 0.2; - public static double ARROW_LENGTH2 = 3.0; - public static double ARROW_WIDTH = 1.8; - + public static double ARROW_LENGTH = 3.2; + public static double ARROW_WIDTH = 3; + static final double OFFSET = 1.5; - - /* - * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2 - */ + static final double ARROW_OFFSET = 3.2; + + /* + * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2 + */ @RelatedElement("http://www.simantics.org/Sysdyn#HasTail") - Connectable tail; + Connectable tail; @RelatedElement("http://www.simantics.org/Sysdyn#HasHead") - Connectable head; - double angle = 0.1; - - // Auxiliary - double angle0; - double angle1; - double cx; - double cy; - double r; - - // Scene graph - ShapeNode lineNode1; - ShapeNode lineNode2; - FilledShapeNode arrowNode; - - public FlowElement() { - } - - public FlowElement(Connectable tail, Connectable head) { - super(); - this.tail = tail; - this.head = head; - } - - @Override - public void elementUpdated(IElement element) { - update(); - } - - @Override - public void remove() { - lineNode1.remove(); - lineNode2.remove(); - tail.removeListener(this); - head.removeListener(this); - } - - @Override - public void init(G2DParentNode parent) { - tail.addListener(this); - head.addListener(this); - - lineNode1 = parent.addNode(ShapeNode.class); - lineNode1.setScaleStroke(true); - lineNode2 = parent.addNode(ShapeNode.class); - lineNode2.setScaleStroke(true); - - //arrowNode = parent.addNode(FilledShapeNode.class); - update(); - } - - protected Shape createArrow(double x, double y, double dx, double dy) { + Connectable head; + double angle = 0.1; + + // Auxiliary + double angle0; + double angle1; + double cx; + double cy; + double r; + + // Scene graph + ShapeNode lineNode1; + ShapeNode lineNode2; + FilledShapeNode arrowNode; + + public FlowElement() { + } + + public FlowElement(Connectable tail, Connectable head) { + super(); + this.tail = tail; + this.head = head; + } + + @Override + public void elementUpdated(IElement element) { + update(); + } + + @Override + public void remove() { + lineNode1.remove(); + lineNode2.remove(); + tail.removeListener(this); + head.removeListener(this); + } + + @Override + public void init(G2DParentNode parent) { + tail.addListener(this); + head.addListener(this); + + lineNode1 = parent.addNode(ShapeNode.class); + lineNode1.setScaleStroke(true); + lineNode2 = parent.addNode(ShapeNode.class); + lineNode2.setScaleStroke(true); + + arrowNode = parent.addNode(FilledShapeNode.class); + update(); + } + + protected void createArrow(Connectable head, Connectable tail) { + double x = tail.getOrigo().getX(); + double y = tail.getOrigo().getY(); + + Rectangle2D rect = new Rectangle2D.Double(); + head.getBounds(rect); + double cx = rect.getCenterX(); + double minx = rect.getMinX(); + double maxx = rect.getMaxX(); + double miny = rect.getMinY(); + double maxy = rect.getMaxY(); + Path2D path = new Path2D.Double(); - path.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy); - x -= ARROW_LENGTH2*dx; - y -= ARROW_LENGTH2*dy; - path.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx); - path.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx); + + // approach from top + if (y < miny) { + path.moveTo(cx, miny); + path.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH); + path.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH); + } + + // approach from beneath + else if (y > maxy) { + path.moveTo(cx, maxy); + path.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH); + path.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH); + } + + // approach from left + else if (x < minx) { + path.moveTo(minx, y); + path.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH); + path.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH); + } + + // approach from right + else if (x > maxx) { + path.moveTo(maxx, y); + path.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH); + path.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH); + } + path.closePath(); - return path; + arrowNode.setShape(path); } - - // TODO - - private void draw(boolean vertical, double ... coordinates) { - lineNode1.setShape(Flows.createOffsetLine(vertical, OFFSET, coordinates)); - lineNode2.setShape(Flows.createOffsetLine(vertical, -OFFSET, coordinates)); - } - - private void draw(Connectable valve, Connectable node) { - double x0 = valve.getOrigo().getX(); - double y0 = valve.getOrigo().getY(); - double x1 = node.getOrigo().getX(); - double y1 = node.getOrigo().getY(); - - Rectangle2D rect = new Rectangle2D.Double(); - node.getBounds(rect); - if( ((ValveElement)valve).rotated ) { - if(y1 > y0) - y0 += OFFSET; - else - y0 -= OFFSET; - if(rect.getMinX() <= x0 && rect.getMaxX() >= x0) { - if(y1 > y0) - draw(true, y0, x0, rect.getMinY()); - else - draw(true, y0, x0, rect.getMaxY()); - } - else { - if(x1 > x0) - draw(true, y0, x0, y1, rect.getMinX()); - else - draw(true, y0, x0, y1, rect.getMaxX()); - } - } - else { - if(x1 > x0) - x0 += OFFSET; - else - x0 -= OFFSET; - if(rect.getMinY() <= y0 && rect.getMaxY() >= y0) { - if(x1 > x0) - draw(false, x0, y0, rect.getMinX()); - else - draw(false, x0, y0, rect.getMaxX()); - } - else { - if(y1 > y0) - draw(false, x0, y0, x1, rect.getMinY()); - else - draw(false, x0, y0, x1, rect.getMaxY()); - } - } - } - - protected void updateSceneGraph() { - if(tail instanceof ValveElement) - draw(tail, head); - else if(head instanceof ValveElement) - draw(head, tail); - } - - // TODO - - public void update() { - if(lineNode1 != null) - updateSceneGraph(); - super.update(); - } - - @Override - public void getBounds(Rectangle2D bounds) { - bounds.setFrame(lineNode1.getBounds()); - } - - @Override - public boolean hitTest(double x, double y, double tolerance) { + + // TODO + + private void draw(boolean vertical, double ... coordinates) { + lineNode1.setShape(Flows.createOffsetLine(vertical, OFFSET, coordinates)); + lineNode2.setShape(Flows.createOffsetLine(vertical, -OFFSET, coordinates)); + } + + private void draw(boolean hasArrow, Connectable valve, Connectable node) { + double x0 = valve.getOrigo().getX(); + double y0 = valve.getOrigo().getY(); + double x1 = node.getOrigo().getX(); + double y1 = node.getOrigo().getY(); + + Rectangle2D rect = new Rectangle2D.Double(); + node.getBounds(rect); + + double minY = hasArrow ? rect.getMinY() - ARROW_OFFSET : rect.getMinY(); + double maxY = hasArrow ? rect.getMaxY() + ARROW_OFFSET : rect.getMaxY(); + double minX = hasArrow ? rect.getMinX() - ARROW_OFFSET : rect.getMinX(); + double maxX = hasArrow ? rect.getMaxX() + ARROW_OFFSET : rect.getMaxX(); + + + if( ((ValveElement)valve).rotated ) { + if(y1 > y0) + y0 += OFFSET; + else + y0 -= OFFSET; + if(rect.getMinX() <= x0 && rect.getMaxX() >= x0) { + if(y1 > y0) + draw(true, y0, x0, minY); + else + draw(true, y0, x0, maxY); + } + else { + if(x1 > x0) + draw(true, y0, x0, y1, minX); + else + draw(true, y0, x0, y1, maxX); + } + } + else { + if(x1 > x0) + x0 += OFFSET; + else + x0 -= OFFSET; + if(rect.getMinY() <= y0 && rect.getMaxY() >= y0) { + if(x1 > x0) + draw(false, x0, y0, minX); + else + draw(false, x0, y0, maxX); + } + else { + if(y1 > y0) + draw(false, x0, y0, x1, minY); + else + draw(false, x0, y0, x1, maxY); + } + } + + + } + + protected void updateSceneGraph() { + boolean hasArrow = tail instanceof ValveElement && !(head instanceof ValveElement); + if(tail instanceof ValveElement) + draw(hasArrow, tail, head); + else if(head instanceof ValveElement) + draw(hasArrow, head, tail); + if(hasArrow) + createArrow(head, tail); + } + + // TODO + + public void update() { + if(lineNode1 != null) + updateSceneGraph(); + super.update(); + } + + @Override + public void getBounds(Rectangle2D bounds) { + bounds.setFrame(lineNode1.getBounds()); + } + + @Override + public boolean hitTest(double x, double y, double tolerance) { // TODO return false; - } - - @Override - public T getInterface(Class clazz) { - return super.getInterface(clazz); - } - - @Override - public void elementRemoved(IElement element) { - remove(); - } - + } + + @Override + public T getInterface(Class clazz) { + return super.getInterface(clazz); + } + + @Override + public void elementRemoved(IElement element) { + remove(); + } + }