X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Felementclass%2Fconnection%2FEdgeClass.java;h=b2ce6f4676aa5715c86ee52b5d28ff29f1460c7b;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=2a8dc182114eacce20d283495045ab2fcf74cc2a;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/elementclass/connection/EdgeClass.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/elementclass/connection/EdgeClass.java index 2a8dc1821..b2ce6f467 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/elementclass/connection/EdgeClass.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/elementclass/connection/EdgeClass.java @@ -1,381 +1,381 @@ -/******************************************************************************* - * 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. - * - *

- * 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. - * - *

- * 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 points = new ArrayList(); - 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 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(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 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 list = e.getHint(KEY_BENDS); - return list.size(); - } - - @Override - public void getBends(IElement e, List bends) { - ArrayList list = e.getHint(KEY_BENDS); - bends.addAll(list); - } - - @Override - public boolean removeBend(IElement e, Bend b) { - ArrayList 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 list = e.getHint(KEY_BENDS); - ArrayList positions = new ArrayList(); - 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; - } - } - -} +/******************************************************************************* + * 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. + * + *

+ * 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. + * + *

+ * 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 points = new ArrayList(); + 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 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(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 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 list = e.getHint(KEY_BENDS); + return list.size(); + } + + @Override + public void getBends(IElement e, List bends) { + ArrayList list = e.getHint(KEY_BENDS); + bends.addAll(list); + } + + @Override + public boolean removeBend(IElement e, Bend b) { + ArrayList 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 list = e.getHint(KEY_BENDS); + ArrayList positions = new ArrayList(); + 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; + } + } + +}