Skip to main content

makepad-2-0-splash

CRITICAL: Use for Makepad 2.0 Splash scripting language. Triggers on: splash language, makepad script, script_mod!, makepad scripting, splash 脚本, makepad 2.0 script, mod.state, on_render, script_eval, streaming evaluation, splash syntax, splash vm, let binding, splash functions, hot reload, live reload, ScriptModKey, script_mod_overrides, checkpoint, incremental parsing, canvas splash, POST splash, fn tick, on_audio, set_text, tab switching, 音乐播放器, token monitor, driver script, audio API, 热重载, 脚本引擎, 增量解析

跳到安装

来源信息

仓库
ZhangHanDong/makepad-skills
最近来源活动
2026年4月4日 17:48
检测到的 SKILL.md 语言
英语
星标
748
分支
87

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
4 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
makepad-2.0-splash
description
CRITICAL: Use for Makepad 2.0 Splash scripting language. Triggers on: splash language, makepad script, script_mod!, makepad scripting, splash 脚本, makepad 2.0 script, mod.state, on_render, script_eval, streaming evaluation, splash syntax, splash vm, let binding, splash functions, hot reload, live reload, ScriptModKey, script_mod_overrides, checkpoint, incremental parsing, canvas splash, POST splash, fn tick, on_audio, set_text, tab switching, 音乐播放器, token monitor, driver script, audio API, 热重载, 脚本引擎, 增量解析
# Makepad 2.0 Splash Scripting Language Splash is Makepad 2.0's core runtime UI scripting language, released February 12, 2026. It replaces the old compile-time `live_design!` macro system with a runtime `script_mod!` macro that enables hot reload, streaming evaluation, and AI-first code generation. ## Core Concepts ### Script Structure Every Splash script starts with a `use` import and is embedded in Rust via the `script_mod!{}` macro: ```rust use makepad_widgets::*; app_main!(App); script_mod! { use mod.prelude.widgets.* // let bindings, functions, state, and UI definitions go here startup() do #(App::script_component(vm)){ ui: Root{ main_window := Window{ window.inner_size: vec2(800, 600) body +: { // UI content } } } } } ``` ### Syntax Rules - **No commas** between properties -- whitespace-delimited - **No semicolons** -- cleaner syntax optimized for LLM generation - **Property assignment**: `key: value` - **Dot-path shorthand**: `draw_bg.color: #f00` (equivalent to `draw_bg +: { color: #f00 }`) - **Merge operator**: `key +: { ... }` extends parent without replacing - **Named children**: `name := Widget{...}` (addressable, overridable per-instance) - **Let bindings**: `let MyTemplate = Widget{...}` (local scope, must be defined before use) - **Rust binding**: `#(Struct::register_widget(vm))` connects Splash to Rust structs - **Debug logging**: `~expression` logs value during evaluation ### State Management State is managed via the `mod.state` object and reactive `on_render` callbacks: ``` // Define state let state = { counter: 0 } mod.state = state // Reactive rendering -- re-runs when .render() is called main_view := View{ on_render: ||{ Label{ text: "Count: " + state.counter } } } ``` ### Event Handling Events are handled both inline in Splash and from Rust: ``` // Inline event handlers in Splash add_button := Button{ text: "Add" on_click: ||{ add_todo(ui.todo_input.text(), "") ui.todo_input.set_text("") } } // TextInput return key todo_input := TextInput{ on_return: || ui.add_button.on_click() } // Startup event on_startup: ||{ ui.main_view.render() } ``` From Rust, use `script_eval!` to execute Splash code: ```rust impl MatchEvent for App { fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) { if self.ui.button(cx, ids!(increment_button)).clicked(actions) { script_eval!(cx, { mod.state.counter += 1 ui.main_view.render() }); } } } ``` ### Functions ``` fn tag_color(tag) { if tag == "dev" theme.color_highlight else if tag == "design" theme.color_selection_focus else theme.color_highlight } fn add_todo(text, tag) { todos.push({text: text, tag: tag, done: false}) ui.todo_list.render() } ``` ### Control Flow ``` // If/else if todos.len() == 0 EmptyState{} else for i, todo in todos { TodoItem{ label.text: todo.text } } // For loops for i, item in array { Label{ text: item.name } } // While while condition { ... } ``` ### HTTP Requests ``` let req = net.HttpRequest{ url: "https://api.example.com/data" method: net.HttpMethod.GET headers: {"User-Agent": "MakepadApp/1.0"} } net.http_request(req) do net.HttpEvents{ on_response: |res| { let text = res.body.to_string() let json = res.body.parse_json() } on_error: |e| { /* handle error */ } } ``` Streaming responses use `is_streaming: true` with `on_stream` and `on_complete` callbacks. ### HTML Parsing ``` let doc = html_string.parse_html() doc.query("p") // all <p> elements doc.query("#main") // by id doc.query("p.bold") // by class doc.query("div > p") // direct children doc.query("p[0]").text // text content doc.query("a@href") // attribute value ``` ### Streaming Evaluation Splash's parser supports checkpoint-based incremental parsing, designed for AI/LLM streaming code generation: ```rust // Rust API for streaming evaluation vm.eval_with_append_source(script_mod, &code, NIL.into()) ``` This enables real-time UI updates as code is generated token-by-token, without requiring a complete script before evaluation. ### Hot Reload & Script Mod Tracking Splash scripts support hot reload via the `--hot` flag. The VM tracks each `script_mod!` block with a unique `ScriptModKey` (file, line, column): ```rust // Internal: ScriptModKey uniquely identifies a script_mod! block ScriptModKey { file: "src/app.rs", line: 5, col: 1 } // Runtime substitution via overrides ScriptCode::script_mod_overrides // HashMap of ScriptModKey -> updated source ``` **How hot reload works:** 1. File watcher (`makepad_live_reload_core`) detects source file changes 2. `script_mod!` blocks are extracted from Rust source (handles raw strings, comments, char literals) 3. Rust placeholder counts (`#(...)`) are tracked -- adding/removing placeholders requires full rebuild 4. Validated script mods are applied via `script_mod_overrides` 5. IP-to-location mapping provides source maps for error reporting (fallback to nearest token for synthetic opcodes) **ScriptSource variants:** - `ScriptSource::Mod` -- Standard module evaluation (startup) - `ScriptSource::Streaming` -- Incremental streaming evaluation (AI/LLM) ## Critical Layout Rules 1. **Always set `height: Fit` on containers** -- default `height: Fill` causes invisible UI (0px height) 2. **Use `width: Fill` on the root container** -- never fixed pixel width at the top level 3. **Set `new_batch: true`** on any View with `show_bg: true` that contains text children 4. **Use `:=` for named children** in templates -- without it, text overrides fail silently 5. **`draw_bg.border_radius` takes a float**, not an Inset -- `draw_bg.border_radius: 16.0` 6. **Use styled Views** (`RoundedView`, `SolidView`) instead of raw `View{show_bg: true}` ## Widget Reference Core containers: `View`, `SolidView`, `RoundedView`, `RectView`, `RoundedShadowView`, `CircleView`, `GradientXView`, `GradientYView`, `ScrollXYView`, `ScrollXView`, `ScrollYView` Text: `Label`, `H1`-`H4`, `P`, `TextBox`, `TextInput`, `LinkLabel`, `Markdown`, `Html` Controls: `Button`, `ButtonFlat`, `ButtonFlatter`, `CheckBox`, `Toggle`, `RadioButton`, `Slider`, `DropDown` Layout: `Splitter`, `FoldHeader`, `Hr`, `Vr`, `Filler` Lists: `PortalList`, `FlatList` Navigation: `Modal`, `Tooltip`, `PopupNotification`, `SlidePanel`, `ExpandablePanel`, `PageFlip`, `StackNavigation` Dock: `Dock`, `DockSplitter`, `DockTabs`, `DockTab` Media: `Image`, `Icon`, `LoadingSpinner`, `Vector`, `MathView`, `MapView` ## Canvas: Rendering Splash from Claude Code Makepad Canvas (`tools/canvas/`) is a standalone app that renders Splash code received via HTTP/WS. Used by Claude Code for visual output. ### HTTP API (recommended for sending Splash) ```bash PORT=$(cat /tmp/makepad-canvas.port) # Full render curl -s -X POST "http://127.0.0.1:$PORT/splash" -d 'View{width:Fill height:Fit Label{text:"Hello"}}' # Streaming render curl -s -X POST "http://127.0.0.1:$PORT/splash/stream" # begin curl -s -X POST "http://127.0.0.1:$PORT/splash/stream" -d 'View{...' # append curl -s -X POST "http://127.0.0.1:$PORT/splash/end" # end # Clear curl -s -X POST "http://127.0.0.1:$PORT/clear" ``` ### WS Event Listening (for receiving click events) ```bash # Long-lived WS connection receives button click events as JSON mkfifo /tmp/ws_fifo; (sleep 99999 > /tmp/ws_fifo &) websocat ws://127.0.0.1:$PORT < /tmp/ws_fifo > /tmp/canvas_events & # Events arrive as: {"event":"click","widget":"btn_name"} ``` ### Interactive Buttons Use `name := Button{...}` to create clickable buttons. The `name` is sent in click events: ``` View{width:Fill height:Fit flow:Right spacing:12 btn_save := Button{text:"Save"} btn_cancel := Button{text:"Cancel"} } ``` When clicked: `{"event":"click","widget":"btn_save"}` ### Vector Animations in Splash ``` // Pulsing dot (loop_:true = indefinite, NOT "indefinite"!) Vector{width:16 height:16 Circle{cx:8 cy:8 r:6 fill:#x44ddaa opacity:Tween{from:0.3 to:1.0 dur:1.5 loop_:true}} } // Moving dot with color change Vector{width:Fill height:30 Path{d:"M 20 15 L 400 15" stroke:#x222244 stroke_width:1.} Circle{cx:Tween{from:20 to:400 dur:3.0 loop_:true} cy:15 r:4 fill:Tween{from:#x44ddaa to:#xffaa44 dur:3.0 loop_:true}} } ``` ### Canvas Splash Syntax (CRITICAL -- differs from script_mod!) When generating Splash for Canvas HTTP rendering (`POST /splash`), use these EXACT patterns. Canvas Splash syntax differs from `script_mod!` macro context in several critical ways: **1. Properties use dot-path inline, NOT nested blocks:** ``` // WRONG -- nested block syntax does not render backgrounds RoundedView{height: Fit draw_bg: { color: #x1a1a2e border_radius: 8.0 } } // CORRECT -- dot-path inline RoundedView{width: Fill height: Fit draw_bg.color: #x1a1a2e draw_bg.radius: 8.} ``` **2. Border radius is `draw_bg.radius`, NOT `draw_bg.border_radius`:** ``` // WRONG draw_bg.border_radius: 8.0 // CORRECT draw_bg.radius: 8. ``` **3. Padding uses explicit `Inset{}` type with trailing-dot floats:** ``` // WRONG -- bare number or nested block padding: 20 padding: { top: 20 bottom: 20 } // CORRECT padding: Inset{left: 20. right: 20. top: 16. bottom: 16.} ``` **4. Align uses explicit `Align{}` type:** ``` // WRONG align: { y: 0.5 } // CORRECT align: Align{y: 0.5} align: Center ``` **5. Float values use trailing dot:** ``` // WRONG // CORRECT 8.0 8. 16.0 16. 0.5 0.5 ``` **6. `SolidView` and `RoundedView` do NOT need `show_bg: true` or `new_batch: true`** -- they render backgrounds out of the box. **7. Use `--data-binary` for multi-line Splash via curl** -- plain `-d` strips newlines. ### Proven Canvas Dashboard Template Source: `tools/canvas/examples/token-dashboard.splash` ``` SolidView{width: Fill height: Fit draw_bg.color: #x0c0c18 flow: Down padding: Inset{left: 32. right: 32. top: 24. bottom: 24.} spacing: 20 // Title
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看