| /******************************************************************************* |
| * 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.gef.editparts; |
| |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.Viewport; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Insets; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.gef.ExposeHelper; |
| import org.eclipse.gef.GraphicalEditPart; |
| |
| /** |
| * An implementation of <code>ExposeHelper</code> for use with editparts using a |
| * <code>Viewport</code>. |
| * |
| * @author hudsonr |
| * @since 2.0 |
| */ |
| public class ViewportExposeHelper extends ViewportHelper implements |
| ExposeHelper { |
| |
| private Insets exposeMargin; |
| private int minimumFrameCount = 3; |
| private int maximumFrameCount = 8; |
| |
| /** |
| * Constructs a new ViewportExposeHelper on the specified GraphicalEditPart. |
| * The GraphicalEditPart 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 ViewportExposeHelper(GraphicalEditPart owner) { |
| super(owner); |
| } |
| |
| /** |
| * Exposes the descendant EditPart by smoothly scrolling the |
| * <code>Viewport</code>. The smoothness is determined by the minimum and |
| * maximum frame count, and the overall amount being scrolled. |
| * |
| * @see org.eclipse.gef.ExposeHelper#exposeDescendant(EditPart) |
| */ |
| public void exposeDescendant(EditPart part) { |
| Viewport port = findViewport(owner); |
| if (port == null) |
| return; |
| IFigure target = ((GraphicalEditPart) part).getFigure(); |
| |
| /* |
| * All calculations are done relative to the contents of the viewport. |
| * The expose margin is added in absolute coordinates, and then taken |
| * back to relative viewport coordinates. |
| */ |
| Rectangle exposeRegion = target.getBounds().getCopy(); |
| target.translateToAbsolute(exposeRegion); |
| if (exposeMargin != null) |
| exposeRegion.expand(exposeMargin); |
| port.getContents().translateToRelative(exposeRegion); |
| |
| Point offset = port.getContents().getBounds().getLocation(); |
| // By substracting the offset, the region is now the difference from the |
| // contents origin. |
| exposeRegion.translate(offset.negate()); |
| exposeRegion.translate(port.getHorizontalRangeModel().getMinimum(), |
| port.getVerticalRangeModel().getMinimum()); |
| |
| Dimension viewportSize = port.getClientArea().getSize(); |
| Point topLeft = exposeRegion.getTopLeft(); |
| Point bottomRight = exposeRegion.getBottomRight().translate( |
| viewportSize.getNegated()); |
| |
| Point finalLocation = new Point(); |
| if (viewportSize.width < exposeRegion.width) |
| finalLocation.x = Math.min(bottomRight.x, |
| Math.max(topLeft.x, port.getViewLocation().x)); |
| else |
| finalLocation.x = Math.min(topLeft.x, |
| Math.max(bottomRight.x, port.getViewLocation().x)); |
| |
| if (viewportSize.height < exposeRegion.height) |
| finalLocation.y = Math.min(bottomRight.y, |
| Math.max(topLeft.y, port.getViewLocation().y)); |
| else |
| finalLocation.y = Math.min(topLeft.y, |
| Math.max(bottomRight.y, port.getViewLocation().y)); |
| |
| Point startLocation = port.getViewLocation(); |
| |
| int dx = finalLocation.x - startLocation.x; |
| int dy = finalLocation.y - startLocation.y; |
| |
| int frames = (Math.abs(dx) + Math.abs(dy)) / 15; |
| frames = Math.max(frames, getMinimumFrameCount()); |
| frames = Math.min(frames, getMaximumFrameCount()); |
| |
| int stepX = Math.min((dx / frames), (viewportSize.width / 3)); |
| int stepY = Math.min((dy / frames), (viewportSize.height / 3)); |
| |
| for (int i = 1; i < frames; i++) { |
| port.setViewLocation(startLocation.x + stepX * i, startLocation.y |
| + stepY * i); |
| port.getUpdateManager().performUpdate(); |
| } |
| port.setViewLocation(finalLocation); |
| } |
| |
| /** |
| * Returns the maximumFrameCount. |
| * |
| * @return int |
| */ |
| public int getMaximumFrameCount() { |
| return maximumFrameCount; |
| } |
| |
| /** |
| * Returns the minimumFrameCount. |
| * |
| * @return int |
| */ |
| public int getMinimumFrameCount() { |
| return minimumFrameCount; |
| } |
| |
| /** |
| * Sets the amount of margin to be left around the descendant being exposed. |
| * There is no margin by default. |
| * |
| * @param margin |
| * the margin in pixels |
| */ |
| public void setMargin(Insets margin) { |
| exposeMargin = margin; |
| } |
| |
| /** |
| * Sets the maximumFrameCount. |
| * |
| * @param maximumFrameCount |
| * The maximumFrameCount to set |
| */ |
| public void setMaximumFrameCount(int maximumFrameCount) { |
| this.maximumFrameCount = maximumFrameCount; |
| } |
| |
| /** |
| * Sets the minimumFrameCount. |
| * |
| * @param minimumFrameCount |
| * The minimumFrameCount to set |
| */ |
| public void setMinimumFrameCount(int minimumFrameCount) { |
| this.minimumFrameCount = minimumFrameCount; |
| if (getMaximumFrameCount() < minimumFrameCount) |
| setMaximumFrameCount(minimumFrameCount); |
| } |
| |
| } |