1. 快速安装与配置 #

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

Terminal
moon add LING71671/moon-egui

在你的模块 moon.pkg 中声明对 moon-egui 子包的导入:

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

2. 极简 Hello World 示范 #

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

MoonBit
pub fn render_app(ctx : @core.UIContext, state : AppState) -> Unit {
  @widgets.window(ctx, "快速控制台", @math.Vec2::new(40.0, 40.0), @math.Vec2::new(300.0, 240.0), fn(win) {
    let _ = win.label("当前点击次数: " + state.count.to_string())
    if @widgets.button_primary(win, "点击增加 (+1)").clicked {
      state.count += 1
    }
    win.separator()
    let (new_val, _) = @widgets.slider(win, "渲染速度", 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 @widgets.button(ctx, "确定保存").clicked { ... }

// 2. 主行动点高亮按钮 (Primary CTA)
if @widgets.button_primary(ctx, "立即编译").clicked { ... }

// 3. 带快捷键徽标指示的按钮
if @widgets.button_with_shortcut(ctx, "快速搜索", "Ctrl+P").clicked { ... }

// 4. 紧凑型小按钮(显式尺寸)
if @widgets.button_sized(ctx, "+", @math.Vec2::new(24.0, 24.0)).clicked { ... }

5.2 TextEdit 文本输入

支持即时光标定位、键盘文本录入、Backspace 退格、左右光标移动及双向绑定的单行/多行文本编辑框:

MoonBit
let (new_text, resp) = @widgets.text_edit_val(ctx, "username", state.username, placeholder="请输入用户名...")
state.username = new_text

5.3 CodeEditor 代码编辑器

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

MoonBit
let (code, resp) = @composite.code_editor(ctx, "source", state.source_code, show_line_numbers=true)
state.source_code = code

5.4 文本展示与排版 (Label)

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

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

6.1 Slider 滑动条

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

MoonBit
let (vol, _) = @widgets.slider(ctx, "音量", state.volume, 0.0, 1.0)
state.volume = vol

let (samples, _) = @widgets.slider_int(ctx, "采样率", state.samples, 1, 64)
state.samples = samples

6.2 DragValue Blender 风格数字微调

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

MoonBit
let (focal, _) = @widgets.drag_value(ctx, "焦距 (mm)", state.focal_length, speed=0.5, min=10.0, max=800.0)
state.focal_length = focal

6.3 Knob 360° 角度旋钮

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

MoonBit
let (angle, _) = @composite.knob(ctx, "rotation", "旋转角度", state.rotation_deg, min_val=0.0, max_val=360.0)
state.rotation_deg = angle

6.4 Checkbox 与 Toggle 胶囊开关

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

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

6.5 ComboBox 下拉选择菜单

MoonBit
let options = ["WebGL 2.0", "Canvas 2D", "WebGPU"]
let (selected_idx, _) = @widgets.combo_box(ctx, "backend", "图形后端", state.backend_idx, options)
state.backend_idx = selected_idx

6.6 ColorButton 颜色选择器

MoonBit
// 色块按钮:点击时返回 picked
let (picked, resp) = @widgets.color_button(ctx, "pen_color", state.pen_color)

// 带十六进制读数与弹出拾色器的按钮
let (pen, _) = @composite.color_picker_button(ctx, "画笔颜色", state.pen_color)
state.pen_color = pen

6.7 Stepper 离散步进调节器

提供带加减步进按钮、边界约束、滚轮微调及修饰键倍率控制(Shift 10×,Ctrl 0.1×)的数值调节器:

MoonBit
let (val, resp) = @widgets.stepper(ctx, "buffer_size", state.buffer_size, step=1.0, min=1.0, max=100.0)
state.buffer_size = val

7. 反馈与展示组件 #

7.1 ProgressBar 进度条

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

MoonBit
@widgets.progress_bar(ctx, state.download_percent)

7.2 Rating 星级评分条

支持 0.5 半星精度矢量裁剪、实时悬浮预览反馈及只读模式的交互式评分组件:

MoonBit
let (stars, resp) = @widgets.rating(ctx, "app_rating", state.rating, allow_half=true)
state.rating = stars

7.3 Spinner 加载动画

MoonBit
@widgets.spinner(ctx, size=18.0)

7.4 Badge 徽标与 Tag 可关闭标签

MoonBit
@widgets.badge(ctx, "PRO", kind=@widgets.BadgeKind::info(), dot=true)
let (closed, resp) = @widgets.tag(ctx, "build_tag", "v0.3.1", closable=true)

7.5 Tooltip 悬浮信息提示

MoonBit
let resp = @widgets.button(ctx, "危险操作")
if resp.hovered {
  @widgets.tooltip(ctx, "此操作将立即清空当前缓存")
}

7.6 Toast 瞬态全局消息通知

MoonBit
let toast = @widgets.Toast::info("文件已成功导出至本地", duration=3.0)
let res = @widgets.toast_stack(ctx, [toast], viewport_size=@math.Vec2::new(800.0, 600.0))

8. 容器与排版系统 #

8.1 Window 自由浮动视窗

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

MoonBit
@widgets.window(ctx, "场景检视器", @math.Vec2::new(80.0, 120.0), @math.Vec2::new(320.0, 400.0), fn(win) {
  let _ = win.label("窗口内部组件...")
}, id_salt="inspector")

8.2 CollapsingHeader 手风琴折叠栏

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

8.3 TabBar 多标签页组织

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

8.4 TreeView 层级树形视图

MoonBit
let nodes = [
  @composite.TreeNode::branch("root", "Root Scene", [
    @composite.TreeNode::leaf("camera", "Main Camera"),
    @composite.TreeNode::leaf("light", "Directional Light"),
    @composite.TreeNode::new("chars", "Characters", [
      @composite.TreeNode::leaf("mesh", "Player_Mesh"),
    ]),
  ]),
]
let res = @composite.tree_view(ctx, "scene_tree", nodes)
if res.selected_id is Some(id) { ... }

8.5 ScrollArea 滚动视口

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

MoonBit
@widgets.scroll_area(ctx, "data_list", @math.Vec2::new(300.0, 200.0), fn(scroll) {
  for i = 0; i < 100; i = i + 1 {
    let _ = scroll.label("数据项 #" + i.to_string())
  }
})

8.6 Steps 流程步骤导航

工作流与引导步骤导航条,支持状态自动推导(Wait/Process/Finish/Error)与无障碍键盘切换:

MoonBit
let step_items = [
  @widgets.StepItem::new("环境校验", desc="检测 Toolchain"),
  @widgets.StepItem::new("编译构建", desc="生成 Wasm 字节码"),
  @widgets.StepItem::new("打包分发", desc="生成发布资源"),
]
let (active_step, _) = @widgets.steps(ctx, "build_flow", state.current_step, step_items, clickable=true)
state.current_step = active_step

8.7 Pagination 数据分页控制器

支持智能折叠省略号(如 1 ... 4 [5] 6 ... 20)与键盘左右/首尾无障碍跳转的数据分页条:

MoonBit
let (page, resp) = @widgets.pagination(ctx, "table_pages", state.current_page, state.total_pages)
state.current_page = page

8.8 NodeEditor 蓝图节点拓扑流连线编辑器

支持无限/边界视口点阵背景、卡片平滑拖拽、端口吸附拾取与平滑三次贝塞尔曲线导线的复合拓扑图组件:

MoonBit
let res = @composite.node_editor(ctx, "shader_graph", @math.Vec2::new(640.0, 420.0), state.nodes, state.connections)
if res.new_connection is Some(conn) {
  state.connections.push(conn)
}

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

10.1 Studio Light 设计令牌 (Design Tokens)

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

MoonBit
let style = ctx.style()
ctx.set_style(style.scaled(1.25))

10.2 Retina 屏与设备物理像素对齐

为杜绝 Canvas 绘图在苹果 Retina 视网膜屏及高分屏下的模糊与毛刺,引擎内置 scale_factor(对齐 window.devicePixelRatio):

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