Skip to content

Repository files navigation

fxtk — 轻量GUI框架 (v2.4)

📖 ENGLISH VERSION AVAILABLE AT docs_en/README_en.md

→ Read this README in English

version license c platform

一个 377KB 单文件、零第三方动态库的 C GUI 框架——ldd 里只有系统库,没有 SDL2.dll、没有 libwinpthread。同一份 fxtk.h 与同一套控件 API,PC 走 sokol(OpenGL)、ESP32 走纯 CPU 路径。 核心纯 C、480×272 响应式设计、属性宏建界面。

可当场验证:cd demo-main && make && ldd ./fxtk_sim —— 或见下方「为什么可能值得一用」。

注:本框架带脏区矩形合并的实现,但当前被 s_full=1 旁路、不生效,每次请求都是整帧重绘 (因此不残影,但也没有脏区优化)——详见「性能」一节与 fxtk.cfx_repaint_rect() 的注释。

画布与抗锯齿(v2.2 无头渲染示意图)

抗锯齿 fx_set_aa(1) 渐变 fx_fill_rect_gradient 自定义控件(仪表盘) 棋盘格(缩放安全)
aa gradient gauge checker

注:以上 v2.2 示意图由 demo-main/test/render_canvas.c 无头渲染(不加载字体),只展示图形/渐变/边缘平滑; 按钮文字、数值等标签在真实运行时有(渲染工具为保持无头把文字函数桩掉了)。完整含文字界面见下方 demo 截图。

完整演示(12 页)见下方 demo 截图: graph image rending texting

fxtk 演示

一段真实录制(非渲染动画):切页 → 图形页的伪 3D 模式 → 图片页拖动四角做真透视形变。

一句话:一套 fxtk.h + 属性宏,写出的界面在 PC 上是单文件、零第三方动态库(Linux 377KB / Windows 439KB), 在 ESP32 上是同一份 API 的纯 CPU 路径。1080P 下压测页 2820 个控件约 102–130 fps(无头软件渲染实测,见 make bench)。

为什么可能值得一用

  • 不想再打包几十 MB 的运行库:Windows 版是一个 exe 出门(objdump 里只有系统 DLL,没有 SDL2.dll、没有 libwinpthread)。
  • 拷过去就能跑:图片解码(PNG/JPEG/BMP/GIF/TGA/PNM)、PNG 截图、剪贴板、文件对话框、随机数、时间、偏好持久化全在框架内,无外部依赖。
  • 两端一套 API:PC 默认接 sokol(OpenGL),ESP32 走纯 CPU;两端只保证"语法一致 + 渲染效果一致",PC 端不迁就嵌入式资源约束。
  • 自带验证体系make test(同一套断言在真实 OS 服务stub 确定性后端各跑一遍)、 make golden(金图逐像素回归)、make esp32-smoke(假 IDF 头做语法级检查)、make bench如实说明覆盖边界make test 用的是无头假驱动,它不渲染帧缓冲push_pixels 只累计像素数), 但 v2.4.4 起已补上颜色/几何契约断言(验证"框架让驱动画了什么")与离屏画布推送计数; 逐像素正确性仍靠 make golden 的金图。金图本地默认容差 0(逐像素), CI 里会跑,但用 GOLDEN_TOL=1 并跳过依赖 SDL/字体版本差异的演示页——即 CI 上不是逐像素口径。
  • 能改得动:所有控件的颜色/圆角/留白集中在 fxtk_tokens.h,换风格只改一个文件。

