001: /**
002: *
003: */package newprocess.diagram.cust.locator;
004:
005: import java.util.List;
006: import java.util.ListIterator;
007:
008: import org.eclipse.draw2d.IFigure;
009: import org.eclipse.draw2d.PositionConstants;
010: import org.eclipse.draw2d.geometry.Point;
011: import org.eclipse.draw2d.geometry.Rectangle;
012: import org.eclipse.gmf.runtime.diagram.ui.figures.BorderItemLocator;
013: import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
014:
015: /**
016: * @author sh
017: *
018: */
019: public class RootTermBorderItemLocator extends BorderItemLocator {
020:
021: public RootTermBorderItemLocator(IFigure borderItem,
022: IFigure parentFigure, Rectangle constraint) {
023: super (borderItem, parentFigure, constraint);
024: }
025:
026: public RootTermBorderItemLocator(IFigure parentFigure,
027: int preferredSide) {
028: super (parentFigure, preferredSide);
029: }
030:
031: public RootTermBorderItemLocator(IFigure parentFigure) {
032: super (parentFigure);
033: }
034:
035: /*
036: * (non-Javadoc)
037: * @see org.eclipse.gmf.runtime.diagram.ui.figures.BorderItemLocator#relocate(org.eclipse.draw2d.IFigure)
038: */
039: public void relocate(IFigure borderItem) {
040: // Get the preferred location. If none has been previously set, use the
041: // preferred side to take an initial guess.
042: Point preferredLocation = getPreferredLocation(borderItem);
043:
044: // get the parent border
045: Rectangle parentBorder = getParentBorder();
046:
047: preferredLocation = getPreferredLocation(borderItem);
048: int preferredSide = getPreferredSideOfParent();
049:
050: // set the new position of the bordered item
051: preferredLocation.x = parentBorder.x + parentBorder.width / 2
052: - borderItem.getBounds().width / 2;
053:
054: Point ptNewLocation = locateOnBorder(preferredLocation,
055: preferredSide, 0, borderItem);
056: borderItem.setLocation(ptNewLocation);
057:
058: // set the current/next side of the parent
059: setCurrentSideOfParent(findClosestSideOfParent(new Rectangle(
060: ptNewLocation, borderItem.getBounds().getSize()),
061: getParentBorder()));
062: }
063:
064: /**
065: * The preferred side takes precendence.
066: *
067: * @param suggestedLocation
068: * @param suggestedSide
069: * @param circuitCount
070: * recursion count to avoid an infinite loop
071: * @return point
072: */
073:
074: private Point locateOnBorder(Point suggestedLocation,
075: int suggestedSide, int circuitCount, IFigure borderItem) {
076: Point recommendedLocation = locateOnParent(suggestedLocation,
077: suggestedSide, borderItem);
078:
079: int vertical_gap = MapModeUtil.getMapMode(getParentFigure())
080: .DPtoLP(8);
081: int horizontal_gap = MapModeUtil.getMapMode(getParentFigure())
082: .DPtoLP(8);
083: Rectangle borderItemBounds = borderItem.getBounds();
084:
085: if (circuitCount < 4
086: && conflicts(recommendedLocation, borderItem)) {
087: if (suggestedSide == PositionConstants.WEST) {
088: do {
089: recommendedLocation.y += borderItemBounds.height
090: + vertical_gap;
091: } while (conflicts(recommendedLocation, borderItem));
092: if (recommendedLocation.y > getParentBorder()
093: .getBottomLeft().y
094: - borderItemBounds.height) { // off the bottom,
095: // wrap south
096: return locateOnBorder(recommendedLocation,
097: PositionConstants.SOUTH, circuitCount + 1,
098: borderItem);
099: }
100: } else if (suggestedSide == PositionConstants.SOUTH) {
101: do {
102: recommendedLocation.x += borderItemBounds.width
103: + horizontal_gap;
104: } while (conflicts(recommendedLocation, borderItem));
105: if (recommendedLocation.x > getParentBorder()
106: .getBottomRight().x
107: - borderItemBounds.width) {
108: return locateOnBorder(recommendedLocation,
109: PositionConstants.EAST, circuitCount + 1,
110: borderItem);
111: }
112: } else if (suggestedSide == PositionConstants.EAST) {
113: // move up the east side
114: do {
115: recommendedLocation.y -= (borderItemBounds.height + vertical_gap);
116: } while (conflicts(recommendedLocation, borderItem));
117: if (recommendedLocation.y < getParentBorder()
118: .getTopRight().y) {
119: // east is full, try north.
120: return locateOnBorder(recommendedLocation,
121: PositionConstants.NORTH, circuitCount + 1,
122: borderItem);
123: }
124: } else { // NORTH
125: do {
126: recommendedLocation.x -= (borderItemBounds.width + horizontal_gap);
127: } while (conflicts(recommendedLocation, borderItem));
128: if (recommendedLocation.x < getParentBorder()
129: .getTopLeft().x) {
130: return locateOnBorder(recommendedLocation,
131: PositionConstants.WEST, circuitCount + 1,
132: borderItem);
133: }
134: }
135: }
136: return recommendedLocation;
137: }
138:
139: /**
140: * Ensure the suggested location actually lies on the parent boundary. The
141: * side takes precendence.
142: *
143: * @param suggestedLocation
144: * @param suggestedSide
145: * @return point
146: */
147: private Point locateOnParent(Point suggestedLocation,
148: int suggestedSide, IFigure borderItem) {
149: Rectangle bounds = getParentBorder();
150: int parentFigureWidth = bounds.width;
151: int parentFigureHeight = bounds.height;
152: int parentFigureX = bounds.x;
153: int parentFigureY = bounds.y;
154: Rectangle borderItemBounds = borderItem.getBounds();
155: int newX = suggestedLocation.x;
156: int newY = suggestedLocation.y;
157: int westX = parentFigureX - borderItemBounds.width
158: + getBorderItemOffset().width;
159: int eastX = parentFigureX + parentFigureWidth
160: - getBorderItemOffset().width;
161: int southY = parentFigureY + parentFigureHeight
162: - getBorderItemOffset().height;
163: int northY = parentFigureY - borderItemBounds.height
164: + getBorderItemOffset().height;
165: if (suggestedSide == PositionConstants.WEST) {
166: if (suggestedLocation.x != westX) {
167: newX = westX;
168: }
169: if (suggestedLocation.y < bounds.getTopLeft().y) {
170: newY = northY + borderItemBounds.height;
171: } else if (suggestedLocation.y > bounds.getBottomLeft().y
172: - borderItemBounds.height) {
173: newY = southY - borderItemBounds.height;
174: }
175: } else if (suggestedSide == PositionConstants.EAST) {
176: if (suggestedLocation.x != eastX) {
177: newX = eastX;
178: }
179: if (suggestedLocation.y < bounds.getTopLeft().y) {
180: newY = northY + borderItemBounds.height;
181: } else if (suggestedLocation.y > bounds.getBottomLeft().y
182: - borderItemBounds.height) {
183: newY = southY - borderItemBounds.height;
184: }
185: } else if (suggestedSide == PositionConstants.SOUTH) {
186: if (suggestedLocation.y != southY) {
187: newY = southY;
188: }
189: if (suggestedLocation.x < bounds.getBottomLeft().x) {
190: newX = westX + borderItemBounds.width;
191: } else if (suggestedLocation.x > bounds.getBottomRight().x
192: - borderItemBounds.width) {
193: newX = eastX - borderItemBounds.width;
194: }
195: } else { // NORTH
196: if (suggestedLocation.y != northY) {
197: newY = northY;
198: }
199: if (suggestedLocation.x < bounds.getBottomLeft().x) {
200: newX = westX + borderItemBounds.width;
201: } else if (suggestedLocation.x > bounds.getBottomRight().x
202: - borderItemBounds.width) {
203: newX = eastX - borderItemBounds.width;
204: }
205: }
206: return new Point(newX, newY);
207: }
208:
209: /**
210: * Determine if the the given point conflicts with the position of an
211: * existing borderItemFigure.
212: *
213: * @param recommendedLocation
214: * @return <code>ture</code> or <code>false</code>
215: */
216: private boolean conflicts(Point recommendedLocation,
217: IFigure targetBorderItem) {
218: Rectangle recommendedRect = new Rectangle(recommendedLocation,
219: targetBorderItem.getSize());
220: List borderItems = targetBorderItem.getParent().getChildren();
221: ListIterator iterator = borderItems.listIterator();
222: while (iterator.hasNext()) {
223: IFigure borderItem = (IFigure) iterator.next();
224: if (borderItem.isVisible()) {
225: Rectangle rect = borderItem.getBounds().getCopy();
226: if (borderItem != targetBorderItem
227: && rect.intersects(recommendedRect)) {
228: return true;
229: }
230: }
231: }
232: return false;
233: }
234: }
|