
org.eclipse.draw2d.ToolbarLayout Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of draw2d Show documentation
Show all versions of draw2d Show documentation
Eclipse GEF Draw2D Library
The newest version!
/*******************************************************************************
* Copyright (c) 2000, 2010 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.draw2d;
import java.util.List;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
/**
* Arranges figures in a single row or column. Orientation can be set to produce
* either a row or column layout. This layout tries to fit all children within
* the parent's client area. To do this, it compresses the children by some
* amount, but will not compress them smaller than their minimum size. If a
* child's preferred size is smaller than the row's or column's minor dimension,
* the layout can be configured to stretch the child.
*/
public class ToolbarLayout extends OrderedLayout {
/**
* Constant for horizontal alignment
*
* @deprecated Unused.
*/
public static final boolean HORIZONTAL = true;
/**
* Constant for vertical alignment
*
* @deprecated Unused.
* */
public static final boolean VERTICAL = false;
/**
* Sets whether children should "stretch" with their container
*
* @deprecated Use {@link OrderedLayout#setStretchMinorAxis(boolean)} and
* {@link OrderedLayout#isStretchMinorAxis()} instead.
* */
protected boolean matchWidth;
/**
* Space in pixels between Figures
*
* @deprecated Use {@link #getSpacing()} and {@link #setSpacing(int)}
* instead.
*/
protected int spacing;
/**
* Constructs a vertically oriented ToolbarLayout with child spacing of 0
* pixels, {@link #setStretchMinorAxis(boolean)} true
, and
* {@link #ALIGN_TOPLEFT} minor alignment.
*
* @since 2.0
*/
public ToolbarLayout() {
setStretchMinorAxis(true);
setSpacing(0);
}
/**
* Constructs a ToolbarLayout with a specified orientation. Default values
* are: child spacing 0 pixels, {@link #setStretchMinorAxis(boolean)}
* false
, and {@link #ALIGN_TOPLEFT} alignment.
*
* @param isHorizontal
* whether the children are oriented horizontally
* @since 2.0
*/
public ToolbarLayout(boolean isHorizontal) {
setHorizontal(isHorizontal);
setStretchMinorAxis(false);
setSpacing(0);
}
private Dimension calculateChildrenSize(List children, int wHint,
int hHint, boolean preferred) {
Dimension childSize;
IFigure child;
int height = 0, width = 0;
for (int i = 0; i < children.size(); i++) {
child = (IFigure) children.get(i);
childSize = transposer.t(preferred ? getChildPreferredSize(child,
wHint, hHint) : getChildMinimumSize(child, wHint, hHint));
height += childSize.height;
width = Math.max(width, childSize.width);
}
return new Dimension(width, height);
}
/**
* Calculates the minimum size of the container based on the given hints. If
* this is a vertically-oriented Toolbar Layout, then only the widthHint is
* respected (which means that the children can be as tall as they desire).
* In this case, the minimum width is that of the widest child, and the
* minimum height is the sum of the minimum heights of all children, plus
* the spacing between them. The border and insets of the container figure
* are also accounted for.
*
* @param container
* the figure whose minimum size has to be calculated
* @param wHint
* the width hint (the desired width of the container)
* @param hHint
* the height hint (the desired height of the container)
* @return the minimum size of the container
* @see #getMinimumSize(IFigure, int, int)
* @since 2.1
*/
protected Dimension calculateMinimumSize(IFigure container, int wHint,
int hHint) {
Insets insets = container.getInsets();
if (isHorizontal()) {
wHint = -1;
if (hHint >= 0)
hHint = Math.max(0, hHint - insets.getHeight());
} else {
hHint = -1;
if (wHint >= 0)
wHint = Math.max(0, wHint - insets.getWidth());
}
List children = container.getChildren();
Dimension minSize = calculateChildrenSize(children, wHint, hHint, false);
// Do a second pass, if necessary
if (wHint >= 0 && minSize.width > wHint) {
minSize = calculateChildrenSize(children, minSize.width, hHint,
false);
} else if (hHint >= 0 && minSize.width > hHint) {
minSize = calculateChildrenSize(children, wHint, minSize.width,
false);
}
minSize.height += Math.max(0, children.size() - 1) * spacing;
return transposer.t(minSize)
.expand(insets.getWidth(), insets.getHeight())
.union(getBorderPreferredSize(container));
}
/**
* Calculates the preferred size of the container based on the given hints.
* If this is a vertically-oriented Toolbar Layout, then only the widthHint
* is respected (which means that the children can be as tall as they
* desire). In this case, the preferred width is that of the widest child,
* and the preferred height is the sum of the preferred heights of all
* children, plus the spacing between them. The border and insets of the
* container figure are also accounted for.
*
* @param container
* the figure whose preferred size has to be calculated
* @param wHint
* the width hint (the desired width of the container)
* @param hHint
* the height hint (the desired height of the container)
* @return the preferred size of the container
* @see #getPreferredSize(IFigure, int, int)
* @since 2.0
*/
protected Dimension calculatePreferredSize(IFigure container, int wHint,
int hHint) {
Insets insets = container.getInsets();
if (isHorizontal()) {
wHint = -1;
if (hHint >= 0)
hHint = Math.max(0, hHint - insets.getHeight());
} else {
hHint = -1;
if (wHint >= 0)
wHint = Math.max(0, wHint - insets.getWidth());
}
List children = container.getChildren();
Dimension prefSize = calculateChildrenSize(children, wHint, hHint, true);
// Do a second pass, if necessary
if (wHint >= 0 && prefSize.width > wHint) {
prefSize = calculateChildrenSize(children, prefSize.width, hHint,
true);
} else if (hHint >= 0 && prefSize.width > hHint) {
prefSize = calculateChildrenSize(children, wHint, prefSize.width,
true);
}
prefSize.height += Math.max(0, children.size() - 1) * spacing;
return transposer.t(prefSize)
.expand(insets.getWidth(), insets.getHeight())
.union(getBorderPreferredSize(container));
}
/**
* @param child
* the figure whose minimum size is to be determined
* @param wHint
* the width hint
* @param hHint
* the height hint
* @return the given figure's minimum size
* @since 3.3
*/
protected Dimension getChildMinimumSize(IFigure child, int wHint, int hHint) {
return child.getMinimumSize(wHint, hHint);
}
/**
* @param child
* the figure whose preferred size is to be determined
* @param wHint
* the width hint
* @param hHint
* the height hint
* @return given figure's preferred size
* @since 3.3
*/
protected Dimension getChildPreferredSize(IFigure child, int wHint,
int hHint) {
return child.getPreferredSize(wHint, hHint);
}
/**
* Returns {@link PositionConstants#VERTICAL} by default.
*
* @see org.eclipse.draw2d.OrderedLayout#getDefaultOrientation()
*/
protected int getDefaultOrientation() {
return PositionConstants.VERTICAL;
}
/**
* @return the spacing between children
*/
public int getSpacing() {
return spacing;
}
/**
* @see org.eclipse.draw2d.AbstractHintLayout#isSensitiveHorizontally(IFigure)
*/
protected boolean isSensitiveHorizontally(IFigure parent) {
return !isHorizontal();
}
/**
* @see org.eclipse.draw2d.AbstractHintLayout#isSensitiveVertically(IFigure)
*/
protected boolean isSensitiveVertically(IFigure parent) {
return isHorizontal();
}
/**
* Returns true
if stretch minor axis has been enabled. The
* default value is false.
*
* @return true
if stretch minor axis is enabled
* @deprecated Use {@link #isStretchMinorAxis()} instead.
*/
public boolean getStretchMinorAxis() {
return isStretchMinorAxis();
}
/**
* Overwritten to guarantee backwards compatibility with {@link #matchWidth}
* field.
*
* @see org.eclipse.draw2d.OrderedLayout#isStretchMinorAxis()
*/
public boolean isStretchMinorAxis() {
return matchWidth;
}
/**
* @see org.eclipse.draw2d.LayoutManager#layout(IFigure)
*/
public void layout(IFigure parent) {
List children = parent.getChildren();
int numChildren = children.size();
Rectangle clientArea = transposer.t(parent.getClientArea());
int x = clientArea.x;
int y = clientArea.y;
int availableHeight = clientArea.height;
Dimension prefSizes[] = new Dimension[numChildren];
Dimension minSizes[] = new Dimension[numChildren];
// Calculate the width and height hints. If it's a vertical
// ToolBarLayout,
// then ignore the height hint (set it to -1); otherwise, ignore the
// width hint. These hints will be passed to the children of the parent
// figure when getting their preferred size.
int wHint = -1;
int hHint = -1;
if (isHorizontal()) {
hHint = parent.getClientArea(Rectangle.SINGLETON).height;
} else {
wHint = parent.getClientArea(Rectangle.SINGLETON).width;
}
/*
* Calculate sum of preferred heights of all children(totalHeight).
* Calculate sum of minimum heights of all children(minHeight). Cache
* Preferred Sizes and Minimum Sizes of all children.
*
* totalHeight is the sum of the preferred heights of all children
* totalMinHeight is the sum of the minimum heights of all children
* prefMinSumHeight is the sum of the difference between all children's
* preferred heights and minimum heights. (This is used as a ratio to
* calculate how much each child will shrink).
*/
IFigure child;
int totalHeight = 0;
int totalMinHeight = 0;
int prefMinSumHeight = 0;
for (int i = 0; i < numChildren; i++) {
child = (IFigure) children.get(i);
prefSizes[i] = transposer.t(getChildPreferredSize(child, wHint,
hHint));
minSizes[i] = transposer
.t(getChildMinimumSize(child, wHint, hHint));
totalHeight += prefSizes[i].height;
totalMinHeight += minSizes[i].height;
}
totalHeight += (numChildren - 1) * spacing;
totalMinHeight += (numChildren - 1) * spacing;
prefMinSumHeight = totalHeight - totalMinHeight;
/*
* The total amount that the children must be shrunk is the sum of the
* preferred Heights of the children minus Max(the available area and
* the sum of the minimum heights of the children).
*
* amntShrinkHeight is the combined amount that the children must shrink
* amntShrinkCurrentHeight is the amount each child will shrink
* respectively
*/
int amntShrinkHeight = totalHeight
- Math.max(availableHeight, totalMinHeight);
if (amntShrinkHeight < 0) {
amntShrinkHeight = 0;
}
for (int i = 0; i < numChildren; i++) {
int amntShrinkCurrentHeight = 0;
int prefHeight = prefSizes[i].height;
int minHeight = minSizes[i].height;
int prefWidth = prefSizes[i].width;
int minWidth = minSizes[i].width;
Rectangle newBounds = new Rectangle(x, y, prefWidth, prefHeight);
child = (IFigure) children.get(i);
if (prefMinSumHeight != 0)
amntShrinkCurrentHeight = (prefHeight - minHeight)
* amntShrinkHeight / (prefMinSumHeight);
int width = Math.min(prefWidth,
transposer.t(child.getMaximumSize()).width);
if (isStretchMinorAxis())
width = transposer.t(child.getMaximumSize()).width;
width = Math.max(minWidth, Math.min(clientArea.width, width));
newBounds.width = width;
int adjust = clientArea.width - width;
switch (getMinorAlignment()) {
case ALIGN_TOPLEFT:
adjust = 0;
break;
case ALIGN_CENTER:
adjust /= 2;
break;
case ALIGN_BOTTOMRIGHT:
break;
}
newBounds.x += adjust;
newBounds.height -= amntShrinkCurrentHeight;
child.setBounds(transposer.t(newBounds));
amntShrinkHeight -= amntShrinkCurrentHeight;
prefMinSumHeight -= (prefHeight - minHeight);
y += newBounds.height + spacing;
}
}
/**
* Sets children's width (if vertically oriented) or height (if horizontally
* oriented) to stretch with their container.
*
* @deprecated use {@link #setStretchMinorAxis(boolean)}
* @param match
* whether to stretch children
* @since 2.0
*/
public void setMatchWidth(boolean match) {
matchWidth = match;
}
/**
* Sets the amount of space between children.
*
* @param space
* the amount of space between children
* @since 2.0
*/
public void setSpacing(int space) {
spacing = space;
}
/**
* Overwritten to guarantee backwards compatibility with {@link #matchWidth}
* field.
*
* @see org.eclipse.draw2d.OrderedLayout#setStretchMinorAxis(boolean)
*/
public void setStretchMinorAxis(boolean value) {
matchWidth = value;
}
/**
* Sets the orientation of the layout
*
* @param flag
* whether the orientation should be vertical
* @since 2.0
* @deprecated Use {@link #setHorizontal(boolean)} with argument
* false
instead.
*/
public void setVertical(boolean flag) {
setHorizontal(!flag);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy