feat(engine): hold-/ hotkey cheat sheet + unified binding table (Phase J) #183

Merged
funman300 merged 1 commits from feat/keyboard-completeness into master 2026-07-14 02:04:07 +00:00
Owner

Phase J from docs/ui-redesign-2026-07.md — keyboard & focus completeness.

Audit results (the good news)

Two of the doc's three deliverables turned out to already exist, written after the doc:

  • Visible focus ring — the FocusOverlay singleton (2px accent ring, breathing pulse, reduce-motion aware, pinned above modals) IS the Terminal-styled ring the doc asked for.
  • Every modal keyboard-reachable/dismissable — post-Phase-C dismissal audit, all modals open via hotkeys (M/O/F1/S/A/P/L/6…) or focusable rows, and close via Esc / focused buttons. Verified in code; also empirically — the entire emulator smoke suite drives the app by keyevents alone.

What was actually missing (this PR)

  • One binding table. Onboarding's slide and Help's list had already diverged (onboarding still said "Mode Launcher (then 1–5)"). New crate::hotkeys module owns the single 21-row table, verified against a grep inventory of every just_pressed(KeyCode::…) handler and pinned by integrity tests. Rows carry an essential flag: onboarding teaches the subset, the cheat sheet shows all.
  • Hold-/ cheat sheet. A lightweight right-anchored overlay (deliberately not a modal — it's a momentary reference) listing every binding while / is held; hides on release, never spawns over a modal (which also keeps it out of the seed-entry field), inert on touch builds.

Tests

5 new (table integrity/uniqueness/subset size, show-hide driver, modal suppression). Full workspace + clippy green, exit-code-verified.

Follow-up noted for the future: a true bindings registry generated from the input systems (the table is hand-maintained but test-pinned — honest 90% at 1% of the cost). Help's touch-specific list intentionally stays separate.

🤖 Generated with Claude Code

Phase J from docs/ui-redesign-2026-07.md — keyboard & focus completeness. ## Audit results (the good news) Two of the doc's three deliverables turned out to already exist, written after the doc: - **Visible focus ring** — the FocusOverlay singleton (2px accent ring, breathing pulse, reduce-motion aware, pinned above modals) IS the Terminal-styled ring the doc asked for. - **Every modal keyboard-reachable/dismissable** — post-Phase-C dismissal audit, all modals open via hotkeys (M/O/F1/S/A/P/L/6…) or focusable rows, and close via Esc / focused buttons. Verified in code; also empirically — the entire emulator smoke suite drives the app by keyevents alone. ## What was actually missing (this PR) - **One binding table.** Onboarding's slide and Help's list had already diverged (onboarding still said "Mode Launcher (then 1–5)"). New `crate::hotkeys` module owns the single 21-row table, verified against a grep inventory of every `just_pressed(KeyCode::…)` handler and pinned by integrity tests. Rows carry an `essential` flag: onboarding teaches the subset, the cheat sheet shows all. - **Hold-`/` cheat sheet.** A lightweight right-anchored overlay (deliberately not a modal — it's a momentary reference) listing every binding while `/` is held; hides on release, never spawns over a modal (which also keeps it out of the seed-entry field), inert on touch builds. ## Tests 5 new (table integrity/uniqueness/subset size, show-hide driver, modal suppression). Full workspace + clippy green, exit-code-verified. Follow-up noted for the future: a true bindings registry generated from the input systems (the table is hand-maintained but test-pinned — honest 90% at 1% of the cost). Help's touch-specific list intentionally stays separate. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
funman300 added 1 commit 2026-07-14 01:58:45 +00:00
feat(engine): hold-/ hotkey cheat sheet + unified binding table (Phase J)
Test / fmt (pull_request) Successful in 4s
Test / test (pull_request) Successful in 4m33s
36605751cd
Phase J audit findings: the visible focus ring the doc asked for
already exists (FocusOverlay singleton, 2px accent ring, breathing
pulse, reduce-motion aware — landed after the doc was written), and
post-Phase-C every modal already opens and dismisses keyboard-only.
The real gaps were two silently diverging static hotkey tables
(onboarding's slide vs Help's list — onboarding still said 'Mode
Launcher (then 1-5)') and no way to see the bindings mid-game.

- New crate::hotkeys module owns THE binding table (21 rows, verified
  against a grep inventory of every just_pressed(KeyCode::..) handler);
  rows carry an `essential` flag — the onboarding slide teaches that
  subset, the cheat sheet shows everything.
- New cheat_sheet_plugin: hold `/` for a right-anchored reference
  overlay of every binding; release hides it. Deliberately not a
  spawn_modal modal (momentary reference, closer to a tooltip), never
  spawns while a modal owns the screen (also keeps it out of the
  seed-entry field), inert on touch builds.
- Onboarding's stale local table deleted in favour of the shared one
  (copy updated: Home naming, hold-to-repeat undo, added H).

5 new tests (table integrity, essential-subset size, uniqueness,
show/hide driver, modal suppression). Workspace + clippy green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
funman300 merged commit cbbab3d09f into master 2026-07-14 02:04:07 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: funman300/Ferrous-Solitaire#183