blob: 6b54c1bb38b68d5f508d4a3e9763b33c6eff4f4c [file] [log] [blame]
package org.eclipse.gmf.tooling.runtime.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();
};
}