Skip to content

SmartDao/zedgui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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.

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.
  • simulator/sdl2/: SDL2 display/input port and PC demo.
  • examples/simple_demo/: reusable demo UI creation code.

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

Build

Windows

Recommended options:

  • If simulator/SDL2-2.0.12 exists, zedgui will try to use it for the SDL2 demo. 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
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
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
cmake --build build

Fedora:

sudo dnf install SDL2-devel cmake gcc
cmake -S . -B build
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.

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.

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.

Roadmap

  • V0.2: small layout system.
  • V0.3: dirty-area partial refresh.
  • V0.4: font converter.
  • V0.5: image converter.
  • V0.6: JSON DSL.
  • V0.7: C code generator.
  • V1.0: UI Designer.

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