package org.eclipse.uml2.diagram.sequence.draw2d; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gmf.runtime.diagram.ui.layout.FreeFormLayoutEx; import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure; public class InteractionContentsLayout extends FreeFormLayoutEx { public void layout(IFigure parent) { Iterator<?> children = parent.getChildren().iterator(); Point offset = getOrigin(parent); IFigure f; List<IFigure> specifics = new LinkedList<IFigure>(); while (children.hasNext()) { f = (IFigure)children.next(); Class<?> specificLayoutKey = isSpecificLayout(f); if (specificLayoutKey != null){ specifics.add(f); continue; } Rectangle bounds = (Rectangle)getConstraint(f); if (bounds == null) continue; int widthHint = bounds.width; int heightHint = bounds.height; if (widthHint == -1 || heightHint == -1) { Dimension _preferredSize = f.getPreferredSize(widthHint, heightHint); bounds = bounds.getCopy(); if (widthHint == -1) bounds.width = _preferredSize.width; if (heightHint == -1) bounds.height = _preferredSize.height; } Dimension min = f.getMinimumSize(widthHint, heightHint); Dimension max = f.getMaximumSize(); if (min.width>bounds.width) bounds.width = min.width; else if (max.width < bounds.width) bounds.width = max.width; if (min.height>bounds.height) bounds.height = min.height; else if (max.height < bounds.height) bounds.height = max.height; bounds = bounds.getTranslated(offset); f.setBounds(bounds); } if (specifics.isEmpty()){ return; } Dimension maxSize = new Dimension(); int minY = Integer.MAX_VALUE; for (IFigure next : specifics){ Rectangle bounds = calculateChildBounds(next); if (bounds == null) continue; maxSize.union(bounds.getSize()); minY = Math.min(minY, bounds.y); } for (IFigure next : specifics){ Rectangle bounds = calculateChildBounds(next); if (bounds == null) continue; bounds.height = maxSize.height; bounds.y = minY; next.setBounds(bounds); } } private Rectangle calculateChildBounds(IFigure next){ Point offset = getOrigin(next.getParent()); Rectangle bounds = (Rectangle)getConstraint(next); if (bounds == null){ return null; } int widthHint = bounds.width; int heightHint = bounds.height; if (widthHint == -1 || heightHint == -1) { Dimension _preferredSize = next.getPreferredSize(widthHint, heightHint); bounds = bounds.getCopy(); if (widthHint == -1) bounds.width = _preferredSize.width; if (heightHint == -1) bounds.height = _preferredSize.height; } Dimension min = next.getMinimumSize(widthHint, heightHint); Dimension max = next.getMaximumSize(); if (min.width>bounds.width) bounds.width = min.width; else if (max.width < bounds.width) bounds.width = max.width; if (min.height>bounds.height) bounds.height = min.height; else if (max.height < bounds.height) bounds.height = max.height; bounds = bounds.getTranslated(offset); return bounds; } private Class<?> isSpecificLayout(IFigure figure){ if (false == figure instanceof NodeFigure){ return null; } NodeFigure nodeFigure = (NodeFigure)figure; if (nodeFigure.getChildren().isEmpty()){ return null; } for (Object nextChild : nodeFigure.getChildren()){ if (nextChild instanceof ISpecificLayoutFigure){ return nextChild.getClass(); } } return null; } }