Makepad とは
Makepad は、Rust で書かれたクロスプラットフォーム(ネイティブおよびWeb)な UIフレームワークです。
2019年から開発が始まり、2025年5月15日に 1.0.0 版がリリースされました。
特徴としては、シェーダーベースのUIレンダリングを行う点、UIを独自のDSLで定義する点、Liveシステムによるホットリロードにより、再コンパイルすることなく、リアルタイムにUIを更新できる点、といったところでしょうか。
リポジトリは以下です。
サンプルの実行
Makepad のリポジトリには、makepad-studio という IDE が含まれています。
以下のように実行できます。
git clone https://github.com/makepad/makepad.git cd makepad cargo run -p makepad-studio --release
IDE っぽいものが起動します。
Makepad の開発者は、Cloud9 IDE の開発者でもる Rik Arends であり、最終的には Makepad で ライブコーディングとデザインのハイブリッドIDEを構築することが目的のようです。
簡単なアプリケーションの作成
少し触ってみましょう。
以下でプロジェクトを作成します。
cargo new makepad_example cd makepad_example cargo add [email protected]
src/main.rs を以下のように編集します。
// Import Makepad Widgets package use makepad_widgets::*; // Define live_design macro for declaring UI components and layout live_design! { use link::widgets::*; App = {{App}} { ui: <Root> { <Window> { body = <View> {} } } } } // Define App struct containing UI and counter #[derive(Live, LiveHook)] pub struct App { #[live] ui: WidgetRef // UI component reference } // Implement LiveRegister trait for registering live design impl LiveRegister for App { fn live_register(cx: &mut Cx) { // Register Makepad Widgets' live design makepad_widgets::live_design(cx); } } // Implement AppMain trait for handling events impl AppMain for App { fn handle_event(&mut self, cx: &mut Cx, event: &Event) { let scope = &mut Scope::empty(); // Handle UI events self.ui.handle_event(cx, event, scope); } } // Define application entry point app_main!(App); fn main() { app_main() }
以下で実行します。
cargo run
空のウインドウが表示されます。
簡単にコードを見ていきましょう。
live_design!
マクロでUIを定義しています。
live_design! { use link::widgets::*; App = {{App}} { ui: <Root> { <Window> { body = <View> {} } } } }
例えば、以下のように変更して保存してみます。
live_design! { use link::widgets::*; App = {{App}} { ui: <Root> { <Window> { show_bg: true, draw_bg: { color: #000 }, body = <View> {} } } } }
ウインドウの背景を黒で表示するように指定しました。 ファイルを保存すれば、ホットリロードされて、即座に変更が反映されます。
ウインドウのボディ内に Label コンポーネントを配備してみます。
live_design! { use link::widgets::*; App = {{App}} { ui: <Root> { <Window> { show_bg: true, draw_bg: { color: #000 }, body = <View> { <Label> { margin: 40, text: "Hello World!" draw_text: { color: #FFFFFF } } } } } } }
またも即座に UI が更新されます。
このようにMakepad では live_design!
マクロにより、UIを定義していきます。
イベント処理
ボタンとラベルを追加します。
live_design! { use link::widgets::*; App = {{App}} { ui: <Root> { <Window> { show_bg: true, draw_bg: { color: #000 }, body = <View> { button = <Button> { margin: 30, text: "Click Me", } msg = <Label> { margin: 15, draw_text: { color: #FFFFFF } } } } } } }
handle_event()
内に以下を追加します。
impl AppMain for App { fn handle_event(&mut self, cx: &mut Cx, event: &Event) { self.match_event(cx, event); // <- 追加 let scope = &mut Scope::empty(); // Handle UI events self.ui.handle_event(cx, event, scope); } }
MatchEvent の実装を以下のように追加します。
impl MatchEvent for App { fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions){ if self.ui.button(id!(button)).clicked(&actions) { self.ui.label(id!(msg)).set_text(cx, "Hello world!"); self.ui.redraw(cx); } } }
UI 上の button
という名前のボタンがクリックされた場合に、msg
というラベルのテキストを変更するだけの処理です。
ボタンをクリックすると、以下のようにメッセージが表示されます。
まとめ
Rust の GUI フレームワーク Makepad を簡単に触ってみました。
基本的なウィジェットも揃っていますし、ホットリロードがなかなかステキです。
ドキュメントも最近公開されたので、興味のある方は触ってみてはいかがでしょうか。