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.
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.
Recommended options:
- If
simulator/SDL2-2.0.12exists, zedgui will try to use it for the SDL2 demo. The commonSDL2-devel-2.0.12-mingw.tar.gzpackage is a MinGW package, so configure with a MinGW compiler:
cmake -S . -B build-mingw -G Ninja -DCMAKE_C_COMPILER=gcc
cmake --build build-mingwIf 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.
Debian/Ubuntu:
sudo apt install libsdl2-dev cmake build-essential
cmake -S . -B build
cmake --build buildFedora:
sudo dnf install SDL2-devel cmake gcc
cmake -S . -B build
cmake --build build./build/simulator/sdl2/zedgui_sdl2_demoOn Windows, run:
build\simulator\sdl2\Debug\zedgui_sdl2_demo.exeor the matching Release path for your generator.
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.
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.
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_COLUMNSupported alignment values:
ZED_ALIGN_START
ZED_ALIGN_CENTER
ZED_ALIGN_END
ZED_ALIGN_SPACE_BETWEEN
ZED_ALIGN_STRETCHThe layout pass runs inside zed_timer_handler() before drawing. Objects without a layout keep their manually assigned coordinates.
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.
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_5x7Current 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);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_ledCurrent converter limits:
- PPM
P3andP6input - 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.
- 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, orfree. 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, andzed_image_t/zed_img_tare stable enough for the next JSON DSL and C CodeGen pass.
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.
- 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.