Friday, April 13, 2012

Decorating GEF figure using EditPolicy

In GMF there is a nifty DragDropEditPolicy that allows you to decorate EditPart's figure by changing background color thus indicating to the user that he is hovering over particular figure. I wanted to use this in my GEF editor, but unfortunately this policy does not exist in GEF.

To make use of this policy I made my plugin depend on import org.eclipse.gmf.runtime.diagram.ui.editpolicies and extended DragDropEditPolicy with my own

  1. public class DesignerDragDropEditPolicty extends DragDropEditPolicy {  
  2.  private Label connectionLabel;  
  3.  private PolylineConnection relationFigure;  
  4.  private DesignerEditor editor;  
  5.  private Image image;  
  6.   
  7.  public DesignerDragDropEditPolicty() {  
  8.   connectionLabel = new Label();  
  9.   connectionLabel.setOpaque(false);  
  10.   image = DesignerUIPlugin.getDefault().getImageRegistry().get(ImageConstants.DROP_ICON);  
  11.   connectionLabel.setIcon(image);  
  12.     
  13.  }  
  14.    
  15.  @Override  
  16.  // remove icon when edit policy is done  
  17.  public void eraseTargetFeedback(Request request) {  
  18.   if(relationFigure != null){  
  19.    if(relationFigure.getChildren().contains(connectionLabel)){  
  20.     relationFigure.remove(connectionLabel);  
  21.    }  
  22.   }  
  23.  }  
  24.    
  25.  // add icon on filtered edit part. Remove it when another edit part is hovered over.  
  26.  public void showTargetFeedback(Request request) {  
  27.   if(request instanceof CreateRequest){  
  28.    editor = (DesignerEditor) DesignerUtil.getActiveDesignerTab();  
  29.    Point location = ((CreateRequest)request).getLocation();  
  30.    EditPart part = editor.getViewer().findObjectAt(location);  
  31.   
  32.    if(part instanceof RelationEditPart){  
  33.     relationFigure = ((RelationEditPart)part).getConnection();  
  34.     relationFigure.add(connectionLabel, new MidpointLocator(relationFigure, 0));  
  35.     relationFigure.repaint();  
  36.    }  
  37.    else{  
  38.     if(relationFigure != null){  
  39.      if(relationFigure.getChildren().contains(connectionLabel)){  
  40.       relationFigure.remove(connectionLabel);  
  41.      }  
  42.     }  
  43.    }  
  44.   }  
  45.  }  
  46. }  


Instead of changing background of the figure as DragDropEditPolicy does I did something different. Whenever user passes inside an EditPart, in my case it's a relation, I put an icon signifying that in this case an object can be dropped onto existing connection an be created in the middle of the relation. I could have put a label saying "Drop here", but I think icons work better than words and after you get used to seeing a particular label with words it gets annoying.

Notice that in showTargetFeedback I filter out EditPart that I am interested in, so here code can be added to add different behavior for other parts.

Blogger Syntax Highliter