Standard User Interactions in GEF
article : graphical editing framework

Summary
This article discusses the types of user interactions that are recognized and supported in GEF.  This article does not cover native DND operations, but does include: resizing, aligning, moving, reparenting, reconnecting, bending, creating, and deleting.  The purpose of this article is to give the developer an overall feel of what is available, and to introduce a consistent terminology for describing interactions.  This article assumes a basic familiarity with GEF's MVC architecture (Model-Figure-EditPart).

By Randy Hudson, IBM Research Triangle Park
May 7, 2003

Introduction

An interaction is defined as a user-invoked change to an Editor's model. There are two broad categories of interactions in GEF.  The first is Actions.  IAction is a JFace concept, but GEF includes several action implementations. Actions usually appear in menus, toolbars, popup, and usually operate on the current selection.  Examples include delete, align, and undo.

The other type of interaction is graphical. Graphical interactions are those which are performed on just a Canvas using the mouse (or keyboard accessible equivalent) and perhaps some key modifiers. Mouse interactions are handled by Tools (Native drag-and-drop is a separate topic). A Tool represents a mode. The active tool or mode determines how mouse events are interpreted. Note: You may be asking why native drag and drop isn't used.

It is important to point out that 99% of all interactions should be carried out as Commands which modify the application model.  The model drives everything in GEF.  Exceptions would be non-persisted data or data that isn't part of the model, such as expansion state or maybe the zoom level.

 

Tool-based Interactions

Creation

Creation of an "object" (which may be a node, class, state, activity, etc.) occurs when the user is in the creation mode and clicks on the editor.  The CreationTool will process the click, and target the appropriate EditPart under the mouse, and send it the appropriate CreateRequest.  The result should be an executable command which is executed, causing the appropriate change to the model.

The interesting information during creation is the point at which the user clicked, the targeted EditPart, and optionally the rectangle drawn-out by the user if size-on-drop is used/supported. 

 

Related Classes  
Tool:
  CreationTool
EditPolicies:
  LayoutEditPolicy and/or
ContainerEditPolicy
Request:
  CreateRequest

Move, Resize, and Reparent

Once you have something created, you can interact with that object directly in several ways. Many interactions in GEF are performed while the editor is in its default mode, with the SelectionTool active.

The selection tool obtains a DragTracker at the time the user presses the mouse, and delegates events to that tracker until the mouse is released.  Which drag tracker is used is dependant on the mouse location and other data.  RESIZE handles allow the user to resize all of the selected EditParts in the direction determined by the handle.  Objects that are not resizable will not participate in the resize and should not show resize feedback.

A DragTacker can also be returned from the EditPart itself.  Dragging an EditPart within the confines of its original container will be interpreted as a MOVE.  Once the user drags the mouse over a new container, the interaction becomes a REPARENT.  While a move operation only involves one container, a reparent involves both the original and new containers.  The old container is asked to ORPHAN the child, while the new container is asked to ADD the child.

 

Related Classes  
Drag Trackers:
  ResizeTracker, DragEditPartsTracker
EditPolicies:
  ResizableEditPolicy and XYLayoutEditPolicy
Request:
  ChangeBoundsRequest

Connection Creation

Creation of a "connection" (a.k.a. link, flow) is done with ConnectionCreationTool. The connection tool requires that the user click twice, once on the source, and again on the target.  This allows the user to scroll the diagram between clicks.

The responsibility of creating the connection is divided between the source and target EditParts.  The source is asked for a "Connection Start" command.  This command is not necessarily executed, but is passed to the target part when the target is asked for the "Connection End" command.  This allows the source to pass information, such as which "terminal" the user clicked on, to the target.  It also allows the source to communicate whether the user clicked in a valid location, via the returned command's isExecutable() result.  Even though the command must indicate that it is executable, it won't get executed because it is only being used to pass data to the target.

During connection creation, the connection editpart does not exist yet. Therefore, GEF will ask the source editpart to show feedback for the creation of the connection. Once the connection editpart exists, it is the primary means for showing feedback.
Related Classes  
Tool:
  ConnectionCreationTool
EditPolicy:
  GraphicalNodeEditPolicy
Request:
  CreateConnectionRequest

Reconnecting

When a connection is selected it displays handles. There are two types of connection handles in GEF that allow for two different interactions. The first and most common interaction is called a reconnect.

Reconnection is a semantic change to the document.  A connection end is moved from one node or "anchor point" to another. (Some applications have only one basic anchor point per node.)

Reconnecting is done using the drag tracker returned by the handle at either end of a connection. Reconnecting is a targeting operation.  As such, the target editpart is responsible for making the change to the model.  But, the connection editpart is still involved in showing feedback during the interaction.

Related Classes  
Tool:
  ConnectionEndpointTracker
EditPolicy:
  GraphicalNodeEditPolicy
EndpointEditPolicy
Request:
  ReconnectRequest

Bending Connections

Bending connections is an aesthetic change. Different applications will use separate approaches to connection bending (a.k.a. routing). Some even allow the user to choose different routing mechanisms at the diagram or even per connection.

When the user clicks on a bendpoint handle, only that bendpoint is modified.  In other words, the set of selected connections has no effect on the interaction.

Bending a connection can also be used to remove an existing bendpoint.  For "oblique" connection routing, the bendpoint should be removed whenever it falls along the imaginary line between the previous and next point in the connection. Different interpretations are necessary for different routing strategies.  For this reason, there is no "remove bendpoint" request in GEF anywhere.  It is up to the bendpoint policy to recognize when removal should be done.

Related Classes  
Tool:
  ConnectionBendpointTracker
EditPolicy:
  BendpointEditPolicy
Request:
  BendpointRequest

Action-driven Interactions

Alignment

Alignment can be performed whenever two or more editparts that support alignment are selected.  There are three types of horizontal alignments (left, center, right), and three vertical (top, middle, bottom).

Each of the selected nodes is aligned with the primary selected node.  The primary selection is indicated by black selection handles, non-primary selection is indicated by white handles with a black outline.

The set of selected editparts is filtered in two passes. First, If both a child and parent are selected, the child is ignored. Second, from the parts remaining after step one, parts that don't understand alignment are ignored. This allows for connections to be ignored.

 

Related Classes  
Action:
  AlignmentAction
EditPolicy:
  ResizableEditPolicy
Request:
  AlignmentRequest

Delete

Delete is an action which operates on the selection set. The DeleteAction creates a DeleteRequest, and asks each selected editpart to contribute to the delete.  The contributions are combined into a compound command.  Whenever the selection changes, the delete action must be updated to calculate its enabled state.  It does this by building the compound command, and testing whether it can be executed.

It is worth pointing out that a view's selection is never empty.  When the user deselects everything, the viewer returns the contents edit part from the viewer as the current selection.  Therefore, the delete action only disables if the contents editpart returns a non-executable command in response to a delete request.  This can be achieved by installing a RootComponentEditPolicy on the contents part.

 

 

Related Classes  
Action:
  DeleteAction
EditPolicy:
  ComponentEditPolicy
RootComponentEditPolicy