Add graphical display support#423
Merged
Merged
Conversation
## Summary - Route board-scoped example paths through a new `Prepare sketch paths` step in `compile-arduino.yml` so hardware-specific sketches can be conditionally included. - Compile `examples/ST7920_SPI` only for ESP32 jobs (and only when the example exists on the branch), while preserving universal sketch compilation for all boards. - Add a rendering docs note describing that CI compiles hardware-specific examples only on compatible board jobs. ## Verification - Workflow/config and docs only change; no unit-test or runtime code paths were modified in this iteration. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added clarification on how continuous integration compiles hardware-specific rendering examples exclusively on compatible board jobs. * **Chores** * Improved CI/CD workflow to conditionally include hardware-specific example sketches in compilation based on target board type. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - Add RTTI-free extension hooks to core renderer/item APIs via `MenuRenderer::queryExtension()` and `MenuItem::queryCapability()`. - Introduce optional extension interfaces for frame lifecycle and graphical context/capabilities (`FrameLifecycleRenderer`, `GraphicalRendererContext`, `GraphicalMenuItem`) without adding pixel-specific methods to base classes. - Wire frame lifecycle hooks into menu flow: `MenuScreen::draw()` calls `beginFrame()` and `LcdMenu` now calls `endFrame()` after handled draw-triggering actions (`setScreen`, `show`, `refresh`, handled `process`). - Add unit tests verifying frame flush behavior on `refresh()` and handled `process()` commands. - Document the extension model in rendering docs. ## Verification - Attempted to run Arduino unit tests locally (`bundle exec arduino_ci.rb --skip-examples-compilation`), but local Ruby gem install requires privileged system paths on this machine. - Performed static diff review and kept PR scope to extension-core + unit tests + docs only. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit # Release Notes * **New Features** * Introduced an extension mechanism allowing renderers to expose optional capabilities and frame lifecycle hooks. * Added support for menu items to discover and expose renderer-compatible capabilities. * Enabled specialized renderers to participate in frame lifecycle management for optimized buffered drawing. * **Documentation** * Added documentation defining the extension mechanism and capability query approach for advanced renderers. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - add a pixel-display foundation with `GraphicalDisplayInterface`, `U8g2DisplayAdapter`, and `GraphicalDisplayRenderer` - introduce graphical renderer extension helpers (`GraphicalIndicatorRenderer`, `GraphicalValueSelectionRenderer`, `GraphicalItemFont`) and extend `GraphicalMenuItem` - wire `MenuScreen` to dynamic row/column context (`getMaxRows/getMaxCols`) so graphical renderers can compute viewport/value layout - add graphical renderer docs and new examples for `SSD1306_I2C` and `ST7920_SPI` - update README and PlatformIO dependencies to include U8g2 usage for graphical examples <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added support for pixel-addressable graphical displays via U8g2 library integration * New interactive menu examples for SSD1306 (I2C) and ST7920 (SPI) displays with features like font metrics, scrollbars, and per-item custom fonts * **Documentation** * Updated README specifying built-in graphical display support with concrete module examples * Added documentation page for graphical display renderer with features overview and C++ usage example <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - teach `MenuScreen` to populate optional `GraphicalRendererContext` state (viewport, active item, value-area width) before drawing and polling - clamp cursor/view using dynamic `getMaxRows()` / `getMaxCols()` so graphical font changes cannot desync visible ranges - preserve draw-owned frame lifecycle (`beginFrame`/`endFrame`) while keeping poll flush behavior unchanged in `LcdMenu` - update unit tests for the new clamped-view behavior and add docs note under graphical renderer integration <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Menu now properly integrates with graphical renderers, providing correct viewport context and accounting for varying font sizes across menu items. * Improved menu navigation to properly handle non-selectable items and adjust view positioning. * **Bug Fixes** * Enhanced cursor bounds checking and viewport recalculation logic. * **Documentation** * Added documentation explaining Menu integration with graphical display renderers. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - Add `GraphicalMenuItem` capability support across core items and widget-backed items, including graphical value-width measurement, toggle/list indicators, and a `BasicItem` implementation for `ITEM_BASIC`/`ITEM_LABEL`. - Improve widget/item drawing safety for graphical rendering by hardening buffer handling (`ITEM_DRAW_BUFFER_SIZE` growth, null-safe bool widget formatting) and exposing optional `GraphicalValueSelectionRenderer` extension hooks. - Add unit coverage for new item capabilities in `test/ItemValue.cpp` and document the new graphical item capability model in `docs/source/overview/rendering/graphical-display.rst`.
## Summary - Extend `ItemInput` with `GraphicalMenuItem` capability support, including graphical value-width measurement and tight selection-box behavior. - Add optional `GraphicalValueSelectionRenderer` integration for `ItemInput` and `ItemInputCharset` so graphical renderers can highlight active character selection during editing. - Update item docs for `input` and `input-charset`, and add unit coverage in `test/LcdMenu.cpp` for graphical input capability exposure and selection-extension edit flow. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Input items now support graphical rendering with visual value selection highlighting in the display area. * **Documentation** * Added documentation describing graphical rendering behavior for input items and character selection display. * **Tests** * Added unit tests for graphical rendering functionality and visual feedback verification. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - Extend `GraphicalDisplayRenderer` to implement and expose `GraphicalValueSelectionRenderer` via `queryExtension()`. - Add value-selection state handling in the renderer draw path so editing overlays can highlight selected value substrings. - Document the renderer hook in `graphical-display` docs and add unit coverage in `test/GraphicalDisplayRenderer.cpp` to verify extension exposure. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added visual selection highlighting support for graphical displays. Text input and character selection components now display an active selection indicator with a highlight box, providing clearer visual feedback when editing text on graphical display interfaces. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - Tighten graphical renderer font metric and row-height handling to match the snapshot behavior. - Render graphical list/submenu indicators with focus-aware draw colors. - Add focused renderer tests for row height and indicator color behavior. ## Checks - git diff --check - pio run -e esp32 ## Notes - `pio run -e uno` currently fails because base `src/main.cpp` builds the graphical/U8g2 showcase and exceeds Uno memory/flash; this branch does not change `src/main.cpp`. - `pio test -e uno` is blocked by missing `ArduinoUnitTests.h`/`Godmode.h` in the current PlatformIO test setup.
## Summary - Clear the graphical scrollbar track before drawing the handle. - Clamp scrollbar track and scroll range math to avoid underflow/division edge cases. - Add focused renderer coverage for scrollbar track clearing. ## Checks - git diff --check - pio run -e esp32 ## Notes - Unrelated local `diagram.json`, `wokwi.toml`, `bin/`, and `docs/source/reference/samples/` changes were not included.
## Summary - Account for left padding, scrollbar inset, and cursor icon width in graphical effective columns. - Make max column calculation fall back to the active display font width when cached width is unset. - Add focused renderer coverage for effective/max column calculations. ## Checks - git diff --check - pio run -e esp32
## Summary - move graphical frame finalization to LcdMenu entry points for setScreen, handled process calls, show, and refresh - stop MenuScreen from ending frames directly during draw - update graphical viewport context before item command handling - adjust lifecycle tests for centralized ownership ## Checks - git diff --check - pio run -e esp32 ## Notes - intentionally skips low-value timeout debounce drift and doc-comment-only drift - intentionally skips broad viewport structural churn without clear behavior value - only src/LcdMenu.cpp, src/MenuScreen.cpp, and test/LcdMenu.cpp are included
## Summary - port remaining graphical renderer drawItem text/value windowing behavior - improve cursor placeholder, blinker, toggle, list/submenu indicator, row-height, and scrollbar handling - update focused GraphicalDisplayRenderer tests, including review-fix coverage for short values ## Review fixes - avoid reserving one-third of the row for short/empty values when valueAreaWidth is unset - align draw color capture test stub with its expanded capture buffer ## Checks - git diff --check - clang-format --dry-run --Werror src/renderer/GraphicalDisplayRenderer.cpp src/renderer/GraphicalDisplayRenderer.h test/GraphicalDisplayRenderer.cpp - pio run -e esp32 ## Notes - pio test -e esp32 is still blocked locally by missing ArduinoUnitTests.h / Godmode.h in the current repo test harness - intentionally skipped snapshot deletion of test/GraphicalDisplayRenderer.cpp because focused coverage is valuable - only GraphicalDisplayRenderer files and test/GraphicalDisplayRenderer.cpp are included
## Summary - always clear graphical value selection after input item rendering - remove stale implementation-specific input graphical docs/comments - strengthen LcdMenu input graphical selection coverage to verify selection set/clear behavior ## Checks - git diff --check - clang-format --dry-run --Werror src/ItemInput.h src/ItemInputCharset.h test/LcdMenu.cpp - pio run -e esp32 - make html (from docs/; succeeded with existing unrelated warnings) ## Notes - focused pio test path remains blocked locally by missing ArduinoUnitTests.h / Godmode.h in the current PlatformIO test harness - intentionally skipped snapshot deletions in test/ItemValue.cpp as low-value/unrelated to this bundle - only scoped input headers, item docs pages, and test/LcdMenu.cpp are included
## Summary - track whether `ItemInput` owns its value buffer before freeing it - make default-empty inputs use owned writable storage - clone external values before mutating them in input and charset edit paths - add regression coverage for default-empty, static, and stack-backed input values ## Verification - `pio run -e esp32` passed - `pio test -e esp32` fails before running tests due missing known harness headers: `ArduinoUnitTests.h` and `Godmode.h` - `pio run -e uno` fails due existing program/RAM size overflow for the current app build
## Summary - expand GraphicalDisplayRenderer documentation with U8g2 display support, fonts, glyphs, layout, highlighting, indicators, scrollbar, and frame buffering - convert existing character-display media examples to tabbed sections with future graphical-display placeholders - preserve existing 16x2 I2C character display screenshots/GIFs and avoid broken image references for missing graphical assets ## Checks - make html from docs/ succeeded with existing unrelated warnings - git diff --cached --check before commit ## Notes - graphical display placeholder tabs describe expected future filenames only; no missing image directives were added - unrelated local files remain uncommitted/excluded: diagram.json, wokwi.toml, examples/Widgets/Widgets.ino, bin/, docs/source/reference/samples/, solo.yml
Contributor
📝 WalkthroughWalkthroughThis PR adds a graphical rendering subsystem for pixel-addressable displays: GraphicalDisplayInterface and U8g2DisplayAdapter, a full GraphicalDisplayRenderer with frame lifecycle and selection highlighting, renderer extension/capability hooks, GraphicalMenuItem support across core items, MenuScreen/Menu lifecycle integration, example Arduino sketches (SSD1306_I2C, ST7920_SPI), platform/CI updates, extensive documentation, and unit tests. Sequence Diagram(s)sequenceDiagram
participant Keyboard as KeyboardAdapter
participant Menu as MenuScreen / LcdMenu
participant Renderer as GraphicalDisplayRenderer
participant Display as U8g2DisplayAdapter
Keyboard->>Menu: observe()/process input
Menu->>Renderer: setViewportContext / setActiveItem / draw
Renderer->>Display: setFont / drawItem / setValueSelection
Renderer->>Display: beginFrame / clearBuffer / sendBuffer
Display-->>Renderer: metrics (getTextWidth, fontHeight)
Renderer-->>Menu: report redraw / cursor moves
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
forntoh
commented
May 27, 2026
Contributor
|
Memory usage change @ 01b473f
Click for full report table
Click for full report CSV |
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.
Preview
Summary
GraphicalDisplayRendererand U8g2-backed display adaptersVerification
Closes #382
Resolves #210
Resolves #200
Summary by CodeRabbit
New Features
Documentation