/******************************************************************************* * Copyright (c) 2000, 2007 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.ui.parts; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.draw2d.FigureCanvas; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.Viewport; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; /** * A Graphical Viewer implementation which uses a {@link org.eclipse.draw2d.FigureCanvas} * for native scrolling. Because the scrolling is handled natively, the root editpart * should not contain a {@link org.eclipse.draw2d.ScrollPane} figure. Do not use root * editparts which provide scrollpane figures, such as <code>GraphicalRootEditPart</code>. * <P> * The RootEditPart for a ScrollingGraphicalViewer may contain a Viewport. If it does, * that viewport will be set as the FigureCanvas' viewport. FigureCanvas has certain * requirements on the viewport figure, see {@link FigureCanvas#setViewport(Viewport)}. * @author hudsonr */ public class ScrollingGraphicalViewer extends GraphicalViewerImpl { /** * Constructs a ScrollingGraphicalViewer; */ public ScrollingGraphicalViewer() { } /** * @see org.eclipse.gef.EditPartViewer#createControl(org.eclipse.swt.widgets.Composite) */ public final Control createControl(Composite parent) { FigureCanvas canvas = new FigureCanvas(parent, getLightweightSystem()); setControl(canvas); installRootFigure(); return canvas; } /** * Convenience method which types the control as a <code>FigureCanvas</code>. This method * returns <code>null</code> whenever the control is null. * @return <code>null</code> or the Control as a FigureCanvas */ protected FigureCanvas getFigureCanvas() { return (FigureCanvas)getControl(); } /** * If the figure is a viewport, set the canvas' viewport, otherwise, set its contents. */ private void installRootFigure() { if (getFigureCanvas() == null) return; if (rootFigure instanceof Viewport) getFigureCanvas().setViewport((Viewport)rootFigure); else getFigureCanvas().setContents(rootFigure); } /** * Extends the superclass implementation to scroll the native Canvas control after the * super's implementation has completed. * @see org.eclipse.gef.EditPartViewer#reveal(org.eclipse.gef.EditPart) */ public void reveal(EditPart part) { super.reveal(part); Viewport port = getFigureCanvas().getViewport(); IFigure target = ((GraphicalEditPart)part).getFigure(); Rectangle exposeRegion = target.getBounds().getCopy(); target = target.getParent(); while (target != null && target != port) { target.translateToParent(exposeRegion); target = target.getParent(); } exposeRegion.expand(5, 5); 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)); getFigureCanvas().scrollSmoothTo(finalLocation.x, finalLocation.y); } /** * @see GraphicalViewerImpl#setRootFigure(IFigure) */ protected void setRootFigure(IFigure figure) { rootFigure = figure; installRootFigure(); } }