| <!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | |
| <title>GEF Interactions</title> | |
| <link rel="stylesheet" href="http://dev.eclipse.org/default_style.css" type="text/css" /> | |
| <style> | |
| <!-- | |
| .whatsnew {border-left:solid #70A070 1px; border-right:solid #70A070 1px;border-bottom:solid #70A070 1px;width:100%;border-collapse:collapse;bordercolor:#111111} | |
| .paracolumn {text-align:justify; margin-right:10px} | |
| .related {float:right;top:80px;width:280px;text-align:right} | |
| .relatedtable {width:100%;cellpadding:0;cellspacing:0;border-collapse:collapse;bordercolor:#111111} | |
| .section {margin-left:60px; margin-bottom:8; margin-top:15} | |
| --> | |
| </style> | |
| </head> | |
| <body topmargin="4" leftmargin="4"> | |
| <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" id="AutoNumber1"> | |
| <tbody> | |
| <tr> | |
| <td width="120"> | |
| <img src="http://www.eclipse.org/articles/Article-Builders/images/Idea.jpg" width="120" height="86" /></td> | |
| <td> | |
| <h1 align="center">Standard User Interactions in GEF<br /> | |
| <font class="indexsub">article : graphical editing framework</font></h1> | |
| </td> | |
| <td width="120"></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <blockquote> | |
| <p><b>Summary</b><br /> | |
| 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).</p> | |
| <p><b>By Randy Hudson, IBM Research Triangle Park<br /> | |
| </b><font size="-1">May 7, 2003</font></p> | |
| </blockquote> | |
| <h2>Introduction</h2> | |
| <p>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.  | |
| <i>IAction</i> is a <i>JFace</i> 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.</p> | |
| <p>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 <b><i> | |
| Tool</i>s</b> (Native drag-and-drop is a separate topic). A Tool represents a | |
| mode. The active tool or mode determines how mouse events are interpreted. <b> | |
| Note:</b> You may be asking why native drag and drop isn't used.</p> | |
| <p>It is important to point out that 99% of all interactions should be carried | |
| out as <i>Commands</i> 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.</p> | |
| <p> </p> | |
| <table border="0" cellpadding="2" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber2" width="800"> | |
| <tr> | |
| <td valign="top" colspan="3" bgcolor="#0070A0"> | |
| <h2 style="line-height: 100%; margin-bottom: 3px"><font color="#FFFFFF">Tool-based Interactions</font></h2> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3"> | |
| <h3 class="section">Creation</h3> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| <p align="right"> | |
| <img border="0" src="images/creation.gif?cvsroot=Tools_Project" /></td> | |
| <td valign="top"> | |
| <div class="paracolumn"> | |
| <p>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.</p> | |
| <p>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. </p> | |
| </div> | |
| <p> </td> | |
| <td valign="top"> | |
| <table class="relatedtable"> | |
| <tbody> | |
| <tr> | |
| <td bgcolor="#70A070" height="15" rowspan="2" nowrap="" align="center"> | |
| <font color="#FFFFFF"> | |
| <b>Related Classes</b></font></td> | |
| <td width="61%"> </td> | |
| </tr> | |
| <tr> | |
| <td bgcolor="#70A070" height="3"> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <table class="whatsnew"> | |
| <tbody> | |
| <tr> | |
| <td valign="top" colspan="2"><b>Tool:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td valign="top">CreationTool</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>EditPolicies:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td valign="top">LayoutEditPolicy and/or<br> | |
| ContainerEditPolicy</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>Request:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td valign="top">CreateRequest</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3"> | |
| <h3 class="section">Move, Resize, and Reparent</h3> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| <p align="right"> | |
| <img border="0" src="images/resize.gif?cvsroot=Tools_Project" /></td> | |
| <td valign="top"> | |
| <div class="paracolumn"> | |
| <p>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.</p> | |
| <p>The selection tool obtains a <i>DragTracker</i> 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. | |
| <b>RESIZE</b> 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.</p> | |
| <p>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 <b>MOVE</b>. Once the user drags the mouse over a new | |
| container, the interaction becomes a <b>REPARENT</b>. 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.</p> | |
| </div> | |
| <p> </td> | |
| <td valign="top"> | |
| <table class="relatedtable"> | |
| <tbody> | |
| <tr> | |
| <td bgcolor="#70A070" height="15" rowspan="2" nowrap="" align="center"> | |
| <font color="#FFFFFF"> | |
| <b>Related Classes</b></font></td> | |
| <td width="61%"> </td> | |
| </tr> | |
| <tr> | |
| <td bgcolor="#70A070" height="3"> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <table class="whatsnew"> | |
| <tbody> | |
| <tr> | |
| <td valign="top" colspan="2"><b>Drag Trackers:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td valign="top">ResizeTracker, DragEditPartsTracker</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>EditPolicies:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td>ResizableEditPolicy and XYLayoutEditPolicy</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>Request:</b></td> | |
| </tr> | |
| <tr> | |
| <td align="right" valign="top"> | |
| </td> | |
| <td>ChangeBoundsRequest</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3"> | |
| <h3 class="section">Connection Creation</h3> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| <p align="right"> | |
| <img border="0" src="images/connect.gif?cvsroot=Tools_Project" /></td> | |
| <td valign="top"> | |
| <div class="paracolumn"> | |
| <p>Creation of a "connection" (a.k.a. link, flow) is done with <i>ConnectionCreationTool</i>. | |
| 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.</p> | |
| <p> | |
| 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.</p> | |
| <table border="0" cellpadding="3" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber3" bgcolor="#FFFF99"> | |
| <tr> | |
| <td valign="top"> | |
| <img border="0" src="images/tip.gif?cvsroot=Tools_Project" /></td> | |
| <td align="justify">During connection creation, the connection editpart | |
| does not exist yet. Therefore, GEF will ask the <i>source</i> editpart | |
| to show feedback for the creation of the connection. Once the connection | |
| editpart exists, it is the primary means for showing feedback.</td> | |
| </tr> | |
| </table> | |
| </div></td> | |
| <td valign="top"> | |
| <table class="relatedtable"> | |
| <tbody> | |
| <tr> | |
| <td bgcolor="#70A070" height="15" rowspan="2" nowrap="" align="center"> | |
| <font color="#FFFFFF"> | |
| <b>Related Classes</b></font></td> | |
| <td width="61%"> </td> | |
| </tr> | |
| <tr> | |
| <td bgcolor="#70A070" height="3"> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <table class="whatsnew"> | |
| <tbody> | |
| <tr> | |
| <td width="37%" valign="top" colspan="2"><b>Tool:</b></td> | |
| </tr> | |
| <tr> | |
| <td align="right" valign="top"> </td> | |
| <td>ConnectionCreationTool</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>EditPolicy:</b></td> | |
| </tr> | |
| <tr> | |
| <td align="right" valign="top"> </td> | |
| <td>GraphicalNodeEditPolicy</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>Request:</b></td> | |
| </tr> | |
| <tr> | |
| <td> | |
| </td> | |
| <td>CreateConnectionRequest</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3"> | |
| <h3 class="section">Reconnecting</h3> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| <p align="right"> | |
| <img border="0" src="images/reconnect.gif?cvsroot=Tools_Project" /></td> | |
| <td valign="top"> | |
| <div class="paracolumn"> | |
| <p>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<i> reconnect</i>.</p> | |
| <p>Reconnection is a <b>semantic</b> 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.)</p> | |
| <p>Reconnecting is done using the drag tracker returned by the handle at | |
| either end of a connection. Reconnecting is a <i>targeting</i> 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.</p> | |
| </div> | |
| </td> | |
| <td valign="top"> | |
| <table class="relatedtable"> | |
| <tbody> | |
| <tr> | |
| <td bgcolor="#70A070" height="15" rowspan="2" nowrap="" align="center"> | |
| <font color="#FFFFFF"> | |
| <b>Related Classes</b></font></td> | |
| <td width="61%"> </td> | |
| </tr> | |
| <tr> | |
| <td bgcolor="#70A070" height="3"> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <table class="whatsnew"> | |
| <tbody> | |
| <tr> | |
| <td width="37%" valign="top" colspan="2"><b>Tool:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td>ConnectionEndpointTracker</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>EditPolicy:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td>GraphicalNodeEditPolicy<br> | |
| EndpointEditPolicy</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>Request:</b></td> | |
| </tr> | |
| <tr> | |
| <td> | |
| </td> | |
| <td>ReconnectRequest</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3"> | |
| <h3 class="section">Bending Connections</h3> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| <p align="right"> | |
| <img border="0" src="images/bend.gif?cvsroot=Tools_Project" /></td> | |
| <td valign="top"> | |
| <div class="paracolumn"> | |
| Bending connections is an <b>aesthetic</b> 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.<p>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.</p> | |
| <p>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.</div> | |
| </td> | |
| <td valign="top"> | |
| <table class="relatedtable"> | |
| <tbody> | |
| <tr> | |
| <td bgcolor="#70A070" height="15" rowspan="2" nowrap="" align="center"> | |
| <font color="#FFFFFF"> | |
| <b>Related Classes</b></font></td> | |
| <td width="61%"> </td> | |
| </tr> | |
| <tr> | |
| <td bgcolor="#70A070" height="3"> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <table class="whatsnew"> | |
| <tbody> | |
| <tr> | |
| <td width="37%" valign="top" colspan="2"><b>Tool:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| </td> | |
| <td>ConnectionBendpointTracker</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>EditPolicy:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| </td> | |
| <td>BendpointEditPolicy</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>Request:</b></td> | |
| </tr> | |
| <tr> | |
| <td> | |
| </td> | |
| <td>BendpointRequest</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3" bgcolor="#0070A0"> | |
| <h2 style="line-height: 100%; margin-bottom: 3px"><font color="#FFFFFF">Action-driven Interactions</font></h2> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3"> | |
| <h3 class="section">Alignment</h3> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| <p align="right"> | |
| <img border="0" src="images/alignment.gif?cvsroot=Tools_Project" /></td> | |
| <td valign="top"> | |
| <div class="paracolumn"> | |
| 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).<p> | |
| Each of the selected nodes is aligned with the <i>primary</i> selected node. | |
| The primary selection is indicated by black selection handles, non-primary | |
| selection is indicated by white handles with a black outline.</p> | |
| <table border="0" cellpadding="3" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber3" bgcolor="#FFFF99"> | |
| <tr> | |
| <td valign="top"> | |
| <img border="0" src="images/tip.gif?cvsroot=Tools_Project" /></td> | |
| <td align="justify">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.</td> | |
| </tr> | |
| </table> | |
| <p> </div> | |
| </td> | |
| <td valign="top"> | |
| <table class="relatedtable"> | |
| <tbody> | |
| <tr> | |
| <td bgcolor="#70A070" height="15" rowspan="2" nowrap="" align="center"> | |
| <font color="#FFFFFF"> | |
| <b>Related Classes</b></font></td> | |
| <td width="61%"> </td> | |
| </tr> | |
| <tr> | |
| <td bgcolor="#70A070" height="3"> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <table class="whatsnew"> | |
| <tbody> | |
| <tr> | |
| <td width="37%" valign="top" colspan="2"> | |
| <b>Action:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| </td> | |
| <td>AlignmentAction</td> | |
| </tr> | |
| <tr> | |
| <td width="37%" valign="top" colspan="2"> | |
| <b>EditPolicy:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| </td> | |
| <td>ResizableEditPolicy</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>Request:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| </td> | |
| <td>AlignmentRequest</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="3"> | |
| <h3 class="section">Delete</h3> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| <p align="right"> | |
| <img border="0" src="images/delete.gif?cvsroot=Tools_Project" /></td> | |
| <td valign="top"> | |
| <div class="paracolumn"> | |
| <p>Delete is an action which operates on the <i>selection set</i>. The <code> | |
| DeleteAction</code> creates a <code>DeleteRequest</code>, 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.</p> | |
| <table border="0" cellpadding="3" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber3" bgcolor="#FFFF99"> | |
| <tr> | |
| <td valign="top"> | |
| <img border="0" src="images/tip.gif?cvsroot=Tools_Project" /></td> | |
| <td align="justify">It is worth pointing out that a view's selection is | |
| never empty. When the user deselects everything, the viewer returns the | |
| <b> <i>contents</i></b> | |
| 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 <code>RootComponentEditPolicy</code> | |
| on the contents part.</td> | |
| </tr> | |
| </table> | |
| <p> </div> | |
| <p> </td> | |
| <td valign="top"> | |
| <table class="relatedtable"> | |
| <tbody> | |
| <tr> | |
| <td bgcolor="#70A070" height="15" rowspan="2" nowrap="" align="center"> | |
| <font color="#FFFFFF"> | |
| <b>Related Classes</b></font></td> | |
| <td width="61%"> </td> | |
| </tr> | |
| <tr> | |
| <td bgcolor="#70A070" height="3"> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <table class="whatsnew"> | |
| <tbody> | |
| <tr> | |
| <td valign="top" colspan="2"><b>Action:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td>DeleteAction</td> | |
| </tr> | |
| <tr> | |
| <td valign="top" colspan="2"> | |
| <b>EditPolicy:</b></td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> </td> | |
| <td>ComponentEditPolicy<br> | |
| RootComponentEditPolicy</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| </td> | |
| <td valign="top"> | |
| </td> | |
| <td valign="top"> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td valign="top"> | |
| </td> | |
| <td valign="top"> | |
| </td> | |
| <td valign="top"> | |
| </td> | |
| </tr> | |
| </table> | |
| </body> | |
| </html> |