Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCéline Janssens2014-08-27 15:15:56 +0000
committerCéline Janssens2014-08-28 08:46:57 +0000
commit15322652cc079d206f5a886bafe9dc01c233ad27 (patch)
treead98d8517aff72a48b01e16772a2d49ed727f7c8
parent8cb2ca4a4ae589a3bd1988070416a1bd0e3d024a (diff)
downloadorg.eclipse.papyrus-15322652cc079d206f5a886bafe9dc01c233ad27.tar.gz
org.eclipse.papyrus-15322652cc079d206f5a886bafe9dc01c233ad27.tar.xz
org.eclipse.papyrus-15322652cc079d206f5a886bafe9dc01c233ad27.zip
442582: [All Diagrams] CustomAlignAction Refactor
https://bugs.eclipse.org/bugs/show_bug.cgi?id=442582 New rules For the Alignment Change-Id: I408d686ca381c2fb54078350f63967460ea5d0c0 Signed-off-by: Céline Janssens <Celine.Janssens@all4tec.net>
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/LabelAlignmentEditPolicy.java34
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/DiagramEditPartsUtil.java27
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/layout/AlignmentTree.java216
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/AlignActionHelper.java445
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/CustomAlignAction.java483
5 files changed, 342 insertions, 863 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/LabelAlignmentEditPolicy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/LabelAlignmentEditPolicy.java
index be862e446d4..481aa72e222 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/LabelAlignmentEditPolicy.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/LabelAlignmentEditPolicy.java
@@ -13,6 +13,9 @@ package org.eclipse.papyrus.infra.gmfdiag.common.editpolicies;
* Céline Janssens (ALL4TEC) celine.janssens@all4tec.net - Initial API and implementation
*
*****************************************************************************/
+import java.util.Iterator;
+import java.util.List;
+
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
@@ -140,7 +143,14 @@ public class LabelAlignmentEditPolicy extends AbstractEditPolicy{
int sourceSelectionType = ((ConnectionEditPart)label.getParent()).getSource().getSelected();
int targetSelectionType = ((ConnectionEditPart)label.getParent()).getTarget().getSelected();
- isAllow = !((sourceSelectionType == EditPart.SELECTED)||(targetSelectionType == EditPart.SELECTED)) ;
+
+ boolean isRefDependent = isRefSibling(parent);
+
+ if (!isRefDependent) {
+ boolean isExtremitiesSelected = (sourceSelectionType == EditPart.SELECTED)||(targetSelectionType == EditPart.SELECTED);
+ isAllow = !isExtremitiesSelected;
+ }
+
} else if (parent instanceof AbstractBorderItemEditPart) {
// if the label is an affixed label and if the affixed node is part of the selection, the label is not aligned
@@ -150,6 +160,28 @@ public class LabelAlignmentEditPolicy extends AbstractEditPolicy{
return isAllow;
}
+ /**
+ * Define if the Label is sibling of the Reference object.
+ * @param parent Label's Parent
+ * @return true if the reference is a sibling of the Label
+ */
+ private boolean isRefSibling(EditPart parent) {
+
+ boolean isRefSibling = false;
+ if (parent instanceof AbstractConnectionEditPart){
+
+ List<?> children = parent.getChildren();
+ Iterator<?> iter = children.iterator();
+
+ while(iter.hasNext() && !isRefSibling ){
+ Object child = iter.next();
+ if (((EditPart)child).getSelected() == EditPart.SELECTED_PRIMARY){
+ isRefSibling = true;
+ }
+ }
+ }
+ return isRefSibling;
+ }
/**
*
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/DiagramEditPartsUtil.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/DiagramEditPartsUtil.java
index acb9cc8ecc0..7320fe5b90c 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/DiagramEditPartsUtil.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/DiagramEditPartsUtil.java
@@ -20,8 +20,11 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.RootEditPart;
+import org.eclipse.gef.editparts.AbstractConnectionEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
@@ -224,4 +227,28 @@ public class DiagramEditPartsUtil {
}
return -1.0;
}
+
+ /**
+ * This Method return the Graphical container of an EditPart.
+ * Depending on the type of EditPart, the container can be the Direct Parent or the grand parent.
+ * @param currentEP
+ * @return
+ */
+ public static final EditPart getContainerEditPart(GraphicalEditPart currentEP) {
+
+ EditPart container;
+ EditPart parent = currentEP.getParent();
+ if (parent instanceof AbstractConnectionEditPart){
+ container = parent.getParent();
+ }else if (parent instanceof AbstractBorderItemEditPart){
+ container = parent.getParent().getParent();
+ }else if (currentEP instanceof AbstractBorderItemEditPart){
+ container = parent.getParent();
+ }else {
+ container = parent;
+ }
+
+ return container;
+ }
+
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/layout/AlignmentTree.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/layout/AlignmentTree.java
deleted file mode 100644
index b929a8ec9a3..00000000000
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/layout/AlignmentTree.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*****************************************************************************
- * Copyright (c) 2010- 2014 CEA LIST.
- *
- *
- * 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:
- * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- * Céline Janssens (All4TEC) celine.Janssens@all4tec.net - Bug 440224: Label Alignment
- *
- *****************************************************************************/
-package org.eclipse.papyrus.uml.diagram.common.layout;
-
-import java.util.List;
-
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.draw2d.geometry.PrecisionRectangle;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.editparts.AbstractConnectionEditPart;
-import org.eclipse.gef.tools.ToolUtilities;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.LabelEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderItemEditPart;
-
-/**
- *
- * A special tree for the alignment action
- *
- */
-public class AlignmentTree extends EditPartTree {
-
- /**
- * this UDI can be used to serialize this class
- */
- private static final long serialVersionUID = 3095221342551975246L;
-
- /**
- *
- * Constructor.
- *
- * @param editpart
- * the editpart represented by this tree
- * @param isSelected
- * Indicates if the represented editpart is selected or not
- *
- */
- public AlignmentTree(Object editpart, boolean isSelected) {
- super(editpart, isSelected);
- }
-
- /**
- *
- * Constructor.
- *
- * @param editparts
- * the editparts used to build the tree
- */
- public AlignmentTree(List<EditPart> editparts) {
- super(editparts);
- }
-
- /**
- * The new position for this element
- */
- private PrecisionRectangle newPosition = null;
-
- /**
- * Gets the new alignment position for the editpart.
- *
- * @return the new alignment position for the editpart
- */
- public PrecisionRectangle getNewPosition() {
- return newPosition;
- }
-
- /**
- * Returns the new bounds of the container
- *
- * @return <ul>
- * <li>{@link EditPartTree#diagramRect} if the container is the diagram</li>
- * <li>the bounds of the container after the shift</li>
- * </ul>
- */
- public PrecisionRectangle getNewContainerBounds() {
- AlignmentTree treeParent = (AlignmentTree) this.getParent();
- PrecisionRectangle newContainerBounds;
-
- if (treeParent.getEditPart() != null) {
- Point oldParentLocation = LayoutUtils.getAbsolutePosition(treeParent.getEditPart()).getLocation();
- Point newParentLocation = treeParent.getNewPosition().getLocation();
-
- // shift between the two positions
- Point shift = newParentLocation.getTranslated(oldParentLocation.getNegated());
- PrecisionRectangle oldContainerBounds;
- // we want know the final position for the container
- if (getEditPart().getParent() instanceof AbstractBorderItemEditPart) {
- // in case of Port Label the container is the grand grand parent
- oldContainerBounds = LayoutUtils.getAbsolutePosition(getEditPart().getParent().getParent().getParent());
- }else if (getEditPart().getParent() instanceof AbstractConnectionEditPart){
- // in case of edge label the container is the grand parent
- oldContainerBounds = LayoutUtils.getAbsolutePosition(getEditPart().getParent().getParent());
- }else{
- // in all the case the container is the direct parent
- oldContainerBounds = LayoutUtils.getAbsolutePosition(getEditPart().getParent());
- }
- newContainerBounds = new PrecisionRectangle(oldContainerBounds);
- newContainerBounds.translate(shift);
- } else {// treeParent is the root of the tree
-
- EditPart containerEditPart;
- // in case of a label, the container is the grand-parent
- if (getEditPart().getParent() instanceof AbstractConnectionEditPart ) {
- containerEditPart = getEditPart().getParent().getParent();
- } else if (getEditPart().getParent() instanceof AbstractBorderItemEditPart) {
- containerEditPart = getEditPart().getParent().getParent().getParent();
- } else {
- containerEditPart = getEditPart().getParent();
- }
-
- newContainerBounds = LayoutUtils.getAbsolutePosition(containerEditPart);
- }
- return newContainerBounds;
- }
-
- /**
- * Returns the absolute position for the editpart in the new container
- *
- * @return the absolute position for the editpart in the new container.
- * That's to say the intermediate position, when the container has
- * moved, and the editpart hasn't moved
- */
- public PrecisionRectangle getAbsolutePositionInTheNewContainerPosition() {
- EditPart editPart = getEditPart();
- EditPart parent = editPart.getParent();
- PrecisionRectangle oldContainerPosition;
- PrecisionRectangle newPosition = new PrecisionRectangle(LayoutUtils.getAbsolutePosition(editPart));
- PrecisionRectangle newContainerPosition = getNewContainerBounds();
-
- if (parent instanceof AbstractConnectionEditPart){
- oldContainerPosition = LayoutUtils.getAbsolutePosition(parent.getParent());
- }else if (parent instanceof AbstractBorderItemEditPart){
- oldContainerPosition = LayoutUtils.getAbsolutePosition(parent.getParent().getParent());
- }else {
- oldContainerPosition = LayoutUtils.getAbsolutePosition(parent);
- }
-
- PrecisionRectangle absoluteNewContainer = (PrecisionRectangle)newContainerPosition.translate(oldContainerPosition.getLocation().getNegated());
- return (PrecisionRectangle)newPosition.translate(absoluteNewContainer.getLocation());
- }
-
- /**
- * Sets the alignment position for the editpart
- *
- * @param newPosition
- * the new alignment position for the editpart
- */
- public void setNewPosition(PrecisionRectangle newPosition) {
- this.newPosition = newPosition;
- }
-
- /**
- *
- * @see org.eclipse.papyrus.uml.diagram.common.layout.EditPartTree#createChildrenTree(java.util.List, java.util.List)
- *
- * @param editparts
- * the selected editpart
- * @param parentsList
- * parents of editparts which could be interesting to add to the
- * tree
- * @return
- */
- @Override
- protected EditPartTree createChildrenTree(List<EditPart> editparts, List<EditPart> parentsList) {
- EditPartTree childTree = null;
- for (EditPart editpart : parentsList) {
-
- /*
- * the editparts are interesting only if they are selected or if its
- * parent is selected!
- */
- if (editparts.contains(editpart) || ((!editparts.contains(editpart)) && ToolUtilities.isAncestorContainedIn(editparts, editpart))) {
- boolean isSelected = editparts.contains(editpart);
- AlignmentTree parentTree = new AlignmentTree(editpart, isSelected);
- if (!isSelected) {
- // this editpart won't move, so we can precise now its
- // position
- parentTree.setNewPosition(LayoutUtils.getAbsolutePosition(editpart));
- }
- if (childTree != null) {
- parentTree.add(childTree);
- }
- childTree = parentTree;
- }
- }
- return childTree;
- }
-
- /**
- * Specifies in the tree which editpart in the selected editpart is used
- * like reference to do the alignment action
- *
- * @see org.eclipse.papyrus.uml.diagram.common.layout.EditPartTree#postBuildOperations(java.util.List)
- *
- * @param editparts
- * the editparts list
- */
- @Override
- protected void postBuildOperations(List<EditPart> editparts) {
- // the reference for the alignment is the last selected element
- ((AlignmentTree) this.getTree(editparts.get(editparts.size() - 1))).setNewPosition(LayoutUtils.getAbsolutePosition(editparts.get(editparts.size() - 1)));
-
- }
-
-}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/AlignActionHelper.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/AlignActionHelper.java
index 64ffe82cb5c..fbc6affc407 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/AlignActionHelper.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/AlignActionHelper.java
@@ -13,21 +13,21 @@ package org.eclipse.papyrus.uml.diagram.menu.actions;
* Céline Janssens (ALL4TEC) celine.janssens@all4tec.net - Code refractor and documentation
*
*****************************************************************************/
-import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
+import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
-import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
-import org.eclipse.gef.tools.ToolUtilities;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderItemEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.LabelEditPart;
-import org.eclipse.papyrus.uml.diagram.common.layout.EditPartTree;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
import org.eclipse.papyrus.uml.diagram.common.layout.LayoutUtils;
@@ -41,8 +41,14 @@ import org.eclipse.papyrus.uml.diagram.common.layout.LayoutUtils;
*/
public class AlignActionHelper {
- //private CustomAlignAction action;
- private CustomAlignAction action;
+
+ /** The alignment. */
+ private int alignment;
+
+ private EditPart refEditPart;
+
+ private List<IGraphicalEditPart> selectedElements;
+
/**
* Default Constructor
@@ -51,85 +57,22 @@ public class AlignActionHelper {
// Default constructor
}
- /**
- * Constructor
- * @param customAlignAction
- */
- public AlignActionHelper(CustomAlignAction customAlignAction){
- this.action = customAlignAction;
-
- }
-
-
- /**
- * Create the new bounds of the unselected child of an EditPartTree compare to the RefEP.
- *
- * @param ept EditPartTree where there is an Unselected Child
- * @param refEP Reference EditPart
- * @return Bounds Rectangle of the unselected Child
- */
- protected PrecisionRectangle getUnselectedChildNewBounds(EditPartTree ept, EditPart refEP) {
- PrecisionRectangle boundsLimit = null;
- List<EditPart> parent = new ArrayList<EditPart>(1);
- parent.add(ept.getEditPart());
- int distance = ept.getDistanceWithTheFirstUnselectedChild();
- EditPartTree unselectedTree = ept.getFirstUnselectedChild();
-
- //we don't need to correct unselected element location when the reference is not inside them
- if(ToolUtilities.isAncestorContainedIn(parent, refEP)) {
- boundsLimit = new PrecisionRectangle(LayoutUtils.getAbsolutePosition(unselectedTree.getEditPart()));
- //we increase the size of the child, to avoid scrollbar in its parent
- boundsLimit.setPreciseX(boundsLimit.x - (distance * LayoutUtils.scrollBarSize));
- boundsLimit.setPreciseY(boundsLimit.y - (distance * LayoutUtils.scrollBarSize));
- boundsLimit.setPreciseWidth(boundsLimit.width + (2 * distance * LayoutUtils.scrollBarSize));
- boundsLimit.setPreciseHeight(boundsLimit.height + (2 * distance * LayoutUtils.scrollBarSize));
- if(action.getAlignment() == PositionConstants.TOP) {
- double dist = getLabelHeightToRemove(ept);
- boundsLimit.setPreciseY(boundsLimit.y() - dist);
- }
- }
- return boundsLimit;
- }
-
-
- /**
- * Returns the height of the label for the current editpart contained in {@code ept}, more the height of the children's label
- *
- * @param ept
- * The {@link EditPartTree} containing the {@link EditPart} used to calculate height
- * @return
- * The height of the label for the current editpart, more the height of the children's label
- *
- */
- protected double getLabelHeightToRemove(EditPartTree ept) {
- double dist = 0;
- List<?> children = ept.getEditPart().getChildren();
- //we search the correct compartment
- for(int iter = 0; iter < children.size(); iter++) {
- if(children.get(iter) instanceof CompartmentEditPart) {
- CompartmentEditPart child = (CompartmentEditPart)children.get(iter);
- EditPolicy policy = child.getEditPolicy(EditPolicy.LAYOUT_ROLE);
- if(policy != null) {
- PrecisionRectangle cptSize = LayoutUtils.getAbsolutePosition(child);
- dist += cptSize.y() - LayoutUtils.getAbsolutePosition(ept.getEditPart()).y();
- break;
- }
- }
- }
- Enumeration<?> eptChildren = ept.children();
- double max = 0;
- while(eptChildren.hasMoreElements()) {
- EditPartTree currentElement = (EditPartTree)eptChildren.nextElement();
- if(currentElement.isSelected() && (!currentElement.isReference())) {
- double tmp = getLabelHeightToRemove(currentElement);
- max = (tmp > max) ? tmp : max;
- }
- }
- dist += max;
- return dist;
+/**
+ * Constructor
+ *
+ * @param customAlignAction
+ * @param alignment
+ * @param refEditPart
+ *
+ */
+ public AlignActionHelper(int alignment, List<IGraphicalEditPart> selectedElements) {
+ this.alignment = alignment;
+ this.selectedElements = selectedElements;
+ this.refEditPart = getRefEditPart();
}
+
/**
* Tests the selection (nodes and edges). If Selection contains nodes (or Labels) and edges the method returns true
@@ -163,197 +106,241 @@ public class AlignActionHelper {
}
+
+
+
/**
- * Create a List of editPart from an EditPartTree from the root element to the passed element.
- * @param ept The EditPartTree we want the Path from the root
- * @return the List of EditPart with the Path from the root to the EditPartTree
+ * Tests if all the selected elements are instance of {@linkplain AbstractConnectionEditPart}
+ *
+ * @param editparts
+ * the editparts list to test
+ * @return
+ * <ul>
+ * <li> {@code true}</li> if all the editparts represents a link
+ * <li>{@code false}</li> if not
+ * </ul>
*/
- protected List<EditPart> getPathRootEditPartList(EditPartTree ept) {
- List<EditPart> nodeChild = new ArrayList<EditPart>();
+ protected boolean isLinkSelection(List<IGraphicalEditPart> editparts) {
+ boolean isEdgeOnly = true;
+ // if no selection
+ if(editparts.size() == 0) {
+ isEdgeOnly = false;
+ // at least one object is selected
+ } else {
- //used to calculate the shift between each element!
- Enumeration<?> vectorisedChildren = ((EditPartTree)ept.getPath()[1]).breadthFirstEnumeration();
- while(vectorisedChildren.hasMoreElements()) {
- nodeChild.add(((EditPartTree)vectorisedChildren.nextElement()).getEditPart());
+ for(Object object : editparts) {
+ if(!(object instanceof AbstractConnectionEditPart)) {
+ isEdgeOnly= false;
+ }
+ }
}
- return nodeChild;
+ return isEdgeOnly;
}
+
/**
- * Add scrollbar width to the Rectangle bounds to avoid to show them
- * @param containerBounds
+ * Define if Alignment is allowed.
+ * @param selectedElements
+ * @return
*/
- protected void addScrollBar(PrecisionRectangle containerBounds) {
- containerBounds.setPreciseX(containerBounds.x + LayoutUtils.scrollBarSize);
- containerBounds.setPreciseY(containerBounds.y + LayoutUtils.scrollBarSize);
- containerBounds.setPreciseWidth(containerBounds.width - 2 * LayoutUtils.scrollBarSize);
- containerBounds.setPreciseHeight(containerBounds.height - 2 * LayoutUtils.scrollBarSize);
+ protected boolean isAlignAllowed(List<IGraphicalEditPart> selectedElements) {
+ boolean alignAllowable = true;
+ // Alignment is not allowed if selection is a mixed with edges and nodes (or labels)
+ alignAllowable = alignAllowable && !isMixedSelection(selectedElements);
+ alignAllowable = alignAllowable && (selectedElements.size() >= 2);
+
+ return alignAllowable;
}
/**
- * Calculate the shift (level) between the EditPartTree and the Reference EP.
+ * Define if the New calculated position is allowed for the Alignment
*
- * @param ept EditPartTree
- * @param refEP Reference EditPart
- * @return shift (number of level) between ept and refEP
+ * @param currentEP current Edit Part to be aligned
+ * @param newPosition theoretical position after alignment
+ * @return true if the new Position fits to the alignment rules
*/
- protected int getShift(EditPartTree ept, EditPart refEP) {
- /*
- * calculus of the shift
- *
- * the shift is the first selected element when the reference is not a child of the editpart
- * the shift is the number of levels between the current editpart and the reference if this reference is a child
- */
- int level;
- if(ToolUtilities.isAncestorContainedIn(getPathRootEditPartList(ept), refEP)) {
- level = action.getRootTree().getTree(refEP).getLevel();
- int currentLevel = ept.getLevel();
- level = level - currentLevel + 1;
-
- } else{
- level = ept.getLevelForFirstSelectedElement();
- }
- return level;
- }
+ protected boolean isPositionAllowed(EditPart currentEP, PrecisionRectangle newPosition) {
+ boolean isAllow = true;
+ isAllow = isAllow && isContained(newPosition, currentEP);
+ isAllow = isAllow && !isRefChild(refEditPart, currentEP);
+ isAllow = isAllow && isPortPositionAllowed(newPosition, currentEP);
+ isAllow = isAllow && !isDependent(refEditPart, currentEP);
+
+
+ return isAllow;
+
+ }
/**
- * Tests if all the selected elements are instance of {@linkplain AbstractConnectionEditPart}
- *
- * @param editparts
- * the editparts list to test
+ * Define if the EditPart position depends on the other EditPart position
+ * @param ref
+ * @param currentEP
* @return
- * <ul>
- * <li> {@code true}</li> if all the editparts represents a link
- * <li>{@code false}</li> if not
- * </ul>
*/
- protected boolean isLinkSelection(List<?> editparts) {
- if(editparts.size() == 0) {
- return false;
- }
- for(Object object : editparts) {
- if(!(object instanceof AbstractConnectionEditPart)) {
- return false;
+ private boolean isDependent(EditPart ref, EditPart currentEP) {
+ boolean isDependent = false;
+ // If The reference is a Connection Label
+ if (ref instanceof LabelEditPart) {
+ if (ref.getParent() instanceof AbstractConnectionEditPart){
+ // Alignment is not allowed if it should moves at the same time as the connector
+ // That means if the Extremities of the Edge have to be aligned.
+ EditPart source = ((ConnectionEditPart)ref.getParent()).getSource();
+ EditPart target = ((ConnectionEditPart)ref.getParent()).getTarget();
+ //If extremities EditPart cannot be a child of the Current Edit part
+ if (currentEP.equals(source) || currentEP.equals(target) ) {
+ isDependent = true ;
+ } else if (isRefChild(source, currentEP) || isRefChild(target, currentEP)) {
+ isDependent = true ;
+ }
}
}
- return true;
+ return isDependent;
}
/**
- * Define if Alignment is allowed.
- * @param editparts
+ * Alignment Rule: In case of a Border Item, the Alignment is allowed only if the Port Position stay on his Parent Bounds.
+ * @param newPosition
+ * @param currentEP
* @return
*/
- protected boolean isAlignAllowed(List<EditPart> editparts) {
+ private boolean isPortPositionAllowed(PrecisionRectangle newPosition,
+ EditPart currentEP) {
+ boolean isPortAllow ;
+
+ if (currentEP instanceof AbstractBorderItemEditPart){
- boolean alignAllowable = true;
- // Alignment is not allowed if selection is a mixed with edges and nodes (or labels)
- alignAllowable = alignAllowable && !isMixedSelection(editparts);
+
+ PrecisionPoint portCenter = (PrecisionPoint) newPosition.getCenter();
+ PrecisionRectangle parentBounds = LayoutUtils.getAbsolutePosition(currentEP.getParent());
- return alignAllowable;
+ boolean isOnVerticalBounds = (portCenter.preciseX() == parentBounds.preciseX()) || (portCenter.preciseX() == parentBounds.preciseX()+ parentBounds.preciseWidth() );
+ boolean isOnHorizontalBounds = (portCenter.preciseY() == parentBounds.preciseY()) || (portCenter.preciseY() == parentBounds.preciseY()+ parentBounds.preciseHeight() );
+ boolean isBetweenHorizontalBounds = (portCenter.preciseY() >= parentBounds.preciseY()) && (portCenter.preciseY() <= parentBounds.preciseY()+parentBounds.preciseHeight());
+ boolean isBetweenVerticalBounds = (portCenter.preciseX() >= parentBounds.preciseX()) && (portCenter.preciseX() <= parentBounds.preciseX()+parentBounds.preciseWidth());
+
+ if ((isOnHorizontalBounds) && (isBetweenVerticalBounds)) {
+ isPortAllow = true;
+ } else if ((isOnVerticalBounds) && (isBetweenHorizontalBounds)) {
+ isPortAllow = true;
+ } else {
+ isPortAllow = false;
+ }
+
+ } else {
+
+ isPortAllow = true;
+ }
+
+ return isPortAllow;
}
+
/**
- * Return the list of Edit Parts based on the selected Elements.
+ * Alignment Rule: the EditPart should be still contained in its parent after the alignment
+ * @param newPosition
+ * @param currentEP
* @return
- * List of EditParts
*/
- protected List<EditPart> getEditPartList() {
- List<EditPart> editparts = new ArrayList<EditPart>();
- for(IGraphicalEditPart current : action.getSelectedElements()) {
- editparts.add(current);
- }
- return editparts;
- }
+ protected boolean isContained(PrecisionRectangle newPosition, EditPart currentEP) {
+ boolean isContained;
+
+ EditPart container = DiagramEditPartsUtil.getContainerEditPart((GraphicalEditPart) currentEP);
+ PrecisionRectangle containerBounds = LayoutUtils.getAbsolutePosition(container);
+ //reduce the reference of 1 pixel in order to avoid the Scrollbar apparition when trying to Align on the parent.
+ containerBounds.expand(new Insets(-1));
+ isContained = containerBounds.contains(newPosition.getBottomLeft()) && containerBounds.contains(newPosition.getTopRight()) ;
+
+ return isContained;
+
+ }
/**
- * Adjust AlignBounds to take scrollBar size into account in order to avoid to show them.
- *
- * @param alignRef The reference bounds to modify
- * @param boundsRef Absolute bounds of reference EP
- * @param ept EditPartTree
- * @param refEP Reference EditPart
+ * Alignment Rule : The parent cannot be aligned on its children
+ * @param ref
+ * @param ep
+ * @return
*/
- protected void adjustAlignRefBounds(PrecisionRectangle alignRef,
- PrecisionRectangle boundsRef, EditPartTree ept, EditPart refEP) {
-
- // AlignRef Bounds should not be adjust in case of LabelEdit Part
- if( !(ept.getEditPart() instanceof LabelEditPart) ){
-
- int level = getShift(ept, refEP);
-
- // depends on the alignment modify the reference rectangle
- switch(action.getAlignment()) {
- case PositionConstants.LEFT:
- alignRef.setPreciseX(boundsRef.x - ((level - 1) * LayoutUtils.scrollBarSize));
- alignRef.setPreciseWidth(boundsRef.width + 2 * ((level - 1) * LayoutUtils.scrollBarSize));
- break;
- case PositionConstants.CENTER:
- break;
- case PositionConstants.RIGHT:
-
- alignRef.setPreciseX(boundsRef.x + ((-level + 1) * LayoutUtils.scrollBarSize));
- alignRef.setPreciseWidth(boundsRef.preciseWidth() - 2 * ((-level + 1) * LayoutUtils.scrollBarSize));
- break;
-
- case PositionConstants.BOTTOM:
- alignRef.setPreciseY(boundsRef.y + ((-level + 1) * LayoutUtils.scrollBarSize));
- alignRef.setPreciseHeight(boundsRef.preciseHeight() - 2 * ((-level + 1) * LayoutUtils.scrollBarSize));
- break;
- case PositionConstants.MIDDLE:
- // get the size of the highest child
- double heightMax = 0;
- Enumeration<?> children = ept.children();
- while(children.hasMoreElements()) {
- EditPartTree currentChild = (EditPartTree)children.nextElement();
- double height = LayoutUtils.getAbsolutePosition(currentChild.getEditPart()).preciseHeight();
- heightMax = Math.max(height, heightMax);
- }
+ protected boolean isRefChild(EditPart ref, EditPart ep) {
+ boolean refIsChild = false;
+ List<?> children = ep.getChildren();
+ Iterator<?> iter = children.iterator();
+ while(iter.hasNext() && !refIsChild ){
- // get the size of the compartment for this figure!
- List<?> childrenEP = ept.getEditPart().getChildren();
- double compartmentHeight = 0;
- Iterator<?> iter = childrenEP.iterator();
- while(iter.hasNext() && compartmentHeight == 0){
- if(iter.next() instanceof CompartmentEditPart) {
- CompartmentEditPart child = (CompartmentEditPart)iter.next();
- EditPolicy policy = child.getEditPolicy(EditPolicy.LAYOUT_ROLE);
- if(policy != null) {
- compartmentHeight = LayoutUtils.getAbsolutePosition(child).preciseHeight();
- }
- }
- }
+ Object child = iter.next();
+ if (ref.equals(child)){
+ refIsChild = true;
- double heightToRemove = getLabelHeightToRemove(ept);
- //test to know if the initial alignment is possible without seeing the scrollbar
- if(compartmentHeight < (heightMax + LayoutUtils.scrollBarSize + heightToRemove)) {
- alignRef.setPreciseY(alignRef.y - heightToRemove);
- alignRef.setPreciseHeight(alignRef.preciseHeight() + heightToRemove);
- }
+ } else if (child instanceof EditPart){
+ refIsChild = isRefChild(ref, (EditPart) child);
+ }
- break;
- case PositionConstants.TOP: //here we can have a problem with the label for the element inheriting from Package
- alignRef.setPreciseY(boundsRef.y - ((level - 1) * LayoutUtils.scrollBarSize));
- alignRef.setPreciseHeight(boundsRef.preciseHeight() + 2 * ((level - 1) * LayoutUtils.scrollBarSize));
+ }
+ return refIsChild;
+ }
- // we don't want that the scrollbar appears, with the top alignment, we need to consider the label of the container element
- if(ept.children().hasMoreElements()) {
- double dist = getLabelHeightToRemove(ept);
- alignRef.setPreciseY(alignRef.y() - dist);
- }
- break;
- default:
- break;
+ /**
+ * Get the reference Edit part for the alignment.
+ * @return reference edit part for the alignment
+ */
+ protected EditPart getRefEditPart() {
+ Iterator<IGraphicalEditPart> iter = selectedElements.iterator();
+ EditPart ref = null;
+
+ while (iter.hasNext() && ref == null){
+ EditPart ep = iter.next();
+ if (ep.getSelected() == EditPart.SELECTED_PRIMARY){
+ ref = ep;
}
}
-
+ return ref;
}
+
+ /**
+ *
+ * @param currentEPBounds
+ * @param refBounds
+ * @return
+ */
+ protected PrecisionRectangle getNewPosition(
+ PrecisionRectangle currentEPBounds, PrecisionRectangle refBounds) {
+
+ // Initialise new Position with the current Position
+ PrecisionRectangle newPosition = new PrecisionRectangle(currentEPBounds);
+ PrecisionPoint distance = new PrecisionPoint (0.0,0.0);
+ switch(this.alignment) {
+ case PositionConstants.LEFT:
+ newPosition.setPreciseX(refBounds.preciseX());
+ break;
+ case PositionConstants.CENTER:
+ distance.setPreciseX(refBounds.getCenter().preciseX() - currentEPBounds.getCenter().preciseX());
+ newPosition.translate(distance);
+ break;
+ case PositionConstants.RIGHT:
+ distance.setPreciseX(refBounds.getTopRight().preciseX() - currentEPBounds.getTopRight().preciseX());
+ newPosition.translate(distance);
+ break;
+ case PositionConstants.TOP:
+ newPosition.setPreciseY(refBounds.preciseY());
+ break;
+ case PositionConstants.MIDDLE:
+ distance.setPreciseY(refBounds.getCenter().preciseY() - currentEPBounds.getCenter().preciseY());
+ newPosition.translate(distance);
+ break;
+ case PositionConstants.BOTTOM:
+ distance.setPreciseY( refBounds.getBottomLeft().preciseY() - currentEPBounds.getBottomLeft().preciseY());
+ newPosition.translate(distance);
+ break;
+ default:
+ break;
+ }
+ return newPosition;
+ }
-}
+} \ No newline at end of file
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/CustomAlignAction.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/CustomAlignAction.java
index 4f673acb3af..f7a9a68182c 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/CustomAlignAction.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.menu/src/org/eclipse/papyrus/uml/diagram/menu/actions/CustomAlignAction.java
@@ -1,7 +1,7 @@
/*****************************************************************************
* Copyright (c) 2010 CEA LIST.
*
- *
+ *
* 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
@@ -9,31 +9,23 @@
*
* Contributors:
* Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- * C�line Janssens (ALL4TEC) celine.janssens@all4tec.net - Code refractor and documentation
+ * Céline Janssens (ALL4TEC) celine.janssens@all4tec.net - Bug 442582 : Code refactor and documentation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.menu.actions;
-import java.util.Enumeration;
import java.util.List;
-import org.eclipse.draw2d.PositionConstants;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
-import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.requests.AlignmentRequest;
-import org.eclipse.gef.tools.ToolUtilities;
import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.papyrus.uml.diagram.common.helper.AlignmentLinkHelper;
-import org.eclipse.papyrus.uml.diagram.common.layout.AlignmentTree;
-import org.eclipse.papyrus.uml.diagram.common.layout.EditPartTree;
import org.eclipse.papyrus.uml.diagram.common.layout.LayoutUtils;
@@ -51,463 +43,120 @@ import org.eclipse.papyrus.uml.diagram.common.layout.LayoutUtils;
* </li>
* </ul>
* If the containing figure is different, a correct alignment is not guaranteed.
- *
+ *
* With this class, we can align nodes, by selecting them, or by selecting the link between them, thanks to {@link AlignmentLinkHelper}
*/
public class CustomAlignAction {
- /**
- * the Tree used to sort editparts
- * It contains all the selected editpart AND the intermediate editparts which can exist between two selected editparts
- *
- */
- private AlignmentTree rootTree;
-
-
- /** The alignment. */
+ /** The alignment type. */
private int alignment;
- /** the selected elements */
- private List<IGraphicalEditPart> selectedElements;
- /** List of selected edit Parts*/
- private List<EditPart> editparts;
+ /** the selected elements. */
+ private List<IGraphicalEditPart> selectedElements;
+
+ /** Reference Edit Part for the Alignment. */
+ private EditPart refEditPart;
+
+ /** Reference Rectangle on which the alignment is based. */
+ private PrecisionRectangle refBounds;
+
/** Helper for specific treatment*/
- private AlignActionHelper helper = new AlignActionHelper(this);
+ private AlignActionHelper helper ;
+
/**
- *
* Constructor.
*
- * @param alignment
- * @param selectedElements
+ * @param alignment Alignment Type
+ * @param selectedElements List of selected EditParts
*/
public CustomAlignAction(int alignment, List<IGraphicalEditPart> selectedElements) {
this.alignment = alignment;
this.selectedElements = selectedElements;
+ helper = new AlignActionHelper(alignment, selectedElements);
}
/**
* Returns the command for this action
- *
+ *
* @return
* the command for this action
*/
public Command getCommand() {
-
- editparts = helper.getEditPartList();
- Command cmd = null;
-
- // In case of alignment not allowed no command is returned.
- if (!helper.isAlignAllowed(editparts)){
- cmd = UnexecutableCommand.INSTANCE;
- }
+
+ CompoundCommand commands = new CompoundCommand("Alignment Commands");
// In case of only Edges selected, a specific alignment is done
- if(helper.isLinkSelection(editparts)) {
+ if(helper.isLinkSelection(selectedElements)) {
// Align Source and target Nodes of the edge depending on the alignment type
- AlignmentLinkHelper helper = new AlignmentLinkHelper(editparts, alignment);
- cmd = helper.createCommand();
- }
-
- // If only 1 Nodes is selected no Alignment is possible
- if(editparts.size() < 2) {
- cmd = UnexecutableCommand.INSTANCE;
-
- }else{
-
- rootTree = new AlignmentTree(editparts);
- // create the alignment requests
- createRequests();
- // return the associated command
- cmd = getAlignmentCommand();
- }
-
- return cmd;
- }
+ AlignmentLinkHelper helper = new AlignmentLinkHelper(selectedElements, alignment);
+ commands.add(helper.createCommand());
- /**
- * Get the Alignment Commands of selected editParts
- * @return
- * the Command related to the selected editParts and the Alignment Request
- */
- private Command getAlignmentCommand() {
-
- CompoundCommand commands = new CompoundCommand("Alignment Commands"); //$NON-NLS-1$
- // Create a enumeration with the sub tree element ordered by breadth
- Enumeration<?> eptEnum = rootTree.breadthFirstEnumeration();
- while(eptEnum.hasMoreElements()) {//for each selected element
- // Create an EditPartTree - hierarchy between selected editparts
- EditPartTree ept = (EditPartTree)eptEnum.nextElement();
-
- if(ept.getEditPart() != null) {
- // get the alignment request associated to the EditPartTree
- AlignmentRequest currentReq = (AlignmentRequest)ept.getRequest();
- if(currentReq != null) {
- Command curCommand = null;
- // if this request is not null, get the associated command for this editPart
- curCommand = ept.getEditPart().getCommand(currentReq);
- if(curCommand != null) {
- // Add it to the compound command
- commands.add(curCommand);
- }
- }
- }
- }
- return commands.isEmpty() ? UnexecutableCommand.INSTANCE : (Command)commands;
- }
+ } else if (helper.isAlignAllowed(selectedElements)){
- /**
- * <ul>
- * <li>Calculates the initial conditions to align each nodes owned by {@link #rootTree}</li>
- * <li>Call {@link #createConstrainedRequest(PrecisionRectangle, PrecisionRectangle, PrecisionRectangle, EditPartTree)} for each node to create the request</li>
- * </ul>
- *
- * @param editparts
- * the editparts to align (the last editpart is the reference for the alignment)
- * @param request
- * the initial request
- */
- protected void createRequests() {
-
- // The reference EP is the last selected
- EditPart refEP = (EditPart)editparts.get(editparts.size() - 1);
- // Get absolute bounds of the Ref EP
- PrecisionRectangle boundsRef = LayoutUtils.getAbsolutePosition(refEP);
-
- // Get the depth of the Align Tree
- int depth = this.rootTree.getDepth();
- for(int i = 1; i <= depth; i++) {//we iterate by level in the rootTree
- List<EditPartTree> epTrees = rootTree.getChildLevel(i);
- for(EditPartTree ept : epTrees) {
- List<EditPart> nodeChild = helper.getPathRootEditPartList(ept);
-
- if (ept.isSelected()) {// the edit part is selected
- if (ept.getEditPart() != refEP && (!ept.existsUnselectedChild())) {
-
-
- // the reference used for the alignment
- PrecisionRectangle alignRef = new PrecisionRectangle(boundsRef);
- PrecisionRectangle containerBounds = ((AlignmentTree)ept).getNewContainerBounds();
-
- // if container bounds is not the same as diagram then take the scrollbar width into account
- if(!containerBounds.equals(LayoutUtils.getAbsolutePosition(ept.getEditPart().getRoot()))) {
- helper.addScrollBar(containerBounds);
- }
-
- // Adjust Ref Bounds with scrollbar, labels and compartment height
- helper.adjustAlignRefBounds(alignRef, boundsRef, ept , refEP );
-
- // create the request
- createConstrainedRequest(alignRef, containerBounds, null, (AlignmentTree) ept);
-
- //The current editPart has not selected child
- } else if(ept.getEditPart() != refEP && (ept.existsUnselectedChild())) {
-
-
-
- PrecisionRectangle boundsLimit = helper.getUnselectedChildNewBounds(ept , refEP);
- PrecisionRectangle containerBounds = ((AlignmentTree) ept).getNewContainerBounds();
-
- if(!containerBounds.equals(LayoutUtils.getAbsolutePosition(ept.getEditPart().getRoot()))) {
- //we reduce the container bounds used to avoid scrollbar
- helper.addScrollBar(containerBounds);
- }
-
- createConstrainedRequest(boundsRef, containerBounds, boundsLimit, (AlignmentTree) ept);
-
-
- } else if(ept.getEditPart() == refEP && ToolUtilities.isAncestorContainedIn(nodeChild, refEP)) {
-
- if(((EditPartTree)ept.getParent()).isSelected()) {
-
- /*
- * we need to create a command for the reference, only if
- * its direct parent is selected.
- * If the reference has ancestor in the selection and if this ancestor is not selected, itn's not necessary to move the
- * reference, because it's the ancestor which must move.
- */
- PrecisionRectangle containerBounds = ((AlignmentTree)ept).getNewContainerBounds();
- containerBounds.setPreciseX(containerBounds.x + LayoutUtils.scrollBarSize);
- containerBounds.setPreciseY(containerBounds.y + LayoutUtils.scrollBarSize);
- containerBounds.setPreciseWidth(containerBounds.width - 2 * LayoutUtils.scrollBarSize);
- containerBounds.setPreciseHeight(containerBounds.height - 2 * LayoutUtils.scrollBarSize);
- createConstrainedRequest(LayoutUtils.getAbsolutePosition(refEP), containerBounds, null, (AlignmentTree)ept);
- }
-
- }
-
- } else {//the Edit Part is not selected! We need to maintain its location
-
- PrecisionRectangle containerBounds = ((AlignmentTree)ept).getNewContainerBounds();
- containerBounds.setPreciseX(containerBounds.x + LayoutUtils.scrollBarSize);
- containerBounds.setPreciseY(containerBounds.y + LayoutUtils.scrollBarSize);
- containerBounds.setPreciseWidth(containerBounds.width - 2 * LayoutUtils.scrollBarSize);
- containerBounds.setPreciseHeight(containerBounds.height - 2 * LayoutUtils.scrollBarSize);
-
- createConstrainedRequest(LayoutUtils.getAbsolutePosition(ept.getEditPart()), containerBounds, null, (AlignmentTree)ept);
+ // Define the reference
+ refEditPart = helper.getRefEditPart();
+ // Get absolute bounds of the Reference Edit Part
+ refBounds = LayoutUtils.getAbsolutePosition(refEditPart);
+ for (EditPart currentEP: selectedElements){
+ if (currentEP.getSelected() == EditPart.SELECTED){
+ PrecisionRectangle currentEPBounds = LayoutUtils.getAbsolutePosition(currentEP);
+ PrecisionRectangle newPosition = helper.getNewPosition(currentEPBounds , refBounds );
+
+ if (helper.isPositionAllowed(currentEP, newPosition)){
+ commands.add(getAlignmentCommand(currentEP, newPosition));
+ }
}
}
+ } else {
+ commands = null;
}
-
+
+ return (Command)commands;
}
/**
- * <ul>
- * <li>Completes the {@link EditPartTree} with the correct new position for the object</li>
- * <li>Adds the created request to the {@link EditPartTree}</li>
- * </ul>
- *
- * @param ref
- * the reference used for the alignment
- * @param containerBounds
- * the size of the editpart container
- * @param dontCross
- * the shift must be done, without the figure bounds are drawn in this rectangle
- * @param tree
- * the tree for which we create the request
+ * Get the Alignment Commands of selected editParts
+ * @param newPosition
+ * @param currentEP
+ * @return
+ * the Command related to the selected editParts and the Alignment Request
*/
+ private Command getAlignmentCommand(EditPart currentEP, PrecisionRectangle newPosition) {
- protected void createConstrainedRequest(PrecisionRectangle ref, PrecisionRectangle containerBounds, PrecisionRectangle dontCross, AlignmentTree tree) {
+ Command curCommand = null;
+ if(currentEP != null) {
+ // get the alignment request associated to the EditPartTree
+ AlignmentRequest currentReq = (AlignmentRequest) getRequest(currentEP , newPosition);
+ if(currentReq != null) {
- PrecisionRectangle editpartBounds = LayoutUtils.getAbsolutePosition(tree.getEditPart());
- PrecisionRectangle newPosition = new PrecisionRectangle(editpartBounds);
-
- //Nominal Case
- if(dontCross == null && containerBounds.equals(LayoutUtils.getAbsolutePosition(tree.getEditPart().getRoot()))) {
-
- AlignmentRequest newRequest = new AlignmentRequest(RequestConstants.REQ_ALIGN);
- PrecisionRectangle newPrecisionRectangle = new PrecisionRectangle(ref);
- newRequest.setAlignment(this.alignment);
- newRequest.setAlignmentRectangle(newPrecisionRectangle);
- double pos = 0;
- switch(this.alignment) {
- case PositionConstants.LEFT:
- newPosition.setPreciseX(ref.x());
- break;
- case PositionConstants.CENTER:
- pos = ref.getTop().x() - (editpartBounds.preciseWidth() / 2.0);
- newPosition.setPreciseX(pos);
- break;
- case PositionConstants.RIGHT:
- pos = ref.getRight().x() - editpartBounds.preciseWidth();
- newPosition.setPreciseX(pos);
- break;
- case PositionConstants.TOP:
- pos = ref.getTop().y();
- newPosition.setPreciseY(pos);
- break;
- case PositionConstants.MIDDLE:
- pos = ref.getLeft().y() - (editpartBounds.preciseHeight() / 2.0);
- newPosition.setPreciseY(pos);
- break;
- case PositionConstants.BOTTOM:
- pos = ref.getBottom().y() - editpartBounds.preciseHeight();
- newPosition.setPreciseY(pos);
- break;
- default:
- break;
- }
- tree.setNewPosition(newPosition);
- tree.setRequest(newRequest);
- return;
-
+ // if this request is not null, get the associated command for this editPart
+ curCommand = currentEP.getCommand(currentReq);
- //Not nominal Cases
- } else {
-
- //variables used to write the request
- PrecisionPoint minPoint = new PrecisionPoint();
- PrecisionPoint maxPoint = new PrecisionPoint();
-
- // Container bigger than Editor
- if(dontCross == null && (!containerBounds.equals(LayoutUtils.getAbsolutePosition(tree.getEditPart().getRoot())))) {
-
- minPoint.setPreciseX(containerBounds.x);
- maxPoint.setPreciseX(containerBounds.getRight().x() - editpartBounds.preciseWidth());
- minPoint.setPreciseY(containerBounds.y);
- maxPoint.setPreciseY(containerBounds.getBottom().y() - editpartBounds.preciseHeight());
-
- // Bounds limits in case of unselected child
- } else if(dontCross != null) {
-
-
- minPoint.setPreciseX(dontCross.getRight().x() - editpartBounds.preciseWidth());
- maxPoint.setPreciseX(dontCross.x);
- minPoint.setPreciseY(dontCross.getBottom().y() - editpartBounds.preciseHeight());
- maxPoint.setPreciseY(dontCross.y);
-
- if(!containerBounds.equals(LayoutUtils.getAbsolutePosition(tree.getEditPart().getRoot()))) {
- //container's limits
- double xMinContainerLimit = containerBounds.x;
- double xMaxContainerLimit = containerBounds.getRight().x() - editpartBounds.preciseWidth();
- double yMinContainerLimit = containerBounds.y;
- double yMaxContainerLimit = containerBounds.getBottom().y() - editpartBounds.preciseHeight();
-
-
- minPoint.setPreciseX(Math.max(minPoint.x() , xMinContainerLimit));
- maxPoint.setPreciseX(Math.min(maxPoint.x() , xMaxContainerLimit));
- minPoint.setPreciseY(Math.max(minPoint.y() , yMinContainerLimit));
- maxPoint.setPreciseY(Math.min(maxPoint.y() , yMaxContainerLimit));
- }
}
-
-
- /* rectangle used to do the alignment */
- PrecisionRectangle myAlignRectangle = new PrecisionRectangle(editpartBounds);
-
- /* the distance between the editpart in the new container position and its alignment reference */
- PrecisionPoint offset = getOffset(minPoint, maxPoint, ref, editpartBounds, tree);
-
-
- myAlignRectangle.setPreciseX(LayoutUtils.getAbsolutePosition(tree.getEditPart()).x + offset.x());
- myAlignRectangle.setPreciseY(LayoutUtils.getAbsolutePosition(tree.getEditPart()).y + offset.y());
-
- /* the point use to translate the editpart */
- Point translationPoint = new PrecisionPoint(0.0,0.0);
-
- /* the new request */
- AlignmentRequest newRequest = new AlignmentRequest(RequestConstants.REQ_ALIGN);
- newRequest.setAlignment(this.alignment);
-
-
-
- newRequest.setAlignmentRectangle(myAlignRectangle);
- newPosition = (PrecisionRectangle)tree.getAbsolutePositionInTheNewContainerPosition().translate(translationPoint);
- tree.setNewPosition(newPosition);
- tree.setRequest(newRequest);
- return;
}
+ return curCommand;
}
/**
- * Get the offset distance between the editpart and the alignement position.
- *
- * If the alignment Position is out of the calculated Bounds (min and max Points),
- * the offset is the distance between the EditPart and the nearest allowed bounds.
- *
- * @param minPoint Minimum allowed position for the editpart
- * @param maxPoint Maximum allowed position for the editpart
- * @param ref Reference rectangle of the alignment request
- * @param editpartBounds edit Part Bounds rectangle
- * @param tree current Alignment Tree
- * @return
+ * Create the Alignment Request.
+ * @param newPosition The wished new position of the EditPart after Alignment
+ * @param currentEP
+
*/
- private PrecisionPoint getOffset(PrecisionPoint minPoint,
- PrecisionPoint maxPoint, PrecisionRectangle ref,
- PrecisionRectangle editpartBounds, AlignmentTree tree) {
-
- PrecisionPoint distance = new PrecisionPoint (0.0,0.0);
- /* the editpart's position in its container, after the shift of the container */
- PrecisionRectangle newTmpPosition = tree.getAbsolutePositionInTheNewContainerPosition();
-
- switch (alignment) {
- case PositionConstants.LEFT:
-
-
- if((ref.x >= minPoint.x()) && (ref.x <= maxPoint.x())) {
- distance.setPreciseX(ref.x - newTmpPosition.x);
- } else if(ref.x < minPoint.x()) {
- distance.setPreciseX(minPoint.x() - newTmpPosition.x);
- } else if(ref.x > maxPoint.x()) {
- distance.setPreciseX(maxPoint.x() - newTmpPosition.x);
- }
-
- break;
-
- case PositionConstants.CENTER:// un alignement central fait de cette facon : tous les packages alignes sur un element exterieur ne marche pas du tout!
-
-
- double minCenter = minPoint.x() + (editpartBounds.preciseWidth() / 2.0);
- double maxCenter = maxPoint.x() + (editpartBounds.preciseWidth() / 2.0);
- if((ref.getTop().x() >= minCenter) && (ref.getTop().x() <= maxCenter)) {
- distance.setPreciseX(ref.x + (ref.preciseWidth() / 2.0) - (newTmpPosition.x + (newTmpPosition.preciseWidth() / 2.0)));
- } else if(ref.getTop().x() < minCenter) {
- distance.setPreciseX(minCenter - (newTmpPosition.x + (newTmpPosition.preciseWidth() / 2.0)));
- } else if(ref.getTop().x() > maxCenter) {
-
- distance.setPreciseX(maxCenter - (newTmpPosition.x + ((newTmpPosition.preciseWidth()) / 2.0)));
- }
-
- break;
-
- case PositionConstants.RIGHT:
-
- double minRight = minPoint.x() + editpartBounds.preciseWidth();
- double maxRight = maxPoint.x() + editpartBounds.preciseWidth();
- if((ref.getRight().x() >= minRight) && (ref.getRight().x() <= maxRight)) {
- distance.setPreciseX((ref.x + ref.preciseWidth()) - (newTmpPosition.x + newTmpPosition.preciseWidth()));
- } else if(ref.getRight().x() < minRight) {
- distance.setPreciseX( minRight - (newTmpPosition.x + newTmpPosition.preciseWidth()));
- } else if(ref.getRight().x() > maxRight) {
- distance.setPreciseX( maxRight - (newTmpPosition.x + newTmpPosition.preciseWidth()));
- }
-
- break;
-
-
- case PositionConstants.BOTTOM:
-
- double minBottom = minPoint.y() + editpartBounds.preciseHeight();
- double maxBottom = maxPoint.y() + editpartBounds.preciseHeight();
- if(((ref.getBottom().y()) >= minBottom) && ((ref.getBottom().y()) <= maxBottom)) {
- distance.setPreciseY( (ref.y + ref.preciseHeight()) - (newTmpPosition.y + newTmpPosition.preciseHeight()));
- } else if((ref.getBottom().y()) < minBottom) {
- distance.setPreciseY( minBottom - (newTmpPosition.y + newTmpPosition.preciseHeight()));
- } else if((ref.getBottom().y()) > maxBottom) {
- distance.setPreciseY( maxBottom - (newTmpPosition.y + newTmpPosition.preciseHeight()));
- }
- break;
-
- case PositionConstants.MIDDLE:
-
- double minMiddle = minPoint.y() + (editpartBounds.preciseHeight() / 2.0);
- double maxMiddle = maxPoint.y() + (editpartBounds.preciseHeight() / 2.0);
- if(((ref.y + (ref.preciseHeight() / 2.0)) >= minMiddle) && ((ref.y + (ref.preciseHeight() / 2.0)) <= maxMiddle)) {
- distance .setPreciseY( (ref.y + (ref.preciseHeight() / 2.0) - (newTmpPosition.y + (newTmpPosition.preciseHeight() / 2.0))));
- } else if((ref.y + (ref.height / 2.0)) < minMiddle) {
- distance .setPreciseY( minMiddle - (newTmpPosition.y + (newTmpPosition.preciseHeight() / 2.0)));
- } else if((ref.y + (ref.height / 2.0)) > maxMiddle) {
- distance .setPreciseY( maxMiddle - (newTmpPosition.y + (newTmpPosition.preciseHeight() / 2.0)));
- }
- break;
-
- case PositionConstants.TOP:
-
- if((ref.y >= minPoint.y()) && (ref.y <= maxPoint.y())) {
- distance .setPreciseY( ref.y - newTmpPosition.y);
- } else if(ref.y < minPoint.y()) {
- distance .setPreciseY( minPoint.y() - newTmpPosition.y);
- } else if(ref.y > maxPoint.y()) {
- distance.setPreciseY( maxPoint.y() - newTmpPosition.y);
- }
- break;
- default:
- break;
- }
-
- return distance;
- }
+ protected AlignmentRequest getRequest(EditPart currentEP, PrecisionRectangle newPosition) {
- /** Get current root Tree. */
- public AlignmentTree getRootTree() {
- return rootTree;
- }
+ AlignmentRequest alignReq = new AlignmentRequest(RequestConstants.REQ_ALIGN);
- /** Get list of Edit Parts. */
- public List<EditPart> getEditparts() {
- return editparts;
- }
- /** Get the Alignment type. */
- public int getAlignment() {
- return alignment;
- }
+ alignReq.setAlignment(alignment);
+ alignReq.setAlignmentRectangle(newPosition);
+ alignReq.setEditParts(currentEP);
+
+ return alignReq;
- /** Get list of selected Elements */
- public List<IGraphicalEditPart> getSelectedElements() {
- return selectedElements;
}
}

Back to the top