blob: 0bdb622affbe16977c4cdcb28dfbd93579e112a0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 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.examples.logicdesigner.edit;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.SnapToGuides;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.editpolicies.ResizableEditPolicy;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.rulers.RulerProvider;
import org.eclipse.gef.examples.logicdesigner.LogicMessages;
import org.eclipse.gef.examples.logicdesigner.figures.CircuitFeedbackFigure;
import org.eclipse.gef.examples.logicdesigner.figures.LabelFeedbackFigure;
import org.eclipse.gef.examples.logicdesigner.figures.LogicColorConstants;
import org.eclipse.gef.examples.logicdesigner.figures.LogicFlowFeedbackFigure;
import org.eclipse.gef.examples.logicdesigner.model.Circuit;
import org.eclipse.gef.examples.logicdesigner.model.LED;
import org.eclipse.gef.examples.logicdesigner.model.LogicDiagram;
import org.eclipse.gef.examples.logicdesigner.model.LogicFlowContainer;
import org.eclipse.gef.examples.logicdesigner.model.LogicGuide;
import org.eclipse.gef.examples.logicdesigner.model.LogicLabel;
import org.eclipse.gef.examples.logicdesigner.model.LogicSubpart;
import org.eclipse.gef.examples.logicdesigner.model.commands.AddCommand;
import org.eclipse.gef.examples.logicdesigner.model.commands.ChangeGuideCommand;
import org.eclipse.gef.examples.logicdesigner.model.commands.CloneCommand;
import org.eclipse.gef.examples.logicdesigner.model.commands.CreateCommand;
import org.eclipse.gef.examples.logicdesigner.model.commands.SetConstraintCommand;
public class LogicXYLayoutEditPolicy extends
org.eclipse.gef.editpolicies.XYLayoutEditPolicy {
public LogicXYLayoutEditPolicy(XYLayout layout) {
super();
setXyLayout(layout);
}
protected Command chainGuideAttachmentCommand(Request request,
LogicSubpart part, Command cmd, boolean horizontal) {
Command result = cmd;
// Attach to guide, if one is given
Integer guidePos = (Integer) request.getExtendedData().get(
horizontal ? SnapToGuides.KEY_HORIZONTAL_GUIDE
: SnapToGuides.KEY_VERTICAL_GUIDE);
if (guidePos != null) {
int alignment = ((Integer) request.getExtendedData().get(
horizontal ? SnapToGuides.KEY_HORIZONTAL_ANCHOR
: SnapToGuides.KEY_VERTICAL_ANCHOR)).intValue();
ChangeGuideCommand cgm = new ChangeGuideCommand(part, horizontal);
cgm.setNewGuide(findGuideAt(guidePos.intValue(), horizontal),
alignment);
result = result.chain(cgm);
}
return result;
}
protected Command chainGuideDetachmentCommand(Request request,
LogicSubpart part, Command cmd, boolean horizontal) {
Command result = cmd;
// Detach from guide, if none is given
Integer guidePos = (Integer) request.getExtendedData().get(
horizontal ? SnapToGuides.KEY_HORIZONTAL_GUIDE
: SnapToGuides.KEY_VERTICAL_GUIDE);
if (guidePos == null)
result = result.chain(new ChangeGuideCommand(part, horizontal));
return result;
}
protected Command createAddCommand(Request request, EditPart childEditPart,
Object constraint) {
LogicSubpart part = (LogicSubpart) childEditPart.getModel();
Rectangle rect = (Rectangle) constraint;
AddCommand add = new AddCommand();
add.setParent((LogicDiagram) getHost().getModel());
add.setChild(part);
add.setLabel(LogicMessages.LogicXYLayoutEditPolicy_AddCommandLabelText);
add.setDebugLabel("LogicXYEP add subpart");//$NON-NLS-1$
SetConstraintCommand setConstraint = new SetConstraintCommand();
setConstraint.setLocation(rect);
setConstraint.setPart(part);
setConstraint
.setLabel(LogicMessages.LogicXYLayoutEditPolicy_AddCommandLabelText);
setConstraint.setDebugLabel("LogicXYEP setConstraint");//$NON-NLS-1$
Command cmd = add.chain(setConstraint);
cmd = chainGuideAttachmentCommand(request, part, cmd, true);
cmd = chainGuideAttachmentCommand(request, part, cmd, false);
cmd = chainGuideDetachmentCommand(request, part, cmd, true);
return chainGuideDetachmentCommand(request, part, cmd, false);
}
/**
* @see org.eclipse.gef.editpolicies.ConstrainedLayoutEditPolicy#createChangeConstraintCommand(org.eclipse.gef.EditPart,
* java.lang.Object)
*/
protected Command createChangeConstraintCommand(EditPart child,
Object constraint) {
return null;
}
protected Command createChangeConstraintCommand(
ChangeBoundsRequest request, EditPart child, Object constraint) {
SetConstraintCommand cmd = new SetConstraintCommand();
LogicSubpart part = (LogicSubpart) child.getModel();
cmd.setPart(part);
cmd.setLocation((Rectangle) constraint);
Command result = cmd;
if ((request.getResizeDirection() & PositionConstants.NORTH_SOUTH) != 0) {
Integer guidePos = (Integer) request.getExtendedData().get(
SnapToGuides.KEY_HORIZONTAL_GUIDE);
if (guidePos != null) {
result = chainGuideAttachmentCommand(request, part, result,
true);
} else if (part.getHorizontalGuide() != null) {
// SnapToGuides didn't provide a horizontal guide, but this part
// is attached
// to a horizontal guide. Now we check to see if the part is
// attached to
// the guide along the edge being resized. If that is the case,
// we need to
// detach the part from the guide; otherwise, we leave it alone.
int alignment = part.getHorizontalGuide().getAlignment(part);
int edgeBeingResized = 0;
if ((request.getResizeDirection() & PositionConstants.NORTH) != 0)
edgeBeingResized = -1;
else
edgeBeingResized = 1;
if (alignment == edgeBeingResized)
result = result.chain(new ChangeGuideCommand(part, true));
}
}
if ((request.getResizeDirection() & PositionConstants.EAST_WEST) != 0) {
Integer guidePos = (Integer) request.getExtendedData().get(
SnapToGuides.KEY_VERTICAL_GUIDE);
if (guidePos != null) {
result = chainGuideAttachmentCommand(request, part, result,
false);
} else if (part.getVerticalGuide() != null) {
int alignment = part.getVerticalGuide().getAlignment(part);
int edgeBeingResized = 0;
if ((request.getResizeDirection() & PositionConstants.WEST) != 0)
edgeBeingResized = -1;
else
edgeBeingResized = 1;
if (alignment == edgeBeingResized)
result = result.chain(new ChangeGuideCommand(part, false));
}
}
if (request.getType().equals(REQ_MOVE_CHILDREN)
|| request.getType().equals(REQ_ALIGN_CHILDREN)) {
result = chainGuideAttachmentCommand(request, part, result, true);
result = chainGuideAttachmentCommand(request, part, result, false);
result = chainGuideDetachmentCommand(request, part, result, true);
result = chainGuideDetachmentCommand(request, part, result, false);
}
return result;
}
protected EditPolicy createChildEditPolicy(EditPart child) {
if (child instanceof LEDEditPart || child instanceof OutputEditPart) {
ResizableEditPolicy policy = new LogicResizableEditPolicy();
policy.setResizeDirections(0);
return policy;
} else if (child instanceof LogicLabelEditPart) {
ResizableEditPolicy policy = new LogicResizableEditPolicy();
policy.setResizeDirections(PositionConstants.EAST
| PositionConstants.WEST);
return policy;
}
return new LogicResizableEditPolicy();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#createSizeOnDropFeedback
* (org.eclipse.gef.requests.CreateRequest)
*/
protected IFigure createSizeOnDropFeedback(CreateRequest createRequest) {
IFigure figure;
if (createRequest.getNewObject() instanceof Circuit)
figure = new CircuitFeedbackFigure();
else if (createRequest.getNewObject() instanceof LogicFlowContainer)
figure = new LogicFlowFeedbackFigure();
else if (createRequest.getNewObject() instanceof LogicLabel)
figure = new LabelFeedbackFigure();
else {
figure = new RectangleFigure();
((RectangleFigure) figure).setXOR(true);
((RectangleFigure) figure).setFill(true);
figure.setBackgroundColor(LogicColorConstants.ghostFillColor);
figure.setForegroundColor(ColorConstants.white);
}
addFeedback(figure);
return figure;
}
protected LogicGuide findGuideAt(int pos, boolean horizontal) {
RulerProvider provider = ((RulerProvider) getHost().getViewer()
.getProperty(
horizontal ? RulerProvider.PROPERTY_VERTICAL_RULER
: RulerProvider.PROPERTY_HORIZONTAL_RULER));
return (LogicGuide) provider.getGuideAt(pos);
}
protected Command getAddCommand(Request generic) {
ChangeBoundsRequest request = (ChangeBoundsRequest) generic;
List editParts = request.getEditParts();
CompoundCommand command = new CompoundCommand();
command.setDebugLabel("Add in ConstrainedLayoutEditPolicy");//$NON-NLS-1$
GraphicalEditPart childPart;
Rectangle r;
Object constraint;
for (int i = 0; i < editParts.size(); i++) {
childPart = (GraphicalEditPart) editParts.get(i);
r = childPart.getFigure().getBounds().getCopy();
// convert r to absolute from childpart figure
childPart.getFigure().translateToAbsolute(r);
r = request.getTransformedRectangle(r);
// convert this figure to relative
getLayoutContainer().translateToRelative(r);
getLayoutContainer().translateFromParent(r);
r.translate(getLayoutOrigin().getNegated());
constraint = getConstraintFor(r);
command.add(createAddCommand(generic, childPart,
translateToModelConstraint(constraint)));
}
return command.unwrap();
}
/**
* Override to return the <code>Command</code> to perform an
* {@link RequestConstants#REQ_CLONE CLONE}. By default, <code>null</code>
* is returned.
*
* @param request
* the Clone Request
* @return A command to perform the Clone.
*/
protected Command getCloneCommand(ChangeBoundsRequest request) {
CloneCommand clone = new CloneCommand();
clone.setParent((LogicDiagram) getHost().getModel());
Iterator i = request.getEditParts().iterator();
GraphicalEditPart currPart = null;
while (i.hasNext()) {
currPart = (GraphicalEditPart) i.next();
clone.addPart((LogicSubpart) currPart.getModel(),
(Rectangle) getConstraintForClone(currPart, request));
}
// Attach to horizontal guide, if one is given
Integer guidePos = (Integer) request.getExtendedData().get(
SnapToGuides.KEY_HORIZONTAL_GUIDE);
if (guidePos != null) {
int hAlignment = ((Integer) request.getExtendedData().get(
SnapToGuides.KEY_HORIZONTAL_ANCHOR)).intValue();
clone.setGuide(findGuideAt(guidePos.intValue(), true), hAlignment,
true);
}
// Attach to vertical guide, if one is given
guidePos = (Integer) request.getExtendedData().get(
SnapToGuides.KEY_VERTICAL_GUIDE);
if (guidePos != null) {
int vAlignment = ((Integer) request.getExtendedData().get(
SnapToGuides.KEY_VERTICAL_ANCHOR)).intValue();
clone.setGuide(findGuideAt(guidePos.intValue(), false), vAlignment,
false);
}
return clone;
}
protected Command getCreateCommand(CreateRequest request) {
CreateCommand create = new CreateCommand();
create.setParent((LogicDiagram) getHost().getModel());
LogicSubpart newPart = (LogicSubpart) request.getNewObject();
create.setChild(newPart);
Rectangle constraint = (Rectangle) getConstraintFor(request);
create.setLocation(constraint);
create.setLabel(LogicMessages.LogicXYLayoutEditPolicy_CreateCommandLabelText);
Command cmd = chainGuideAttachmentCommand(request, newPart, create,
true);
return chainGuideAttachmentCommand(request, newPart, cmd, false);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#getCreationFeedbackOffset
* (org.eclipse.gef.requests.CreateRequest)
*/
protected Insets getCreationFeedbackOffset(CreateRequest request) {
if (request.getNewObject() instanceof LED
|| request.getNewObject() instanceof Circuit)
return new Insets(2, 0, 2, 0);
return new Insets();
}
/**
* Returns the layer used for displaying feedback.
*
* @return the feedback layer
*/
protected IFigure getFeedbackLayer() {
return getLayer(LayerConstants.SCALED_FEEDBACK_LAYER);
}
}