blob: fde4893545a916ed062fc3cedcab1e667e1098d2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2010 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.setPreciseX(where.preciseX());
rect.setPreciseY(where.preciseY());
snapDirections = snapRectangle(request, snapDirections, rect,
resultRect);
result.setPreciseX(result.preciseX() + resultRect.preciseX());
result.setPreciseY(result.preciseY() + resultRect.preciseY());
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.setPreciseX(result.preciseX() + resultRect.preciseX());
result.setPreciseY(result.preciseY() + resultRect.preciseY());
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);
}