Eric Streit c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
..
examples c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
API.md dfd6c4a57e Add auto-indentation to the tvision-m2 editor 3 weeks ago
Makefile c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago
README.md c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
SUMMARY.md c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
TUTORIAL.md c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
demo c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
demo.mod 2c45b5a1f5 Add menu bar and drop-down menus to tvision-m2 3 weeks ago
ttysize.mod 45e47499f4 Add tvision-m2: a TVision-style terminal UI toolkit in GNU Modula-2 3 weeks ago
tv.def c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
tv.mod c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
tv.o c3d0ec2633 Add resizable windows and a complete tutorial to tvision-m2 3 weeks ago
tvfont.def c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago
tvfont.mod c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago
tvfont.o c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago
tvg.def c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago
tvg.mod c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago
tvg.o c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago
tvtty.def c39de8c815 Add tigr graphics backend and a multi-line editor to tvision-m2 3 weeks ago

README.md

tvision-m2 - a TVision/Turbo-Vision style toolkit in GNU Modula-2

A character-cell UI toolkit written in ISO GNU Modula-2 (gm2 -fiso) that runs in a terminal (xterm and friends). It is a small, self-contained Turbo-Vision-like library: a retained view tree with clipping and z-order, a diffed ANSI cell screen, keyboard and mouse decoding (xterm SGR mouse reports), widgets, and modal dialogs.

Everything is Modula-2 except tvtty.def, the tiny libc binding used to put the terminal in raw mode and to query its size (termios, ioctl, read, write). There is no C source and no graphics dependency.

Files

file role
tvtty.def libc binding (raw mode, winsize, read/write)
tv.def / tv.mod the toolkit: screen, view tree, widgets, events
tvg.def / tvg.mod tigr graphics backend (renders the view tree in a window)
tvfont.def / tvfont.mod bundled 8x16 monospaced bitmap font for the backend
demo.mod demo application
ttysize.mod diagnostic: checks the tty binding

Build & run

gm2 -fiso -c tvtty.def
gm2 -fiso -I. -c tv.mod
gm2 -fiso -I. tv.o demo.mod -o demo
./demo

make -C examples

or simply make. The graphics example needs the tigr object from the sibling project:

make tvg.o tvfont.o
make -C examples gfx
./examples/gfx  Run it from a real terminal; `Esc` exits.  See

TUTORIAL.md to write your own and API.md for the full reference.

What works

  • Alternate screen, hidden/show cursor, terminal restored on exit.
  • 16-colour foreground/background with blink; UTF-8 output (box-drawing).
  • Perspective view tree: groups and windows contain children; drawing is clipped to each window; overlapping windows are ordered (z-order) and the one you click comes to the front.
  • Windows: double-line frame, title, X close box, draggable by the title bar with the mouse and resizable by the bottom-right ■ handle (WindowResize; children flagged vfExpand grow with the window).
  • Menu bar + drop-down menus (mouse and keyboard).
  • Multi-line editor widget (VEditor): insert/overwrite, arrows/Home/End/ PgUp/PgDn, Enter/Backspace/Delete, Tab indent, mouse positioning, wheel scroll, its own Ln/Col/Insert/Modified status row, plus load/save to a file (EditorLoad/EditorSave).
  • Syntax highlighting for Modula-2, Pascal and Oberon (keywords, strings, numbers, (* *)/{ }/// comments) and automatic keyword up-casing for Modula-2 and Oberon (begin -> BEGIN), plus auto-indentation (indent after BEGIN/THEN/DO/..., dedent on END/UNTIL/ELSE).
  • Widgets: static text, single/double frame, input line (insert, backspace, delete, Home/End/arrows), push button, check box, radio buttons, list box with selection and wheel scrolling, vertical scroll bar.
  • Focus chain: Tab/Shift-Tab and up/down cycle widgets; the focused input gets the hardware cursor.
  • Keyboard decoding: printable UTF-8, arrows, Home/End, PgUp/PgDn, Ins/Del, Tab/Shift-Tab, F1-F12, Enter, Space, Backspace, Esc, Ctrl-C.
  • Mouse: xterm SGR reporting - click to focus/press, drag window titles, click list rows, wheel-scroll lists.
  • Diffed redraw (only changed cells are written).
  • Generic modal dialog builder (Dialog/DlgInput/DlgCheck/DlgRadio/ DlgButton/DlgRun/DlgTextAt/DlgValue) and MessageBox (OK / OK-Cancel / Yes-No), plus the Message shorthand.
  • SIGWINCH-driven resize detection (Resized), no polling required.
  • Optional tigr graphics backend (tvg): the same views, widgets, menus and dialogs render inside a tigr window (colours, box drawing and text via a bundled 8x16 monospaced VGA font, box drawing as line segments); tigr keyboard/mouse are turned into the same events. Terminal programs stay free of any graphics dependency.
  • Menu bar with drop-down menus: click a title (or press F10), navigate with Left/Right/Up/Down, select with Enter/Space or a mouse click; item separators (MenuSep) are supported. The selected item's tag is returned by HandleEvent.

Roadmap ideas

  • Form validation and a file/directory dialog.
  • Menu item hotkeys (Alt+letter) and check/radio menu items.
  • Nested clipping groups and a desktop with many windows / tiling.
  • Tabs, combo box, progress bar, syntax highlighting, search/replace.
  • SIGWINCH-driven relayout (today the app polls the size).
  • Mouse hover highlight and resizable windows.

GNU Modula-2 notes

  • Value-returning procedures with no parameters need explicit () (PROCEDURE Cols() : INTEGER;), otherwise the .def fails to parse when compiled through the .mod.
  • Pointer fields require ^ (v^.rect); there is no implicit dereference.
  • A compound BEGIN ... END block is not a statement, so it cannot appear directly in a CASE alternative - use a helper procedure.
  • An INTEGER index compared with HIGH(array) (a CARDINAL) must be converted: i <= VAL(INTEGER, HIGH(a)).
  • The libc struct termios/struct winsize are accessed through an opaque byte buffer with fixed Linux offsets (see tv.mod).