/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.custom;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
 * A ScrolledComposite provides scrollbars and will scroll its content when the user
 * uses the scrollbars.
 *
 *
 * <p>There are two ways to use the ScrolledComposite:
 *
 * <p>
 * 1) Set the size of the control that is being scrolled and the ScrolledComposite
 * will show scrollbars when the contained control can not be fully seen.
 *
 * 2) The second way imitates the way a browser would work.  Set the minimum size of
 * the control and the ScrolledComposite will show scroll bars if the visible area is
 * less than the minimum size of the control and it will expand the size of the control
 * if the visible area is greater than the minimum size.  This requires invoking
 * both setMinWidth(), setMinHeight() and setExpandHorizontal(), setExpandVertical().
 *
 * <code><pre>
 * public static void main (String [] args) {
 *      Display display = new Display ();
 *      Color red = display.getSystemColor(SWT.COLOR_RED);
 *      Color blue = display.getSystemColor(SWT.COLOR_BLUE);
 *      Shell shell = new Shell (display);
 *      shell.setLayout(new FillLayout());
 *
 *      // set the size of the scrolled content - method 1
 *      final ScrolledComposite sc1 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
 *      final Composite c1 = new Composite(sc1, SWT.NONE);
 *      sc1.setContent(c1);
 *      c1.setBackground(red);
 *      GridLayout layout = new GridLayout();
 *      layout.numColumns = 4;
 *      c1.setLayout(layout);
 *      Button b1 = new Button (c1, SWT.PUSH);
 *      b1.setText("first button");
 *      c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *
 *      // set the minimum width and height of the scrolled content - method 2
 *      final ScrolledComposite sc2 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
 *      sc2.setExpandHorizontal(true);
 *      sc2.setExpandVertical(true);
 *      final Composite c2 = new Composite(sc2, SWT.NONE);
 *      sc2.setContent(c2);
 *      c2.setBackground(blue);
 *      layout = new GridLayout();
 *      layout.numColumns = 4;
 *      c2.setLayout(layout);
 *      Button b2 = new Button (c2, SWT.PUSH);
 *      b2.setText("first button");
 *      sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *
 *      Button add = new Button (shell, SWT.PUSH);
 *      add.setText("add children");
 *      final int[] index = new int[]{0};
 *      add.addListener(SWT.Selection, new Listener() {
 *          public void handleEvent(Event e) {
 *              index[0]++;
 *              Button button = new Button(c1, SWT.PUSH);
 *              button.setText("button "+index[0]);
 *              // reset size of content so children can be seen - method 1
 *              c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *              c1.layout();
 *
 *              button = new Button(c2, SWT.PUSH);
 *              button.setText("button "+index[0]);
 *              // reset the minimum width and height so children can be seen - method 2
 *              sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *              c2.layout();
 *          }
 *      });
 *
 *      shell.open ();
 *      while (!shell.isDisposed ()) {
 *          if (!display.readAndDispatch ()) display.sleep ();
 *      }
 *      display.dispose ();
 * }
 * </pre></code>
 *
 * <dl>
 * <dt><b>Styles:</b><dd>H_SCROLL, V_SCROLL
 * </dl>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#scrolledcomposite">ScrolledComposite snippets</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 */
public class ScrolledComposite extends Composite {

	Control content;
	Listener contentListener;
	Listener filter;

	int minHeight = 0;
	int minWidth = 0;
	boolean expandHorizontal = false;
	boolean expandVertical = false;
	boolean alwaysShowScroll = false;
	boolean showFocusedControl = false;
	boolean showNextFocusedControl = true;

/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a widget which will be the parent of the new instance (cannot be null)
 * @param style the style of widget to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 * </ul>
 *
 * @see SWT#H_SCROLL
 * @see SWT#V_SCROLL
 * @see #getStyle()
 */
public ScrolledComposite(Composite parent, int style) {
	super(parent, checkStyle(style));
	super.setLayout(new ScrolledCompositeLayout());
	ScrollBar hBar = getHorizontalBar ();
	if (hBar != null) {
		hBar.setVisible(false);
		hBar.addListener (SWT.Selection, e -> hScroll());
	}

	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) {
		vBar.setVisible(false);
		vBar.addListener (SWT.Selection, e -> vScroll());
	}

	contentListener = e -> {
		if (e.type != SWT.Resize) return;
		layout(false);
	};

