/*******************************************************************************
* 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:
* Alexander Nyßen (itemis AG) - initial API and implementation
* Matthias Wienand (itemis AG) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.fx.anchors;
import org.eclipse.gef.geometry.convert.fx.FX2Geometry;
import org.eclipse.gef.geometry.planar.Point;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
/**
* An {@link StaticAnchor} provides a position for each {@link AnchorKey}, based
* on a reference position relative to the anchorage {@link Node}, to which the
* {@link StaticAnchor} is bound, or based on a (global) static reference
* position in case the {@link StaticAnchor} is unbound.
*
* @author anyssen
* @author mwienand
*/
public class StaticAnchor extends AbstractAnchor {
private ObjectProperty<Point> referencePositionProperty = new SimpleObjectProperty<>();
{
referencePositionProperty.addListener(new ChangeListener<Point>() {
@Override
public void changed(ObservableValue<? extends Point> observable,
Point oldValue, Point newValue) {
// recompute positions for all anchor keys
updatePositions();
}
});
}
/**
* Creates an {@link StaticAnchor} that is bound to the provided anchorage.
* It will used the passed in reference position (in the local coordinate
* system of the anchorage {@link Node}) to compute positions (see
* {@link #positionsUnmodifiableProperty()}) for all attached
* {@link AnchorKey}s (in the local coordinate system of the attached
* {@link AnchorKey}'s {@link Node} ).
* <p>
* In case the anchorage {@link Node} or any of its ancestors are changed in
* a way that will affect the position, the
* {@link #positionsUnmodifiableProperty()} will be updated.
*
* @param anchorage
* The anchorage {@link Node} to bind this {@link StaticAnchor}
* to.
* @param referencePositionInAnchorageLocal
* The position within the local coordinate space of the
* anchorage {@link Node}, which is used to compute the position
* (in scene coordinates) for all attached {@link AnchorKey}s.
*/
public StaticAnchor(Node anchorage,
Point referencePositionInAnchorageLocal) {
super(anchorage);
referencePositionProperty.set(referencePositionInAnchorageLocal);
}
/**
* Creates an {@link StaticAnchor} that is not bound to an anchorage
* {@link Node} and will always provide the passed in position (in scene
* coordinates) for all attached {@link AnchorKey}s (i.e. anchored
* {@link Node}s).
*
* @param referencePositionInScene
* The position in scene coordinates to be provided for all
* attached {@link AnchorKey}s.
*/
public StaticAnchor(Point referencePositionInScene) {
this(null, referencePositionInScene);
}
@Override
protected Point computePosition(AnchorKey key) {
// in case an anchorage is set, the position is interpreted to be in its
// local coordinate system, so transform it into scene coordinates
Node anchored = key.getAnchored();
Node anchorage = getAnchorage();
Point positionInScene = anchorage == null
? referencePositionProperty.get()
: FX2Geometry.toPoint(anchorage.localToScene(
referencePositionProperty.get().x,
referencePositionProperty.get().y));
Point positionInAnchoredLocal = FX2Geometry.toPoint(
anchored.sceneToLocal(positionInScene.x, positionInScene.y));
return positionInAnchoredLocal;
}
/**
* Returns the reference position of this {@link StaticAnchor}.
*
* @return The reference position of this {@link StaticAnchor}.
*/
public Point getReferencePosition() {
return referencePositionProperty.get();
}
/**
* Returns the {@link ObjectProperty} that manages the reference position of
* this {@link StaticAnchor}.
*
* @return The {@link ObjectProperty} that manages the reference position of
* this {@link StaticAnchor}.
*/
public ObjectProperty<Point> referencePositionProperty() {
return referencePositionProperty;
}
/**
* Sets the reference position of this {@link StaticAnchor} to the given
* value.
*
* @param referencePosition
* The new reference position for this {@link StaticAnchor}.
*/
public void setReferencePosition(Point referencePosition) {
referencePositionProperty.set(referencePosition);
}
@Override
public String toString() {
return "StaticAnchor[referencePosition = "
+ referencePositionProperty.get() + "]";
}
}