/*******************************************************************************
* 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
* Alexander Nyßen (itemis AG) - initial API & implementation
*
*******************************************************************************/
package org.eclipse.gef.zest.fx.behaviors;
import org.eclipse.gef.geometry.planar.Dimension;
import org.eclipse.gef.geometry.planar.Point;
import org.eclipse.gef.layout.LayoutContext;
import org.eclipse.gef.layout.LayoutProperties;
import org.eclipse.gef.mvc.fx.parts.IContentPart;
import org.eclipse.gef.zest.fx.ZestProperties;
import org.eclipse.gef.zest.fx.parts.NodePart;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.transform.Affine;
/**
* The {@link NodeLayoutBehavior} is a {@link NodePart}-specific
* {@link AbstractLayoutBehavior} implementation.
*
* @author mwienand
* @author anyssen
*
*/
// only applicable to NodePart (see #getHost())
public class NodeLayoutBehavior extends AbstractLayoutBehavior {
private Dimension preLayoutSize = null;
@Override
public NodePart getHost() {
return (NodePart) super.getHost();
}
@Override
protected LayoutContext getLayoutContext() {
IContentPart<? extends Node> graphPart = getHost().getRoot().getViewer().getContentPartMap()
.get(getHost().getContent().getGraph());
return graphPart.getAdapter(GraphLayoutBehavior.class).getLayoutContext();
}
@Override
protected void postLayout() {
org.eclipse.gef.graph.Node content = getHost().getContent();
// update size
Dimension postLayoutSize = LayoutProperties.getSize(content);
if (postLayoutSize != null) {
ZestProperties.setSize(content, postLayoutSize);
}
// location is center, position is top-left
Point postLayoutLocation = LayoutProperties.getLocation(content);
if (postLayoutLocation != null) {
ZestProperties.setPosition(content, postLayoutLocation.getTranslated(
(postLayoutSize == null ? preLayoutSize : postLayoutSize).getScaled(0.5).getNegated()));
}
// refresh our visual
getHost().refreshVisual();
// update label positions (from visual locations) as they are not
// provided by layout
layoutLabels();
}
@Override
protected void preLayout() {
org.eclipse.gef.graph.Node content = getHost().getContent();
Node visual = getHost().getVisual();
Bounds hostBounds = visual.getLayoutBounds();
double minx = hostBounds.getMinX();
double miny = hostBounds.getMinY();
double maxx = hostBounds.getMaxX();
double maxy = hostBounds.getMaxY();
Affine transform = getHost().getVisualTransform();
// initialize size
if (ZestProperties.getSize(content) != null) {
// no model information available yet, use visual location
preLayoutSize = ZestProperties.getSize(content).getCopy();
} else {
preLayoutSize = new Dimension(maxx - minx, maxy - miny);
}
// constrain to visual's min-size
{
double minWidth = visual.minWidth(-1);
double minHeight = visual.minHeight(-1);
if (preLayoutSize.width < minWidth) {
preLayoutSize.width = minWidth;
}
if (preLayoutSize.height < minHeight) {
preLayoutSize.height = minHeight;
}
}
// System.out.println("pre layout size of " + content + ": " +
// preLayoutSize);
LayoutProperties.setSize(content, preLayoutSize.getCopy());
// initialize location (layout location is center while visual position
// is top-left)
if (ZestProperties.getPosition(content) != null) {
LayoutProperties.setLocation(content,
ZestProperties.getPosition(content).getTranslated(preLayoutSize.getScaled(0.5)));
} else {
// no model information available yet, use visual location
LayoutProperties.setLocation(content, new Point(transform.getTx() + minx + (maxx - minx) / 2,
transform.getTy() + miny + (maxy - miny) / 2));
}
// additional information inferred from visual
LayoutProperties.setResizable(content, visual.isResizable());
}
}