/** * <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.mm.chess.Board; import org.eclipse.graphiti.examples.mm.chess.Colors; import org.eclipse.graphiti.examples.mm.chess.Files; import org.eclipse.graphiti.examples.mm.chess.Ranks; import org.eclipse.graphiti.examples.mm.chess.Square; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.context.IAddContext; import org.eclipse.graphiti.features.impl.AbstractAddShapeFeature; import org.eclipse.graphiti.mm.algorithms.Ellipse; import org.eclipse.graphiti.mm.algorithms.Rectangle; import org.eclipse.graphiti.mm.algorithms.Text; import org.eclipse.graphiti.mm.algorithms.styles.Orientation; import org.eclipse.graphiti.mm.pictograms.BoxRelativeAnchor; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.services.Graphiti; import org.eclipse.graphiti.services.ICreateService; import org.eclipse.graphiti.services.IGaLayoutService; import org.eclipse.graphiti.services.IGaService; import org.eclipse.graphiti.ui.services.GraphitiUi; import org.eclipse.graphiti.util.IColorConstant; public class AddChessBoardFeature extends AbstractAddShapeFeature { private static final int SQUARE_SIZE = 50; private static final int BOARD_SIZE = SQUARE_SIZE * 8; private static final int FRAME_WIDTH = 20; private static final int FRAME_HEIGHT = 20; public AddChessBoardFeature(IFeatureProvider fp) { super(fp); } public boolean canAdd(IAddContext context) { if (context.getNewObject() instanceof Board) { if (context.getTargetContainer() instanceof Diagram) { // Add new board only in case of an empty diagram return context.getTargetContainer().getChildren().size() == 0; } } return false; } public PictogramElement add(IAddContext context) { // Get the Graphiti services ICreateService createService = Graphiti.getCreateService(); IGaLayoutService layoutService = Graphiti.getGaLayoutService(); // Get the board to add Board board = (Board) context.getNewObject(); // Create the visualisation of the board as a square ContainerShape outerContainerShape = createService.createContainerShape(getDiagram(), true); // Create invisible outer rectangle that holds the rank and file names Rectangle outerRectangle = createService.createRectangle(outerContainerShape); outerRectangle.setBackground(manageColor(IColorConstant.LIGHT_GRAY)); outerRectangle.setTransparency(0.8d); layoutService.setLocationAndSize(outerRectangle, context.getX() - FRAME_WIDTH, context.getY() - FRAME_HEIGHT, BOARD_SIZE + FRAME_WIDTH * 2, BOARD_SIZE + FRAME_HEIGHT * 2); for (Files file : Files.values()) { if (Files.NONE.equals(file)) { continue; } // Display file names on top Text text = createService.createText(outerRectangle); setLayoutForBorderTexts(layoutService, text); layoutService.setLocationAndSize(text, FRAME_WIDTH + (file.getValue() - 1) * SQUARE_SIZE, 0, SQUARE_SIZE, FRAME_HEIGHT); text.setValue(file.getLiteral()); // Display file names at bottom text = createService.createText(outerRectangle); setLayoutForBorderTexts(layoutService, text); layoutService.setLocationAndSize(text, FRAME_WIDTH + (file.getValue() - 1) * SQUARE_SIZE, FRAME_HEIGHT + BOARD_SIZE, SQUARE_SIZE, FRAME_HEIGHT); text.setValue(file.getLiteral()); } for (Ranks rank : Ranks.values()) { if (Ranks.NONE.equals(rank)) { continue; } // Display rank names at left side Text text = createService.createText(outerRectangle); setLayoutForBorderTexts(layoutService, text); layoutService.setLocationAndSize(text, 0, FRAME_WIDTH + (8 - rank.getValue()) * SQUARE_SIZE, FRAME_WIDTH, SQUARE_SIZE); text.setValue(Integer.toString(rank.getValue())); // Display rank names at right side text = createService.createText(outerRectangle); setLayoutForBorderTexts(layoutService, text); layoutService.setLocationAndSize(text, FRAME_WIDTH + BOARD_SIZE, FRAME_WIDTH + (8 - rank.getValue()) * SQUARE_SIZE, FRAME_WIDTH, SQUARE_SIZE); text.setValue(Integer.toString(rank.getValue())); } Rectangle boardRectangle = createService.createRectangle(outerRectangle); boardRectangle.setParentGraphicsAlgorithm(outerRectangle); layoutService.setLocationAndSize(boardRectangle, 20, 20, BOARD_SIZE, BOARD_SIZE); // Link the visualisation with the board link(outerContainerShape, board); // Add the 64 single squares to the board for (Square square : board.getSquares()) { // Visualise as a square at the correct location ContainerShape squareShape = createService.createContainerShape(outerContainerShape, true); Rectangle squareRectangle = createService.createRectangle(squareShape); layoutService.setLocationAndSize(squareRectangle, FRAME_WIDTH + square.getOffsetX() * SQUARE_SIZE, FRAME_HEIGHT + square.getOffsetY() * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE); // Set the fill color IColorConstant color; if (square.getColor() == Colors.LIGHT) { color = IColorConstant.WHITE; } else { color = IColorConstant.BLACK; } squareRectangle.setBackground(manageColor(color)); squareRectangle.setForeground(manageColor(color)); // And do the linking link(squareShape, square); // Create an anchor for attaching moves (in fact we are using two // anchors here. The first one is a chopbox anchor that serves for // catching the connection creation. The second one is a box // relative anchor; it is used to actually attach the connection to. // The box relative anchor is visualised as a circle with diameter // 0 (invisible). The advantage of this construction is that it is // possible to attach the connection to the complete shape (via the // chopbox anchor) and not to have the clipping (because of the box // relative anchor) while the user does not have the possibility to // move the anchor around and while he still can get hold of the // shape under the box relative anchor. createService.createChopboxAnchor(squareShape); BoxRelativeAnchor relativeAnchor = createService.createBoxRelativeAnchor(squareShape); relativeAnchor.setRelativeHeight(0.5d); relativeAnchor.setRelativeWidth(0.5d); relativeAnchor.setReferencedGraphicsAlgorithm(squareRectangle); relativeAnchor.setUseAnchorLocationAsConnectionEndpoint(true); Ellipse anchorEllipse = createService.createEllipse(relativeAnchor); layoutService.setLocationAndSize(anchorEllipse, 25, 25, 0, 0); } return outerContainerShape; } private void setLayoutForBorderTexts(IGaLayoutService layoutService, Text text) { text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER); text.setVerticalAlignment(Orientation.ALIGNMENT_CENTER); text.setForeground(manageColor(IColorConstant.BLACK)); text.setFont(GraphitiUi.getGaService().manageFont(getDiagram(), IGaService.DEFAULT_FONT, 12, false, true)); } }