/*******************************************************************************
* Copyright (c) 2014, 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 & implementation
*
*******************************************************************************/
package org.eclipse.gef.zest.tests.fx;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;
import org.eclipse.gef.geometry.convert.fx.Geometry2FX;
import org.eclipse.gef.geometry.planar.Dimension;
import org.eclipse.gef.geometry.planar.Point;
import org.eclipse.gef.graph.Graph;
import org.eclipse.gef.graph.Node;
import org.eclipse.gef.layout.LayoutContext;
import org.eclipse.gef.layout.LayoutProperties;
import org.eclipse.gef.mvc.fx.parts.IVisualPart;
import org.eclipse.gef.mvc.fx.parts.LayeredRootPart;
import org.eclipse.gef.mvc.fx.policies.ResizePolicy;
import org.eclipse.gef.mvc.fx.policies.TransformPolicy;
import org.eclipse.gef.mvc.fx.providers.TransformProvider;
import org.eclipse.gef.mvc.fx.viewer.InfiniteCanvasViewer;
import org.eclipse.gef.mvc.tests.fx.rules.FXApplicationThreadRule;
import org.eclipse.gef.zest.fx.behaviors.NodeLayoutBehavior;
import org.eclipse.gef.zest.fx.parts.NodePart;
import org.junit.Rule;
import org.junit.Test;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.transform.Affine;
public class NodeLayoutBehaviorTests {
/**
* Ensure all tests are executed on the JavaFX application thread (and the
* JavaFX toolkit is properly initialized).
*/
@Rule
public FXApplicationThreadRule fxApplicationThreadRule = new FXApplicationThreadRule();
private Node createNode() {
Node node = new Node.Builder().buildNode();
Graph graph = new Graph.Builder().nodes(node).build();
LayoutContext glc = new LayoutContext();
glc.setGraph(graph);
return node;
}
private NodeLayoutBehavior createNodeLayoutBehavior(final Point location, final Dimension size, final Node node) {
NodeLayoutBehavior behavior = new NodeLayoutBehavior() {
private NodePart host;
@Override
public NodePart getHost() {
if (host == null) {
host = new NodePart() {
{
setAdapter(new ResizePolicy());
TransformProvider transformProvider = new TransformProvider();
setAdapter(transformProvider, IVisualPart.TRANSFORM_PROVIDER_KEY.getRole());
setAdapter(new TransformPolicy());
Affine affine = transformProvider.get();
affine.setTx(location.x);
affine.setTy(location.y);
}
@Override
protected Group doCreateVisual() {
Group visual = super.doCreateVisual();
if (size != null) {
// ensure we are resizable
// getNestedChildrenPane().setPrefWidth(10);
visual.resize(size.width, size.height);
}
return visual;
}
@Override
public Node getContent() {
return node;
}
};
// TODO: use injection
LayeredRootPart rootPart = new LayeredRootPart();
InfiniteCanvasViewer viewer = new InfiniteCanvasViewer();
viewer.setAdapter(rootPart);
host.setParent(rootPart);
}
return host;
}
};
return behavior;
}
@Test
public void test_adapt() throws Exception {
Node nodeLayout = createNode();
NodeLayoutBehavior behavior = createNodeLayoutBehavior(new Point(), null, nodeLayout);
Point location = new Point(1, 5);
Dimension size = new Dimension(100, 200);
LayoutProperties.setLocation(nodeLayout, location);
LayoutProperties.setSize(nodeLayout, size);
// postLayout
Method method = NodeLayoutBehavior.class.getDeclaredMethod("postLayout", new Class[] {});
method.setAccessible(true);
method.invoke(behavior, new Object[] {});
// zest position is top-left, while layout location is center
Affine affine = Geometry2FX
.toFXAffine(behavior.getHost().getAdapter(TransformPolicy.class).getCurrentTransform());
assertEquals(location.getTranslated(size.getScaled(-0.5)), new Point(affine.getTx(), affine.getTy()));
}
@Test
public void test_provide() throws Exception {
final Point location = new Point(10, 20);
// setup with non-resizable figure
Node nodeLayout = createNode();
NodeLayoutBehavior behavior = createNodeLayoutBehavior(location, null, nodeLayout);
Group visual = behavior.getHost().getVisual();
// preLayout
Method method = NodeLayoutBehavior.class.getDeclaredMethod("preLayout", new Class[] {});
method.setAccessible(true);
method.invoke(behavior, new Object[] {});
assertEquals(visual.isResizable(), LayoutProperties.isResizable(nodeLayout));
// zest position is top-left, while layout location is center
Bounds layoutBounds = visual.getLayoutBounds();
double minX = layoutBounds.getMinX();
double minY = layoutBounds.getMinY();
double maxX = layoutBounds.getMaxX();
double maxY = layoutBounds.getMaxY();
assertEquals(location, LayoutProperties.getLocation(nodeLayout).translate(-minX - ((maxX - minX) / 2),
-minY - ((maxY - minY) / 2)));
assertEquals(new Dimension(layoutBounds.getWidth(), layoutBounds.getHeight()),
LayoutProperties.getSize(nodeLayout));
}
}