SUMMARY.md 4.6 KB

tvision-m2 - milestone summary (2026-09-16)

A TVision/Turbo-Vision style character-cell UI toolkit written in ISO GNU Modula-2 (gm2 -fiso) for the terminal, developed alongside the tigr and microui bindings in this repository. No C source and no graphics dependency; the only non-Modula-2 part is the libc binding tvtty.def.

Status

Working milestone: a retained view tree with clipping and z-order, a diffed ANSI screen, keyboard + mouse input, widgets and modal dialogs. Builds warning-free and was exercised by driving a real pty (frames reconstructed from the captured terminal stream).

Files

file role
tvtty.def libc binding: raw mode, winsize, read/write
tv.def / tv.mod screen, view tree, widgets, events, modal dialog
demo.mod demo application (two windows, all widgets, mouse)
ttysize.mod diagnostic for the tty binding
Makefile build
README.md build/run + API + GM2 notes

Implemented

  • Alternate screen, hidden/show cursor, terminal restore on exit.
  • 16-colour fg/bg, explicit blink on/off, UTF-8 box drawing, clipping stack.
  • Diffed redraw: only changed cells are written.
  • View tree: groups and windows own children; per-window clipping; z-order with click-to-front; windows draggable by the title row (any direction), resizable by the bottom-right handle (WindowResize), clamped so the title stays on screen; X close box.
  • Widgets: static text, frame, input line (insert/backspace/delete/Home/End/ arrows), push button, check box, radio buttons, list box (selection, wheel scroll) and vertical scroll bar.
  • Focus chain (Tab / Shift-Tab / up-down); hardware cursor in the focused input; Enter/Space activate.
  • Keyboard decoding: printable UTF-8, arrows, Home/End, PgUp/PgDn, Ins/Del, F1-F12, Enter, Space, Backspace, Esc, Ctrl-C.
  • Mouse: xterm SGR reporting (mode 1002/1006) - click to focus/press, drag titles, click list rows, wheel scroll.
  • Generic modal dialog builder (Dialog/Dlg*/DlgRun) with inputs, check boxes (self-exclusive radio groups) and tagged buttons; MessageBox (OK / OK-Cancel / Yes-No) and the Message shorthand.
  • SIGWINCH-driven resize detection via a libc signal handler.
  • Multi-line editor widget (VEditor) with insert/overwrite, navigation, Tab indent, mouse positioning, a Ln/Col/Insert/Modified status row and file load/save; syntax highlighting for Modula-2/Pascal/Oberon and automatic keyword up-casing and auto-indentation for Modula-2/Oberon (indent after open keywords, dedent on close keywords); demo examples/edit (with a Syntax menu to switch language).
  • Example programs (empty, window, dialog, menus, edit, gfx); API reference (API.md) and tutorial (TUTORIAL.md).
  • tigr graphics backend (tvg): the same view tree rendered in a window. Text uses a bundled 8x16 monospaced VGA font (tvfont, public-domain IBM VGA glyphs) so no system font is needed; box drawing is line segments; tigr keyboard/mouse are mapped to tv events. tv.InitVirtual lets any driver set the virtual screen size without touching the terminal.
  • Menu bar with drop-down menus: click or F10 to open, Left/Right switch menus, Up/Down move, Enter/Space or click selects (returns the item tag); separators supported.

Verified

Driving the demo through a pty and reconstructing the screen:

  • initial layout (Editor + About windows, list, radios, check box, buttons, status bar) renders correctly;
  • clicking OK with the mouse opens the modal Info box;
  • dragging the title moves the window in every direction and clamps at the top-left so the title stays visible;
  • clicking the File title opens the drop-down (New/Open/Sep/Quit), F10
    • Enter selects the first item (status shows the command tag), and clicking Quit exits the program.

Known limitations / next steps

  • Menu items have no hotkeys; no check/radio menu items.
  • No form validation or file/directory dialog.
  • The graphics window uses integer scaling (TIGR_FIXED); no per-window font size or resizable grid yet.
  • Windows are not resizable; no hover highlight.
  • Terminal size is polled (no SIGWINCH-driven relayout).
  • Nested clipping groups beyond windows are untested.

GNU Modula-2 notes

See README.md: value-returning no-arg procedures need () in the .def; pointer fields need ^; a BEGIN...END block cannot be a CASE branch; INTEGER vs HIGH() comparisons need VAL; termios/winsize use fixed Linux offsets. A subtle runtime bug was found and fixed in the ANSI output: SGR attributes accumulate, so blink must be emitted explicitly as ;5/;25 or it leaks into every following cell.