Vainolo's Blog

Creating an OPM GEF Editor – Part 18: Snapping to Grid and to Geometry

5 comments

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.

  1. 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) called SnapFeedbackPolicy. As usual this is done in the createEditPolicies 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());
        }
    
  2. 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 the OPMObjectProcessDiagramEditPart and OPMThingEditPart 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.

  3. 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));		
        }
    
  4. 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.

Written by vainolo

September 4th, 2011 at 9:40 am

Posted in Programming

Tagged with , , , , , ,

5 Responses to 'Creating an OPM GEF Editor – Part 18: Snapping to Grid and to Geometry'

Subscribe to comments with RSS or TrackBack to 'Creating an OPM GEF Editor – Part 18: Snapping to Grid and to Geometry'.

  1. Hi there. Great tutorials for me. But I cannot change grid size, have any ideas?

    Olexandr

    27 Dec 11 at 16:55

  2. I founded it!
    getGraphicalViewer().setProperty(SnapToGrid.PROPERTY_GRID_SPACING, new Dimension(50,50));

    Olexandr

    27 Dec 11 at 17:40

  3. Exactly. That is what I also found in Google

    admin

    27 Dec 11 at 18:15

  4. 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?

    Leonid Dworzanski

    28 Jan 14 at 17:55

  5. 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.

    vainolo

    2 Feb 14 at 22:29

Leave a Reply

%d bloggers like this: