# tvision-m2 - API reference All names are in module `tv`. Import it qualified (`IMPORT tv;`) or with `FROM tv IMPORT ...`. Every drawing call draws into an off-screen cell buffer; nothing reaches the terminal until `Present` (or `Finish`). ## Lifecycle | procedure | description | |---|---| | `Init() : BOOLEAN` | enter raw mode + alternate screen, install SIGWINCH handler, create the desktop. FALSE if stdin is not a tty. | | `Done` | leave the alternate screen and restore the terminal. | | `Cols() / Rows() : INTEGER` | current screen size. | | `Resized() : BOOLEAN` | TRUE if the terminal size changed or SIGWINCH fired since the last call (also re-clears the screen). Call it in your loop. | | `Finish` | `DrawTree` + `Present` (redraw everything and flush). | | `DrawTree` | draw the desktop, all views and the menu bar into the cell buffer. | | `Present` | flush the diff to the terminal. | ## Colours and attributes 16 colours: `Black Blue Green Cyan Red Magenta Brown LightGray DarkGray LightBlue LightGreen LightCyan LightRed LightMagenta Yellow White`. `A(fg, bg : INTEGER; blink : BOOLEAN) : Attr` builds an attribute. Frame styles: `SingleFrame`, `DoubleFrame`. ## Low-level screen `Clear(attr)`, `Fill(x,y,w,h, cp, attr)`, `DrawCh(x,y,cp,attr)`, `DrawText(x,y, s, attr)`, `DrawBox(r, style, attr)`, `DrawShadow(r, attr)`, `SetCursor(x,y)`, `HideCursor`. `cp` is a Unicode code point (`CARDINAL`); ASCII text can use `VAL(CARDINAL, ORD(ch))`. ## Text helpers `TextLen(s) : INTEGER`, `CopyText(dest, s)`, `AppendText(dest, s)`, `PadText(dest, s, width)`, `IntToText(dest, n, width)`. ## Events ``` TYPE Event = RECORD kind : EventKind; (* evNone evKey evMouse *) key : INTEGER; (* kChar kUp kDown kLeft kRight kHome kEnd kPgUp kPgDn kIns kDel kEnter kEsc kTab kBack kSpace kF1..kF12 kCtrlC kNone *) ch : CARDINAL; (* code point for kChar *) ctrl : BOOLEAN; (* e.g. Shift-Tab gives kTab with ctrl=TRUE *) mx, my : INTEGER; (* mouse position, 0-based *) mbtn : INTEGER; (* 1 left, 2 middle, 3 right; held button during motion *) mpressed, mreleased : BOOLEAN; mwheel : INTEGER; (* -1 up, +1 down *) END; ``` `ReadEvent(e) : BOOLEAN` waits up to ~0.1 s and returns FALSE on timeout. `HandleEvent(e) : INTEGER` dispatches one event to the menu bar, the modal dialog (if any) or the desktop, and returns a command: `cmNone`, `cmClose`, or the tag of the activated control/menu item. `Sender() : ViewPtr` returns the view that produced it (`NIL` for menus). Built-in commands: `cmNone cmClose cmOK cmCancel cmYes cmNo`. ## View tree ``` TYPE VKind = (VGroup, VWindow, VText, VFrame, VInput, VButton, VCheck, VRadio, VList, VScroll); View = RECORD ... END; ViewPtr = POINTER TO View; ``` | procedure | description | |---|---| | `NewView(kind, x,y,w,h) : ViewPtr` | allocate a view (absolute screen coordinates). | | `AddView(parent, child)` | append a child to a group/window. | | `DelView(v)` | remove a view and its children. | | `SetText(v, s)` / `SetTag(v, n)` | set text / command tag. | | `Desk() : ViewPtr` | the desktop group; add top-level windows here. | | `BringToFront(v)` | raise within its parent (z-order). | | `FocusView(v)` / `FocusNext(backwards)` | set/advance keyboard focus. | | `MoveViewBy(v, dx, dy)` | move a view and its descendants. | Fields are public: `v^.rect`, `v^.text`, `v^.flags`, `v^.value`, `v^.minv`, `v^.maxv`, `v^.tag`, `v^.list`, `v^.focus`. Flags: `vfDisabled`, `vfSelected`, `vfFramed`. Widget kinds: `VText` (label), `VFrame` (box), `VInput`, `VButton`, `VCheck`, `VRadio`, `VList` (needs `v^.list : ListDataPtr`), `VScroll` (`v^.value/minv/maxv`), `VWindow`, `VGroup`. ``` TYPE ListData = RECORD items : ARRAY [0..255] OF ARRAY [0..63] OF CHAR; count : INTEGER; END; ListDataPtr = POINTER TO ListData; ``` ## Menus `MenuBarInit`, `MenuAdd(title)`, `MenuItemAdd(text, tag)`, `MenuSep`, `MenuBar(show : BOOLEAN)`. The menu bar is drawn on row 0; selecting an item makes `HandleEvent` return its tag. Mouse: click a title, click an item. Keyboard: `F10`, arrows, Enter/Space, Esc. ## Dialogs Build a centred modal window, add controls, then run it: ``` tv.Dialog("Options", 44, 12); iName := tv.DlgInput("Name:", "Modula-2"); (* -> field index *) cOn := tv.DlgCheck("Enabled", TRUE); rFast := tv.DlgRadio("Fast", TRUE); (* radios auto-exclusive *) rSafe := tv.DlgRadio("Safe", FALSE); tv.DlgButton("OK", tv.cmOK); tv.DlgButton("Cancel", tv.cmCancel); cmd := tv.DlgRun; (* blocks; returns the tag *) tv.DlgTextAt(iName, s); (* read an input *) n := tv.DlgValue(cOn); (* 1 if selected *) ``` `DlgRun` returns the pressed button's tag, `cmCancel` on Esc, `cmClose` from the close box. ## Message boxes `MessageBox(title, text, kind) : INTEGER` where `kind` is `mbOK`, `mbOKCancel` or `mbYesNo`; returns `cmOK`, `cmCancel`, `cmYes` or `cmNo`. `Message(title, text)` is shorthand for `MessageBox(..., mbOK)`. ## Building against the library gm2 -fiso -c tvtty.def gm2 -fiso -I. -c tv.mod gm2 -fiso -I. tv.o myapp.mod -o myapp