blob: a75465fb6eac23e812fd2d48800f8f287ef47169 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2004, 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.gmf.runtime.diagram.ui.editpolicies;
import org.eclipse.draw2d.FigureListener;
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.Rectangle;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx;
import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities;
import org.eclipse.gmf.runtime.gef.ui.internal.editpolicies.GraphicalEditPolicyEx;
/**
* An EditPolicy that tethers a shape to the connection to which it
* applies. The default style for the tether is <code>Graphics.LINE_DASH</code>
*
* @author jcorchis
*/
public class TetherConnectionEditPolicy
extends GraphicalEditPolicyEx {
private Polyline tether;
private OwnerMovedListener ownerMovedListener = new OwnerMovedListener();
/**
* Returns the tether figure which is a <code>Polyline</code> with the
* given style.
*
* @return the <code>Polyline</code>
* @since 1.2
*/
public Polyline getConnection() {
if (tether == null) {
tether = new PolylineConnectionEx();
tether.setLineStyle(Graphics.LINE_DASH);
}
return tether;
}
/**
* Listens to the owner figure being moved so the tether position can be
* updated when this occurs.
*/
private class OwnerMovedListener
implements FigureListener {
/**
* @see org.eclipse.draw2d.FigureListener#figureMoved(org.eclipse.draw2d.IFigure)
*/
public void figureMoved(IFigure source) {
refresh();
}
}
/**
* Adds the tether upon activation
*/
public void activate() {
super.activate();
addConnection();
((IGraphicalEditPart) getHost()).getFigure().addFigureListener(
ownerMovedListener);
}
/**
* Removes the tether upon deactivation.
*/
public void deactivate() {
((IGraphicalEditPart) getHost()).getFigure().removeFigureListener(
ownerMovedListener);
removeConnection();
super.deactivate();
}
/**
* Removes the tether from the label.
*/
private void removeConnection() {
if (getParentFigure().getChildren().contains(getConnection()))
getParentFigure().remove(getConnection());
}
/**
* Adds the tether
*
*/
private void addConnection() {
if (!getParentFigure().getChildren().contains(getConnection()))
getParentFigure().add(getConnection());
}
/**
* Updates the end-points of the tether based on the figure's position.
*/
public void refresh() {
IFigure figure = ((GraphicalEditPart) getHost()).getFigure();
Rectangle r = figure.getBounds().getCopy();
PointList pl = new PointList();
Point refPoint = new Point();
if (getHost().getParent() instanceof AbstractConnectionEditPart) {
AbstractConnectionEditPart connectionClassEP = (AbstractConnectionEditPart) getHost()
.getParent();
pl = connectionClassEP.getConnectionFigure().getPoints();
refPoint = PointListUtilities.calculatePointRelativeToLine(pl, 0, 50, true);
} else {
refPoint = ((AbstractGraphicalEditPart)getHost().getParent()).getFigure().getBounds().getLocation();
}
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;
getConnection().setStart(startPoint);
getConnection().setEnd(refPoint);
getConnection().setForegroundColor(
((AbstractGraphicalEditPart) getHost().getParent()).getFigure()
.getForegroundColor());
}
/**
* Returns the layer that the tether will be added.
*
* @return the layer that the tether will be added
*/
private IFigure getParentFigure() {
return getHostFigure().getParent();
}
}