| /** |
| * <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); |
| } |
| } |
| } |