Skip to content

SmartDao/zedgui

Repository files navigation

zedgui

zedgui is a small C99 embedded GUI framework for MCU, bare-metal, RTOS, small LCDs, and SDL2 desktop simulation. It borrows proven ideas from object trees, events, styles, and themes, but keeps the first version intentionally small and readable.

V2.0 SDL2 demo

V4.1 AA rendering

V4.0 records the AI Embedded UI Studio foundation as a platform status checkpoint:

AI Brief -> AI Handoff Packet -> Designer Model -> JSON DSL -> C CodeGen -> MCU Port Template

It is not a stable production release claim. The implemented baseline is the core runtime, basic JSON DSL loader, basic zedgui C CodeGen, SDL2 demo source path, generated-C syntax/build smoke path, and basic part/state style API. Real hardware validation, complete Designer UX, production multi-target CodeGen, AI quality pipeline validation, and export package hardening remain pending.

Architecture

  • include/: public C API.
  • src/core/: object pool, object tree, events, input, refresh.
  • src/core/zed_layout.c: minimal row/column layout with padding, gap, align, and flex grow.
  • src/draw/: pixels, lines, rectangles, rounded rectangles, text, bars, switches, clipping.
  • src/style/: style and theme definitions.
  • src/widgets/: panel, label, button, bar, switch.
  • ports/: MCU display/input integration templates.
  • simulator/sdl2/: SDL2 display/input port and PC demo.
  • examples/simple_demo/: reusable demo UI creation code.
  • tools/: Designer model, CodeGen, resources, performance, export, Studio, and stabilization checks.
  • tests/: non-SDL smoke targets for generated C.

The core library does not include SDL2 headers. SDL2 is only used by simulator/sdl2.

The V3.1 architecture notes are in:

docs/ARCHITECTURE.md
docs/RELEASE_CHECKLIST.md
docs/RELEASE_STATUS.md
docs/RELEASE_HISTORY.md
docs/platform/V4.0_AI_EMBEDDED_UI_PLATFORM.md

Build

Default Core Build

The default CMake path is core-only and does not require SDL2:

cmake -S . -B build_core -DZED_BUILD_SDL2_SIMULATOR=OFF
cmake --build build_core
ctest --test-dir build_core

Windows SDL2 Preview

Recommended options:

  • The SDL2 simulator is opt-in. If simulator/SDL2-2.0.12 exists, the common SDL2-devel-2.0.12-mingw.tar.gz package is a MinGW package, so configure with a MinGW compiler:
cmake -S . -B build-mingw -G Ninja -DCMAKE_C_COMPILER=gcc -DZED_BUILD_SDL2_SIMULATOR=ON
cmake --build build-mingw

If your default generator is Visual Studio, this MinGW SDL2 package cannot be linked by MSVC. Install an MSVC SDL2 development package or build with MinGW.

  • Install SDL2 with vcpkg:
vcpkg install sdl2
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake -DZED_BUILD_SDL2_SIMULATOR=ON
cmake --build build
  • Or install SDL2 development package manually and expose it through CMAKE_PREFIX_PATH.

Linux

Debian/Ubuntu:

sudo apt install libsdl2-dev cmake build-essential
cmake -S . -B build -DZED_BUILD_SDL2_SIMULATOR=ON
cmake --build build

Fedora:

sudo dnf install SDL2-devel cmake gcc
cmake -S . -B build -DZED_BUILD_SDL2_SIMULATOR=ON
cmake --build build

Run

./build/simulator/sdl2/zedgui_sdl2_demo

On Windows, run:

build\simulator\sdl2\Debug\zedgui_sdl2_demo.exe

or the matching Release path for your generator.

V3.1 Stabilization Checks

Run the architecture and example contract scan:

python tools/test/zed_v31_scan.py

Build the non-SDL generated-C smoke target:

cmake -S . -B D:/tmp/zedgui_v31_smoke -DZEDGUI_BUILD_SDL2_DEMO=OFF -DZEDGUI_BUILD_MCU_RGB565_SIM=OFF -DZEDGUI_BUILD_EXAMPLE_SMOKE=ON
cmake --build D:/tmp/zedgui_v31_smoke --config Debug

This target compiles and runs examples/simple_demo/demo_ui_generated.c without SDL2.

VS Code / CMake Tools

The default CMake configure path is core-only and does not require SDL2:

