diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-19 21:58:58 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-19 21:58:58 +0200 |
| commit | 4329ffb98d7eeffe2b3874d2b31cb0857d33d944 (patch) | |
| tree | 16e777dc90fa334ce3f436a3b5d3a7a9efdbd8b9 /docs | |
| parent | 34fc2b1dce788fbb093e70c2124630167e7980ef (diff) | |
| download | bokf-0.1.36.tar.gz bokf-0.1.36.zip | |
tui: shared widget layer (fields, prompts, lists, forms, pager) + testsv0.1.36
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/STATE.md | 6 | ||||
| -rw-r--r-- | docs/TUI-GUIDELINES.md | 23 |
2 files changed, 27 insertions, 2 deletions
diff --git a/docs/STATE.md b/docs/STATE.md index 60c70d9..32b2a4e 100644 --- a/docs/STATE.md +++ b/docs/STATE.md @@ -12,6 +12,12 @@ server/protocol/ledger only. ## Locked decisions +0. **TUI widget layer**: `clients/tui.[ch]` is the only module that touches + ncurses; screens compose its widgets and never keep local input/drawing + patterns. Every widget has a spec in `TUI-GUIDELINES.md` and unit tests + in `tests/test_tui.c` (run by `make test`; pure logic separated from + drawing). Extend the layer, not the screen. + 1. **Name/license**: `bokf`, daemon `bokfd`, clients `bokfctl` (scriptable) and `bokftui` (ncurses); GPL-3.0-or-later; repo `~/work/bokf`. 2. **Stack**: C11, Makefile, vendored SQLite 3.53.4 / yyjson 0.13.0 / Argon2 diff --git a/docs/TUI-GUIDELINES.md b/docs/TUI-GUIDELINES.md index a54fef8..63c492f 100644 --- a/docs/TUI-GUIDELINES.md +++ b/docs/TUI-GUIDELINES.md @@ -104,12 +104,31 @@ written compactly as `^N`, `^A`, `^C`, `^R` to save width. - Selection = reverse video, headers = bold, derived data = dim. - All user-visible TUI text is Swedish; server messages are English. +## Widget layer (`clients/tui.[ch]`) + +Every element a screen needs is a widget here, and the widget layer is the +only place that touches ncurses. Rules: + +- Screens never call ncurses directly (`mvadd*`, `attron`, `getch`…) and + never keep a local one-off input or drawing loop. +- If no widget fits, **extend the widget layer first** (spec in this file + + unit tests in `tests/test_tui.c`) and then use it. There is no "do it + locally once" option. +- Pure logic (line editing, date input, list navigation, prompts parsing) + is separated from drawing so it can be tested without a terminal. +- Widgets return key codes (`-1` back, `-2` refresh, `-4` new, `-6` remove, + `-7` toggle) and write text into the caller's buffer; nothing returns + static storage. +- The application supplies input, frame/hints and quit through + `tui_set_input`/`tui_set_screen`/`tui_set_quit`. + ## Adding a view — checklist 1. Data comes from public protocol commands only. 2. Wrap the screen in `frame()`/`hints()`; return `Esc`/`q` to the parent. -3. Use `menu()` or `select_list()` instead of writing a new loop; pass +3. Use `tui_menu`/`tui_select_list` instead of writing a new loop; pass `allow_new`/`allow_refresh` so the universal keys apply. -4. Forms use the shared editor (`field_edit`) and the row-normalising helpers. +4. Forms use the shared editor (`tui_edit_field`, `tui_prompt_into`, + `tui_date_prompt_into`, `tui_amount_prompt_into`) and the row helpers. 5. Support `F5` if the data can change elsewhere. 6. Update `PROTOCOL.md` §8 and this file if you add a new key or interaction. |
