Bug 572493 - improved preResizeShape

Updated algorithm for method preResizeShape
Fixed GraphicsUtil method getBoundingRectangle

Change-Id: Ifb41e0dd1ddf7c1b992afcaff7c3eb0548faf5ca
Signed-off-by: Ralph Soika <ralph.soika@imixs.com>
diff --git a/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/containers/lane/ResizeLaneFeature.java b/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/containers/lane/ResizeLaneFeature.java
index e6ee46e..bd0e92b 100644
--- a/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/containers/lane/ResizeLaneFeature.java
+++ b/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/containers/lane/ResizeLaneFeature.java
@@ -12,11 +12,15 @@
  ******************************************************************************/
 package org.eclipse.bpmn2.modeler.core.features.containers.lane;
 
+import java.util.List;
+
 import org.eclipse.bpmn2.Lane;
 import org.eclipse.bpmn2.modeler.core.features.GraphitiConstants;
 import org.eclipse.bpmn2.modeler.core.features.containers.AbstractResizeContainerFeature;
 import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
 import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
+import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
+import org.eclipse.draw2d.geometry.Rectangle;
 import org.eclipse.graphiti.features.IFeatureProvider;
 import org.eclipse.graphiti.features.IResizeShapeFeature;
 import org.eclipse.graphiti.features.context.IResizeShapeContext;
@@ -233,26 +237,40 @@
 		}
 	}
 	
+	/**
+	 * This method calculates the minimum size of a container (pool or lane) 
+	 * and avoids shrinking the container if child elements are hidden
+	 */
 	@Override
 	protected void preResizeShape(IResizeShapeContext context) {
 		super.preResizeShape(context);
-		// TODO: figure out an algorithm to resize lanes so that children
-		// are always visible
-//		List<PictogramElement> children = FeatureSupport.getPoolOrLaneChildren((ContainerShape)context.getShape());
-//		Rectangle bounds = GraphicsUtil.getBoundingRectangle(children);
-//		int direction = 0;
-//		if (bounds.x < context.getX()) {
-//			((ResizeShapeContext)context).setX(bounds.x);
-//		}
-//		if (bounds.y < context.getY()) {
-//			((ResizeShapeContext)context).setY(bounds.y);
-//		}
-//		if (bounds.x + bounds.width > context.getWidth()) {
-//			((ResizeShapeContext)context).setWidth(bounds.x + bounds.width);
-//		}
-//		if (bounds.y + bounds.height > context.getHeight()) {
-//			((ResizeShapeContext)context).setHeight(bounds.y + bounds.height);
-//		}
+		List<PictogramElement> children = FeatureSupport.getPoolOrLaneChildren((ContainerShape)context.getShape());
+		Rectangle bounds = GraphicsUtil.getBoundingRectangle(children);
+		
+		// create an offset of 10px
+		if (bounds.x>10) {
+			bounds.x=bounds.x-10;
+		}
+		if (bounds.y>10) {
+			bounds.y=bounds.y-10;
+		}
+		bounds.width=bounds.width+20;
+		bounds.height=bounds.height+20;
+		
+		// check if the desired dimension is possible
+		if (bounds.x < context.getX()) {
+			((ResizeShapeContext)context).setX(bounds.x);
+		}
+		if (bounds.y < context.getY()) {
+			// TODO this is not yet working correctly
+			((ResizeShapeContext)context).setY(bounds.y);
+		}
+		if (bounds.x + bounds.width > context.getWidth()) {
+			((ResizeShapeContext)context).setWidth(bounds.x + bounds.width);
+		}
+		if (bounds.y + bounds.height > context.getHeight()) {
+			((ResizeShapeContext)context).setHeight(bounds.y + bounds.height);
+		}
 	}
 	
 	private ContainerShape getLowestLane(ContainerShape root, boolean useFirstLane) {
diff --git a/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java b/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
index 429a982..f926add 100644
--- a/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
+++ b/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
@@ -797,6 +797,12 @@
 		return lx-dist <= x && x <= lx+dist && ly-dist <= y && y <= ly+dist;
 	}
 
+	/**
+	 * This method computes a bounding rectangle around a group of PictorgramElements 
+	 * 
+	 * @param pes
+	 * @return
+	 */
 	public static Rectangle getBoundingRectangle(List<? extends PictogramElement> pes) {
 		int xMin = Integer.MAX_VALUE;
 		int yMin = Integer.MAX_VALUE;
@@ -805,6 +811,35 @@
 		
 		for (PictogramElement pe : pes) {
 			if (pe instanceof Shape) {
+				GraphicsAlgorithm peGa = pe.getGraphicsAlgorithm();
+				IDimension size = calculateSize(pe);
+				if (peGa.getX()<xMin)
+					xMin = peGa.getX();
+				if (peGa.getY()<yMin)
+					yMin = peGa.getY();
+				if (peGa.getX() + size.getWidth()>xMax)
+					xMax = peGa.getX() + size.getWidth();
+				if (peGa.getY() + size.getHeight()>yMax)
+					yMax = peGa.getY() + size.getHeight();
+			}
+		}
+		return new Rectangle(xMin, yMin, xMax-xMin, yMax-yMin);
+	}
+	
+	/**
+	 * This method computes a bounding rectangle around a group of PictorgramElements with absolute 
+	 * x,y coordinates relative to the Diagram
+	 * @param pes
+	 * @return
+	 */
+	public static Rectangle getBoundingRectangleAbsolute(List<? extends PictogramElement> pes) {
+		int xMin = Integer.MAX_VALUE;
+		int yMin = Integer.MAX_VALUE;
+		int xMax = Integer.MIN_VALUE;
+		int yMax = Integer.MIN_VALUE;
+		
+		for (PictogramElement pe : pes) {
+			if (pe instanceof Shape) {
 				ILocation loc = Graphiti.getPeService().getLocationRelativeToDiagram((Shape)pe);
 				IDimension size = calculateSize(pe);
 				if (loc.getX()<xMin)
@@ -818,5 +853,5 @@
 			}
 		}
 		return new Rectangle(xMin, yMin, xMax-xMin, yMax-yMin);
-	}
+	}	
 }