cmake -S . -B build_core
cmake --build build_core
ctest --test-dir build_core

Enable SDL2 previews explicitly when the host has a compiler-compatible SDL2 package:

cmake -S . -B build_sdl -DZED_BUILD_SDL2_SIMULATOR=ON

On Windows, the bundled simulator/SDL2-2.0.12 package is MinGW-oriented. Leave SDL2 simulator builds disabled for the default MSVC CMake Tools configure, or install an MSVC-compatible SDL2 package.

V4.0 Platform Checks

V4.0 uses the same stabilization scan and adds release-asset coverage for the platform docs and Studio manifest. Treat these as checkpoint checks, not proof of production readiness:

python tools/test/zed_v31_scan.py

Representative performance checks:

python tools/perf/zed_perf_analyze.py examples/simple_demo/demo_ui.json --spi-mhz 40
python tools/perf/zed_perf_analyze.py examples/widget_gallery/widget_gallery.json --spi-mhz 40
python tools/perf/zed_perf_analyze.py examples/templates/industry/energy_inverter/ui.json --spi-mhz 40

V4.1 Rendering Enhancement Checks

AA and alpha are compile-time optional:

cmake -S . -B D:/tmp/zedgui_v41_fast -DZEDGUI_BUILD_SDL2_DEMO=OFF -DZEDGUI_BUILD_MCU_RGB565_SIM=OFF -DZEDGUI_BUILD_EXAMPLE_SMOKE=ON -DZEDGUI_USE_ANTIALIAS=OFF -DZEDGUI_USE_ALPHA_BLEND=OFF
cmake --build D:/tmp/zedgui_v41_fast --config Debug

cmake -S . -B D:/tmp/zedgui_v41_aa -DZEDGUI_BUILD_SDL2_DEMO=OFF -DZEDGUI_BUILD_MCU_RGB565_SIM=OFF -DZEDGUI_BUILD_EXAMPLE_SMOKE=ON -DZEDGUI_USE_ANTIALIAS=ON -DZEDGUI_USE_ALPHA_BLEND=ON
cmake --build D:/tmp/zedgui_v41_aa --config Debug

The runtime macros are:

#define ZED_USE_ANTIALIAS     0
#define ZED_USE_ALPHA_BLEND   0

Use docs/designer/v4.1_aa_preview.md for SDL2, Studio, and MCU switching notes.

Code::Blocks SDL2 Demo

The repository includes a Code::Blocks project for the local MinGW SDL2 package:

simulator/codeblocks/zedgui_sdl2_demo.cbp

Open this file in Code::Blocks and select a GNU GCC / MinGW compiler. The project expects:

simulator/SDL2-2.0.12/x86_64-w64-mingw32

Build the Debug or Release target. The post-build step copies SDL2.dll into:

simulator/codeblocks/bin/Debug
simulator/codeblocks/bin/Release

If Code::Blocks reports missing gcc, install the Code::Blocks MinGW bundle or configure Settings -> Compiler -> Toolchain executables to point to your MinGW-w64 installation.

Theme Switching

Call one of these before creating widgets:

zed_theme_set(zed_theme_light());
zed_theme_set(zed_theme_dark());
zed_theme_set(zed_theme_blue_tech());
zed_theme_set(zed_theme_industrial());

The demo uses zed_theme_blue_tech() by default.

Minimal Layout

V0.2 adds a small layout layer for MCU-friendly automatic positioning:

zed_obj_set_layout(card, ZED_LAYOUT_COLUMN);
zed_obj_set_padding(card, 16, 16, 18, 14);
zed_obj_set_gap(card, 16);
zed_obj_set_align(card, ZED_ALIGN_START, ZED_ALIGN_STRETCH);

Supported layout modes:

ZED_LAYOUT_NONE
ZED_LAYOUT_ROW
ZED_LAYOUT_COLUMN

Supported alignment values:

ZED_ALIGN_START
ZED_ALIGN_CENTER
ZED_ALIGN_END
ZED_ALIGN_SPACE_BETWEEN
ZED_ALIGN_STRETCH

The layout pass runs inside zed_timer_handler() before drawing. Objects without a layout keep their manually assigned coordinates.

Dirty Area Refresh

V0.3 adds a small dirty-area refresh path. Core setters call zed_obj_invalidate() automatically, and the refresh handler redraws only dirty clips:

