From 1bc5e88f645853d74c618b7f20c554274f67f7e9 Mon Sep 17 00:00:00 2001
From: Simon Barner <barner@fortiss.org>
Date: Fri, 19 May 2017 14:20:31 +0000
Subject: [PATCH] - Ensure that coordinates are aligned to the grid refs 2898

---
 .../ui/layout/auto/KielerAutoLayouter.java    | 62 ++++++++++++++++---
 1 file changed, 53 insertions(+), 9 deletions(-)

diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java
index f87edfcbf..742a6dc7a 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java
@@ -18,9 +18,11 @@ $Id$
 package org.fortiss.tooling.base.ui.layout.auto;
 
 import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_CONNECTOR_SIZE;
+import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_GRID_SIZE;
 import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_SHAPE_MINIMUM_HEIGHT;
 import static org.fortiss.tooling.base.utils.LayoutDataUtils.getNodeSize;
 import static org.fortiss.tooling.base.utils.LayoutDataUtils.setNodePosition;
+import static org.fortiss.tooling.base.utils.LayoutDataUtils.setStickyConnectorLayoutData;
 
 import java.util.Map.Entry;
 
@@ -80,7 +82,7 @@ import de.cau.cs.kieler.klay.layered.properties.Properties;
  * @author offtermatt, barner
  * @author $Author$
  * @version $Rev$
- * @ConQAT.Rating YELLOW Hash: EEC3D86CD41265BFED5C9CB32D2EDA5F
+ * @ConQAT.Rating YELLOW Hash: 8BE55A0C36B936EF103CD3350B857042
  */
 public class KielerAutoLayouter implements IAutoLayouter {
 
@@ -128,6 +130,43 @@ public class KielerAutoLayouter implements IAutoLayouter {
 		AnnotationViewPartBase.setUpdateEnabled(avUpdateEnabled);
 	}
 
+	/**
+	 * Rounds a given {@code float} value and decreases the value until it is a multiple of the grid
+	 * size.
+	 * 
+	 * @param f
+	 *            {@code float} to process
+	 * 
+	 * @return Given float value, rounded and aligned to the underlying grid.
+	 */
+	private int roundSnap2Grid(float f) {
+		return roundSnap2Grid(f, false);
+	}
+
+	/**
+	 * Rounds a given {@code float} value and aligns it the grid size.
+	 * 
+	 * @param f
+	 *            {@code float} to process
+	 * 
+	 * @param enlarge
+	 *            Whether to enlarge the given value while aligning to the grid.
+	 * 
+	 * @return Given float value, rounded and aligned to the underlying grid.
+	 */
+	private int roundSnap2Grid(float f, boolean enlarge) {
+		int rval = (int)f;
+
+		final int deviationFromGrid = rval % DEFAULT_GRID_SIZE;
+		if(deviationFromGrid > 0)
+			if(enlarge) {
+				rval += DEFAULT_GRID_SIZE;
+			}
+		rval -= deviationFromGrid;
+
+		return rval;
+	}
+
 	/**
 	 * Applies the layout defined in the {@link KNode} follows to given {@link IHierarchicElement}.
 	 * 
@@ -146,8 +185,9 @@ public class KielerAutoLayouter implements IAutoLayouter {
 				KNode curNode = modelElementsToKNodes.get(curElement);
 				KShapeLayout curLayout = curNode.getData(KShapeLayout.class);
 				LayoutDataUtils.setNodeLayoutData((ILayoutedModelElement)curElement,
-						(int)curLayout.getXpos(), (int)curLayout.getYpos(),
-						(int)curLayout.getWidth(), (int)curLayout.getHeight());
+						roundSnap2Grid(curLayout.getXpos()), roundSnap2Grid(curLayout.getYpos()),
+						roundSnap2Grid(curLayout.getWidth(), true),
+						roundSnap2Grid(curLayout.getHeight(), true));
 			}
 
 			for(Entry<IConnection, KEdge> curEntry : connectionsToKEdges) {
@@ -156,7 +196,8 @@ public class KielerAutoLayouter implements IAutoLayouter {
 				KEdgeLayout curLayout = curEdge.getData(KEdgeLayout.class);
 				for(KPoint k : curLayout.getBendPoints()) {
 					LayoutDataUIUtils.addBendPointToConnection(
-							(ILayoutedModelElement)curConnection, (int)k.getX(), (int)k.getY());
+							(ILayoutedModelElement)curConnection, roundSnap2Grid(k.getX()),
+							roundSnap2Grid(k.getY()));
 				}
 			}
 
@@ -181,7 +222,8 @@ public class KielerAutoLayouter implements IAutoLayouter {
 			KPort p = i.getValue();
 			KNode temp = p.getNode();
 			KShapeLayout lay = temp.getData(KShapeLayout.class);
-			setNodePosition((ILayoutedModelElement)port, (int)lay.getXpos(), (int)lay.getYpos());
+			setNodePosition((ILayoutedModelElement)port, roundSnap2Grid(lay.getXpos()),
+					roundSnap2Grid(lay.getYpos()));
 		}
 	}
 
@@ -214,8 +256,9 @@ public class KielerAutoLayouter implements IAutoLayouter {
 					orientation = EOrientation.SOUTH;
 					break;
 			}
-			LayoutDataUtils.setStickyConnectorLayoutData((ILayoutedModelElement)port, orientation,
-					(int)(portLayout.getYpos()));
+
+			setStickyConnectorLayoutData((ILayoutedModelElement)port, orientation,
+					roundSnap2Grid((portLayout.getYpos())));
 		}
 	}
 
@@ -287,8 +330,9 @@ public class KielerAutoLayouter implements IAutoLayouter {
 
 			int portNmbr = Math.max(inputPorts.size(), outputPorts.size());
 			curLayout.setHeight(Math.max((1 + 2 * portNmbr) * DEFAULT_CONNECTOR_SIZE,
-					dimension.getHeight()));
-			curLayout.setWidth(Math.max(DEFAULT_SHAPE_MINIMUM_HEIGHT, dimension.getWidth()));
+					roundSnap2Grid(dimension.getHeight(), true)));
+			curLayout.setWidth(Math.max(DEFAULT_SHAPE_MINIMUM_HEIGHT,
+					roundSnap2Grid(dimension.getWidth(), true)));
 
 			curKNode.setParent(parentNode);
 			modelElementsToKNodes.put(curElement, curKNode);
-- 
GitLab