# $Id$

! Note: This version is not completed yet !


This is SHEdit for Free Pascal, an object-oriented text editor engine with
support for:
- syntax highlighting
- clipboard (cut, copy & paste)
- undo/redo buffers
- fully customizable behaviour
- multiple views (editors) for a single document at a time
- completely independent of any toolkit; it even can be used both in text and
  in graphics modes


Architecture
------------

There are three basic classes in SHEdit:
- Document
- Editor
- Renderer

The document class (TTextDoc) in doc_text.pp is quite simple, it just
stores a text (ASCII) document as a collection of strings.
What you have to know about TTextDoc is that it stores a 32-bit value for
each line, which it doesn't modify on its own. The lower 8 bits of these
LineFlags are reserved for syntax highlighting (SH): The first bit determines
if the other SH flags are valid; and the remaining 7 bits can be used to
indicate SH states which do not end at the end of the line.


The editor itself is encapsulated in the class TSHTextEdit (in unit shedit.pp).
It can only work in conjunction with a renderer, which is responsible for
displaying the document. When you create a TSHTextEdit, the constructor expects
two arguments: The document to use, and the renderer to use.

The renderer itself is declared as an abstract interface class (i.e. all
methods are 'virtual abstract'), this interface is called ISHRenderer.
When you want to use SHEdit in your own programs, you will have to provide
an implementation of the methods declared in ISHRenderer. There is a reference
implementation for GTK, gtkdemo.


Renderer interface
------------------

This interface is quite simple; just note that SHEdit expects all corrdinates
relative to the upper left corner of the document (0/0), and it uses the
cell size (width and height) of the characters as base unit. For example,
the coordinate X=3/Y=2 references the fourth character in the third line.


procedure InvalidateLines(y1, y2: Integer);
  The renderer should initiate the redrawing of the lines between y1 and y2.
  It is recommended to use the Invalidate commands of the underlying graphics
  or windowing toolkit; but an implementation may choose to simply call
  TSHTextEdit.DrawContent.

procedure ClearRect(x1, y1, x2, y2: Integer);
  The renderer must clear the given rectangle in the background (whitespace)
  color.

procedure DrawTextLine(x1, x2, y: Integer; s: PChar);
  This is the most complex method: The renderer has to draw a complete line of
  text, which is given in "s". The vertical position is line "y", x1 and x2
  specify a horizontal clipping span.
  "s" has a very special format, as it contains highlighting tags:
  You can process "s" character by character, as usual. BUT when you encounter
  a special escape character (LF_Escape, defined in doc_text.pp) the renderer
  has to switch to the font style/color given in the following character. This
  character is just a index in the range ASCII #1..#255, the renderer must know
  himself what to do with this index. These highlighting tags are generated by
  a special highlighting function, see below.

procedure ShowCursor(x, y: Integer);
procedure HideCursor(x, y: Integer);
  The cursor should be drawn or be hidden, its position is given in "x" and
  "y". SHEdit does its own reference counting, i.e. it won't call HideCursor
  for an already invisible cursor, and it won't call ShowCursor for a visible
  cursor. If the cursor position changes, SHEdit will call HideCursor with
  the old position and then ShowCursor with the new position as arguments.

function GetVertPos: Integer;
  This function shall return the vertical scrolling position of the window
  which is managed by the renderer.

procedure SetVertPos(y: Integer);
  Sets the vertical scrolling position.

function GetPageHeight: Integer;
  Gets the height of the visible part of the document.

procedure SetLineCount(count: Integer);
  SHEdit calls this method if the number of lines in the document has changed.

function GetClipboard: String;
  GetClipboard is called by SHEdit if the user wants to paste the contents of
  the clipboard into the document. GetClipboard must check if the system's
  clipboard contains valid text data and return it; if not, it has to return
  an empty string.

procedure SetClipboard(Content: String);
  This method is used to set the content of the clipboard after a
  "ClipboardCut" or "ClipboardCopy" action occured.



Highlighters and document type specific features
------------------------------------------------

TSHTextEdit does not perform any syntax highlighting, and it always acts as a
normal text editor without any fancy extra feature.
This can easily be changed by deriving your own class from TSHTextEdit.
Currently there are two special editor classes: TSHPasEdit (unit sh_pas.pp) and
TSHXMLEdit (unit sh_xml.pp).

TSHPasEdit supports syntax highlighting for Pascal sources, and it adds auto
indent facilities to SHEdit (currently, when you press the Enter key, it will
add as many spaces as the previous line to the new created line).

TSHXMLEdit just adds syntax highlighting for XML and DTD documents.

Please note that currently there is no framework for handling with different
kinds of documents. It is up to the program which wants to use SHEdit to
determine which editor class to use.


- Sebastian Guenther, sg@freepascal.org
