/******************************************************************************* * Copyright (c) 2016 itemis AG 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: * Matthias Wienand (itemis AG) - initial API and implementation * *******************************************************************************/ package org.eclipse.gef.mvc.fx.handlers; import org.eclipse.gef.fx.nodes.InfiniteCanvas; import org.eclipse.gef.geometry.convert.fx.FX2Geometry; import org.eclipse.gef.geometry.planar.Rectangle; import org.eclipse.gef.mvc.fx.policies.ViewportPolicy; import javafx.geometry.HPos; import javafx.geometry.Pos; import javafx.geometry.VPos; /** * The {@link PanningSupport} can be used to compute panning translations that * align the contents with the viewport. * * @author wienand * */ public class PanningSupport { /** * Removes free space between the contents and the viewport for the sides * specified by the given {@link Pos}. * * @param viewportPolicy * The {@link ViewportPolicy} that is used to remove free space. * @param orientation * The orientation {@link Pos} that specifies the sides where * free space is reduced, or the contents is aligned, * respectively. * @param alignIfContentsFit * <code>true</code> to indicate that contents are aligned with * the given {@link Pos} if they completely fit into the * viewport, <code>false</code> to indicate that contents are not * aligned, but only free space is reduced if the contents do not * fit into the viewport. */ public void removeFreeSpace(ViewportPolicy viewportPolicy, Pos orientation, boolean alignIfContentsFit) { InfiniteCanvas canvas = (InfiniteCanvas) viewportPolicy.getAdaptable() .getRoot().getViewer().getCanvas(); // determine contents and viewport bounds Rectangle viewportBoundsInCanvasLocal = new Rectangle(0, 0, canvas.getWidth(), canvas.getHeight()); Rectangle contentBoundsInCanvasLocal = FX2Geometry .toRectangle(canvas.getContentBounds()); // compute translation based on given alignment position, free space, // and contents-may-fit flag HPos hpos = orientation.getHpos(); double deltaTx = 0; if (hpos != null) { if (HPos.RIGHT.equals(hpos)) { double freeSpaceRight = viewportBoundsInCanvasLocal.getRight().x - contentBoundsInCanvasLocal.getRight().x; deltaTx = alignIfContentsFit && contentBoundsInCanvasLocal .getWidth() <= viewportBoundsInCanvasLocal.getWidth() || contentBoundsInCanvasLocal .getWidth() > viewportBoundsInCanvasLocal .getWidth() && freeSpaceRight > 0 ? freeSpaceRight : 0; } else if (HPos.LEFT.equals(hpos)) { double freeSpaceLeft = contentBoundsInCanvasLocal.getLeft().x - viewportBoundsInCanvasLocal.getLeft().x; deltaTx = alignIfContentsFit && contentBoundsInCanvasLocal .getWidth() <= viewportBoundsInCanvasLocal.getWidth() || contentBoundsInCanvasLocal .getWidth() > viewportBoundsInCanvasLocal .getWidth() && freeSpaceLeft > 0 ? -freeSpaceLeft : 0; } // TODO: HPos.CENTER } VPos vpos = orientation.getVpos(); double deltaTy = 0; if (vpos != null) { if (VPos.BOTTOM.equals(vpos)) { double freeSpaceBottom = viewportBoundsInCanvasLocal .getBottom().y - contentBoundsInCanvasLocal.getBottom().y; deltaTy = alignIfContentsFit && contentBoundsInCanvasLocal .getHeight() <= viewportBoundsInCanvasLocal.getHeight() || contentBoundsInCanvasLocal .getHeight() > viewportBoundsInCanvasLocal .getHeight() && freeSpaceBottom > 0 ? freeSpaceBottom : 0; } else if (VPos.TOP.equals(vpos)) { double freeSpaceTop = contentBoundsInCanvasLocal.getTop().y - viewportBoundsInCanvasLocal.getTop().y; deltaTy = alignIfContentsFit && contentBoundsInCanvasLocal .getHeight() <= viewportBoundsInCanvasLocal.getHeight() || contentBoundsInCanvasLocal .getHeight() > viewportBoundsInCanvasLocal .getHeight() && freeSpaceTop > 0 ? -freeSpaceTop : 0; } // TODO: VPos.CENTER } if (deltaTx != 0 || deltaTy != 0) { viewportPolicy.scroll(true, deltaTx, deltaTy); } } }