9.0 KiB
Terminal UI and toolbox plan
This document records the planned terminal UI direction for future mars-nwe administration tools. It is a design note, not a commitment that the runtime implementation already exists.
Goals
mars-nwe should not grow more direct curses.h users. The FLAIM test utilities
currently show why this matters: an otherwise optional developer/test tool can
pull ncurses into the build shape. Future interactive tools such as setup,
filer, salvage, metadata repair and backup helpers should share one small TUI
layer instead of each choosing a terminal library.
The preferred shape is:
third_party/termbox2/ pinned MIT terminal/event backend, tag v2.5.0
third_party/iniparser/ pinned MIT INI reader/writer backend, tag v4.2.6
include/core/ini.h shared libnwcore INI API used by server and tools
src/core/ini.c mars-nwe INI wrapper/adaptation and policy
src/nwtui/ mars-nwe terminal widgets and themes
include/nwtui.h public tool-facing TUI API
src/nwi18n/ small mars-nwe translation catalog loader
include/nwi18n.h public translation lookup API
src/nwtoolbox/ multi-call toolbox binary
Tool code must call nwtui_* and nwi18n_*, not the backend directly. The
backend now starts with termbox2 behind the libnwtui facade. A minimal
ANSI backend or another terminal backend can still replace it later without
rewriting nwsetup, nwfiler or nwsalvage.
Configuration/catalog parsing must not be private to the TUI layer. The shared
INI parser/writer belongs in libnwcore so that production daemons, setup tools
and optional translation catalogs all use one policy. See
doc/NWCORE_INI_PLAN.md.
Default look
The default visual style should be a coloured DOS/NetWare-like text UI, not a monochrome curses application. Use ASCII borders as the mandatory base so old terminals still work. UTF-8 block graphics may become an optional theme later, but are not required for the design.
The existing blue bar tradition in dosutils/login.c is the local mars-nwe
reference. External DOS file-manager/BBS screenshots can be used as visual
inspiration for blue panels, cyan/bright borders, highlighted menu items and a
fixed help line, but should not be copied verbatim.
A typical screen should have this structure:
+------------------------------------------------------------------------------+
| MARS-NWE Toolbox 0.99 Server: MARS SYS: OK IPX: L2 |
+------------------------------------------------------------------------------+
| Setup | Filer | Salvage | Metadata | Backup | Logs | Exit |
+------------------------------------------------------------------------------+
+------------------------------+ +----------------------------------------+
| Setup steps | | Networking |
| | | IPX backend: L2 Ethernet II |
| > Configure server name | | Interface: eth0 |
| Configure IPX | | Network: 0x00000002 |
| Configure volumes | | |
+------------------------------+ +----------------------------------------+
+---------------------------+
| Running: validate config |
| Status : waiting |
+---------------------------+
+------------------------------------------------------------------------------+
| F1 Help | Enter Select | Esc Back | Tab Next | Alt+S Setup |
+------------------------------------------------------------------------------+
The header should be wider and calmer than very compact DOS file managers:
- header/version/system-status line;
- top menu or wizard step line;
- content/work area with panels, forms, lists or dialogs;
- optional right/bottom running-action box;
- bottom help/status line.
Theme roles
Tools should never hard-code raw colours. They should request style roles from
nwtui:
typedef enum {
NWTUI_STYLE_NORMAL,
NWTUI_STYLE_HEADER,
NWTUI_STYLE_MENU,
NWTUI_STYLE_MENU_SELECTED,
NWTUI_STYLE_PANEL,
NWTUI_STYLE_PANEL_TITLE,
NWTUI_STYLE_STATUS,
NWTUI_STYLE_HELP,
NWTUI_STYLE_ERROR,
NWTUI_STYLE_WARNING,
NWTUI_STYLE_OK,
NWTUI_STYLE_DISABLED
} NwTuiStyle;
The first theme should be named mars-blue:
- header/menu/status bars: blue background;
- normal panel background: blue or terminal-default according to capability;
- borders: cyan/bright blue;
- selected menu/list items: inverted or high-contrast highlight;
- help/hotkeys: yellow/bright accent;
- errors: red/bright red;
- warnings: yellow/brown;
- successful/done states: green;
- disabled items: dim/grey.
Navigation widgets
Top navigation is a first-class widget. It is used both as a menu and as a wizard-step bar. It should be keyboard reachable and mouse clickable where the backend supports mouse input.
Expected behaviour:
- Left/Right move between top items;
- Alt+hotkey activates a named item;
- Enter selects the focused item;
- Tab moves between fields/panels;
- F1 opens help;
- Esc goes back or exits the current modal action;
- mouse click selects a top item or panel item if mouse support is enabled.
nwsetup can use the same widget as a progress/step line, for example:
Configuration | Networking | Volumes | Bindery | Logging | Finish
The bottom help line should be stable and translated. It should not carry large version text; version and system status belong in the header.
Multi-call binary
The future interactive tools should be built as one multi-call binary, not as several unrelated terminal programs:
nwtoolbox main interactive menu
nwsetup symlink/hardlink/argv[0] entry to setup mode
nwfiler symlink/hardlink/argv[0] entry to filer mode
nwsalvage symlink/hardlink/argv[0] entry to salvage mode
nwmetadata symlink/hardlink/argv[0] entry to metadata/repair mode
nwbackup symlink/hardlink/argv[0] entry to backup/export mode
nwtoolbox without a specific applet name opens the main menu and lets the user
choose setup, filer, salvage, metadata, backup, logs and future tools. If the
same binary is invoked through a specific symlink name, it should start that
applet directly. This keeps shared UI, translation, config loading and privilege
checks in one executable while preserving familiar command names.
Conceptual dispatch:
int main(int argc, char **argv)
{
const char *name = nw_basename(argv[0]);
if (!strcmp(name, "nwsetup"))
return nwtoolbox_run_setup(argc, argv);
if (!strcmp(name, "nwfiler"))
return nwtoolbox_run_filer(argc, argv);
if (!strcmp(name, "nwsalvage"))
return nwtoolbox_run_salvage(argc, argv);
return nwtoolbox_run_menu(argc, argv);
}
The applets should share process-wide initialisation:
- load configuration;
- load translation catalog;
- initialise logging;
- initialise terminal backend/theme;
- check privileges and server paths;
- then enter the selected applet.
Command-line subcommands may still exist for scripts, but the interactive TUI entry should be the multi-call toolbox.
Translation without gettext
Do not add a gettext dependency just for TUI strings. Use a small mars-nwe translation API. The backing catalog can be an INI-like file, a generated C table, or a small project-owned parser. Tools should not know the storage format.
Conceptual API:
int nwi18n_load(const char *language, const char *catalog_path);
const char *nwi18n_get(const char *key);
const char *nwi18n_get_default(const char *key, const char *fallback);
Catalog keys should be stable English identifiers, not source strings:
[en]
toolbox.title = MARS-NWE Toolbox
menu.setup = Setup
menu.filer = Filer
menu.salvage = Salvage
help.main = F1 Help | Enter Select | Esc Back
[de]
toolbox.title = MARS-NWE Toolbox
menu.setup = Setup
menu.filer = Filer
menu.salvage = Salvage
help.main = F1 Hilfe | Enter Auswählen | Esc Zurück
The default built-in language should be English. Missing keys fall back to the built-in English string or to the key name in developer builds.
FLAIM curses replacement path
The immediate dependency goal is to remove the ncurses requirement from FLAIM
test/tool paths. Do not rewrite every FLAIM utility at once. First isolate the
terminal dependency behind nwtui, then convert the small curses-using test
path to the wrapper.
Steps:
- inventory the current FLAIM test/tool source that includes
curses.h; - add
nwtuideclarations and a minimal backend plan; - convert the FLAIM test path from direct curses calls to
nwtuicalls; - remove ncurses from that tool path once the converted test compiles;
- keep PAM/ncurses header extraction in
prepare-local-deps.shonly while other compile checks still need it.
No production daemon should depend on the TUI stack.