blob: 12daf8a64add8802a6526c4d3c6635b081bb2b5a [file] [log] [blame]
<!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.&#160; This article does not cover native DND operations, but
does include: resizing, aligning, moving, reparenting, reconnecting, bending,
creating, and deleting.&#160; 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.&#160; 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.&#160; The first is
Actions.&#160;
<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.&#160; 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.&#160; The model
drives everything in GEF.&#160; 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>&nbsp;</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 &quot;object&quot; (which may be a node, class, state, activity,
etc.) occurs when the user is in the creation mode and clicks on the editor.&nbsp;
The CreationTool will process the click, and target the appropriate EditPart
under the mouse, and send it the appropriate CreateRequest.&nbsp; 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.&nbsp;</p>
</div>
<p>&nbsp;</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%">&nbsp;</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">&nbsp;</td>
<td valign="top">CreationTool</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>EditPolicies:</b></td>
</tr>
<tr>
<td valign="top">&nbsp;</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">&nbsp;</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.&nbsp; Which drag tracker is used is dependant on the mouse
location and other data.&nbsp;
<b>RESIZE</b> handles allow the user to resize all of the selected EditParts
in the direction determined by the handle.&nbsp; 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.&nbsp;
Dragging an EditPart within the confines of its original container will be
interpreted as a <b>MOVE</b>.&nbsp; Once the user drags the mouse over a new
container, the interaction becomes a <b>REPARENT</b>.&nbsp; While a move
operation only involves one container, a reparent involves both the original
and new containers.&nbsp; The old container is asked to ORPHAN the child,
while the new container is asked to ADD the child.</p>
</div>
<p>&nbsp;</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%">&#160;</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">&nbsp;</td>
<td valign="top">ResizeTracker, DragEditPartsTracker</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>EditPolicies:</b></td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td>ResizableEditPolicy and XYLayoutEditPolicy</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>Request:</b></td>
</tr>
<tr>
<td align="right" valign="top">
&nbsp;</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 &quot;connection&quot; (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.&#160; 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.&#160; The source is asked for a &quot;Connection Start&quot; command.&#160;
This command is not necessarily executed, but is passed to the target part when
the target is asked for the &quot;Connection End&quot; command.&#160; This allows the
source to pass information, such as which &quot;terminal&quot; the user clicked on, to
the target.&#160; It also allows the source to communicate whether the user
clicked in a valid location, via the returned command's isExecutable() result.&#160;
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%">&#160;</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">&nbsp;</td>
<td>ConnectionCreationTool</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>EditPolicy:</b></td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td>
<td>GraphicalNodeEditPolicy</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>Request:</b></td>
</tr>
<tr>
<td>
&nbsp;</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.&nbsp; A connection end is moved from one node or
&quot;anchor point&quot; to another.&nbsp;(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.&nbsp;Reconnecting is a <i>targeting</i> operation.&nbsp;
As such, the target editpart is responsible for making the change to the
model.&nbsp; 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%">&#160;</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">&nbsp;</td>
<td>ConnectionEndpointTracker</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>EditPolicy:</b></td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td>GraphicalNodeEditPolicy<br>
EndpointEditPolicy</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>Request:</b></td>
</tr>
<tr>
<td>
&nbsp;</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.&nbsp; 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.&nbsp;
For &quot;oblique&quot; 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.&nbsp; For this reason, there is no &quot;remove bendpoint&quot; request in
GEF anywhere.&nbsp; 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%">&#160;</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">
&nbsp;</td>
<td>ConnectionBendpointTracker</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>EditPolicy:</b></td>
</tr>
<tr>
<td valign="top">
&nbsp;</td>
<td>BendpointEditPolicy</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>Request:</b></td>
</tr>
<tr>
<td>
&nbsp;</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.&nbsp; 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.&nbsp;
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>&nbsp;</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%">&#160;</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">
&nbsp;</td>
<td>AlignmentAction</td>
</tr>
<tr>
<td width="37%" valign="top" colspan="2">
<b>EditPolicy:</b></td>
</tr>
<tr>
<td valign="top">
&nbsp;</td>
<td>ResizableEditPolicy</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>Request:</b></td>
</tr>
<tr>
<td valign="top">
&nbsp;</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.&#160; The contributions are combined into
a compound command.&#160; Whenever the selection changes, the delete action
must be updated to calculate its enabled state.&#160; 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.&nbsp; When the user deselects everything, the viewer returns the
<b> <i>contents</i></b>
edit part from the viewer as the current selection.&#160; Therefore, the delete action only disables
if the contents editpart returns a non-executable command in response to a delete
request.&#160; This can be achieved by installing a <code>RootComponentEditPolicy</code>
on the contents part.</td>
</tr>
</table>
<p>&nbsp;</div>
<p>&nbsp;</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%">&#160;</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">&nbsp;</td>
<td>DeleteAction</td>
</tr>
<tr>
<td valign="top" colspan="2">
<b>EditPolicy:</b></td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td>ComponentEditPolicy<br>
RootComponentEditPolicy</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td valign="top">
&nbsp;</td>
<td valign="top">
&nbsp;</td>
<td valign="top">
&nbsp;</td>
</tr>
<tr>
<td valign="top">
&nbsp;</td>
<td valign="top">
&nbsp;</td>
<td valign="top">
&nbsp;</td>
</tr>
</table>
</body>
</html>