Analysis
Overview
In this group the model and the functionality for the text elements should be defined. The model should allow the creation of chained views, styling of text, rotation, transparency and different modes of wrapping . It should allow persisting of texts along with all the applied attributes. The task consists of two logical parts
- a model for the text itself
- a model for the view components.
- Text model
- The model for the text consist of styled text and contains information about the attributes of the text itself
- font
- size
- color
- opacity
- modifiers (bold, italic, underline, strikethrough)
- attached actions
- other attributes that may appear
- The chained view components will share a common text model and each will display only part of it.
- This model should be persistable and it should be consistent with the overall persistent strategy in Sophie (BASE_PERSISTENCE_INTERMEDIATE_STORAGE_R0, BASE_PERSISTENCE_COMMONS_R0)
- An undo/redo mechanism should be designed in a way that will allow it so seamlessly integrate with the properties oriented undo/redo mechanism used in Sophie (PRO_CHANGE_UNDO_MANAGER_R0).
- Individual text component model
- The model of the individual text component should contain additional information for the rendering of the text in the particular view – transparency
- rotation
- wrapping mode
- other attributes that may appear
- The view component model should contain information what part of the text model it should display, in the case of chained views.
- A mechanism should exist that will trigger recalculation of the ranges of the texts displayed in different chained views if some change is made in one of them, causing its range to change. Among this kind of changes include
- insert/remove/replace text
- change the size of the view component
- changes in the size of some part of the text inside the component
- change the wrapping mode of the component
- maybe other
Considering the complexity of this task it is probable that parts of it will have to be moved to separate tasks and, in addition, unplanned related tasks can emerge. Such tasks have to be identified and described, during the work. Such tasks may be, for example, the persistence mechanism, the undo/redo mechanism, the attachment of actions (hyperlink style) to the text, and others.
Task requirements
Focus on following requirements:
- The model should support chaining of views.
- The model should support styling of the text.
- The model should support selection split over more than one view. (selection of text starting in one view and continuing in another)
Task result
The result of this task should be design description and only a prove of concept prototype implementation code.
Implementation idea
Currently the text support presented in JDK is not sufficient for our requirements. So we need to design our own such one.
Related
BASE_PERSISTENCE_INTERMEDIATE_STORAGE_R0
BASE_PERSISTENCE_COMMONS_R0
WRAPPING_TEXT_RENDERING_R0
PRO_CHANGE_UNDO_MANAGER_R0
How to demo
- Create a frame containing more than one text views over the same model, prefilled with text, with at least two different styles.
- Observe the different styles
- Type some text in the views and observe the splitting of the text on different views.
- Select some text with part of the selection at the end of the first view and part – at the beginning of the second.
- Copy and paste the selected text to ensure the selection is correct
Design
The text is a sequence of symbols. In our case this sequence is a list and it consists of symbol units. Every unit has a symbol id which is a integer.
Every unit knows the position before it and the position after it. This is important for the purpose of character and paragraph formating and style definitions. Positions denote place between the units, that is, where the user can go with the cursor. Thus, if the contained text is "Hello!\n", The following actual positions are present (denoted with '|'):
| H | e | l | l | o | ! | \n |
However, for each actual position, there are at least two logical positions. For example, the position between 'H' and 'e', may be referred as "after H" or "before e". But, if we insert a character between them, they wont point to the same character any more.
Also every symbol unit can have some styling – font family, size, bold, italic, underline, strike-through, color, etc. And this styling can be defined for a single symbol or for a sequence. For this purpose every symbol unit defines a symbol style before and after it. This way defining styles is just proper nesting of style definitions for symbol units. Also if a new symbol is inserted the style of the previous one won't be automatically applied to it because it will be a closing style definition.
For easy moving around the text a Navigator is defined. With it you can move through the text and take the symbol units before or after a position.
For easy applying styles for the text a Styler is defined. With it you can get and set style definition to a range of symbol units.
Style definition for the text is a list of style values. Every style value has an attribute (something like a key in the sequence) and a value. The purpose of the attribute is to store some meta information like default value, etc.
For proper styling we should have proper nesting that's why it's a good idea this logic to be presented like a stack with proper sequence call to pop/push operations. Even more, the number of operations with values is a finite number, and to become more error prone this is how the design looks:
Sophie2's formatted text is one that should not work only in rectangle areas, that's why we need a a custom graphical component and a layout mechanism.
The custom graphical component is a scene element that uses the graphical context to draw the formatted text. HotTextSceneElement is associated with HotTextSceneElementHelper where the actual drawing is performed. In HotTextSceneElementHelper#draw method you should call the text layout to render the actual representation.
The layout mechanism is most appropriate to be a graph where where each route have a cost and then the path with the minimal cost will be used
Implementation
(Describe and link the implementation results here (from the wiki or the repository).)
Testing
(Place the testing results here.)
Comments
(Write comments for this or later revisions here.)