| <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. This is also referred to as WYSIWYG |
| (what-you-see-is-what-you-get) text editing. 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. The |
| major concerns include navigation and placement of the Caret, enhancements to |
| Commands and the CommandStack, Selection of text, accessibility, and |
| bidirectional languages (BiDi). 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 "characters". Object-based selection will still exist |
| and will coincide with textual selection range. 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. The user may navigate, edit, and select text within a single |
| EditPart and any given time. 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. In a similar way for text support, a <i><b>textual</b></i> EditPart |
| will allow the viewer to tell it its "selection range" in the text |
| sense. 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. EditParts may correspond to paragraphs, styled regions |
| of text, images, table cells, etc. It is common to allow the user |
| to select across such boundaries. 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. The |
| selection range must be contiguous, so all textual elements between the |
| start and the end are also implicitly selected. This most likely |
| means that the leaf-node parts are selected. But there may be |
| applications where selection offsets are inside a container part.<br> |
| <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. In the case where the start and end |
| EditParts are the same, this is identical to the simple |
| selection range above. Application will have a way of |
| preventing selection from spanning EditParts. Disjoint |
| selection ranges are not being considered. 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"> |
| </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. 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> </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> </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. 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. Also, the viewer |
| must be scrolled some amount to expose the maximum of that range.</p> |
| </li> |
| <li> |
| <p>Processing of editing must be context aware. 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. 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. 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. For example, If you have a bold word, and you |
| delete it using backspace and then type again, the text should be bold. |
| However, if you delete it and commit that edition, then the empty bold |
| editpart should not exist. Such a pending state is |
| application-specific.</p></li> |
| <li> |
| <p>Pending states may also be caused by invoking toolbar or |
| keyboard Actions. For example, pressing CTRL+B should enter a pending |
| "bold" state. Any characters typed should be inserted with bold |
| attributes. 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. 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>. |
| The candidate target will be the common ancestor of the start and end parts. |
| 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. 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 |
| "body" 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. An initial request |
| will be sent which contains the current selection range, and the key which was |
| typed. The editpart will return a command for the modification to the |
| model. That command will be executed on the command stack. 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. If the editpart wishes to continue the same edit, it must append |
| to this command instance any new editing, and return that same command. |
| 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. 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 "re-execute" 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. |
| First, the viewer indicates to all of the textual editparts between the start |
| and end of the selection range that they are selected. This is done so |
| that selection may be rendered in each editpart's figure. 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. |
| 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. 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. The preceding and succeeding elements should be merged |
| whenever possible. 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>. |
| It would be incorrect to leave the two paragraphs separated. 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. 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. This is |
| shown in <b>Figure 6.2</b>. Finally, if the two parents represent styles |
| which are applied to their children, then those styles should remain intact. |
| 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>. In all 3 cases, the final location for the caret will be |
| where the selection range began. 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> </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. |
| At which point, that text node is empty and probably has no effect on the |
| rendering of the document. The model should be compacted to its simplest |
| representation. But, the application does not know the users intentions. |
| The user may either start typing immediately, or save the document. If the |
| document is saved, it should be in its simplest form. 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. For this to work, we will |
| probably need some pending state object returned from the backspace operation. |
| That state will affect how an inserted character is treated. 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 "classes" such as H1, etc. Sometimes invoking a style change |
| has an immediate affect on the document. 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. For example, turning on BOLD does not modify the document |
| until you type something. 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. 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. 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"> </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. F2 or 2 mouse clicks should cause the text |
| editing to become active. Focus lost, Selection lost, or CTRL+ENTER must |
| exit the mode and commit the change. ESC must rollback all text edits and |
| exit the text editing mode.</p> |
| |
| </body></html> |