v2.4 新增

  • 默认后端换成 sokol(OpenGL), SDL2 降为遗留对照。因此 Windows 版是单 exe、无第三方 DLL; SDL 代码保留只为"无头假驱动"给基准与金图回归用(CI 没有显示器)。
  • GPU 真透视四边形形变 fx_draw_image_quad():每角透视权重进 gl_Position.w, 单次 draw 即透视正确 —— 没有"两个三角形各做仿射"的对角缝。图片页可直接玩:导入 → 缩放 → 拖四角手柄 → 复位。
  • 伪 3D 演示(图形页第 4 模式):地板/天花板、走廊砖墙、旋转纹理立方体、公告板精灵全部由四边形形变拼出, HUD 显示四边形数 / fps / 走的哪条路径。
  • GPU 实时光线步进 fx_raymarch_available() / fx_draw_raymarch():片元着色器直接算, 不占 CPU 像素、不回读。
  • 设计令牌 components/fxtk/fxtk_tokens.h:控件颜色/圆角/留白集中一处, 改一处即可统一换肤。
  • 后端服务层 fxtk_backends.h:随机(PCG32 可复现)/时间/路径/文件/图片解码(PNG·JPEG·BMP·GIF·TGA·PNM)/ PNG 编码/剪贴板/文件对话框/偏好/能力协商;-DFXTK_BACKEND_STUB 提供确定性变体。
  • canvas 变换栈 fx_canvas_push_affine/pop_affine + fx_fill_quad:push 后矩形填充变实心四边形、图片走透视。
  • 验证体系:make test(真实/stub 两种 OS 服务后端, 无头假驱动、不含像素断言)/ make golden(金图, 本地容差 0; CI 上 GOLDEN_TOL=1 并跳过演示页)/ make esp32-smoke(语法级)/ make bench; 截图 fx_screenshot() 走驱动的 read_pixels, 零外部依赖。
  • 注意:控件层 SDF 抗锯齿默认开启(s_widget_aa = 1);要对比或排查观感用 fx_set_widget_aa(0/1/2) —— 它在"画布 + 文字 + quadwarp 混排"场景下有一个已知缺陷正在修(详见 CHANGELOG v2.4.1)。

已知限制

  • 中文输入(输入法)在 sokol 版不可用 —— v2.4.1 已解决:给 vendored sokol_app 的 X11 后端补了 XIM 支持(惰性 XOpenIM/XCreateIC + setlocale + XSetLocaleModifiers + 事件循环里的 XFilterEvent + Xutf8LookupString),现在 fcitx5/ibus 等输入法在 sokol 版可正常组字。实测(本机 fcitx5 + rime): 输入框里打 nihao → 上屏"你好" ✓。
  • 控件层 SDF 抗锯齿是默认开启的(s_widget_aa = 1):v2.4.1 曾因"画布 + 文字 + quadwarp 混排"下 实心填充退化成边界环而临时默认关闭, v2.4.2 修好混排后已恢复默认开启,逻辑见 fxtk_draw.c。 需要对比性能或排查观感时可用 fx_set_widget_aa(0/1/2);注意 FXTK_AA=0|1|2 这个环境变量 只由演示程序 demo-main/app.c 读取,你自己的应用里设它不生效(请直接调 fx_set_widget_aa)。

两个目标端:已分化,只要求"语法一致 + 效果一致"

fxtk 起于 ESP32 端(esp32(测试) → fxtk-pc(v1.0) → esp32-fxtk(自 PC v1.0 搬运)), 但两端现在已高度分化,因此方针是:

  • PC 端不必迁就 ESP 的资源约束。PC 有几百 MB 内存和 GPU,硬把"零动态分配/极小静态池"搬到 PC, 换来的是"列表开多了就滚不动"这类人为 bug,不是优点。
  • 只保证两条:① API 与语法一致(同一份 fxtk.h,同一套控件宏与回调约定); ② 渲染效果一致(同样的控件、同样的坐标,两端画出来是一个东西)。
  • 具体体现:并发资源在 PC 上给足并可按需调大(FX_MAX_SCROLL_STATES / FX_MAX_EXTRA_WIDGETS 在 PC 上默认 64,在 ESP32 上仍是 8);热路径允许 PC 侧按需分配 (如粒子缓冲 pt_reserve() 就地扩容);ESP 端保留纯 CPU 绘制路径,PC 端默认走 GPU。
  • 不是"把单片机的紧箍咒套在 PC 上",而是"一套 API 两端跑":PC 端负责快与好用,ESP 端负责小与稳。

