Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » GEF » Draw2D & GEF: qualified associations
Draw2D & GEF: qualified associations [message #1005682] Mon, 28 January 2013 09:15 Go to next message
Tim E. is currently offline Tim E.Friend
Messages: 56
Registered: November 2012
Member
Hi,

I've got a new problem, and cannot think of a good idea.

I need to draw qualified associations, as they can be seen in this picture (itemID)
http://www.informit.com/content/images/ch16_9780131489066/elementLinks/16fig15.jpg

The user is able to move around classes and connections (with bendpoints) and thus the position of the "qualifier" is also not fixed.
So it needs to be moveable.

I thought of using ConnectionDecorator and a label,
but it does not really work, since the gap on top of a class if different from the gap on the side of a class.

I'd appreciate any help, ideas, hints....

Thanks in advance,
Tim
Re: Draw2D & GEF: qualified associations [message #1009513 is a reply to message #1005682] Fri, 15 February 2013 09:03 Go to previous message
Tim E. is currently offline Tim E.Friend
Messages: 56
Registered: November 2012
Member
Just to help people with the same problem, here is my solution by extending the ConnectionLocator class. May not be the best solution, but at least it is one Smile

public class EndPointFigureLocator extends ConnectionLocator {
  
  private enum POSITION {
    NORTH, EAST, SOUTH, WEST;
  }
  
  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();
    
    switch (getAlignment()) {
      case SOURCE:
        ConnectionAnchor sAnchor = con.getSourceAnchor();
        IFigure fig = sAnchor.getOwner();
        if (fig == null) {
          return super.getLocation(points);
        }
        Rectangle bounds = fig.getBounds();
        
        Point point = points.getPoint(Point.SINGLETON, 0);
        switch (computePosition(bounds, point)) {
          case EAST:
            point = new Point(point.x + lWidth / 2 - 4, point.y);
            break;
          case NORTH:
            point = new Point(point.x, point.y - lHeight / 2);
            break;
          case SOUTH:
            point = new Point(point.x, point.y + 2);
            break;
          case WEST:
            point = new Point(point.x - lWidth / 2 + 2, point.y);
            break;
        }
        return point;
      case TARGET:
        ConnectionAnchor tAnchor = con.getTargetAnchor();
        fig = tAnchor.getOwner();
        if (fig == null) {
          return super.getLocation(points);
        }
        bounds = fig.getBounds();
        
        point = points.getPoint(Point.SINGLETON, points.size() - 1);
        switch (computePosition(bounds, point)) {
          case EAST:
            point = new Point(point.x + lWidth / 2 - 4, point.y);
            break;
          case NORTH:
            point = new Point(point.x, point.y - lHeight / 2);
            break;
          case SOUTH:
            point = new Point(point.x, point.y + 2);
            break;
          case WEST:
            point = new Point(point.x - lWidth / 2 + 2, point.y);
            break;
        }
        return point;
      case MIDDLE:
        if (points.size() % 2 == 0) {
          int i = points.size() / 2;
          int j = i - 1;
          Point p1 = points.getPoint(j);
          Point p2 = points.getPoint(i);
          Dimension d = p2.getDifference(p1);
          return Point.SINGLETON.setLocation(p1.x + d.width / 2, p1.y + d.height / 2);
        }
        int i = (points.size() - 1) / 2;
        return points.getPoint(Point.SINGLETON, i);
      default:
        return new Point();
    }
  }
  
  private POSITION computePosition(Rectangle figBounds, Point location) {
    int figX = figBounds.x;
    int figY = figBounds.y;
    int figH = figBounds.height;
    int figW = figBounds.width;
    
    int locX = location.x;
    int locY = location.y;
    
    if (locX >= figX && locY <= figY) {
      return POSITION.NORTH;
    }
    if (locX >= figX && locY >= figY + figH) {
      return POSITION.SOUTH;
    }
    if (locX <= figX && locY >= figY) {
      return POSITION.WEST;
    }
    if (locX >= figX + figW && locY >= figY) {
      return POSITION.EAST;
    }
    
    // special case, this is the top left corner
    if (locX < figX && locY < figY) {
      return POSITION.NORTH;
    }
    
    return null;
  }
Previous Topic:[Zest] Maintaining order of leaves in SpaceTreeLayout
Next Topic:enforce node position n gridlayout
Goto Forum:
  


Current Time: Sun Dec 21 06:27:32 GMT 2014

Powered by FUDForum. Page generated in 0.01833 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software