Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/locator/PinPositionLocator.java')
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/locator/PinPositionLocator.java928
1 files changed, 464 insertions, 464 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/locator/PinPositionLocator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/locator/PinPositionLocator.java
index f3fc95ffec0..2bac3856b84 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/locator/PinPositionLocator.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/locator/PinPositionLocator.java
@@ -1,464 +1,464 @@
-/*****************************************************************************
- * Copyright (c) 2009 Atos Origin.
- *
- *
- * 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:
- * Atos Origin - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.uml.diagram.activity.locator;
-
-import org.eclipse.draw2d.AbstractPointListShape;
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.PositionConstants;
-import org.eclipse.draw2d.geometry.Dimension;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
-import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
-import org.eclipse.gmf.runtime.notation.Bounds;
-import org.eclipse.papyrus.uml.diagram.activity.figures.AcceptEventActionFigure;
-import org.eclipse.papyrus.uml.diagram.activity.figures.OutputPinFigure;
-import org.eclipse.papyrus.uml.diagram.activity.figures.PinFigure;
-import org.eclipse.papyrus.uml.diagram.activity.helper.ActivityFigureDrawer;
-import org.eclipse.papyrus.uml.diagram.common.figure.node.PapyrusSendNodeFigure;
-import org.eclipse.papyrus.uml.diagram.common.locator.AdvancedBorderItemLocator;
-import org.eclipse.uml2.uml.Action;
-import org.eclipse.uml2.uml.CallOperationAction;
-
-/**
- * This class is used to constrain the position of Pin
- *
- * TODO : The pin is not re-sizable
- */
-public class PinPositionLocator extends AdvancedBorderItemLocator {
-
- /**
- * The offset to add to default position. (to avoid corner of rounded
- * rectangles)
- */
- public static final int EXTRA_BORDER_DEFAULT_OFFSET = 8;
-
- /** The default size of a pin */
- public static final int DEFAULT_PIN_SIZE = 16;
-
- /**
- * the maximum authorized x position on the template of a Send Signal Action
- * figure
- */
- private static final int SEND_SIGNAL_ACTION_MAX_X = 150;
-
- /** the width of the template of a Send Signal Action figure */
- private static final int SEND_SIGNAL_ACTION_WIDTH = 200;
-
- /** Constructor **/
- public PinPositionLocator(IFigure parentFigure) {
- super(parentFigure);
- }
-
- /** Constructor **/
- public PinPositionLocator(IFigure borderItem, IFigure parentFigure, Rectangle constraint) {
- super(borderItem, parentFigure, constraint);
- }
-
- /** Constructor **/
- public PinPositionLocator(IFigure parentFigure, int preferredSide) {
- super(parentFigure, preferredSide);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Rectangle getValidLocation(Rectangle proposedLocation, IFigure borderItem) {
- Rectangle realLocation = new Rectangle(proposedLocation);
- realLocation.width = Math.max(realLocation.width, realLocation.height);
- realLocation.height = realLocation.width;
- int side = findClosestAuthorizedSideOfParent(proposedLocation, getParentBorder());
- Point newTopLeft = locateOnBorder(realLocation.getTopLeft(), side, 0, borderItem);
- realLocation.setLocation(newTopLeft);
- return realLocation;
- }
-
- /**
- * The preferred side takes precedence.
- *
- * @param suggestedLocation
- * @param suggestedSide
- * @param circuitCount
- * recursion count to avoid an infinite loop
- * @return point
- */
- @Override
- protected Point locateOnBorder(Point suggestedLocation, int suggestedSide, int circuitCount, IFigure borderItem) {
- Point suggestedCenter = borderItem.getBounds().getCopy().setLocation(suggestedLocation).getCenter();
- suggestedSide = redefineSuggestedSide(suggestedCenter, suggestedSide);
- if (isInSendSignalAction()) {
- // prevent a pin too far EAST that would be on the convex sides of
- // the pentagon
- if (suggestedSide == PositionConstants.SOUTH || suggestedSide == PositionConstants.NORTH) {
- int maxLocation = getParentBorder().x + getParentBorder().width * SEND_SIGNAL_ACTION_MAX_X / SEND_SIGNAL_ACTION_WIDTH - getSize(borderItem).width;
- if (suggestedLocation.x > maxLocation) {
- suggestedLocation.x = maxLocation;
- }
- }
- }
- Point recommendedLocation = super.locateOnBorder(suggestedLocation, suggestedSide, circuitCount, borderItem);
- return recommendedLocation;
- }
-
- /**
- * Ensure the suggested location actually lies on the parent boundary. The
- * side takes precedence.
- *
- * @param suggestedLocation
- * suggested location
- * @param suggestedSide
- * suggested side
- * @param borderItem
- * the item figure
- * @return point
- */
- @Override
- protected Point locateOnParent(Point suggestedLocation, int suggestedSide, IFigure borderItem) {
- Rectangle bounds = getParentBorder();
- int parentFigureWidth = bounds.width;
- int parentFigureHeight = bounds.height;
- int parentFigureX = bounds.x;
- int parentFigureY = bounds.y;
- Dimension borderItemSize = getSize(borderItem);
- int newX = suggestedLocation.x;
- int newY = suggestedLocation.y;
- int westX = parentFigureX - borderItemSize.width + getBorderItemOffset().width;
- int eastX = parentFigureX + parentFigureWidth - getBorderItemOffset().width;
- int maxX = 0;
- if (isInSendSignalAction()) {
- // prevent a pin too far EAST that would be on the convex sides of
- // the pentagon
- if (suggestedSide == PositionConstants.SOUTH || suggestedSide == PositionConstants.NORTH) {
- maxX = parentFigureX + parentFigureWidth * SEND_SIGNAL_ACTION_MAX_X / SEND_SIGNAL_ACTION_WIDTH - getBorderItemOffset().width;
- }
- }
- int southY = parentFigureY + parentFigureHeight - getBorderItemOffset().height;
- int northY = parentFigureY - borderItemSize.height + getBorderItemOffset().height;
- if (suggestedSide == PositionConstants.WEST) {
- if (suggestedLocation.x != westX) {
- newX = westX;
- }
- if (suggestedLocation.y < bounds.getTopLeft().y) {
- newY = northY + borderItemSize.height;
- } else if (suggestedLocation.y > bounds.getBottomLeft().y - borderItemSize.height) {
- newY = southY - borderItemSize.height;
- }
- } else if (suggestedSide == PositionConstants.EAST) {
- if (suggestedLocation.x != eastX) {
- newX = eastX;
- }
- if (suggestedLocation.y < bounds.getTopLeft().y) {
- newY = northY + borderItemSize.height;
- } else if (suggestedLocation.y > bounds.getBottomLeft().y - borderItemSize.height) {
- newY = southY - borderItemSize.height;
- }
- } else if (suggestedSide == PositionConstants.SOUTH) {
- if (suggestedLocation.y != southY) {
- newY = southY;
- }
- if (suggestedLocation.x < bounds.getBottomLeft().x) {
- newX = westX + borderItemSize.width;
- } else if (suggestedLocation.x > bounds.getBottomRight().x - borderItemSize.width) {
- newX = eastX - borderItemSize.width;
- }
- } else { // NORTH
- if (suggestedLocation.y != northY) {
- newY = northY;
- }
- if (suggestedLocation.x < bounds.getBottomLeft().x) {
- newX = westX + borderItemSize.width;
- } else if (suggestedLocation.x > bounds.getBottomRight().x - borderItemSize.width) {
- newX = eastX - borderItemSize.width;
- }
- }
- if (maxX > 0 && newX > maxX) {
- newX = maxX;
- }
- return new Point(newX, newY);
- }
-
- /**
- * Recomputes the suggested side by eliminating unauthorized sides depending
- * on the action type
- *
- * @param childCenter
- * suggested location center
- * @param suggestedSide
- * suggested side
- * @return correct side
- */
- private int redefineSuggestedSide(Point childCenter, int suggestedSide) {
- if (isInSendSignalAction()) {
- // EAST side is not authorized
- if (suggestedSide == PositionConstants.EAST) {
- Point parentCenter = getParentBorder().getCenter();
- if (childCenter.y < parentCenter.y) {
- suggestedSide = PositionConstants.NORTH;
- } else {
- suggestedSide = PositionConstants.SOUTH;
- }
- }
- } else if (isInAcceptEventAction()) {
- // WEST side is not authorized
- if (suggestedSide == PositionConstants.WEST) {
- Point parentCenter = getParentBorder().getCenter();
- if (childCenter.y < parentCenter.y) {
- suggestedSide = PositionConstants.NORTH;
- } else {
- suggestedSide = PositionConstants.SOUTH;
- }
- }
- // EAST side is not authorized for AcceptTimeEventAction
- if (suggestedSide == PositionConstants.EAST && isInAcceptTimeEventAction()) {
- Point parentCenter = getParentBorder().getCenter();
- if (childCenter.y < parentCenter.y) {
- suggestedSide = PositionConstants.NORTH;
- } else {
- suggestedSide = PositionConstants.SOUTH;
- }
- }
- }
- return suggestedSide;
- }
-
- /**
- * Find the closest side when x,y is inside parent.
- *
- * @param proposedLocation
- * @param parentBorder
- * @return draw constant
- */
- public int findClosestAuthorizedSideOfParent(Rectangle proposedLocation, Rectangle parentBorder) {
- int side = findClosestSideOfParent(proposedLocation, parentBorder);
- side = redefineSuggestedSide(proposedLocation.getCenter(), side);
- return side;
- }
-
- /**
- * Know whether containing action is a SendSignalAction
- *
- * @return true is containing action is a SendSignalAction
- */
- private boolean isInSendSignalAction() {
- IFigure parentFigure = getParentFigure();
- for (Object child : parentFigure.getChildren()) {
- if (child instanceof PapyrusSendNodeFigure) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Know whether containing action is an AcceptEventAction
- *
- * @return true is containing action is an AcceptEventAction
- */
- private boolean isInAcceptEventAction() {
- IFigure parentFigure = getParentFigure();
- for (Object child : parentFigure.getChildren()) {
- if (child instanceof AcceptEventActionFigure) {
- ((AcceptEventActionFigure) child).isTemplateForAcceptTimeEventActionUsed();
- return true;
- }
- }
- return false;
- }
-
- /**
- * Know whether containing action is an AcceptTimeEventAction
- *
- * @return true is containing action is an AcceptEventAction with
- * AcceptTimeEventAction representation
- */
- private boolean isInAcceptTimeEventAction() {
- IFigure parentFigure = getParentFigure();
- for (Object child : parentFigure.getChildren()) {
- if (child instanceof AcceptEventActionFigure) {
- return ((AcceptEventActionFigure) child).isTemplateForAcceptTimeEventActionUsed();
- }
- }
- return false;
- }
-
- /**
- * Re-arrange the location of the border item, and also the contained arrow.
- *
- * @see org.eclipse.gmf.runtime.diagram.ui.figures.BorderItemLocator#relocate(org.eclipse.draw2d.IFigure)
- *
- * @param borderItem
- */
- @Override
- public void relocate(IFigure borderItem) {
- // reset bounds of borderItem
- Dimension size = getSize(borderItem);
- Rectangle rectSuggested = getConstraint().getCopy();
- if (rectSuggested.getTopLeft().x == 0 && rectSuggested.getTopLeft().y == 0) {
- rectSuggested.setLocation(getPreferredLocation(borderItem));
- } else {
- // recovered constraint must be translated with the parent location
- // to be absolute
- rectSuggested.setLocation(rectSuggested.getLocation().translate(getParentBorder().getTopLeft()));
- }
- rectSuggested.setSize(size);
- Rectangle validLocation = getValidLocation(rectSuggested, borderItem);
- // the constraint is not reset, but the item bounds are
- borderItem.setBounds(validLocation);
- // ensure the side property is correctly set
- setCurrentSideOfParent(findClosestAuthorizedSideOfParent(borderItem.getBounds(), getParentBorder()));
- // refresh the arrow depending on the Pin type and the side on which it
- // is located
- for (Object subfigure : borderItem.getChildren()) {
- if (subfigure instanceof IFigure) {
- for (Object child : ((IFigure) subfigure).getChildren()) {
- refreshPinDescriptorArrow(child, MapModeUtil.getMapMode(borderItem), size);
- }
- }
- }
- }
-
- /**
- * Refresh the arrow in case child is a Pin Descriptor
- *
- * @param child
- * the Pin Descriptor (no effect otherwise)
- * @param mapMode
- * the IMapMode
- * @param size
- * the size of the border item
- */
- private void refreshPinDescriptorArrow(Object child, IMapMode mapMode, Dimension size) {
- boolean arrowIn = false;
- AbstractPointListShape arrow = null;
- if (child instanceof PinFigure) {
- arrowIn = true;
- arrow = ((PinFigure) child).getOptionalArrowFigure();
- }
-
- if (child instanceof OutputPinFigure) {
- arrowIn = false;
- arrow = ((PinFigure) child).getOptionalArrowFigure();
- }
-
- if (arrow != null && arrow.getPoints().size() > 0) {
- int arrowDirection;
- int side = getCurrentSideOfParent();
- switch (side) {
- case PositionConstants.NORTH:
- if (arrowIn) {
- arrowDirection = PositionConstants.SOUTH;
- } else {
- arrowDirection = PositionConstants.NORTH;
- }
- break;
- case PositionConstants.EAST:
- if (arrowIn) {
- arrowDirection = PositionConstants.WEST;
- } else {
- arrowDirection = PositionConstants.EAST;
- }
- break;
- case PositionConstants.SOUTH:
- if (arrowIn) {
- arrowDirection = PositionConstants.NORTH;
- } else {
- arrowDirection = PositionConstants.SOUTH;
- }
- break;
- case PositionConstants.WEST:
- default:
- if (arrowIn) {
- arrowDirection = PositionConstants.EAST;
- } else {
- arrowDirection = PositionConstants.WEST;
- }
- }
- ActivityFigureDrawer.redrawPinArrow(arrow, mapMode, size, arrowDirection);
- }
- }
-
- /**
- * Get an initial location based on the side. ( appropriate extremity of the
- * side )
- *
- * @param side
- * the preferred side of the parent figure on which to place this
- * border item as defined in {@link PositionConstants}
- * @return point
- */
- @Override
- protected Point getPreferredLocation(int side, IFigure borderItem) {
- Rectangle bounds = getParentBorder();
- int parentFigureWidth = bounds.width;
- int parentFigureHeight = bounds.height;
- int parentFigureX = bounds.x;
- int parentFigureY = bounds.y;
- int x = parentFigureX;
- int y = parentFigureY;
- Dimension borderItemSize = getSize(borderItem);
- switch (side) {
- case PositionConstants.NORTH:
- x += EXTRA_BORDER_DEFAULT_OFFSET + getBorderItemOffset().width;
- y += -borderItemSize.height + getBorderItemOffset().height;
- break;
- case PositionConstants.EAST:
- // take south east extremity to allow following pins placing above
- x += parentFigureWidth - getBorderItemOffset().width;
- y += parentFigureHeight - borderItemSize.height - EXTRA_BORDER_DEFAULT_OFFSET - getBorderItemOffset().height;
- break;
- case PositionConstants.SOUTH:
- x += EXTRA_BORDER_DEFAULT_OFFSET + getBorderItemOffset().width;
- y += parentFigureHeight - getBorderItemOffset().height;
- break;
- case PositionConstants.WEST:
- default:
- x += -borderItemSize.width + getBorderItemOffset().width;
- y += EXTRA_BORDER_DEFAULT_OFFSET + getBorderItemOffset().height;
- }
- return new Point(x, y);
- }
-
- /**
- * Adapt the bounds constraint to fit to the action's contained pins
- *
- * @param boundsConstraint
- * the constraint to adapt
- * @param domainElement
- * the model action
- * @return
- * @return boundsConstraint for convenience
- *
- */
- public static Bounds adaptActionHeight(Bounds boundsConstraint, EObject domainElement) {
- if (domainElement instanceof Action) {
- int pinsOnHeight = 0;
- int numberOfInputs = ((Action) domainElement).getInputs().size();
- int numberOfOutputs = ((Action) domainElement).getOutputs().size();
- if (domainElement instanceof CallOperationAction) {
- // target is located on top
- pinsOnHeight = Math.max(numberOfInputs - 1, numberOfOutputs);
- } else {
- pinsOnHeight = Math.max(numberOfInputs, numberOfOutputs);
- }
- if (pinsOnHeight > 0) {
- // each pin is 16 px height, consider extra px for margins
- int heightInPx = 2 * EXTRA_BORDER_DEFAULT_OFFSET + pinsOnHeight * (DEFAULT_PIN_SIZE + 8) - 8;
- boundsConstraint.setHeight(heightInPx);
- }
- }
- return boundsConstraint;
- }
-}
+/*****************************************************************************
+ * Copyright (c) 2009 Atos Origin.
+ *
+ *
+ * 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:
+ * Atos Origin - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.diagram.activity.locator;
+
+import org.eclipse.draw2d.AbstractPointListShape;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
+import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
+import org.eclipse.gmf.runtime.notation.Bounds;
+import org.eclipse.papyrus.uml.diagram.activity.figures.AcceptEventActionFigure;
+import org.eclipse.papyrus.uml.diagram.activity.figures.OutputPinFigure;
+import org.eclipse.papyrus.uml.diagram.activity.figures.PinFigure;
+import org.eclipse.papyrus.uml.diagram.activity.helper.ActivityFigureDrawer;
+import org.eclipse.papyrus.uml.diagram.common.figure.node.PapyrusSendNodeFigure;
+import org.eclipse.papyrus.uml.diagram.common.locator.AdvancedBorderItemLocator;
+import org.eclipse.uml2.uml.Action;
+import org.eclipse.uml2.uml.CallOperationAction;
+
+/**
+ * This class is used to constrain the position of Pin
+ *
+ * TODO : The pin is not re-sizable
+ */
+public class PinPositionLocator extends AdvancedBorderItemLocator {
+
+ /**
+ * The offset to add to default position. (to avoid corner of rounded
+ * rectangles)
+ */
+ public static final int EXTRA_BORDER_DEFAULT_OFFSET = 8;
+
+ /** The default size of a pin */
+ public static final int DEFAULT_PIN_SIZE = 16;
+
+ /**
+ * the maximum authorized x position on the template of a Send Signal Action
+ * figure
+ */
+ private static final int SEND_SIGNAL_ACTION_MAX_X = 150;
+
+ /** the width of the template of a Send Signal Action figure */
+ private static final int SEND_SIGNAL_ACTION_WIDTH = 200;
+
+ /** Constructor **/
+ public PinPositionLocator(IFigure parentFigure) {
+ super(parentFigure);
+ }
+
+ /** Constructor **/
+ public PinPositionLocator(IFigure borderItem, IFigure parentFigure, Rectangle constraint) {
+ super(borderItem, parentFigure, constraint);
+ }
+
+ /** Constructor **/
+ public PinPositionLocator(IFigure parentFigure, int preferredSide) {
+ super(parentFigure, preferredSide);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Rectangle getValidLocation(Rectangle proposedLocation, IFigure borderItem) {
+ Rectangle realLocation = new Rectangle(proposedLocation);
+ realLocation.width = Math.max(realLocation.width, realLocation.height);
+ realLocation.height = realLocation.width;
+ int side = findClosestAuthorizedSideOfParent(proposedLocation, getParentBorder());
+ Point newTopLeft = locateOnBorder(realLocation.getTopLeft(), side, 0, borderItem);
+ realLocation.setLocation(newTopLeft);
+ return realLocation;
+ }
+
+ /**
+ * The preferred side takes precedence.
+ *
+ * @param suggestedLocation
+ * @param suggestedSide
+ * @param circuitCount
+ * recursion count to avoid an infinite loop
+ * @return point
+ */
+ @Override
+ protected Point locateOnBorder(Point suggestedLocation, int suggestedSide, int circuitCount, IFigure borderItem) {
+ Point suggestedCenter = borderItem.getBounds().getCopy().setLocation(suggestedLocation).getCenter();
+ suggestedSide = redefineSuggestedSide(suggestedCenter, suggestedSide);
+ if (isInSendSignalAction()) {
+ // prevent a pin too far EAST that would be on the convex sides of
+ // the pentagon
+ if (suggestedSide == PositionConstants.SOUTH || suggestedSide == PositionConstants.NORTH) {
+ int maxLocation = getParentBorder().x + getParentBorder().width * SEND_SIGNAL_ACTION_MAX_X / SEND_SIGNAL_ACTION_WIDTH - getSize(borderItem).width;
+ if (suggestedLocation.x > maxLocation) {
+ suggestedLocation.x = maxLocation;
+ }
+ }
+ }
+ Point recommendedLocation = super.locateOnBorder(suggestedLocation, suggestedSide, circuitCount, borderItem);
+ return recommendedLocation;
+ }
+
+ /**
+ * Ensure the suggested location actually lies on the parent boundary. The
+ * side takes precedence.
+ *
+ * @param suggestedLocation
+ * suggested location
+ * @param suggestedSide
+ * suggested side
+ * @param borderItem
+ * the item figure
+ * @return point
+ */
+ @Override
+ protected Point locateOnParent(Point suggestedLocation, int suggestedSide, IFigure borderItem) {
+ Rectangle bounds = getParentBorder();
+ int parentFigureWidth = bounds.width;
+ int parentFigureHeight = bounds.height;
+ int parentFigureX = bounds.x;
+ int parentFigureY = bounds.y;
+ Dimension borderItemSize = getSize(borderItem);
+ int newX = suggestedLocation.x;
+ int newY = suggestedLocation.y;
+ int westX = parentFigureX - borderItemSize.width + getBorderItemOffset().width;
+ int eastX = parentFigureX + parentFigureWidth - getBorderItemOffset().width;
+ int maxX = 0;
+ if (isInSendSignalAction()) {
+ // prevent a pin too far EAST that would be on the convex sides of
+ // the pentagon
+ if (suggestedSide == PositionConstants.SOUTH || suggestedSide == PositionConstants.NORTH) {
+ maxX = parentFigureX + parentFigureWidth * SEND_SIGNAL_ACTION_MAX_X / SEND_SIGNAL_ACTION_WIDTH - getBorderItemOffset().width;
+ }
+ }
+ int southY = parentFigureY + parentFigureHeight - getBorderItemOffset().height;
+ int northY = parentFigureY - borderItemSize.height + getBorderItemOffset().height;
+ if (suggestedSide == PositionConstants.WEST) {
+ if (suggestedLocation.x != westX) {
+ newX = westX;
+ }
+ if (suggestedLocation.y < bounds.getTopLeft().y) {
+ newY = northY + borderItemSize.height;
+ } else if (suggestedLocation.y > bounds.getBottomLeft().y - borderItemSize.height) {
+ newY = southY - borderItemSize.height;
+ }
+ } else if (suggestedSide == PositionConstants.EAST) {
+ if (suggestedLocation.x != eastX) {
+ newX = eastX;
+ }
+ if (suggestedLocation.y < bounds.getTopLeft().y) {
+ newY = northY + borderItemSize.height;
+ } else if (suggestedLocation.y > bounds.getBottomLeft().y - borderItemSize.height) {
+ newY = southY - borderItemSize.height;
+ }
+ } else if (suggestedSide == PositionConstants.SOUTH) {
+ if (suggestedLocation.y != southY) {
+ newY = southY;
+ }
+ if (suggestedLocation.x < bounds.getBottomLeft().x) {
+ newX = westX + borderItemSize.width;
+ } else if (suggestedLocation.x > bounds.getBottomRight().x - borderItemSize.width) {
+ newX = eastX - borderItemSize.width;
+ }
+ } else { // NORTH
+ if (suggestedLocation.y != northY) {
+ newY = northY;
+ }
+ if (suggestedLocation.x < bounds.getBottomLeft().x) {
+ newX = westX + borderItemSize.width;
+ } else if (suggestedLocation.x > bounds.getBottomRight().x - borderItemSize.width) {
+ newX = eastX - borderItemSize.width;
+ }
+ }
+ if (maxX > 0 && newX > maxX) {
+ newX = maxX;
+ }
+ return new Point(newX, newY);
+ }
+
+ /**
+ * Recomputes the suggested side by eliminating unauthorized sides depending
+ * on the action type
+ *
+ * @param childCenter
+ * suggested location center
+ * @param suggestedSide
+ * suggested side
+ * @return correct side
+ */
+ private int redefineSuggestedSide(Point childCenter, int suggestedSide) {
+ if (isInSendSignalAction()) {
+ // EAST side is not authorized
+ if (suggestedSide == PositionConstants.EAST) {
+ Point parentCenter = getParentBorder().getCenter();
+ if (childCenter.y < parentCenter.y) {
+ suggestedSide = PositionConstants.NORTH;
+ } else {
+ suggestedSide = PositionConstants.SOUTH;
+ }
+ }
+ } else if (isInAcceptEventAction()) {
+ // WEST side is not authorized
+ if (suggestedSide == PositionConstants.WEST) {
+ Point parentCenter = getParentBorder().getCenter();
+ if (childCenter.y < parentCenter.y) {
+ suggestedSide = PositionConstants.NORTH;
+ } else {
+ suggestedSide = PositionConstants.SOUTH;
+ }
+ }
+ // EAST side is not authorized for AcceptTimeEventAction
+ if (suggestedSide == PositionConstants.EAST && isInAcceptTimeEventAction()) {
+ Point parentCenter = getParentBorder().getCenter();
+ if (childCenter.y < parentCenter.y) {
+ suggestedSide = PositionConstants.NORTH;
+ } else {
+ suggestedSide = PositionConstants.SOUTH;
+ }
+ }
+ }
+ return suggestedSide;
+ }
+
+ /**
+ * Find the closest side when x,y is inside parent.
+ *
+ * @param proposedLocation
+ * @param parentBorder
+ * @return draw constant
+ */
+ public int findClosestAuthorizedSideOfParent(Rectangle proposedLocation, Rectangle parentBorder) {
+ int side = findClosestSideOfParent(proposedLocation, parentBorder);
+ side = redefineSuggestedSide(proposedLocation.getCenter(), side);
+ return side;
+ }
+
+ /**
+ * Know whether containing action is a SendSignalAction
+ *
+ * @return true is containing action is a SendSignalAction
+ */
+ private boolean isInSendSignalAction() {
+ IFigure parentFigure = getParentFigure();
+ for (Object child : parentFigure.getChildren()) {
+ if (child instanceof PapyrusSendNodeFigure) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Know whether containing action is an AcceptEventAction
+ *
+ * @return true is containing action is an AcceptEventAction
+ */
+ private boolean isInAcceptEventAction() {
+ IFigure parentFigure = getParentFigure();
+ for (Object child : parentFigure.getChildren()) {
+ if (child instanceof AcceptEventActionFigure) {
+ ((AcceptEventActionFigure) child).isTemplateForAcceptTimeEventActionUsed();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Know whether containing action is an AcceptTimeEventAction
+ *
+ * @return true is containing action is an AcceptEventAction with
+ * AcceptTimeEventAction representation
+ */
+ private boolean isInAcceptTimeEventAction() {
+ IFigure parentFigure = getParentFigure();
+ for (Object child : parentFigure.getChildren()) {
+ if (child instanceof AcceptEventActionFigure) {
+ return ((AcceptEventActionFigure) child).isTemplateForAcceptTimeEventActionUsed();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Re-arrange the location of the border item, and also the contained arrow.
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.figures.BorderItemLocator#relocate(org.eclipse.draw2d.IFigure)
+ *
+ * @param borderItem
+ */
+ @Override
+ public void relocate(IFigure borderItem) {
+ // reset bounds of borderItem
+ Dimension size = getSize(borderItem);
+ Rectangle rectSuggested = getConstraint().getCopy();
+ if (rectSuggested.getTopLeft().x == 0 && rectSuggested.getTopLeft().y == 0) {
+ rectSuggested.setLocation(getPreferredLocation(borderItem));
+ } else {
+ // recovered constraint must be translated with the parent location
+ // to be absolute
+ rectSuggested.setLocation(rectSuggested.getLocation().translate(getParentBorder().getTopLeft()));
+ }
+ rectSuggested.setSize(size);
+ Rectangle validLocation = getValidLocation(rectSuggested, borderItem);
+ // the constraint is not reset, but the item bounds are
+ borderItem.setBounds(validLocation);
+ // ensure the side property is correctly set
+ setCurrentSideOfParent(findClosestAuthorizedSideOfParent(borderItem.getBounds(), getParentBorder()));
+ // refresh the arrow depending on the Pin type and the side on which it
+ // is located
+ for (Object subfigure : borderItem.getChildren()) {
+ if (subfigure instanceof IFigure) {
+ for (Object child : ((IFigure) subfigure).getChildren()) {
+ refreshPinDescriptorArrow(child, MapModeUtil.getMapMode(borderItem), size);
+ }
+ }
+ }
+ }
+
+ /**
+ * Refresh the arrow in case child is a Pin Descriptor
+ *
+ * @param child
+ * the Pin Descriptor (no effect otherwise)
+ * @param mapMode
+ * the IMapMode
+ * @param size
+ * the size of the border item
+ */
+ private void refreshPinDescriptorArrow(Object child, IMapMode mapMode, Dimension size) {
+ boolean arrowIn = false;
+ AbstractPointListShape arrow = null;
+ if (child instanceof PinFigure) {
+ arrowIn = true;
+ arrow = ((PinFigure) child).getOptionalArrowFigure();
+ }
+
+ if (child instanceof OutputPinFigure) {
+ arrowIn = false;
+ arrow = ((PinFigure) child).getOptionalArrowFigure();
+ }
+
+ if (arrow != null && arrow.getPoints().size() > 0) {
+ int arrowDirection;
+ int side = getCurrentSideOfParent();
+ switch (side) {
+ case PositionConstants.NORTH:
+ if (arrowIn) {
+ arrowDirection = PositionConstants.SOUTH;
+ } else {
+ arrowDirection = PositionConstants.NORTH;
+ }
+ break;
+ case PositionConstants.EAST:
+ if (arrowIn) {
+ arrowDirection = PositionConstants.WEST;
+ } else {
+ arrowDirection = PositionConstants.EAST;
+ }
+ break;
+ case PositionConstants.SOUTH:
+ if (arrowIn) {
+ arrowDirection = PositionConstants.NORTH;
+ } else {
+ arrowDirection = PositionConstants.SOUTH;
+ }
+ break;
+ case PositionConstants.WEST:
+ default:
+ if (arrowIn) {
+ arrowDirection = PositionConstants.EAST;
+ } else {
+ arrowDirection = PositionConstants.WEST;
+ }
+ }
+ ActivityFigureDrawer.redrawPinArrow(arrow, mapMode, size, arrowDirection);
+ }
+ }
+
+ /**
+ * Get an initial location based on the side. ( appropriate extremity of the
+ * side )
+ *
+ * @param side
+ * the preferred side of the parent figure on which to place this
+ * border item as defined in {@link PositionConstants}
+ * @return point
+ */
+ @Override
+ protected Point getPreferredLocation(int side, IFigure borderItem) {
+ Rectangle bounds = getParentBorder();
+ int parentFigureWidth = bounds.width;
+ int parentFigureHeight = bounds.height;
+ int parentFigureX = bounds.x;
+ int parentFigureY = bounds.y;
+ int x = parentFigureX;
+ int y = parentFigureY;
+ Dimension borderItemSize = getSize(borderItem);
+ switch (side) {
+ case PositionConstants.NORTH:
+ x += EXTRA_BORDER_DEFAULT_OFFSET + getBorderItemOffset().width;
+ y += -borderItemSize.height + getBorderItemOffset().height;
+ break;
+ case PositionConstants.EAST:
+ // take south east extremity to allow following pins placing above
+ x += parentFigureWidth - getBorderItemOffset().width;
+ y += parentFigureHeight - borderItemSize.height - EXTRA_BORDER_DEFAULT_OFFSET - getBorderItemOffset().height;
+ break;
+ case PositionConstants.SOUTH:
+ x += EXTRA_BORDER_DEFAULT_OFFSET + getBorderItemOffset().width;
+ y += parentFigureHeight - getBorderItemOffset().height;
+ break;
+ case PositionConstants.WEST:
+ default:
+ x += -borderItemSize.width + getBorderItemOffset().width;
+ y += EXTRA_BORDER_DEFAULT_OFFSET + getBorderItemOffset().height;
+ }
+ return new Point(x, y);
+ }
+
+ /**
+ * Adapt the bounds constraint to fit to the action's contained pins
+ *
+ * @param boundsConstraint
+ * the constraint to adapt
+ * @param domainElement
+ * the model action
+ * @return
+ * @return boundsConstraint for convenience
+ *
+ */
+ public static Bounds adaptActionHeight(Bounds boundsConstraint, EObject domainElement) {
+ if (domainElement instanceof Action) {
+ int pinsOnHeight = 0;
+ int numberOfInputs = ((Action) domainElement).getInputs().size();
+ int numberOfOutputs = ((Action) domainElement).getOutputs().size();
+ if (domainElement instanceof CallOperationAction) {
+ // target is located on top
+ pinsOnHeight = Math.max(numberOfInputs - 1, numberOfOutputs);
+ } else {
+ pinsOnHeight = Math.max(numberOfInputs, numberOfOutputs);
+ }
+ if (pinsOnHeight > 0) {
+ // each pin is 16 px height, consider extra px for margins
+ int heightInPx = 2 * EXTRA_BORDER_DEFAULT_OFFSET + pinsOnHeight * (DEFAULT_PIN_SIZE + 8) - 8;
+ boundsConstraint.setHeight(heightInPx);
+ }
+ }
+ return boundsConstraint;
+ }
+}

Back to the top