/*******************************************************************************
* 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.fx.operations;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.AbstractOperation;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.gef.fx.utils.NodeUtils;
import org.eclipse.gef.mvc.fx.parts.ITransformableContentPart;
import javafx.scene.Node;
import javafx.scene.transform.Affine;
/**
* The {@link TransformVisualOperation} can be used to change an {@link Affine},
* for example, one that is contained within the transformations list of a
* {@link Node} to transform that {@link Node}.
*
* @author mwienand
*
*/
public class TransformVisualOperation extends AbstractOperation
implements ITransactionalOperation {
private ITransformableContentPart<? extends Node> transformablePart;
private Affine initialTransform;
private Affine finalTransform;
/**
* Constructs a new {@link TransformVisualOperation} to change the given
* <i>nodeTransform</i>.
*
* @param transformablePart
* The {@link ITransformableContentPart} that will be transformed
* by this operation.
*/
public TransformVisualOperation(
ITransformableContentPart<? extends Node> transformablePart) {
this(transformablePart, transformablePart.getVisualTransform());
}
/**
* Constructs a new {@link TransformVisualOperation} to change the given
* <i>nodeTransform</i>. The given <i>newTransform</i> will be applied to
* the <i>nodeTransform</i> upon execution of this operation.
*
* @param transformablePart
* The {@link ITransformableContentPart} that will be transformed
* by this operation.
* @param newTransform
* The {@link Affine} that will be set as the visual
* transformation for the given {@link ITransformableContentPart}
* upon execution of this operation.
*/
public TransformVisualOperation(
ITransformableContentPart<? extends Node> transformablePart,
Affine newTransform) {
super("Transform");
this.transformablePart = transformablePart;
this.initialTransform = NodeUtils.setAffine(new Affine(),
transformablePart.getVisualTransform());
this.finalTransform = NodeUtils.setAffine(new Affine(), newTransform);
}
/**
* Sets the visual transformation to the given {@link Affine}.
*
* @param transform
* The {@link Affine} that is to be set as the total visual
* transformation for the {@link ITransformableContentPart}.
*/
protected void applyTransform(Affine transform) {
if (!NodeUtils.equals(transformablePart.getVisualTransform(),
transform)) {
transformablePart.setVisualTransform(transform);
}
}
@Override
public IStatus execute(IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
applyTransform(finalTransform);
return Status.OK_STATUS;
}
/**
* Returns the initial {@link Affine} of the
* {@link ITransformableContentPart}.
*
* @return The initial {@link Affine} of the
* {@link ITransformableContentPart}.
*/
public Affine getInitialTransform() {
return initialTransform;
}
/**
* Returns the {@link Affine} that will be set as the transformation matrix
* of the {@link ITransformableContentPart}.
*
* @return The {@link Affine} that will be set as the transformation matrix
* of the {@link ITransformableContentPart}.
*/
public Affine getNewTransform() {
return finalTransform;
}
@Override
public boolean isContentRelevant() {
return false;
}
@Override
public boolean isNoOp() {
return NodeUtils.equals(initialTransform, finalTransform);
}
@Override
public IStatus redo(IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
return execute(monitor, info);
}
/**
* Sets the {@link Affine} that will be set as the transformation matrix of
* the {@link ITransformableContentPart}.
*
* @param newTransform
* The {@link Affine} that will be set as the transformation
* matrix of the {@link ITransformableContentPart}.
*/
public void setFinalTransform(Affine newTransform) {
this.finalTransform = NodeUtils.setAffine(new Affine(), newTransform);
}
@Override
public IStatus undo(IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
applyTransform(initialTransform);
return Status.OK_STATUS;
}
}