Sunday, August 18, 2013

Text Morph and Morphic Tutorial

During the last week, I implemented a text area morph in Amber-Athens. The basic functionality is almost finished, and after three iterations, I can say that I am more or less satisfied with the design. It is not perfect and the implementation is still quite slow, but I know a couple of methods that could be optimized in order to boost the performance.

The text area box supports the following features.

  • Displaying and editing text without formatting

  • Multi-line strings

  • Automatic line break if a line is longer than the width of the text area box

  • Vertical scroll bar

  • Cursor and multi-character selections

  • Navigation with arrow keys

Here's a short overview of the characteristic of my implementation.

  • The content of the text area box contains of several lines. In addition, more lines might be generated if the content is changed, if a line is longer than the width of the text area box. We call all such lines ("real" and "newly-created lines") virtual lines. "AthensVirtualTextAreaLine" represents a virtual line and is responsible for handling horizontal pixel coordinates (offsets inside a line). The text are box ("AthensEditableTextMorph") is responsible for handling vertical pixel coordinates (lines). For example, given a pixel offset, "AthensEditableTextMorph" retrieves the line and "AthensVirtualTextAreaLine" retrieves the position of the cursor in that line.

  • When editing text, the new string is currently set via "text:". This re-generates all virtual lines. Actually, this is not necessary in most cases. Consider, for instance, that we added a single character to a (virtual) line. We might have to move some characters to other lines (below) even in the lines below the insertion, but it is a more or less local change. Lines before the insertion are not affected at all. In a future version, I will change the algorithm to handle small text editings in the virtual line class and use the same algorithm (recursively) for the next line, if a change is necessary (in most cases this will not be the case).

  • The text is rendered in the morph "AthensEditableTextMorph". We can specify a width for this morph, but not a height. It is always as high as the text content requires it to be. "AthensTextAreaMorph" is a subclass of "AthensScrollAreaMorph" and a decorator for "AthensEditableTextMorph". It adds the scrolling functionality to the text area box and delegates all method calls to it.

  • Text selections are represented with a "selectionStart" and a "selectionLength". If the selection length is zero, nothing is selected and we show only the cursor. The length can also be negative. The selection start is the offset of character preceding (in front of) the cursor. I.e., "selectionStart == 1" means that the first cursor is in front of the first character.

With the new text box, I could build a tutorial for the Morphic functionality (works in Chrome/Chromium only so far, I will fix that soon) that runs entirely on the Morphic stuff itself. There are only four steps at the moment, but I will add more steps in the future in order to cover the basic features.

As you can see, the tutorial is now a full-screen application, i.e. the Canvas and the world morph cover the whole page content.

No comments:

Post a Comment