/******************************************************************************* * 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 * Intershop, Gunnar Wagenknecht - fix for 44288 *******************************************************************************/ package org.eclipse.gef.editparts; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.Viewport; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.AutoexposeHelper; import org.eclipse.gef.GraphicalEditPart; /** * An implementation of {@link org.eclipse.gef.AutoexposeHelper} that performs * autoscrolling of a <code>Viewport</code> figure. This helper is for use with * graphical editparts that contain a viewport figure. This helper will search the * editpart and find the viewport. Autoscroll will occur when the detect location is * inside the viewport's bounds, but near its edge. It will continue for as long as the * location continues to meet these criteria. The autoscroll direction is approximated to * the nearest orthogonal or diagonal direction (north, northeast, east, etc.). * * @author hudsonr */ public class ViewportAutoexposeHelper extends ViewportHelper implements AutoexposeHelper { /** defines the range where autoscroll is active inside a viewer */ private static final Insets DEFAULT_EXPOSE_THRESHOLD = new Insets(18); /** the last time an auto expose was performed */ private long lastStepTime = 0; /** The insets for this helper. */ private Insets threshold; /** * Constructs a new helper on the given GraphicalEditPart. The editpart must have a * <code>Viewport</code> somewhere between its <i>contentsPane</i> and its <i>figure</i> * inclusively. * @param owner the GraphicalEditPart that owns the Viewport */ public ViewportAutoexposeHelper(GraphicalEditPart owner) { super(owner); threshold = DEFAULT_EXPOSE_THRESHOLD; } /** * Constructs a new helper on the given GraphicalEditPart. The editpart must have a * <code>Viewport</code> somewhere between its <i>contentsPane</i> and its <i>figure</i> * inclusively. * @param owner the GraphicalEditPart that owns the Viewport * @param threshold the Expose Threshold to use when determing whether or not a scroll * should occur. */ public ViewportAutoexposeHelper(GraphicalEditPart owner, Insets threshold) { super(owner); this.threshold = threshold; } /** * Returns <code>true</code> if the given point is inside the viewport, but near its edge. * @see org.eclipse.gef.AutoexposeHelper#detect(org.eclipse.draw2d.geometry.Point) */ public boolean detect(Point where) { lastStepTime = 0; Viewport port = findViewport(owner); Rectangle rect = Rectangle.SINGLETON; port.getClientArea(rect); port.translateToParent(rect); port.translateToAbsolute(rect); return rect.contains(where) && !rect.crop(threshold).contains(where); } /** * Returns <code>true</code> if the given point is outside the viewport or near its edge. * Scrolls the viewport by a calculated (time based) amount in the current direction. * * todo: investigate if we should allow auto expose when the pointer is outside the viewport * * @see org.eclipse.gef.AutoexposeHelper#step(org.eclipse.draw2d.geometry.Point) */ public boolean step(Point where) { Viewport port = findViewport(owner); Rectangle rect = Rectangle.SINGLETON; port.getClientArea(rect); port.translateToParent(rect); port.translateToAbsolute(rect); if (!rect.contains(where) || rect.crop(threshold).contains(where)) return false; // set scroll offset (speed factor) int scrollOffset = 0; // calculate time based scroll offset if (lastStepTime == 0) lastStepTime = System.currentTimeMillis(); long difference = System.currentTimeMillis() - lastStepTime; if (difference > 0) { scrollOffset = ((int) difference / 3); lastStepTime = System.currentTimeMillis(); } if (scrollOffset == 0) return true; rect.crop(threshold); int region = rect.getPosition(where); Point loc = port.getViewLocation(); if ((region & PositionConstants.SOUTH) != 0) loc.y += scrollOffset; else if ((region & PositionConstants.NORTH) != 0) loc.y -= scrollOffset; if ((region & PositionConstants.EAST) != 0) loc.x += scrollOffset; else if ((region & PositionConstants.WEST) != 0) loc.x -= scrollOffset; port.setViewLocation(loc); return true; } /** * @see java.lang.Object#toString() */ public String toString() { return "ViewportAutoexposeHelper for: " + owner; //$NON-NLS-1$ } }