blob: a85cbe32badfddffbe9dd8e7e09f4ed2269aa97b [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2011, 2011 SAP AG.
* 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:
* SAP AG - initial API, implementation and documentation
*
* </copyright>
*/
package org.eclipse.graphiti.examples.chess.features;
import org.eclipse.graphiti.examples.chess.MoveUtil;
import org.eclipse.graphiti.examples.chess.diagram.ChessFeatureProvider;
import org.eclipse.graphiti.examples.mm.chess.Colors;
import org.eclipse.graphiti.examples.mm.chess.Piece;
import org.eclipse.graphiti.examples.mm.chess.Square;
import org.eclipse.graphiti.features.IDeleteFeature;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.IMoveShapeContext;
import org.eclipse.graphiti.features.context.IMultiDeleteInfo;
import org.eclipse.graphiti.features.context.impl.DeleteContext;
import org.eclipse.graphiti.features.context.impl.MoveShapeContext;
import org.eclipse.graphiti.features.context.impl.MultiDeleteInfo;
import org.eclipse.graphiti.features.impl.DefaultMoveShapeFeature;
import org.eclipse.graphiti.mm.algorithms.Polygon;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.util.IColorConstant;
/**
*
*/
public class MoveChessPieceFeature extends DefaultMoveShapeFeature {
public MoveChessPieceFeature(IFeatureProvider fp) {
super(fp);
}
@Override
public boolean canMoveShape(IMoveShapeContext context) {
Object bo = getBusinessObjectForPictogramElement(context.getShape());
// We can only move pieces
if (!(bo instanceof Piece)) {
return false;
}
Piece piece = (Piece) bo;
// Moving pieces is only allowed from one square to another not
// within the same square
if (context.getSourceContainer().equals(context.getTargetContainer())) {
return false;
}
// Find the source and target squares
Square sourceSquare = (Square) getBusinessObjectForPictogramElement(context.getSourceContainer());
Object targetBO = getBusinessObjectForPictogramElement(context.getTargetContainer());
Square targetSquare;
if (targetBO instanceof Square) {
targetSquare = (Square) targetBO;
} else if (targetBO instanceof Piece) {
targetSquare = ((Piece) targetBO).getSquare();
} else {
// Not allowed to drop onto anything else than squares and pieces
return false;
}
return MoveUtil.isMoveAllowed(piece, sourceSquare, targetSquare);
}
protected void preMoveShape(IMoveShapeContext context) {
// We need an instance of MoveShapeContext (and can be sure to have it)
// to be able to modify the X and Y coordinates
MoveShapeContext moveContext = (MoveShapeContext) context;
// Set the X and Y coordinates to 0; they are set to the location the
// user dropped the shape but pieces always need a location of 0 because
// the visible polygon already has the offset from the source of the
// containing shape
moveContext.setX(0);
moveContext.setY(0);
Object targetContainerBO = getBusinessObjectForPictogramElement(context.getTargetContainer());
if (targetContainerBO instanceof Piece) {
// Dropped onto piece --> correct the target shape to the shape of
// the square
moveContext.setTargetContainer(context.getTargetContainer().getContainer());
}
}
@Override
protected void postMoveShape(IMoveShapeContext context) {
// Find the moved piece target square (target container was already set
// to the square shape in preMoveShape)
Piece piece = (Piece) getBusinessObjectForPictogramElement(context.getShape());
Square targetSquare = (Square) getBusinessObjectForPictogramElement(context.getTargetContainer());
// Check for taking and delete the taken piece
if (targetSquare.getPiece() != null) {
deleteTakenPieceFromSquare(targetSquare);
}
// Adapt business model to reflect new containment
piece.setSquare(targetSquare);
// Adapt shape
adaptMovedPieceShape(context, targetSquare);
}
private void adaptMovedPieceShape(IMoveShapeContext context, Square targetSquare) {
// Set the line color; it needs to be the opposite color of the square
Polygon polygon = (Polygon) context.getShape().getGraphicsAlgorithm();
if (Colors.LIGHT.equals(targetSquare.getColor())) {
polygon.setForeground(manageColor(IColorConstant.BLACK));
} else {
polygon.setForeground(manageColor(IColorConstant.WHITE));
}
polygon.setLineWidth(2);
}
private void deleteTakenPieceFromSquare(Square targetSquare) {
// Find the shape
ContainerShape takenPieceShape = (ContainerShape) Graphiti.getLinkService()
.getPictogramElements(getDiagram(), targetSquare.getPiece()).get(0);
// Create a delete context for that shape and prevent "are you sure?"
// popup
DeleteContext deleteContext = new DeleteContext(takenPieceShape);
IMultiDeleteInfo multiDeleteInfo = new MultiDeleteInfo(false, false, 0);
deleteContext.setMultiDeleteInfo(multiDeleteInfo);
// Delegate to the delete feature for pieces; since it is disabled for
// the UI we need to set programmatic mode for the feature provider,
// which will enable delivery of the feature
try {
((ChessFeatureProvider) getFeatureProvider()).setProgrammaticFeatureCallActive(true);
IDeleteFeature deleteFeature = getFeatureProvider().getDeleteFeature(deleteContext);
deleteFeature.execute(deleteContext);
} finally {
// Make sure to set back programmatic mode
((ChessFeatureProvider) getFeatureProvider()).setProgrammaticFeatureCallActive(false);
}
}
}