+++ /dev/null
-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.sysdyn.ui.elements2.connections;\r
-\r
-import java.awt.Color;\r
-import java.awt.Stroke;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.GeneralPath;\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.PathIterator;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import org.simantics.g2d.diagram.DiagramHints;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.Topology;\r
-import org.simantics.g2d.diagram.handler.Topology.Connection;\r
-import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil;\r
-import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.BendsHandler;\r
-import org.simantics.g2d.element.handler.EdgeVisuals;\r
-import org.simantics.g2d.element.handler.EdgeVisuals.ArrowType;\r
-import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
-import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals;\r
-import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;\r
-import org.simantics.g2d.element.handler.impl.FillColorImpl;\r
-import org.simantics.g2d.element.handler.impl.ParentImpl;\r
-import org.simantics.g2d.element.handler.impl.ShapePick;\r
-import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
-import org.simantics.g2d.elementclass.BranchPoint;\r
-import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler;\r
-import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;\r
-import org.simantics.g2d.elementclass.connection.EdgeSceneGraph;\r
-import org.simantics.g2d.routing.Constants;\r
-import org.simantics.g2d.routing.IRouter2;\r
-import org.simantics.g2d.utils.PathUtils;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.scenegraph.g2d.nodes.EdgeNode;\r
-import org.simantics.sysdyn.ui.editor.participant.SysdynConnectTool.SysdynConnection;\r
-import org.simantics.sysdyn.ui.editor.routing.FlowRouter;\r
-import org.simantics.sysdyn.ui.elements2.ValveFactory.ValveSceneGraph;\r
-\r
-public class FlowEdgeClassOld {\r
-\r
- // TODO scale, rotate, move, transform\r
- public static final ElementClass CLASS = ElementClass.compile(\r
- FlowEdgeSceneGraph.INSTANCE, EdgeHandler.INSTANCE,\r
- ConfigurableEdgeVisuals.DEFAULT, FillColorImpl.BLACK,\r
- FixedTransform.INSTANCE, ShapePick.INSTANCE,\r
- ConnectionSelectionOutline.INSTANCE, SimpleElementLayers.INSTANCE,\r
- ParentImpl.INSTANCE).setId("FlowEdgeClass");\r
-\r
- public static class FlowEdgeSceneGraph extends EdgeSceneGraph {\r
-\r
- private static final long serialVersionUID = -8737581995034992604L;\r
-\r
- public static final EdgeSceneGraph INSTANCE = new FlowEdgeSceneGraph();\r
-\r
- @Override\r
- public void init(IElement e, G2DParentNode parent) {\r
- ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE,\r
- "edge_" + e.hashCode(), FlowEdgeNodeOld.class);\r
- final IDiagram diagram = ElementUtils.peekDiagram(e);\r
-\r
- boolean toValve = false;\r
- if (diagram != null) {\r
- Topology topology = diagram.getDiagramClass()\r
- .getAtMostOneItemOfClass(Topology.class);\r
- if (topology != null) {\r
- Connection endConnection = topology.getConnection(e,\r
- EdgeEnd.End);\r
- toValve = endConnection.node.getElementClass()\r
- .containsClass(ValveSceneGraph.class);\r
- }\r
- }\r
-\r
- ConfigurableEdgeVisuals cev = e.getElementClass()\r
- .getAtMostOneItemOfClass(ConfigurableEdgeVisuals.class);\r
- if (cev != null) {\r
- if (toValve)\r
- cev.setArrowType(e, EdgeEnd.End, ArrowType.None);\r
- else {\r
- cev.setArrowType(e, EdgeEnd.End, ArrowType.Fill);\r
- cev.setArrowSize(e, EdgeEnd.End, 2);\r
- }\r
- }\r
-\r
- updateRoute(e);\r
- update(e);\r
-\r
- }\r
-\r
- private static Path2D trimLineToArrows(Path2D line,\r
- ArrowType endArrowType, double endArrowSize) {\r
- Path2D result = new Path2D.Double();\r
- PathIterator pi = line.getPathIterator(null);\r
-\r
- double lineTo[] = new double[2];\r
- double prevLine[] = new double[2];\r
- double dummy[] = new double[2];\r
-\r
- while (!pi.isDone()) {\r
- int type = pi.currentSegment(lineTo);\r
- pi.next();\r
- int nextType = pi.currentSegment(dummy);\r
-\r
- if (type == PathIterator.SEG_LINETO\r
- && nextType == PathIterator.SEG_MOVETO) {\r
- // this is the end of one line\r
- if (endArrowType == ArrowType.Fill) {\r
- double dx = (lineTo[0] - prevLine[0]);\r
- double dy = (lineTo[1] - prevLine[1]);\r
- double x2 = dx * dx;\r
- double y2 = dy * dy;\r
- double len = Math.sqrt(x2 + y2);\r
- if (len > endArrowSize) {\r
- double scale = endArrowSize / len;\r
- lineTo[0] -= dx * scale;\r
- lineTo[1] -= dy * scale;\r
- }\r
- }\r
- }\r
-\r
- if (type == 0) {\r
- result.moveTo(lineTo[0], lineTo[1]);\r
- } else if (type == 1) {\r
- result.lineTo(lineTo[0], lineTo[1]);\r
- } else {\r
- throw new UnsupportedOperationException(\r
- "invalid path segment type: " + type);\r
- }\r
- prevLine[0] = lineTo[0];\r
- prevLine[1] = lineTo[1];\r
-\r
- }\r
-\r
- result.setWindingRule(line.getWindingRule());\r
- return result;\r
- }\r
-\r
- private void updateRoute(final IElement e) {\r
-\r
- final List<IElement> segments = new ArrayList<IElement>();\r
- segments.add(e);\r
-\r
- IRouter2 router = ElementUtils.getHintOrDefault(e,\r
- DiagramHints.ROUTE_ALGORITHM, new FlowRouter());\r
-\r
- router.route(new SysdynConnection() {\r
-\r
- IDiagram diagram = ElementUtils.peekDiagram(e);\r
-\r
- final Topology topology = diagram.getDiagramClass()\r
- .getSingleItem(Topology.class);\r
-\r
- @Override\r
- public Connector getBegin(Object seg) {\r
- IElement e = (IElement) seg;\r
- Connection begin = topology.getConnection(e, EdgeEnd.Begin);\r
- return getConnector(begin);\r
- }\r
-\r
- @Override\r
- public Connector getEnd(Object seg) {\r
- IElement e = (IElement) seg;\r
- Connection end = topology.getConnection(e, EdgeEnd.End);\r
- return getConnector(end);\r
- }\r
-\r
- private Connector getConnector(Connection connection) {\r
- Connector c = new Connector();\r
- c.allowedDirections = Constants.EAST_FLAG | Constants.WEST_FLAG\r
- | Constants.NORTH_FLAG | Constants.SOUTH_FLAG;\r
- \r
- AffineTransform at = TerminalUtil.getTerminalPosOnDiagram(\r
- connection.node, connection.terminal);\r
- c.x = at.getTranslateX();\r
- c.y = at.getTranslateY();\r
-\r
- if (connection.node.getElementClass().containsClass(\r
- ValveSceneGraph.class)) {\r
- Rectangle2D bounds = ElementUtils\r
- .getElementBoundsOnDiagram(connection.node)\r
- .getBounds2D();\r
- c.parentObstacle = new Rectangle2D.Double(bounds\r
- .getCenterX() - FlowRouter.OFFSET, bounds\r
- .getCenterY() - FlowRouter.OFFSET,\r
- FlowRouter.OFFSET * 2, FlowRouter.OFFSET * 2);\r
- c.allowedDirections = Constants.EAST_FLAG | Constants.WEST_FLAG;\r
- } else {\r
- c.parentObstacle = ElementUtils\r
- .getElementBoundsOnDiagram(connection.node)\r
- .getBounds2D();\r
- \r
- }\r
-\r
- return c;\r
- }\r
-\r
- private int toAllowedDirections(BranchPoint.Direction direction) {\r
- switch (direction) {\r
- case Any:\r
- return 0xf;\r
- case Horizontal:\r
- return Constants.EAST_FLAG | Constants.WEST_FLAG;\r
- case Vertical:\r
- return Constants.NORTH_FLAG | Constants.SOUTH_FLAG;\r
- default:\r
- throw new IllegalArgumentException(\r
- "unrecognized direction: " + direction);\r
- }\r
- }\r
-\r
- @Override\r
- public Collection<? extends Object> getSegments() {\r
- return segments;\r
- }\r
-\r
- @Override\r
- public void setPath(Object seg, Path2D path) {\r
- IElement e = (IElement) seg;\r
- BendsHandler bends = e.getElementClass()\r
- .getAtMostOneItemOfClass(BendsHandler.class);\r
- AffineTransform elementTransform = ElementUtils\r
- .getInvTransform(e);\r
- path = (Path2D) path.clone();\r
- path.transform(elementTransform);\r
- bends.setPath(e, path);\r
- }\r
- });\r
-\r
- }\r
-\r
- public void update(final IElement e) {\r
- EdgeNode node = e.getHint(KEY_SG_NODE);\r
- if (node == null)\r
- return;\r
-\r
- EdgeVisuals vh = e.getElementClass().getSingleItem(\r
- EdgeVisuals.class);\r
- ArrowType at1 = vh.getArrowType(e, EdgeEnd.Begin);\r
- ArrowType at2 = vh.getArrowType(e, EdgeEnd.End);\r
- Stroke stroke = vh.getStroke(e);\r
- // StrokeType strokeType = vh.getStrokeType(e);\r
- double as1 = vh.getArrowSize(e, EdgeEnd.Begin);\r
- double as2 = vh.getArrowSize(e, EdgeEnd.End);\r
-\r
- Color c = ElementUtils.getFillColor(e, Color.BLACK);\r
-\r
- // Get terminal shape for clipping the painted edge to its bounds.\r
- IDiagram diagram = ElementUtils.peekDiagram(e);\r
- if (diagram != null) {\r
- Topology topology = diagram.getDiagramClass()\r
- .getAtMostOneItemOfClass(Topology.class);\r
- if (topology != null) {\r
- Connection beginConnection = topology.getConnection(e,\r
- EdgeEnd.Begin);\r
- Connection endConnection = topology.getConnection(e,\r
- EdgeEnd.End);\r
- int beginBranchDegree = getBranchPointDegree(\r
- beginConnection, topology);\r
- int endBranchDegree = getBranchPointDegree(endConnection,\r
- topology);\r
- if (beginBranchDegree > 0 && beginBranchDegree < 3) {\r
- at1 = ArrowType.None;\r
- }\r
- if (endBranchDegree > 0 && endBranchDegree < 3) {\r
- at2 = ArrowType.None;\r
- }\r
- }\r
- }\r
-\r
- // Read bends\r
- BendsHandler bh = e.getElementClass().getSingleItem(\r
- BendsHandler.class);\r
- Path2D line = bh.getPath(e);\r
-\r
- boolean drawArrows = at1 != ArrowType.None || at2 != ArrowType.None;\r
- // line = clipLineEnds(line, beginTerminalShape, endTerminalShape);\r
-\r
- Point2D first = new Point2D.Double();\r
- Point2D dir1 = new Point2D.Double();\r
- Point2D last = new Point2D.Double();\r
- Point2D dir2 = new Point2D.Double();\r
- PathIterator pi = line.getPathIterator(null);\r
- drawArrows &= getPathArrows(pi, first, dir1, last, dir2);\r
-\r
- if (drawArrows) {\r
- line = trimLineToArrows(line, at2, as2);\r
- }\r
-\r
- EdgeNode.ArrowType pat1 = convert(at1);\r
- EdgeNode.ArrowType pat2 = convert(at2);\r
-\r
- node.init(new GeneralPath(line), stroke, c, dir1, dir2, first,\r
- last, as1, as2, pat1, pat2, null, null);\r
- }\r
-\r
- private boolean getPathArrows(PathIterator pi, Point2D begin,\r
- Point2D beginDirection, Point2D end, Point2D endDirection) {\r
-\r
- Iterator<double[]> i = PathUtils.toLineIterator(pi);\r
-\r
- double first1[] = null, last1[] = null;\r
- double first2[] = null, last2[] = null;\r
-\r
- // double current[] = new double[2];\r
-\r
- double[] previous = null;\r
-\r
- while (i.hasNext()) {\r
- double[] current = i.next();\r
-\r
- // Start of the first path\r
- if (first1 == null) {\r
- first1 = current;\r
- last1 = current;\r
- }\r
-\r
- // Command was moveTo => start of the second path\r
- else if (previous != null\r
- && (previous[2] != current[0] || previous[3] != current[1])) {\r
- first2 = current;\r
- last2 = current;\r
- }\r
-\r
- // first2 == null => still in the first line\r
- else if (first2 == null) {\r
- last1 = current;\r
- }\r
-\r
- // second path\r
- else if (!i.hasNext()) {\r
- last2 = current;\r
- }\r
-\r
- previous = current;\r
- }\r
-\r
- if (first1 == null || last1 == null || first2 == null\r
- || last2 == null)\r
- return false;\r
-\r
- double[] first = { mean(first1[0], first2[0]),\r
- mean(first1[1], first2[1]), mean(first1[2], first2[2]),\r
- mean(first1[3], first2[3]) };\r
- double[] last = { mean(last1[0], last2[0]),\r
- mean(last1[1], last2[1]), mean(last1[2], last2[2]),\r
- mean(last1[3], last2[3]) };\r
-\r
- begin.setLocation(PathUtils.getLinePos(first, 0));\r
- beginDirection.setLocation(PathUtils.getLineTangent(first, 0));\r
- end.setLocation(PathUtils.getLinePos(last, 1));\r
- Point2D endTangent = PathUtils.getLineTangent(last, 1);\r
- endDirection.setLocation(-endTangent.getX(), -endTangent.getY());\r
-\r
- return true;\r
- }\r
-\r
- private double mean(double c1, double c2) {\r
- return c1 + (c2 - c1) / 2;\r
- }\r
-\r
- private static EdgeNode.ArrowType convert(ArrowType at) {\r
- switch (at) {\r
- case None:\r
- return EdgeNode.ArrowType.None;\r
- case Stroke:\r
- return EdgeNode.ArrowType.Stroke;\r
- case Fill:\r
- return EdgeNode.ArrowType.Fill;\r
- default:\r
- throw new IllegalArgumentException("unsupported arrow type: "\r
- + at);\r
- }\r
- }\r
-\r
- private final Collection<Connection> connectionsTemp = new ArrayList<Connection>();\r
-\r
- private int getBranchPointDegree(Connection connection,\r
- Topology topology) {\r
- if (connection != null && connection.node != null) {\r
- if (connection.node.getElementClass().containsClass(\r
- BranchPoint.class)) {\r
- connectionsTemp.clear();\r
- topology.getConnections(connection.node,\r
- connection.terminal, connectionsTemp);\r
- int degree = connectionsTemp.size();\r
- connectionsTemp.clear();\r
- return degree;\r
- }\r
- }\r
- return -1;\r
- }\r
-\r
- }\r
-\r
-}\r
+++ /dev/null
-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.sysdyn.ui.elements2.connections;\r
-\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Graphics2D;\r
-import java.awt.Stroke;\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.Rectangle2D;\r
-\r
-import org.simantics.scenegraph.ISelectionPainterNode;\r
-import org.simantics.scenegraph.g2d.G2DNode;\r
-import org.simantics.scenegraph.utils.NodeUtil;\r
-\r
-public class FlowNodeOld extends G2DNode implements ISelectionPainterNode {\r
-\r
- private static final long serialVersionUID = 328942356917631237L;\r
-\r
- private static final BasicStroke STROKE = new BasicStroke(1.0f);\r
-\r
- private Color color;\r
- private Stroke stroke;\r
- private Rectangle2D beginBounds;\r
- private Rectangle2D endBounds;\r
- private Path2D lines;\r
- private Path2D arrow;\r
-\r
- @PropertySetter("color")\r
- @SyncField("color")\r
- public void setColor(Color color) {\r
- this.color = color;\r
- }\r
-\r
- @PropertySetter("stroke")\r
- @SyncField("stroke")\r
- public void setStroke(Stroke stroke) {\r
- this.stroke = stroke;\r
- }\r
-\r
- @PropertySetter("beginBounds")\r
- @SyncField("beginBounds")\r
- public void setBeginBounds(Rectangle2D beginBounds) {\r
- this.beginBounds = beginBounds;\r
- }\r
-\r
- @PropertySetter("endBounds")\r
- @SyncField("endBounds")\r
- public void setEndBounds(Rectangle2D endBounds) {\r
- this.endBounds = endBounds;\r
- }\r
- \r
- @PropertySetter("lines")\r
- @SyncField("lines")\r
- public void setLines(Path2D lines) {\r
- this.lines = lines;\r
- }\r
- \r
- @PropertySetter("arrow")\r
- @SyncField("arrow")\r
- public void setArrow(Path2D arrow) {\r
- this.arrow = arrow;\r
- }\r
-\r
- public Color getColor() {\r
- return color;\r
- }\r
-\r
- public Stroke getStroke() {\r
- return stroke;\r
- }\r
-\r
- public Rectangle2D getBeginBounds() {\r
- return beginBounds;\r
- }\r
-\r
- public Rectangle2D getEndBounds() {\r
- return endBounds;\r
- }\r
-\r
- public Path2D getLines() {\r
- return lines;\r
- }\r
- \r
- public Path2D getArrow() {\r
- return arrow;\r
- }\r
- \r
- @Override\r
- public void render(Graphics2D g) {\r
- // Removed to let the global control handle rendering quality issues.\r
- //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
-\r
- /*\r
- * There are two cases, first is from Stock|Cloud to Valve and second is from Valve to Stock|Cloud\r
- * -In the first case there is no arrow and valve is endBounds\r
- * -In the second case there is an arrow and valve is beginBounds\r
- */\r
-\r
- boolean selected = NodeUtil.isSelected(this, 2);\r
- if(selected) {\r
- g.setColor(Color.PINK);\r
- g.setStroke(STROKE);\r
- g.draw(lines);\r
- if(color != null) g.setColor(color);\r
- g.setStroke(stroke);\r
- if(lines!= null) g.draw(lines);\r
- if(arrow != null) g.fill(arrow);\r
- } else {\r
- if(color != null) g.setColor(color);\r
- if(stroke != null) g.setStroke(stroke);\r
- if(lines!= null) g.draw(lines);\r
- if(arrow != null) g.fill(arrow);\r
- }\r
-\r
-\r
- }\r
-\r
- @Override\r
- public Rectangle2D getBoundsInLocal() {\r
- return null;\r
- }\r
-}\r