theming todo
This commit is contained in:
parent
8f2b545c81
commit
2f769edee3
2 changed files with 78 additions and 0 deletions
|
|
@ -142,6 +142,7 @@ A calculator application with three frontends (CLI, TUI, Android) sharing a comm
|
||||||
- **FR-7.7**: Every action must be reachable from the keyboard alone; the TUI is fully usable without a mouse.
|
- **FR-7.7**: Every action must be reachable from the keyboard alone; the TUI is fully usable without a mouse.
|
||||||
- **FR-7.8**: REMOVED. Quick-switch keys (`d`=dec, `h`=hex, `o`=oct, `b`=bin) to highlight the primary base cannot coexist with editable value fields: in the value zone those letters are hex and binary digits. The requirement predates editable fields, and the fields are the more useful feature. Base selection stays on the arrow keys and the mouse.
|
- **FR-7.8**: REMOVED. Quick-switch keys (`d`=dec, `h`=hex, `o`=oct, `b`=bin) to highlight the primary base cannot coexist with editable value fields: in the value zone those letters are hex and binary digits. The requirement predates editable fields, and the fields are the more useful feature. Base selection stays on the arrow keys and the mouse.
|
||||||
- **FR-7.9**: Support terminal resize gracefully.
|
- **FR-7.9**: Support terminal resize gracefully.
|
||||||
|
- **FR-7.9.3**: NOT IMPLEMENTED. The colour scheme is selectable rather than fixed. Molokai stays the default, and the requirement is that it is a default: a light theme, a terminal's own 16 colours, and a user's choice are all reachable without editing the source. Today `draw.C` is eleven literal RGB triples read directly by every view, which makes the palette a compile-time fact. Prerequisite is naming the roles the views use (error, focus, selection, accent) instead of the colours they happen to be; tasks.md open item 17 holds the detail.
|
||||||
- **FR-7.9.1**: Nothing in the TUI's own chrome is cut off mid-word at 60 columns or more. Status lines are lists of key hints, and a line too long for the terminal drops whole hints from the end rather than losing the last one's tail: each mode orders its hints so the keys that leave the current zone (`?:help`, `Tab:mode`, the zone toggle) come first and are the last to go. Status lines also leave the final column clear, which is what lets a rendered frame be checked for clipping at all: any row but the separator reaching the right edge is then a fault, not a maybe. Below 60 columns the notices themselves cannot fit, and shortening them further would leave them saying nothing.
|
- **FR-7.9.1**: Nothing in the TUI's own chrome is cut off mid-word at 60 columns or more. Status lines are lists of key hints, and a line too long for the terminal drops whole hints from the end rather than losing the last one's tail: each mode orders its hints so the keys that leave the current zone (`?:help`, `Tab:mode`, the zone toggle) come first and are the last to go. Status lines also leave the final column clear, which is what lets a rendered frame be checked for clipping at all: any row but the separator reaching the right edge is then a fault, not a maybe. Below 60 columns the notices themselves cannot fit, and shortening them further would leave them saying nothing.
|
||||||
- **FR-7.9.2**: Input is ASCII. A key event carrying non-ASCII text is dropped rather than stored: every column in the TUI is one byte, so an accented character would occupy a cell per UTF-8 byte, drawn as blanks, and then fail to tokenize. Refusing it keeps what is on screen equal to what is in the buffer. A wider fix is a different piece of work: the whole layout counts columns in bytes.
|
- **FR-7.9.2**: Input is ASCII. A key event carrying non-ASCII text is dropped rather than stored: every column in the TUI is one byte, so an accented character would occupy a cell per UTF-8 byte, drawn as blanks, and then fail to tokenize. Refusing it keeps what is on screen equal to what is in the buffer. A wider fix is a different piece of work: the whole layout counts columns in bytes.
|
||||||
- **FR-7.10**: Vi-style and Emacs-style keybinding options for expression input. NOT IMPLEMENTED: the prompt is a plain text field. Deferred, not dropped.
|
- **FR-7.10**: Vi-style and Emacs-style keybinding options for expression input. NOT IMPLEMENTED: the prompt is a plain text field. Deferred, not dropped.
|
||||||
|
|
|
||||||
|
|
@ -1718,6 +1718,83 @@ STILL OPEN, in the order I would take them:
|
||||||
history: earlier results stay FR-1.7's replay, so the set is one name and the
|
history: earlier results stay FR-1.7's replay, so the set is one name and the
|
||||||
third kind of name has exactly one member.
|
third kind of name has exactly one member.
|
||||||
|
|
||||||
|
17. **The colour palette is a hardcoded theme.** `src/tui/draw.zig` declares `C`, a
|
||||||
|
namespace of eleven Molokai colours as literal RGB triples, and every view reads
|
||||||
|
from it directly (`C.cyan`, `C.pink`, `C.sel`). Nothing is wrong with Molokai as
|
||||||
|
the default, but it is the only possibility: there is no way to ship a light
|
||||||
|
theme, follow a terminal's own colours, or let a user pick.
|
||||||
|
|
||||||
|
What the entry-14 review left in place is the shape that makes this awkward. `C`
|
||||||
|
is a container full of `pub const`s, so a colour is resolved at compile time at
|
||||||
|
every call site. A theme has to be a value the app holds and passes, or reads
|
||||||
|
through one accessor, before any of it can change at run time. The names
|
||||||
|
themselves are also the palette's rather than the interface's: views ask for
|
||||||
|
`C.pink` where what they mean is "an error", and `C.yellow` where they mean "the
|
||||||
|
focused field". A theme that has to answer to `pink` cannot be a theme.
|
||||||
|
|
||||||
|
So the work is two steps, in order: name the roles the views actually use
|
||||||
|
(error, focus, selection, muted, accent, and so on), then make the mapping from
|
||||||
|
role to colour a value rather than a constant. Only then does the choice of
|
||||||
|
palette become data - a default, a file, or a flag. Doing the second without the
|
||||||
|
first just moves the same eleven names behind a pointer.
|
||||||
|
|
||||||
|
18. **Entry 15 review findings for `src/tui.zig`**, recorded rather than acted on. In
|
||||||
|
rough order of weight:
|
||||||
|
|
||||||
|
- **A double free on OOM in `submitConvert`.** `value` is guarded by an
|
||||||
|
`errdefer value.deinit()`, and the conversion-failure branch also calls
|
||||||
|
`value.deinit()` explicitly before two `try`s. If either the `dupe` or the
|
||||||
|
`history.append` fails, the errdefer fires on an already-freed value. The fix is
|
||||||
|
the ownership-transfer pattern: `var adopted = false; defer if (!adopted)
|
||||||
|
value.deinit();`, with the flag set where `conv_value` takes it.
|
||||||
|
- **`ProgField.expression` is a dead focus stop.** Up/Down in the value zone cycles
|
||||||
|
`bin -> expression -> bits`, but no row is drawn for it, no key does anything in
|
||||||
|
it (`handleValueInput` has an empty prong, `fieldBitStep` returns 0), and nothing
|
||||||
|
highlights it, so the user gets a keystroke that appears to do nothing. Either
|
||||||
|
drop it from the enum or make it mean what its name says and hand focus back to
|
||||||
|
the input line, which is what backtick and `focus_input` already do.
|
||||||
|
- **The decimal fields cannot be corrected or signed.** The value zone handles no
|
||||||
|
backspace, so a mistyped digit in DEC(s)/DEC(u) can only be fixed by retyping the
|
||||||
|
whole value, and `handleValueInput` treats both decimal fields as unsigned
|
||||||
|
multiply-and-add: typing into DEC(s) while it shows a negative number operates on
|
||||||
|
the two's complement bits and produces nonsense. There is also no way to type a
|
||||||
|
minus sign. FR-7.3 already carries a note about the value zone's `Enter:set`
|
||||||
|
hint; this is the same area.
|
||||||
|
- **Two copies of the bit grid's geometry.** `handleValueZoneKey` computes
|
||||||
|
`bits_per_row = if (width > 32) 32 else width` for Up/Down, and
|
||||||
|
`programmer.zig`'s `drawBitGrid` computes the same thing for drawing. Change the
|
||||||
|
grid to 16 per row and the arrows would silently disagree with the display.
|
||||||
|
- **Two copies of the float-view toggle.** `applyAction`'s `.toggle_float` and
|
||||||
|
`handleKey`'s Ctrl-F both flip `float_view_active`, call `syncFloatWidth` and set
|
||||||
|
`prog_field = .bits`; the keyboard path then re-clamps the bit cursor, which
|
||||||
|
`syncFloatWidth` has already done, and `loadAnsIntoProgrammer` re-clamps it a
|
||||||
|
third time. One `toggleFloatView` method would hold it.
|
||||||
|
- **The file header is stale.** It says "Split into sub-modules" and lists three of
|
||||||
|
the six files it imports, missing `float_view`, `convert` and `financial`.
|
||||||
|
`display_format`'s doc comment points at a `clipboard_format` that does not exist
|
||||||
|
(open item 14: nothing yanks yet). `App.env` and `init` spell
|
||||||
|
`engine.evaluator.Environment` where the `engine.Environment` alias exists.
|
||||||
|
- **`drawHistory` is open item 8's other half.** Fixing it is now a small change
|
||||||
|
rather than a redesign: fill the line window newest-first, bounded by the rows
|
||||||
|
actually visible, instead of flattening oldest-first into 512 slots and slicing
|
||||||
|
the tail. The cap then limits how far back a very tall terminal can show, not how
|
||||||
|
long a session can run before new results stop appearing.
|
||||||
|
- **The multi-base breakdown exists twice.** `submitStandard` builds
|
||||||
|
`hex:`/`oct:`/`bin:` detail lines behind `has_nondecimal_literal` and a
|
||||||
|
displayable-integer test written inline; `cli/format.zig` has the same three
|
||||||
|
labels behind `isDisplayableInt`. Same words, same predicate, two sinks. FR-5.7's
|
||||||
|
sub-bullet settled the equivalent question for the financial function list.
|
||||||
|
- **`display_format` is duplicated** between `tui.zig` and `cli/format.zig`: five
|
||||||
|
identical numbers with the same NFR-9.9 rationale in both. Per-frontend choice is
|
||||||
|
the requirement, so this may be right as it stands, but it should be a decision
|
||||||
|
rather than a coincidence.
|
||||||
|
- Cosmetics: `modeIndex` wraps `@intFromEnum` for two callers six lines below it;
|
||||||
|
`Mode` is private while `Action`, `nextMode` and `prevMode` are public and name
|
||||||
|
it; `loadAnsIntoProgrammer` bounds its "fits an integer" test with the literals
|
||||||
|
`-9223372036854775808.0` and `18446744073709551616.0`; and `handleKey` is a
|
||||||
|
200-line if-chain mixing global keys, mode-specific keys and zone dispatch, which
|
||||||
|
reads fine today but is where a new binding will end up in the wrong order.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Phase 6: Android App
|
## Phase 6: Android App
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue