1. 快速安装与配置 #
moon-egui 采用纯 MoonBit 编写,无任何 C 语言或浏览器 DOM 依赖。可直接通过官方包管理器引入并在 WebAssembly / Canvas 2D 或桌面平台运行。
moon add LING71671/moon-egui
在你的模块 moon.pkg.json 中声明对 moon-egui/core 的导入:
{
"import": [
"LING71671/moon-egui/core"
]
}
ui.button(...) 被调用时,即刻完成布局度量、鼠标碰撞检测、绘制指令排队,并直接返回 Response 响应结构。
2. 极简 Hello World 示范 #
仅需数行声明式代码,即可在指定视窗内运行带状态记忆的计数器与滑块:
struct AppState {
mut count : Int
mut speed : Double
}
pub fn render_app(ui : @core.UIContext, state : AppState) -> Unit {
ui.window("快速控制台", @core.Vec2::new(40.0, 40.0), @core.Vec2::new(300.0, 240.0), fn(win) {
win.label("当前点击次数: " + state.count.to_string())
if win.button_primary("点击增加 (+1)").clicked() {
state.count += 1
}
win.separator()
let (new_val, _) = win.slider("渲染速度", state.speed, 0.0, 100.0)
state.speed = new_val
})
}
3. 宿主渲染循环接入 #
引擎为平台无关架构,每帧通过 RawInput 传入当前帧时间、指针坐标、滚轮与修饰键,并在求值后输出 DrawList 矢量绘制图元供宿主执行渲染:
function frame(timestamp) {
// 1. 执行 MoonBit Wasm 导出的帧函数
const drawList = window.moon_step(mouseX, mouseY, isMouseDown, deltaTime);
// 2. 在 Canvas 2D 上批量分发 DrawCmd
dispatchDrawCommands(ctx, drawList);
// 3. 驱动下一帧渲染
requestAnimationFrame(frame);
}
4. 核心数学与几何模型 #
4.1 2D 向量与坐标点 (`Vec2`)
二维单精度/双精度坐标容器,提供完整的向量平移与欧式距离计算:
pub struct Vec2 { x : Double; y : Double }
fn Vec2::new(x : Double, y : Double) -> Vec2
fn Vec2::zero() -> Vec2
fn Vec2::add(self : Vec2, other : Vec2) -> Vec2
fn Vec2::sub(self : Vec2, other : Vec2) -> Vec2
fn Vec2::scale(self : Vec2, factor : Double) -> Vec2
fn Vec2::dist(self : Vec2, other : Vec2) -> Double
4.2 轴对齐外接矩形 (`Rect`)
所有控件尺寸与命中判定(Hit-testing)的基础数据结构:
pub struct Rect { x : Double; y : Double; w : Double; h : Double }
fn Rect::new(x : Double, y : Double, w : Double, h : Double) -> Rect
fn Rect::contains(self : Rect, pt : Vec2) -> Bool
fn Rect::intersects(self : Rect, other : Rect) -> Bool
fn Rect::intersect(self : Rect, other : Rect) -> Rect
fn Rect::expand(self : Rect, margin : Double) -> Rect
fn Rect::shrink(self : Rect, margin : Double) -> Rect
4.3 颜色模型 (`Color` - RGBA)
pub struct Color { r : Int; g : Int; b : Int; a : Int }
fn Color::rgb(r : Int, g : Int, b : Int) -> Color
fn Color::rgba(r : Int, g : Int, b : Int, a : Int) -> Color
fn Color::hex(hex_code : Int) -> Color
fn Color::with_alpha(self : Color, alpha : Int) -> Color
4.4 交互契约结构体 (`Response`)
任何可交互控件在执行后即刻产生一个富状态快照:
| 方法 / 字段 | 类型 | 说明 |
|---|---|---|
clicked() |
Bool | 当前帧指针在控件外接矩形内完成按下并释放(完整点击) |
hovered() |
Bool | 当前指针处于该控件外接矩形内部,且未被前台遮罩遮挡 |
dragged() |
Bool | 当前正处于按住并移动拖拽状态中 |
double_clicked() |
Bool | 在双击时间窗口内完成连续两次点击命中 |
rect |
Rect | 该控件在当帧布局中锁定的全局外接矩形范围 |
5. 基础输入组件套件 #
5.1 Button 按钮套件
提供普通下压按钮、主行动点 CTA 强调按钮、小尺寸按钮以及快捷键集成按钮:
// 1. 标准按钮
if ui.button("确定保存").clicked() { ... }
// 2. 主行动点高亮按钮 (Primary CTA)
if ui.button_primary("立即编译").clicked() { ... }
// 3. 带快捷键徽标指示的按钮
if ui.button_with_shortcut("快速搜索", "Ctrl+P").clicked() { ... }
// 4. 紧凑型小按钮
if ui.button_small("+").clicked() { ... }
5.2 TextEdit 文本输入
支持即时光标定位、键盘文本录入、Backspace 退格、左右光标移动及双向绑定的单行/多行文本编辑框:
let (new_text, resp) = ui.text_edit(state.username, placeholder="请输入用户名...")
state.username = new_text
5.3 CodeEditor 代码编辑器
内置等宽行号显示、Tab 缩进与深色代码展示容器:
let (code, resp) = ui.code_editor(state.source_code, line_numbers=true)
state.source_code = code
5.4 文本展示与排版 (Label & Heading)
ui.heading("项目总览")
ui.label("普通状态描述文本")
ui.label_colored("运行正常", @core.Color::rgb(16, 185, 129))
6. 选择与数值调节组件 #
6.1 Slider 滑动条
支持连续型双精度浮点与离散整型滑动条,带微秒级平滑滚珠拖拽:
let (vol, _) = ui.slider("音量", state.volume, 0.0, 1.0)
state.volume = vol
let (samples, _) = ui.slider_int("采样率", state.samples, 1, 64)
state.samples = samples
6.2 DragValue Blender 风格数字微调
按住数值标签横向拖动即可平滑加减数值,支持指定拖拽步进速度:
let (focal, _) = ui.drag_value("焦距 (mm)", state.focal_length, speed=0.5, min=10.0, max=800.0)
state.focal_length = focal
6.3 Knob 360° 角度旋钮
直观的环形仪表角度控制器,非常适合音频合成与旋转角度参数调节:
let (angle, _) = ui.knob("旋转角度", state.rotation_deg, 0.0, 360.0)
state.rotation_deg = angle
6.4 Checkbox 与 Toggle 胶囊开关
let (sync, _) = ui.checkbox("启用垂直同步", state.vsync)
state.vsync = sync
let (wire, _) = ui.toggle("线框模式", state.wireframe)
state.wireframe = wire
6.5 ComboBox 下拉选择菜单
let options = ["WebGL 2.0", "Canvas 2D", "WebGPU"]
let (selected_idx, _) = ui.combo_box("图形后端", options, state.backend_idx)
state.backend_idx = selected_idx
6.6 ColorButton 颜色选择器
let (col, resp) = ui.color_button("画笔颜色", state.pen_color)
state.pen_color = col
7. 反馈与展示组件 #
7.1 ProgressBar 进度条
取值范围为 0.0 至 1.0,自动绘制平滑填充滑道:
ui.progress_bar(state.download_percent)
7.2 Spinner 加载动画
ui.spinner(size=18.0)
7.3 Badge 徽标与 Avatar 头像
ui.badge("PRO", @core.Color::rgb(37, 99, 235))
ui.avatar("LX", size=28.0)
7.4 Tooltip 悬浮信息提示
let resp = ui.button("危险操作")
resp.on_hover_text(ui, "此操作将立即清空当前缓存")
7.5 Toast 瞬态全局消息通知
ui.toast("文件已成功导出至本地", duration_sec=3.0)
10. 样式设计系统与高分屏适配 #
10.1 Studio Light 设计令牌 (Design Tokens)
moon-egui 采用精细校准的 Studio Light 素雅现代工业风。核心控件样式(圆角、内边距、高亮色)均封装在 WidgetStyle 中,支持在运行时无缝微调:
let style = ui.get_style()
style.rounding = 6.0
style.item_spacing = @core.Vec2::new(8.0, 6.0)
style.primary_color = @core.Color::rgb(37, 99, 235)
10.2 Retina 屏与设备物理像素对齐
为杜绝 Canvas 绘图在苹果 Retina 视网膜屏及高分屏下的模糊与毛刺,引擎内置 scale_factor(对齐 window.devicePixelRatio):
Separator 分割线与视窗边框)自动对齐在 x + 0.5 物理栅格坐标上,光栅化后纯净锐利、零子像素混叠发虚。