3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RustのGUIフレームワーク「GPUI」を使ってみた: Hello World

Posted at

GPUIとは

GPUIは、コードエディタの「Zed」を開発しているZed Industriesが開発した、Rust製のGUIフレームワークです。
開発には、かつて人気を博したコードエディタ「Atom」の開発者が参加しており、その経験からパフォーマンスを重視して設計されました。
現在は、オープンソースとして開発され、Apache Licenseで提供されています。

GPUIの特徴

GPUIには以下の特徴があります。

高パフォーマンスなUIレンダリング

  • ハイブリッド描画方式: 即時モードと保持モードのハイブリッドな描画方式を採用し、120fpsのなめらかな応答性と、必要な部分のみを効率的に再描画する仕組みを実現しています。

  • GPUレンダリング: Tauriなどで使用されるWebViewのレンダリングエンジンとは異なり、GPUを直接使用したレンダリングを行います。

  • マルチプラットフォーム対応: Windows、Mac、Linuxのマルチプラットフォームに対応しています。

宣言型のUI構築

  • 宣言型UI: UIの構築方法は宣言型を採用し、UIとロジックの分離や、コンポーネント化・再利用がしやすくなっています。

  • モダンなレイアウト・スタイリングシステム: FlexboxやGridを使用したレイアウト構築が可能です。
    また、Teilwind風のユーティリティ関数を使用したスタイリングが行えます。

Rustの所有権システムと統合した状態管理

  • 一元的な状態管理: アプリケーションの状態は、AppContextという単一のトップレベルオブジェクトに所有権が集約され、GPUIが一元的に管理します。

  • 安全なデータフロー: 状態の更新は、AppContextのAPIを経由して行われます。この方法は独特ですが、Rustの所有権システムと統合されており、メモリ安全性やリソース効率といった言語機能の恩恵を受けながら、複雑なUIでも一貫性を持った状態管理を可能にします。

Hello World

以上がGPUIのざっくりした紹介でした。
次からは、さっそくHello Worldを作成して、実際のコーディングの雰囲気を紹介したいと思います。

プロジェクトセットアップ

まずは必要な依存関係をインストールします。
GPUIはcrates.ioで提供されているので、プロジェクトを作成し、cargo addでプロジェクトにインストールできます。

cargo new my_gpui_app
cd my_gpui_app
cargo add gpui

アプリケーションの設定

GPUIでは、Application → Window → Viewという階層構造でGUIが構築されます。
Applicationはアプリ全体を管理する最上位のコンテナとして、ウィンドウの生成や、リソースやイベントの管理などアプリケーションレベルの処理を担当します。

use gpui::*;

fn main() {
    Application::new().run(|cx: &mut App| {
        // ここでアプリケーションの設定やウィンドウの生成などを行う
    });
}

GPUIの特徴で少し触れましたが、run()のコールバック関数で受け取る引数のcx: &mut AppはAppContextと呼ばれるトップレベルオブジェクトで、アプリケーション全体の状態を管理します。
以降様々な処理をAppContextから提供されるAPIを経由して行います。
特に決まりはありませんが、GPUIでは慣例的にcxという変数名が使用されます。

ウィンドウの表示

Windowでは、OS上のウィンドウを作成・表示し、実際のGUIの枠を提供します。
フォーカス・リサイズなどのウィンドウイベント管理やViewツリーを保持・レンダリングを行います。
ウィンドウの作成も簡単で、AppContextのopen_window()を呼び出すことで、ウィンドウを開くことができます。

use gpui::*;

fn main() {
    Application::new().run(|cx: &mut App| {
        cx.open_window(WindowOptions::default(), |_, cx| {
            cx.new(|_cx| Empty)  // 空のViewを作成する
        })
        .unwrap();
    });
}

現段階では何も表示しないので、枠だけの透明なウィンドウが生成されます。
cx.new(|_cx| Empty)の部分で空のViewを作成しています。
ここを起点にViewツリーを構築し、UIを作成していきます。

Viewの描画

Viewは、GPUIにおけるUIの基本要素であり、ComposableなUIコンポーネントを作成します。
レイアウトやデザインなどの、実際の見た目や、自分自身の状態(Model)を保持します。
以下のコードでは、HelloWorld Viewを作成し、緑色の背景にHello Worldを表示します。

use gpui::*;
 
struct HelloWorld {
    text: SharedString,
}
 
impl Render for HelloWorld {
    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .flex()
            .bg(rgb(0x2e7d32))
            .size_full()
            .justify_center()
            .items_center()
            .text_xl()
            .text_color(rgb(0xffffff))
            .child(format!("Hello, {}!", &self.text))
    }
}

fn main() {
    Application::new().run(|cx: &mut App| {
        cx.open_window(WindowOptions::default(), |_, cx| {
            cx.new(|_cx| HelloWorld {
                text: "World".into(),
            })
        })
        .unwrap();
    });
}

実行

あとはcargo runで実行すると、以下のようなウィンドウが表示されると思います。

実は公式ツールが提供されており、create-gpui-appを使用することで、ここまでのコードがセットアップされた状態で、プロジェクトを開始できます。
SS.png

まとめ

以上が使用感などの紹介でした。
GPUIは、高速・宣言的・Rustらしいメモリ安全な設計を兼ね備えた非常に有望なGUIフレームワークです。
まだまだドキュメントの不足など発展途上ではありますが、Rustでデスクトップアプリを作る際の選択肢として注目されています。
次の記事では、ユーザーイベントの処理と、状態管理について解説します。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?