展示HN:面向Ada的现代GUI库——CSS样式、XML界面与SDL3

Hacker News Top 工具

摘要

Adi2是一个面向Ada的现代GUI库,提供CSS样式、基于XML的UI布局,并在SDL3上实现丰富内容渲染,同时支持WebAssembly和工具特性。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/08/24 16:49

ovenpasta/adi2 来源: https://github.com/ovenpasta/adi2

Adi2

一个用于 Ada 的现代 GUI 库。

Adi2 为您提供一个真正的控件工具包,具备开发者期望从现代 UI 技术栈中获得的所有特性:类似 CSS 的样式支持(支持实时重载)、声明式 XML 布局、动画效果、SVG 与 Lottie 图形、国际化以及资源打包——所有这些功能均基于 SDL3 以原生 Ada 代码实现。

现状: 已在生产环境中使用,但尚未发布稳定版本——不同版本间的 API 可能会发生变更。


为什么选择 Adi2?

  • 像 Web 一样为 UI 设置样式。 选择器、伪类、部件、过渡效果、渐变、盒阴影——全部使用熟悉的 .css 语法。编辑文件,保存,即可看到变更。开发过程中无需重新编译。更喜欢纯 Ada 代码?CSS 规则本质上就是 Style_Rules 的 Ada 聚合体——可以完全手写,无需额外步骤(参见下方代码片段)。
  • 以声明方式描述 UI——或者不采用声明方式。 在 XML 中编写 <button><stack><label> 等标签,让工具链生成清晰的 Ada 包,或者在 Ada 中通过基于句柄的构建器直接构造相同的控件树。两种方式最终都调用完全相同的 API;XML 生成器只是一种便利工具,而非必需品。
  • 渲染丰富内容。 内置的轻量级 HTML 视图控件可以渲染文档风格的标记语言,并支持级联样式。通过 SDL3_image 处理位图图像,通过内置的 plutosvg 处理 SVG,通过内置的 rlottie 处理 Lottie 动画。
  • 分发单个二进制文件。 将所有 CSS 文件、字体、图片、翻译文件和 SVG 精灵图打包进您的可执行文件中。运行时无需文件系统依赖。
  • 使用用户的语言。 兼容 Gettext 的国际化方案,支持复数形式、自动区域检测以及 .po → Ada 的编译。
  • 无需样板代码即可实现动画。 支持对 colorbackground-colorborder-colorborder-widthborder-radiuspaddingmarginopacitybox-shadowfont-size 进行 CSS 过渡——框架自动处理插值和计时。
  • 适配高 DPI 设备的单位。 布局使用 dp/dip,排版使用 rem,当需要精确表示一个渲染像素时使用 pix,而 px——根据是否调用 Set_Px_Maps_To_Dip 来决定是否跟随显示缩放比例。详见 docs/css_styling.md
  • 为工具链和自动化构建。 一个仅在开发阶段可用的 MCP 桥接器,允许编辑器和 AI 助手截取运行应用的屏幕截图、遍历控件树,并操控它——点击按钮、在输入框中输入内容、移动焦点、读取性能计数器。非常适合您选择的 AI 来编写端到端测试。
  • 可在浏览器中运行。 示例代码可通过 GNAT-LLVM 和 Emscripten 编译为 WebAssembly——在线体验 (https://pizzahack.eu/adi2/demo/),或查看 wasm/ 目录了解构建方式。

发布所需的成本

一个发布版本会将所有内容静态链接成一个不到 10 MB 的单一可执行文件——控件工具包、CSS 引擎、SVG 和 Lottie 渲染,全部包含在内。您打包的任何资源都会在此基础上增加其体积。它通过 SDL 的渲染器进行绘制,该渲染器绑定到宿主系统提供的任何图形 API:在 Windows 上是 Direct3D,在 macOS 上是 Metal,在支持的地方使用 Vulkan 或 OpenGL,软件渲染作为兜底方案。Windows XP 使用 Direct3D 9,而当前 Mac 使用 Metal,均来自相同的源代码。

Adi2QtFlutterElectron
发布大小<10 MB,单文件~15–30 MB 静态链接;否则需要随附一个 Qt 运行时~20 MB+,引擎加数据目录~100 MB+,捆绑 Chromium 和 Node
运行时自包含Qt 库和插件Flutter 引擎;在 Linux 上为 GTK3Chromium 和 Node
图形SDL 渲染器,包含软件后备GPU 或光栅化后端Skia 或 Impeller,需要 GPUGPU 栈和合成器
可移植性Windows XP+,macOS,Linux,WebAssemblyWindows 10+,macOS,Linux,移动端,嵌入式Windows 10+,macOS,Linux,移动端,WebWindows 10+,macOS,Linux
语言AdaC++DartJavaScript
内存安全已检查,确定性回收手动管理垃圾回收垃圾回收
样式CSSQSSDart 控件代码CSS

尺寸数据基于最小应用;您的应用会因自身代码和资源而增长。其他选项的体积换来了庞大的生态系统和多年的生产实践——Adi2 提供的权衡是,您只需交付一个单一文件,即使在那些已被其他工具放弃的硬件上也能运行。


截图

hello_example
hello_example

material_demo
material_demo

html_view_example
html_view_example

rlottie_example
rlottie_example

assets_example
assets_example

所有示例的完整截图集:docs/gallery.md。或在浏览器中自行运行:在线演示 (https://pizzahack.eu/adi2/demo/)。


快速体验

声明式路径 — XML + CSS

/* examples/css/hello_example.css */
.primary {
    background-color: rgb(37, 99, 235);
    border-radius: 8px;
    padding: 10px 16px;
    transition: background-color 150ms ease-out;
}
.primary:hover {
    background-color: rgb(29, 78, 216);
}
.primary::label {
    color: white;
    font-size: 14px;
    font-weight: 500;
}
<stack>
    <button class="primary">
        <label>Hello, world!</label>
    </button>
</stack>

工具链会生成一个类型化的 Ada 包,您可以在 main 中实例化它——完整的约 25 行程序请参见 examples/hello_example.adb

同样的事情,使用 Ada 手写实现

上面的 CSS 规则只是一个聚合体。XML 控件树也只是几个构造器调用。两种方式最终都使用相同的 API——完整的等效程序请参见 examples/hello_raw_example.adb。样式代码的结构如下:

function Style return Style_Builder renames Adi.Widget_Styles.Create;

-- 相当于 hello_example.css 中的 .primary 基础样式 + :hover 状态
Primary_Base : constant Style_Rules := (
    Background_Color => Set_Bg (RGB (37, 99, 235)),
    Border_Radius    => Set (Radius (Px (8.0))),
    Padding          => Set (CSS_Box (Px (10.0), Px (16.0))),
    Transition       => Set ((Duration => 0.15, Easing => Ease_Out,
                             Properties => Props (Prop_Background_Color))),
    others           => <>
);

Primary_Hover : constant Style_Rules := (
    Background_Color => Set_Bg (RGB (29, 78, 216)),
    others           => <>
);

-- 将基础样式和悬停样式绑定到按钮的 Main_Part
Set_Part_Style (Widget_Handle'(+Btn), Main_Part,
    Style.Base (Primary_Base).On_Hover (Primary_Hover).Build);

构建并运行任一版本:

tools/build_examples.sh hello_example hello_raw_example

./examples/bin/hello_example     # XML + CSS 流水线
./examples/bin/hello_raw_example # 纯手写 Ada

快速开始

# 构建库
alr build -- -j0

# 构建并运行测试套件
tools/run_tests.sh

# 构建所有示例程序
tools/build_examples.sh

# ...或仅构建一个
tools/build_examples.sh stack_example

# 试运行一个演示
./examples/bin/material_demo
./examples/bin/html_view_example

要在您自己的项目中使用 Adi2,只需添加 with "adi.gpr" 依赖——SDL 链接器选项已包含在内。库的公共规范使用了 Ada 2022 特性,因此引用 Adi.* 包的单元需要添加 pragma Ada_2022; 或使用编译选项 -gnat2022

开始您自己的项目? docs/getting_started.md 将引导您从一个空目录开始,分别用 XML/CSS 和纯 Ada 创建一个可工作的窗口。完整的构建说明(包括不使用 Alire 的构建方法),请参阅 docs/build.mddocs/gprbuild_without_alire.md


路线图

CSS。

  • 扩展 CSS 覆盖面 —— 更多标准属性、选择器和值。

HTML 视图。

  • 表格 —— tabletrtd/th、列宽、合并单元格。
  • Flexbox 和 Grid —— 在文档内使用 display: flexdisplay: grid

控件与主题。

  • 更多控件 —— 树状视图、数据网格、菜单栏、进度和忙碌指示器、工具提示、分割面板、日期和颜色选择器。
  • 现成主题 —— Material、Fluent、Adwaita 和 macOS 风格,每种均提供浅色和深色版本。

文本与可达性。

  • 从右到左和双向文本 —— direction 和双向文本重排。
  • 无障碍访问 —— 为屏幕阅读器提供语义化角色、名称和状态,通过 AT-SPI、UI Automation 和 NSAccessibility 实现。

可移植性。

  • 可插拔后端 —— 抽象层允许 Win32/Direct2D、Cocoa、GLFW、raylib 或 Skia 取代 SDL3(设计文档)。
  • 嵌入式设备

创作与工具链。

  • 可视化设计器 —— 类似 RAD IDE 的体验,同时编辑 UI XML 和 CSS。
  • 使用 HAC 进行脚本编写 —— 嵌入 HAC Ada 编译器,以实现可重载的应用逻辑。
  • XML UI 的实时重载 —— XML 控件树可像 CSS 一样热重载。
  • 更完善的生成文档 —— 使用 gnatdoc 生成可浏览的 API 文档。

正确性与 API。

  • 改进回调 —— 允许失败的回调让应用继续运行、一次性触发的回调,以及与 UI 安全通信的后台任务(设计文档)。
  • 契约 —— Pre/Post/Type_Invariant 和 SPARK 模式子集。
  • C API —— 为非 Ada 调用者提供稳定的、可 C 调用的接口。

有想法?请开启一个 issue(相关策略请参阅 CONTRIBUTING.md)。


支持的平台

已在 GNU/LinuxWindows(XP, 7, 8, 10, 11,通过 MinGW)、macOSWebAssembly(Emscripten)上测试。

任何其他支持 GNAT 和 SDL3 构建的环境都应该可以运行——包括 BSD 系列。渲染通过 SDL 渲染器抽象层进行,因此它会在有硬件加速的机器上使用加速,在没有的地方回退到软件渲染。正是这一点使得同一个二进制文件能在 Windows XP 和当前的桌面系统上运行。


问题解答

为什么叫 “Adi2”?为什么 Ada 包名仍然是 Adi.* “adi” 对搜索引擎来说太常见了——Adi2 更容易被找到。代码中的命名空间保持 Adi.* 是因为 with Adi.Widget.Button;Adi2.Widget.Button 读起来更顺畅,而且重命名它会给每个源文件带来无谓的变更,却没有任何功能上的收益。项目名称 = Adi2,包名 = Adi


相关演讲

《Ada 的原生、可移植 GUI 框架》 —— 第三届 Ada 开发者研讨会,AEiC 2026 (https://www.ada-europe.org/conference2026/workshop_adadev.html),2026年6月13日。构建一个 Adi2 应用,并通过 MCP 桥接器使用 LLM 操控运行中的 UI。
第一部分 (https://www.youtube.com/watch?v=d-RISfK9Sy8) · 第二部分 (https://www.youtube.com/watch?v=H8SMfI7dJfc)


深入了解

主题文档
您的第一个 Adi2 应用docs/getting_started.md
高层架构与核心组件docs/architecture.md
CSS 样式 — 选择器、属性、运行时 API、代码生成docs/css_styling.md
声明式 XML UI 与控件语法docs/xml_ui_system.md
HTML 视图控件规范docs/html_view_spec.md
静态资源打包(单二进制分发)docs/static_assets.md
国际化、复数形式、.po 编译docs/i18n.md
设置存储与 JSON 后端docs/settings.md
操作系统集成 — 对话框、剪贴板、路径docs/os_integration.md
信号与延迟派发docs/signals.md
抗锯齿渲染原语docs/rendering_aa.md
MCP 运行时内省与交互docs/mcp.md
句柄所有权模型docs/handle_ownership.md
编码规范docs/coding_conventions.md
添加 CSS 属性 / 示例 / 测试docs/adding_css_property.md, docs/adding_example.md, docs/adding_test.md

贡献

欢迎提交 issue 和拉取请求。 对于小修复以外的贡献,请先开启一个 issue 讨论方案,然后再投入时间编写代码。请遵循现有的代码风格(docs/coding_conventions.md),保持测试通过,并为新增功能添加测试。除非您明确声明,否则提交的贡献将被视为在 Apache-2.0 许可证下发布,依据其第 5 条——无需签署 CLA。详细信息请参阅 CONTRIBUTING.md


赞助

Adi2 是独立开发和维护的。赞助资金用于支持持续维护、跨平台测试、文档编写以及公共路线图上的工作。有兴趣支持本项目或资助特定功能、移植或集成的组织:[email protected]

赞助支持的是项目整体。如需保证响应时间或交付承诺,需要签订单独的商业协议。


许可证

Apache-2.0。详见 LICENSE

vendor/ 目录下的第三方代码保留其原始许可证,许可证文件列在各自子目录中。大部分是宽松许可证——MIT、Apache-2.0、BSD 风格、OFL。

vendor/rlottie/src/vector/vinterpolator.cpp 是 MPL-2.0,这是一个文件级别的 Copyleft 许可证,而非宽松许可证;其文本发布在 vendor/rlottie/licenses/COPYING.MPL

examples/assets/ 下的示例资源是演示内容,并非库的一部分;其中涉及已知第三方条款的内容已在 examples/assets/NOTICE.md 中注明。


联系方式

Adi2 由 Aldo Nicolas Bruno 编写。请通过 issue 跟踪器报告错误和建议功能。私信咨询、赞助开发或商业支持:[email protected]

相似文章

Show HN:一个ASCII 3D渲染引擎

Hacker News Top

GlyphCSS是一个JavaScript库,它使用ASCII字符在DOM中渲染带纹理的3D网格,支持多种3D格式,并与原生JS、React和Vue集成。

Show HN:一个CSS 3D引擎(无需WebGL)

Hacker News Top

PolyCSS 是一个 CSS 多边形网格库,能将 3D 模型渲染为真实的 HTML 元素(使用 CSS matrix3d),支持 OBJ/MTL、GLB 和 VOX 格式,可与 React、Vue 或原生 JavaScript 配合使用。

Gsxui – 适用于 Go 的 Shadcn 风格组件

Hacker News Top

Gsxui 是一套面向 Go 的 Shadcn 风格组件集,支持复制集成、类型检查且使用 Tailwind 样式化的服务器端渲染 UI 组件。它提供了用于初始化和添加组件的 CLI。