package org.eclipse.uml2.diagram.sequence.draw2d.layouts; import java.util.List; import org.eclipse.draw2d.AbstractLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Rectangle; /** * Places the first child in the center and shrinks it if necessary * to fit inside container bounds. Child bounds are not expanded to * match container bounds as it happens in BorderLayout with CENTER * hint. Child minimum size is ignored. * * If positive scale level specified will always scale child bounds * correspondingly. * * Designed for containers with exactly one child; other children * will be ignored. * * @author dstadnik */ public class CenteringLayout extends AbstractLayout { protected static final int DEFAULT_WIDTH = 50; protected static final int DEFAULT_HEIGHT = 50; public CenteringLayout() { } public CenteringLayout(double scaleLevel) { setScale(scaleLevel); } /** * Fixed child scale level. Should be within 0..1 range. * Zero value means that child should not be scaled. */ public final double getScale() { return myScaleLevel; } public void setScale(double level) { if (level < 0 || level > 1) { throw new IllegalArgumentException(); } myScaleLevel = level; } protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) { List<?> children = container.getChildren(); if (children.isEmpty()) { return new Dimension(wHint < 0 ? DEFAULT_WIDTH : wHint, hHint < 0 ? DEFAULT_HEIGHT : hHint); } IFigure child = (IFigure) children.get(0); Dimension size = child.getPreferredSize(); // do not pass hints! if (size == null) { size = new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } else { size = size.getCopy(); if (myScaleLevel > 0) { size.width /= myScaleLevel; size.height /= myScaleLevel; } } if (wHint >= 0) { size.width = wHint; } if (hHint >= 0) { size.height = hHint; } return size; } public void layout(IFigure container) { Rectangle bounds = container.getClientArea(); List<?> children = container.getChildren(); if (children.isEmpty()) { return; } IFigure child = (IFigure) children.get(0); Dimension size; if (myScaleLevel > 0) { size = bounds.getSize(); size.width *= myScaleLevel; size.height *= myScaleLevel; } else { size = child.getPreferredSize(bounds.width, bounds.height); if (size == null) { size = new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } if (size.width > bounds.width) { size.width = bounds.width; } if (size.height > bounds.height) { size.height = bounds.height; } } int woff = bounds.x + (bounds.width - size.width) / 2; int hoff = bounds.y + (bounds.height - size.height) / 2; child.setBounds(new Rectangle(woff, hoff, size.width, size.height)); } private double myScaleLevel; }