blob: df2fbc79052ff9e078c3550ba70e5359c930f3a4 [file] [log] [blame]
/*******************************************************************************
* 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 org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.geometry.Transposer;
/**
* Lays out the Figures that make up a ScrollBar.
*/
public class ScrollBarLayout extends AbstractLayout {
/** Used as a constraint for the up arrow figure. */
public static final String UP_ARROW = "up arrow"; //$NON-NLS-1$
/** Used as a constraint for the down arrow figure. */
public static final String DOWN_ARROW = "down arrow"; //$NON-NLS-1$
/** Used as a constraint for the thumb figure. */
public static final String THUMB = "thumb"; //$NON-NLS-1$
/** Used as a constraint for the page up figure. */
public static final String PAGE_UP = "page_up"; //$NON-NLS-1$
/** Used as a constraint for the page down figure. */
public static final String PAGE_DOWN = "page_down"; //$NON-NLS-1$
IFigure up, down, thumb, pageUp, pageDown;
/**
* Transposes values if the ScrollBar is horizontally oriented. When used
* properly, the layout manager just needs to code for one case: vertical
* orientation.
*/
protected final Transposer transposer;
/**
* Constructs a ScrollBarLayout. If the given Transposer is enabled, the
* Scrollbar will be horizontally oriented. Otherwise, the ScrollBar will be
* vertically oriented.
*
* @param t
* the Transposer
* @since 2.0
*/
public ScrollBarLayout(Transposer t) {
transposer = t;
}
/**
* @see AbstractLayout#setConstraint(IFigure, Object)
*/
public void setConstraint(IFigure figure, Object constraint) {
if (constraint.equals(UP_ARROW))
up = figure;
else if (constraint.equals(DOWN_ARROW))
down = figure;
else if (constraint.equals(THUMB))
thumb = figure;
else if (constraint.equals(PAGE_UP))
pageUp = figure;
else if (constraint.equals(PAGE_DOWN))
pageDown = figure;
}
/**
* @see AbstractLayout#calculatePreferredSize(IFigure, int, int)
*/
protected Dimension calculatePreferredSize(IFigure parent, int w, int h) {
Insets insets = transposer.t(parent.getInsets());
Dimension d = new Dimension(16, 16 * 4);
d.expand(insets.getWidth(), insets.getHeight());
return transposer.t(d);
}
/**
* @see LayoutManager#layout(IFigure)
*/
public void layout(IFigure parent) {
ScrollBar scrollBar = (ScrollBar) parent;
Rectangle trackBounds = layoutButtons(scrollBar);
int extent = scrollBar.getExtent();
int max = scrollBar.getMaximum();
int min = scrollBar.getMinimum();
int totalRange = max - min;
int valueRange = totalRange - extent;
if ((valueRange < 1) || (!scrollBar.isEnabled())) {
Rectangle boundsUpper = new Rectangle(trackBounds), boundsLower = new Rectangle(
trackBounds);
boundsUpper.height /= 2;
boundsLower.y += boundsUpper.height;
boundsLower.height = trackBounds.height - boundsUpper.height;
if (pageUp != null)
pageUp.setBounds(transposer.t(boundsUpper));
if (pageDown != null)
pageDown.setBounds(transposer.t(boundsLower));
return;
}
if (totalRange == 0)
return;
int thumbHeight = Math.max(thumb == null ? 0
: thumb.getMinimumSize().height, trackBounds.height * extent
/ totalRange);
if (thumb != null)
thumb.setVisible(trackBounds.height > thumbHeight);
int thumbY = trackBounds.y + (trackBounds.height - thumbHeight)
* (scrollBar.getValue() - min) / valueRange;
Rectangle thumbBounds = new Rectangle(trackBounds.x, thumbY,
trackBounds.width, thumbHeight);
if (thumb != null)
thumb.setBounds(transposer.t(thumbBounds));
if (pageUp != null)
pageUp.setBounds(transposer.t(new Rectangle(trackBounds.x,
trackBounds.y, trackBounds.width, thumbBounds.y
- trackBounds.y)));
if (pageDown != null)
pageDown.setBounds(transposer.t(new Rectangle(trackBounds.x,
thumbBounds.y + thumbHeight, trackBounds.width, trackBounds
.bottom() - thumbBounds.bottom())));
}
/**
* Places the buttons and returns the Rectangle into which the track should
* be placed. The track consists of the pageup, pagedown, and thumb figures.
* The Rectangle returned should be transposed correctly, that is, it should
* be vertically oriented. Users of the rectangle will re-transpose it for
* horizontal use.
*
* @param scrollBar
* the scrollbar whose buttons are being layed out
* @return the Rectangle into which the track should be placed
* @since 2.0
*/
protected Rectangle layoutButtons(ScrollBar scrollBar) {
Rectangle bounds = transposer.t(scrollBar.getClientArea());
Dimension buttonSize = new Dimension(bounds.width, Math.min(
bounds.width, bounds.height / 2));
if (up != null)
up.setBounds(transposer.t(new Rectangle(bounds.getTopLeft(),
buttonSize)));
if (down != null) {
Rectangle r = new Rectangle(bounds.x, bounds.bottom()
- buttonSize.height, buttonSize.width, buttonSize.height);
down.setBounds(transposer.t(r));
}
Rectangle trackBounds = bounds.getCropped(new Insets((up == null) ? 0
: buttonSize.height, 0, (down == null) ? 0 : buttonSize.height,
0));
return trackBounds;
}
/**
* @see LayoutManager#remove(IFigure)
*/
public void remove(IFigure child) {
if (child == up) {
up = null;
} else if (child == down) {
down = null;
} else if (child == thumb) {
thumb = null;
} else if (child == pageUp) {
pageUp = null;
} else if (child == pageDown) {
pageDown = null;
}
}
}