Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "Graphical Modeling Framework/Recipes"
(→Recipe: HowTo reorder children in a GMF compartment with Drag & Drop) |
([Reorder-Chapter] Fixed problem that target feedback cannot be shown, my fix only removes it after dropping) |
||
(5 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
== Recipe: HowTo reorder children in a GMF compartment with Drag & Drop== | == Recipe: HowTo reorder children in a GMF compartment with Drag & Drop== | ||
− | '''Problem:''' You have created a node class which can contain other nodes. E.g. a class bookshelf that contains objects of the class book. Therefore you created a compartment. After adding books to the bookshelf in your editor, you want to rearrange the books by drag & drop. But it doesn't work... | + | '''Problem:''' |
+ | |||
+ | You have created a node class which can contain other nodes. E.g. a class bookshelf that contains objects of the class book. Therefore you created a compartment. After adding books to the bookshelf in your editor, you want to rearrange the books by drag & drop. But it doesn't work... | ||
'''Solution:''' | '''Solution:''' | ||
Line 33: | Line 35: | ||
<pre> | <pre> | ||
− | public class | + | package whatever.package.you.want; |
− | extends org.eclipse.gef.editpolicies.FlowLayoutEditPolicy | + | |
− | { | + | import org.eclipse.core.commands.ExecutionException; |
+ | import org.eclipse.core.runtime.IAdaptable; | ||
+ | import org.eclipse.core.runtime.IProgressMonitor; | ||
+ | import org.eclipse.emf.common.util.EList; | ||
+ | import org.eclipse.emf.ecore.EObject; | ||
+ | import org.eclipse.emf.transaction.TransactionalEditingDomain; | ||
+ | import org.eclipse.gef.EditPart; | ||
+ | import org.eclipse.gmf.runtime.common.core.command.CommandResult; | ||
+ | import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; | ||
+ | import org.eclipse.gmf.runtime.emf.commands.core.commands.RepositionEObjectCommand; | ||
+ | import org.eclipse.gmf.runtime.notation.View; | ||
+ | |||
+ | public class CompartmentRepositionEObjectCommand extends RepositionEObjectCommand { | ||
+ | |||
+ | EditPart childToMove = null; | ||
+ | int newIndex = 0; | ||
+ | |||
+ | public CompartmentRepositionEObjectCommand( | ||
+ | TransactionalEditingDomain editingDomain, String label, | ||
+ | EList elements, EObject element, int displacement) { | ||
+ | super(editingDomain, label, elements, element, displacement); | ||
+ | } | ||
+ | |||
+ | public CompartmentRepositionEObjectCommand(EditPart childToMove, | ||
+ | TransactionalEditingDomain editingDomain, String label, | ||
+ | EList elements, EObject element, int displacement, int newIndex) { | ||
+ | super(editingDomain, label, elements, element, displacement); | ||
+ | |||
+ | this.childToMove = childToMove; | ||
+ | this.newIndex = newIndex; | ||
+ | } | ||
+ | |||
+ | public CommandResult doExecuteWithResult( | ||
+ | IProgressMonitor progressMonitor, IAdaptable info) | ||
+ | throws ExecutionException { | ||
+ | CommandResult rs = super.doExecuteWithResult(progressMonitor, info); | ||
+ | |||
+ | EditPart compartment = childToMove.getParent(); | ||
+ | |||
+ | ViewUtil.repositionChildAt((View)compartment.getModel(), (View)childToMove.getModel(), newIndex); | ||
+ | compartment.refresh(); | ||
+ | |||
+ | return rs; | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | package whatever.package.you.want; | ||
+ | |||
+ | import whatever.package.you.want.CompartmentRepositionEObjectCommand; | ||
+ | import org.eclipse.emf.common.util.EList; | ||
+ | import org.eclipse.emf.ecore.EStructuralFeature; | ||
+ | import org.eclipse.emf.transaction.TransactionalEditingDomain; | ||
+ | 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.requests.CreateRequest; | ||
+ | import org.eclipse.gmf.runtime.diagram.core.commands.AddCommand; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ResizableEditPolicyEx; | ||
+ | import org.eclipse.gmf.runtime.emf.commands.core.commands.RepositionEObjectCommand; | ||
+ | import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter; | ||
+ | import org.eclipse.gmf.runtime.notation.View; | ||
+ | |||
+ | public class CompartmentEditPolicy extends org.eclipse.gef.editpolicies.FlowLayoutEditPolicy { | ||
private EStructuralFeature feature = null; | private EStructuralFeature feature = null; | ||
Line 79: | Line 148: | ||
(EList)((View)child.getParent().getModel()).getElement().eGet(feature), | (EList)((View)child.getParent().getModel()).getElement().eGet(feature), | ||
((View)child.getModel()).getElement(), | ((View)child.getModel()).getElement(), | ||
− | displacement, newIndex) | + | displacement, newIndex) { |
− | + | ||
− | + | public CommandResult doExecuteWithResult( | |
+ | IProgressMonitor progressMonitor, IAdaptable info) { | ||
+ | // remove target feedback after dropping | ||
+ | eraseLayoutTargetFeedback(null); | ||
+ | return super.doExecuteWithResult(progressMonitor, info); | ||
+ | } | ||
+ | }; | ||
return new ICommandProxy(command); | return new ICommandProxy(command); | ||
Line 108: | Line 183: | ||
} | } | ||
+ | |||
</pre> | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | == Recipe: HowTo add children in a GMF compartment at a specific position== | ||
+ | '''Problem:''' | ||
+ | |||
+ | You have created a node class which can contain other nodes. E.g. a class bookshelf that contains objects of the class book. Therefore you created a compartment. Now you want to add a book to the bookshelf at a specific position and not always at the end. | ||
+ | |||
+ | '''Solution:''' | ||
+ | |||
+ | In the xxxCompartmentEditPart class rewrite the createFigure() method: | ||
<pre> | <pre> | ||
− | public | + | public IFigure createFigure() { |
+ | |||
+ | ResizableCompartmentFigure rcf = (ResizableCompartmentFigure) super.createFigure(); | ||
+ | FlowLayout layout = new FlowLayout(); | ||
+ | layout.setMajorSpacing(getMapMode().DPtoLP(5)); | ||
+ | layout.setMinorSpacing(getMapMode().DPtoLP(5)); | ||
+ | layout.setHorizontal(false); | ||
− | + | rcf.getContentPane().setLayoutManager(layout); | |
− | int | + | |
+ | rcf.setTitleVisibility(false); | ||
+ | |||
+ | return rcf; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | In the createDefaultEditPolicies() method of the xxxCompartmentEditPart class change the following EditPolicy: | ||
+ | <pre> | ||
+ | - change | ||
+ | installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CreationEditPolicy()); | ||
+ | + to | ||
+ | installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CompartmentChildCreationEditPolicy()); | ||
+ | </pre> | ||
+ | |||
+ | and add the CompartmentChildCreateCommand and CompartmentChildCreationEditPolicy classes: | ||
+ | |||
+ | |||
+ | <pre> | ||
+ | package org.diagram.edit.commands; | ||
+ | |||
+ | import org.eclipse.core.commands.ExecutionException; | ||
+ | import org.eclipse.core.runtime.IAdaptable; | ||
+ | import org.eclipse.core.runtime.IProgressMonitor; | ||
+ | import org.eclipse.emf.transaction.TransactionalEditingDomain; | ||
+ | import org.eclipse.gmf.runtime.common.core.command.CommandResult; | ||
+ | import org.eclipse.gmf.runtime.diagram.core.services.ViewService; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor; | ||
+ | import org.eclipse.gmf.runtime.notation.View; | ||
+ | import org.eclipse.jface.util.Assert; | ||
+ | |||
+ | public class CompartmentChildCreateCommand extends CreateCommand { | ||
+ | |||
+ | int index; | ||
− | public | + | public CompartmentChildCreateCommand (TransactionalEditingDomain editingDomain, ViewDescriptor viewDescriptor, |
− | + | View containerView, int index) { | |
− | + | super(editingDomain, viewDescriptor, containerView); | |
− | super(editingDomain, | + | this.index = index; |
} | } | ||
− | + | @Override | |
− | + | protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) | |
− | + | throws ExecutionException { | |
− | + | ||
− | + | View view = | |
− | + | ViewService.getInstance().createView( | |
− | + | viewDescriptor.getViewKind(), | |
+ | viewDescriptor.getElementAdapter(), | ||
+ | containerView, | ||
+ | viewDescriptor.getSemanticHint(), | ||
+ | index, | ||
+ | viewDescriptor.isPersisted(), | ||
+ | viewDescriptor.getPreferencesHint()); | ||
+ | Assert.isNotNull(view, "failed to create a view"); //$NON-NLS-1$ | ||
+ | viewDescriptor.setView(view); | ||
+ | |||
+ | return CommandResult.newOKCommandResult(viewDescriptor); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | package org.diagram.edit.policies; | ||
+ | |||
+ | import java.util.Iterator; | ||
+ | import java.util.List; | ||
+ | |||
+ | import org.diagram.edit.commands.CompartmentChildCreateCommand; | ||
+ | import org.eclipse.draw2d.FlowLayout; | ||
+ | import org.eclipse.draw2d.IFigure; | ||
+ | import org.eclipse.draw2d.geometry.Point; | ||
+ | import org.eclipse.draw2d.geometry.Rectangle; | ||
+ | import org.eclipse.draw2d.geometry.Transposer; | ||
+ | import org.eclipse.emf.transaction.TransactionalEditingDomain; | ||
+ | import org.eclipse.gef.EditPart; | ||
+ | import org.eclipse.gef.GraphicalEditPart; | ||
+ | import org.eclipse.gef.Request; | ||
+ | import org.eclipse.gef.commands.Command; | ||
+ | import org.eclipse.gef.requests.DropRequest; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; | ||
+ | import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest; | ||
+ | import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand; | ||
+ | import org.eclipse.gmf.runtime.notation.View; | ||
+ | |||
+ | public class CompartmentChildCreationEditPolicy extends CreationEditPolicy { | ||
+ | |||
+ | @Override | ||
+ | protected Command getCreateCommand(CreateViewRequest request) { | ||
+ | TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()) | ||
+ | .getEditingDomain(); | ||
+ | CompositeTransactionalCommand cc = new CompositeTransactionalCommand( | ||
+ | editingDomain, DiagramUIMessages.AddCommand_Label); | ||
+ | |||
+ | Iterator descriptors = request.getViewDescriptors().iterator(); | ||
+ | |||
+ | while (descriptors.hasNext()) { | ||
+ | CreateViewRequest.ViewDescriptor descriptor = | ||
+ | (CreateViewRequest.ViewDescriptor)descriptors.next(); | ||
+ | |||
+ | CreateCommand createCommand = | ||
+ | new CompartmentChildCreateCommand(editingDomain, | ||
+ | descriptor, | ||
+ | (View)(getHost().getModel()), getFeedbackIndexFor(request)); | ||
+ | |||
+ | cc.compose(createCommand); | ||
} | } | ||
+ | return new ICommandProxy(cc.reduce()); | ||
+ | } | ||
+ | |||
− | + | protected int getFeedbackIndexFor(Request request) { | |
− | + | List children = getHost().getChildren(); | |
− | + | if (children.isEmpty()) | |
− | + | return -1; | |
− | + | ||
− | + | Transposer transposer = new Transposer(); | |
+ | transposer.setEnabled (!isHorizontal()); | ||
− | + | Point p = transposer.t(getLocationFromRequest(request)); | |
− | + | ||
− | + | // Current row bottom, initialize to above the top. | |
− | return | + | int rowBottom = Integer.MIN_VALUE; |
+ | int candidate = -1; | ||
+ | for (int i = 0; i < children.size(); i++) { | ||
+ | EditPart child = (EditPart) children.get(i); | ||
+ | Rectangle rect = transposer.t(getAbsoluteBounds(((GraphicalEditPart)child))); | ||
+ | if (rect.y > rowBottom) { | ||
+ | /* | ||
+ | * We are in a new row, so if we don't have a candidate but yet are within the | ||
+ | * previous row, then the current entry becomes the candidate. This is because | ||
+ | * we know we must be to the right of center of the last Figure in the | ||
+ | * previous row, so this Figure (which is at the start of a new row) is the | ||
+ | * candidate. | ||
+ | */ | ||
+ | if (p.y <= rowBottom) { | ||
+ | if (candidate == -1) | ||
+ | candidate = i; | ||
+ | break; | ||
+ | } else | ||
+ | candidate = -1; // Mouse's Y is outside the row, so reset the candidate | ||
+ | } | ||
+ | rowBottom = Math.max(rowBottom, rect.bottom()); | ||
+ | if (candidate == -1) { | ||
+ | /* | ||
+ | * See if we have a possible candidate. It is a candidate if the cursor is | ||
+ | * left of the center of this candidate. | ||
+ | */ | ||
+ | if (p.x <= rect.x + (rect.width / 2)) | ||
+ | candidate = i; | ||
+ | } | ||
+ | if (candidate != -1) { | ||
+ | // We have a candidate, see if the rowBottom has grown to include the mouse Y. | ||
+ | if (p.y <= rowBottom) { | ||
+ | /* | ||
+ | * Now we have determined that the cursor.Y is above the bottom of the | ||
+ | * current row of figures. Stop now, to prevent the next row from being | ||
+ | * searched | ||
+ | */ | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | return candidate; | ||
+ | } | ||
+ | |||
+ | protected boolean isHorizontal() { | ||
+ | IFigure figure = ((GraphicalEditPart)getHost()).getContentPane(); | ||
+ | return ((FlowLayout)figure.getLayoutManager()).isHorizontal(); | ||
+ | } | ||
+ | |||
+ | private Point getLocationFromRequest(Request request) { | ||
+ | return ((DropRequest)request).getLocation(); | ||
+ | } | ||
+ | |||
+ | private Rectangle getAbsoluteBounds(GraphicalEditPart ep) { | ||
+ | Rectangle bounds = ep.getFigure().getBounds().getCopy(); | ||
+ | ep.getFigure().translateToAbsolute(bounds); | ||
+ | return bounds; | ||
} | } | ||
} | } | ||
+ | |||
</pre> | </pre> | ||
[[Category:GMF]] | [[Category:GMF]] |
Latest revision as of 11:12, 12 July 2013
Recipe: HowTo reorder children in a GMF compartment with Drag & Drop
Problem:
You have created a node class which can contain other nodes. E.g. a class bookshelf that contains objects of the class book. Therefore you created a compartment. After adding books to the bookshelf in your editor, you want to rearrange the books by drag & drop. But it doesn't work...
Solution:
In the xxxCompartmentEditPart class rewrite the createFigure() method:
public IFigure createFigure() { ResizableCompartmentFigure rcf = (ResizableCompartmentFigure) super.createFigure(); FlowLayout layout = new FlowLayout(); layout.setMajorSpacing(getMapMode().DPtoLP(5)); layout.setMinorSpacing(getMapMode().DPtoLP(5)); layout.setHorizontal(false); rcf.getContentPane().setLayoutManager(layout); rcf.setTitleVisibility(false); return rcf; }
In the createDefaultEditPolicies() method of the xxxCompartmentEditPart class add an EditPolicy:
installEditPolicy(EditPolicy.LAYOUT_ROLE, new CompartmentEditPolicy(xxxPackage.Literals.xxx));
Note: xxxPackage.Literals.xxx has to be the EStructuralFeature of the EList Attribute that contains the Objects which should be reordered.
Use the classes CompartmentEditPolicy and CompartmentRepositionEObjectCommand:
package whatever.package.you.want; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gef.EditPart; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; import org.eclipse.gmf.runtime.emf.commands.core.commands.RepositionEObjectCommand; import org.eclipse.gmf.runtime.notation.View; public class CompartmentRepositionEObjectCommand extends RepositionEObjectCommand { EditPart childToMove = null; int newIndex = 0; public CompartmentRepositionEObjectCommand( TransactionalEditingDomain editingDomain, String label, EList elements, EObject element, int displacement) { super(editingDomain, label, elements, element, displacement); } public CompartmentRepositionEObjectCommand(EditPart childToMove, TransactionalEditingDomain editingDomain, String label, EList elements, EObject element, int displacement, int newIndex) { super(editingDomain, label, elements, element, displacement); this.childToMove = childToMove; this.newIndex = newIndex; } public CommandResult doExecuteWithResult( IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { CommandResult rs = super.doExecuteWithResult(progressMonitor, info); EditPart compartment = childToMove.getParent(); ViewUtil.repositionChildAt((View)compartment.getModel(), (View)childToMove.getModel(), newIndex); compartment.refresh(); return rs; } }
package whatever.package.you.want; import whatever.package.you.want.CompartmentRepositionEObjectCommand; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.transaction.TransactionalEditingDomain; 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.requests.CreateRequest; import org.eclipse.gmf.runtime.diagram.core.commands.AddCommand; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ResizableEditPolicyEx; import org.eclipse.gmf.runtime.emf.commands.core.commands.RepositionEObjectCommand; import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter; import org.eclipse.gmf.runtime.notation.View; public class CompartmentEditPolicy extends org.eclipse.gef.editpolicies.FlowLayoutEditPolicy { private EStructuralFeature feature = null; protected Command createAddCommand(EditPart child, EditPart after) { int index = getHost().getChildren().indexOf(after); TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain(); AddCommand command = new AddCommand(editingDomain, new EObjectAdapter((View)getHost().getModel()), new EObjectAdapter((View)child.getModel()), index); return new ICommandProxy(command); } protected EditPolicy createChildEditPolicy(EditPart child) { ResizableEditPolicyEx policy = new ResizableEditPolicyEx(); policy.setResizeDirections(0); return policy; } protected Command createMoveChildCommand(EditPart child, EditPart after) { int newIndex; int displacement; int childIndex = getHost().getChildren().indexOf(child); int afterIndex = getHost().getChildren().indexOf(after); if(afterIndex == -1) { newIndex = getHost().getChildren().size()-1; displacement = newIndex - childIndex; } else { newIndex = afterIndex; displacement = afterIndex - childIndex; if (childIndex <= afterIndex) { newIndex--; displacement--; } } TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain(); RepositionEObjectCommand command = new CompartmentRepositionEObjectCommand(child, editingDomain, "", (EList)((View)child.getParent().getModel()).getElement().eGet(feature), ((View)child.getModel()).getElement(), displacement, newIndex) { public CommandResult doExecuteWithResult( IProgressMonitor progressMonitor, IAdaptable info) { // remove target feedback after dropping eraseLayoutTargetFeedback(null); return super.doExecuteWithResult(progressMonitor, info); } }; return new ICommandProxy(command); } protected Command getCreateCommand(CreateRequest request) { return null; } protected Command getDeleteDependantCommand(Request request) { return null; } protected Command getOrphanChildrenCommand(Request request) { return null; } /** * @param feature has to be an EList */ public CompartmentEditPolicy(EStructuralFeature feature) { super(); this.feature = feature; } }
Recipe: HowTo add children in a GMF compartment at a specific position
Problem:
You have created a node class which can contain other nodes. E.g. a class bookshelf that contains objects of the class book. Therefore you created a compartment. Now you want to add a book to the bookshelf at a specific position and not always at the end.
Solution:
In the xxxCompartmentEditPart class rewrite the createFigure() method:
public IFigure createFigure() { ResizableCompartmentFigure rcf = (ResizableCompartmentFigure) super.createFigure(); FlowLayout layout = new FlowLayout(); layout.setMajorSpacing(getMapMode().DPtoLP(5)); layout.setMinorSpacing(getMapMode().DPtoLP(5)); layout.setHorizontal(false); rcf.getContentPane().setLayoutManager(layout); rcf.setTitleVisibility(false); return rcf; }
In the createDefaultEditPolicies() method of the xxxCompartmentEditPart class change the following EditPolicy:
- change installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CreationEditPolicy()); + to installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CompartmentChildCreationEditPolicy());
and add the CompartmentChildCreateCommand and CompartmentChildCreationEditPolicy classes:
package org.diagram.edit.commands; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.diagram.core.services.ViewService; import org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand; import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.jface.util.Assert; public class CompartmentChildCreateCommand extends CreateCommand { int index; public CompartmentChildCreateCommand (TransactionalEditingDomain editingDomain, ViewDescriptor viewDescriptor, View containerView, int index) { super(editingDomain, viewDescriptor, containerView); this.index = index; } @Override protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { View view = ViewService.getInstance().createView( viewDescriptor.getViewKind(), viewDescriptor.getElementAdapter(), containerView, viewDescriptor.getSemanticHint(), index, viewDescriptor.isPersisted(), viewDescriptor.getPreferencesHint()); Assert.isNotNull(view, "failed to create a view"); //$NON-NLS-1$ viewDescriptor.setView(view); return CommandResult.newOKCommandResult(viewDescriptor); } }
package org.diagram.edit.policies; import java.util.Iterator; import java.util.List; import org.diagram.edit.commands.CompartmentChildCreateCommand; import org.eclipse.draw2d.FlowLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.draw2d.geometry.Transposer; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; import org.eclipse.gef.requests.DropRequest; import org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest; import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand; import org.eclipse.gmf.runtime.notation.View; public class CompartmentChildCreationEditPolicy extends CreationEditPolicy { @Override protected Command getCreateCommand(CreateViewRequest request) { TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()) .getEditingDomain(); CompositeTransactionalCommand cc = new CompositeTransactionalCommand( editingDomain, DiagramUIMessages.AddCommand_Label); Iterator descriptors = request.getViewDescriptors().iterator(); while (descriptors.hasNext()) { CreateViewRequest.ViewDescriptor descriptor = (CreateViewRequest.ViewDescriptor)descriptors.next(); CreateCommand createCommand = new CompartmentChildCreateCommand(editingDomain, descriptor, (View)(getHost().getModel()), getFeedbackIndexFor(request)); cc.compose(createCommand); } return new ICommandProxy(cc.reduce()); } protected int getFeedbackIndexFor(Request request) { List children = getHost().getChildren(); if (children.isEmpty()) return -1; Transposer transposer = new Transposer(); transposer.setEnabled (!isHorizontal()); Point p = transposer.t(getLocationFromRequest(request)); // Current row bottom, initialize to above the top. int rowBottom = Integer.MIN_VALUE; int candidate = -1; for (int i = 0; i < children.size(); i++) { EditPart child = (EditPart) children.get(i); Rectangle rect = transposer.t(getAbsoluteBounds(((GraphicalEditPart)child))); if (rect.y > rowBottom) { /* * We are in a new row, so if we don't have a candidate but yet are within the * previous row, then the current entry becomes the candidate. This is because * we know we must be to the right of center of the last Figure in the * previous row, so this Figure (which is at the start of a new row) is the * candidate. */ if (p.y <= rowBottom) { if (candidate == -1) candidate = i; break; } else candidate = -1; // Mouse's Y is outside the row, so reset the candidate } rowBottom = Math.max(rowBottom, rect.bottom()); if (candidate == -1) { /* * See if we have a possible candidate. It is a candidate if the cursor is * left of the center of this candidate. */ if (p.x <= rect.x + (rect.width / 2)) candidate = i; } if (candidate != -1) { // We have a candidate, see if the rowBottom has grown to include the mouse Y. if (p.y <= rowBottom) { /* * Now we have determined that the cursor.Y is above the bottom of the * current row of figures. Stop now, to prevent the next row from being * searched */ break; } } } return candidate; } protected boolean isHorizontal() { IFigure figure = ((GraphicalEditPart)getHost()).getContentPane(); return ((FlowLayout)figure.getLayoutManager()).isHorizontal(); } private Point getLocationFromRequest(Request request) { return ((DropRequest)request).getLocation(); } private Rectangle getAbsoluteBounds(GraphicalEditPart ep) { Rectangle bounds = ep.getFigure().getBounds().getCopy(); ep.getFigure().translateToAbsolute(bounds); return bounds; } }