/******************************************************************************* * 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 java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.draw2d.geometry.Translatable; /** * A Viewport is a flexible window onto a {@link ScrollPane} and represents the visible * portion of the ScrollPane. */ public class Viewport extends Figure implements PropertyChangeListener { /** ID for the view location property */ public static final String PROPERTY_VIEW_LOCATION = "viewLocation"; //$NON-NLS-1$ private IFigure view; private boolean useTranslate = false; private boolean trackWidth = false; private boolean trackHeight = false; private boolean ignoreScroll = false; private RangeModel horiztonalRangeModel = null, verticalRangeModel = null; { setLayoutManager(new ViewportLayout()); setHorizontalRangeModel(new DefaultRangeModel()); setVerticalRangeModel(new DefaultRangeModel()); } /** * Constructs a new Viewport with the default values. */ public Viewport() { } /** * Constructs a new Viewport. If <i>setting</i> is <code>true</code>, the viewport will * use graphics translation to paint. * @param setting whether to use graphics translation */ public Viewport(boolean setting) { useTranslate = setting; } /** * @see IFigure#getClientArea(Rectangle) */ public Rectangle getClientArea(Rectangle rect) { super.getClientArea(rect); if (useGraphicsTranslate()) rect.translate(getViewLocation()); return rect; } /** * Returns the view, which is the contents of the {@link ScrollPane} associated with this * Viewport. * * @return the contents * @since 2.0 */ public IFigure getContents() { return view; } /** * Returns the RangeModel associated with the horizontal motion of this Viewport * @return the RangeModel * * @since 2.0 */ public RangeModel getHorizontalRangeModel() { return horiztonalRangeModel; } /** * Returns <code>true</code> if the Viewport resizes itself in the vertical direction when * the available height of its view is decreased, false otherwise. This option is turned * off by default, and can be activated by calling * {@link #setContentsTracksHeight(boolean)} and passing in <code>true</code>. * * @return whether the contents tracks height * @since 2.0 */ public boolean getContentsTracksHeight() { return trackHeight; } /** * Returns <code>true</code> if the Viewport resizes itself in the horizontal direction * when the available width of its view is decreased, false otherwise. This option is * turned off by default, and can be activated by calling * {@link #setContentsTracksWidth(boolean)} and passing in <code>true</code>. * * @return whether the contents tracks width * @since 2.0 */ public boolean getContentsTracksWidth() { return trackWidth; } /** * Returns the range model associated with the vertical motion of the Viewport. * @return the RangeModel * * @since 2.0 */ public RangeModel getVerticalRangeModel() { return verticalRangeModel; } /** * Returns the current location of this Viewport. * @return the current location of this Viewport * * @since 2.0 */ public Point getViewLocation() { return new Point( getHorizontalRangeModel().getValue(), getVerticalRangeModel().getValue()); } private void localRevalidate() { invalidate(); if (getLayoutManager() != null) getLayoutManager().invalidate(); getUpdateManager().addInvalidFigure(this); } /** * @see Figure#paintClientArea(Graphics) */ protected void paintClientArea(Graphics g) { if (useGraphicsTranslate()) { Point p = getViewLocation(); try { g.translate(-p.x, -p.y); g.pushState(); super.paintClientArea(g); g.popState(); } finally { g.translate(p.x, p.y); } } else super.paintClientArea(g); } /** * @see org.eclipse.draw2d.Figure#isCoordinateSystem() */ public boolean isCoordinateSystem() { return useGraphicsTranslate() || super.isCoordinateSystem(); } /** * Listens for either of the {@link RangeModel RangeModels} to fire a property change * event and updates the view accordingly. * @param event the event */ public void propertyChange(PropertyChangeEvent event) { if (event.getSource() instanceof RangeModel) { if (RangeModel.PROPERTY_VALUE.equals(event.getPropertyName())) { if (!ignoreScroll) { localRevalidate(); if (useGraphicsTranslate()) { repaint(); fireMoved(); } } firePropertyChange(PROPERTY_VIEW_LOCATION, event.getOldValue(), event.getNewValue()); } } } /** * Sets extents of {@link RangeModel RangeModels} to the client area of this Viewport. * Sets RangeModel minimums to zero. Sets RangeModel maximums to this Viewport's * height/width. * * @since 2.0 */ protected void readjustScrollBars() { if (getContents() == null) return; getVerticalRangeModel().setAll(0, getClientArea().height, getContents().getBounds().height); getHorizontalRangeModel().setAll(0, getClientArea().width, getContents().getBounds().width); } /** * Sets this Viewport to be associated with the passed Figure. * * @param figure the new contents * @since 2.0 */ public void setContents(IFigure figure) { if (view == figure) return; if (view != null) remove(view); view = figure; if (view != null) add(figure); } /** * Toggles the Viewport's ability to resize itself automatically when its view is * decreased in size in the vertical direction. This is disabled by default. * * @param track whether this viewport should track its height * @since 2.0 */ public void setContentsTracksHeight(boolean track) { trackHeight = track; } /** * Toggles the Viewport's ability to resize itself automatically when its view is * decreased in size in the horizontal direction. This is disabled by default. * * @param track whether this viewport should track its width * @since 2.0 */ public void setContentsTracksWidth(boolean track) { trackWidth = track; } /** * Sets the horizontal location of the Viewport's view to the passed value. * * @param value the new horizontal location * @since 2.0 */ public void setHorizontalLocation(int value) { setViewLocation(value, getVerticalRangeModel().getValue()); } /** * Sets the horizontal range model to the passed RangeModel. * * @param rangeModel the new horizontal range model * @since 2.0 */ public void setHorizontalRangeModel(RangeModel rangeModel) { if (horiztonalRangeModel != null) horiztonalRangeModel.removePropertyChangeListener(this); horiztonalRangeModel = rangeModel; horiztonalRangeModel.addPropertyChangeListener(this); } /** * If <i>value</i> is <code>true</code>, this viewport will ignore any scrolling that * occurs until this method is called again with <code>false</code>. * * @param value whether this viewport should ignore future scrolls */ public void setIgnoreScroll(boolean value) { ignoreScroll = value; } /** * Sets the vertical location of the Viewport's view to the passed value. * * @param value the new vertical location * @since 2.0 */ public void setVerticalLocation(int value) { setViewLocation(getHorizontalRangeModel().getValue(), value); } /** * Sets the vertical range model to the passed RangeModel. * * @param rangeModel the new vertical RangeModel * @since 2.0 */ public void setVerticalRangeModel(RangeModel rangeModel) { if (verticalRangeModel != null) verticalRangeModel.removePropertyChangeListener(this); verticalRangeModel = rangeModel; verticalRangeModel.addPropertyChangeListener(this); } /** * Sets the location of the Viewport's view to the passed values. * * @param x The new x coordinate of the Viewport's view. * @param y The new y coordinate of the Viewport's view. * @since 2.0 */ public void setViewLocation(int x, int y) { if (getHorizontalRangeModel().getValue() != x) getHorizontalRangeModel().setValue(x); if (getVerticalRangeModel().getValue() != y) getVerticalRangeModel().setValue(y); } /** * Sets the location of the Viewport's view to the passed Point. * * @param p The new location of the Viewport's view. * @since 2.0 */ public void setViewLocation(Point p) { setViewLocation(p.x, p.y); } /** * @see IFigure#translateFromParent(Translatable) */ public void translateFromParent(Translatable t) { if (useTranslate) t.performTranslate( getHorizontalRangeModel().getValue(), getVerticalRangeModel().getValue() ); super.translateFromParent(t); } /** * @see IFigure#translateToParent(Translatable) */ public void translateToParent(Translatable t) { if (useTranslate) t.performTranslate( -getHorizontalRangeModel().getValue(), -getVerticalRangeModel().getValue() ); super.translateToParent(t); } /** * Returns <code>true</code> if this viewport uses graphics translation. * @return whether this viewport uses graphics translation */ public boolean useGraphicsTranslate() { return useTranslate; } /** * @see IFigure#validate() */ public void validate() { super.validate(); readjustScrollBars(); } }