blob: d958b3106d310b577f262214b6492926f8f170d4 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2004, 2007 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.diagram.ui.editpolicies;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Polyline;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.NonResizableEditPolicy;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.SetBoundsCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.figures.LabelHelper;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.notation.View;
/**
* Edit policy which supports
*
* @author jcorchis
*/
public class ResizableShapeLabelEditPolicy
extends ResizableShapeEditPolicy {
private Polyline tether = null;
/**
* Removes the tether from the feedback
*
* @see NonResizableEditPolicy#eraseChangeBoundsFeedback(ChangeBoundsRequest)
*/
protected void eraseChangeBoundsFeedback(ChangeBoundsRequest request) {
super.eraseChangeBoundsFeedback(request);
if (tether != null)
removeFeedback(tether);
tether = null;
}
/**
* Add the tether to the feedback
*
* @see NonResizableEditPolicy#createDragSourceFeedbackFigure()
*/
protected IFigure createDragSourceFeedbackFigure() {
IFigure feedback = super.createDragSourceFeedbackFigure();
tether = new Polyline();
tether.setLineStyle(Graphics.LINE_DASHDOT);
tether.setForegroundColor(((IGraphicalEditPart) getHost().getParent())
.getFigure().getForegroundColor());
addFeedback(tether);
return feedback;
}
protected Command getMoveCommand(ChangeBoundsRequest request) {
Point refPoint = getReferencePoint();
// translate the feedback figure
PrecisionRectangle rect = new PrecisionRectangle(
getInitialFeedbackBounds().getCopy());
getHostFigure().translateToAbsolute(rect);
rect.translate(request.getMoveDelta());
rect.resize(request.getSizeDelta());
getHostFigure().translateToRelative(rect);
adjustRect(rect);
Point normalPoint = LabelHelper.offsetFromRelativeCoordinate(
getHostFigure(), rect, refPoint);
TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost())
.getEditingDomain();
ICommand moveCommand = new SetBoundsCommand(editingDomain,
DiagramUIMessages.MoveLabelCommand_Label_Location,
new EObjectAdapter((View) getHost().getModel()), normalPoint);
return new ICommandProxy(moveCommand);
}
/**
* adjust the rectangle used for the move command; the default implementatin
* assumes no behavior, clients can override this function to change
* this behavior
*
* @param rect
* Rect to adjust
*/
protected void adjustRect(PrecisionRectangle rect) {
// do nothing
}
protected void showChangeBoundsFeedback(ChangeBoundsRequest request) {
super.showChangeBoundsFeedback(request);
IFigure p = getDragSourceFeedbackFigure();
Rectangle r = p.getBounds();
Point refPoint = getReferencePoint();
// translate the feedback figure
PrecisionRectangle rect = new PrecisionRectangle(
getInitialFeedbackBounds().getCopy());
getHostFigure().translateToAbsolute(rect);
rect.translate(request.getMoveDelta());
rect.resize(request.getSizeDelta());
p.translateToRelative(rect);
p.setBounds(rect);
// translate the refPoint
PrecisionRectangle ref = new PrecisionRectangle(new Rectangle(
refPoint.x, refPoint.y, 0, 0));
getHostFigure().translateToAbsolute(ref);
p.translateToRelative(ref);
Point midTop = new Point(r.x + r.width / 2, r.y);
Point midBottom = new Point(r.x + r.width / 2, r.y + r.height);
Point midLeft = new Point(r.x, r.y + r.height / 2);
Point midRight = new Point(r.x + r.width, r.y + r.height / 2);
Point startPoint = midTop;
int x = r.x + r.width / 2 - refPoint.x;
int y = r.y + r.height / 2 - refPoint.y;
if (y > 0 && y > x && y > -x)
startPoint = midTop;
else if (y < 0 && y < x && y < -x)
startPoint = midBottom;
else if (x < 0 && y > x && y < -x)
startPoint = midRight;
else
startPoint = midLeft;
tether.setStart(startPoint);
tether.setEnd(ref.getLocation());
}
/**
* @param request
* the resize request
* @return the command contribution obtained from the parent
*/
protected Command getResizeCommand(ChangeBoundsRequest request) {
PrecisionRectangle rect = new PrecisionRectangle(
getInitialFeedbackBounds().getCopy());
getHostFigure().translateToAbsolute(rect);
rect.translate(request.getMoveDelta());
rect.resize(request.getSizeDelta());
getHostFigure().translateToRelative(rect);
View shapeView = (View) getHost().getModel();
TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost())
.getEditingDomain();
Point refPoint = getReferencePoint();
Point normalPoint = LabelHelper.offsetFromRelativeCoordinate(
getHostFigure(), rect, refPoint);
ICommand resizeCommand = new SetBoundsCommand(editingDomain,
DiagramUIMessages.SetLocationCommand_Label_Resize,
new EObjectAdapter(shapeView), new Rectangle(normalPoint, rect
.getSize()));
return new ICommandProxy(resizeCommand);
}
/**
* Helper method to calculate the reference point on the middle of the
* parent edge or the point given by the location of a node.
*
* @return the reference point
*/
private Point getReferencePoint() {
if (getHost().getParent() instanceof AbstractConnectionEditPart) {
PointList ptList = ((AbstractConnectionEditPart) getHost()
.getParent()).getConnectionFigure().getPoints();
return PointListUtilities.calculatePointRelativeToLine(ptList, 0,
50, true);
} else {
return ((GraphicalEditPart) getHost().getParent()).getFigure()
.getBounds().getLocation();
}
}
}