tv.def 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. DEFINITION MODULE tv;
  2. (* A small TVision/Turbo-Vision style character-cell UI toolkit in ISO
  3. GNU Modula-2 (gm2 -fiso), terminal backend.
  4. It provides a tiny retained view tree (groups/windows containing widgets)
  5. with clipping and z-order, a diffed ANSI cell screen, keyboard and mouse
  6. decoding (xterm SGR mouse reports), and widgets: static text, frame,
  7. input line, button, check box, radio buttons, list box and scroll bar.
  8. Compile (from this directory):
  9. gm2 -fiso -c tvtty.def
  10. gm2 -fiso -I. -c tv.mod
  11. gm2 -fiso -I. tv.o demo.mod -o demo
  12. The only non-Modula-2 part is tvtty.def (libc termios/ioctl/read/write). *)
  13. FROM SYSTEM IMPORT ADDRESS;
  14. CONST
  15. (* 16 terminal colours *)
  16. Black = 0; Blue = 1; Green = 2; Cyan = 3;
  17. Red = 4; Magenta = 5; Brown = 6; LightGray = 7;
  18. DarkGray = 8; LightBlue = 9; LightGreen = 10; LightCyan = 11;
  19. LightRed = 12; LightMagenta = 13; Yellow = 14; White = 15;
  20. SingleFrame = 1;
  21. DoubleFrame = 2;
  22. (* key codes *)
  23. kNone = 0; kChar = 1; kUp = 2; kDown = 3;
  24. kLeft = 4; kRight = 5; kHome = 6; kEnd = 7;
  25. kPgUp = 8; kPgDn = 9; kEnter = 10; kEsc = 11;
  26. kTab = 12; kBack = 13; kDel = 14; kIns = 15;
  27. kF1 = 20; kF2 = 21; kF3 = 22; kF4 = 23; kF5 = 24;
  28. kF6 = 25; kF7 = 26; kF8 = 27; kF9 = 28; kF10 = 29;
  29. kCtrlC = 30; kF11 = 31; kF12 = 32; kSpace = 33;
  30. (* built-in commands (button tags) *)
  31. cmNone = 0;
  32. cmClose = 1;
  33. cmOK = 2;
  34. cmCancel = 3;
  35. cmYes = 4;
  36. cmNo = 5;
  37. (* message box kinds *)
  38. mbOK = 0;
  39. mbOKCancel = 1;
  40. mbYesNo = 2;
  41. (* view flags *)
  42. vfDisabled = 1;
  43. vfSelected = 2;
  44. vfFramed = 4;
  45. MAXLINE = 128;
  46. MAXVIEWS = 128;
  47. EDMAXLINES = 512;
  48. EDMAXCOL = 160;
  49. (* editor languages (for highlighting / keyword upcasing) *)
  50. langNone = 0;
  51. langModula2 = 1;
  52. langPascal = 2;
  53. langOberon = 3;
  54. TYPE
  55. Attr = CARDINAL;
  56. Point = RECORD x, y : INTEGER; END;
  57. Rect = RECORD x, y, w, h : INTEGER; END;
  58. EventKind = (evNone, evKey, evMouse);
  59. Event = RECORD
  60. kind : EventKind;
  61. key : INTEGER;
  62. ch : CARDINAL;
  63. ctrl : BOOLEAN;
  64. mx, my : INTEGER;
  65. mbtn : INTEGER; (* 1 left, 2 middle, 3 right *)
  66. mpressed, mreleased : BOOLEAN;
  67. mwheel : INTEGER; (* -1 up, +1 down *)
  68. END;
  69. (* ---- screen ------------------------------------------------------------ *)
  70. PROCEDURE Init() : BOOLEAN;
  71. (* Initialise for a non-terminal driver (e.g. the tigr backend): sets the
  72. virtual screen size and resets state without touching the terminal. *)
  73. PROCEDURE InitVirtual (c, r : INTEGER) : BOOLEAN;
  74. PROCEDURE Done;
  75. PROCEDURE Cols() : INTEGER;
  76. PROCEDURE Rows() : INTEGER;
  77. PROCEDURE Resized() : BOOLEAN;
  78. PROCEDURE A (fg, bg : INTEGER; blink : BOOLEAN) : Attr;
  79. PROCEDURE Clear (attr : Attr);
  80. PROCEDURE Fill (x, y, w, h : INTEGER; cp : CARDINAL; attr : Attr);
  81. PROCEDURE DrawCh (x, y : INTEGER; cp : CARDINAL; attr : Attr);
  82. PROCEDURE CellAt (x, y : INTEGER; VAR cp, attr : CARDINAL);
  83. PROCEDURE DrawText (x, y : INTEGER; s : ARRAY OF CHAR; attr : Attr);
  84. PROCEDURE DrawBox (r : Rect; style : INTEGER; attr : Attr);
  85. PROCEDURE DrawShadow (r : Rect; attr : Attr);
  86. PROCEDURE SetCursor (x, y : INTEGER);
  87. PROCEDURE HideCursor;
  88. PROCEDURE Present;
  89. PROCEDURE ReadEvent (VAR e : Event) : BOOLEAN;
  90. (* ---- text helpers ------------------------------------------------------ *)
  91. PROCEDURE TextLen (s : ARRAY OF CHAR) : INTEGER;
  92. PROCEDURE CopyText (VAR dest : ARRAY OF CHAR; s : ARRAY OF CHAR);
  93. PROCEDURE AppendText (VAR dest : ARRAY OF CHAR; s : ARRAY OF CHAR);
  94. PROCEDURE PadText (VAR dest : ARRAY OF CHAR; s : ARRAY OF CHAR; width : INTEGER);
  95. PROCEDURE IntToText (VAR dest : ARRAY OF CHAR; n : INTEGER; width : INTEGER);
  96. (* ---- view tree --------------------------------------------------------- *)
  97. TYPE
  98. VKind = (VGroup, VWindow, VText, VFrame, VInput, VButton,
  99. VCheck, VRadio, VList, VScroll, VEditor);
  100. ListData = RECORD
  101. items : ARRAY [0..255] OF ARRAY [0..63] OF CHAR;
  102. count : INTEGER;
  103. END;
  104. ListDataPtr = POINTER TO ListData;
  105. (* Multi-line editor buffer. Declare one per editor (it is a few tens of
  106. KB) at module scope and attach it to a VEditor view. *)
  107. EditorData = RECORD
  108. line : ARRAY [0..EDMAXLINES - 1] OF ARRAY [0..EDMAXCOL - 1] OF CHAR;
  109. len : ARRAY [0..EDMAXLINES - 1] OF INTEGER;
  110. count : INTEGER;
  111. cx, cy : INTEGER; (* cursor: column, line *)
  112. top, left : INTEGER; (* scroll *)
  113. ins : BOOLEAN; (* insert mode *)
  114. dirty : BOOLEAN;
  115. lang : INTEGER; (* one of the lang* constants *)
  116. indent : INTEGER; (* auto-indent step (0 = off) *)
  117. END;
  118. EditorDataPtr = POINTER TO EditorData;
  119. ViewPtr = POINTER TO View;
  120. View = RECORD
  121. kind : VKind;
  122. rect : Rect;
  123. parent, next, prev, first, last, focus : ViewPtr;
  124. clipKids : BOOLEAN;
  125. text : ARRAY [0..MAXLINE - 1] OF CHAR;
  126. len, pos : INTEGER;
  127. value, minv, maxv, tag : INTEGER;
  128. flags : CARDINAL;
  129. list : ListDataPtr;
  130. ed : EditorDataPtr;
  131. END;
  132. PROCEDURE NewView (kind : VKind; x, y, w, h : INTEGER) : ViewPtr;
  133. PROCEDURE FreeView (v : ViewPtr);
  134. PROCEDURE AddView (parent, child : ViewPtr);
  135. PROCEDURE DelView (v : ViewPtr);
  136. PROCEDURE SetText (v : ViewPtr; s : ARRAY OF CHAR);
  137. PROCEDURE SetTag (v : ViewPtr; t : INTEGER);
  138. PROCEDURE Desk () : ViewPtr;
  139. PROCEDURE DrawTree; (* draw desktop + all views *)
  140. PROCEDURE Finish; (* DrawTree + Present *)
  141. PROCEDURE HandleEvent (e : Event) : INTEGER; (* returns a command *)
  142. PROCEDURE Sender () : ViewPtr; (* view that produced it *)
  143. PROCEDURE BringToFront (v : ViewPtr);
  144. PROCEDURE FocusView (v : ViewPtr);
  145. PROCEDURE FocusNext (backwards : BOOLEAN);
  146. PROCEDURE MoveViewBy (v : ViewPtr; dx, dy : INTEGER);
  147. (* Menu bar + drop-down menus. Typical use:
  148. MenuBarInit;
  149. MenuAdd("File"); MenuItemAdd("New", cNew); MenuItemAdd("Quit", cQuit);
  150. MenuAdd("Help"); MenuItemAdd("About", cAbout);
  151. Selecting an item makes HandleEvent return its tag. *)
  152. PROCEDURE MenuBarInit;
  153. PROCEDURE MenuAdd (title : ARRAY OF CHAR);
  154. PROCEDURE MenuItemAdd (text : ARRAY OF CHAR; tag : INTEGER);
  155. PROCEDURE MenuSep;
  156. PROCEDURE MenuBar (show : BOOLEAN);
  157. (* Generic modal dialog builder. Dialog() starts a centered window; the
  158. Dlg* procedures add controls top-to-bottom (inputs/checks/radios get a
  159. field index); DlgRun() shows it modally and returns the command of the
  160. button that was pressed (its tag), cmCancel on Esc, or cmClose. *)
  161. PROCEDURE Dialog (title : ARRAY OF CHAR; w, h : INTEGER);
  162. PROCEDURE DlgLabel (text : ARRAY OF CHAR);
  163. PROCEDURE DlgInput (label : ARRAY OF CHAR; initial : ARRAY OF CHAR) : INTEGER;
  164. PROCEDURE DlgCheck (label : ARRAY OF CHAR; checked : BOOLEAN) : INTEGER;
  165. PROCEDURE DlgRadio (label : ARRAY OF CHAR; selected : BOOLEAN) : INTEGER;
  166. PROCEDURE DlgButton (text : ARRAY OF CHAR; tag : INTEGER);
  167. PROCEDURE DlgRun () : INTEGER;
  168. PROCEDURE DlgTextAt (idx : INTEGER; VAR s : ARRAY OF CHAR);
  169. PROCEDURE DlgValue (idx : INTEGER) : INTEGER; (* 1 if check/radio selected *)
  170. (* Modal message box; returns cmOK/cmCancel/cmYes/cmNo. *)
  171. PROCEDURE MessageBox (title : ARRAY OF CHAR; text : ARRAY OF CHAR;
  172. kind : INTEGER) : INTEGER;
  173. (* Modal helper: a message box with an OK button. *)
  174. PROCEDURE Message (title : ARRAY OF CHAR; text : ARRAY OF CHAR);
  175. (* ---- editor ------------------------------------------------------------ *)
  176. PROCEDURE EditorAttach (v : ViewPtr; data : EditorDataPtr);
  177. PROCEDURE EditorInit (data : EditorDataPtr);
  178. PROCEDURE EditorAddLine (data : EditorDataPtr; s : ARRAY OF CHAR);
  179. PROCEDURE EditorGetLine (data : EditorDataPtr; i : INTEGER; VAR s : ARRAY OF CHAR);
  180. PROCEDURE EditorLoad (data : EditorDataPtr; path : ARRAY OF CHAR) : BOOLEAN;
  181. PROCEDURE EditorSave (data : EditorDataPtr; path : ARRAY OF CHAR) : BOOLEAN;
  182. PROCEDURE EditorDirty (data : EditorDataPtr) : BOOLEAN;
  183. PROCEDURE EditorSetLanguage (data : EditorDataPtr; lang : INTEGER);
  184. PROCEDURE EditorSetIndent (data : EditorDataPtr; n : INTEGER);
  185. END tv.