/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.windowtester.runtime.gef.internal.finder;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.NodeEditPart;
import com.windowtester.internal.debug.LogHandler;
import com.windowtester.runtime.gef.Position;
import com.windowtester.runtime.gef.internal.GEF;
import com.windowtester.runtime.gef.internal.locator.AnchorNotFoundException;
import com.windowtester.runtime.swt.internal.display.RunnableWithResult;
import com.windowtester.runtime.swt.internal.finder.RetrySupport;
/**
* A helper for finding GEF Figure anchors.
*/
public class AnchorFinder {
private static final ConnectionAnchor[] NONE = new ConnectionAnchor[]{};
/**
* Get the anchor for this point or <code>null</code> if there is none.
*/
public static IAnchorInfo forFigureAtPoint(IFigure figure, Point point) {
NodeEditPart part = getNodePart(figure);
if (part == null)
return null;
ConnectionAnchor anchor = getAnchorForPointOnPart(point, part);
if (anchor == null)
return null;
return findPositionforAnchorInFigure(anchor, figure);
}
private static IAnchorInfo findPositionforAnchorInFigure(ConnectionAnchor anchor, IFigure figure) {
IAnchorInfo[] positionedAnchors = forFigure(figure);
for (int i = 0; i < positionedAnchors.length; i++) {
IAnchorInfo positionedAnchor = positionedAnchors[i];
if (positionedAnchor.getAnchor() == anchor)
return positionedAnchor;
}
return null;
}
private static ConnectionAnchor getAnchorForPointOnPart(Point point, NodeEditPart part) {
try {
ConnectionAnchor[] anchors = new AnchorRequester().requestAnchorsForPointOnNode(point, part);
// TODO: can this ever return more than 1?
if (anchors.length == 0)
return null;
return anchors[0];
} catch (MultipleAnchorsForLocationException e) {
LogHandler.log(e);
}
return null;
}
private static NodeEditPart getNodePart(IFigure figure) {
EditPart[] parts = GEF.getFinder().findAllEditParts(figure);
if (parts.length == 0)
return null;
if (!(parts[0] instanceof NodeEditPart))
return null;
return (NodeEditPart)parts[0];
}
public static IAnchorInfo[] forFigure(IFigure figure) {
ConnectionAnchor[] anchors;
try {
anchors = forFigure0(figure);
} catch (MultipleAnchorsForLocationException e) {
return new IAnchorInfo[]{IAnchorInfo.MULTIPLE_ANCHORS};
}
IAnchorInfo[] info = new IAnchorInfo[anchors.length];
for (int i = 0; i < anchors.length; i++) {
info[i] = AnchorInfo.forAnchor(anchors[i], anchors);
}
return info;
}
public static IAnchorInfo forPositionInFigure(Position position, final IFigure figure) throws AnchorNotFoundException {
IAnchorInfo[] anchors = (IAnchorInfo[]) RetrySupport.retryUntilArrayResultIsNonEmpty(new RunnableWithResult(){
public Object runWithResult() {
return forFigure(figure);
}
});
for (int i = 0; i < anchors.length; i++) {
if (anchors[i].getPosition().equals(position))
return anchors[i];
}
throw new AnchorNotFoundException();
}
private static ConnectionAnchor[] forFigure0(IFigure figure) throws MultipleAnchorsForLocationException {
EditPart[] parts = GEF.getFinder().findAllEditParts(figure);
if (parts.length == 0)
return NONE;
//TODO: handle multiples here?
return forFigureWithPart(figure, parts[0]);
}
private static ConnectionAnchor[] forFigureWithPart(IFigure figure, EditPart part) throws MultipleAnchorsForLocationException {
if (!(part instanceof NodeEditPart))
return NONE;
return forFigureWithNodePart(figure, (NodeEditPart) part);
}
private static ConnectionAnchor[] forFigureWithNodePart(IFigure figure, NodeEditPart part) throws MultipleAnchorsForLocationException {
return new AnchorRequester().requestAnchorsForFigureWithNodePart(figure, part);
}
}