| /****************************************************************************** |
| * 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); |
| } |
| } |