Rust の GUI ライブラリ Xilem


Xilem 何?

  • Rust で書かれた実験的なマルチプラットフォーム GUI ライブラリ
  • Druid の後継と位置づけられ、Druid が直面したいくつかの課題を克服することを目標
  • wgpuベースの描画処理
  • React や SwiftUI などから影響を受けたリアクティブなアプローチ
  • 現時点では実験的なプロジェクトであり、活発な開発が継続中(現在はバージョン0.3.0)

植物の維管束の一部で、根から茎や葉へ水を運ぶ木部である xylem(ザイレム) に由来(出発点となったxi-editorの xi が言及されている)

github.com


Hello Xilem

依存を追加。

[dependencies]
xilem = "0.3.0"
winit = "0.30.12"

アプリケーションのステート構造体を用意し、

struct State {
    text: String,
}

UIを宣言的に定義し、

fn app_logic(data: &mut State) -> impl WidgetView<State> + use<> {
    flex((
        FlexSpacer::Fixed(1.0),
        label(format!("Hello {}", data.text)),
        FlexSpacer::Fixed(1.0),
        textbox(data.text.clone(), |state: &mut State, new_value| {
            state.text = new_value;
        }),
    ))
}

アプリケーション生成。

let app = Xilem::new(State { text: "xilem".to_string() }, app_logic);

ウインドウとイベント処理は winit がベースとなります。

app.run_windowed_in(
    EventLoop::with_user_event(),
    Window::default_attributes()
                 .with_title("Hello App")
                 .with_resizable(true)
                 .with_inner_size(LogicalSize::new(600., 300.))
)?;


全体としては以下のようになります。

use winit::error::EventLoopError;
use winit::window::Window;
use xilem::view::{flex, label, textbox, FlexSpacer};
use xilem::{EventLoop, WidgetView, Xilem};
use xilem::dpi::LogicalSize;

struct State {
    text: String,
}

fn app_logic(data: &mut State) -> impl WidgetView<State> + use<> {
    flex((
        FlexSpacer::Fixed(1.0),
        label(format!("Hello {}", data.text)),
        FlexSpacer::Fixed(1.0),
        textbox(data.text.clone(), |state: &mut State, new_value| {
            state.text = new_value;
        }),
    ))
}

fn main() -> Result<(), EventLoopError> {
    let app = Xilem::new(State { text: "xilem".to_string() }, app_logic);
    app.run_windowed_in(
        EventLoop::with_user_event(),
        Window::default_attributes()
                     .with_title("Hello App")
                     .with_resizable(true)
                     .with_inner_size(LogicalSize::new(600., 300.))
    )?;
    Ok(())
}

実行すると以下のようになります。

テキストボックスには、IMEによる日本語入力も機能しますが、Copy & Paste などはまだ機能しないようです。


ビュー要素

現時点では以下のビュー要素が利用できます。

  • flex: フレックスレイアウト
  • grid: グリッドレイアウト
  • sized_box: 子要素に特定のサイズを強制
  • split: 領域を縦または横に分割する2つのビュー
  • button: ボタン要素
  • image: 画像
  • portal: スクロール可能な領域
  • progress_bar: 進行バー要素
  • prose: 不変で選択可能なテキスト
  • textbox: ユーザーによるテキスト編集領域
  • task: 非同期タスクを起動
  • zstack: 子要素を積み重ねて配置

まだ基本的な要素のみですが、単純なアプリケーションであれば動かすことができます。

まとめ

Xilem について簡単に見てみました。

開発途上であり、API も安定していませんが、未だ決定打の無い Rust の GUI ライブラリの中でも、 野心的な Xilem の今後に期待したいところです。