/******************************************************************************* * Copyright (c) 2000, 2010, 2012 IBM Corporation, Gerhardt Informatics Kft. 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 * Gerhardt Informatics Kft. - GEFGWT port *******************************************************************************/ package org.eclipse.gef.editpolicies; import java.util.List; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.OrderedLayout; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.requests.ChangeBoundsRequest; /** * A LayoutEditPolicy for use with <code>LayoutManagers</code> that take no * constraints. Such layout managers typically position children in <x,y> * coordinates based on their order in * {@link org.eclipse.draw2d.IFigure#getChildren() getChildren()}. Therefore, * this EditPolicy must perform the inverse mapping. Given a mouse location from * the User, the policy must determine the index at which the child[ren] should * be added/created. * * @author hudsonr * @since 2.0 */ public abstract class OrderedLayoutEditPolicy extends LayoutEditPolicy { /** * Returns the <code>Command</code> to add the specified child after a * reference <code>EditPart</code>. If the reference is <code>null</code>, * the child should be added as the first child. * * @param child * the child being added * @param after * <code>null</code> or a reference EditPart * @return a Command to add the child */ protected abstract Command createAddCommand(EditPart child, EditPart after); /** * Since Ordered layouts generally don't use constraints, a * {@link NonResizableEditPolicy} is used by default for children. * Subclasses may override this method to supply a different EditPolicy. * * @see org.eclipse.gef.editpolicies.LayoutEditPolicy#createChildEditPolicy(EditPart) */ protected EditPolicy createChildEditPolicy(EditPart child) { return new NonResizableEditPolicy(); } /** * Returns the <code>Command</code> to move the specified child before the * given reference <code>EditPart</code>. If the reference is * <code>null</code>, the child should be moved in front of all children. * <P> * A move is a change in the order of the children, which indirectly causes * a change in location on the screen. * * @param child * the child being moved * @param after * <code>null</code> or the EditPart that should be after (or to * the right of) the child being moved * @return a Command to move the child */ protected abstract Command createMoveChildCommand(EditPart child, EditPart after); /** * This method is overridden from the superclass to calculate the * <i>index</i> at which the children should be added. The index is * determined by finding a reference EditPart, and adding the new child[ren] * <em>after</em> that reference part. <code>null</code> is used to indicate * that the child[ren] should be added at the beginning. * <P> * Subclasses must override {@link #createAddCommand(EditPart, EditPart)}, * and should not override this method. * * @see org.eclipse.gef.editpolicies.LayoutEditPolicy#getAddCommand(Request) */ protected Command getAddCommand(Request req) { ChangeBoundsRequest request = (ChangeBoundsRequest) req; List editParts = request.getEditParts(); CompoundCommand command = new CompoundCommand(); for (int i = 0; i < editParts.size(); i++) { EditPart child = (EditPart) editParts.get(i); command.add(createAddCommand(child, getInsertionReference(request))); } return command.unwrap(); } /** * Calculates a <i>reference</i> <code>EditPart</code> using the specified * <code>Request</code>. The EditPart returned is used to mark the index * coming <em>after</em> that EditPart. <code>null</code> is used to * indicate the index that comes after <em>no</em> EditPart, that is, it * indicates the very last index. * * @param request * the Request * @return <code>null</code> or a reference EditPart */ protected abstract EditPart getInsertionReference(Request request); /** * A move is interpreted here as a change in order of the children. This * method obtains the proper index, and then calls * {@link #createMoveChildCommand(EditPart, EditPart)}, which subclasses * must implement. Subclasses should not override this method. * * @see LayoutEditPolicy#getMoveChildrenCommand(Request) */ protected Command getMoveChildrenCommand(Request request) { CompoundCommand command = new CompoundCommand(); List editParts = ((ChangeBoundsRequest) request).getEditParts(); EditPart insertionReference = getInsertionReference(request); for (int i = 0; i < editParts.size(); i++) { EditPart child = (EditPart) editParts.get(i); command.add(createMoveChildCommand(child, insertionReference)); } return command.unwrap(); } /** * Returns whether the layout container's layout manager has a horizontal * orientation or not. * * @return <code>true</code> if the layout container's layout manager has a * horizontal orientation, <code>false</code> otherwise * @since 3.7 */ protected boolean isLayoutHorizontal() { IFigure figure = getLayoutContainer(); return ((OrderedLayout) figure.getLayoutManager()).isHorizontal(); } }