void zed_refr_invalidate_area(const zed_area_t *area);
void zed_refr_invalidate_full(void);

Display drivers can optionally implement region flushing:

static void lcd_flush_area(const zed_area_t *area, void *user_data);

disp.flush_area = lcd_flush_area;
disp.flush = lcd_flush_done;

If flush_area is NULL, zedgui still renders dirty clips into the framebuffer and calls flush() once. The SDL2 port uses this fallback because it presents a full texture.

Font Conversion

V0.4 exposes zed_font_t and adds a small BDF converter:

python tools/fontconv/zed_fontconv.py tools/fontconv/samples/demo_5x7.bdf D:/tmp/zed_font_demo.c --name zed_font_demo_5x7

Current converter limits:

  • monochrome BDF input
  • fixed-width output
  • font height up to 8 pixels
  • ASCII range 32-126 by default

Generated fonts can be attached through styles:

extern const zed_font_t zed_font_demo_5x7;

zed_style_t label_style;
zed_style_init(&label_style);
label_style.font = &zed_font_demo_5x7;
zed_obj_set_style(label, &label_style);

Image Conversion

V0.5 adds a minimal image asset format and PPM converter:

python tools/imgconv/zed_imgconv.py tools/imgconv/samples/status_led.ppm D:/tmp/zed_img_status_led.c --name zed_img_status_led

Current converter limits:

  • PPM P3 and P6 input
  • RGB888 output
  • no alpha channel
  • no compression

Generated images can be drawn directly:

extern const zed_image_t zed_img_status_led;
zed_draw_image(ctx, 10, 10, &zed_img_status_led);

zed_img_t is provided as a short alias for zed_image_t, intended for generated UI/resource code.

The runtime does not decode PNG/JPEG. Conversion happens on the PC, and the MCU draws simple C arrays from flash.

V0.5.1 API Review Notes

  • Core headers and sources do not include or call SDL2. SDL2 remains isolated in simulator/sdl2.
  • Core headers and sources do not use malloc, calloc, realloc, or free. The SDL2 simulator allocates its PC framebuffer in the port layer.
  • Dirty-area refresh uses a small fixed list controlled by ZED_MAX_DIRTY_AREAS; overflow merges areas into one larger redraw region.
  • Layout changes invalidate the owning layout container only when child geometry changes, which avoids stale pixels without forcing continuous redraw.
  • The public model types zed_obj_t, zed_style_t, zed_layout_t, zed_font_t, and zed_image_t/zed_img_t are stable enough for the next JSON DSL and C CodeGen pass.

JSON DSL

V0.6 adds a minimal JSON DSL loader. It is dependency-free, allocation-free, and maps directly to the current C API:

static zed_event_cb_t resolve_event(const char *name)
{
    if(strcmp(name, "onClick_start") == 0) return on_start_clicked;
    return NULL;
}

zed_dsl_resolver_t resolver = {
    .event_cb = resolve_event,
    .font = NULL,
    .image = NULL,
};

zed_obj_t *screen = NULL;
zed_dsl_load_json(json_text, &resolver, &screen);

Supported concepts:

  • stable object id / var names for future CodeGen
  • event names such as onClick_start
  • resource names such as "font": "6x8_default" and "image": "status_led" reserved for CodeGen
  • pos, size, layout, padding, gap, align_main, align_cross
  • widget fields: text, value, checked, muted, hidden, disabled

The schema reference is in:

docs/dsl/v0.6_schema.md

The CodeGen compatibility table is in:

docs/dsl/v0.6.1_field_compat.md

The parser is intentionally small. In V0.6, each widget object should put type before fields that need an object instance.

C Code Generation

V0.7 adds a PC-side C generator for JSON DSL files:

python tools/codegen/zed_codegen.py examples/simple_demo/demo_ui.json D:/tmp/zed_demo_generated.c --function zed_demo_generated_create

The generator emits C99 that uses public zedgui APIs:

  • parent objects before child objects
  • stable variable names from var or id
  • zed_obj_set_id() calls for object lookup/debugging
  • empty event callback stubs
  • extern declarations for font/image resources

The CodeGen notes are in:

docs/codegen/v0.7_codegen.md

The V0.7.1 CodeGen review is in:

docs/codegen/v0.7.1_review.md

Widget/Style Polish

