diff options
Diffstat (limited to 'plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/DiagramGridSpec.java')
-rw-r--r-- | plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/DiagramGridSpec.java | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/DiagramGridSpec.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/DiagramGridSpec.java new file mode 100644 index 00000000000..885fc7fe7e5 --- /dev/null +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/DiagramGridSpec.java @@ -0,0 +1,144 @@ +package org.eclipse.papyrus.infra.gmfdiag.common.linklf; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PrecisionRectangle; +import org.eclipse.gef.EditPartViewer; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.SnapToGrid; + +/** + * Utility class to compute active grid specification for given edit part viewer. + * <p/> + * Clients may call static methods to compute grid spec once, or may setup listeners + * that will automatically update the active spec when it changed + */ +public class DiagramGridSpec { + + private final EditPartViewer myViewer; + + private PrecisionRectangle myRelativeGridSpec; + + private PrecisionRectangle myAbsoluteGridSpec; + + private final GridSpecListener myGridListener; + + public DiagramGridSpec(EditPartViewer viewer) { + myViewer = viewer; + myGridListener = new GridSpecListener() { + + @Override + public void gridSpecChanged() { + myRelativeGridSpec = null; + myAbsoluteGridSpec = null; + } + }; + myViewer.addPropertyChangeListener(myGridListener); + } + + public void dispose() { + myViewer.removePropertyChangeListener(myGridListener); + myRelativeGridSpec = null; + myAbsoluteGridSpec = null; + } + + /** + * Always returns the same instance to avoid endless creation + * @return active grid specification in absolute coordinates or <code>null</code> if not enabled + */ + public PrecisionRectangle getAbsoluteGridSpec() { + PrecisionRectangle result = getRelativeGridSpec(); + if (result == null) { + return null; + } + + if (myAbsoluteGridSpec == null) { + myAbsoluteGridSpec = new PrecisionRectangle(); + } + myAbsoluteGridSpec.setPreciseBounds(result.preciseX(), result.preciseY(), result.preciseWidth(), result.preciseHeight()); + GraphicalEditPart diagramEP = (GraphicalEditPart) myViewer.getContents(); + diagramEP.getContentPane().translateToAbsolute(myAbsoluteGridSpec); + + return myAbsoluteGridSpec; + } + + private PrecisionRectangle getRelativeGridSpec() { + if (myRelativeGridSpec == null) { + myRelativeGridSpec = getRelativeGridSpec(myViewer); + } + return myRelativeGridSpec; + } + + public EditPartViewer getViewer() { + return myViewer; + } + + /** + * Computes actual grid specification (origin + single cell width and height) in the absolute coordinate system. + * Note, in contrast to {@link #getRelativeGridSpec(EditPartViewer)} this specification depends on the active zoom or scroll + * and can't be cached by clients. + * @param viewer + * @return absolute grid specification, or <code>null</code> if grid is not enabled + */ + public static PrecisionRectangle getAbsoluteGridSpec(EditPartViewer viewer) { + PrecisionRectangle spec = getRelativeGridSpec(viewer); + if (spec != null) { + GraphicalEditPart diagramEP = (GraphicalEditPart) viewer.getContents(); + diagramEP.getContentPane().translateToAbsolute(spec); + } + return spec; + } + + /** + * Computes actual grid specification (origin + single cell width and height) in the coordinates relative + * to the diagram content pane. + * <p/> + * This specification depends only on the grid-relative properties stored in + * the {@link EditPartViewer}, so client may cache it and rely on {@link EditPartViewer#addPropertyChangeListener(PropertyChangeListener)} + * @param viewer + * @return grid specification in the coordinate system relative to diagram content pane, or <code>null</code> if grid is not enabled + */ + private static PrecisionRectangle getRelativeGridSpec(EditPartViewer viewer) { + Boolean enabled = (Boolean) viewer.getProperty(SnapToGrid.PROPERTY_GRID_ENABLED); + if (enabled == null || !enabled) { + return null; + } + double gridX = 0; + double gridY = 0; + Dimension spacing = (Dimension) viewer.getProperty(SnapToGrid.PROPERTY_GRID_SPACING); + if (spacing != null) { + gridX = spacing.preciseWidth(); + gridY = spacing.preciseHeight(); + } + if (gridX <= 0) { + gridX = SnapToGrid.DEFAULT_GRID_SIZE; + } + if (gridY <= 0) { + gridY = SnapToGrid.DEFAULT_GRID_SIZE; + } + Point origin = (Point) viewer.getProperty(SnapToGrid.PROPERTY_GRID_ORIGIN); + PrecisionRectangle result = new PrecisionRectangle(// + origin == null ? 0 : origin.preciseX(), origin == null ? 0 : origin.preciseY(), gridX, gridY); + + return result; + } + + public static abstract class GridSpecListener implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent evt) { + String propertyName = evt.getPropertyName(); + if (SnapToGrid.PROPERTY_GRID_ORIGIN.equals(propertyName) || // + SnapToGrid.PROPERTY_GRID_ENABLED.equals(propertyName) || // + SnapToGrid.PROPERTY_GRID_SPACING.equals(propertyName)) { + + gridSpecChanged(); + } + } + + public abstract void gridSpecChanged(); + }; + +} |