	filter = event -> {
		if (event.type == SWT.FocusIn) {
			if (!showNextFocusedControl) {
				showNextFocusedControl = true;
			} else if (event.widget instanceof Control) {
				Control control = (Control) event.widget;
				if (contains(control)) showControl(control);
			}
		} else {
			Widget w = event.widget;
			if (w instanceof Control) {
				showNextFocusedControl = w.getDisplay().getActiveShell() == ((Control) w).getShell();
			}
		}
	};

	addDisposeListener(e -> {
		getDisplay().removeFilter(SWT.FocusIn, filter);
		getDisplay().removeFilter(SWT.FocusOut, filter);
	});
}

static int checkStyle (int style) {
	int mask = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
	return style & mask;
}

boolean contains(Control control) {
	if (control == null || control.isDisposed()) return false;

	Composite parent = control.getParent();
	while (parent != null && !(parent instanceof Shell)) {
		if (this == parent) return true;
		parent = parent.getParent();
	}
	return false;
}

/**
 * Returns the Always Show Scrollbars flag.  True if the scrollbars are
 * always shown even if they are not required.  False if the scrollbars are only
 * visible when some part of the composite needs to be scrolled to be seen.
 * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the
 * horizontal and vertical directions.
 *
 * @return the Always Show Scrollbars flag value
 */
public boolean getAlwaysShowScrollBars() {
	/*
	 * This call is intentionally commented out, to allow this getter method to be
	 * called from a thread which is different from one that created the widget.
	 */
	//checkWidget();
	return alwaysShowScroll;
}

/**
 * Returns <code>true</code> if the content control
 * will be expanded to fill available horizontal space.
 *
 * @return the receiver's horizontal expansion state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.2
 */
public boolean getExpandHorizontal() {
	checkWidget();
	return expandHorizontal;
}

/**
 * Returns <code>true</code> if the content control
 * will be expanded to fill available vertical space.
 *
 * @return the receiver's vertical expansion state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.2
 */
public boolean getExpandVertical() {
	checkWidget();
	return expandVertical;
}

/**
 * Returns the minimum width of the content control.
 *
 * @return the minimum width
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.2
 */
public int getMinWidth() {
	checkWidget();
	return minWidth;
}

/**
 * Returns the minimum height of the content control.
 *
 * @return the minimum height
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.2
 */
public int getMinHeight() {
	checkWidget();
	return minHeight;
}

/**
 * Get the content that is being scrolled.
 *
 * @return the control displayed in the content area
 */
public Control getContent() {
	/*
	 * This call is intentionally commented out, to allow this getter method to be
	 * called from a thread which is different from one that created the widget.
	 */
	//checkWidget();
	return content;
}

/**
 * Returns <code>true</code> if the receiver automatically scrolls to a focused child control
 * to make it visible. Otherwise, returns <code>false</code>.
 *
 * @return a boolean indicating whether focused child controls are automatically scrolled into the viewport
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.4
 */
public boolean getShowFocusedControl() {
	checkWidget();
	return showFocusedControl;
}

void hScroll() {
	if (content == null) return;
	Point location = content.getLocation ();
	ScrollBar hBar = getHorizontalBar ();
	int hSelection = hBar.getSelection ();
	content.setLocation (-hSelection, location.y);
}
boolean needHScroll(Rectangle contentRect, boolean vVisible) {
	ScrollBar hBar = getHorizontalBar();
	if (hBar == null) return false;

	Rectangle hostRect = getBounds();
	int border = getBorderWidth();
	hostRect.width -= 2*border;
	ScrollBar vBar = getVerticalBar();
	if (vVisible && vBar != null) hostRect.width -= vBar.getSize().x;

	if (!expandHorizontal && contentRect.width > hostRect.width) return true;
	if (expandHorizontal && minWidth > hostRect.width) return true;
	return false;
}

boolean needVScroll(Rectangle contentRect, boolean hVisible) {
	ScrollBar vBar = getVerticalBar();
	if (vBar == null) return false;

	Rectangle hostRect = getBounds();
	int border = getBorderWidth();
	hostRect.height -= 2*border;
	ScrollBar hBar = getHorizontalBar();
	if (hVisible && hBar != null) hostRect.height -= hBar.getSize().y;

	if (!expandVertical && contentRect.height > hostRect.height) return true;
	if (expandVertical && minHeight > hostRect.height) return true;
	return false;
}

