/******************************************************************************* * 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; } } }