REALbasic, like Visual Basic, lets you build your application’s user interface by dragging controls (which might be called “widgets” in another environment) onto a window. One of these controls is the TextArea. (Until REALbasic 2009R3 came out, this was called the EditField. It is a text box.) This control is essentially a formatted-text editor: The user can type in and edit multiple lines of text, and multiple fonts and styles can be applied to different parts of the text. My text-editor application will obviously need something like this. So why am I considering rolling my own formatted-text-editor control instead?
I have several reasons:
- Handling of large amounts of text. The TextArea is reportedly very slow when it has a huge amount of text in it. Although most text files my editor will handle will likely be under a megabyte in size, I’d like the editor to be able to work with huge files, tens or hundreds of megabytes in size, every once in a while.
- Memory use. The complete file has to be loaded into the TextArea. There is no provision to defer loading a part of the file until the user actually scrolls or jumps to that part. This is necessary if the control is to support the editing of huge files.
- Word wrap. The TextArea doesn’t let you turn off word wrap; a text editor should let you do this (the better to see the structure of source code with very long lines).
- Indentation. You can indent the first line of a paragraph in a TextArea by inserting tab characters at the start of the first line in the paragraph, but the TextArea doesn’t provide anything else for indentation. Whenever a paragraph is wrapped, each line after the first one always starts at the left edge of the control; a text editor ought to be able to indent all of the lines in each paragraph. The structure of a text outline, for example, is easier to see if every line in each paragraph, and not just the first line in each, is indented.
- Tabstops. The TextArea supports only the conventional fixed-width tabstops. These tab stops are useful for indenting the first line of a paragraph but aren’t much use in arranging substrings of text separated by tabs. Variable-width tabstops are a feature of word processors, not text editors, and they usually have to be set by the user — but I’d like to have my editor support elastic tabstops, which the editor can just calculate on the fly, and which the user doesn’t even need to set.
- Showing invisible characters. Text editors often have an option to display normally invisible characters using visible substitutes — spaces as raised dots (“·”, U+00B7, middle dot), or tab characters as right-pointing triangles (“▶”, U+25B6, black right-pointing triangle), or newlines as pilcrow signs (“¶”, U+00B6) or as left-pointing arrows (“↵”, U+21B5, downwards arrow with corner leftwards). TextArea doesn’t offer anything like this.
- Background colors. It would be nice if my text editor can use different background colors to mark spans of text that match ad-hoc searches. TextArea can show text in different colors, but it has one background color for selected text and one for unselected text. This isn’t a huge deal, but I’d like a little more flexibility. I’d like to use light or pastel background colors for search matches and a dark color for the actual selection.
- Drawing events. The TextArea does not offer any events that would allow a subclass to draw onto the canvas or to alter the positions of text on the canvas. Therefore I can’t create the kind of control I want by subclassing TextArea.
- Hiding lines. Code folding and outlining are two text-editor features that would require the control to display two lines while hiding the lines in between. The TextArea does not offer this, either.
It is wonderful that REALbasic lets you roll your own controls in REALbasic. But others have already written substitutes for the TextArea — True North Software’s FormattedText control and Alex Restrepo’s CustomTextField are examples. Why not use one of them? Because they don’t offer the feature mix I want, and because I like the idea of having my own code that I can modify as I see fit and having the freedom to add the things I want.
So I’ll be spending time figuring out how to wrap lines of text on a Canvas control, how to display a blinking cursor, how to display text as selected as the user drags the mouse over the control, how the text should be structured in memory to support all of these features, and how to regression-test everything so I know it all works. Hopefully the results will be worth the effort.