/******************************************************************************* * Copyright (c) 2003, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.gef; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.PrecisionPoint; import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.draw2d.geometry.Translatable; /** * A helper used temporarily by Tools for snapping certain mouse interactions. * SnapToHelpers should not be reused by tools or by the editparts which provide * them to the tools. For example, for a move operation, the life-cycle of a SnapToHelper * begins when a drag is initiated, and ends when the drag is over. If another drag is * initiated right after the first one is completed, new SnapToHelpers are employed. This * means that helpers can assume that everything else is static, and there is no need to * track changes outside of the helper. * @since 3.0 * @author Randy Hudson * @author Pratik Shah */ public abstract class SnapToHelper implements PositionConstants { /** * Translates from a given figure to absolute coordinates. * * @param figure the reference figure * @param t the object to translate */ protected void makeAbsolute(IFigure figure, Translatable t) { figure.translateToAbsolute(t); } /** * Translates from absolute to coordinates relative to the given figure. * @param figure the reference figure * @param t the object to translate */ protected void makeRelative(IFigure figure, Translatable t) { figure.translateToRelative(t); } /** * Applies a snapping correction to the given result. Snapping can occur in the four * primary directions: NORTH, SOUTH, EAST, WEST, as defined on {@link PositionConstants}. * By default a Point is treated as an empty Rectangle. Only NORTH and WEST should be used * in general. But SOUTH and EAST may also be used. Similarly, VERTICAL and HORIZONTAL * may be used to allow a point to snap to the "center" or "middle" as defined by the * concrete subclass. * <P> * The returned value should be a subset of the given snapDirections based on what * correction was applied to the result. e.g., if the <b>x</b> value was adjusted, the * returned value should not contain WEST, EAST, or HORIZONTAL. * <P> * All coordinate information received and returned by this method should be in absolute * coordinates. * * @param request a request or <code>null</code> * @param snapDirections the directions in which snapping should occur. * @param where the rectangle used to determine snapping * @param result the result * @return the remaining snap locations */ public int snapPoint(Request request, int snapDirections, PrecisionPoint where, PrecisionPoint result) { PrecisionRectangle rect = new PrecisionRectangle(); PrecisionRectangle resultRect = new PrecisionRectangle(); rect.preciseX = where.preciseX; rect.preciseY = where.preciseY; rect.updateInts(); snapDirections = snapRectangle(request, snapDirections, rect, resultRect); result.preciseX += resultRect.preciseX; result.preciseY += resultRect.preciseY; result.updateInts(); return snapDirections; } /** * A convenience method for snapping a Point based on an array of rectangles. By default, * this method will construct an empty rectangle at the same locations as the provided * point, and call {@link #snapRectangle(Request, int, PrecisionRectangle[], * PrecisionRectangle)}. The intended usage of this method is when dragging one or more * parts in a diagram. * <P> * The returned value should be a subset of the given snapDirections based on what * correction was applied to the result. e.g., if the <b>x</b> value was adjusted, the * returned value should not contain WEST, EAST, or HORIZONTAL. * <P> * All coordinate information received and returned by this method should be in absolute * coordinates. * * @param request the request or <code>null</code> * @param snapLocations the types of snapping to perform * @param rects an array of one or more rectangles used to perform the snapping * @param result the correction will be applied to this point * @return the remaining snap locations */ public int snapPoint(Request request, int snapLocations, PrecisionRectangle rects[], PrecisionPoint result) { PrecisionRectangle resultRect = new PrecisionRectangle(); snapLocations = snapRectangle(request, snapLocations, rects, resultRect); result.preciseX += resultRect.preciseX; result.preciseY += resultRect.preciseY; result.updateInts(); return snapLocations; } /** * A convenience method for snapping a Rectangle based on one or more rectangles. This * method will call {@link #snapRectangle(Request, int, PrecisionRectangle, * PrecisionRectangle)} for each rectangle in the array or until no more snap locations * remain. * <P> * All coordinate information received and returned by this method should be in absolute * coordinates. * * @param request the request or <code>null</code> * @param baseRects the prioritized rectangles to snap to * @param result the output * @param snapOrientation the input snap locations * @return the remaining snap locations */ public int snapRectangle(Request request, int snapOrientation, PrecisionRectangle baseRects[], PrecisionRectangle result) { for (int i = 0; i < baseRects.length && snapOrientation != 0; i++) snapOrientation = snapRectangle(request, snapOrientation, baseRects[i], result); return snapOrientation; } /** * Applies a snap correction to a Rectangle based on a given Rectangle. The provided * baseRect will be used as a reference for snapping. The types of snapping to be * performed are indicated by the snapOrientation parameter. The correction is applied to * the result field. * <P> * The baseRect is not modified. The correction is applied to the result. The request's * {@link Request#getExtendedData() extended data} may contain additional information * about the snapping which was performed. * <P> * All coordinate information received and returned by this method should be in absolute * coordinates. * * @since 3.0 * @param request the request or <code>null</code> * @param baseRect the input rectangle * @param result the correction is applied to this rectangle * @param snapOrientation the input snap locations * @return the remaining snap locations */ public abstract int snapRectangle(Request request, int snapOrientation, PrecisionRectangle baseRect, PrecisionRectangle result); }