| /******************************************************************************* |
| * 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); |
| } |
| |
| } |