blob: 7e0b44d7b3ed860f845b103a8e33ccd952e87752 [file] [log] [blame]
<html>
<head>
<title>GEF Design Documents</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="http://dev.eclipse.org/default_style.css" type="text/css">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border=0 cellspacing=5 cellpadding=2 width="100%">
<tr>
<td align=left width="72%"> <font class=indextop> Graphical Text Proposal
(Draft)</font><br>
<font class=indexsub> design documents</font></td>
<td width="28%"><img src="http://dev.eclipse.org/images/Idea.jpg" height=86 width=120></td>
</tr>
</table>
<table BORDER=0 CELLPADDING=2 WIDTH="100%" >
<tr>
<td ALIGN=LEFT VALIGN=TOP BGCOLOR="#0080C0"><b>
<font face="Arial,Helvetica" color="#FFFFFF">Support for Graphical Text Editing</font></b></td>
</tr>
</table>
<p>This document outlines the requirements for textual graphical
editing and any known design decision we have chosen.</p>
<p>Last Updated: November 17<sup>th</sup> 2004</p>
<h2>Introduction</h2>
<p>Graphical Text Editing is defined as the editing of text directly
in a Graphical Viewer without the use of native SWT controls such as those used
by CellEditors.&nbsp; This is also referred to as WYSIWYG
(what-you-see-is-what-you-get) text editing.&nbsp; Such functionality could be
used as the basis for editing textual nodes (i.e. sticky notes) in a diagram,
building an HTML editor, or even a new form of java source editor.&nbsp; The
major concerns include navigation and placement of the Caret, enhancements to
Commands and the CommandStack, Selection of text, accessibility, and
bidirectional languages (BiDi).&nbsp; The initial phase will concentrate on
getting the editing infrastructure right, and not on enhancing the figures and
layouts in draw2d to render complex documents.</p>
<h2>Table of Contents</h2>
<p dir="ltr">Defining Textual Selection</p>
<h2><a name="Defining_Textual_Selection">Defining Textual Selection</a></h2>
<table border="0" id="table3" cellspacing="0" cellpadding="2">
<tr>
<td valign="top" colspan="2">
<p>The notion of selection will be extended to support a single range of
selected &quot;characters&quot;.&nbsp; Object-based selection will still exist
and will coincide with textual selection range.&nbsp; Listeners of selection
service will receive some new ISelection derivative which can be queried for
both the object selection or textual selection.</p>
<p><b>Simple Selection Range<br>
</b>In a simple use case, one or more EditParts display text which can be edited
individually.&nbsp; The user may navigate, edit, and select text within a single
EditPart and any given time.&nbsp; An example of this would be sticky notes in a
class diagram, or text blocks in a program for slide presentation editor.</p>
<p>Simple selection can be represented by the EditPart which owns the
text selection, and a starting and ending offset index.</p>
</td>
<td rowspan="2" align="right">
<table border="1" id="table8" bordercolorlight="#000000" bordercolordark="#000000" cellspacing="0" cellpadding="3">
<tr>
<td bgcolor="#FFFF66">Graphical Text Viewer</td>
</tr>
<tr>
<td>
<img border="0" src="images/simpleselection.gif?cvsroot=Tools_Project" width="223" height="205">
</td>
</tr>
</table>
<i><b>Figure 1</b> - Simple selection range</i>
</td>
</tr>
<tr>
<td valign="top" rowspan="2"><b>Defining a Textual EditPart<br>
</b>The EditPart interface allows the viewer to set the selection state
on the part.&nbsp; In a similar way for text support, a <i><b>textual</b></i> EditPart
will allow the viewer to tell it its &quot;selection range&quot; in the text
sense.&nbsp; EditParts are told of their selection state so that it may
be rendered correctly in the UI.<p><b>Extended Selection Range<br>
</b>In the more general case, text selection may span across multiple
EditParts.&nbsp; EditParts may correspond to paragraphs, styled regions
of text, images, table cells, etc.&nbsp; It is common to allow the user
to select across such boundaries.&nbsp; It is not common to allow
multiple disjoint selection ranges.</p>
<p>Complex selection can be defined by a pointer to the
starting and ending EditParts, and an offset within each.&nbsp; The
selection range must be contiguous, so all textual elements between the
start and the end are also implicitly selected.&nbsp; This most likely
means that the leaf-node parts are selected.&nbsp; But there may be
applications where selection offsets are inside a container part.<br>
&nbsp;<table border="0" id="table10" cellspacing="0" cellpadding="0">
<tr>
<td valign="top">
<img border="0" src="images/decision.gif?cvsroot=Tools_Project" width="63" height="38"></td>
<td valign="top"><b>Decision</b> - GEF will supported extended
selection ranges.&nbsp; In the case where the start and end
EditParts are the same, this is identical to the simple
selection range above.&nbsp; Application will have a way of
preventing selection from spanning EditParts.&nbsp; Disjoint
selection ranges are not being considered.&nbsp; Disjoint <b>
Object</b> selection (such as selecting multiple table cells) is
not to be confused with a form of textual selection.</td>
</tr>
</table>
</td>
<td valign="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</td>
</tr>
<tr>
<td valign="top" colspan="2" align="right">
<br><i><b>Figure 2</b> - Extended selection across multiple parts</i>
<table border="1" id="table9" bordercolorlight="#000000" bordercolordark="#000000" cellspacing="0" cellpadding="3">
<tr>
<td bgcolor="#FFFF66">Graphical Text Viewer</td>
</tr>
<tr>
<td>
<img border="0" src="images/complexselection.gif?cvsroot=Tools_Project" width="337" height="319"></td>
</tr>
</table></td>
</tr>
</table>
<h2><a name="Navigation_via_keyboard_">Navigation via keyboard</a></h2>
<p>Keyboard navigation will occur by asking the caret owner for the next caret
placement.&nbsp; The presence of a SHIFT modifier will determine whether the
existing selection is modified or replaced.</p>
<p>The following table shows some of the strategies for determining the next
location.</p>
<table border="1" cellpadding="5" cellspacing="0" bordercolorlight="#000000" bordercolordark="#000000" id="table20">
<tr>
<td>&nbsp;</td>
<td><b><font size="3">Inline</font></b></td>
<td><b><font size="3">Inline Containers</font></b></td>
<td><b><font size="3">Blocks</font></b></td>
</tr>
<tr>
<td><b><font size="3">LEFT, RIGHT</font></b></td>
<td>local search, then parent</td>
<td>check sibling, then parent</td>
<td>check sibling, then parent</td>
</tr>
<tr>
<td><b><font size="3">UP, DOWN</font></b></td>
<td>ask parent</td>
<td>ask parent</td>
<td>ordered search, compare multiple results</td>
</tr>
<tr>
<td><b><font size="3">UP_INTO, DOWN_INTO</font></b></td>
<td>local search</td>
<td>local child search, compare multiple results</td>
<td>local child search, compare multiple results</td>
</tr>
<tr>
<td><b><font size="3">HOME_QUERY, END_QUERY</font></b></td>
<td>local search</td>
<td>first successful child</td>
<td>first successful child</td>
</tr>
<tr>
<td><b><font size="3">HOME, END</font></b></td>
<td>ask parent</td>
<td>ask parent</td>
<td>
<p dir="ltr">ordered search, compare multiple results</td>
</tr>
</table>
<p>&nbsp;</p>
<h2><a name="Typing_Via_Keyboard">Typing Via Keyboard</a></h2>
<h3>Requirements:</h3>
<ul>
<li>
<p>Commands must be used to modify the model.</p></li>
<li>
<p>Typing multiple characters is considered a single edit by the
user, and should be undoable via a single invoke of Undo.</p></li>
<li>
<p>Pressing backspace or delete multiple times is considered a
single edit by the user.&nbsp; The removal should be undoable via a single
invoke of Undo.</p></li>
<li>
<p>Undo and Redo of edits must also place the selection and caret
and selection range to the area of the undo/redo.&nbsp; Also, the viewer
must be scrolled some&nbsp; amount to expose the maximum of that range.</p>
</li>
<li>
<p>Processing of editing must be context aware.&nbsp; Different editparts
may allow different forms of editing.</p></li>
<li>
<p>Delete, Backspace, and inserting when there is a selection
range are all special types of removes.&nbsp; In these cases, the selection
range is removed from the model, and the contents following the selection
range should be re-parented and even merged into the contents preceding the
selection range.&nbsp; When merging is not possible, the Caret is left with
the preceding element.</p></li>
<li>
<p>Any edit may return a pending state which is to be applied to a
subsequent typing text.&nbsp; For example, If you have a bold word, and you
delete it using backspace and then type again, the text should be bold.&nbsp;
However, if you delete it and commit that edition, then the empty bold
editpart should not exist.&nbsp; Such a pending state is
application-specific.</p></li>
<li>
<p>Pending states may also be caused by invoking toolbar or
keyboard Actions.&nbsp; For example, pressing CTRL+B should enter a pending
&quot;bold&quot; state.&nbsp; Any characters typed should be inserted with bold
attributes.&nbsp; But if not text is typed, the model should not be changed.</p>
</li>
</ul>
<h3>Obtaining the Commands</h3>
<p>Commands will be obtained from one target EditPart.&nbsp; The
target editpart will be calculated based on the <b><i>start</i></b> and <b><i>
end</i></b> EditParts of the viewer's current <b><i>Selection Range</i></b>.&nbsp;
The candidate target will be the common ancestor of the start and end parts.&nbsp;
If the start and end are the same, then the common ancestor is that part. The
candidate will then be asked for the target editpart for the current request,
and it may return itself.&nbsp; However, it will often return the outer-most
context in which it resides, such as a block of text, a cell inside a table, the
&quot;body&quot; of the document, etc.</p>
<h3>Continued Editing</h3>
<p>As the user continues to type, delete, or press backspace, the
command which made the initial edit will be updated.&nbsp; An initial request
will be sent which contains the current selection range, and the key which was
typed.&nbsp; The editpart will return a command for the modification to the
model.&nbsp; That command will be executed on the command stack.&nbsp; Upon
subsequent editions of the same type, the target editpart will receive another
request for a command, but this request will contain the previously executed
command.&nbsp; If the editpart wishes to continue the same edit, it must append
to this command instance any new editing, and return that same command.&nbsp;
Otherwise it may return a different command instance which will be executed
normally.</p>
<p>A reused command will implement a special interface allowing it to
be executed multiple times by the text tool.&nbsp; When the command is appended,
it should <b>not</b> change its undo/redo behavior until this addition has been
committed by calling some type of &quot;re-execute&quot; API.</p>
<h3>Removal of a Selection Range</h3>
<p>When the user removes the selection range (either via DEL,
BACKSPACE, or typing), there are several steps to processing the removal.&nbsp;
First, the viewer indicates to all of the textual editparts between the start
and end of the selection range that they are selected.&nbsp; This is done so
that selection may be rendered in each editpart's figure.&nbsp; This is shown in
<b>Figure 3</b>.</p>
<blockquote>
<i><b>Figure 3</b> - The text viewer and its indicated selection</i><table border="1" cellpadding="5" cellspacing="0" bordercolorlight="#000000" bordercolordark="#000000" id="table16">
<tr>
<td>
<img border="0" src="images/example_remove_selected.gif?cvsroot=Tools_Project"></td>
</tr>
</table>
</blockquote>
<p>However, the selected parts are not necessarily all that is removed.&nbsp;
If all of the text parts inside a compound part are selected, then that compound
parts should be deleted, as shown in <b>Figure 4</b>.</p>
<blockquote>
<i><b>Figure 4</b> - EditPart structure showing what needs to be deleted</i><table border="1" cellpadding="5" cellspacing="0" bordercolorlight="#000000" bordercolordark="#000000" id="table17">
<tr>
<td>
<img border="0" src="images/example_remove_which.gif?cvsroot=Tools_Project"></td>
</tr>
</table>
</blockquote>
<p>Once the appropriate objects to remove are identified, the
application should attempt to merge the text which immediately preceded and
followed the selection range.&nbsp; Merging can be complex, but it is important
to follow existing conventions whenever possible.</p>
<blockquote>
<i><b>Figure 5 </b>- Intermediate structure after
selection range removal</i><table border="1" cellpadding="5" cellspacing="0" bordercolorlight="#000000" bordercolordark="#000000" id="table18">
<tr>
<td>
<img border="0" src="images/example_remove_merge.gif?cvsroot=Tools_Project"></td>
</tr>
</table>
</blockquote>
<p><b>Figure 5</b> shows the intermediate results after the removal but prior to
a possible merge.&nbsp; The preceding and succeeding elements should be merged
whenever possible.&nbsp; For example, if <b>both</b> parents represent
a paragraph, and the children are text with identical styles, then the two
remaining portions should be joined together as shown in <b>Figure 6.1</b>.&nbsp;
It would be incorrect to leave the two paragraphs separated.&nbsp; The operation
should be equivalent to deleting the ranges from each paragraph, and then
placing the caret at the end location and pressing BACKSPACE, which would join
the two paragraphs.&nbsp; If both parents are paragraphs, but the children are
text with different styles, then the end child is re-parented to the first
paragraph, and the second paragraph is removed from the document.&nbsp; This is
shown in <b>Figure 6.2</b>.&nbsp; Finally, if the two parents represent styles
which are applied to their children, then those styles should remain intact.&nbsp;
For example, if the first child were parented by a <b>bold</b> style, and the
second child's parent indicated a <font face="Arial" color="#0000FF">blue</font>
foreground, then this style structure should be maintained, as shown in <b>
Figure 6.3</b>.&nbsp; In all 3 cases, the final location for the caret will be
where the selection range began.&nbsp; It does not matter if the user selected
the range in a forward or backward direction.</p>
<blockquote>
<b><i>Figure 6 </i></b><i>- Final structure and caret
placement if merging occurs</i><table border="1" cellpadding="5" cellspacing="0" bordercolorlight="#000000" bordercolordark="#000000" id="table19">
<tr>
<td>
<img border="0" src="images/example_remove_results.gif?cvsroot=Tools_Project" width="568" height="255"></td>
</tr>
</table>
</blockquote>
<p>&nbsp;</p>
<h3>Backspace</h3>
<p>As the user presses backspace repeatedly, text will get removed
from the current selection part until that part has no more text to be deleted.&nbsp;
At which point, that text node is empty and probably has no effect on the
rendering of the document.&nbsp; The model should be compacted to its simplest
representation.&nbsp; But, the application does not know the users intentions.&nbsp;
The user may either start typing immediately, or save the document.&nbsp; If the
document is saved, it should be in its simplest form.&nbsp; But, if the user
inserts a character, the node which became empty should be restored and the
character should be placed back into that node.&nbsp; For this to work, we will
probably need some pending state object returned from the backspace operation.&nbsp;
That state will affect how an inserted character is treated.&nbsp; Several
actions will cause the pending state to be thrown out, such as the selection
range changing.</p>
<h2 dir="ltr">Interaction with Styles</h2>
<p dir="ltr">Styles are things like Bold, font name, Italic, Underline, or
even style &quot;classes&quot; such as H1, etc.&nbsp; Sometimes invoking a style change
has an immediate affect on the document.&nbsp; Other times, it has a pending
effect which is committed if the user inserts text normally.</p>
<h3 dir="ltr">Requirements</h3>
<ol dir="ltr">
<li dir="ltr">
<p dir="ltr">When selection is empty, a style change may have a pending
effect.&nbsp; For example, turning on BOLD does not modify the document
until you type something.&nbsp; Similar for setting font height or name,
colors, etc.</p>
</li>
<li dir="ltr">
<p dir="ltr">When selection is empty, a style change may also have an
immediate effect.</p>
</li>
<li dir="ltr">
<p dir="ltr">When selection exists, a style change must cause an immediate
change in the document or do nothing.</p></li>
<li dir="ltr">
<p dir="ltr">It should be possible to display a style value in a read-only
way.&nbsp; For example, a locked region of a document is BOLD.</p></li>
</ol>
<p dir="ltr">Because of number 2. above, things like paragraph alignment could
optionally be implemented as a style.&nbsp; However, generally changing
paragraph alignment always has an immediate effect on the document, so it could
be just a simple selection-based action. </p>
<p dir="ltr">&nbsp;</p>
<h2>Mouse Interactions</h2>
<p>[Placing the caret with the mouse, selecting with the mouse, dragging
selected text, etc].</p>
<h2>Mixed Mode Use</h2>
<p>Using the logic editor as an example, it should be possible to edit a label
object without celleditors.&nbsp; F2 or 2 mouse clicks should cause the text
editing to become active.&nbsp; Focus lost, Selection lost, or CTRL+ENTER must
exit the mode and commit the change.&nbsp; ESC must rollback all text edits and
exit the text editing mode.</p>
</body></html>