用途
该技能用于 Makepad 2.0 的 DSL 语法与属性系统。Makepad 2.0 以运行时的 script_mod! 宏替换了编译期的 live_design! 宏,由 Splash 脚本语言驱动。技能内容覆盖完整 DSL 语法、属性系统、注册模式以及常见陷阱。触发场景包括 makepad dsl、script_mod!、makepad syntax、makepad property、makepad 2.0 等。
核心语法规则
属性赋值使用冒号(:)而非等号(=)。key: value 是正确写法;key = value 是旧的 1.x 语法,已不再生效。属性之间以空白或换行分隔,同级属性之间不用逗号。示例:
View{
width: Fill
height: Fit
flow: Down
spacing: 10
padding: 15
}
命名实例(:= 运算符)
使用 := 创建可寻址的命名组件实例,例如 my_button := Button{ text: "Click me" }、title := Label{ text: "Hello" }。命名实例可从 Rust 代码通过 id!(my_button) 或 ids!(my_button) 寻址;可通过点路径语法覆盖:MyTemplate{ title.text: "New text" };存储在脚本对象的 vec(而非 map)中。普通属性使用 : 并进入 map:width: Fill、label := Label{}。
合并运算符(+:)
+: 运算符用于与父级扩展/合并,而不是替换。例如 draw_bg +: { color: #f00 } 只覆盖 color,保留 draw_bg 的其他所有属性;而 draw_bg: { color: #f00 } 会替换整个 draw_bg,丢失 hover、边框等。
点路径是合并的语法糖:draw_bg.color: #f00 等价于 draw_bg +: { color: #f00 };draw_text.text_style.font_size: 14 等价于 draw_text +: { text_style +: { font_size: 14 } }。
let 绑定
let 在 script_mod! 块内创建本地可复用模板,例如:
let MyCard = RoundedView{
width: Fill height: Fit
padding: 16 flow: Down spacing: 8
draw_bg.color: #2a2a3d
draw_bg.border_radius: 8.0
title := Label{ text: "Default Title" draw_text.color: #fff }
body := Label{ text: "" draw_text.color: #aaa }
}
MyCard{ title.text: "Card 1" body.text: "Content here" }
注意:let 绑定仅在当前 script_mod! 块内有效,其他 script_mod! 块无法访问。跨模块共享需存入 mod.widgets.*。
展开运算符(..)
用于从其他定义继承全部属性,例如 set_type_default() do #(DrawMyShader::script_shader(vm)){ ..mod.draw.DrawQuad }。
脚本模块结构
基本应用结构包含 use 声明、app_main!、script_mod! 块与 impl App。script_mod! 中通过 load_all_resources() do 定义 UI,Root 下包含 Window,Window 的 body 中加入内容。App 需实现 run,按顺序注册:先 crate::makepad_widgets::script_mod(vm) 注册基础组件,再调用 App::from_script_mod。App 结构体需 #[derive(Script, ScriptHook)],并包含必需的 #[source] source: ScriptObjectRef 与 #[live] ui: WidgetRef。通过 impl MatchEvent 的 handle_actions 处理动作,通过 impl AppMain 的 handle_event 分发事件。
组件定义与注册
组件定义模块使用 use mod.prelude.widgets_internal.* 与 use mod.widgets.*。注册分两步:先把 Rust 结构体注册为组件基础 mod.widgets.MyWidgetBase = #(MyWidget::register_widget(vm)),再用 set_type_default() do 创建带默认属性的样式变体。非组件结构体使用 #(MyComponent::script_component(vm));自定义绘图着色器用 #(DrawMyShader::script_shader(vm))。
注册顺序至关重要:组件模块必须先于使用它们的 UI 模块注册。lib.rs 聚合模式中,script_mod 函数按顺序调用各模块的 script_mod。
Prelude 系统
mod.prelude.widgets.* 用于应用开发,包含全部标准组件;mod.prelude.widgets_internal.* 用于组件库内部开发。Prelude 别名语法可把 mod.std 展开进作用域,并为 mod.theme、mod.draw 创建别名。跨模块共享只能通过 mod 对象:在组件模块导出到 mod.widgets 命名空间,在 UI 模块用 use mod.widgets.* 导入。use crate.module.* 不可用,crate. 前缀在 script_mod 中不存在。
运行时属性更新与调试
运行时更新使用 script_apply_eval! 替代旧的 apply_over + live!,Rust 表达式插值用 #(expr)。例如 script_apply_eval!(cx, item, { height: #(height) draw_bg: { is_even: #(if is_even { 1.0 } else { 0.0 }) } })。调试可用 ~expression 在脚本求值时记录值,如 ~mod.theme、~some_variable。
常见陷阱
- 所有 Script 派生结构体必须有
#[source] source: ScriptObjectRef。 - 容器缺少
height: Fit:默认高度为 Fill,在 Fit 父级中会形成循环依赖导致高度为 0、不可见。 - 混淆
:与:=:前者设置属性(存入 map),后者创建命名的可寻址子项(存入 vec);用label: Label{}创建匿名实例不可寻址,覆盖会静默失败。 - 忘记
+:合并运算符会替换整个属性。 - 主题访问错误:应使用
theme.color_bg_app、theme.space_2、theme.font_size_p,而非旧的 THEME_COLOR_BG 常量或括号引用。 - 含 'e' 的十六进制颜色需加
#x前缀,因为 Rust 分词器会把 e/E 解释为科学计数法指数,如#x2ecc71、#x1e1e2e;不含 e 的颜色可直接用#ff4444。 - script_mod 中 pub 关键字无效,可见性由 Rust 模块系统控制。
- 边距/内边距需用构造器语法:
margin: Inset{ left: 10 }、align: Align{ x: 0.5 y: 0.5 };统一值可直接写数字如padding: 15。 - 使用 #[repr(C)] 的绘图表结构体字段顺序:非实例数据(#[rust]、非实例 #[live] 字段)必须在 #[deref] 之前,仅实例字段(着色器输入)在其后。
- script_mod! 首个代码前不能有注释,否则会偏移错误位置信息。
其他陷阱
光标值使用 cursor: MouseCursor.Hand;资源路径使用 crate_resource("self://path");纹理声明使用 tex: texture_2d(float);着色器浮点取模用 modf(a, b) 而非 mod(a, b);枚举默认值用 default: @off(带 @ 前缀);不使用 DefaultNone derive,改用 #[derive(Default)] 与 #[default] 属性;着色器中方法链用 .method() 而非 ::method();颜色混合优先使用 color1.mix(color2, hover) 链式写法;组件未注册时需在 App::run() 中先调用 crate::makepad_widgets::script_mod(vm)。
新旧语法对照
<BaseWidget> 对应 mod.widgets.BaseWidget{} 或导入后的 BaseWidget{};{{StructName}} 对应 #(Struct::register_widget(vm));(THEME_COLOR_X) 对应 theme.color_x;<THEME_FONT> 对应 theme.font_regular;instance hover: 0.0 对应 hover: instance(0.0);uniform color: #fff 对应 color: uniform(#fff);draw_bg: {}(替换)对应 draw_bg +: {}(合并);default: off 对应 default: @off;fn pixel(self) 对应 pixel: fn();item.apply_over(cx, live!{...}) 对应 script_apply_eval!(cx, item, {...})。
参考文件
DSL Syntax Reference(完整语法与示例)、Property System(Walk、Layout、Draw 与着色器属性)。
限制
资料未提供该技能的收费、价格、平台支持范围或具体效果等信息,暂未提供。