/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.gallery; import org.eclipse.draw2d.AbstractHintLayout; import org.eclipse.draw2d.AbstractLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Rectangle; /** * @author Frank Shaka */ public class FrameBorderLayout extends AbstractHintLayout { /** * Constant to be used as a constraint for child figures */ public static final Integer CENTER = new Integer(PositionConstants.CENTER); /** * Constant to be used as a constraint for child figures */ public static final Integer TOP = new Integer(PositionConstants.TOP); /** * Constant to be used as a constraint for child figures */ public static final Integer BOTTOM = new Integer(PositionConstants.BOTTOM); /** * Constant to be used as a constraint for child figures */ public static final Integer LEFT = new Integer(PositionConstants.LEFT); /** * Constant to be used as a constraint for child figures */ public static final Integer RIGHT = new Integer(PositionConstants.RIGHT); private IFigure center, left, top, bottom, right; private int vGap = 0, hGap = 0; private boolean useCenterAsHint = false; public boolean isUseCenterAsHint() { return useCenterAsHint; } public void setUseCenterAsHint(boolean useCenterAsHint) { this.useCenterAsHint = useCenterAsHint; } /** * @see org.eclipse.draw2d.AbstractHintLayout#calculateMinimumSize(IFigure, * int, int) */ protected Dimension calculateMinimumSize(IFigure container, int wHint, int hHint) { Insets border = container.getInsets(); return new Dimension(border.getWidth(), border.getHeight()); // int minWHint = 0, minHHint = 0; // if (wHint < 0) { // minWHint = -1; // } // if (hHint < 0) { // minHHint = -1; // } // Insets border = container.getInsets(); // wHint = Math.max(minWHint, wHint - border.getWidth()); // hHint = Math.max(minHHint, hHint - border.getHeight()); // Dimension minSize = new Dimension(); // int middleRowWidth = 0, middleRowHeight = 0; // int rows = 0, columns = 0; // // Dimension centerSize; // if (useCenterAsHint && center != null && center.isVisible()) { // centerSize = center.getMinimumSize(wHint, hHint); // } else { // centerSize = null; // } // // if (top != null && top.isVisible()) { // Dimension childSize = top.getMinimumSize(wHint, hHint); // hHint = Math.max(minHHint, hHint - (childSize.height + vGap)); // minSize.setSize(childSize); // rows += 1; // } // if (bottom != null && bottom.isVisible()) { // Dimension childSize = bottom.getMinimumSize(wHint, hHint); // hHint = Math.max(minHHint, hHint - (childSize.height + vGap)); // minSize.width = Math.max(minSize.width, childSize.width); // minSize.height += childSize.height; // rows += 1; // } // if (left != null && left.isVisible()) { // Dimension childSize = left.getMinimumSize(wHint, hHint); // middleRowWidth = childSize.width; // middleRowHeight = childSize.height; // wHint = Math.max(minWHint, wHint - (childSize.width + hGap)); // columns += 1; // } // if (right != null && right.isVisible()) { // Dimension childSize = right.getMinimumSize(wHint, hHint); // middleRowWidth += childSize.width; // middleRowHeight = Math.max(childSize.height, middleRowHeight); // wHint = Math.max(minWHint, wHint - (childSize.width + hGap)); // columns += 1; // } // if (center != null && center.isVisible()) { // Dimension childSize = center.getMinimumSize(wHint, hHint); // middleRowWidth += childSize.width; // middleRowHeight = Math.max(childSize.height, middleRowHeight); // columns += 1; // } // // rows += columns > 0 ? 1 : 0; // // Add spacing, insets, and the size of the middle row // minSize.height += middleRowHeight + border.getHeight() // + ((rows - 1) * vGap); // minSize.width = Math.max(minSize.width, middleRowWidth) // + border.getWidth() + ((columns - 1) * hGap); // // return minSize; } /** * @see AbstractLayout#calculatePreferredSize(IFigure, int, int) */ protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) { // int minWHint = 0, minHHint = 0; // if (wHint < 0) // minWHint = -1; // if (hHint < 0) // minHHint = -1; // Insets border = container.getInsets(); // wHint = Math.max(minWHint, wHint - border.getWidth()); // hHint = Math.max(minHHint, hHint - border.getHeight()); Dimension prefSize = new Dimension(); // int rows = 0, columns = 0; if (center != null && center.isVisible()) { Dimension childSize = center.getPreferredSize(); prefSize.setSize(childSize); // columns += 1; } if (top != null && top.isVisible()) { // wHint = prefSize.width; // hHint = Math.max(minHHint, hHint - (prefSize.height + vGap)); Dimension childSize = top.getPreferredSize(prefSize.width, -1); prefSize.height += childSize.height + vGap; // rows += 1; } else if (bottom != null && bottom.isVisible()) { // hHint = Math.max(minHHint, hHint - (prefSize.height + vGap)); Dimension childSize = bottom.getPreferredSize(prefSize.width, -1); // prefSize.width = Math.max(prefSize.width, childSize.width); prefSize.height += childSize.height + vGap; // rows += 1; } else if (left != null && left.isVisible()) { // wHint = Math.max(minWHint, wHint - (prefSize.width + hGap)); Dimension childSize = left.getPreferredSize(-1, prefSize.height); prefSize.width += childSize.width + hGap; // columns += 1; } else if (right != null && right.isVisible()) { Dimension childSize = right.getPreferredSize(-1, prefSize.height); prefSize.width += childSize.width + hGap; // wHint = Math.max(minWHint, wHint - (childSize.width + hGap)); // columns += 1; } // rows += columns > 0 ? 1 : 0; // Add spacing, insets, and the size of the middle row // prefSize.height += middleRowHeight + border.getHeight() // + ((rows - 1) * vGap); // prefSize.width = Math.max(prefSize.width, middleRowWidth) // + border.getWidth() + ((columns - 1) * hGap); prefSize.height += border.getHeight(); prefSize.width += border.getHeight(); return prefSize; } /** * @see org.eclipse.draw2d.LayoutManager#layout(IFigure) */ public void layout(IFigure container) { Rectangle area = container.getClientArea(); Rectangle rect = new Rectangle(); int wHint = area.width; int hHint = area.height; // if ((top != null && top.isVisible()) // || (bottom != null && bottom.isVisible())) { // hHint = -1; // } else if ((left != null && left.isVisible()) // || (right != null && right.isVisible())) { // wHint = -1; // } Dimension centerSize; if (center != null && center.isVisible()) { centerSize = center.getPreferredSize(wHint, hHint); } else { centerSize = new Dimension(); } // Dimension childSize; if (top != null && top.isVisible()) { rect.setLocation(area.x, area.y); rect.setSize(area.width, Math.max(0, area.height - centerSize.height - vGap)); top.setBounds(rect); area.y += rect.height + vGap; area.height -= rect.height + vGap; } else if (bottom != null && bottom.isVisible()) { rect.setLocation(area.x, area.y + centerSize.height + vGap); rect.setSize(area.width, Math.max(0, area.height - centerSize.height - vGap)); bottom.setBounds(rect); area.height -= rect.height + vGap; } else if (left != null && left.isVisible()) { rect.setLocation(area.x, area.y); rect.setSize(Math.max(0, area.width - centerSize.width - hGap), area.height); left.setBounds(rect); area.x += rect.width + hGap; area.width -= rect.width + hGap; } else if (right != null && right.isVisible()) { rect.setLocation(area.x + centerSize.width + hGap, area.y); rect.setSize(Math.max(0, area.width - centerSize.width - hGap), area.height); right.setBounds(rect); area.width -= rect.width + hGap; } // if (top != null && top.isVisible()) { // childSize = top.getPreferredSize(area.width, -1); // rect.setLocation(area.x, area.y); // rect.setSize(childSize); // rect.width = area.width; // top.setBounds(rect); // area.y += rect.height + vGap; // area.height -= rect.height + vGap; // } // if (bottom != null && bottom.isVisible()) { // childSize = bottom.getPreferredSize(Math.max(area.width, 0), -1); // rect.setSize(childSize); // rect.width = area.width; // rect.setLocation(area.x, area.y + area.height - rect.height); // bottom.setBounds(rect); // area.height -= rect.height + vGap; // } // if (left != null && left.isVisible()) { // childSize = left.getPreferredSize(-1, Math.max(0, area.height)); // rect.setLocation(area.x, area.y); // rect.width = childSize.width; // rect.height = Math.max(0, area.height); // left.setBounds(rect); // area.x += rect.width + hGap; // area.width -= rect.width + hGap; // } // if (right != null && right.isVisible()) { // childSize = right.getPreferredSize(-1, Math.max(0, area.height)); // rect.width = childSize.width; // rect.height = Math.max(0, area.height); // rect.setLocation(area.x + area.width - rect.width, area.y); // right.setBounds(rect); // area.width -= rect.width + hGap; // } if (center != null && center.isVisible()) { if (area.width < 0) area.width = 0; if (area.height < 0) area.height = 0; center.setBounds(area); } } /** * @see org.eclipse.draw2d.AbstractLayout#remove(IFigure) */ public void remove(IFigure child) { if (center == child) { center = null; } else if (top == child) { top = null; } else if (bottom == child) { bottom = null; } else if (right == child) { right = null; } else if (left == child) { left = null; } } /** * Sets the location of hte given child in this layout. Valid constraints: * <UL> * <LI>{@link #CENTER}</LI> * <LI>{@link #TOP}</LI> * <LI>{@link #BOTTOM}</LI> * <LI>{@link #LEFT}</LI> * <LI>{@link #RIGHT}</LI> * <LI><code>null</code> (to remove a child's constraint)</LI> * </UL> * * <p> * Ensure that the given Figure is indeed a child of the Figure on which * this layout has been set. Proper behaviour cannot be guaranteed if that * is not the case. Also ensure that every child has a valid constraint. * </p> * <p> * Passing a <code>null</code> constraint will invoke * {@link #remove(IFigure)}. * </p> * <p> * If the given child was assigned another constraint earlier, it will be * re-assigned to the new constraint. If there is another child with the * given constraint, it will be over-ridden so that the given child now has * that constraint. * </p> * * @see org.eclipse.draw2d.AbstractLayout#setConstraint(IFigure, Object) */ public void setConstraint(IFigure child, Object constraint) { remove(child); super.setConstraint(child, constraint); if (constraint == null) { return; } switch (((Integer) constraint).intValue()) { case PositionConstants.CENTER: center = child; break; case PositionConstants.TOP: top = child; break; case PositionConstants.BOTTOM: bottom = child; break; case PositionConstants.RIGHT: right = child; break; case PositionConstants.LEFT: left = child; break; default: break; } } /** * Sets the horizontal spacing to be used between the children. Default is * 0. * * @param gap * The horizonal spacing */ public void setHorizontalSpacing(int gap) { hGap = gap; } /** * Sets the vertical spacing ot be used between the children. Default is 0. * * @param gap * The vertical spacing */ public void setVerticalSpacing(int gap) { vGap = gap; } }