/*******************************************************************************
* MontiCore Language Workbench
* Copyright (c) 2015, 2016, MontiCore, All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package de.monticore.genericgraphics.view.figures.connections.locators;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.ConnectionLocator;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
/**
* <p>
* A {@link ConnectionLocator} implementation, that places a figure at the end
* of a connection, either source or target.
* </p>
* <p>
* This figure is moved around the source or target figure of the connection,
* according to the position of the connection.
* </p>
* <p>
* A gap for each side (North, South, East, West) can be set, to adjust to
* possible borders (like ShadowBorder) or similar.<br>
* <br>
* Defaults values for the gaps are:
* <ul>
* <li>North = 1</li>
* <li>East = -2</li>
* <li>South = 5</li>
* <li>West = 2</li>
* </ul>
* </p>
* <p>
* For example: A qualified association from class diagrams.<br>
* The figure of this locator would a simple label with text, used as qualifier.
* <br>
* Using this locator the label would always be positioned at the border of the
* figure.
* </p>
*
* @author Tim Enger
*/
public class EndPointFigureLocator extends ConnectionLocator {
private int northGap = 1;
private int eastGap = -2;
private int southGap = 5;
private int westGap = 2;
private IFigure figure;
/**
* Constructor
*
* @param connection The {@link Connection} this locator should be used for.
* @param align The alignment of the locator. Only if
* {@link ConnectionLocator#SOURCE} and
* {@link ConnectionLocator#TARGET} will change the behavior. If
* {@link ConnectionLocator#MIDDLE} is passed, the default behavior
* of {@link ConnectionLocator} is used.
* @param figure The {@link IFigure} that should be placed at the Endpoint of
* the connection.
*/
public EndPointFigureLocator(Connection connection, int align, IFigure figure) {
super(connection, align);
this.figure = figure;
}
@Override
protected Point getLocation(PointList points) {
// size of figure
Dimension prefsLabel = figure.getPreferredSize();
int lHeight = prefsLabel.height;
int lWidth = prefsLabel.width;
Connection con = getConnection();
Point point;
IFigure fig;
if (getAlignment() == SOURCE) {
ConnectionAnchor sAnchor = con.getSourceAnchor();
fig = sAnchor.getOwner();
if (fig == null) {
return super.getLocation(points);
}
point = points.getPoint(Point.SINGLETON, 0);
}
else {// TARGET:
ConnectionAnchor tAnchor = con.getTargetAnchor();
fig = tAnchor.getOwner();
if (fig == null) {
return super.getLocation(points);
}
point = points.getPoint(Point.SINGLETON, points.size() - 1);
}
Rectangle bounds = fig.getBounds();
switch (PositionUtil.computePosition(bounds, point)) {
case PositionConstants.EAST:
point = new Point(point.x + lWidth / 2 + eastGap, point.y);
break;
case PositionConstants.NORTH:
point = new Point(point.x, point.y - lHeight / 2 + northGap);
break;
case PositionConstants.SOUTH:
point = new Point(point.x, point.y + southGap);
break;
case PositionConstants.WEST:
point = new Point(point.x - lWidth / 2 + westGap, point.y);
break;
}
return point;
}
/**
* @return The eastGap
*/
public int getEastGap() {
return eastGap;
}
/**
* @param eastGap The eastGap to set
*/
public void setEastGap(int eastGap) {
this.eastGap = eastGap;
}
/**
* @return The westGap
*/
public int getWestGap() {
return westGap;
}
/**
* @param westGap The westGap to set
*/
public void setWestGap(int westGap) {
this.westGap = westGap;
}
/**
* @return The northGap
*/
public int getNorthGap() {
return northGap;
}
/**
* @param northGap The northGap to set
*/
public void setNorthGap(int northGap) {
this.northGap = northGap;
}
/**
* @return The southGap
*/
public int getSouthGap() {
return southGap;
}
/**
* @param southGap The southGap to set
*/
public void setSouthGap(int southGap) {
this.southGap = southGap;
}
}