1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g2d.elementclass;
\r
14 import java.awt.BasicStroke;
\r
15 import java.awt.Color;
\r
16 import java.awt.Rectangle;
\r
17 import java.awt.Shape;
\r
18 import java.awt.geom.AffineTransform;
\r
19 import java.awt.geom.Ellipse2D;
\r
20 import java.awt.geom.Point2D;
\r
21 import java.awt.geom.Rectangle2D;
\r
22 import java.util.Collection;
\r
24 import org.simantics.g2d.diagram.handler.Topology.Terminal;
\r
25 import org.simantics.g2d.element.ElementClass;
\r
26 import org.simantics.g2d.element.ElementUtils;
\r
27 import org.simantics.g2d.element.IElement;
\r
28 import org.simantics.g2d.element.handler.InternalSize;
\r
29 import org.simantics.g2d.element.handler.SceneGraph;
\r
30 import org.simantics.g2d.element.handler.TerminalLayout;
\r
31 import org.simantics.g2d.element.handler.TerminalTopology;
\r
32 import org.simantics.g2d.element.handler.impl.BorderColorImpl;
\r
33 import org.simantics.g2d.element.handler.impl.DefaultTransform;
\r
34 import org.simantics.g2d.element.handler.impl.FillColorImpl;
\r
35 import org.simantics.g2d.element.handler.impl.Resizeable;
\r
36 import org.simantics.g2d.element.handler.impl.TextImpl;
\r
37 import org.simantics.g2d.element.handler.impl.TextPainter;
\r
38 import org.simantics.g2d.utils.geom.DirectionSet;
\r
39 import org.simantics.scenegraph.g2d.G2DParentNode;
\r
40 import org.simantics.scenegraph.g2d.nodes.ShapeNode;
\r
41 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
\r
45 * @author Toni Kalajainen
\r
47 public class BoxClass {
\r
49 public static final ElementClass BOXCLASS =
\r
50 ElementClass.compile(
\r
51 DefaultTransform.INSTANCE,
\r
52 Resizeable.UNCONSTRICTED,
\r
53 BorderColorImpl.BLACK,
\r
54 FillColorImpl.WHITE,
\r
56 new RectangleSGNode(),
\r
59 //new RotatorHandler()
\r
62 final static BasicStroke STROKE = new BasicStroke(1.0f);
\r
64 static class RectangleSGNode implements SceneGraph {
\r
68 private static final long serialVersionUID = -1550908516884986157L;
\r
69 private G2DParentNode node = null;
\r
72 public void cleanup(IElement e) {
\r
80 public void init(IElement e, G2DParentNode parent) {
\r
82 node = parent.addNode(G2DParentNode.class);
\r
84 ShapeNode bgnode = node.getOrCreateNode("bg", ShapeNode.class);
\r
85 bgnode.setZIndex(1);
\r
86 ShapeNode fgnode = node.getOrCreateNode("fg", ShapeNode.class);
\r
87 fgnode.setZIndex(2);
\r
89 Color fc = ElementUtils.getFillColor(e);
\r
90 Color bc = ElementUtils.getBorderColor(e);
\r
92 Rectangle2D rect = ElementUtils.getElementBounds(e);
\r
93 bgnode.setColor(fc);
\r
94 bgnode.setFill(true);
\r
95 bgnode.setShape(rect);
\r
97 fgnode.setColor(bc);
\r
98 fgnode.setFill(false);
\r
99 fgnode.setStroke(STROKE);
\r
100 fgnode.setScaleStroke(true);
\r
101 fgnode.setShape(rect);
\r
107 static class TerminalPoint implements Terminal {
\r
110 public static class TerminalKeyOf extends KeyOf {
\r
111 public final Terminal terminal;
\r
113 private final int hashCode;
\r
115 public TerminalKeyOf(Terminal terminal, Class<?> clazz) {
\r
117 this.terminal = terminal;
\r
118 hashCode = terminal.hashCode() ^ clazz.hashCode();
\r
122 public int hashCode() {
\r
127 public boolean equals(Object obj) {
\r
128 if (!(obj instanceof TerminalKeyOf)) return false;
\r
129 TerminalKeyOf other = (TerminalKeyOf) obj;
\r
130 if (!other.terminal.equals(terminal)) return false;
\r
131 return super.equals(obj);
\r
135 public static class TerminalConnectKey extends TerminalKeyOf {
\r
136 public TerminalConnectKey(Terminal terminal) {
\r
137 super(terminal, IElement.class);
\r
142 static class BoxNode implements TerminalTopology, TerminalLayout {
\r
143 private static final long serialVersionUID = 4561446983606561224L;
\r
144 public static final Terminal T0 = new TerminalPoint();
\r
145 public static final Terminal T1 = new TerminalPoint();
\r
146 public static final Terminal T2 = new TerminalPoint();
\r
147 public static final Terminal T3 = new TerminalPoint();
\r
148 public static final Terminal T4 = new TerminalPoint();
\r
149 public static final Terminal T5 = new TerminalPoint();
\r
150 public static final Terminal T6 = new TerminalPoint();
\r
151 public static final Terminal T7 = new TerminalPoint();
\r
152 public static final Terminal T8 = new TerminalPoint();
\r
155 public void getTerminals(IElement e, Collection<Terminal> result) {
\r
168 public AffineTransform getTerminalPosition(IElement node, Terminal t)
\r
170 InternalSize b = node.getElementClass().getSingleItem(InternalSize.class);
\r
171 Rectangle2D rect = b.getBounds(node, null);
\r
172 Point2D pos = null;
\r
173 if (rect == null) {
\r
174 pos = new Point2D.Double(0, 0);
\r
176 if (t==T0) pos = new Point2D.Double(rect.getCenterX(), rect.getCenterY());
\r
177 if (t==T1) pos = new Point2D.Double(rect.getMinX(), rect.getMinY());
\r
178 if (t==T2) pos = new Point2D.Double(rect.getCenterX(), rect.getMinY());
\r
179 if (t==T3) pos = new Point2D.Double(rect.getMaxX(), rect.getMinY());
\r
180 if (t==T4) pos = new Point2D.Double(rect.getMaxX(), rect.getCenterY());
\r
181 if (t==T5) pos = new Point2D.Double(rect.getMaxX(), rect.getMaxY());
\r
182 if (t==T6) pos = new Point2D.Double(rect.getCenterX(), rect.getMaxY());
\r
183 if (t==T7) pos = new Point2D.Double(rect.getMinX(), rect.getMaxY());
\r
184 if (t==T8) pos = new Point2D.Double(rect.getMinX(), rect.getCenterY());
\r
186 AffineTransform result = new AffineTransform();
\r
187 result.setToTranslation(pos.getX(), pos.getY());
\r
192 public boolean getTerminalDirection(IElement node, Terminal t, DirectionSet directions) {
\r
194 directions.addAll(DirectionSet.NESW);
\r
198 directions.addAll(DirectionSet.NW2);
\r
202 directions.addAll(DirectionSet.N);
\r
206 directions.addAll(DirectionSet.NE2);
\r
210 directions.addAll(DirectionSet.E);
\r
214 directions.addAll(DirectionSet.SE2);
\r
218 directions.addAll(DirectionSet.S);
\r
222 directions.addAll(DirectionSet.SW2);
\r
226 directions.addAll(DirectionSet.W);
\r
232 public static final Shape BOX_SHAPE = new Rectangle(-3, -3, 7, 7);
\r
233 public static final Shape CIRCLE_SHAPE = new Ellipse2D.Double(-5, -5, 9, 9);
\r
236 public Shape getTerminalShape(IElement node, Terminal t) {
\r
237 return (t==T6 || t==T7 || t==T0) ? CIRCLE_SHAPE : null;
\r