blob: b7e4439b53723523ff479f8f0eddeaf31df0321a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
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();
}
}