/******************************************************************************* | |
* <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 java.util.ArrayList; | |
import java.util.List; | |
import org.eclipse.emf.common.util.EList; | |
import org.eclipse.fmc.blockdiagram.editor.util.FMCUtil; | |
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; | |
import org.eclipse.graphiti.mm.algorithms.MultiText; | |
import org.eclipse.graphiti.mm.algorithms.Polygon; | |
import org.eclipse.graphiti.mm.algorithms.styles.Point; | |
import org.eclipse.graphiti.mm.pictograms.ContainerShape; | |
import org.eclipse.graphiti.mm.pictograms.Shape; | |
/** | |
* This abstract class collects all methods common to U-shaped polygons. | |
* | |
* 07 43 xx xx x6xx5x 1xxxx2 | |
* | |
* | |
* @author Benjamin Schmeling | |
* @author Heiko Witteborg | |
* | |
*/ | |
public abstract class AbstractUPolygonAlgorithm extends | |
AbstractLPolygonAlgorithm implements UPolygonAlgorithm { | |
// ---------------------------------------- | |
// ----------- (U)Polygon Impl ------------ | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.fmc.blockdiagram.editor.node.AbstractLPolygonAlgorithm#getInitialPoints | |
* (int, int, int, int) | |
*/ | |
public List<Point> getInitialPoints(int x, int y, int width, int height) { | |
int outerCornerSize = hasRoundedCorners() ? L_PART_DEFAULT_SIZE / 2 : 0; | |
int innerCornerSize = hasRoundedCorners() ? outerCornerSize * 2 / 3 : 0; | |
List<Point> points = new ArrayList<Point>(); | |
/* 0 */points.add(ga | |
.createPoint(x, y, outerCornerSize, outerCornerSize)); | |
/* 1 */points.add(ga.createPoint(x, y + height, outerCornerSize, | |
outerCornerSize)); | |
/* 2 */points.add(ga.createPoint(x + width, y + height, | |
outerCornerSize, outerCornerSize)); | |
/* 3 */points.add(ga.createPoint(x + width, y, outerCornerSize, | |
outerCornerSize)); | |
/* 4 */points.add(ga.createPoint(x + width - L_PART_DEFAULT_SIZE, y, | |
outerCornerSize, outerCornerSize)); | |
/* 5 */points.add(ga.createPoint(x + width - L_PART_DEFAULT_SIZE, y | |
+ height - L_PART_DEFAULT_SIZE, innerCornerSize, | |
innerCornerSize)); | |
/* 6 */points.add(ga.createPoint(x + L_PART_DEFAULT_SIZE, y + height | |
- L_PART_DEFAULT_SIZE, innerCornerSize, innerCornerSize)); | |
/* 7 */points.add(ga.createPoint(x + L_PART_DEFAULT_SIZE, y, | |
outerCornerSize, outerCornerSize)); | |
return points; | |
} | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.fmc.blockdiagram.editor.polygon.UPolygonAlgorithm#resizeLeftPart( | |
* org.eclipse.graphiti.mm.algorithms.Polygon, int) | |
*/ | |
public void resizeLeftPart(Polygon polygon, int size) { | |
int oldSize = getLeftPartSize(polygon); | |
int sizeDif = size - oldSize; | |
EList<Point> points = polygon.getPoints(); | |
if (sizeDif != 0) { | |
switch (getAngle(polygon)) { | |
case 90: | |
points.get(6).setY(points.get(6).getY() + sizeDif); | |
points.get(7).setY(points.get(7).getY() + sizeDif); | |
break; | |
case 180: | |
points.get(6).setX(points.get(6).getX() - sizeDif); | |
points.get(7).setX(points.get(7).getX() - sizeDif); | |
break; | |
case 270: | |
points.get(6).setY(points.get(6).getY() - sizeDif); | |
points.get(7).setY(points.get(7).getY() - sizeDif); | |
break; | |
default: | |
points.get(6).setX(points.get(6).getX() + sizeDif); | |
points.get(7).setX(points.get(7).getX() + sizeDif); | |
} | |
} | |
// adapt corner roundings if polygon has rounded corners | |
if (hasRoundedCorners()) { | |
int leftTopCornerSize = getLeftPartTopCornerSize(polygon); | |
int leftBottomCornerSize = getLeftPartBottomCornerSize(polygon); | |
points.get(0).setBefore(leftTopCornerSize); | |
points.get(0).setAfter(leftTopCornerSize); | |
points.get(1).setBefore(leftBottomCornerSize); | |
points.get(6).setAfter(leftBottomCornerSize); | |
points.get(7).setBefore(leftTopCornerSize); | |
points.get(7).setAfter(leftTopCornerSize); | |
} | |
relocateText(polygon); | |
EList<GraphicsAlgorithm> graphicsAlgorithmChildren = polygon | |
.getGraphicsAlgorithmChildren(); | |
for (int i = 0; i < graphicsAlgorithmChildren.size(); i++) { | |
// Resize left part of polygon children | |
if (graphicsAlgorithmChildren.get(i) instanceof Polygon) | |
this.resizeLeftPart((Polygon) graphicsAlgorithmChildren.get(i), | |
size); | |
// Update relative anchors when the ga modification is done | |
if (i == graphicsAlgorithmChildren.size() - 1) | |
createBoxAnchorSet(this.getContainerShape(polygon)); | |
} | |
} | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.fmc.blockdiagram.editor.polygon.UPolygonAlgorithm#getLeftPartSize | |
* (org.eclipse.graphiti.mm.algorithms.Polygon) | |
*/ | |
public int getLeftPartSize(Polygon polygon) { | |
EList<Point> points = polygon.getPoints(); | |
if (isFlattened(polygon)) | |
return Math.abs(points.get(7).getY() - points.get(0).getY()); | |
else | |
return Math.abs(points.get(7).getX() - points.get(0).getX()); | |
} | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see org.eclipse.fmc.blockdiagram.editor.graphicsalgorithms.LPolygonAlgorithm# | |
* resizeBottomPart(org.eclipse.graphiti.mm.algorithms.Polygon, int) | |
*/ | |
public void resizeBottomPart(Polygon polygon, int size) { | |
int oldSize = getBottomPartSize(polygon); | |
int sizeDif = isFlipped(polygon) ? oldSize - size : size - oldSize; | |
EList<Point> points = polygon.getPoints(); | |
if (sizeDif != 0) { | |
switch (getAngle(polygon)) { | |
case 90: | |
points.get(6).setX(points.get(6).getX() + sizeDif); | |
points.get(5).setX(points.get(5).getX() + sizeDif); | |
break; | |
case 180: | |
points.get(6).setY(points.get(6).getY() + sizeDif); | |
points.get(5).setY(points.get(5).getY() + sizeDif); | |
break; | |
case 270: | |
points.get(6).setX(points.get(6).getX() - sizeDif); | |
points.get(5).setX(points.get(5).getX() - sizeDif); | |
break; | |
default: | |
points.get(6).setY(points.get(6).getY() - sizeDif); | |
points.get(5).setY(points.get(5).getY() - sizeDif); | |
} | |
} | |
// adapt corner roundings if polygon has rounded corners | |
if (hasRoundedCorners()) { | |
int bottomLeftCornerSize = getBottomPartLeftCornerSize(polygon); | |
int bottomRightCornerSize = getBottomPartRightCornerSize(polygon); | |
points.get(1).setAfter(bottomLeftCornerSize); | |
points.get(2).setBefore(bottomRightCornerSize); | |
points.get(5).setAfter(bottomRightCornerSize); | |
points.get(6).setBefore(bottomLeftCornerSize); | |
} | |
relocateText(polygon); | |
EList<GraphicsAlgorithm> graphicsAlgorithmChildren = polygon | |
.getGraphicsAlgorithmChildren(); | |
for (int i = 0; i < graphicsAlgorithmChildren.size(); i++) { | |
// Resize bottom part of polygon children | |
if (graphicsAlgorithmChildren.get(i) instanceof Polygon) | |
this.resizeBottomPart( | |
(Polygon) graphicsAlgorithmChildren.get(i), size); | |
// Update relative anchors when the ga modification is done | |
if (i == graphicsAlgorithmChildren.size() - 1) | |
createBoxAnchorSet(this.getContainerShape(polygon)); | |
} | |
} | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.fmc.blockdiagram.editor.node.UPolygonAlgorithm#getLeftPartTopCornerSize | |
* (org.eclipse.graphiti.mm.algorithms.Polygon) | |
*/ | |
public int getLeftPartTopCornerSize(Polygon polygon) { | |
return getLeftPartSize(polygon) / 2; | |
} | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see org.eclipse.fmc.blockdiagram.editor.node.UPolygonAlgorithm# | |
* getLeftPartBottomCornerSize(org.eclipse.graphiti.mm.algorithms.Polygon) | |
*/ | |
public int getLeftPartBottomCornerSize(Polygon polygon) { | |
return getLeftPartTopCornerSize(polygon); | |
} | |
// ---------------------------------------- | |
// ----------- Resizable Node ------------- | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.fmc.blockdiagram.editor.node.AbstractLPolygonAlgorithm#resize(org | |
* .eclipse.graphiti.mm.algorithms.GraphicsAlgorithm, int, int, int, int) | |
*/ | |
public void resize(GraphicsAlgorithm algorithm, int x, int y, int width, | |
int height) { | |
Polygon polygon = (Polygon) algorithm; | |
int angle = getAngle(polygon); | |
int[] resizeX = new int[4]; | |
int[] resizeY = new int[4]; | |
if (isFlipped(polygon)) { | |
switch (angle) { | |
case 90: | |
resizeX[0] = 1; | |
resizeX[1] = 2; | |
resizeX[2] = 5; | |
resizeX[3] = 6; | |
resizeY[0] = 2; | |
resizeY[1] = 3; | |
resizeY[2] = 4; | |
resizeY[3] = 5; | |
break; | |
case 180: | |
resizeX[0] = 0; | |
resizeX[1] = 1; | |
resizeX[2] = 6; | |
resizeX[3] = 7; | |
resizeY[0] = 1; | |
resizeY[1] = 2; | |
resizeY[2] = 5; | |
resizeY[3] = 6; | |
break; | |
case 270: | |
resizeX[0] = 0; | |
resizeX[1] = 3; | |
resizeX[2] = 4; | |
resizeX[3] = 7; | |
resizeY[0] = 0; | |
resizeY[1] = 1; | |
resizeY[2] = 6; | |
resizeY[3] = 7; | |
break; | |
default: | |
resizeX[0] = 2; | |
resizeX[1] = 3; | |
resizeX[2] = 4; | |
resizeX[3] = 5; | |
resizeY[0] = 0; | |
resizeY[1] = 3; | |
resizeY[2] = 4; | |
resizeY[3] = 7; | |
} | |
} else { | |
switch (angle) { | |
case 90: | |
resizeX[0] = 0; | |
resizeX[1] = 3; | |
resizeX[2] = 4; | |
resizeX[3] = 7; | |
resizeY[0] = 2; | |
resizeY[1] = 3; | |
resizeY[2] = 4; | |
resizeY[3] = 5; | |
break; | |
case 180: | |
resizeX[0] = 0; | |
resizeX[1] = 1; | |
resizeX[2] = 6; | |
resizeX[3] = 7; | |
resizeY[0] = 0; | |
resizeY[1] = 3; | |
resizeY[2] = 4; | |
resizeY[3] = 7; | |
break; | |
case 270: | |
resizeX[0] = 1; | |
resizeX[1] = 2; | |
resizeX[2] = 5; | |
resizeX[3] = 6; | |
resizeY[0] = 0; | |
resizeY[1] = 1; | |
resizeY[2] = 6; | |
resizeY[3] = 7; | |
break; | |
default: | |
resizeX[0] = 2; | |
resizeX[1] = 3; | |
resizeX[2] = 4; | |
resizeX[3] = 5; | |
resizeY[0] = 1; | |
resizeY[1] = 2; | |
resizeY[2] = 5; | |
resizeY[3] = 6; | |
} | |
} | |
int oldHeight = polygon.getHeight(); | |
int oldWidth = polygon.getWidth(); | |
int heightDif = height - oldHeight; | |
int widthDif = width - oldWidth; | |
EList<Point> points = polygon.getPoints(); | |
for (int i = 0; i < resizeX.length; i++) { | |
points.get(resizeX[i]).setX( | |
points.get(resizeX[i]).getX() + widthDif); | |
} | |
for (int i = 0; i < resizeY.length; i++) { | |
points.get(resizeY[i]).setY( | |
points.get(resizeY[i]).getY() + heightDif); | |
} | |
// adapt corner roundings if polygon has rounded corners | |
if (hasRoundedCorners()) { | |
int leftTopCornerSize = getLeftPartTopCornerSize(polygon); | |
int leftBottomCornerSize = getLeftPartBottomCornerSize(polygon); | |
int rightTopCornerSize = getRightPartTopCornerSize(polygon); | |
int rightBottomCornerSize = getRightPartBottomCornerSize(polygon); | |
int bottomLeftCornerSize = getBottomPartLeftCornerSize(polygon); | |
int bottomRightCornerSize = getBottomPartRightCornerSize(polygon); | |
points.get(0).setBefore(leftTopCornerSize); | |
points.get(0).setAfter(leftTopCornerSize); | |
points.get(1).setBefore(leftBottomCornerSize); | |
points.get(1).setAfter(bottomLeftCornerSize); | |
points.get(2).setBefore(bottomRightCornerSize); | |
points.get(2).setAfter(rightBottomCornerSize); | |
points.get(3).setBefore(rightTopCornerSize); | |
points.get(3).setAfter(rightTopCornerSize); | |
points.get(4).setBefore(rightTopCornerSize); | |
points.get(4).setAfter(rightTopCornerSize); | |
points.get(5).setBefore(rightBottomCornerSize); | |
points.get(5).setAfter(bottomRightCornerSize); | |
points.get(6).setBefore(bottomLeftCornerSize); | |
points.get(6).setAfter(leftBottomCornerSize); | |
points.get(7).setBefore(leftTopCornerSize); | |
points.get(7).setAfter(leftTopCornerSize); | |
} | |
ga.setLocationAndSize(polygon, x, y, width, height); | |
relocateText(polygon); | |
// adapt first level container (relative anchors + invisible shape) | |
ContainerShape container = this.getContainerShape(polygon); | |
createBoxAnchorSet(container); | |
synchronizeFirstLevelShape(container); | |
} | |
// ---------------------------------------- | |
// ----------- Named Node ----------------- | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.fmc.blockdiagram.editor.node.NamedNode#relocateText(org.eclipse.graphiti | |
* .mm.algorithms.GraphicsAlgorithm) | |
*/ | |
public void relocateText(GraphicsAlgorithm graphicsAlgorithm) { | |
Polygon polygon = (Polygon) graphicsAlgorithm; | |
MultiText text = this.getText(graphicsAlgorithm); | |
if (text != null) { | |
int multipleOffset = 0; | |
if (this.isMultipleInstances(this | |
.getContainerShape(graphicsAlgorithm))) { | |
multipleOffset = MULTI_INSTANCE_GAP; | |
} | |
int angle = getAngle(graphicsAlgorithm); | |
int textContainingPartSize; | |
boolean isOnTop = false; | |
switch (angle) { | |
case 90: | |
textContainingPartSize = getRightPartSize(polygon); | |
break; | |
case 270: | |
textContainingPartSize = getLeftPartSize(polygon); | |
break; | |
default: | |
textContainingPartSize = getBottomPartSize(polygon); | |
} | |
if ((isFlipped(graphicsAlgorithm) && angle == 0) | |
|| (!isFlipped(graphicsAlgorithm) && angle == 180)) { | |
isOnTop = true; | |
} | |
int x = super.textMargin; | |
int width = graphicsAlgorithm.getWidth() - 2 * super.textMargin | |
- multipleOffset; | |
int y = (isOnTop ? super.textMargin : graphicsAlgorithm.getHeight() | |
- textContainingPartSize + super.textMargin) | |
+ multipleOffset; | |
int height = textContainingPartSize - 2 * super.textMargin | |
- multipleOffset; | |
ga.setLocationAndSize(text, x, y, width, height); | |
} | |
} | |
// ---------------------------------------- | |
// ----------- Anchored Node -------------- | |
@Override | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.eclipse.fmc.blockdiagram.editor.node.AbstractLPolygonAlgorithm#addBoxAnchorSet | |
* (org.eclipse.graphiti.mm.pictograms.ContainerShape) | |
*/ | |
protected void addBoxAnchorSet(Shape shape) { | |
GraphicsAlgorithm firstLevelPolygon = shape.getGraphicsAlgorithm(); | |
Polygon secondLevelPolygon = (Polygon) firstLevelPolygon | |
.getGraphicsAlgorithmChildren().get(0); | |
// Sides of the polygon: | |
// 7 3 | |
// --- --- | |
// | | | | | |
// | | 6 4 | | | |
// 0 | | 5 | | 2 | |
// | ------- | | |
// | | | |
// --------------- | |
// 1 | |
int numSides = 8; | |
int lineWidth = getDefaultLineWidth(); | |
Point[] point = new Point[numSides]; | |
for (int i = 0; i < point.length; i++) { | |
point[i] = secondLevelPolygon.getPoints().get(i); | |
} | |
// Offset in case of a multi instance shape (adapt anchors when drawing | |
// background part) | |
double offsetMultiInstance = 0.0d; | |
if (firstLevelPolygon.getWidth() != secondLevelPolygon.getWidth()) { | |
// Remove anchors created when drawing the main part | |
FMCUtil.removeObsoleteAnchors(shape); | |
offsetMultiInstance = MULTI_INSTANCE_GAP; | |
} | |
// Length of the sides (not taking into account rounded corners) | |
int[] length = new int[numSides]; | |
length[0] = Math.abs(isFlattened(secondLevelPolygon) ? point[2].getX() | |
- point[3].getX() : point[2].getY() - point[3].getY()); | |
length[1] = Math.abs(isFlattened(secondLevelPolygon) ? point[1].getY() | |
- point[2].getY() : point[1].getX() - point[2].getX()); | |
length[2] = length[0]; | |
length[3] = getRightPartSize(secondLevelPolygon) + lineWidth; | |
length[4] = length[2] - getBottomPartSize(secondLevelPolygon); | |
length[6] = length[4]; | |
length[7] = getLeftPartSize(secondLevelPolygon) + lineWidth; | |
length[5] = length[1] - length[7] - length[3]; | |
// Length of the sides that should contain anchors | |
int[] anchoredLength = new int[numSides]; | |
for (int i = 0; i < numSides; i++) | |
anchoredLength[i] = Math.max(length[i] - point[i].getAfter() | |
- point[(i + 1) % numSides].getBefore(), | |
DEFAULT_ANCHOR_DIAMETER); | |
// Number of anchors of the sides | |
int[] numAnchors = new int[numSides]; | |
// Gaps between the anchor starting points of the sides (in x and y | |
// direction) | |
double[][] gaps = new double[numSides][2]; | |
for (int i = 0; i < gaps.length; i++) | |
for (int j = 0; j < gaps[i].length; j++) | |
gaps[i][j] = 0.0d; | |
// Offsets of the starting points of the sides (in x and y direction) | |
double[][] offset = new double[numSides][2]; | |
switch (getAngle(secondLevelPolygon)) { | |
case 90: | |
if (isFlipped(secondLevelPolygon)) { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = 0.0d; | |
offset[0][0] = offsetMultiInstance; | |
offset[1][1] = 0.0d; | |
offset[1][0] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[2][1] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[2][0] = 0.0d; | |
offset[3][1] = length[7] + length[5] + offsetMultiInstance; | |
offset[3][0] = 0.0d; | |
offset[4][1] = length[7] + length[5]; | |
offset[4][0] = offsetMultiInstance; | |
offset[5][1] = length[7] + offsetMultiInstance; | |
offset[5][0] = length[4] - lineWidth; | |
offset[6][1] = length[7] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[6][0] = 0.0d; | |
offset[7][1] = offsetMultiInstance; | |
offset[7][0] = 0.0d; | |
// adjust length of segments due to overlapping of multi | |
// instances | |
if (offsetMultiInstance > point[4].getAfter()) | |
anchoredLength[4] = anchoredLength[4] | |
- (int) Math.abs((offsetMultiInstance - point[4] | |
.getAfter())); | |
} else { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = 0.0d; | |
offset[0][0] = offsetMultiInstance; | |
offset[1][1] = offsetMultiInstance; | |
offset[1][0] = 0.0d; | |
offset[2][1] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[2][0] = 0.0d; | |
offset[3][1] = length[7] + length[5]; | |
offset[3][0] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[4][1] = length[7] + length[5]; | |
offset[4][0] = length[0] - length[4] + offsetMultiInstance; | |
offset[5][1] = length[7]; | |
offset[5][0] = length[0] - length[4] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER + lineWidth; | |
offset[6][1] = length[7] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[6][0] = length[0] - length[4] + offsetMultiInstance; // overlapping | |
offset[7][1] = 0.0d; | |
offset[7][0] = length[0] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
// adjust length of segments due to overlapping of multi | |
// instances | |
if (offsetMultiInstance > point[6].getAfter()) | |
anchoredLength[6] = anchoredLength[6] | |
- (int) Math.abs((offsetMultiInstance - point[6] | |
.getAfter())); | |
} | |
break; | |
case 180: | |
if (isFlipped(secondLevelPolygon)) { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = 0.0d; | |
offset[0][0] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[1][1] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[1][0] = 0.0d; | |
offset[2][1] = offsetMultiInstance; | |
offset[2][0] = 0.0d; | |
offset[3][1] = 0.0d; | |
offset[3][0] = offsetMultiInstance; | |
offset[4][1] = 0.0d; | |
offset[4][0] = length[3] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[5][1] = length[4] - lineWidth; | |
offset[5][0] = length[3] + offsetMultiInstance; | |
offset[6][1] = offsetMultiInstance; | |
offset[6][0] = length[3] + length[5]; | |
offset[7][1] = 0.0d; | |
offset[7][0] = length[3] + length[5] + offsetMultiInstance; | |
} else { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = 0.0d; | |
offset[0][0] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[1][1] = 0.0d; | |
offset[1][0] = offsetMultiInstance; | |
offset[2][1] = offsetMultiInstance; | |
offset[2][0] = 0.0d; | |
offset[3][1] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[3][0] = 0.0d; | |
offset[4][1] = length[0] - length[4] + offsetMultiInstance; | |
offset[4][0] = length[3] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[5][1] = length[0] - length[4] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER + lineWidth; | |
offset[5][0] = length[3] + offsetMultiInstance; | |
offset[6][1] = length[0] - length[4] + offsetMultiInstance; | |
offset[6][0] = length[3] + length[5]; | |
offset[7][1] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[7][0] = length[3] + length[5]; | |
// adjust length of segments due to overlapping of multi | |
// instances | |
if (offsetMultiInstance > point[4].getAfter()) | |
anchoredLength[4] = anchoredLength[4] | |
- (int) Math.abs((offsetMultiInstance - point[4] | |
.getAfter())); | |
} | |
break; | |
case 270: | |
if (isFlipped(secondLevelPolygon)) { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[0][0] = 0.0d; | |
offset[1][1] = offsetMultiInstance; | |
offset[1][0] = 0.0d; | |
offset[2][1] = 0.0d; | |
offset[2][0] = offsetMultiInstance; | |
offset[3][1] = 0.0d; | |
offset[3][0] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[4][1] = length[3] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[4][0] = length[0] - length[4] + offsetMultiInstance; | |
offset[5][1] = length[3] + offsetMultiInstance; | |
offset[5][0] = length[0] - length[4] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER + lineWidth; | |
offset[6][1] = length[3] + length[5]; | |
offset[6][0] = length[0] - length[4] + offsetMultiInstance; | |
offset[7][1] = length[3] + length[5]; | |
offset[7][0] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
// adjust length of segments due to overlapping of multi | |
// instances | |
if (offsetMultiInstance > point[4].getAfter()) | |
anchoredLength[4] = anchoredLength[4] | |
- (int) Math.abs((offsetMultiInstance - point[4] | |
.getAfter())); | |
if (offsetMultiInstance > point[5].getAfter()) | |
anchoredLength[5] = anchoredLength[5] | |
- (int) Math.abs((offsetMultiInstance - point[5] | |
.getAfter())); | |
} else { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[0][0] = 0.0d; | |
offset[1][1] = 0.0d; | |
offset[1][0] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[2][1] = 0.0d; | |
offset[2][0] = offsetMultiInstance; | |
offset[3][1] = offsetMultiInstance; | |
offset[3][0] = 0.0d; | |
offset[4][1] = length[3] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[4][0] = 0.0d; | |
offset[5][1] = length[3] + offsetMultiInstance; | |
offset[5][0] = length[4] - lineWidth; | |
offset[6][1] = length[3] + length[5]; | |
offset[6][0] = offsetMultiInstance; | |
offset[7][1] = length[3] + length[5] + offsetMultiInstance; | |
offset[7][0] = 0.0d; | |
// adjust length of segments due to overlapping of multi | |
// instances | |
if (offsetMultiInstance > point[6].getAfter()) | |
anchoredLength[6] = anchoredLength[6] | |
- (int) Math.abs((offsetMultiInstance - point[6] | |
.getAfter())); | |
} | |
break; | |
default: // rotation = 0 | |
if (isFlipped(secondLevelPolygon)) { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = offsetMultiInstance; | |
offset[0][0] = 0.0d; | |
offset[1][1] = 0.0d; | |
offset[1][0] = offsetMultiInstance; | |
offset[2][1] = 0.0d; | |
offset[2][0] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[3][1] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[3][0] = length[7] + length[5]; | |
offset[4][1] = length[0] - length[4] + offsetMultiInstance; | |
offset[4][0] = length[7] + length[5]; | |
offset[5][1] = length[0] - length[4] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER + lineWidth; | |
offset[5][0] = length[7]; | |
offset[6][1] = length[0] - length[4] + offsetMultiInstance; | |
offset[6][0] = length[7] - DEFAULT_ANCHOR_DIAMETER | |
+ offsetMultiInstance; // overlapping | |
offset[7][1] = length[0] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[7][0] = 0.0d; | |
// adjust length of segments due to overlapping of multi | |
// instances | |
if (offsetMultiInstance > point[6].getAfter()) | |
anchoredLength[6] = anchoredLength[6] | |
- (int) (offsetMultiInstance - point[6].getAfter()); | |
} else { | |
// specify relative starting points of polygon line segments | |
offset[0][1] = offsetMultiInstance; | |
offset[0][0] = 0.0d; | |
offset[1][1] = length[2] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[1][0] = 0.0d; | |
offset[2][1] = 0.0d; | |
offset[2][0] = length[1] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[3][1] = 0.0d; | |
offset[3][0] = length[7] + length[5] + offsetMultiInstance; | |
offset[4][1] = offsetMultiInstance; | |
offset[4][0] = length[7] + length[5]; | |
offset[5][1] = length[4] - lineWidth; | |
offset[5][0] = length[7] + offsetMultiInstance; | |
offset[6][1] = 0.0d; | |
offset[6][0] = length[7] + offsetMultiInstance | |
- DEFAULT_ANCHOR_DIAMETER; | |
offset[7][1] = 0.0d; | |
offset[7][0] = offsetMultiInstance; | |
// adjust length of segments due to overlapping of multi | |
// instances | |
if (offsetMultiInstance > point[5].getAfter()) | |
anchoredLength[5] = anchoredLength[5] | |
- (int) (offsetMultiInstance - point[5].getAfter()); | |
} | |
} | |
// adjust offsets according to rounded corners | |
for (int i = 0; i < numSides; i++) { | |
if (point[i].getX() == point[(i + 1) % numSides].getX()) { // vertical | |
// side | |
offset[i][1] = offset[i][1] | |
+ (point[i].getY() < point[(i + 1) % numSides].getY() ? (point[i] | |
.getAfter() > 0 ? point[i].getAfter() | |
- ((double) DEFAULT_ANCHOR_DIAMETER) / 2 : 0.0d) | |
: (point[(i + 1) % numSides].getBefore() > 0 ? point[(i + 1) | |
% numSides].getBefore() | |
- ((double) DEFAULT_ANCHOR_DIAMETER) | |
/ 2 | |
: 0.0d)); | |
} else { // horizontal side | |
offset[i][0] = offset[i][0] | |
+ (point[i].getX() < point[(i + 1) % numSides].getX() ? (point[i] | |
.getAfter() > 0 ? point[i].getAfter() | |
- ((double) DEFAULT_ANCHOR_DIAMETER) / 2 : 0.0d) | |
: (point[(i + 1) % numSides].getBefore() > 0 ? point[(i + 1) | |
% numSides].getBefore() | |
- ((double) DEFAULT_ANCHOR_DIAMETER) | |
/ 2 | |
: 0.0d)); | |
} | |
} | |
// Calculate number of anchors per side | |
for (int i = 0; i < numSides; i++) | |
numAnchors[i] = anchoredLength[i] / DEFAULT_ANCHOR_GAP; | |
// Calculate gaps between the starting points of the anchors for each | |
// side | |
int direction = 0; | |
for (int i = 0; i < numSides; i++) { | |
direction = isFlattened(secondLevelPolygon) ? (i % 2) | |
: ((i + 1) % 2); | |
gaps[i][direction] = ((double) anchoredLength[i]) / numAnchors[i]; | |
} | |
// Create relative box anchors | |
for (int i = 0; i < numSides; i++) | |
for (int j = 0; j < numAnchors[i]; j++) | |
createBoxAnchor(shape, (offset[i][0] + j * gaps[i][0]) | |
/ firstLevelPolygon.getWidth(), (offset[i][1] + j | |
* gaps[i][1]) | |
/ firstLevelPolygon.getHeight(), | |
AnchoredNode.DEFAULT_ANCHOR_GAP, | |
AnchoredNode.DEFAULT_ANCHOR_DIAMETER); | |
} | |
} |