package org.archstudio.bna.utils; import java.awt.geom.Point2D; import java.util.List; import org.archstudio.bna.IBNAWorld; import org.archstudio.bna.IThing; import org.archstudio.bna.constants.GridDisplayType; import org.archstudio.bna.facets.IHasMutableAnchorPoint; import org.archstudio.bna.facets.IHasMutableBoundingBox; import org.archstudio.bna.facets.IHasMutableEndpoints; import org.archstudio.bna.facets.IHasMutableMidpoints; import org.archstudio.bna.facets.IHasMutableReferencePoint; import org.archstudio.bna.facets.IHasMutableSize; import org.archstudio.bna.facets.IHasReferencePoint; import org.archstudio.bna.things.utility.GridThing; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; public class GridUtils { private GridUtils() { } public static void rectifyToGrid(IBNAWorld world) { BNAUtils.checkLock(); int gridSpacing = GridUtils.getGridSpacing(world); if (gridSpacing == 0) { return; } for (IThing t : world.getBNAModel().getAllThings()) { if (t instanceof IHasMutableEndpoints && UserEditableUtils.isEditableForAnyQualities(t, IHasMutableEndpoints.USER_MAY_MOVE_ENDPOINT_1, IHasMutableEndpoints.USER_MAY_MOVE_ENDPOINT_2)) { rectifyToGrid(gridSpacing, (IHasMutableEndpoints) t); } if (t instanceof IHasMutableMidpoints && UserEditableUtils.isEditableForAllQualities(t, IHasMutableMidpoints.USER_MAY_MOVE_MIDPOINTS)) { rectifyToGrid(gridSpacing, (IHasMutableMidpoints) t); } if (t instanceof IHasMutableBoundingBox) { if (UserEditableUtils.isEditableForAllQualities(t, IHasMutableReferencePoint.USER_MAY_MOVE, IHasMutableSize.USER_MAY_RESIZE)) { rectifyToGrid(gridSpacing, (IHasMutableBoundingBox) t); } else if (t instanceof IHasMutableReferencePoint && UserEditableUtils.isEditableForAllQualities(t, IHasMutableReferencePoint.USER_MAY_MOVE)) { Point p = ((IHasReferencePoint) t).getReferencePoint(); ((IHasReferencePoint) t).setReferencePoint(snapToGrid(gridSpacing, p)); } } if (t instanceof IHasMutableAnchorPoint && UserEditableUtils.isEditableForAllQualities(t, IHasMutableReferencePoint.USER_MAY_MOVE)) { rectifyToGrid(gridSpacing, (IHasMutableAnchorPoint) t); } } } private static void rectifyToGrid(int gridSpacing, IHasMutableBoundingBox t) { Rectangle r = t.getBoundingBox(); if (UserEditableUtils.isEditableForAllQualities(t, IHasMutableSize.USER_MAY_RESIZE)) { int x1 = r.x; int y1 = r.y; int x2 = r.x + r.width; int y2 = r.y + r.height; int nx1 = GridUtils.snapToGrid(gridSpacing, x1); int ny1 = GridUtils.snapToGrid(gridSpacing, y1); int nx2 = GridUtils.snapToGrid(gridSpacing, x2); int ny2 = GridUtils.snapToGrid(gridSpacing, y2); if (nx1 == nx2) { nx2 += gridSpacing; } if (ny1 == ny2) { ny2 += gridSpacing; } r.x = nx1; r.y = ny1; r.width = nx2 - nx1; r.height = ny2 - ny1; } t.setBoundingBox(r); } private static void rectifyToGrid(int gridSpacing, IHasMutableEndpoints t) { Point2D ep1 = t.getEndpoint1(); if (UserEditableUtils.isEditableForAllQualities(t, IHasMutableEndpoints.USER_MAY_MOVE_ENDPOINT_1)) { ep1 = GridUtils.snapToGrid(gridSpacing, ep1); } Point2D ep2 = t.getEndpoint2(); if (UserEditableUtils.isEditableForAllQualities(t, IHasMutableEndpoints.USER_MAY_MOVE_ENDPOINT_2)) { ep2 = GridUtils.snapToGrid(gridSpacing, t.getEndpoint2()); } if (Math.abs(ep2.getX() - ep1.getX()) / gridSpacing < 0.5 && Math.abs(ep1.getY() - ep1.getY()) / gridSpacing < 0.5) { if (UserEditableUtils.isEditableForAllQualities(t, IHasMutableEndpoints.USER_MAY_MOVE_ENDPOINT_1)) { ep1.setLocation(ep1.getX() - gridSpacing, ep1.getY() - gridSpacing); } if (UserEditableUtils.isEditableForAllQualities(t, IHasMutableEndpoints.USER_MAY_MOVE_ENDPOINT_2)) { ep2.setLocation(ep2.getX() + gridSpacing, ep2.getY() + gridSpacing); } } t.setEndpoint1(ep1); t.setEndpoint2(ep2); } private static void rectifyToGrid(int gridSpacing, IHasMutableMidpoints t) { List<Point2D> midPoints = t.getMidpoints(); for (int i = 0; i < midPoints.size(); i++) { midPoints.set(i, GridUtils.snapToGrid(gridSpacing, midPoints.get(i))); } t.setMidpoints(midPoints); } private static void rectifyToGrid(int gridSpacing, IHasMutableAnchorPoint t) { t.setAnchorPoint(snapToGrid(gridSpacing, t.getAnchorPoint())); } public static int getGridSpacing(IBNAWorld world) { GridThing gridThing = GridThing.getIn(world); if (gridThing != null) { return gridThing.getGridSpacing(); } return 0; } public static void setGridSpacing(IBNAWorld world, int gridSpacing) { GridThing gridThing = GridThing.createIn(world); if (gridThing != null) { gridThing.setGridSpacing(gridSpacing); } } public static GridDisplayType getGridDisplayType(IBNAWorld world) { GridThing gridThing = GridThing.getIn(world); if (gridThing != null) { return gridThing.getGridDisplayType(); } return GridDisplayType.NONE; } public static void setGridDisplayType(IBNAWorld world, GridDisplayType gdt) { GridThing gridThing = GridThing.createIn(world); if (gridThing != null) { gridThing.setGridDisplayType(gdt); } } public static Point snapToGrid(int gridSpacing, Point p) { if (gridSpacing == 0) { return p; } return new Point(snapToGrid(gridSpacing, p.x), snapToGrid(gridSpacing, p.y)); } private static int snapToGrid(int gridSpacing, int coord) { return (coord + gridSpacing / 2) / gridSpacing * gridSpacing; } public static Point2D snapToGrid(int gridSpacing, Point2D p) { if (gridSpacing == 0) { return p; } return new Point2D.Double(snapToGrid(gridSpacing, p.getX()), snapToGrid(gridSpacing, p.getY())); } private static double snapToGrid(int gridSpacing, double coord) { return Math.round(coord / gridSpacing) * gridSpacing; } }