🗄️

制作中のGUIライブラリの妄想と進捗

2022/12/24に公開

Siv3D Advent Calendar 2022の24日目の記事です。

はじめに

OpenSiv3D(v0.6.6)でGUIを作る場合、基本はSimpleGUIか、Rect::leftClicked()とかを使って1から作ることが多いと思います。

しかし、いざ複雑なUIを作ろうとすると座標を直接指定して調整するのは限界があります。
てな訳でこれまで自動でレイアウト調整してくれるのGUIライブラリを移植, 実装してきました。

https://gist.github.com/sthairno/887740c5ec1a8857e66e30ba179fdc3b

https://qiita.com/sthairno/items/edfb969a4d8f51f57a2a

今回、また新しいGUIライブラリを作っているので紹介します。

新しいGUIライブラリ SivImGui(仮)

現在制作中の新しいGUIライブラリ SivImGui(仮) では、こんなUIや

Wordle

こんなUIが

Switchのコントローラー選択画面

(いずれ)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上にあります。

https://github.com/sthairno/SivImGui

また、Wordle風のデモはWeb版のOpenSiv3Dでビルドして公開しています。PCの場合はウィンドウサイズを変えると自動でレイアウトが変化するので、試してみてください。
Wordle風デモ

いずれ完成したらレイアウトシステムの詳細についても書こうと思います。

Discussion