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.