プログラム全体はgithubのogata-k/GUI_cmp/example_icedをご覧ください。
iced
今回使用するバージョンは0.1.0-beta
です。
どんなクレートか
icedはバージョンにbetaとあるようにまだまだ開発中のGUIライブラリです。READMEによるとElmにインスパイアされて作られたクロスプラットフォーム向けのライブラリです。Elmを参考にしているだけあってコードの見た目もElmに見えます。
珍しいことにWebアプリもサポートしてるとのことです。さらに各種基本的なレンダーライブラリの対応や非同期も対応しています。
コード
use iced::{Sandbox, Element, Button, Column, Text, Settings, Container, Length, Align, HorizontalAlignment, Color, Background, button};
use iced::settings::Window;
pub fn main() {
Counter::run(Settings {
window: Window {
size: (300, 300), // (x, y)
resizable: false,
}
})
}
// state
struct Counter {
// counter value
value: i32,
// state of the two buttons
increment_button: button::State,
reset_button: button::State,
}
// message
#[derive(Debug, Clone, Copy)]
pub enum Message {
Increment,
Reset,
}
impl Sandbox for Counter {
type Message = Message;
fn new() -> Self {
Counter {
value: 0,
increment_button: button::State::default(),
reset_button: button::State::default(),
}
}
fn title(&self) -> String {
String::from("count up")
}
// update
fn update(&mut self, message: Message) {
match message {
Message::Increment => {
self.value += 1;
}
Message::Reset => {
self.value = 0;
}
}
}
// view logic
fn view(&mut self) -> Element<Message> {
Container::new(
Column::new()
.push(
Button::new(&mut self.increment_button, Text::new("+1"))
.on_press(Message::Increment)
.border_radius(5)
.background(Background::Color(Color{r: 0.8, g: 0.8, b: 0.8, a: 1.})),
)
.push(
Text::new(self.value.to_string()).size(50).horizontal_alignment(HorizontalAlignment::Center),
)
.push(
Button::new(&mut self.reset_button, Text::new("reset"))
.on_press(Message::Reset),
)
.align_items(Align::Center)
)
.width(Length::Fill)
.center_x()
.height(Length::Fill)
.center_y()
.into()
}
}
コードの説明
main
関数ではGUIのおおもととなるWindowの設定を元にアプリを起動するところだけを請け負います。
次に状態のモデルとなるCounter
モデルです。今回はカウント値、カウントアップボタン、リセットボタンの状態を表現しています。
次に状態の変更を通知するときに通知するイベントメッセージのMessage
列挙体です。今回は増加とリセットを表現しています。
そしてSandbox
トレイトを実装することで描画と更新処理を実装します。Application
というトレイトもあるのですが、こちらは非同期を扱うときのトレイトとなります。描画はview
関数で定義します。少しレイアウトの定義関数に癖がある気がしますが、よくある記述で書くことができます。
更新処理のupdate
関数は状態モデルを更新する処理だけを行います。
所感
まだまだ実用には向かず未成熟な感じが強いですが、触ってみた限り完全にElmですね。モデルやメッセージが肥大化しそうな予感はありますが、慣れるとElmアーキテクチャの方がGUIは表記しやすいかもしれませんね。
まとめ
まだまだ未成熟なライブラリですが、実用的になればRustでGUIと言ったらこれ!といえるGUIライブラリの一つになりそうな予感がします。