/******************************************************************************* * Copyright (c) 2015, 2016 itemis AG and others. * 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: * Matthias Wienand (itemis AG) - initial API and implementation * *******************************************************************************/ package org.eclipse.gef.mvc.tests.fx; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import java.util.Collections; import java.util.List; import java.util.Map; import org.eclipse.gef.common.adapt.AdapterKey; import org.eclipse.gef.geometry.planar.AffineTransform; import org.eclipse.gef.geometry.planar.Point; import org.eclipse.gef.mvc.fx.MvcFxModule; import org.eclipse.gef.mvc.fx.domain.IDomain; import org.eclipse.gef.mvc.fx.parts.AbstractContentPart; import org.eclipse.gef.mvc.fx.parts.IContentPart; import org.eclipse.gef.mvc.fx.parts.IContentPartFactory; import org.eclipse.gef.mvc.fx.parts.ITransformableContentPart; import org.eclipse.gef.mvc.fx.policies.TransformPolicy; import org.eclipse.gef.mvc.fx.viewer.IViewer; import org.eclipse.gef.mvc.tests.fx.rules.FXApplicationThreadRule; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.google.common.collect.HashMultimap; import com.google.common.collect.SetMultimap; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.multibindings.MapBinder; import javafx.embed.swing.JFXPanel; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.shape.Rectangle; import javafx.scene.transform.Affine; public class TransformPolicyTests { static class PointPart extends AbstractContentPart<Rectangle> implements ITransformableContentPart<Rectangle> { private Affine transform = new Affine(); @Override protected Rectangle doCreateVisual() { return new Rectangle(10, 10); } @Override protected SetMultimap<? extends Object, String> doGetContentAnchorages() { return HashMultimap.create(); } @Override protected List<? extends Object> doGetContentChildren() { return Collections.emptyList(); } @Override protected void doRefreshVisual(Rectangle visual) { visual.setX(getContent().x); visual.setY(getContent().y); } @Override public Point getContent() { return (Point) super.getContent(); } @Override public Affine getContentTransform() { return transform; } @Override public void setContentTransform(Affine transform) { this.transform = transform; } } static class TxContentPartFactory implements IContentPartFactory { @Inject private Injector injector; @Override public IContentPart<? extends Node> createContentPart(Object content, Map<Object, Object> contextMap) { if (content instanceof Point) { return injector.getInstance(PointPart.class); } else { throw new IllegalArgumentException(content.getClass().toString()); } } } private TransformPolicy transformPolicy; @Inject private IDomain domain; /** * Ensure all tests are executed on the JavaFX application thread (and the * JavaFX toolkit is properly initialized). */ @Rule public FXApplicationThreadRule fxApplicationThreadRule = new FXApplicationThreadRule(); public TransformPolicy createTransformPolicy() { // create injector Injector injector = Guice.createInjector(new MvcFxModule() { @Override protected void bindAbstractContentPartAdapters(MapBinder<AdapterKey<?>, Object> adapterMapBinder) { super.bindAbstractContentPartAdapters(adapterMapBinder); adapterMapBinder.addBinding(AdapterKey.defaultRole()).to(TransformPolicy.class); } protected void bindIContentPartFactory() { binder().bind(IContentPartFactory.class).to(TxContentPartFactory.class); } @Override protected void configure() { super.configure(); bindIContentPartFactory(); } }); injector.injectMembers(this); // get viewer IViewer viewer = domain.getAdapter(AdapterKey.get(IViewer.class, IDomain.CONTENT_VIEWER_ROLE)); // hook viewer to scene Scene scene = new Scene(viewer.getCanvas(), 100, 100); JFXPanel panel = new JFXPanel(); panel.setScene(scene); // set viewer contents Point content = new Point(0, 0); viewer.getContents().setAll(Collections.singletonList(content)); // activate domain domain.activate(); // get content part for the content object IContentPart<? extends Node> contentPart = viewer.getContentPartMap().get(content); // get transform policy for that part return contentPart.getAdapter(TransformPolicy.class); } @Before public void setUp() { transformPolicy = createTransformPolicy(); transformPolicy.init(); } @Test public void test_concat() { // test that the initial and current node transformation are identity // transforms assertEquals(new AffineTransform(), transformPolicy.getInitialTransform()); assertEquals(transformPolicy.getInitialTransform(), transformPolicy.getCurrentTransform()); // create pre and post transforms assertEquals(0, transformPolicy.createPreTransform()); assertEquals(1, transformPolicy.createPreTransform()); assertEquals(2, transformPolicy.createPreTransform()); assertEquals(0, transformPolicy.createPostTransform()); assertEquals(1, transformPolicy.createPostTransform()); assertEquals(2, transformPolicy.createPostTransform()); // create affine transformations here that are transfered to the // transform policy AffineTransform t0 = new AffineTransform().setToScale(2, 2); AffineTransform t1 = new AffineTransform().setToTranslation(2, 2); AffineTransform t2 = new AffineTransform().setToRotation(2); AffineTransform t3 = new AffineTransform().setToScale(2, 2); AffineTransform t4 = new AffineTransform().setToTranslation(2, 2); AffineTransform t5 = new AffineTransform().setToRotation(2); // transfer them transformPolicy.setPostTransform(2, t0); transformPolicy.setPostTransform(1, t1); transformPolicy.setPostTransform(0, t2); transformPolicy.setPreTransform(0, t3); transformPolicy.setPreTransform(1, t4); transformPolicy.setPreTransform(2, t5); // test the concatenation AffineTransform concatenation = t0.getCopy().concatenate(t1).concatenate(t2).concatenate(t3).concatenate(t4) .concatenate(t5); assertEquals(concatenation, transformPolicy.getCurrentTransform()); } @Test public void test_create() { // test that the initial and current node transformation are identity // transforms assertEquals(new AffineTransform(), transformPolicy.getInitialTransform()); assertEquals(transformPolicy.getInitialTransform(), transformPolicy.getCurrentTransform()); // create a new transform that is applied before the node transformation int firstPreIndex = transformPolicy.createPreTransform(); // test that the first created transform has index 0 assertEquals(0, firstPreIndex); // create a new transform that is applied after the node transformation int firstPostIndex = transformPolicy.createPostTransform(); // test that the first created transform has index 0 assertEquals(0, firstPostIndex); // create a new transform that is applied before all transformations int secondPreIndex = transformPolicy.createPreTransform(); // test that the second created transform has index 1 assertEquals(1, secondPreIndex); // create a new transform that is applied after all transformations int secondPostIndex = transformPolicy.createPostTransform(); // test that the second created transform has index 1 assertEquals(1, secondPostIndex); // explicitly set one of the transforms to identity so that the // composite transform is computed transformPolicy.setPreTranslate(firstPreIndex, 0, 0); // test that the composite transformation equals the initial // transformation since only identity transforms have been applied assertEquals(transformPolicy.getInitialTransform(), transformPolicy.getCurrentTransform()); // set all transforms to translations transformPolicy.setPreTranslate(firstPreIndex, 10, 10); transformPolicy.setPreTranslate(secondPreIndex, 10, 10); transformPolicy.setPostTranslate(firstPostIndex, 10, 10); transformPolicy.setPostTranslate(secondPostIndex, 10, 10); // test that the composite transform equals a translation by 40, 40 (4 // individual translations by 10, 10 => 40, 40) assertEquals(new AffineTransform().setToTranslation(40, 40), transformPolicy.getCurrentTransform()); } @Test public void test_init() { // test that the initial and current node transformation are identity // transforms assertEquals(new AffineTransform(), transformPolicy.getInitialTransform()); assertEquals(transformPolicy.getInitialTransform(), transformPolicy.getCurrentTransform()); // create a new transform that is applied before the node transformation int firstIndex = transformPolicy.createPreTransform(); // test that the first created transform has index 0 assertEquals(0, firstIndex); // set the transform to a translation transformPolicy.setPreTranslate(firstIndex, 10, 10); // test that the initial node transformation differs from the current // node transformation (due to the translation) assertFalse(transformPolicy.getInitialTransform().equals(transformPolicy.getCurrentTransform())); // call init() again to reset the policy transformPolicy.rollback(); transformPolicy.init(); // test that the initial and current node transformation are identity // transforms again assertEquals(new AffineTransform(), transformPolicy.getInitialTransform()); assertEquals(transformPolicy.getInitialTransform(), transformPolicy.getCurrentTransform()); // create a new transform that is applied before the node transformation firstIndex = transformPolicy.createPreTransform(); // test that the first created transform has index 0 assertEquals(0, firstIndex); } }