V0.8 adds lightweight part/state style overrides without dynamic allocation:

zed_obj_set_part_style(btn, ZED_PART_MAIN, ZED_STATE_PRESSED, &pressed_style);
zed_obj_set_part_style(bar, ZED_PART_INDICATOR, ZED_STATE_NORMAL, &indicator_style);
zed_obj_set_part_style(sw, ZED_PART_KNOB, ZED_STATE_NORMAL, &knob_style);

Supported part slots:

ZED_PART_MAIN
ZED_PART_INDICATOR
ZED_PART_KNOB

Supported main-state override slots:

ZED_STATE_NORMAL
ZED_STATE_PRESSED
ZED_STATE_DISABLED
ZED_STATE_CHECKED

Buttons use pressed/disabled styles, bars use main/indicator styles, and switches use main/checked/knob styles. The default theme still works when no override is provided.

V0.8.1 defines the JSON DSL and CodeGen contract for these overrides. DSL objects may use a styles array:

{
  "type": "button",
  "id": "start_btn",
  "styles": [
    { "part": "main", "state": "pressed", "style": "styles.button.primary_pressed" }
  ]
}

CodeGen maps the logical style resource name to a valid C symbol and emits:

extern const zed_style_t styles_button_primary_pressed;
zed_obj_set_part_style(start_btn, ZED_PART_MAIN, ZED_STATE_PRESSED, &styles_button_primary_pressed);

The runtime JSON loader is intentionally not a complex style loader. Application-owned C style resources remain the source of truth for generated UI code. The detailed contract is documented in:

docs/style/v0.8.1_style_dsl_codegen_contract.md

Replacing SDL2 With an MCU LCD Port

Implement zed_disp_drv_t for your LCD:

static void lcd_set_pixel(int x, int y, zed_color_t color, void *user_data);
static void lcd_fill_rect(const zed_area_t *area, zed_color_t color, void *user_data);
static void lcd_flush(void *user_data);

zed_disp_drv_t disp = {
    .hor_res = 320,
    .ver_res = 240,
    .user_data = lcd_ctx,
    .set_pixel = lcd_set_pixel,
    .fill_rect = lcd_fill_rect,
    .flush_area = lcd_flush_area,
    .flush = lcd_flush,
};
zed_disp_register(&disp);

Feed touch/key input through zed_input_proc(). The core never calls SDL2 directly.

MCU Port Template

V0.9.0 adds a board-neutral MCU port template:

ports/mcu_template/zed_port_mcu.h
ports/mcu_template/zed_port_mcu.c
examples/mcu_demo/
docs/PORTING_MCU.md

The template demonstrates:

  • RGB565 framebuffer storage.
  • Dirty rectangle flushing through zed_disp_drv_t.flush_area.
  • Optional partial-buffer copying for LCD drivers that need packed rectangles.
  • Touch/key polling that feeds zed_input_proc().
  • Generated C UI integration without SDL2 and without runtime JSON parsing.

Generate UI C on the PC, then add the generated file to the MCU project:

python tools/codegen/zed_codegen.py examples/simple_demo/demo_ui.json generated_ui.c --function zed_demo_generated_create

The MCU application calls zed_demo_generated_create() after registering the display driver.

V1.0 Workflow

V1.0 freezes the first end-to-end workflow:

JSON DSL -> SDL2 Preview -> C CodeGen -> Generated C Demo -> MCU Port Template

The workflow release note is in:

docs/V1.0_WORKFLOW_RELEASE.md

Alpha and Anti-Alias

V1.2 adds optional software alpha blending:

zed_draw_pixel_opa(ctx, x, y, color, 128);

Display drivers can implement get_pixel for true source-over blending. Rounded rectangles can opt in to 2x2 edge coverage with:

style.ext_flags |= ZED_STYLE_FLAG_ANTIALIAS;

Designer Model

V1.3 adds a PC-side designer project format:

*.zedui.json

Validate or convert it with:

python tools/designer/zed_designer_model.py validate examples/simple_demo/demo_project.zedui.json

V4.0.2 records the current Designer foundation as a Python CLI model tool. Its intended verification path is project validation, from-dsl, and to-dsl conversion, plus proof that exported DSL can be passed to tools/codegen/zed_codegen.py. In this environment the Python command chain was not verified because process spawning repeatedly failed with windows sandbox: spawn setup refresh. It is not a full visual editor.

