/******************************************************************************* * Copyright (c) 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: * Research Group Software Construction, * RWTH Aachen University, Germany - initial API and implementation */ package org.eclipse.draw2d; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Utility class to support working with {@link Viewport}s. * * @author Philip Ritzkopf * @author Alexander Nyssen * * @since 3.6 * */ public final class ViewportUtilities { private ViewportUtilities() { // provides only static utility functions and should not be accessed in // any other way than static. } /** * Returns all enclosing {@link Viewport}s for a given {@link IFigure}, * beginning with its direct enclosing {@link Viewport} up the root * {@link Viewport} in the figure's parent hierarchy. * * @param figure * @return A list of {@link Viewport}s representing the figure's enclosing * {@link Viewport} path, where the nearest enclosing * {@link Viewport} as the first element and the root * {@link Viewport} as the last element. In case there is no * enclosing {@link Viewport}, an empty list is returned. */ public static List getEnclosingViewportsPath(IFigure figure) { Viewport nearestEnclosingViewport = getNearestEnclosingViewport(figure); if (nearestEnclosingViewport == null) { return new ArrayList(); } Viewport rootViewport = getRootViewport(figure); return getViewportsPath(nearestEnclosingViewport, rootViewport, true); } /** * Returns a list containing the provided leaf {@link Viewport} as the first * element, and all its enclosing {@link Viewport}s up to the root * {@link Viewport}, where the root {@link Viewport} forms the last element * of the list. * * @param leafViewport * The {@link Viewport}, whose parent hierarchy is processed. * @param rootViewport * an ancestor of the given leafViewport, which marks the end * point of the hierarchy to be processed. * @return A list of {@link Viewport}s containing the leaf {@link Viewport} * as the first element, the root {@link Viewport} as the last and * in between all enclosing {@link Viewport}s of the leaf * {@link Viewport} up to the root. Returns an empty list in case * leaf or root {@link Viewport} are null or in case the root * viewport is not an ancestor of the leaf {@link Viewport}. */ public static List getViewportsPath(final Viewport leafViewport, final Viewport rootViewport) { return getViewportsPath(leafViewport, rootViewport, true); } /** * Returns a list containing the provided leaf {@link Viewport} as the first * element, and all its enclosing {@link Viewport}s up to the root * {@link Viewport}. The root {@link Viewport} forms the last element of the * list, in case includeRootViewport is set to true, otherwise the viewport * directly nested below the root viewport will be the last in the list. * * @param leafViewport * The {@link Viewport}, whose parent hierarchy is processed. * @param rootViewport * an ancestor of the given leafViewport, which marks the end * point of the hierarchy to be processed. * @param includeRootViewport * whether the provided rootViewport should be included in the * list of returned viewports (as the last one) or not. * @return A list of {@link Viewport}s containing the leaf {@link Viewport} * as the first element, the root {@link Viewport} as the last and * in between all enclosing {@link Viewport}s of the leaf * {@link Viewport} up to the root. Returns an empty list in case * leaf or root {@link Viewport} are null or in case the root * viewport is not an ancestor of the leaf {@link Viewport}. */ public static List getViewportsPath(final Viewport leafViewport, final Viewport rootViewport, boolean includeRootViewport) { if (leafViewport == null || rootViewport == null) { return Collections.EMPTY_LIST; } // search all enclosing viewports of leaf viewport up to root viewport // (or until no enclosing viewport can be found) List nestedViewports = new ArrayList(); Viewport currentViewport = leafViewport; do { nestedViewports.add(currentViewport); currentViewport = ViewportUtilities .getNearestEnclosingViewport(currentViewport); } while (currentViewport != null && currentViewport != rootViewport); // check if root viewport is an ancestor of the given leaf viewport if (currentViewport != null) { if (includeRootViewport) { nestedViewports.add(currentViewport); } return nestedViewports; } return Collections.EMPTY_LIST; } /** * Returns the nearest common enclosing {@link Viewport} for two given * {@link Figure}s. * * @param firstFigure * @param secondFigure * @return The nearest common {@link Viewport} of the two given figures, or * null if no common enclosing {@link Viewport} could be found. */ public static Viewport getNearestCommonViewport(IFigure firstFigure, IFigure secondFigure) { return getNearestViewport(FigureUtilities.findCommonAncestor( firstFigure, secondFigure)); } /** * Returns the upper most enclosing {@link Viewport} for the given * {@link IFigure}. * * @param figure * @return The upper most enclosing {@link Viewport} or null if there is no * enclosing {@link Viewport} for the given {@link IFigure}, */ public static Viewport getRootViewport(final IFigure figure) { Viewport currentViewport = getNearestViewport(figure); while (getNearestEnclosingViewport(currentViewport) != null) { currentViewport = getNearestEnclosingViewport(currentViewport); } return currentViewport; } /** * Returns the given figure in case it is a {@link Viewport} itself, * otherwise its nearest enclosing {@link Viewport}. * * @param figure * @return The given figure in case it is a {@link Viewport} itself, * otherwise the nearest enclosing {@link Viewport} or null if there * is no nearest enclosing {@link Viewport}. */ public static Viewport getNearestViewport(final IFigure figure) { if (figure == null) { return null; } if (figure instanceof Viewport) { return (Viewport) figure; } else { return getNearestEnclosingViewport(figure); } } /** * Returns the nearest enclosing {@link Viewport} of a given {@link IFigure} * by walking up the figure's hierarchy. * * @param figure * @return The nearest enclosing {@link Viewport} of the given figure, or * null if none could be found. */ public static Viewport getNearestEnclosingViewport(final IFigure figure) { if (figure == null) { return null; } Viewport viewport = null; IFigure currentFigure = figure; while (currentFigure.getParent() != null) { if (currentFigure.getParent() instanceof Viewport) { viewport = (Viewport) currentFigure.getParent(); break; } currentFigure = currentFigure.getParent(); } return viewport; } }