feat: on-device menu core, Device Info, Factory Reset (PR 6/9) - #41
Merged
Merged
Conversation
Adds the on-device menu system: hold Left Up+Down together for 1s to open it, then Left Up/Down scroll, Stick Click confirms, Bumper backs out. All pure logic — MenuController (menu.h/.cpp) knows nothing about real buttons or the display; SnipsController.ino translates button edges into its four nav calls, and renderMenuScreen() turns menu state into a ScreenBuffer for the existing OledDisplay to draw. Menu tree covers everything that's genuinely local and has everything it needs already built: - Calibrate Stick / Calibrate Trigger — wires up the guided-calibration flows built in PR 5 (previously unused), persisting results via CalibrationStore - Device Info — placeholder pending PR 8's XBee SPI transport, which is what will actually let this query the module's SL - Factory Reset — confirm-gated, currently clears calibration data; extends to the droid list once DroidStore exists (PR 7) Switch Droid/Manage Droids (PR 7) and Display Config (PR 9) aren't part of this menu tree yet — they need subsystems that don't exist. Also adds TextEntryWidget (text_entry.h/.cpp), the reusable one- character-at-a-time entry widget (full alphanumeric charset, or hex-only) that PR 7's Manage Droids screen will need for name/PAN ID entry — built now alongside the rest of the menu framework per the rewrite plan, not yet wired to anything. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 6 of the firmware rewrite (PR 1: #35, PR 2: #36, PR 3: #38, PR 4: #39, PR 5: #40). Adds the on-device menu system.
MenuController(include/menu.h/src/menu.cpp): pure state machine. Knows nothing about real buttons or the display. Held-combo detection (Left Up+Down for 1s) opens the menu from inactive; once open,onUp()/onDown()scroll,onEnter()confirms,onBack()cancels/exits.renderMenuScreen(): pure function deciding what text goes on screen for the menu's current state — the existingOledDisplay/ScreenBuffersplit from PR 3 does the actual drawing.CalibrationStore.SLneeds PR 8's SPI transport, which doesn't exist yet.DroidStoreexists (PR 7).TextEntryWidget(include/text_entry.h/src/text_entry.cpp): the reusable one-character-at-a-time entry widget (full alphanumeric, or hex-only) PR 7's Manage Droids screen will need for name/PAN ID entry. Built now alongside the rest of the framework per the rewrite plan; not wired to anything yet.SnipsController.ino: Left Up/Down + Stick Click + Bumper are "stolen" for nav only while the menu is open — harmless since the packet protocol (PR 8) doesn't exist yet for Amidala to see them any other way. Display only redraws on an actual state change, not every tick.Test plan
pio test -e native— all 104 test cases passgcovr --exclude 'src/SnipsController\.ino' --exclude 'src/oled\.cpp' --exclude 'src/rgb_led\.cpp' --exclude 'src/calibration_store\.cpp' --fail-under-line 90— 98.5% line coverage (remaining gaps are defensive branches unreachable through the public state machine)pio run -e esp32s3— builds successfully🤖 Generated with Claude Code