blob: ee0118246bde90bd34d6af47984ce98cbe08e15e [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2013, 2013 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.fmc.blockdiagram.editor.algorithm.node;
import org.eclipse.fmc.blockdiagram.editor.util.StyleUtil;
import org.eclipse.fmc.blockdiagram.editor.util.FMCUtil;
import org.eclipse.graphiti.mm.GraphicsAlgorithmContainer;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.Shape;
/**
* This storage algorithm class represents the standard rectangular shape with
* rounded corners for storages.
*
* @author Heiko Witteborg
*
*/
public class RectangleStorageAlgorithm extends AbstractRectangleAlgorithm
implements StorageAlgorithm {
// ----------------------------------------
// ----------- Graphics Node --------------
public static final int STORAGE_MINIMUM_WIDTH = 15;
public static final int STORAGE_MINIMUM_HEIGHT = 15;
public static final int STORAGE_DEFAULT_WIDTH = 60;
public static final int STORAGE_DEFAULT_HEIGHT = 40;
public static final int STORAGE_DEFAULT_LINEWIDTH = 3;
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.GraphicsNode#createGraphics(org.eclipse
* .graphiti.mm.pictograms.Diagram,
* org.eclipse.graphiti.mm.GraphicsAlgorithmContainer, int, int, int, int)
*/
public GraphicsAlgorithm createGraphics(Diagram diagram,
GraphicsAlgorithmContainer container, int x, int y, int width,
int height) {
int w = width; // width < STORAGE_MINIMUM_CORNER_WIDTH * 2 ?
// STORAGE_MINIMUM_CORNER_WIDTH * 2 : width;
int h = height; // height < STORAGE_MINIMUM_CORNER_WIDTH * 2 ?
// STORAGE_MINIMUM_CORNER_WIDTH * 2 : height;
int cornerWidth = (w < h) ? w : h;
RoundedRectangle rec = ga.createRoundedRectangle(container,
cornerWidth, cornerWidth);
ga.setLocationAndSize(rec, x, y, w, h);
rec.setLineWidth(3);
rec.setTransparency(null);
rec.setStyle(StyleUtil.getStyle(diagram, StyleUtil.SHAPE));
// Create anchors
if (container instanceof GraphicsAlgorithm) {
ContainerShape containerShape = this.getContainerShape(rec);
pe.createChopboxAnchor(containerShape);
createBoxAnchorSet(containerShape);
}
return rec;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.GraphicsNode#getMinimumHeight()
*/
public int getMinimumHeight() {
return STORAGE_MINIMUM_HEIGHT;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.GraphicsNode#getMinimumWidth()
*/
public int getMinimumWidth() {
return STORAGE_MINIMUM_WIDTH;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.GraphicsNode#getDefaultHeight()
*/
public int getDefaultHeight() {
return STORAGE_DEFAULT_HEIGHT;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.GraphicsNode#getDefaultWidth()
*/
public int getDefaultWidth() {
return STORAGE_DEFAULT_WIDTH;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.GraphicsNode#getDefaultLineWidth()
*/
public int getDefaultLineWidth() {
return STORAGE_DEFAULT_LINEWIDTH;
}
// ----------------------------------------
// ----------- Resizable Node -------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.graphicsalgorithms.FMCNodeAlgorithm#resize
* (org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm, int, int, int,
* int)
*/
public void resize(GraphicsAlgorithm algorithm, int x, int y, int width,
int height) {
ContainerShape container = this.getContainerShape(algorithm);
ga.setLocationAndSize(algorithm, x, y, width, height);
// update rounded corner width and height
RoundedRectangle rec = (RoundedRectangle) algorithm;
int cornerWidth = (width < height) ? width : height;
rec.setCornerHeight(cornerWidth);
rec.setCornerWidth(cornerWidth);
relocateText(algorithm);
// adapt first level container (relative anchors + invisible shape)
createBoxAnchorSet(container);
}
// ----------------------------------------
// ----------- Anchored Node --------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.AbstractNode#addBoxAnchorSet(org.eclipse
* .graphiti.mm.pictograms.ContainerShape)
*/
protected void addBoxAnchorSet(Shape shape) {
int radius, numOfAnchorsForStraightSections;
GraphicsAlgorithm firstLevelRectangle = shape.getGraphicsAlgorithm(); // graphics
// =
// Rectangle
GraphicsAlgorithm secondLevelRectangle = firstLevelRectangle
.getGraphicsAlgorithmChildren().get(0); // graphics = Rectangle
// adapt anchors when drawing background part (front part)
double gapForStraightSections, offsetMultiInstance = 0.0d;
if (firstLevelRectangle.getWidth() != secondLevelRectangle.getWidth()) {
// Remove anchors created when drawing the main part
FMCUtil.removeObsoleteAnchors(shape);
offsetMultiInstance = MULTI_INSTANCE_GAP;
}
if (secondLevelRectangle.getWidth() > secondLevelRectangle.getHeight()) {
// case width > height
// A
// ___________
// / \
// D | | B
// \ ___________ /
//
// C
// add anchors for A+C
radius = secondLevelRectangle.getHeight() / 2;
numOfAnchorsForStraightSections = (secondLevelRectangle.getWidth() - 2 * radius)
/ AnchoredNode.DEFAULT_ANCHOR_GAP;
double relativeOffsetXForA = (((double) radius + offsetMultiInstance) / firstLevelRectangle
.getWidth());
double relativeOffsetXForC = ((double) radius)
/ firstLevelRectangle.getWidth();
double relativeOffsetYForA = 0.0d;
double relativeOffsetYForC = 1.0d - (((double) AnchoredNode.DEFAULT_ANCHOR_DIAMETER) / firstLevelRectangle
.getHeight());
gapForStraightSections = (1.0d - relativeOffsetXForA - relativeOffsetXForC)
/ numOfAnchorsForStraightSections;
for (int i = 0; i <= numOfAnchorsForStraightSections; i++) {
createBoxAnchor(shape, relativeOffsetXForA + i
* gapForStraightSections, relativeOffsetYForA,
AnchoredNode.DEFAULT_ANCHOR_GAP,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
createBoxAnchor(shape, relativeOffsetXForC + i
* gapForStraightSections, relativeOffsetYForC,
AnchoredNode.DEFAULT_ANCHOR_GAP,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
}
// add anchors for B+D
double relativeOffsetXForB = (((double) firstLevelRectangle
.getWidth()) - AnchoredNode.DEFAULT_ANCHOR_DIAMETER)
/ firstLevelRectangle.getWidth();
double relativeOffsetXForD = 0.0d;
double relativeOffsetYForB = (((double) radius) - (AnchoredNode.DEFAULT_ANCHOR_DIAMETER / 2))
/ firstLevelRectangle.getHeight();
double relativeOffsetYForD = (((double) radius)
- (AnchoredNode.DEFAULT_ANCHOR_DIAMETER / 2) + offsetMultiInstance)
/ firstLevelRectangle.getHeight();
createBoxAnchor(shape, relativeOffsetXForD, relativeOffsetYForD,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
createBoxAnchor(shape, relativeOffsetXForB, relativeOffsetYForB,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
} else {
// case width < height
// A
// ___
// / \
// | |
// D | | B
// | |
// \___/
//
// C
// add anchors for B+D
radius = secondLevelRectangle.getWidth() / 2;
numOfAnchorsForStraightSections = (secondLevelRectangle.getHeight() - 2 * radius)
/ AnchoredNode.DEFAULT_ANCHOR_GAP;
double relativeOffsetYForB = ((double) radius)
/ firstLevelRectangle.getHeight();
double relativeOffsetYForD = ((double) radius + offsetMultiInstance)
/ firstLevelRectangle.getHeight();
double relativeOffsetXForB = 1.0d - (((double) AnchoredNode.DEFAULT_ANCHOR_DIAMETER) / firstLevelRectangle
.getWidth());
double relativeOffsetXForD = 0.0d;
gapForStraightSections = (1.0d - relativeOffsetYForB - relativeOffsetYForD)
/ numOfAnchorsForStraightSections;
for (int i = 0; i <= numOfAnchorsForStraightSections; i++) {
createBoxAnchor(shape, relativeOffsetXForD, relativeOffsetYForD
+ i * gapForStraightSections,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER,
AnchoredNode.DEFAULT_ANCHOR_GAP);
createBoxAnchor(shape, relativeOffsetXForB, relativeOffsetYForB
+ i * gapForStraightSections,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER,
AnchoredNode.DEFAULT_ANCHOR_GAP);
}
// add anchors for A+C
double relativeOffsetXForA = (((double) radius)
- (AnchoredNode.DEFAULT_ANCHOR_DIAMETER / 2) + offsetMultiInstance)
/ firstLevelRectangle.getWidth();
double relativeOffsetXForC = (((double) radius) - (AnchoredNode.DEFAULT_ANCHOR_DIAMETER / 2))
/ firstLevelRectangle.getWidth();
double relativeOffsetYForA = 0.0d;
double relativeOffsetYForC = (((double) firstLevelRectangle
.getHeight()) - AnchoredNode.DEFAULT_ANCHOR_DIAMETER)
/ firstLevelRectangle.getHeight();
createBoxAnchor(shape, relativeOffsetXForA, relativeOffsetYForA,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
createBoxAnchor(shape, relativeOffsetXForC, relativeOffsetYForC,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
}
}
}