Skip to content

feat(examples): Update BSP examples which have a display to use a gui class for clearer / more useful example code to start from#663

Merged
finger563 merged 3 commits into
mainfrom
feat/example-gui-classes
Jul 7, 2026
Merged

feat(examples): Update BSP examples which have a display to use a gui class for clearer / more useful example code to start from#663
finger563 merged 3 commits into
mainfrom
feat/example-gui-classes

Conversation

@finger563

Copy link
Copy Markdown
Contributor

Description

Refactors all 13 BSP display examples (esp-box, t-deck, wrover-kit,
matouch-rotary-display, seeed-studio-round-display, byte90,
ws-s3-lcd-1-47, ws-s3-touch, ws-s3-geek, smartpanlee-sc01-plus,
t-dongle-s3, m5stack-tab5, esp32-p4-function-ev-board) so that all LVGL
UI code lives in a per-example Gui class (example/main/gui.hpp +
gui.cpp) instead of ad-hoc statics and lambdas in app_main.

Each Gui class follows the same canonical pattern (modeled on the Gui /
Menu components in esp-box-emu,
without the squareline-generated code):

  • Owns a std::recursive_mutex guarding every LVGL call and an espp::Task
    which pumps lv_task_handler() every 16 ms.
  • init_ui() is broken into small member functions, one per logical piece of
    the UI (init_background(), init_label(), init_buttons(),
    init_circle_layer(), ...).
  • All LVGL events are registered with this as user-data and dispatched
    through a single static trampoline (event_callback) into member handlers.
  • The rest of the application interacts with the UI only through small,
    thread-safe, doxygen-documented methods (set_label_text(),
    draw_circle(), clear_circles(), next_rotation(), plus board-specific
    ones such as set_kalman_down() / set_madgwick_down(),
    set_clock_text(), set_status_text(), cycle_brightness()).

The app_mains now contain only board/peripheral init and calls into the
Gui (−2,999 / +410 lines across the 14 modified example mains). The doxygen
//! [<name> example] snippet markers are unchanged, so the rendered docs now
show the much cleaner app_main usage.

Behavior is preserved everywhere (touch-to-draw circles, rotation, keyboard /
encoder / hardware-button handling, IMU gravity lines, RTC clock, LED
animation tasks, audio clicks, networking/RTPS status on the P4 board), with
a few improvements:

  • All touch-capable boards gained an on-screen LV_SYMBOL_TRASH clear button
    next to the existing rotate button, exercising multi-button event dispatch
    through the trampoline.
  • m5stack-tab5: fixed the hardware brightness button passing 0.25–1.0 to the
    percent-based (0–100) brightness() API — which effectively blanked the
    screen — and added an on-screen brightness button; both now cycle
    25/50/75/100% through a shared Gui::cycle_brightness().
  • m5stack-tab5 BSP: fixed a compile failure under
    -Werror=missing-field-initializers (missing .write_then_read designated
    initializer in src/touchpad.cpp).

Motivation and Context

The display examples had grown into large app_main functions full of static
globals, free functions, and lambdas sharing a hand-rolled LVGL mutex — nearly
identical boilerplate duplicated 13 times, and not a good template for users
to build real UIs from. Encapsulating the UI in a Gui class gives users a
copyable, idiomatic starting point for structuring C++ LVGL applications on
top of the espp BSPs (thread-safety, event dispatch, and update-task ownership
all handled in one place), and makes the examples themselves shorter and
easier to follow.

How has this been tested?

  • All 13 examples were clean-built (rm -rf build && idf.py build) with
    ESP-IDF v6.0.1 across their respective targets (esp32, esp32s3, esp32p4);
    13/13 pass.
  • Verified no raw lv_* calls remain in any example app_main.
  • Verified every BSP initialize_* call from the original examples is
    preserved in the refactored ones.
  • Verified the doxygen snippet markers are intact in all 13 examples so the
    documentation still renders the example code.
  • All new/modified files formatted with the repo's .clang-format.
  • Runtime behavior (touch, buttons, rotation, IMU lines, audio) not yet
    re-verified on hardware.

Screenshots (if appropriate, e.g. schematic, board, console logs, lab pictures):

N/A — no visual changes beyond the added clear/brightness buttons.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update
  • Hardware (schematic, board, system design) change
  • Software change

Checklist:

  • My change requires a change to the documentation.
  • I have added / updated the documentation related to this change via either README or WIKI

Software

  • I have added tests to cover my changes.
  • I have updated the .github/workflows/build.yml file to add my new test to the automated cloud build github action.
  • All new and existing tests passed.
  • My code follows the code style of this project.

… class for clearer / more useful example code to start from
Copilot AI review requested due to automatic review settings July 7, 2026 14:59
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

✅Static analysis result - no issues found! ✅

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors multiple ESPP BSP display examples to move LVGL UI creation, event dispatch, and LVGL task ownership into per-example Gui classes (example/main/gui.hpp + gui.cpp), leaving app_main focused on board/peripheral initialization and high-level UI interactions.

Changes:

  • Introduces per-example Gui classes that encapsulate LVGL objects, a guarded lv_task_handler() pump task, and centralized LVGL event trampolines.
  • Updates example app_main implementations to call into the Gui API instead of managing ad-hoc statics/lambdas and LVGL locking.
  • Fixes a BSP build warning/error for m5stack-tab5 by adding the missing designated initializer field.

Reviewed changes

