X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Felement%2Fhandler%2Fimpl%2FDefaultTransform.java;h=c81348ace5dd98195e81796df6fcfbebc815fbfa;hp=2550bbc403fd46fe8cb2ba1797f5b5c2076e8333;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/DefaultTransform.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/DefaultTransform.java index 2550bbc40..c81348ace 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/DefaultTransform.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/DefaultTransform.java @@ -1,243 +1,243 @@ -/******************************************************************************* - * 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.element.handler.impl; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.util.Collection; - -import org.simantics.g2d.canvas.ICanvasContext; -import org.simantics.g2d.diagram.IDiagram; -import org.simantics.g2d.element.ElementHints; -import org.simantics.g2d.element.IElement; -import org.simantics.g2d.element.handler.LifeCycle; -import org.simantics.g2d.element.handler.Move; -import org.simantics.g2d.element.handler.Rotate; -import org.simantics.g2d.element.handler.Scale; -import org.simantics.g2d.element.handler.Transform; -import org.simantics.g2d.element.handler.Validator; - -/** - * This class implements Transform, Move, Rotate, and Scale. - * It maintains element position in element variable ElementHints.KEY_TRANSFORM. - * - * @author Toni Kalajainen - */ -public class DefaultTransform implements Transform, Move, Rotate, Scale, Validator, LifeCycle { - - private static final long serialVersionUID = -2394690413166528179L; - - public static final DefaultTransform INSTANCE = new DefaultTransform(null); - - Double aspectRatio; - - public DefaultTransform() { - this(null); - } - - public DefaultTransform(Double aspectRatio) { - this.aspectRatio = aspectRatio; - } - - @Override - public Double getFixedAspectRatio(IElement e) { - return aspectRatio; - } - - @Override - public Point2D getScale(IElement e) { - AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); - return _getScale(at); - } - - @Override - public void setScale(IElement e, Point2D newScale) { - Point2D oldScale = getScale(e); - double sx = newScale.getX() / oldScale.getX(); - double sy = newScale.getY() / oldScale.getY(); - AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); - at = new AffineTransform(at); - at.scale(sx, sy); - e.setHint(ElementHints.KEY_TRANSFORM, at); - } - - @Override - public Point2D getMaximumScale(IElement e) { - return null; - } - - @Override - public Point2D getMinimumScale(IElement e) { - return null; - } - - private static Point2D _getScale(AffineTransform at) { - double m00 = at.getScaleX(); - double m11 = at.getScaleY(); - double m10 = at.getShearY(); - double m01 = at.getShearX(); - // Project unit vector to canvas - double sx = Math.sqrt(m00 * m00 + m10 * m10); - double sy = Math.sqrt(m01 * m01 + m11 * m11); - return new Point2D.Double(sx, sy); - } - - @Override - public void validate(final IElement e, final ICanvasContext ctx, Collection lst) { - /* - if (aspectRatio != null) { - // Validate aspect ratio - final Point2D scale = getScale(e); - double currentRatio = scale.getX() / scale.getY(); - if (Math.abs(currentRatio - aspectRatio) > 0.000001) { - lst.add(new Issue() { - @Override - public String getMessage() { - return "Aspect ratio is wrong"; - } - - @Override - public void addSuggestions( - Collection suggestionList) { - suggestionList.add(new Suggestion() { - @Override - public boolean fix() { - double newSx = scale.getX(); - double newSy = newSx * aspectRatio; - Point2D newScale = new Point2D.Double(newSx, - newSy); - setScale(e, newScale); - ctx.setDirty(); - return true; - } - - @Override - public String getMessage() { - return "Scale height, keep width"; - } - }); - } - }); - } - // TODO min scale validator - // TODO max scale validator - } - - if (e.getHint(ElementHints.KEY_TRANSFORM) == null) { - Issue i = new Issue() { - @Override - public String getMessage() { - return "Transform is missing"; - } - - @Override - public void addSuggestions(Collection suggestionList) { - Suggestion s = new Suggestion() { - @Override - public boolean fix() { - e.setHint(ElementHints.KEY_TRANSFORM, - new AffineTransform()); - return true; - } - - @Override - public String getMessage() { - return "Set default transform"; - } - }; - suggestionList.add(s); - } - }; - lst.add(i); - } - */ - } - - @Override - public void rotate(IElement e, double theta, Point2D origo) { - if (Double.isNaN(theta)) return; - AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); - at = (AffineTransform) at.clone(); - Point2D localOrigo = at.transform(origo, null); - at.preConcatenate(AffineTransform.getRotateInstance(theta, localOrigo.getX(), localOrigo.getY())); - // This code concatenated the matrix from the wrong side - //at.rotate(theta, origo.getX(), origo.getY()); - e.setHint(ElementHints.KEY_TRANSFORM, at); - } - - @Override - public double getAngle(IElement e) { - AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); - double m01 = at.getShearX(); - double m11 = at.getScaleY(); - return -Math.atan2(m01, m11); - } - - @Override - public Point2D getPosition(IElement e) { - AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); - Point2D p = new Point2D.Double(at.getTranslateX(), at.getTranslateY()); - return p; - } - - @Override - public void moveTo(IElement e, double x, double y) { - AffineTransform origAt = e.getHint(ElementHints.KEY_TRANSFORM); - - AffineTransform result = new AffineTransform(origAt); - result.preConcatenate(AffineTransform.getTranslateInstance(x - origAt.getTranslateX(), y - origAt.getTranslateY())); - e.setHint(ElementHints.KEY_TRANSFORM, result); - } - - @Override - public AffineTransform getTransform(IElement e) { - - AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); - - IElement parentElement = e.getHint(ElementHints.KEY_PARENT_ELEMENT); - if(parentElement == null) return at; - - Transform parentTransform = parentElement.getElementClass().getSingleItem(Transform.class); - assert(parentTransform!=null); - - AffineTransform result = (AffineTransform)at.clone(); - AffineTransform parentAT = parentTransform.getTransform(parentElement); - result.preConcatenate(AffineTransform.getTranslateInstance(parentAT.getTranslateX(), parentAT.getTranslateY())); - - return result; - - } - - @Override - public void setTransform(IElement e, AffineTransform at) { - e.setHint(ElementHints.KEY_TRANSFORM, at.clone()); - } - - @Override - public void onElementActivated(IDiagram d, IElement e) { - } - - @Override - public void onElementCreated(IElement e) { - e.setHint(ElementHints.KEY_TRANSFORM, new AffineTransform()); - } - - @Override - public void onElementDeactivated(IDiagram d, IElement e) { - } - - @Override - public void onElementDestroyed(IElement e) { - } - - -} +/******************************************************************************* + * 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.element.handler.impl; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.util.Collection; + +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.LifeCycle; +import org.simantics.g2d.element.handler.Move; +import org.simantics.g2d.element.handler.Rotate; +import org.simantics.g2d.element.handler.Scale; +import org.simantics.g2d.element.handler.Transform; +import org.simantics.g2d.element.handler.Validator; + +/** + * This class implements Transform, Move, Rotate, and Scale. + * It maintains element position in element variable ElementHints.KEY_TRANSFORM. + * + * @author Toni Kalajainen + */ +public class DefaultTransform implements Transform, Move, Rotate, Scale, Validator, LifeCycle { + + private static final long serialVersionUID = -2394690413166528179L; + + public static final DefaultTransform INSTANCE = new DefaultTransform(null); + + Double aspectRatio; + + public DefaultTransform() { + this(null); + } + + public DefaultTransform(Double aspectRatio) { + this.aspectRatio = aspectRatio; + } + + @Override + public Double getFixedAspectRatio(IElement e) { + return aspectRatio; + } + + @Override + public Point2D getScale(IElement e) { + AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); + return _getScale(at); + } + + @Override + public void setScale(IElement e, Point2D newScale) { + Point2D oldScale = getScale(e); + double sx = newScale.getX() / oldScale.getX(); + double sy = newScale.getY() / oldScale.getY(); + AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); + at = new AffineTransform(at); + at.scale(sx, sy); + e.setHint(ElementHints.KEY_TRANSFORM, at); + } + + @Override + public Point2D getMaximumScale(IElement e) { + return null; + } + + @Override + public Point2D getMinimumScale(IElement e) { + return null; + } + + private static Point2D _getScale(AffineTransform at) { + double m00 = at.getScaleX(); + double m11 = at.getScaleY(); + double m10 = at.getShearY(); + double m01 = at.getShearX(); + // Project unit vector to canvas + double sx = Math.sqrt(m00 * m00 + m10 * m10); + double sy = Math.sqrt(m01 * m01 + m11 * m11); + return new Point2D.Double(sx, sy); + } + + @Override + public void validate(final IElement e, final ICanvasContext ctx, Collection lst) { + /* + if (aspectRatio != null) { + // Validate aspect ratio + final Point2D scale = getScale(e); + double currentRatio = scale.getX() / scale.getY(); + if (Math.abs(currentRatio - aspectRatio) > 0.000001) { + lst.add(new Issue() { + @Override + public String getMessage() { + return "Aspect ratio is wrong"; + } + + @Override + public void addSuggestions( + Collection suggestionList) { + suggestionList.add(new Suggestion() { + @Override + public boolean fix() { + double newSx = scale.getX(); + double newSy = newSx * aspectRatio; + Point2D newScale = new Point2D.Double(newSx, + newSy); + setScale(e, newScale); + ctx.setDirty(); + return true; + } + + @Override + public String getMessage() { + return "Scale height, keep width"; + } + }); + } + }); + } + // TODO min scale validator + // TODO max scale validator + } + + if (e.getHint(ElementHints.KEY_TRANSFORM) == null) { + Issue i = new Issue() { + @Override + public String getMessage() { + return "Transform is missing"; + } + + @Override + public void addSuggestions(Collection suggestionList) { + Suggestion s = new Suggestion() { + @Override + public boolean fix() { + e.setHint(ElementHints.KEY_TRANSFORM, + new AffineTransform()); + return true; + } + + @Override + public String getMessage() { + return "Set default transform"; + } + }; + suggestionList.add(s); + } + }; + lst.add(i); + } + */ + } + + @Override + public void rotate(IElement e, double theta, Point2D origo) { + if (Double.isNaN(theta)) return; + AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); + at = (AffineTransform) at.clone(); + Point2D localOrigo = at.transform(origo, null); + at.preConcatenate(AffineTransform.getRotateInstance(theta, localOrigo.getX(), localOrigo.getY())); + // This code concatenated the matrix from the wrong side + //at.rotate(theta, origo.getX(), origo.getY()); + e.setHint(ElementHints.KEY_TRANSFORM, at); + } + + @Override + public double getAngle(IElement e) { + AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); + double m01 = at.getShearX(); + double m11 = at.getScaleY(); + return -Math.atan2(m01, m11); + } + + @Override + public Point2D getPosition(IElement e) { + AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); + Point2D p = new Point2D.Double(at.getTranslateX(), at.getTranslateY()); + return p; + } + + @Override + public void moveTo(IElement e, double x, double y) { + AffineTransform origAt = e.getHint(ElementHints.KEY_TRANSFORM); + + AffineTransform result = new AffineTransform(origAt); + result.preConcatenate(AffineTransform.getTranslateInstance(x - origAt.getTranslateX(), y - origAt.getTranslateY())); + e.setHint(ElementHints.KEY_TRANSFORM, result); + } + + @Override + public AffineTransform getTransform(IElement e) { + + AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM); + + IElement parentElement = e.getHint(ElementHints.KEY_PARENT_ELEMENT); + if(parentElement == null) return at; + + Transform parentTransform = parentElement.getElementClass().getSingleItem(Transform.class); + assert(parentTransform!=null); + + AffineTransform result = (AffineTransform)at.clone(); + AffineTransform parentAT = parentTransform.getTransform(parentElement); + result.preConcatenate(AffineTransform.getTranslateInstance(parentAT.getTranslateX(), parentAT.getTranslateY())); + + return result; + + } + + @Override + public void setTransform(IElement e, AffineTransform at) { + e.setHint(ElementHints.KEY_TRANSFORM, at.clone()); + } + + @Override + public void onElementActivated(IDiagram d, IElement e) { + } + + @Override + public void onElementCreated(IElement e) { + e.setHint(ElementHints.KEY_TRANSFORM, new AffineTransform()); + } + + @Override + public void onElementDeactivated(IDiagram d, IElement e) { + } + + @Override + public void onElementDestroyed(IElement e) { + } + + +}