| /******************************************************************************* |
| * Copyright 2005-2006, CHISEL Group, University of Victoria, Victoria, BC, |
| * Canada. 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: The Chisel Group, University of Victoria |
| *******************************************************************************/ |
| package org.eclipse.zest.core.widgets.internal; |
| |
| import org.eclipse.draw2d.AbstractLocator; |
| import org.eclipse.draw2d.Connection; |
| 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; |
| |
| /** |
| * A locator that finds the middle of a connection based on the bendpoints. |
| * @author Del Myers |
| * |
| */ |
| //@tag zest(bug(154391-ArcEnds(fix))) : use this locator to ensure that labels will be in the middle of connections. |
| //@tag zest.bug.160368-ConnectionAlign : replaces MidBenpointLocator in order to have finer control over alignment. |
| public class AligningBendpointLocator extends AbstractLocator { |
| /** |
| * "Vertical" alignment contstant. Figures should be placed in the middle |
| * of the line. |
| */ |
| public static final int MIDDLE = 0; |
| /** |
| * "Vertical" alignment constant. Figures should be placed above the line. |
| */ |
| public static final int ABOVE = 1; |
| /** |
| * "Vertical" alignment constant. Figures should be placed below the line. |
| */ |
| public static final int BELOW = 2; |
| |
| /** |
| * "Horizontal" alignment constant. Figures should be placed in the center |
| * of the points on the line. |
| */ |
| public static final int CENTER = 0; |
| |
| /** |
| * "Horizontal" alignment constant. Figures should be placed at the beginning |
| * of the line. Figures will be anchored so that they have one end at the |
| * beginning of the connection, not so that they are centered at the start |
| * point. Which end of the figure is placed at that point will depend |
| * on the direction of the first two points. |
| */ |
| public static final int BEGINNING = 1; |
| |
| /** |
| * "Horizontal" alignment constant. Figures should be placed at the end of |
| * the line. Figures will be anchored so that they have one end at the |
| * beginning of the connection, not so that they are centered at the end |
| * point. Which end of the figure is placed at that point will depend |
| * on the direction of the last two points. |
| */ |
| public static final int END = 2; |
| |
| /** |
| * "Horizontal" alignment constant. Figures should be centered between the |
| * first two points on the connection. For connections with only two points, |
| * this will behave the same as CENTER. |
| */ |
| public static final int CENTER_BEGINNING = 3; |
| |
| /** |
| * "Horizontal" alignment constant. Figures should be centered between the |
| * last two points on the connection. For connections with only two points, |
| * this will behave the same as CENTER. |
| */ |
| public static final int CENTER_END = 4; |
| private int horizontal; |
| private int vertical; |
| private Connection connection; |
| |
| /** |
| * @param connection |
| */ |
| public AligningBendpointLocator(Connection connection) { |
| this(connection, CENTER, MIDDLE); |
| } |
| |
| public AligningBendpointLocator(Connection connection, int horizontal, int vertical) { |
| this.connection = connection; |
| this.horizontal = horizontal; |
| this.vertical = vertical; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.draw2d.ConnectionLocator#getReferencePoint() |
| */ |
| protected Point getReferencePoint() { |
| PointList points = getConnection().getPoints(); |
| Point p = points.getMidpoint().getCopy(); |
| PointList tempPoints = new PointList(); |
| switch (horizontal) { |
| case BEGINNING: |
| p = points.getFirstPoint().getCopy(); |
| break; |
| case END: |
| p = points.getLastPoint().getCopy(); |
| break; |
| case CENTER_BEGINNING: |
| tempPoints.addPoint(points.getFirstPoint().getCopy()); |
| tempPoints.addPoint(points.getPoint(1).getCopy()); |
| p = tempPoints.getMidpoint().getCopy(); |
| break; |
| case CENTER_END: |
| tempPoints = new PointList(); |
| int s = points.size(); |
| tempPoints.addPoint(points.getLastPoint().getCopy()); |
| tempPoints.addPoint(points.getPoint(s - 2).getCopy()); |
| p = tempPoints.getMidpoint().getCopy(); |
| case CENTER: |
| default: |
| p = points.getMidpoint().getCopy(); |
| } |
| return p; |
| } |
| |
| /** |
| * Recalculates the position of the figure and returns the updated bounds. |
| * @param target The figure to relocate |
| */ |
| public void relocate(IFigure target) { |
| Dimension prefSize = target.getPreferredSize(); |
| Point center = getReferencePoint(); |
| calculatePosition(); |
| //@tag zest(bug(GEFProblem)) : there seems to be a bug in GEF that if the following is done, then labels get printed in the wrong location |
| //target.translateToRelative(center); |
| target.setBounds(getNewBounds(prefSize, center)); |
| } |
| |
| /** |
| * Translates the center point depending on the horizontal and veritical |
| * alignments based on the given bounds. |
| * @param center |
| */ |
| private void calculatePosition() { |
| PointList points = getConnection().getPoints(); |
| int position = 0; |
| switch (horizontal) { |
| case BEGINNING: |
| Point first = points.getFirstPoint(); |
| Point next = points.getPoint(1); |
| if (first.x <= next.x) |
| position |= PositionConstants.EAST; |
| else |
| position |= PositionConstants.WEST; |
| break; |
| case END: |
| Point last = points.getLastPoint(); |
| int s = points.size(); |
| Point before = points.getPoint(s - 1); |
| if (last.x <= before.x) |
| position |= PositionConstants.EAST; |
| else |
| position |= PositionConstants.WEST; |
| break; |
| } |
| if (position == 0) |
| position = PositionConstants.CENTER; |
| switch (vertical) { |
| case ABOVE: |
| position |= PositionConstants.NORTH; |
| break; |
| case BELOW: |
| position |= PositionConstants.SOUTH; |
| break; |
| case MIDDLE: |
| position |= PositionConstants.MIDDLE; |
| } |
| setRelativePosition(position); |
| |
| } |
| |
| /** |
| * @return the horizontal alignment. |
| */ |
| public int getHorizontalAlignment() { |
| return horizontal; |
| } |
| |
| /** |
| * @param horizontal the horizontal alignment to set. One of CENTER, |
| * BEGINNING, END, CENTER_BEGINNING, or CENTER_END. |
| */ |
| public void setHorizontalAlignment(int horizontal) { |
| this.horizontal = horizontal; |
| } |
| |
| /** |
| * @param vertical the vertical alignment to set. One of ABOVE, MIDDLE, or |
| * BELOW. |
| */ |
| public void setVerticalAlginment(int vertical) { |
| this.vertical = vertical; |
| } |
| |
| /** |
| * @return the vertical alginment. |
| */ |
| public int getVerticalAlignment() { |
| return vertical; |
| } |
| |
| /** |
| * @return the connection |
| */ |
| public Connection getConnection() { |
| return connection; |
| } |
| |
| } |