/******************************************************************************* * Copyright (c) 2008 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.gef.internal.ui.palette.editparts; import java.util.List; import org.eclipse.draw2d.FlowLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Rectangle; /** * Extends <code>FlowLayout</code> to allow the pane of a pinnable stack in * icon mode to occupy the row following the row in which the icon of the * palette stack header appears. * * @author crevells * @since 3.4 */ public class PaletteContainerFlowLayout extends FlowLayout { /** * Constructs a PaletteContainerFlowLayout with horizontal orientation. */ public PaletteContainerFlowLayout() { } /** * Constructs a PaletteContainerFlowLayout whose orientation is given in the * input. * * @param isHorizontal * <code>true</code> if the layout should be horizontal */ public PaletteContainerFlowLayout(boolean isHorizontal) { setHorizontal(isHorizontal); } /** * Overridden to include the size of the expanded pane of an expanded pinnable * palette stack. * * @see org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(IFigure, int, * int) */ protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) { Dimension prefSize = super.calculatePreferredSize(container, wHint, hHint); List children = container.getChildren(); IFigure child; // Build the sizes for each row, and update prefSize accordingly Dimension expandedPaneSize = null; for (int i = 0; i < children.size(); i++) { child = (IFigure) children.get(i); if (child instanceof PinnablePaletteStackFigure && ((PinnablePaletteStackFigure) child).isExpanded()) { // Subtract out the insets from the hints if (wHint > -1) wHint = Math.max(0, wHint - container.getInsets().getWidth()); if (hHint > -1) hHint = Math.max(0, hHint - container.getInsets().getHeight()); // Figure out the new hint that we are interested in based on the // orientation. Ignore the other hint (by setting it to -1). NOTE: // The children of the parent figure will then be asked to ignore // that hint as well. if (isHorizontal()) { hHint = -1; } else { wHint = -1; } expandedPaneSize = ((PinnablePaletteStackFigure) child) .getExpandedContainerPreferredSize(wHint, hHint); break; // there can only be one expanded stack } } if (expandedPaneSize != null) { // increment height to account for expanded stack prefSize.height += transposer.t(expandedPaneSize).height; prefSize.union(getBorderPreferredSize(container)); } return prefSize; } /** * Overridden to handle <code>PinnablePaletteStackFigure</code>. * * @see FlowLayout#getChildSize(IFigure, int, int) */ protected Dimension getChildSize(IFigure child, int wHint, int hHint) { if (child instanceof PinnablePaletteStackFigure) { return ((PinnablePaletteStackFigure) child).getHeaderPreferredSize( wHint, hHint); } else { return child.getPreferredSize(wHint, hHint); } } /** * Overridden to include the size of the expanded pane of an expanded pinnable * palette stack during the layout. * * @see FlowLayout#layoutRow(IFigure) */ protected void layoutRow(IFigure parent) { int majorAdjustment = 0; int minorAdjustment = 0; int correctMajorAlignment = majorAlignment; int correctMinorAlignment = minorAlignment; majorAdjustment = data.area.width - data.rowWidth + getMinorSpacing(); switch (correctMajorAlignment) { case ALIGN_LEFTTOP: majorAdjustment = 0; break; case ALIGN_CENTER: majorAdjustment /= 2; break; case ALIGN_RIGHTBOTTOM: break; } int expandedPaneHeight = 0; for (int j = 0; j < data.rowCount; j++) { if (fill) { data.bounds[j].height = data.rowHeight; } else { minorAdjustment = data.rowHeight - data.bounds[j].height; switch (correctMinorAlignment) { case ALIGN_LEFTTOP: minorAdjustment = 0; break; case ALIGN_CENTER: minorAdjustment /= 2; break; case ALIGN_RIGHTBOTTOM: break; } data.bounds[j].y += minorAdjustment; } data.bounds[j].x += majorAdjustment; IFigure child = data.row[j]; setBoundsOfChild(parent, data.row[j], transposer.t(data.bounds[j])); if (child instanceof PinnablePaletteStackFigure && ((PinnablePaletteStackFigure) child).isExpanded()) { int wHint = -1; int hHint = -1; if (isHorizontal()) wHint = parent.getClientArea().width; else hHint = parent.getClientArea().height; expandedPaneHeight = ((PinnablePaletteStackFigure) child) .getExpandedContainerPreferredSize(wHint, hHint).height; child.setBounds(new Rectangle(data.area.x, data.area.y + data.rowY, data.area.width, data.rowHeight + expandedPaneHeight)); } } data.rowY += getMajorSpacing() + data.rowHeight + expandedPaneHeight; initRow(); } /** * Overridden to set the bounds for <code>PinnablePaletteStackFigures</code>. * * @see FlowLayout#setBoundsOfChild(IFigure, IFigure, Rectangle) */ protected void setBoundsOfChild(IFigure parent, IFigure child, Rectangle bounds) { if (child instanceof PinnablePaletteStackFigure && ((PinnablePaletteStackFigure) child).isExpanded()) { parent.getClientArea(Rectangle.SINGLETON); bounds.translate(Rectangle.SINGLETON.x, Rectangle.SINGLETON.y); ((PinnablePaletteStackFigure) child).setHeaderBoundsLayoutHint(bounds); } else { super.setBoundsOfChild(parent, child, bounds); } } }