mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-10-17 10:55:06 +00:00
3.3 KiB
3.3 KiB
Architecture: LVGL
User interfaces should scale well for everything between very large (e.g. 1280x720) and small (e.g. 135x240) displays. Vertical and horizontal layouts are supported.
Margins and padding are set in density-independent pixels with LV_DPX(), not in raw pixels.
Two kernel modules cover LVGL:
lvgl-module(Modules/lvgl-module/,<lvgl/*.h>) owns LVGL's lifecycle: init/deinit, the LVGL task loop, andlvgl_lock()/lvgl_try_lock()/lvgl_unlock()mutex-based locking that any task must hold before touching LVGL objects. It bridges Tactility's device model to LVGL indevs (lvgl/devices/*.h:display,pointer,keyboard,trackball), and provides shared fonts (lvgl/fonts.h: Montserrat text sizes, Material Symbols icon sets for statusbar/launcher/shared use) and a few shared widgets (lvgl/widgets/*.h:toolbar,spinner,sliderbox).lvgl-window-manager-module(Modules/lvgl-window-manager-module/,<lvgl_window_manager/*.h>) manages a single stacked window per app instance on top oflvgl-module.window_manager_start()/window_manager_stop()create/tear down the root widget (plus optional chrome from a configuredWindowManagerScreenInitFn);window_manager_create()/window_manager_remove()push/pop an app's window and (re)populate it via aWindowCreateWidgetsFn. Only the topmost window ever has live widgets - burying and resurfacing a window deletes and rebuilds its widget tree rather than hiding/showing it. That rebuild-on-remove path can runcreate_widgetson a different app's thread (whichever app'swindow_manager_remove()call caused this window to resurface), socreate_widgetsmust only rebuild already-committed state, never decide what happens next - state transitions belong in the app's ownmain()event loop, driven by realAPP_EVENT_RESULTs. Widget pointers an app keeps become dangling once its window is buried (e.g. by a dialog it started). Usewindow_manager_create_ext()with adestroy_widgetscallback that clears them, and skip widget updates from the app's own thread while they're cleared.
Keyboard navigation
- Put groups of related focusable widgets (pills/chips, rows of buttons, toggle tiles) in a grid navigation container with
lvgl_grid_navigation_add()(lvgl/grid_navigation.h). Only the container joins the input group: left/right moves within the group and up/down moves between groups. - Never make checkable widgets (switches, checkable buttons) direct input group members: LVGL toggles them on arrow keys. Grid navigation forwards only Enter to them.
Theming (LSS)
The themes in Modules/lvgl-module/source/themes/lv_theme_material*.c/.h are generated: never edit them directly. They're compiled from the LVGL Style Sheets in Modules/lvgl-module/themes/*.lss by the LSS tool, a git submodule at Modules/lvgl-module/lss/ (see its README.md for the syntax).
- Styles are defined once and attached to widget types with
apply(<widget>) { <style>: <state/part>; }rules. Custom widget classes oflvgl-module(e.g.lvgl_card_class) are declared with@widget <name>: <class>;. - Change
material.lssandmaterial_mono.lsstogether, then regenerate (requirespip install lark):
cd Modules/lvgl-module
python lss/compile.py themes/material.lss --output source/themes
python lss/compile.py themes/material_mono.lss --output source/themes