/**
 * Return the point in the content that currently appears in the top left
 * corner of the scrolled composite.
 *
 * @return the point in the content that currently appears in the top left
 * corner of the scrolled composite.  If no content has been set, this returns
 * (0, 0).
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 2.0
 */
public Point getOrigin() {
	checkWidget();
	if (content == null) return new Point(0, 0);
	Point location = content.getLocation();
	return new Point(-location.x, -location.y);
}
/**
 * Scrolls the content so that the specified point in the content is in the top
 * left corner.  If no content has been set, nothing will occur.
 *
 * Negative values will be ignored.  Values greater than the maximum scroll
 * distance will result in scrolling to the end of the scrollbar.
 *
 * @param origin the point on the content to appear in the top left corner
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_INVALID_ARGUMENT - value of origin is outside of content
 * </ul>
 * @since 2.0
 */
public void setOrigin(Point origin) {
	setOrigin(origin.x, origin.y);
}
/**
 * Scrolls the content so that the specified point in the content is in the top
 * left corner.  If no content has been set, nothing will occur.
 *
 * Negative values will be ignored.  Values greater than the maximum scroll
 * distance will result in scrolling to the end of the scrollbar.
 *
 * @param x the x coordinate of the content to appear in the top left corner
 *
 * @param y the y coordinate of the content to appear in the top left corner
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 2.0
 */
public void setOrigin(int x, int y) {
	checkWidget();
	if (content == null) return;
	ScrollBar hBar = getHorizontalBar ();
	if (hBar != null) {
		hBar.setSelection(x);
		x = -hBar.getSelection ();
	} else {
		x = 0;
	}
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null) {
		vBar.setSelection(y);
		y = -vBar.getSelection ();
	} else {
		y = 0;
	}
	content.setLocation(x, y);
}
/**
 * Set the Always Show Scrollbars flag.  True if the scrollbars are
 * always shown even if they are not required.  False if the scrollbars are only
 * visible when some part of the composite needs to be scrolled to be seen.
 * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the
 * horizontal and vertical directions.
 *
 * @param show true to show the scrollbars even when not required, false to show scrollbars only when required
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setAlwaysShowScrollBars(boolean show) {
	checkWidget();
	if (show == alwaysShowScroll) return;
	alwaysShowScroll = show;
	ScrollBar hBar = getHorizontalBar ();
	if (hBar != null && alwaysShowScroll) hBar.setVisible(true);
	ScrollBar vBar = getVerticalBar ();
	if (vBar != null && alwaysShowScroll) vBar.setVisible(true);
	layout(false);
}

/**
 * Set the content that will be scrolled.
 *
 * @param content the control to be displayed in the content area
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setContent(Control content) {
	checkWidget();
	if (this.content != null && !this.content.isDisposed()) {
		this.content.removeListener(SWT.Resize, contentListener);
		this.content.setBounds(new Rectangle(-200, -200, 0, 0));
	}

	this.content = content;
	ScrollBar vBar = getVerticalBar ();
	ScrollBar hBar = getHorizontalBar ();
	if (this.content != null) {
		if (vBar != null) {
			vBar.setMaximum (0);
			vBar.setThumb (0);
			vBar.setSelection(0);
		}
		if (hBar != null) {
			hBar.setMaximum (0);
			hBar.setThumb (0);
			hBar.setSelection(0);
		}
		content.setLocation(0, 0);
		layout(false);
		this.content.addListener(SWT.Resize, contentListener);
	} else {
		if (hBar != null) hBar.setVisible(alwaysShowScroll);
		if (vBar != null) vBar.setVisible(alwaysShowScroll);
	}
}
/**
 * Configure the ScrolledComposite to resize the content object to be as wide as the
 * ScrolledComposite when the width of the ScrolledComposite is greater than the
 * minimum width specified in setMinWidth.  If the ScrolledComposite is less than the
 * minimum width, the content will not be resized and instead the horizontal scroll bar will be
 * used to view the entire width.
 * If expand is false, this behaviour is turned off.  By default, this behaviour is turned off.
 *
 * @param expand true to expand the content control to fill available horizontal space
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setExpandHorizontal(boolean expand) {
	checkWidget();
	if (expand == expandHorizontal) return;
	expandHorizontal = expand;
	layout(false);
}
/**
 * Configure the ScrolledComposite to resize the content object to be as tall as the
 * ScrolledComposite when the height of the ScrolledComposite is greater than the
 * minimum height specified in setMinHeight.  If the ScrolledComposite is less than the
 * minimum height, the content will not be resized and instead the vertical scroll bar will be
 * used to view the entire height.
 * If expand is false, this behaviour is turned off.  By default, this behaviour is turned off.
 *
 * @param expand true to expand the content control to fill available vertical space
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setExpandVertical(boolean expand) {
	checkWidget();
	if (expand == expandVertical) return;
	expandVertical = expand;
	layout(false);
}
/**
 * Sets the layout which is associated with the receiver to be
 * the argument which may be null.
 * <p>
 * Note: No Layout can be set on this Control because it already
 * manages the size and position of its children.
 * </p>
 *
 * @param layout the receiver's new layout or null
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
@Override
public void setLayout (Layout layout) {
	checkWidget();
	return;
}
/**
 * Specify the minimum height at which the ScrolledComposite will begin scrolling the
 * content with the vertical scroll bar.  This value is only relevant if
 * setExpandVertical(true) has been set.
 *
 * @param height the minimum height or 0 for default height
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setMinHeight(int height) {
	setMinSize(minWidth, height);
}
/**
 * Specify the minimum width and height at which the ScrolledComposite will begin scrolling the
 * content with the horizontal scroll bar.  This value is only relevant if
 * setExpandHorizontal(true) and setExpandVertical(true) have been set.
 *
 * @param size the minimum size or null for the default size
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setMinSize(Point size) {
	if (size == null) {
		setMinSize(0, 0);
	} else {
		setMinSize(size.x, size.y);
	}
}
/**
 * Specify the minimum width and height at which the ScrolledComposite will begin scrolling the
 * content with the horizontal scroll bar.  This value is only relevant if
 * setExpandHorizontal(true) and setExpandVertical(true) have been set.
 *
 * @param width the minimum width or 0 for default width
 * @param height the minimum height or 0 for default height
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setMinSize(int width, int height) {
	checkWidget();
	if (width == minWidth && height == minHeight) return;
	minWidth = Math.max(0, width);
	minHeight = Math.max(0, height);
	layout(false);
}
/**
 * Specify the minimum width at which the ScrolledComposite will begin scrolling the
 * content with the horizontal scroll bar.  This value is only relevant if
 * setExpandHorizontal(true) has been set.
 *
 * @param width the minimum width or 0 for default width
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setMinWidth(int width) {
	setMinSize(width, minHeight);
}

/**
 * Configure the receiver to automatically scroll to a focused child control
 * to make it visible.
 *
 * If show is <code>false</code>, show a focused control is off.
 * By default, show a focused control is off.
 *
 * @param show <code>true</code> to show a focused control.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.4
 */
