Last updated on 2014-09-07
Previous Tutorial: Creating an OPM GEF Editor – Part 17: How to Define Container Edit Parts.
As a finishing touch to our editor, we will now add snapping functionality to our editor. This will probably be the last tutorial I’ll be writing for some time since I have now a working editor that can be used for my purposes. Only if I find some new GEF features that have not been covered here they will be added. But the development of my OPM editor with continue and you are always invited to check the repository for new versions.
- For how snapping is implemented, it looks like an undocumented feature, but it is something that I ADORE in editors, so why not use it? and the implementation is really easy. First, we have to add a new
Policy
to all the container nodes (OPD, Thing) calledSnapFeedbackPolicy
. As usual this is done in thecreateEditPolicies
method:@Override protected void createEditPolicies() { installEditPolicy(EditPolicy.LAYOUT_ROLE, new OPMContainerXYLayoutPolicy()); installEditPolicy("Snap Feedback", new SnapFeedbackPolicy()); }
@Override protected void createEditPolicies() { super.createEditPolicies(); installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new OPMThingDirectEditPolicy()); installEditPolicy("Snap Feedback", new SnapFeedbackPolicy()); }
- Second thing we need to do is adapt these classes to
SnapToHelper
instances, which is a GEF provided class that helps create the snap functionality. We have to do this again twice in theOPMObjectProcessDiagramEditPart
andOPMThingEditPart
classes (Hm… looks like a good place to start refactoring in the future to remove duplicate code):/** * Currently the class only adapts to create a {@link SnapToHelper} * when the editor is in snapping mode (either to grid or to shapes). */ @Override public Object getAdapter(Class key) { if (key == SnapToHelper.class) { List<SnapToHelper> helpers = new ArrayList<SnapToHelper>(); if (Boolean.TRUE.equals(getViewer().getProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED))) { helpers.add(new SnapToGeometry(this)); } if (Boolean.TRUE.equals(getViewer().getProperty(SnapToGrid.PROPERTY_GRID_ENABLED))) { helpers.add(new SnapToGrid(this)); } if(helpers.size()==0) { return null; } else { return new CompoundSnapToHelper(helpers.toArray(new SnapToHelper[0])); } } return super.getAdapter(key); }
the same implementation works in the
OPMThingEditPart
. - Now we have to register the snap actions in the editor:
@Override protected void configureGraphicalViewer() { super.configureGraphicalViewer(); getGraphicalViewer().setEditPartFactory(new OPMEditPartFactory()); getActionRegistry().registerAction(new ToggleGridAction(getGraphicalViewer())); getActionRegistry().registerAction(new ToggleSnapToGeometryAction(getGraphicalViewer())); }
and add the actions to the toolbar:
@Override protected void buildActions() { addRetargetAction(new UndoRetargetAction()); addRetargetAction(new RedoRetargetAction()); addRetargetAction(new DeleteRetargetAction()); addRetargetAction(new RetargetAction(GEFActionConstants.TOGGLE_GRID_VISIBILITY, GEFMessages.ToggleGrid_Label, IAction.AS_CHECK_BOX)); addRetargetAction(new RetargetAction(GEFActionConstants.TOGGLE_SNAP_TO_GEOMETRY, GEFMessages.ToggleSnapToGeometry_Label, IAction.AS_CHECK_BOX)); } @Override public void contributeToToolBar(IToolBarManager toolBarManager) { super.contributeToToolBar(toolBarManager); toolBarManager.add(getAction(ActionFactory.UNDO.getId())); toolBarManager.add(getAction(ActionFactory.REDO.getId())); toolBarManager.add(getAction(ActionFactory.DELETE.getId())); toolBarManager.add(getAction(GEFActionConstants.TOGGLE_GRID_VISIBILITY)); toolBarManager.add(getAction(GEFActionConstants.TOGGLE_SNAP_TO_GEOMETRY)); }
- That is all that is needed!. Fire your editor and see the nice blue lines helping you snap your figures:
As usual, I hope this short explanation has helped you in your work. If you have any questions/suggestions, don’t hesitate to leave a comment.
Next Tutorial: Creating an OPM GEF Editor – Part 19: Displaying Tooltips.
Hi there. Great tutorials for me. But I cannot change grid size, have any ideas?
I founded it!
getGraphicalViewer().setProperty(SnapToGrid.PROPERTY_GRID_SPACING, new Dimension(50,50));
Exactly. That is what I also found in Google
After I’ve added Grid and SnapToGeometry buttons the sizes of undo redo buttons changed to much bigger sized. Have you experienced the same problem?
Yea, I had this problem… I think it happens because these buttons only handle pictures correctly. Tried debugging the eclipse UI, but things get really complicated there :-(. I think the solution is to set a picture for the buttons. Check the Github repository’s latest version, since I think my current implementation is working OK.