blob: 9e9d3e7932fb00381eb39e3e1b022b9abb31c708 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.diagram.ui.figures;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
/**
* A utility class used to find the location to place an <i>undefined</i>
* child figure.
* @author mhanner
*/
public class LayoutHelper {
/**
* constructor
*
*/
public LayoutHelper() {
//
}
/** Constant that represetns an <i>undefined</i> element. */
public static final Rectangle UNDEFINED = new Rectangle(-1,-1,-1,-1);
/**
* Layout the supplied parent's children whose position is equal to {@link #UNDEFINED}.
* @see #getReferencePosition(IFigure)
* @param mgr the calling layout manager
* @param parent the containing figure.
* @param registry the [figure,editpart] registry
*/
public void layoutUndefinedChildren(
ICanonicalShapeCompartmentLayout mgr,
IFigure parent,
Map registry) {
List children = getUnpositionedChildren(parent);
if (!children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
IFigure child = (IFigure) children.get(i);
Point loc = getReferencePosition(parent);
loc = validatePosition(parent, new Rectangle(loc, child.getSize()));
child.setLocation( loc );
parent.getLayoutManager().setConstraint( child, child.getBounds());
}
}
}
/**
* Return the supplied figures children whose location is {@link #UNDEFINED}.
* @param parent the containing figure.
* @return list of figures
*/
public final List getUnpositionedChildren(IFigure parent) {
List children = parent.getChildren();
List retval = new ArrayList();
for (int i = 0; i < children.size(); i++) {
IFigure child = (IFigure) children.get(i);
// System.out.println( "getConstraints(" + child + ") " + parent.getLayoutManager().getConstraint(child));//$NON-NLS-2$//$NON-NLS-1$
if (UNDEFINED
.getLocation()
.equals(child.getBounds().getLocation())) {
retval.add(child);
}
}
return retval;
}
/**
* Return an initial point to position <i>UNDEFINED</i> children.
* @see #validatePosition(IFigure, Rectangle)
* @param parent the containing figure (typically <tt>layout()</tt>'s input parameter)
* @return <code>parent.getBounds().getCenter().getCopy();</code>
*/
public Point getReferencePosition(IFigure parent) {
return parent.getBounds().getCenter().getCopy();
}
/**
* Returns a location inside the supplied <tt>parent</tt> that is currently
* unoccupied by another figure.
* @param parent containing figure.
* @param bounds are being searched.
* @return an unoccupied position.
*/
public Point validatePosition( IFigure parent, Rectangle bounds ) {
Rectangle theBounds = bounds.getCopy();
IFigure clobber = findFigureIn(parent, bounds);
if ( clobber != null ) {
theBounds.setLocation( updateClobberedPosition(clobber,null) );
return validatePosition(parent, theBounds);
}
return theBounds.getLocation();
}
/**
* Return a child figure that is already occupying the a position within
* the supplied <tt>bounds</tt>
* figure.
* @param parent The parent figure of the newly added child.
* @param bounds the area being tested.
* @return a child figure already occupying the supplied <tt>bounds</tt>
* or <tt>null</tt> if the bounds are unoccuppied.
*/
public IFigure findFigureIn(IFigure parent, Rectangle bounds) {
ListIterator listIterator = parent.getChildren().listIterator();
final boolean useContainCheck = UNDEFINED.getSize().equals(bounds.getSize());
while (listIterator.hasNext()) {
IFigure child = (IFigure)listIterator.next();
Rectangle cBounds = child.getBounds();
if (UNDEFINED.getLocation().equals(cBounds.getLocation())) {
continue; //ignore this figure
}
if (useContainCheck) {
if (cBounds.contains(bounds.getLocation())) {
return child;
}
}
else if (cBounds.intersects(bounds)) {
return child;
}
}
return null;
}
/**
* Returns a position <b>not</b> contained with the supplied figures bounds.
* @param clobbered the figure currently occuping the <i>reference position<\i>
* @param newlyAddedChild the child figure being added. <B>NOTE, MAY BE NULL</B>
* @return <code>clobbered.getBounds().getRight().getCopy().translate(30,0);</code>
* @see #getReferencePosition(IFigure)
* @see #validatePosition(IFigure, Rectangle)
*/
public Point updateClobberedPosition(
IFigure clobbered, IFigure newlyAddedChild) {
return clobbered.getBounds().getRight().getCopy().translate(MapModeUtil.getMapMode(clobbered).DPtoLP(30), 0);
}
}