-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in 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.g2d.elementclass.connection;\r
-\r
-import java.awt.Shape;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.ElementHints;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.BendsHandler;\r
-import org.simantics.g2d.element.handler.InternalSize;\r
-import org.simantics.g2d.element.handler.LifeCycle;\r
-import org.simantics.g2d.element.handler.Move;\r
-import org.simantics.g2d.element.handler.Outline;\r
-import org.simantics.g2d.element.handler.Parent;\r
-import org.simantics.g2d.element.handler.Transform;\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.PlainElementPropertySetter;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
-\r
-/**\r
- * @author Toni Kalajainen\r
- */\r
-public class EdgeClass {\r
-\r
- /**\r
- * A {@link Transform} and {@link Move} implementation suitable for edges\r
- * which are connected to nodes and cannot be moved by themselves.\r
- * \r
- * <p>\r
- * The {@link Transform} implementation is a simple one with support for a\r
- * parent element through {@link ElementHints#KEY_PARENT_ELEMENT}. The\r
- * {@link Move} implementation in turn is a stub which does nothing to make\r
- * edges immovable.\r
- * \r
- * <p>\r
- * FIXME: The more correct solution would be not to have a {@link Move}\r
- * handler at all but much the current participant code is very highly\r
- * dependent on having a single {@link Move} handler available that this\r
- * workaround seems better at this point.\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
- public static class FixedTransform implements Transform, Move {\r
-\r
- private static final long serialVersionUID = 2287402413442694915L;\r
-\r
- public static final FixedTransform INSTANCE = new FixedTransform();\r
- public static final AffineTransform IDENTITY = new AffineTransform();\r
-\r
- @Override\r
- public AffineTransform getTransform(IElement e) {\r
- AffineTransform local = e.getHint(ElementHints.KEY_TRANSFORM);\r
- if (local == null)\r
- local = IDENTITY;\r
-\r
- Parent p = e.getElementClass().getAtMostOneItemOfClass(Parent.class);\r
- if (p == null)\r
- return local;\r
-\r
- IElement parentElement = p.getParent(e);\r
- if (parentElement == null)\r
- return local;\r
-\r
- AffineTransform parentTransform = parentElement.getElementClass().getSingleItem(Transform.class).getTransform(parentElement);\r
- if (parentTransform.isIdentity())\r
- return local;\r
-\r
- AffineTransform result = new AffineTransform(local);\r
- result.preConcatenate(parentTransform);\r
- return result;\r
- }\r
-\r
- @Override\r
- public void setTransform(IElement e, AffineTransform at) {\r
- assert at != null;\r
- e.setHint(ElementHints.KEY_TRANSFORM, at);\r
- }\r
-\r
- @Override\r
- public Point2D getPosition(IElement e) {\r
- AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);\r
- if (at == null)\r
- return new Point2D.Double();\r
- return new Point2D.Double(at.getTranslateX(), at.getTranslateY());\r
- }\r
-\r
- @Override\r
- public void moveTo(IElement e, double x, double y) {\r
- // Don't allow moving.\r
- }\r
- }\r
-\r
- // TODO scale, rotate, move, transform\r
- public static final ElementClass STRAIGHT =\r
- ElementClass.compile(\r
- EdgeSceneGraph.INSTANCE,\r
- EdgeHandler.INSTANCE,\r
- ConfigurableEdgeVisuals.DEFAULT,\r
- FillColorImpl.RED,\r
- FixedTransform.INSTANCE,\r
- ShapePick.INSTANCE,\r
- ConnectionSelectionOutline.INSTANCE,\r
- SimpleElementLayers.INSTANCE,\r
- ParentImpl.INSTANCE,\r
- new PlainElementPropertySetter(EdgeSceneGraph.KEY_SG_NODE)\r
- ).setId("EdgeClass.STRAIGHT");\r
-\r
-\r
- public static class EdgeHandler implements BendsHandler, Outline, LifeCycle, InternalSize {\r
-\r
- private static final long serialVersionUID = -5949432471958957382L;\r
-\r
- public static final EdgeHandler INSTANCE = new EdgeHandler();\r
-\r
- public static final Key KEY_PATH = new KeyOf(Path2D.class, "PATH");\r
- public static final Key KEY_BOUNDS = new KeyOf(Rectangle2D.class, "BOUNDS");\r
- public static final Key KEY_ANGLETYPE = new KeyOf(AngleType.class);\r
- public static final Key KEY_BENDS = new KeyOf(ArrayList.class, "BENDS");\r
-\r
- public static class BendImpl implements Bend {\r
- Point2D pos;\r
- }\r
-\r
- /**\r
- * Reads bends, builds path, and writes it to KEY_PATH\r
- * @param e\r
- */\r
- /*\r
- private void buildPath(IElement e)\r
- {\r
- ArrayList<Point2D> points = new ArrayList<Point2D>();\r
- ElementUtils.getBends(e, points);\r
- Path2D path = GeometryUtils.buildPath(points);\r
- e.setHint(KEY_PATH, path);\r
- e.setHint(KEY_BOUNDS, path.getBounds2D());\r
- }*/\r
-\r
- @Override\r
- public void setAngleType(IElement e, AngleType angleType) {\r
- e.setHint(KEY_ANGLETYPE, angleType);\r
- }\r
-\r
- @Override\r
- public AngleType getAngleType(IElement e) {\r
- return e.getHint(KEY_ANGLETYPE);\r
- }\r
-\r
- @Override\r
- public Shape getElementShape(IElement e) {\r
- // Path2DOutlineShape no longer needed with ConnectionSelectionOutline\r
- // that uses Stroke.createStrokedShape.\r
- //return new Path2DOutlineShape((Path2D)e.getHint(KEY_PATH));\r
- return e.getHint(KEY_PATH);\r
- }\r
-/*\r
- @Override\r
- public AffineTransform getTransform(IElement e) {\r
- AffineTransform at = GeometryUtils.IDENTITY;\r
- assert(at.isIdentity());\r
- return at;\r
- }\r
-\r
- @Override\r
- public void setTransform(IElement e, AffineTransform at) {\r
- Path2D path = e.getHint(KEY_PATH);\r
- if (path==null) return;\r
- ArrayList<BendImpl> list = e.getHint(KEY_BENDS);\r
- for (BendImpl bi : list)\r
- at.transform(bi.pos, bi.pos);\r
- buildPath(e);\r
- }\r
-\r
- @Override\r
- public Point2D getPosition(IElement e) {\r
- return new Point2D.Double(0, 0);\r
- }\r
-\r
- @Override\r
- public void moveTo(IElement e, double x, double y) {\r
- AffineTransform at = new AffineTransform();\r
- at.setToTranslation(x, y);\r
- setTransform(e, at);\r
- }\r
-\r
- @Override\r
- public double getAngle(IElement e, ICanvasContext ctx) {\r
- return 0;\r
- }\r
-\r
- @Override\r
- public void rotate(IElement e, ICanvasContext ctx, double theta, Point2D origo) {\r
- AffineTransform at = new AffineTransform();\r
- at.setToRotation(theta, origo.getX(), origo.getY());\r
- setTransform(e, at);\r
- }\r
-\r
- @Override\r
- public Double getFixedAspectRatio(IElement e) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Point2D getMaximumScale(IElement e) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Point2D getMinimumScale(IElement e) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Point2D getScale(IElement e) {\r
- return new Point2D.Double(1, 1);\r
- }\r
-\r
- @Override\r
- public void setScale(IElement e, Point2D newScale) {\r
- AffineTransform at = new AffineTransform();\r
- at.setToScale(newScale.getX(), newScale.getY());\r
- setTransform(e, at);\r
- }\r
- */\r
- @Override\r
- public void onElementActivated(IDiagram d, IElement e) {\r
- update(e);\r
- }\r
-\r
- @Override\r
- public void onElementCreated(IElement e) {\r
- e.setHint(KEY_PATH, new Path2D.Double(Path2D.WIND_NON_ZERO, 2));\r
- e.setHint(KEY_ANGLETYPE, AngleType.RightAngled);\r
- e.setHint(KEY_BOUNDS, new Rectangle2D.Double());\r
- e.setHint(KEY_BENDS, new ArrayList<BendImpl>(2));\r
- }\r
- @Override\r
- public void onElementDestroyed(IElement e) {\r
-// EdgeSGNode sg = e.getElementClass().getAtMostOneItemOfClass(EdgeSGNode.class);\r
-// if(sg != null)\r
-// sg.cleanup(e);\r
- }\r
-\r
- private void update(IElement e) {\r
- EdgeSceneGraph sg = e.getElementClass().getAtMostOneItemOfClass(EdgeSceneGraph.class);\r
- if(sg != null)\r
- sg.update(e);\r
- }\r
-\r
- @Override\r
- public void onElementDeactivated(IDiagram d, IElement e) {\r
- }\r
-\r
- @Override\r
- public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
- Rectangle2D rect = e.getHint(KEY_BOUNDS);\r
- if (size==null) size = new Rectangle2D.Double();\r
- if (rect != null)\r
- size.setFrame(rect);\r
- return rect;\r
- }\r
-\r
- @Override\r
- public Bend addBend(IElement e, int index, Point2D pos) {\r
- ArrayList<BendImpl> list = e.getHint(KEY_BENDS);\r
- BendImpl b = new BendImpl();\r
- b.pos = new Point2D.Double(pos.getX(), pos.getY());\r
- list.add(index, b);\r
-// buildPath(e);\r
- update(e);\r
- return b;\r
- }\r
-\r
- @Override\r
- public void getBendPosition(IElement e, Bend b, Point2D pos) {\r
- pos.setLocation( ((BendImpl)b).pos );\r
- }\r
-\r
- @Override\r
- public int getBendsCount(IElement e) {\r
- ArrayList<BendImpl> list = e.getHint(KEY_BENDS);\r
- return list.size();\r
- }\r
-\r
- @Override\r
- public void getBends(IElement e, List<Bend> bends) {\r
- ArrayList<BendImpl> list = e.getHint(KEY_BENDS);\r
- bends.addAll(list);\r
- }\r
-\r
- @Override\r
- public boolean removeBend(IElement e, Bend b) {\r
- ArrayList<BendImpl> list = e.getHint(KEY_BENDS);\r
- if (!list.remove(b)) return false;\r
-// buildPath(e);\r
- return true;\r
- }\r
-\r
- @Override\r
- public Path2D getPath(IElement e) {\r
- return e.getHint(KEY_PATH);\r
- }\r
-\r
- @Override\r
- public void setPath(IElement e, Path2D path) {\r
- e.setHint(KEY_PATH, path);\r
- e.setHint(KEY_BOUNDS, path.getBounds2D());\r
- /*\r
- ArrayList<BendImpl> list = e.getHint(KEY_BENDS);\r
- ArrayList<Point2D> positions = new ArrayList<Point2D>();\r
- GeometryUtils.getPoints(path, positions);\r
- list.clear();\r
- for (Point2D p : positions) {\r
- BendImpl bi = new BendImpl();\r
- bi.pos = p;\r
- list.add(bi);\r
- }*/\r
- update(e);\r
- }\r
-\r
- @Override\r
- public void moveBend(IElement e, Bend b, Point2D pos) {\r
- BendImpl bi = ((BendImpl)b);\r
- if (bi.pos.equals(pos)) return;\r
- bi.pos.setLocation(pos);\r
-// buildPath(e);\r
- update(e);\r
- }\r
- }\r
-\r
- public static class ControlPointKey extends Key {\r
- public final int index;\r
- final int hash;\r
- public ControlPointKey(int index)\r
- {\r
- super();\r
- this.index = index;\r
- hash = getClass().hashCode() ^ index ^ 54392439;\r
- }\r
- @Override\r
- public boolean isValueAccepted(Object value) {\r
- return IElement.class.isInstance(value);\r
- }\r
- @Override\r
- public int hashCode() {\r
- return hash;\r
- }\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (obj == null)\r
- return false;\r
- if (getClass() != obj.getClass())\r
- return false;\r
- ControlPointKey other = (ControlPointKey) obj;\r
- return other.index == index;\r
- }\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g2d.elementclass.connection;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.BendsHandler;
+import org.simantics.g2d.element.handler.InternalSize;
+import org.simantics.g2d.element.handler.LifeCycle;
+import org.simantics.g2d.element.handler.Move;
+import org.simantics.g2d.element.handler.Outline;
+import org.simantics.g2d.element.handler.Parent;
+import org.simantics.g2d.element.handler.Transform;
+import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals;
+import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;
+import org.simantics.g2d.element.handler.impl.FillColorImpl;
+import org.simantics.g2d.element.handler.impl.ParentImpl;
+import org.simantics.g2d.element.handler.impl.ShapePick;
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
+import org.simantics.g2d.elementclass.PlainElementPropertySetter;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+
+/**
+ * @author Toni Kalajainen
+ */
+public class EdgeClass {
+
+ /**
+ * A {@link Transform} and {@link Move} implementation suitable for edges
+ * which are connected to nodes and cannot be moved by themselves.
+ *
+ * <p>
+ * The {@link Transform} implementation is a simple one with support for a
+ * parent element through {@link ElementHints#KEY_PARENT_ELEMENT}. The
+ * {@link Move} implementation in turn is a stub which does nothing to make
+ * edges immovable.
+ *
+ * <p>
+ * FIXME: The more correct solution would be not to have a {@link Move}
+ * handler at all but much the current participant code is very highly
+ * dependent on having a single {@link Move} handler available that this
+ * workaround seems better at this point.
+ *
+ * @author Tuukka Lehtonen
+ */
+ public static class FixedTransform implements Transform, Move {
+
+ private static final long serialVersionUID = 2287402413442694915L;
+
+ public static final FixedTransform INSTANCE = new FixedTransform();
+ public static final AffineTransform IDENTITY = new AffineTransform();
+
+ @Override
+ public AffineTransform getTransform(IElement e) {
+ AffineTransform local = e.getHint(ElementHints.KEY_TRANSFORM);
+ if (local == null)
+ local = IDENTITY;
+
+ Parent p = e.getElementClass().getAtMostOneItemOfClass(Parent.class);
+ if (p == null)
+ return local;
+
+ IElement parentElement = p.getParent(e);
+ if (parentElement == null)
+ return local;
+
+ AffineTransform parentTransform = parentElement.getElementClass().getSingleItem(Transform.class).getTransform(parentElement);
+ if (parentTransform.isIdentity())
+ return local;
+
+ AffineTransform result = new AffineTransform(local);
+ result.preConcatenate(parentTransform);
+ return result;
+ }
+
+ @Override
+ public void setTransform(IElement e, AffineTransform at) {
+ assert at != null;
+ e.setHint(ElementHints.KEY_TRANSFORM, at);
+ }
+
+ @Override
+ public Point2D getPosition(IElement e) {
+ AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);
+ if (at == null)
+ return new Point2D.Double();
+ return new Point2D.Double(at.getTranslateX(), at.getTranslateY());
+ }
+
+ @Override
+ public void moveTo(IElement e, double x, double y) {
+ // Don't allow moving.
+ }
+ }
+
+ // TODO scale, rotate, move, transform
+ public static final ElementClass STRAIGHT =
+ ElementClass.compile(
+ EdgeSceneGraph.INSTANCE,
+ EdgeHandler.INSTANCE,
+ ConfigurableEdgeVisuals.DEFAULT,
+ FillColorImpl.RED,
+ FixedTransform.INSTANCE,
+ ShapePick.INSTANCE,
+ ConnectionSelectionOutline.INSTANCE,
+ SimpleElementLayers.INSTANCE,
+ ParentImpl.INSTANCE,
+ new PlainElementPropertySetter(EdgeSceneGraph.KEY_SG_NODE)
+ ).setId("EdgeClass.STRAIGHT");
+
+
+ public static class EdgeHandler implements BendsHandler, Outline, LifeCycle, InternalSize {
+
+ private static final long serialVersionUID = -5949432471958957382L;
+
+ public static final EdgeHandler INSTANCE = new EdgeHandler();
+
+ public static final Key KEY_PATH = new KeyOf(Path2D.class, "PATH");
+ public static final Key KEY_BOUNDS = new KeyOf(Rectangle2D.class, "BOUNDS");
+ public static final Key KEY_ANGLETYPE = new KeyOf(AngleType.class);
+ public static final Key KEY_BENDS = new KeyOf(ArrayList.class, "BENDS");
+
+ public static class BendImpl implements Bend {
+ Point2D pos;
+ }
+
+ /**
+ * Reads bends, builds path, and writes it to KEY_PATH
+ * @param e
+ */
+ /*
+ private void buildPath(IElement e)
+ {
+ ArrayList<Point2D> points = new ArrayList<Point2D>();
+ ElementUtils.getBends(e, points);
+ Path2D path = GeometryUtils.buildPath(points);
+ e.setHint(KEY_PATH, path);
+ e.setHint(KEY_BOUNDS, path.getBounds2D());
+ }*/
+
+ @Override
+ public void setAngleType(IElement e, AngleType angleType) {
+ e.setHint(KEY_ANGLETYPE, angleType);
+ }
+
+ @Override
+ public AngleType getAngleType(IElement e) {
+ return e.getHint(KEY_ANGLETYPE);
+ }
+
+ @Override
+ public Shape getElementShape(IElement e) {
+ // Path2DOutlineShape no longer needed with ConnectionSelectionOutline
+ // that uses Stroke.createStrokedShape.
+ //return new Path2DOutlineShape((Path2D)e.getHint(KEY_PATH));
+ return e.getHint(KEY_PATH);
+ }
+/*
+ @Override
+ public AffineTransform getTransform(IElement e) {
+ AffineTransform at = GeometryUtils.IDENTITY;
+ assert(at.isIdentity());
+ return at;
+ }
+
+ @Override
+ public void setTransform(IElement e, AffineTransform at) {
+ Path2D path = e.getHint(KEY_PATH);
+ if (path==null) return;
+ ArrayList<BendImpl> list = e.getHint(KEY_BENDS);
+ for (BendImpl bi : list)
+ at.transform(bi.pos, bi.pos);
+ buildPath(e);
+ }
+
+ @Override
+ public Point2D getPosition(IElement e) {
+ return new Point2D.Double(0, 0);
+ }
+
+ @Override
+ public void moveTo(IElement e, double x, double y) {
+ AffineTransform at = new AffineTransform();
+ at.setToTranslation(x, y);
+ setTransform(e, at);
+ }
+
+ @Override
+ public double getAngle(IElement e, ICanvasContext ctx) {
+ return 0;
+ }
+
+ @Override
+ public void rotate(IElement e, ICanvasContext ctx, double theta, Point2D origo) {
+ AffineTransform at = new AffineTransform();
+ at.setToRotation(theta, origo.getX(), origo.getY());
+ setTransform(e, at);
+ }
+
+ @Override
+ public Double getFixedAspectRatio(IElement e) {
+ return null;
+ }
+
+ @Override
+ public Point2D getMaximumScale(IElement e) {
+ return null;
+ }
+
+ @Override
+ public Point2D getMinimumScale(IElement e) {
+ return null;
+ }
+
+ @Override
+ public Point2D getScale(IElement e) {
+ return new Point2D.Double(1, 1);
+ }
+
+ @Override
+ public void setScale(IElement e, Point2D newScale) {
+ AffineTransform at = new AffineTransform();
+ at.setToScale(newScale.getX(), newScale.getY());
+ setTransform(e, at);
+ }
+ */
+ @Override
+ public void onElementActivated(IDiagram d, IElement e) {
+ update(e);
+ }
+
+ @Override
+ public void onElementCreated(IElement e) {
+ e.setHint(KEY_PATH, new Path2D.Double(Path2D.WIND_NON_ZERO, 2));
+ e.setHint(KEY_ANGLETYPE, AngleType.RightAngled);
+ e.setHint(KEY_BOUNDS, new Rectangle2D.Double());
+ e.setHint(KEY_BENDS, new ArrayList<BendImpl>(2));
+ }
+ @Override
+ public void onElementDestroyed(IElement e) {
+// EdgeSGNode sg = e.getElementClass().getAtMostOneItemOfClass(EdgeSGNode.class);
+// if(sg != null)
+// sg.cleanup(e);
+ }
+
+ private void update(IElement e) {
+ EdgeSceneGraph sg = e.getElementClass().getAtMostOneItemOfClass(EdgeSceneGraph.class);
+ if(sg != null)
+ sg.update(e);
+ }
+
+ @Override
+ public void onElementDeactivated(IDiagram d, IElement e) {
+ }
+
+ @Override
+ public Rectangle2D getBounds(IElement e, Rectangle2D size) {
+ Rectangle2D rect = e.getHint(KEY_BOUNDS);
+ if (size==null) size = new Rectangle2D.Double();
+ if (rect != null)
+ size.setFrame(rect);
+ return rect;
+ }
+
+ @Override
+ public Bend addBend(IElement e, int index, Point2D pos) {
+ ArrayList<BendImpl> list = e.getHint(KEY_BENDS);
+ BendImpl b = new BendImpl();
+ b.pos = new Point2D.Double(pos.getX(), pos.getY());
+ list.add(index, b);
+// buildPath(e);
+ update(e);
+ return b;
+ }
+
+ @Override
+ public void getBendPosition(IElement e, Bend b, Point2D pos) {
+ pos.setLocation( ((BendImpl)b).pos );
+ }
+
+ @Override
+ public int getBendsCount(IElement e) {
+ ArrayList<BendImpl> list = e.getHint(KEY_BENDS);
+ return list.size();
+ }
+
+ @Override
+ public void getBends(IElement e, List<Bend> bends) {
+ ArrayList<BendImpl> list = e.getHint(KEY_BENDS);
+ bends.addAll(list);
+ }
+
+ @Override
+ public boolean removeBend(IElement e, Bend b) {
+ ArrayList<BendImpl> list = e.getHint(KEY_BENDS);
+ if (!list.remove(b)) return false;
+// buildPath(e);
+ return true;
+ }
+
+ @Override
+ public Path2D getPath(IElement e) {
+ return e.getHint(KEY_PATH);
+ }
+
+ @Override
+ public void setPath(IElement e, Path2D path) {
+ e.setHint(KEY_PATH, path);
+ e.setHint(KEY_BOUNDS, path.getBounds2D());
+ /*
+ ArrayList<BendImpl> list = e.getHint(KEY_BENDS);
+ ArrayList<Point2D> positions = new ArrayList<Point2D>();
+ GeometryUtils.getPoints(path, positions);
+ list.clear();
+ for (Point2D p : positions) {
+ BendImpl bi = new BendImpl();
+ bi.pos = p;
+ list.add(bi);
+ }*/
+ update(e);
+ }
+
+ @Override
+ public void moveBend(IElement e, Bend b, Point2D pos) {
+ BendImpl bi = ((BendImpl)b);
+ if (bi.pos.equals(pos)) return;
+ bi.pos.setLocation(pos);
+// buildPath(e);
+ update(e);
+ }
+ }
+
+ public static class ControlPointKey extends Key {
+ public final int index;
+ final int hash;
+ public ControlPointKey(int index)
+ {
+ super();
+ this.index = index;
+ hash = getClass().hashCode() ^ index ^ 54392439;
+ }
+ @Override
+ public boolean isValueAccepted(Object value) {
+ return IElement.class.isInstance(value);
+ }
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ControlPointKey other = (ControlPointKey) obj;
+ return other.index == index;
+ }
+ }
+
+}