[previous] [up] [next]     [index]
Next: Editor Structure and Terminology Up: Editor Toolbox Previous: Editor Toolbox

Editor Toolbox

The editor toolbox provides a foundation for two common kinds of applications:

  1. Programs that need a sophisticated text editor -- The simple text field control is inadequate for text-intensive applications. Many programs need editors that can handle multiple fonts and non-text items.
  2. Programs that need a canvas with dragable objects -- The drawing toolbox provides a generic drawing surface for plotting lines and boxes, but many applications need an interactive canvas, where the user can drag and resize individual objects.

Both kinds of applications need an extensible editor that can handle text, images, programmer-defined items, and even embedded editors. The difference between them is the layout of items. MrEd therefore provides two kinds of editors via two classes:

MrEd's editor architecture addresses the full range of real-world issues for an editor--including cut-and-paste, extensible file formats, and layered text styles--while supporting a high level of extensibility. Unfortunately, the system is fairly complex as a result,[footnote] and using the editor classes effectively requires a solid understanding of the structure and terminology of the editor toolbox. Nevertheless, enough applications fit one (or both) of the descriptions above to justify the depth and complexity of the toolbox and the learning investment required to use it.

A brief example illustrates how MrEd editors work. To start, an editor needs an editor-canvas% to display its contents. Then, we can create a text editor an install it into the canvas:

  (define f (make-object frame% "Simple Edit" #f 200 200)) 
  (define c (make-object editor-canvas% f)) 
  (define t (make-object text%)) 
  (send c set-editor t) 
  (send f show #t) 
At this point, the editor is fully functional: the user can type text into the editor, but no cut-and-paste operations are available. We can support all of the standard optionations on an editor via the menu bar:
  (define mb (make-object menu-bar% f)) 
  (define m-edit (make-object menu% "Edit" mb)) 
  (define m-font (make-object menu% "Font" mb)) 
  (append-editor-operation-menu-items m-edit) 
  (append-editor-font-menu-items m-font) 
Now, the standard cut and paste operations work, and the user can even set font styles. The user can also insert an embedded editor by selecting Insert Text from the Edit menu; after selecting the menu item, a box appears in the editor with the caret inside. Typing with the caret in the box stretches the box as text is added, and font operations apply wherever the caret is active. Text on the outside of the box is rearranged as the box changes sizes. Note that the box itself can be copied and pasted.

The content of an editor is made up of snips. An embedded editor is a single snip from the embedding editor's point-of-view. To encode immediate text, a snip can be a single character, but more often a snip is a sequence of adjacent characters on the same line. The find-snip method extracts a snip from a text editor:

  (send t find-snip 0 'after) 
The above expression returns the first snip in the editor, which may be a string snip (for immediate text) or an editor snip (for an embedded editor).

An editor is not permanently attached to any display. We can take the text editor out of our canvas and put a pastboard editor in the canvas, instead:

  (define pb (make-object pasteboard%)) 
  (send c set-editor pb) 
With the pasteboard editor installed, the user can no longer type characters directly into the editor (because a pasteboard does not support directly entered text). However, the user can cut text from elsewhere and paste it into pasteboard, or select one of the Insert menu items in the Edit menu. Snips are clearly identifiable in a pasteboard editor (unlike a text editor) because each snip is separately dragable.

We can insert the old text editor (which we recently removed from the canvas) as an embedded editor in the pasteboard by explicitly creating an editor snip:

  (define s (make-object editor-snip% t)) ; t is the old text editor 
  (send pb insert s) 
An individual snip cannot be inserted into different editors at the same time, or inserted multiple times in the same editor:
  (send pb insert s) ; no effect 
However, we can make a deep copy of the snip and insert the copy into the pasteboard:
  (send pb insert (send s copy)) 

Applications that use the editor classes typically derive new versions of the text% and pasteboard% classes. For example, to implement an append-only editor (which allows insertions only at the end and never allows deletions), derive a new class from text% and override the can-insert? and can-delete? methods:

  (define append-only-text% 
    (class text% args 
      (inherit last-position) 
      (override 
       [can-insert? (lambda (s l) (= s (last-position)))] 
       [can-delete? (lambda (s l) #f)])
      (sequence (apply super-init args)))) 



[previous] [up] [next]     [index]
Next: Editor Structure and Terminology Up: Editor Toolbox Previous: Editor Toolbox

PLT