能做什么

  • 控件:按钮 / 标签 / 滑条 / 进度条 / 复选框 / 网格键盘 / 画布 / 标签页 / 图片 / 输入框 / 列表 / 下拉 / 滚动容器 / 卡片
  • 布局pixel()(480×272 设计坐标,窗口响应式等比缩放)/ percent() / grid()
  • 开箱默认配色:不写 color() 也能直接看;想统一换风格改 fxtk_tokens.h 一个文件
  • 画布(立即模式):线/圆/椭圆/三角/多边形/圆弧/圆角矩形/文字/渐变,支持离屏缓冲与抗锯齿 (fx_set_aa(1);开启后该画布自动走离屏)
  • 输入:文本编辑(换行、跨行框选、Ctrl+A/C/V/X 系统剪贴板、字数上限)、滚轮路由、 带动画的滚动(目标值逐帧逼近,静止时零重绘)、滚动条拖拽(含自绘画布)、焦点管理
  • 渲染fx_image_* 24bit 表面、旋转贴图、图像后处理(翻转/灰度/染色/亮度)、 多线程软件 Raymarching(SDF 软阴影/AO/雾)+ 可选 GPU(GLSL) 通道
  • 性能:GPU 顶点批、行级持久线程池光追;1080P 压测页 2820 控件约 102–130 fps(实测区间)
    • 说明:当前每次请求都是整帧重绘(脏区合并未启用,见本文档开头「注」)—— 该帧率是整帧重建口径下的读数
  • 工程化:统一 Makefile(单一源清单)、无头单测、金图回归、GitHub CI(Linux + Windows 交叉 + ESP32 冒烟)
  • 体积裁剪-DFXTK_WIDGET_XXX=0 编译期裁掉用不到的控件(受限平台用);tools/autotrim.sh 自动扫描并生成开关
  • 跨平台文件 APIfx_fs_pick_dir() / fx_fs_list(),演示里是完整的文件浏览器

目录结构

components/fxtk/   框架本体 (fxtk.c/draw/widgets/effects/extra/backends + 头文件;读代码先看这里)
drivers/           后端驱动 (sokol 驱动 + stb 文本层 + 应用外壳 + 各自的 main;SDL2 驱动为遗留对照)
your_app/          从这里开始写你自己的应用 (最小示例 + build.sh/build_win.sh;不参与主构建)
demo-main/         PC 演示与工具链 (12 页演示 app / GPU 光追 / examples / 统一 Makefile)
demo-main/test/    无头单元测试与基准 (无需窗口)
examples/          独立示例 ex01~ex18
examples/canvas/   画布学习教程 (canvas_01 ~ canvas_10)
third_party/       vendored 依赖 (sokol 头文件 1.9MB,含本项目为 X11 输入法所做的本地修改;stb 在 components/fxtk/vendor)
docs/              中文文档 (quickstart / guide / api / desktop / effects / examples / internals / backends)
docs_en/           英文文档 (结构与 docs/ 对应)
test/golden/       金图回归参考图 (逐像素比对,容差 0)
tools/             开发工具 (autotrim / esp32_smoke / golden / package_release)
.github/           CI (Linux 构建 + 测试 + Windows 交叉)
screenshot_*.png   画布/抗锯齿/渐变示意图
CHANGELOG.md       按版本记录变更 (含根因与实测数字)
LICENSE            MIT 许可 (第三方许可见各 vendored 文件头部)

快速开始 (Linux)

# 必要依赖: X11/Xcursor + GL —— 默认后端是 sokol, 不依赖 SDL2
sudo apt install libx11-dev libxcursor-dev libxi-dev libgl1-mesa-dev
cd demo-main
./build.sh                # 编译并运行完整演示 (12 个标签页, 默认 sokol)
./build.sh --sdl          # 遗留 SDL 版(需要 SDL2 全家桶), 仅作对照
./build_ex.sh ex01_hello  # 运行独立示例
make package              # 打发布包(源码 + Linux/Win 产物) → dist/pkg/

