/*******************************************************************************
* Copyright (c) 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 java.util.Map;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.gef.common.adapt.AdapterKey;
import org.eclipse.gef.geometry.planar.Dimension;
import org.eclipse.gef.geometry.planar.Point;
import org.eclipse.gef.mvc.examples.logo.model.GeometricShape;
import org.eclipse.gef.mvc.examples.logo.parts.GeometricShapePart;
import org.eclipse.gef.mvc.fx.domain.IDomain;
import org.eclipse.gef.mvc.fx.gestures.ClickDragGesture;
import org.eclipse.gef.mvc.fx.handlers.AbstractHandler;
import org.eclipse.gef.mvc.fx.handlers.IOnDragHandler;
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.LayeredRootPart;
import org.eclipse.gef.mvc.fx.policies.CreationPolicy;
import org.eclipse.gef.mvc.fx.viewer.IViewer;
import org.eclipse.gef.mvc.fx.viewer.InfiniteCanvasViewer;
import com.google.common.collect.HashMultimap;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
public class CreateAndTranslateShapeOnDragHandler extends AbstractHandler implements IOnDragHandler {
private GeometricShapePart createdShapePart;
private Map<AdapterKey<? extends IOnDragHandler>, IOnDragHandler> dragPolicies;
@Override
public void abortDrag() {
if (createdShapePart == null) {
return;
}
// forward event to bend target part
if (dragPolicies != null) {
for (IOnDragHandler dragPolicy : dragPolicies.values()) {
dragPolicy.abortDrag();
}
}
createdShapePart = null;
dragPolicies = null;
}
@Override
public void drag(MouseEvent event, Dimension delta) {
if (createdShapePart == null) {
return;
}
// forward drag events to bend target part
if (dragPolicies != null) {
for (IOnDragHandler dragPolicy : dragPolicies.values()) {
dragPolicy.drag(event, delta);
}
}
}
@Override
public void endDrag(MouseEvent e, Dimension delta) {
if (createdShapePart == null) {
return;
}
// forward event to bend target part
if (dragPolicies != null) {
for (IOnDragHandler dragPolicy : dragPolicies.values()) {
dragPolicy.endDrag(e, delta);
}
}
restoreRefreshVisuals(createdShapePart);
createdShapePart = null;
dragPolicies = null;
}
protected IViewer getContentViewer() {
return getHost().getRoot().getViewer().getDomain()
.getAdapter(AdapterKey.get(IViewer.class, IDomain.CONTENT_VIEWER_ROLE));
}
@Override
public GeometricShapePart getHost() {
return (GeometricShapePart) super.getHost();
}
protected Point getLocation(MouseEvent e) {
Point2D location = ((InfiniteCanvasViewer) getHost().getRoot().getViewer()).getCanvas().getContentGroup()
.sceneToLocal(e.getSceneX(), e.getSceneY());
return new Point(location.getX(), location.getY());
}
@Override
public void hideIndicationCursor() {
}
@Override
public boolean showIndicationCursor(KeyEvent event) {
return false;
}
@Override
public boolean showIndicationCursor(MouseEvent event) {
return false;
}
@Override
public void startDrag(MouseEvent event) {
// find model part
IRootPart<? extends Node> contentRoot = getContentViewer().getRootPart();
// copy the prototype
GeometricShape copy = getHost().getContent().getCopy();
// determine coordinates of prototype's origin in model coordinates
Point2D localToScene = getHost().getVisual().localToScene(0, 0);
Point2D originInModel = ((LayeredRootPart) getContentViewer().getRootPart()).getContentLayer()
.sceneToLocal(localToScene.getX(), localToScene.getY());
// initially move to the originInModel
double[] matrix = copy.getTransform().getMatrix();
copy.getTransform().setTransform(matrix[0], matrix[1], matrix[2], matrix[3], originInModel.getX(),
originInModel.getY());
// create copy of host's geometry using CreationPolicy from root part
CreationPolicy creationPolicy = contentRoot.getAdapter(CreationPolicy.class);
init(creationPolicy);
createdShapePart = (GeometricShapePart) creationPolicy.create(copy, contentRoot,
HashMultimap.<IContentPart<? extends Node>, String> create());
commit(creationPolicy);
// disable refresh visuals for the created shape part
storeAndDisableRefreshVisuals(createdShapePart);
// build operation to deselect all but the new part
List<IContentPart<? extends Node>> toBeDeselected = new ArrayList<>(
getContentViewer().getAdapter(SelectionModel.class).getSelectionUnmodifiable());
toBeDeselected.remove(createdShapePart);
DeselectOperation deselectOperation = new DeselectOperation(getContentViewer(), toBeDeselected);
// execute on stack
try {
getHost().getRoot().getViewer().getDomain().execute(deselectOperation, new NullProgressMonitor());
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
// find drag target part
dragPolicies = createdShapePart.getAdapters(ClickDragGesture.ON_DRAG_POLICY_KEY);
if (dragPolicies != null) {
for (IOnDragHandler dragPolicy : dragPolicies.values()) {
dragPolicy.startDrag(event);
}
}
}
}