/*******************************************************************************
* 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.editpolicies;
import java.util.List;
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();
}
}