public void setShowFocusedControl(boolean show) {
	checkWidget();
	if (showFocusedControl == show) return;
	Display display = getDisplay();
	display.removeFilter(SWT.FocusIn, filter);
	display.removeFilter(SWT.FocusOut, filter);
	showFocusedControl = show;
	if (!showFocusedControl) return;
	display.addFilter(SWT.FocusIn, filter);
	display.addFilter(SWT.FocusOut, filter);
	Control control = display.getFocusControl();
	if (contains(control)) showControl(control);
}

/**
 * Scrolls the content of the receiver so that the control is visible.
 *
 * @param control the control to be shown
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the control is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.4
 */
public void showControl(Control control) {
	checkWidget ();
	if (control == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (control.isDisposed ()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	if (!contains(control)) SWT.error(SWT.ERROR_INVALID_ARGUMENT);

	Rectangle itemRect = getDisplay().map(control.getParent(), this, control.getBounds());
	Rectangle area = getClientArea();
	Point origin = getOrigin();
	if (itemRect.x < 0) {
		origin.x = Math.max(0, origin.x + itemRect.x);
	} else {
		if (area.width < itemRect.x + itemRect.width) origin.x = Math.max(0, origin.x + itemRect.x + Math.min(itemRect.width, area.width) - area.width);
	}
	if (itemRect.y < 0) {
		origin.y = Math.max(0, origin.y + itemRect.y);
	} else {
		if (area.height < itemRect.y + itemRect.height) origin.y = Math.max(0, origin.y + itemRect.y + Math.min(itemRect.height, area.height) - area.height);
	}
	setOrigin(origin);
}

void vScroll() {
	if (content == null) return;
	Point location = content.getLocation ();
	ScrollBar vBar = getVerticalBar ();
	int vSelection = vBar.getSelection ();
	content.setLocation (location.x, -vSelection);
}
}
