DEFINITON TermWin; (* Stephan Junker  9.11.93 / 26.11.93 *)

(* TermWin extends the object WinView.Viewer in order to provide a simple
 * method of displaying text data in a window. The usual output procedures
 * WriteChar etc. are implemented as procedures bound to the viewer.
 * Input of characters is automatically displayed. If return or enter
 * is pressed, an event STRING with the contents of the current line as
 * argument is generated. The string is written into and read from the
 * terminal, but the line is not left. If other behaviour is desired,
 * just override HandleKeyEvent (by extending WriteTerminal.Viewer) and
 * react on the desired keys. For example, react on cursor up and down
 * by displaying a command history. ReadTerminal works only with the
 * characters stored in the terminal window, so you may write a different
 * string without causing trouble.
 * All VT52 escape sequences are supported except esc-b, esc-c, esc-p,
 * esc-q, esc-v and esc-w. But using them will not cause any trouble.
 *
 * Usage:
 * Allocate and initialize an object of type TermWin.Viewer (or an
 * extension of that type). Use the methods Open and Close to open and
 * close the window. Install an event handler for the extended event
 * STRING. If an event STRING is generated, Events.string contains the
 * edited string and Events.viewer the viewer in which it was edited.
 * After Init, the cursor is invisible and editing therefor inhibited.
 * Use CursorOn to enable editing.
 *
 * Notes: All procedures which change output open the viewer if it is
 *        closed.
 *        VT52 procedures are also exported for direct use.
 *)


TYPE
  Events*    = RECORD(GemApp.Events)
                 string* : ARRAY 162 OF CHAR;
                    (* the edited string on a string event *)
                  viewer*: Viewer;
                    (* the viewer in which the string was edited *)
               END;

  Viewer*   = POINTER TO ViewDesc;
  ViewDesc* = RECORD(WinView.ViewDesc)
                rows-,cols- : INTEGER;
                curx-,cury- : INTEGER;
                station-    : INTEGER;
                cw-,ch-     : INTEGER;

                PROCEDURE (v : Viewer) CursorOn*;

                PROCEDURE (v : Viewer) CursorOff*;

                PROCEDURE(v : Viewer) ClearHome*;
                  (* clears the memory of viewer v and the window if opened *)

                PROCEDURE(v : Viewer) SetCursor*(col,row : INTEGER);
                  (* changes the position where the next output has to appear. If one
                     of the parameter exceeds its limits, it will be set at the maximum
                     value. *)

                PROCEDURE(v : Viewer) SetSize*(cols,rows : INTEGER);
                  (* changes the size of viewer v. The memory size is adjusted and its
                     previous contents transferred to the new location. If size became
                     smaller, the data will be cut, else the new characters will be
                     cleared. The old memory is of course disposed. If the window is
                     open, it will also be changed in size. *)

                PROCEDURE(v : Viewer) SetFont*(fontId,fontHeight : INTEGER);
                  (* sets the font used to display the characters. FontId is the value
                     used for VstFont, and FontHeight is used for VstHeight. Correct
                     function with proportional fonts is not guaranteed. The number of
                     characters per line is calculated using the maximum size of a
                     character, so there will be an unused margin at the right. The cursor
                     position is calculated as the product of v.col and maximum width
                     of characters (v.cw), so this will cause problems.
                     If the window is open, it will be updated immediatly. *)

                PROCEDURE(v : Viewer) Init*;
                  (* initializes a viewer. The size is set to 80 columns and 22 rows
                     (640*400 screen with 8*16 font). A closer and mover is provided.
                     The title is "STDIO", but you can change it using v.SetTitle.
                     The screen is cleared, of course, and cursor is in row 0, col 0.
                     Cursor means the position where the next output will appear, but
                     there is no visible cursor. *)

                PROCEDURE(v : Viewer) WriteChar*(c : CHAR);
                  (* writes a character into the memory of viewer v at the current cursor
                     position. The position is increased. If the end of line is reached,
                     output will continue in the next line. If the last line is reached,
                     the output is shifted up one line. If the window is not open, it will
                     be opened *)

                PROCEDURE(v : Viewer) WriteString*(str : ARRAY OF CHAR);
                  (* writes a string into the memory of viewer v at the current cursor
                     position. It follows the same procedure as WriteChar. *)

                PROCEDURE(v : Viewer) WriteLn*;
                  (* sets the cursor in the following line at column 0 *)

                PROCEDURE(v : Viewer) WriteInt*(Value : LONGINT);
                  (* Writes a decimal integer value *)

                PROCEDURE(v : Viewer) WriteFInt*(Value : LONGINT; Base,Adj,Len : INTEGER; Fill : CHAR);
                  (* Writes an integer value with any base Base. For example, base 10 is
                     decimal, 16 hexadecimal and so on. The string is formatted with
                     Strings.Adjust. See constant definitions of Strings for explanation
                     of Adj,Len and Fill. *)

                PROCEDURE(v : Viewer) WriteReal*(Value : REAL; n,Adj,Len : INTEGER; Fill : CHAR);
                  (* Writes a real value with n digits after the decimal point. See constant
                     definitions of Strings for explanation of Adj,Len and Fill. *)

                PROCEDURE(v : Viewer) Remove*;
                  (* removes viewer v from memory. If it is open, it will be closed *)

                PROCEDURE (v : Viewer) CursorUp*;
                  (* set cursor in previous line. Scroll down and clear first line if
                     cursor is in first line *)

                PROCEDURE (v : Viewer) ClearEOS*;
                  (* clears from cursor to end of screen *)

                PROCEDURE (v : Viewer) ClearSOS*;
                  (* clears from start of screen to cursor *)

                PROCEDURE (v : Viewer) ClearEOL*;
                  (* clears from cursor to end of line *)

                PROCEDURE (v : Viewer) InsertLine*;
                  (* inserts a line above the current line. The line is cleared and
                     cursor set at column 0 *)

                PROCEDURE (v : Viewer) DeleteLine*;
                  (* deletes the current line. Cursor is set at column 0 *)

                PROCEDURE (v : Viewer) SaveCursor*;
                  (* saves the current cursor position *)

                PROCEDURE (v : Viewer) RestoreCursor*;
                  (* restores the current cursor position *)

                PROCEDURE (v : Viewer) ClearLine*;
                  (* clears the line the cursor is in. Cursor is sest in column 0 *)

                PROCEDURE (v : Viewer) ClearSOL*;
                  (* clears from start of line to cursor *)

                PROCEDURE (v : Viewer) Backspace*;
                  (* cursor left and overwrite character with space *)

                PROCEDURE (v : Viewer) Delete*;
                  (* delete character by shifting the rest of the line *)

                PROCEDURE (v : Viewer) Insert*;
                  (* shifts the line to the right and inserts a space *)

                PROCEDURE(v : Viewer) LineFeed*;
                  (* set cursor in following row, scroll if needed *)

                PROCEDURE (v : Viewer) Tabulator*;
                  (* sets the cursor to the next tabulator position *)

                PROCEDURE(v : Viewer) SetEditStart*;
                  (* normally, the editing of a string starts in column zero. If there is
                     a prompt or so, set the start at the current column with this
                     procedure. After a STRING event, the start is column 0 again. *)

                PROCEDURE (v : Viewer) HandleKeyEvent*(shift : SET;
                                               scan : INTEGER; ascii : CHAR) : BOOLEAN;
                  (* edits a string. Override for different behaviour. *)

              END;

END TermWin.