| /******************************************************************************* |
| * Copyright (c) 2011, 2021 THALES GLOBAL SERVICES and others. |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Obeo - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.sirius.ext.gmf.runtime.editparts; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Objects; |
| import java.util.Optional; |
| |
| import org.eclipse.draw2d.FigureCanvas; |
| import org.eclipse.draw2d.FreeformViewport; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.PointList; |
| import org.eclipse.draw2d.geometry.PrecisionPoint; |
| import org.eclipse.draw2d.geometry.PrecisionRectangle; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.gef.GraphicalEditPart; |
| import org.eclipse.gef.RootEditPart; |
| import org.eclipse.gef.SnapToGrid; |
| import org.eclipse.gef.handles.HandleBounds; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; |
| import org.eclipse.gmf.runtime.draw2d.ui.figures.BaseSlidableAnchor; |
| import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg; |
| import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities; |
| import org.eclipse.gmf.runtime.notation.Anchor; |
| import org.eclipse.gmf.runtime.notation.IdentityAnchor; |
| import org.eclipse.sirius.ext.draw2d.figure.FigureUtilities; |
| import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.IFigureWithoutLabels; |
| |
| /** |
| * Utility class to collect helper methods which deal with GraphicalOrdering but which are not part of its API. |
| * |
| * @author nlepine |
| */ |
| public final class GraphicalHelper { |
| private GraphicalHelper() { |
| // Prevent instantiation. |
| } |
| |
| /** |
| * Get the zoom factor. |
| * |
| * @param part |
| * the current part |
| * @return the zoom factor |
| */ |
| public static double getZoom(EditPart part) { |
| Objects.requireNonNull(part); |
| double scale = 1.0; |
| RootEditPart root = part.getRoot(); |
| if (root instanceof DiagramRootEditPart) { |
| DiagramRootEditPart rootEditPart = (DiagramRootEditPart) root; |
| scale = rootEditPart.getZoomManager().getZoom(); |
| } |
| return scale; |
| } |
| |
| /** |
| * Applied zoom on relative point.<BR> |
| * For example: |
| * <UL> |
| * <LI>For a zoom of 200%, the result of this method for the point (100, 100) is (200, 200)</LI> |
| * <LI>For a zoom of 50%, the result of this method for the point (100, 100) is (50, 50)</LI> |
| * </UL> |
| * |
| * @param part |
| * the current part |
| * @param relativePoint |
| * relative point |
| * @deprecated Use {@link #applyInverseZoomOnPoint(IGraphicalEditPart, Point)} instead |
| */ |
| @Deprecated |
| public static void appliedZoomOnRelativePoint(IGraphicalEditPart part, Point relativePoint) { |
| double zoom = getZoom(part); |
| if (relativePoint instanceof PrecisionPoint) { |
| ((PrecisionPoint) relativePoint).setPreciseLocation(relativePoint.preciseX() / zoom, relativePoint.preciseY() / zoom); |
| } else { |
| relativePoint.setLocation((int) (relativePoint.x * zoom), (int) (relativePoint.y * zoom)); |
| } |
| } |
| |
| /** |
| * Applies zoom on a point and returns this point for convenience.<BR> |
| * For example: |
| * <UL> |
| * <LI>For a zoom of 200%, the result of this method for the point (100, 100) is (200, 200)</LI> |
| * <LI>For a zoom of 50%, the result of this method for the point (100, 100) is (50, 50)</LI> |
| * </UL> |
| * |
| * @param part |
| * the current part |
| * @param point |
| * a point |
| * @return <code>point</code> for convenience |
| */ |
| public static Point applyZoomOnPoint(IGraphicalEditPart part, Point point) { |
| double zoom = getZoom(part); |
| if (point instanceof PrecisionPoint) { |
| ((PrecisionPoint) point).setPreciseLocation(point.preciseX() * zoom, point.preciseY() * zoom); |
| } else { |
| point.setLocation((int) (point.x * zoom), (int) (point.y * zoom)); |
| } |
| return point; |
| } |
| |
| /** |
| * Applies inverse zoom on a point and returns this point for convenience. <BR> |
| * For example: |
| * <UL> |
| * <LI>For a zoom of 200%, the result of this method for the point (100, 100) is (50, 50)</LI> |
| * <LI>For a zoom of 50%, the result of this method for the point (100, 100) is (200, 200)</LI> |
| * </UL> |
| * |
| * @param part |
| * the current part |
| * @param point |
| * a point |
| * @return <code>point</code> for convenience |
| */ |
| public static Point applyInverseZoomOnPoint(IGraphicalEditPart part, Point point) { |
| double zoom = getZoom(part); |
| if (point instanceof PrecisionPoint) { |
| ((PrecisionPoint) point).setPreciseLocation(point.preciseX() / zoom, point.preciseY() / zoom); |
| } else { |
| point.setLocation((int) (point.x / zoom), (int) (point.y / zoom)); |
| } |
| return point; |
| } |
| |
| /** |
| * Set the zoom factor. |
| * |
| * @param part |
| * the current part |
| * @param scale |
| * the zoom factor |
| */ |
| public static void setZoom(IGraphicalEditPart part, double scale) { |
| Objects.requireNonNull(part); |
| RootEditPart root = part.getRoot(); |
| if (root instanceof DiagramRootEditPart) { |
| DiagramRootEditPart rootEditPart = (DiagramRootEditPart) root; |
| rootEditPart.getZoomManager().setZoom(scale); |
| } |
| } |
| |
| /** |
| * Returns the difference between the logical origin (0, 0) and the top-left point actually visible. This |
| * corresponds to how much the scrollbars "shift" the diagram. |
| * |
| * @param part |
| * an edit part on the view |
| * @return the scroll size |
| */ |
| public static Point getScrollSize(GraphicalEditPart part) { |
| Objects.requireNonNull(part); |
| FreeformViewport viewport = FigureUtilities.getRootFreeformViewport(part.getFigure()); |
| if (viewport != null) { |
| return viewport.getViewLocation(); |
| } else { |
| return new Point(0, 0); |
| } |
| } |
| |
| /** |
| * Returns the difference between the logical origin (0, 0) and the top-left point actually visible. This |
| * corresponds to how much the scrollbars "shift" the successive containers. |
| * |
| * @param part |
| * an edit part on the view |
| * @return the scroll size |
| */ |
| protected static Point getContainerScrollSize(GraphicalEditPart part) { |
| Objects.requireNonNull(part); |
| Point result = new Point(0, 0); |
| Point diagramScrollSize = new Point(0, 0); |
| |
| IFigure current = part.getFigure(); |
| FreeformViewport rootFreeformViewport = null; |
| while (current != null) { |
| if (current instanceof FreeformViewport) { |
| rootFreeformViewport = (FreeformViewport) current; |
| diagramScrollSize = rootFreeformViewport.getViewLocation(); |
| result.translate(diagramScrollSize); |
| } |
| current = current.getParent(); |
| } |
| result.translate(diagramScrollSize.negate()); |
| return result; |
| } |
| |
| /** |
| * . |
| * |
| * @param part |
| * an edit part on the view |
| * @param scrollPosition |
| * the scroll size |
| */ |
| public static void setScrollSize(IGraphicalEditPart part, Point scrollPosition) { |
| Objects.requireNonNull(part); |
| // FreeformViewport viewport = |
| // FigureUtilities.getFreeformViewport(part.getFigure()); |
| // if (viewport != null) { |
| // viewport.setLocation(scrollPosition); |
| // } |
| if (part.getViewer().getControl() instanceof FigureCanvas) { |
| // UIThreadRunnable.syncExec(new VoidResult() { |
| // public void run() { |
| ((FigureCanvas) part.getViewer().getControl()).scrollTo(scrollPosition.x, scrollPosition.y); |
| // } |
| // }); |
| } |
| } |
| |
| /** |
| * Converts a point from screen coordinates to logical coordinates. |
| * |
| * @param point |
| * the point to convert. |
| * @param part |
| * a part from the diagram. |
| */ |
| public static void screen2logical(Point point, GraphicalEditPart part) { |
| point.translate(GraphicalHelper.getScrollSize(part)); |
| point.performScale(1.0d / GraphicalHelper.getZoom(part)); |
| } |
| |
| /** |
| * Converts a rectangle from screen coordinates to logical coordinates. |
| * |
| * @param rect |
| * the rectangle to convert. |
| * @param part |
| * a part from the diagram. |
| */ |
| public static void screen2logical(Rectangle rect, GraphicalEditPart part) { |
| screen2logical(rect, part, false); |
| } |
| |
| /** |
| * Converts a rectangle from screen coordinates to logical coordinates. |
| * |
| * @param rect |
| * the rectangle to convert. |
| * @param part |
| * a part from the diagram. |
| * @param considerAllScroll |
| * In all cases, the scroll of the diagram is used, but the scroll of containers are considered only if |
| * this parameter is true. |
| */ |
| protected static void screen2logical(Rectangle rect, GraphicalEditPart part, boolean considerAllScroll) { |
| double zoom = GraphicalHelper.getZoom(part); |
| if (considerAllScroll) { |
| rect.translate(GraphicalHelper.getContainerScrollSize(part).scale(zoom)); |
| } |
| rect.translate(GraphicalHelper.getScrollSize(part)); |
| rect.performScale(1.0d / zoom); |
| } |
| |
| /** |
| * Converts a dimension from screen coordinates to logical coordinates. Dimensions have no defined position, so only |
| * the current zoom level is take into account, not the scroll state. |
| * |
| * @param dim |
| * the dimension to convert. |
| * @param part |
| * a part from the diagram. |
| */ |
| public static void screen2logical(Dimension dim, IGraphicalEditPart part) { |
| dim.performScale(1.0d / GraphicalHelper.getZoom(part)); |
| } |
| |
| /** |
| * Converts a point from logical coordinates to screen coordinates. |
| * |
| * @param point |
| * the point to convert. |
| * @param part |
| * a part from the diagram. |
| */ |
| public static void logical2screen(Point point, IGraphicalEditPart part) { |
| point.performScale(GraphicalHelper.getZoom(part)); |
| point.translate(GraphicalHelper.getScrollSize(part).negate()); |
| } |
| |
| /** |
| * Converts a rectangle from logical coordinates to screen coordinates. |
| * |
| * @param rect |
| * the rectangle to convert. |
| * @param part |
| * a part from the diagram. |
| */ |
| public static void logical2screen(Rectangle rect, IGraphicalEditPart part) { |
| rect.performScale(GraphicalHelper.getZoom(part)); |
| rect.translate(GraphicalHelper.getScrollSize(part).negate()); |
| } |
| |
| /** |
| * Converts a dimension from logical coordinates to screen coordinates. Dimensions have no defined position, so only |
| * the current zoom level is take into account, not the scroll state. |
| * |
| * @param dim |
| * the dimension to convert. |
| * @param part |
| * a part from the diagram. |
| */ |
| public static void logical2Screen(Dimension dim, IGraphicalEditPart part) { |
| dim.performScale(GraphicalHelper.getZoom(part)); |
| } |
| |
| /** |
| * Return the Point (absolute draw2d coordinates) corresponding to this Anchor. If anchor is not an IdentityAnchor, |
| * the center of <code>parent</code> is returned. |
| * |
| * @param parent |
| * The parent node |
| * @param anchor |
| * The anchor |
| * @return The corresponding point to this anchor |
| */ |
| public static Point getAnchorPoint(GraphicalEditPart parent, Anchor anchor) { |
| if (anchor instanceof IdentityAnchor) { |
| return getAnchorPoint(parent, (IdentityAnchor) anchor); |
| } else { |
| return getAnchorPoint(parent, null); |
| } |
| } |
| |
| /** |
| * Return the Point (absolute draw2d coordinates) corresponding to this Anchor. If anchor is null, the center of |
| * <code>parent</code> is returned. |
| * |
| * @param parent |
| * The parent node |
| * @param anchor |
| * The anchor |
| * @return The corresponding point to this anchor |
| */ |
| public static Point getAnchorPoint(GraphicalEditPart parent, IdentityAnchor anchor) { |
| PrecisionRectangle bounds; |
| if (parent.getFigure() instanceof HandleBounds) { |
| bounds = new PrecisionRectangle(((HandleBounds) parent.getFigure()).getHandleBounds()); |
| } else { |
| bounds = new PrecisionRectangle(parent.getFigure().getBounds()); |
| } |
| parent.getFigure().translateToAbsolute(bounds); |
| screen2logical(bounds, parent); |
| |
| PrecisionPoint rel; |
| if (anchor != null) { |
| rel = BaseSlidableAnchor.parseTerminalString(anchor.getId()); |
| } else { |
| // If anchor is null, the default value is (0.5, 0.5) |
| rel = new PrecisionPoint(0.5, 0.5); |
| } |
| Point location = new PrecisionPoint(bounds.preciseX() + bounds.preciseWidth() * rel.preciseX(), bounds.preciseY() + bounds.preciseHeight() * rel.preciseY()); |
| return location; |
| } |
| |
| /** |
| * Get intersection between a line between lineOrigin and lineTerminus, and the rectangle bounds of the part. If |
| * there are several intersections, the shortest is returned. |
| * |
| * @param lineOrigin |
| * Origin of the line |
| * @param lineTerminus |
| * Terminus of the line |
| * @param part |
| * Part to detect intersection. |
| * @param minimalDistancefromLineOrigin |
| * true if the shortest distance is between the line origin and the part, false otherwise. |
| * @return Intersection between a line and a rectangle. |
| */ |
| public static Optional<Point> getIntersection(Point lineOrigin, Point lineTerminus, IGraphicalEditPart part, boolean minimalDistancefromLineOrigin) { |
| return getIntersection(lineOrigin, lineTerminus, part, minimalDistancefromLineOrigin, false); |
| } |
| |
| /** |
| * Get intersection between a line between lineOrigin and lineTerminus, and the rectangle bounds of the part. If |
| * there are several intersections, the shortest is returned. |
| * |
| * @param lineOrigin |
| * Origin of the line |
| * @param lineTerminus |
| * Terminus of the line |
| * @param part |
| * Part to detect intersection. |
| * @param minimalDistancefromLineOrigin |
| * true if the shortest distance is between the line origin and the part, false otherwise. |
| * @param useNearestPoint |
| * If true, if there is no intersection, the nearest point on the rectangle is returned. |
| * @return Intersection between a line and a rectangle. |
| */ |
| public static Optional<Point> getIntersection(Point lineOrigin, Point lineTerminus, IGraphicalEditPart part, boolean minimalDistancefromLineOrigin, boolean useNearestPoint) { |
| // Get the bounds of the part |
| Rectangle bounds = getAbsoluteBoundsIn100Percent(part); |
| return getIntersection(lineOrigin, lineTerminus, bounds, minimalDistancefromLineOrigin, useNearestPoint); |
| } |
| |
| /** |
| * Get intersection between a line between lineOrigin and lineTerminus, and a rectangle. If there are several |
| * intersections, the shortest is returned. |
| * |
| * @param lineOrigin |
| * Origin of the line |
| * @param lineTerminus |
| * Terminus of the line |
| * @param rectangle |
| * rectangle to detect intersection. |
| * @param minimalDistancefromLineOrigin |
| * true if the shortest distance is between the line origin and the part, false otherwise. |
| * @return Intersection between a line and a rectangle. |
| */ |
| public static Optional<Point> getIntersection(Point lineOrigin, Point lineTerminus, Rectangle rectangle, boolean minimalDistancefromLineOrigin) { |
| return getIntersection(lineOrigin, lineTerminus, rectangle, minimalDistancefromLineOrigin, false); |
| } |
| |
| /** |
| * Get intersection between a line between lineOrigin and lineTerminus, and a rectangle. If there are several |
| * intersections, the shortest is returned. |
| * |
| * @param lineOrigin |
| * Origin of the line |
| * @param lineTerminus |
| * Terminus of the line |
| * @param rectangle |
| * rectangle to detect intersection. |
| * @param minimalDistancefromLineOrigin |
| * true if the shortest distance is between the line origin and the part, false otherwise. |
| * @param useNearestPoint |
| * If true, if there is no intersection, the nearest point on the rectangle is returned. |
| * @return Intersection between a line and a rectangle. |
| */ |
| public static Optional<Point> getIntersection(Point lineOrigin, Point lineTerminus, Rectangle rectangle, boolean minimalDistancefromLineOrigin, boolean useNearestPoint) { |
| Optional<Point> result = Optional.empty(); |
| // Create the line segment |
| PointList line = new PointList(); |
| line.addPoint(lineOrigin); |
| line.addPoint(lineTerminus); |
| // Get the intersection |
| PointList partBoundsPointList = PointListUtilities.createPointsFromRect(rectangle); |
| PointList distances = new PointList(); |
| PointList intersections = new PointList(); |
| PointListUtilities.findIntersections(line, partBoundsPointList, intersections, distances); |
| |
| Point oppositePoint; |
| if (minimalDistancefromLineOrigin) { |
| oppositePoint = lineOrigin; |
| } else { |
| oppositePoint = lineTerminus; |
| } |
| if (intersections.size() > 0) { |
| Point shortestPoint = intersections.getFirstPoint(); |
| double minimalDistance = shortestPoint.getDistance(oppositePoint); |
| for (int i = 1; i < intersections.size(); i++) { |
| Point intersectionPoint = intersections.getPoint(i); |
| double currentDistance = intersectionPoint.getDistance(oppositePoint); |
| if (currentDistance < minimalDistance) { |
| minimalDistance = currentDistance; |
| shortestPoint = intersectionPoint; |
| } |
| } |
| result = Optional.of(shortestPoint); |
| } else if (!lineOrigin.equals(lineTerminus) && useNearestPoint) { |
| // If no intersection is found and the origin is not the terminus, |
| // the origin (or the terminus) is outside the rectangle, probably |
| // because of the snap, so we search the nearest point on the figure |
| // respecting one of the x or y coordinate. |
| Point linePointToConsider; |
| if (minimalDistancefromLineOrigin) { |
| linePointToConsider = lineTerminus; |
| } else { |
| linePointToConsider = lineOrigin; |
| } |
| |
| List<Point> nearestPoints = findNearestPoints(partBoundsPointList, linePointToConsider); |
| if (nearestPoints.size() > 0) { |
| double minimalDistance = -1; |
| Point resultPoint = null; |
| // Search the closest intersection |
| for (Point nearestPoint : nearestPoints) { |
| double distance = nearestPoint.getDistance(oppositePoint); |
| if (minimalDistance == -1 || distance < minimalDistance) { |
| minimalDistance = distance; |
| resultPoint = nearestPoint; |
| } |
| } |
| result = Optional.ofNullable(resultPoint); |
| } |
| |
| } |
| return result; |
| } |
| |
| private static List<Point> findNearestPoints(PointList partBoundsPointList, Point linePointToConsider) { |
| List<Point> nearestPoints = new ArrayList<>(); |
| List<?> rectangleBorders = PointListUtilities.getLineSegments(partBoundsPointList); |
| for (Object rectangleBorder : rectangleBorders) { |
| if (rectangleBorder instanceof LineSeg) { |
| LineSeg lineSeg = (LineSeg) rectangleBorder; |
| Point potentialNearestPoint; |
| if (lineSeg.getOrigin().x == lineSeg.getTerminus().x) { |
| potentialNearestPoint = new Point(lineSeg.getOrigin().x, linePointToConsider.y); |
| } else { |
| potentialNearestPoint = new Point(linePointToConsider.x, lineSeg.getOrigin().y); |
| } |
| if (lineSeg.containsPoint(potentialNearestPoint, 0)) { |
| nearestPoints.add(potentialNearestPoint); |
| } |
| } |
| } |
| return nearestPoints; |
| } |
| |
| /** |
| * Get the intersection point list between the segment formed by the start and end points and the given figure |
| * bounds. |
| * |
| * @param start |
| * start point |
| * @param end |
| * end point |
| * @param figureBounds |
| * the figure bounds. |
| * @return the intersection point list. |
| */ |
| public static PointList getIntersectionPoints(Point start, Point end, Rectangle figureBounds) { |
| PointList intersection = new PointList(); |
| final PointList polygon = PointListUtilities.createPointsFromRect(figureBounds); |
| LineSeg lineSeg = new LineSeg(start, end); |
| PointList intersectionTemp = lineSeg.getLineIntersectionsWithLineSegs(polygon); |
| for (int i = 0; i < intersectionTemp.size(); i++) { |
| Point currentPoint = intersectionTemp.getPoint(i); |
| if (lineSeg.containsPoint(currentPoint, 1)) { |
| intersection.addPoint(currentPoint); |
| } |
| } |
| return intersection; |
| } |
| |
| /** |
| * Get the absolute bounds of this <code>part</code>.<BR> |
| * Detail: If the zoom is set to 200%, the location and the size are multiplied by two with respect to the real |
| * location and size. |
| * |
| * @param part |
| * The part to consider. |
| * @return The absolute bounds. |
| */ |
| public static Rectangle getAbsoluteBounds(IGraphicalEditPart part) { |
| PrecisionRectangle bounds; |
| if (part.getFigure() instanceof HandleBounds) { |
| bounds = new PrecisionRectangle(((HandleBounds) part.getFigure()).getHandleBounds()); |
| } else { |
| bounds = new PrecisionRectangle(part.getFigure().getBounds()); |
| } |
| part.getFigure().translateToAbsolute(bounds); |
| return bounds; |
| } |
| |
| /** |
| * Get the absolute bounds of this <code>part</code>. In case of zoom or/and a scrollbar, the bounds are converted |
| * from screen to logical.<BR> |
| * |
| * @param part |
| * The part to consider. |
| * @return The absolute bounds. |
| */ |
| public static Rectangle getAbsoluteBoundsIn100Percent(GraphicalEditPart part) { |
| return getAbsoluteBoundsIn100Percent(part, false); |
| } |
| |
| /** |
| * Get the absolute bounds of this <code>part</code>. In case of zoom or/and scrollbars, the bounds are converted |
| * from screen to logical.<BR> |
| * |
| * @param part |
| * The part to consider. |
| * @param considerAllScroll |
| * In all cases, the scroll of the diagram is used, but the scroll of containers are considered only if |
| * this parameter is true. |
| * @return The absolute bounds. |
| */ |
| public static Rectangle getAbsoluteBoundsIn100Percent(GraphicalEditPart part, boolean considerAllScroll) { |
| PrecisionRectangle bounds; |
| if (part.getFigure() instanceof HandleBounds) { |
| bounds = new PrecisionRectangle(((HandleBounds) part.getFigure()).getHandleBounds()); |
| } else { |
| bounds = new PrecisionRectangle(part.getFigure().getBounds()); |
| } |
| part.getFigure().translateToAbsolute(bounds); |
| screen2logical(bounds, part, considerAllScroll); |
| return bounds; |
| } |
| |
| /** |
| * Get the absolute bounds of this <code>part</code> by excluding labels from the bounds.<br/> |
| * In case of zoom or/and scrollbars, the bounds are converted from screen to logical.<BR> |
| * |
| * @param part |
| * The part to consider. |
| * @return The absolute bounds. |
| */ |
| public static Rectangle getAbsoluteBoundsWithoutLabelsIn100Percent(GraphicalEditPart part) { |
| PrecisionRectangle bounds; |
| if (part.getFigure() instanceof IFigureWithoutLabels) { |
| bounds = new PrecisionRectangle(((IFigureWithoutLabels) part.getFigure()).getBoundsWithoutLabels()); |
| part.getFigure().translateToAbsolute(bounds); |
| screen2logical(bounds, part, false); |
| } else { |
| bounds = new PrecisionRectangle(getAbsoluteBoundsIn100Percent(part)); |
| } |
| return bounds; |
| } |
| |
| /** |
| * Return true if the snapToGrid is enabled for the diagram containing this edit part, false otherwise. |
| * |
| * @param editPart |
| * The edit part to use. |
| * @return true if the snapToGrid is enabled for the diagram containing this edit part, false otherwise. |
| */ |
| public static boolean isSnapToGridEnabled(EditPart editPart) { |
| return (Boolean) editPart.getViewer().getProperty(SnapToGrid.PROPERTY_GRID_ENABLED); |
| } |
| |
| /** |
| * Return the grid spacing in pixels for the diagram containing this edit part. |
| * |
| * @param editPart |
| * The edit part to use. |
| * @return the grid spacing in pixels. |
| */ |
| public static int getGridSpacing(EditPart editPart) { |
| return ((Dimension) editPart.getViewer().getProperty(SnapToGrid.PROPERTY_GRID_SPACING)).width; |
| } |
| } |