Copilot reviewed 40 out of 40 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
components/ws-s3-touch/example/main/gui.hpp New Gui API for ws-s3-touch (labels, buttons, gravity lines, circle layer).
components/ws-s3-touch/example/main/gui.cpp Implements ws-s3-touch GUI setup, LVGL task loop, event dispatch, circle drawing.
components/ws-s3-lcd-1-47/example/main/ws_s3_lcd_1_47_example.cpp Refactors example main to use Gui instead of static LVGL helpers.
components/ws-s3-lcd-1-47/example/main/gui.hpp New Gui API for ws-s3-lcd-1-47 (label + circle layer + rotation).
components/ws-s3-lcd-1-47/example/main/gui.cpp Implements ws-s3-lcd-1-47 GUI and LVGL update task.
components/ws-s3-geek/example/main/ws_s3_geek_example.cpp Refactors ws-s3-geek example main to use Gui.
components/ws-s3-geek/example/main/gui.hpp New Gui API for ws-s3-geek.
components/ws-s3-geek/example/main/gui.cpp Implements ws-s3-geek GUI and LVGL update task.
components/wrover-kit/example/main/wrover_kit_example.cpp Refactors wrover-kit example main to use Gui.
components/wrover-kit/example/main/gui.hpp New Gui API for wrover-kit.
components/wrover-kit/example/main/gui.cpp Implements wrover-kit GUI and LVGL update task.
components/t-dongle-s3/example/main/t_dongle_s3_example.cpp Refactors t-dongle-s3 example main to use Gui.
components/t-dongle-s3/example/main/gui.hpp New Gui API for t-dongle-s3.
components/t-dongle-s3/example/main/gui.cpp Implements t-dongle-s3 GUI and LVGL update task.
components/t-deck/example/main/gui.hpp New Gui API for t-deck (buttons + circle layer).
components/t-deck/example/main/gui.cpp Implements t-deck GUI, event dispatch, and circle drawing.
components/smartpanlee-sc01-plus/example/main/smartpanlee_sc01_plus_example.cpp Refactors SmartPanlee example main to use Gui and thread-safe UI calls from touch callback.
components/smartpanlee-sc01-plus/example/main/gui.hpp New Gui API for SmartPanlee (label + buttons + circle layer).
components/smartpanlee-sc01-plus/example/main/gui.cpp Implements SmartPanlee GUI layout + event dispatch + circle drawing.
components/seeed-studio-round-display/example/main/seeed_studio_round_display_example.cpp Refactors round-display example main to use Gui.
components/seeed-studio-round-display/example/main/gui.hpp New Gui API for round-display.
components/seeed-studio-round-display/example/main/gui.cpp Implements round-display GUI, layout updates, and event dispatch.
components/matouch-rotary-display/example/main/matouch_rotary_display_example.cpp Refactors matouch rotary display example main to use Gui.
components/matouch-rotary-display/example/main/gui.hpp New Gui API for matouch rotary display.
components/matouch-rotary-display/example/main/gui.cpp Implements matouch rotary display GUI, event dispatch, and circle drawing.
components/m5stack-tab5/src/touchpad.cpp Adds missing designated initializer field (.write_then_read) to satisfy -Wmissing-field-initializers.
components/m5stack-tab5/example/main/gui.hpp New Gui API for tab5 (gravity lines + brightness cycling + buttons).
components/m5stack-tab5/example/main/gui.cpp Implements tab5 GUI, gravity line updates, and brightness cycling.
components/esp32-p4-function-ev-board/example/main/gui.hpp New Gui API for P4 EV board (title + status + buttons + circles).
components/esp32-p4-function-ev-board/example/main/gui.cpp Implements P4 EV board GUI, event dispatch, and circle drawing.
components/esp32-p4-function-ev-board/example/main/esp32_p4_function_ev_board_example.cpp Refactors P4 EV board example main to use Gui for status and touch-to-draw.
components/esp-box/example/main/gui.hpp New Gui API for esp-box (gravity lines + buttons + circles).
components/esp-box/example/main/gui.cpp Implements esp-box GUI and gravity line vector remapping.
components/byte90/example/main/gui.hpp New Gui API for byte90 (label + circles + rotation).
components/byte90/example/main/gui.cpp Implements byte90 GUI and circle drawing.
components/byte90/example/main/byte90_example.cpp Refactors byte90 example main to use Gui.

Comment thread components/ws-s3-geek/example/main/ws_s3_geek_example.cpp
Comment thread components/wrover-kit/example/main/wrover_kit_example.cpp
Comment thread components/t-dongle-s3/example/main/t_dongle_s3_example.cpp
Comment thread components/ws-s3-lcd-1-47/example/main/ws_s3_lcd_1_47_example.cpp
Comment thread components/ws-s3-geek/example/main/ws_s3_geek_example.cpp Outdated
Comment thread components/t-dongle-s3/example/main/t_dongle_s3_example.cpp Outdated
Comment thread components/ws-s3-touch/example/main/gui.cpp
Comment thread components/esp-box/example/main/gui.cpp
Comment thread components/m5stack-tab5/example/main/gui.cpp
Comment thread components/ws-s3-lcd-1-47/example/main/ws_s3_lcd_1_47_example.cpp Outdated
finger563 and others added 2 commits July 7, 2026 10:26
…tability

- Add <cmath> (and <numbers>) where math functions were used via transitive
  includes; replace non-standard M_PI with std::numbers::pi_v<float> and bare
  cos/sin with std::cos/std::sin in the circle-drawing examples
- Add <utility> where std::swap was used via transitive includes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@finger563 finger563 merged commit 35e120b into main Jul 7, 2026
120 checks passed
@finger563 finger563 deleted the feat/example-gui-classes branch July 7, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants