🗄️
制作中のGUIライブラリの妄想と進捗
Siv3D Advent Calendar 2022の24日目の記事です。
はじめに
OpenSiv3D(v0.6.6)でGUIを作る場合、基本はSimpleGUIか、Rect::leftClicked()
とかを使って1から作ることが多いと思います。
しかし、いざ複雑なUIを作ろうとすると座標を直接指定して調整するのは限界があります。
てな訳でこれまで自動でレイアウト調整してくれるのGUIライブラリを移植, 実装してきました。
今回、また新しいGUIライブラリを作っているので紹介します。
新しいGUIライブラリ SivImGui(仮)
現在制作中の新しいGUIライブラリ SivImGui(仮) では、こんなUIや
こんなUIが
(いずれ)Siv3Dで簡単に作れるようになります。
特徴
画面サイズに合わせて調整するレイアウトシステム
縦幅,横幅をいっぱいに要素を広げることができます。
これの実装のためにWPFとFlutterのソースコードを読みまくりました。
2種類あるUI定義方法
XMLとプログラム内からUIの構造を定義することができます。
XMLはWPFのXAML風、プログラム内定義はRustのegui風に書くことができます。
例えば、XMLとプログラムで下図のようなUIを作成するには次のようになります。
プログラム内定義例
void Main()
{
// ...
int counter = 0;
while (System::Update())
{
// ...
{
SivImGui::Builder b(target);
b.vertical([&]{
b.label(U"Demo");
if (b.button(U"Click Me"))
{
Print << U"Hello, World!";
counter++;
}
b.label(U"{}"_fmt(counter));
});
}
// ...
}
}
XML定義例
UI.xml
<Widget>
<VerticalLayout>
<Label>Demo</Label>
<Button name="helloBtn">Click Me</Button>
<Label name="counterLabel">0</Label>
</VerticalLayout>
</Widget>
void Main()
{
SivImGui::GUI gui(U"UI.xml");
int counter = 0;
while (System::Update())
{
// ...
if (auto btn = gui.findByName<SivImGui::Button>(U"helloBtn") &&
btn.clicked())
{
counter++;
}
if (auto label = gui.findByName<SivImGui::Label>(U"counterLabel"))
{
label.text = U"{}"_fmt(counter);
}
// ...
}
}
現在の進捗
これまでの進捗はGitHub上にあります。
また、Wordle風のデモはWeb版のOpenSiv3Dでビルドして公開しています。PCの場合はウィンドウサイズを変えると自動でレイアウトが変化するので、試してみてください。
いずれ完成したらレイアウトシステムの詳細についても書こうと思います。
Discussion