1. 快速安装与配置 #

moon-egui 采用纯 MoonBit 编写,无任何 C 语言或浏览器 DOM 依赖。可直接通过官方包管理器引入并在 WebAssembly / Canvas 2D 或桌面平台运行。

Terminal
moon add LING71671/moon-egui

在你的模块 moon.pkg.json 中声明对 moon-egui/core 的导入:

JSON · moon.pkg.json
{
  "import": [
    "LING71671/moon-egui/core"
  ]
}
即时模式核心概念
在即时模式中,界面不维护持久化的控件树。每帧当 ui.button(...) 被调用时,即刻完成布局度量、鼠标碰撞检测、绘制指令排队,并直接返回 Response 响应结构。

2. 极简 Hello World 示范 #

仅需数行声明式代码,即可在指定视窗内运行带状态记忆的计数器与滑块:

MoonBit
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 矢量绘制图元供宿主执行渲染:

JavaScript / Browser Host
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`)

二维单精度/双精度坐标容器,提供完整的向量平移与欧式距离计算:

MoonBit
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)的基础数据结构:

MoonBit
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)

MoonBit
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 强调按钮、小尺寸按钮以及快捷键集成按钮:

MoonBit
// 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 退格、左右光标移动及双向绑定的单行/多行文本编辑框:

MoonBit
let (new_text, resp) = ui.text_edit(state.username, placeholder="请输入用户名...")
state.username = new_text

5.3 CodeEditor 代码编辑器

内置等宽行号显示、Tab 缩进与深色代码展示容器:

MoonBit
let (code, resp) = ui.code_editor(state.source_code, line_numbers=true)
state.source_code = code

5.4 文本展示与排版 (Label & Heading)

MoonBit
ui.heading("项目总览")
ui.label("普通状态描述文本")
ui.label_colored("运行正常", @core.Color::rgb(16, 185, 129))

6. 选择与数值调节组件 #

6.1 Slider 滑动条

支持连续型双精度浮点与离散整型滑动条,带微秒级平滑滚珠拖拽:

MoonBit
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 风格数字微调

按住数值标签横向拖动即可平滑加减数值,支持指定拖拽步进速度:

MoonBit
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° 角度旋钮

直观的环形仪表角度控制器,非常适合音频合成与旋转角度参数调节:

MoonBit
let (angle, _) = ui.knob("旋转角度", state.rotation_deg, 0.0, 360.0)
state.rotation_deg = angle

6.4 Checkbox 与 Toggle 胶囊开关

MoonBit
let (sync, _) = ui.checkbox("启用垂直同步", state.vsync)
state.vsync = sync

let (wire, _) = ui.toggle("线框模式", state.wireframe)
state.wireframe = wire

6.5 ComboBox 下拉选择菜单

MoonBit
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 颜色选择器

MoonBit
let (col, resp) = ui.color_button("画笔颜色", state.pen_color)
state.pen_color = col

7. 反馈与展示组件 #

7.1 ProgressBar 进度条

取值范围为 0.01.0,自动绘制平滑填充滑道:

MoonBit
ui.progress_bar(state.download_percent)

7.2 Spinner 加载动画

MoonBit
ui.spinner(size=18.0)

7.3 Badge 徽标与 Avatar 头像

MoonBit
ui.badge("PRO", @core.Color::rgb(37, 99, 235))
ui.avatar("LX", size=28.0)

7.4 Tooltip 悬浮信息提示

MoonBit
let resp = ui.button("危险操作")
resp.on_hover_text(ui, "此操作将立即清空当前缓存")

7.5 Toast 瞬态全局消息通知

MoonBit
ui.toast("文件已成功导出至本地", duration_sec=3.0)

8. 容器与排版系统 #

8.1 Window 自由浮动视窗

支持鼠标拖拽标题栏位移、右下角缩放手柄、局部坐标相对排版与自动视口剪裁(Scissor Clip):

MoonBit
ui.window("场景检视器", @core.Vec2::new(80.0, 120.0), @core.Vec2::new(320.0, 400.0), fn(win) {
  win.label("窗口内部组件...")
})

8.2 CollapsingHeader 手风琴折叠栏

MoonBit
ui.collapsing_header("高级渲染设置", default_open=false, fn(panel) {
  panel.checkbox("环境光遮蔽 (SSAO)", state.ssao)
  panel.checkbox("泛光辉光 (Bloom)", state.bloom)
})

8.3 TabBar 多标签页组织

MoonBit
let tabs = ["基本信息", "材质贴图", "动画骨骼"]
let (active_tab, _) = ui.tab_bar(tabs, state.current_tab)
state.current_tab = active_tab

8.4 TreeView 层级树形视图

MoonBit
ui.tree_node("Root Scene", fn(node) {
  node.leaf("Main Camera")
  node.leaf("Directional Light")
  node.tree_node("Characters", fn(sub) {
    sub.leaf("Player_Mesh")
  })
})

8.5 ScrollArea 滚动视口

针对超长列表进行局部滚动显示,提供平滑滚轮与拖拽滚动条:

MoonBit
ui.scroll_area(height=200.0, fn(scroll) {
  for i = 0; i < 100; i = i + 1 {
    scroll.label("数据项 #" + i.to_string())
  }
})

10. 样式设计系统与高分屏适配 #

10.1 Studio Light 设计令牌 (Design Tokens)

moon-egui 采用精细校准的 Studio Light 素雅现代工业风。核心控件样式(圆角、内边距、高亮色)均封装在 WidgetStyle 中,支持在运行时无缝微调:

MoonBit
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):

半像素对齐规则
1px 细线(如 Separator 分割线与视窗边框)自动对齐在 x + 0.5 物理栅格坐标上,光栅化后纯净锐利、零子像素混叠发虚。