/*******************************************************************************
* Copyright (c) 2000, 2005 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;
/**
* This class handles the calculation of solving for the area of a
* {@link org.eclipse.draw2d.ScrollPane}'s viewport and insets. Also determines if
* the horizontal and vertical scrollbars should be visible.
*/
public class ScrollPaneSolver {
/** Scrollbar visibility constants -- never show scrollbars **/
public static final int NEVER = 0;
/** Scrollbar visibility constants -- show scrollbars automatically **/
public static final int AUTOMATIC = 1;
/** Scrollbar visibility constants -- always show scrollbars **/
public static final int ALWAYS = 2;
/**
* Container class for the results of ScrollPaneSolver's solve method
*/
public static class Result {
/** Show horizontal scrollbar boolean **/
public boolean showH;
/** Show vertical scrollbar boolean **/
public boolean showV;
/** Area of ScrollPane's viewport **/
public Rectangle viewportArea;
/** Insets of ScrollPane **/
public Insets insets;
}
/**
* Solves for the viewport area, insets, and visibility of horizontal and vertical
* scrollbars of a ScrollPane
* @param clientArea The ScrollPane's client area
* @param viewport The ScrollPane's Viewport
* @param hVis Horizontal scrollbar visibility
* @param vVis Vertical scrollbar visibility
* @param vBarWidth Width of vertical scrollbar
* @param hBarHeight Height of horizontal scrollbar
* @return the Result
*/
public static Result solve(Rectangle clientArea, Viewport viewport, int hVis, int vVis,
int vBarWidth, int hBarHeight) {
Result result = new Result();
result.insets = new Insets();
result.insets.bottom = hBarHeight;
result.insets.right = vBarWidth;
Dimension available = clientArea.getSize();
Dimension guaranteed = new Dimension(available).shrink(
(vVis == NEVER ? 0 : result.insets.right),
(hVis == NEVER ? 0 : result.insets.bottom));
guaranteed.width = Math.max(guaranteed.width, 0);
guaranteed.height = Math.max(guaranteed.height, 0);
int wHint = guaranteed.width;
int hHint = guaranteed.height;
Dimension preferred = viewport.getPreferredSize(wHint, hHint).getCopy();
Insets viewportInsets = viewport.getInsets();
/*
* This was calling viewport.getMinimumSize(), but viewport's minimum size was really
* small, and wasn't a function of its contents.
*/
Dimension viewportMinSize = new Dimension(
viewportInsets.getWidth(), viewportInsets.getHeight());
if (viewport.getContents() != null) {
if (viewport.getContentsTracksHeight() && hHint > -1)
hHint = Math.max(0, hHint - viewportInsets.getHeight());
if (viewport.getContentsTracksWidth() && wHint > -1)
wHint = Math.max(0, wHint - viewportInsets.getWidth());
viewportMinSize.expand(
viewport.getContents().getMinimumSize(wHint, hHint));
}
/*
* Adjust preferred size if tracking flags set. Basically, tracking == "compress view
* until its minimum size is reached".
*/
if (viewport.getContentsTracksHeight())
preferred.height = viewportMinSize.height;
if (viewport.getContentsTracksWidth())
preferred.width = viewportMinSize.width;
boolean none = available.contains(preferred),
both = !none && preferred.containsProper(guaranteed),
showV = both || preferred.height > available.height,
showH = both || preferred.width > available.width;
//Adjust for visibility override flags
result.showV = vVis != NEVER && (showV || vVis == ALWAYS);
result.showH = hVis != NEVER && (showH || hVis == ALWAYS);
if (!result.showV)
result.insets.right = 0;
if (!result.showH)
result.insets.bottom = 0;
result.viewportArea = clientArea.getCropped(result.insets);
viewport.setBounds(result.viewportArea);
return result;
}
}