也可以用统一入口 Makefile(单一源清单):

cd demo-main
make                       # 构建完整演示 fxtk_sim (sokol, 单文件)
make fxtk_sim_en           # 英文版
make test                  # 无头单元测试: 真实后端 + stub 后端各一遍
make golden                # 金图回归(画布示例; 本地容差 0, CI 用 GOLDEN_TOL=1)
make esp32-smoke           # ESP32 接口级编译冒烟(不需要 ESP-IDF 工具链)
make bench                 # 渲染吞吐基准(无头, 无 vsync)
make shared                # 打包成动态库(exe 只留 app 层, 体积更小)
make ex01_hello            # 构建指定示例
make clean

测试与 CI

  • 无头单元测试 demo-main/test/headless_test.c 用一个假 fx_driver_t 直接驱动核心库, 验证 pixel/percent/grid 布局press/release 命中回调value 读写控件计数fx_find/fx_delete,不初始化 SDL/窗口/字体。
  • 回归与冒烟:tools/golden.sh(金图逐像素)、tools/esp32_smoke.sh(ESP32 接口级)、 tools/package_release.sh(发布打包)、tools/gallery.sh(截图画廊)。
  • CI (.github/workflows/ci.yml) 三个 job:Linux(构建 + 单测 + 示例 + 画布金图)、 windows-cross(交叉编译单 exe)、esp32-smoke(接口级冒烟)。

演示页速览

波形(动画画布) / 图形(矢量动效 + 第 4 模式: 伪 3D 场景) / 控件(网格键盘 + 卡片容器) / 图片(导入图片 + 缩放 + 四角手柄做真透视形变) / 3D(GPU 片元着色器光追, HUD 显示走 GPU 还是 CPU) / 输入(文本框全家套) / 画板(鼠标作画) / 键鼠(事件监视) / 压测(动态控件生长) / 滚动(长列表+滚动条) / 组件(文件浏览器/名字编辑器/可拖动组件/颜色选择器) / 粒子(万级图元)

发布

cd demo-main && make package     # 或 ../tools/package_release.sh
# → dist/pkg/fxtk-<版本>-src.tar.gz          纯源码(git archive, 无产物) → 传 GitHub
#   dist/pkg/fxtk-<版本>-linux-x86_64.tar.gz 中英双语单文件 + 文档 + 展示图
#   dist/pkg/fxtk-<版本>-win-x86_64.zip      中英双语单 exe(无第三方 DLL)
#   dist/pkg/fxtk-<版本>-linux-shared.tar.gz exe + libfxtk.so + libfxtk_sokol.so

文档

许可

MIT(示例与文档同许可)。全文见 LICENSE

后端策略(v2.4 起)

sokol 是默认且唯一在演进的 PC 后端,SDL2 降为遗留:

目标 后端 用途
make / make fxtk_sim sokol(OpenGL) 默认演示程序;新功能只往这里加
make fxtk_sim_en sokol 英文版
make sokol sokol fxtk_sim 的别名(旧脚本兼容)
make fxtk_sim_sdl / _sdl_en SDL2(遗留) 仅用于对照与过渡,不再加新功能

为什么 SDL 代码还留着test/bench(性能基准)与 tools/golden.sh(金图回归)需要 无显示器的确定性渲染,SDL 的 SDL_VIDEODRIVER=dummy 正好提供这个能力;而 sokol 需要真实 GL 上下文,CI 里起不来。所以 SDL 驱动现在只当"无头假驱动"用,发布产物一律走 sokol (也正因如此,Windows 版才能做到单 exe 无第三方 DLL)。

About

A lightweight-gui framework only 377kb without dependencies 轻量通用图形库,使用了AI进行了部分编写

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages