blob: 24d5339e74745f25c1732d865a6adbbc6c5cc29c [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2009 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.gmf.runtime.gef.ui.internal.figures;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Locator;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.handles.HandleBounds;
/**
* This locator places the figure relative to the reference figure's edge
* (where the reference figure's edge is the same as where the resize/move
* handles would be placed).
* There are three options available for controlling where the figure is
* placed:
* <ol>
* <li>direction - A direction to place the figure relative to the reference
* figure as defined in {@link PositionConstants}
* <li>margin - The margin is the space between the reference figure's edge
* and the figure. A positive margin will place the figure outside the
* reference figure, a negative margin will place the figure inside the
* reference figure.
* </ol>
*
* NOTE: This locator uses the size of the figure to calculate where it should
* be placed. Therefore it may be necessary to explicitly set this figure's
* size.
*
* @author cmahoney
*/
public class RelativeToBorderLocator implements Locator {
/** the margin to leave by the edge of the parent figure */
private int margin;
/** the direction */
protected int direction;
/** the parent figure */
protected IFigure reference;
/**
* Constructor for <code>RelativeToBorderLocator</code>.
*
* @param reference the parent figure
* @param direction A direction to place the figure relative to the reference
* figure as defined in {@link PositionConstants}
* @param margin The margin is the space between the reference figure's edge
* and the figure. A positive margin will place the figure outside the
* reference figure, a negative margin will place the figure inside the
* reference figure.
*/
public RelativeToBorderLocator(
IFigure reference,
int direction,
int margin) {
this.reference = reference;
this.direction = direction;
this.margin = margin;
}
/**
* Puts the figure either inside or outside the parent edge (where the edge
* is the same as where the resize/move handles would be placed),
* identified by the direction, with a margin.
*
* @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigure)
*/
public void relocate(IFigure target) {
Rectangle bounds =
reference instanceof HandleBounds
? new PrecisionRectangle(((HandleBounds) reference).getHandleBounds())
: new PrecisionRectangle(reference.getBounds());
reference.translateToAbsolute(bounds);
target.translateToRelative(bounds);
int width = target.getBounds().width;
int halfWidth = width / 2;
int height = target.getBounds().height;
int halfHeight = height / 2;
if (direction == PositionConstants.CENTER) {
Dimension shift = new Dimension(-halfWidth, -halfHeight);
target.setLocation(bounds.getCenter().getTranslated(shift));
} else if (margin < 0) {
if (direction == PositionConstants.NORTH_WEST) {
Dimension shift = new Dimension(-margin, -margin);
target.setLocation(bounds.getTopLeft().getTranslated(shift));
} else if (direction == PositionConstants.NORTH) {
Dimension shift = new Dimension(-halfWidth, -margin);
target.setLocation(bounds.getTop().getTranslated(shift));
} else if (direction == PositionConstants.NORTH_EAST) {
Dimension shift = new Dimension(-(width + -margin), -margin);
target.setLocation(bounds.getTopRight().getTranslated(shift));
} else if (direction == PositionConstants.SOUTH_WEST) {
Dimension shift = new Dimension(-margin, -(height + -margin));
target.setLocation(bounds.getBottomLeft().getTranslated(shift));
} else if (direction == PositionConstants.SOUTH) {
Dimension shift = new Dimension(-halfWidth, -(height + -margin));
target.setLocation(bounds.getBottom().getTranslated(shift));
} else if (direction == PositionConstants.SOUTH_EAST) {
Dimension shift = new Dimension(-(width + -margin),
-(height + -margin));
target
.setLocation(bounds.getBottomRight().getTranslated(shift));
} else if (direction == PositionConstants.WEST) {
Dimension shift = new Dimension(-margin, -halfHeight);
target.setLocation(bounds.getLeft().getTranslated(shift));
} else if (direction == PositionConstants.EAST) {
Dimension shift = new Dimension(-(width + -margin), -halfHeight);
target.setLocation(bounds.getRight().getTranslated(shift));
}
} else {
if (direction == PositionConstants.NORTH_WEST) {
Dimension shift =
new Dimension(- (width + margin), - (height + margin));
target.setLocation(bounds.getTopLeft().getTranslated(shift));
} else if (direction == PositionConstants.NORTH) {
Dimension shift =
new Dimension(-halfWidth, - (height + margin));
target.setLocation(bounds.getTop().getTranslated(shift));
} else if (direction == PositionConstants.NORTH_EAST) {
Dimension shift = new Dimension(margin, - (height + margin));
target.setLocation(bounds.getTopRight().getTranslated(shift));
} else if (direction == PositionConstants.SOUTH_WEST) {
Dimension shift = new Dimension(- (width + margin), margin);
target.setLocation(bounds.getBottomLeft().getTranslated(shift));
} else if (direction == PositionConstants.SOUTH) {
Dimension shift = new Dimension(-halfWidth, margin);
target.setLocation(bounds.getBottom().getTranslated(shift));
} else if (direction == PositionConstants.SOUTH_EAST) {
Dimension shift = new Dimension(margin, margin);
target.setLocation(
bounds.getBottomRight().getTranslated(shift));
} else if (direction == PositionConstants.WEST) {
Dimension shift =
new Dimension(- (width + margin), -halfHeight);
target.setLocation(bounds.getLeft().getTranslated(shift));
} else if (direction == PositionConstants.EAST) {
Dimension shift = new Dimension(margin, -halfHeight);
target.setLocation(bounds.getRight().getTranslated(shift));
}
}
}
}