/******************************************************************************* * Copyright (c) 2001, 2005 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); } }