/*******************************************************************************
* 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.examples.logo.handlers;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.gef.fx.nodes.Connection;
import org.eclipse.gef.geometry.convert.fx.FX2Geometry;
import org.eclipse.gef.mvc.fx.handlers.AbstractHandler;
import org.eclipse.gef.mvc.fx.handlers.IOnClickHandler;
import org.eclipse.gef.mvc.fx.models.SelectionModel;
import org.eclipse.gef.mvc.fx.operations.DeselectOperation;
import org.eclipse.gef.mvc.fx.parts.IContentPart;
import org.eclipse.gef.mvc.fx.parts.IRootPart;
import org.eclipse.gef.mvc.fx.parts.ITransformableContentPart;
import org.eclipse.gef.mvc.fx.policies.CreationPolicy;
import org.eclipse.gef.mvc.fx.policies.TransformPolicy;
import org.eclipse.gef.mvc.fx.viewer.IViewer;
import com.google.common.collect.HashMultimap;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.transform.Affine;
public class CloneOnClickHandler extends AbstractHandler implements IOnClickHandler {
@Override
public void click(MouseEvent event) {
if (!isCloneModifierDown(event)) {
return;
}
// clone content
Object cloneContent = getHost().getAdapter(AbstractCloneContentSupport.class).cloneContent();
// create the clone content part
IRootPart<? extends Node> root = getHost().getRoot();
CreationPolicy creationPolicy = root.getAdapter(CreationPolicy.class);
init(creationPolicy);
IContentPart<? extends Node> clonedContentPart = creationPolicy.create(cloneContent, getHost().getParent(),
HashMultimap.<IContentPart<? extends Node>, String> create());
commit(creationPolicy);
// XXX: Ensure start and end anchor are set for connections, so that
// they can be interacted with (transform/bend).
if (clonedContentPart.getVisual() instanceof Connection) {
Connection connection = (Connection) clonedContentPart.getVisual();
if (connection.getStartAnchor() == null) {
connection.setStartPoint(((Connection) getHost().getVisual()).getStartPoint());
}
if (connection.getEndAnchor() == null) {
connection.setEndPoint(((Connection) getHost().getVisual()).getEndPoint());
}
}
// deselect all but the clone
IViewer viewer = getHost().getRoot().getViewer();
List<? extends IContentPart<? extends Node>> toBeDeselected = new ArrayList<>(
viewer.getAdapter(SelectionModel.class).getSelectionUnmodifiable());
toBeDeselected.remove(clonedContentPart);
try {
viewer.getDomain().execute(new DeselectOperation(getHost().getRoot().getViewer(), toBeDeselected),
new NullProgressMonitor());
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
// copy the transformation
if (getHost() instanceof ITransformableContentPart) {
@SuppressWarnings("unchecked")
ITransformableContentPart<Node> transformableContentPart = (ITransformableContentPart<Node>) getHost();
Affine originalTransform = transformableContentPart.getVisualTransform();
TransformPolicy transformPolicy = clonedContentPart.getAdapter(TransformPolicy.class);
init(transformPolicy);
transformPolicy.setTransform(FX2Geometry.toAffineTransform(originalTransform));
commit(transformPolicy);
}
}
protected boolean isCloneModifierDown(MouseEvent e) {
return e.isAltDown() || e.isShiftDown();
}
}