Studio Prototype

V1.4 adds a dependency-free static HTML prototype:

tools/studio/index.html

Open it directly in a browser; no npm install, server, or backend is required. It opens .zedui.json, previews the UI on a canvas, displays the object tree, runs basic validation, and exports runtime/codegen JSON DSL.

Current limits:

  • No drag-and-drop editing.
  • No full property panel editing.
  • No undo/redo.
  • No integrated SDL2 launch.
  • No direct CodeGen execution inside Studio.
  • No production-ready Designer yet.

See docs/DESIGNER.md for current Designer model notes and limitations.

For the Studio beta workflow, use:

docs/STUDIO_USAGE.md
docs/V5.0_PRODUCTION_DESIGNER_BETA.md
examples/studio_demo_project/

Widget Gallery

V2.3 expands the embedded widget set and adds:

examples/widget_gallery/

The gallery covers image-capable controls, icon buttons, checkbox, radio, list, tab, popup/msgbox, slider, spacer, separator, and custom-widget hooks.

Resource Pipeline

V2.4 adds resource manifest generation:

python tools/resourcegen/zed_resourcegen.py examples/resources/demo_resources.json D:/tmp/zed_resources

It emits resources.h, resources.c, and resources_stats.json for MCU integration planning.

Performance Analysis

V2.5 adds runtime counters and a PC-side estimator:

python tools/perf/zed_perf_analyze.py examples/widget_gallery/widget_gallery.json --spi-mhz 40

Multi-Target CodeGen

V2.6 can generate basic UI code for multiple targets:

python tools/codegen/zed_multitarget_codegen.py examples/simple_demo/demo_ui.json D:/tmp/ui_lvgl.c --target lvgl

Project Export

V2.7 exports MCU project skeletons:

python tools/export/zed_project_export.py examples/simple_demo/demo_ui.json D:/tmp/zedgui_export

AI Embedded UI Studio

V3.0 defines the product foundation for zedgui Studio:

examples/studio/zedgui_studio_project.json
tools/studio/studio_manifest.json

It ties AI handoff, Designer projects, resources, events, CodeGen, MCU export, and performance analysis into one workflow.

V3.1 Stabilization

V3.1 is an engineering review stage. Its scope is to verify the existing V3.0 workflow rather than add new hardware ports, new Designer features, or expanded multi-target CodeGen.

Primary checks:

  • Core/runtime remains SDL2-free, heap-free, and file-system-free.
  • core, studio, designer, codegen, and ports boundaries remain explicit.
  • JSON DSL, Designer Model, and CodeGen supported widgets/themes stay aligned.
  • Generated example C is reproducible from committed JSON DSL.
  • Non-SDL generated-C smoke builds are available through CMake.

AI-Native Workflow

V2.0 adds a local AI handoff workflow:

AI Brief -> AI Handoff Packet -> Designer Model -> JSON DSL -> C CodeGen -> MCU Port Template

Start from:

examples/simple_demo/ai_ui_brief.md
examples/simple_demo/ai_workflow.zedai.json

The runtime stays C99 and does not depend on AI services.

MCU RGB565 Simulator

V0.9.1 adds an SDL2-hosted MCU rendering simulator:

simulator/mcu_rgb565_sim/

It uses the MCU port template, RGB565 framebuffer storage, dirty-area flush_area updates, and generated C UI. SDL2 is only the PC presentation shell; the zedgui display path is the MCU-style RGB565 path.

Roadmap

The version roadmap is maintained in:

ROADMAP.md

Platform checkpoints and partial stages:

  • V3.1: Stabilization and engineering review.
  • V3.2: Real hardware validation package documented; real-board validation remains pending.
  • V3.3: Industry template library examples exist; production validation remains pending.
  • V3.4: Resource and performance analysis tooling exists; MCU measurements remain pending.
  • V3.5: Multi-target CodeGen hardening is documented / partial.
  • V3.6: AI generation quality workflow is documented / pending validation.
  • V3.7: Designer experience is prototype / partial.
  • V3.8: MCU project export package is partial / pending hardening.
  • V4.0: AI Embedded UI Platform checkpoint, not a stable production release.

About

A minimal embedded C GUI framework with theme, layout, SDL2 simulator, font/image tools, and MCU-oriented rendering.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors