OpenSiv3Dで自作したImGuiライクなGUIライブラリの紹介

Advent Calendar初投稿です。よろしくお願いします。

## ImGuiとは?
ImGuiは少ない行数でGUIを作ることができるライブラリです。
**GitHub:** https://github.com/ocornut/imgui

```cpp
ImGui::Text("Hello, world %d", 123);
if (ImGui::Button("Save"))
    MySaveFunction();
ImGui::InputText("string", buf, IM_ARRAYSIZE(buf));
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
```
![sample code output (dark)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v175/capture_readme_styles_0001.png) ![sample code output (light)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v175/capture_readme_styles_0002.png)
去年の冬にエンジンを改変せずに使えるように移植をしました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">OpenSiv3DでImGuiを使うにはライブラリを書き換える必要があった(↓)ので、<a href="https://t.co/JcZAwbxWDk">https://t.co/JcZAwbxWDk</a><br>ライブラリを書き換えずに済むimgui_impl_s3dを作った!<a href="https://twitter.com/hashtag/OpenSiv3D?src=hash&amp;ref_src=twsrc%5Etfw">#OpenSiv3D</a> <a href="https://t.co/y4KVJQKuOm">pic.twitter.com/y4KVJQKuOm</a></p>&mdash; てゃいの (@telyaino) <a href="https://twitter.com/telyaino/status/1209112739110514689?ref_src=twsrc%5Etfw">December 23, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

しかしOpenSiv3D流の書き方と違う点が気になったり、個人的に自前実装したい意欲が高まったので今年の春にImGuiライクなGUIライブラリ「SasaGUI」を開発しました。

## SasaGUIの紹介
SasaGUIは、ImGuiのように少ない行数でGUIを作成できるのはもちろん、ウィンドウや様々なパーツを用意しています。
**GitHub:** https://github.com/sthairno/SasaGUI
![ScreenShot](https://raw.githubusercontent.com/sthairno/SasaGUI/master/image/screenshot.png)

### 導入
`SasaGUI.hpp`をプロジェクトに追加した後、`Main.cpp`を以下のように変更します。

```diff:Main.cpp
#include <Siv3D.hpp>
+ #include "path/to/SasaGUI.hpp"

void Main()
{
+   SasaGUI::GUIManager gui;
    
    while(System::Update())
    {
+       gui.frameBegin();
        
        //ここにGUIの処理を書く
        
+       gui.frameEnd();
    }
}
```
### UIパーツ
現在17個のパーツを用意しています。
[コントロール一覧(GitHub)](https://github.com/sthairno/SasaGUI/wiki/Controls)
ここではボタンの使い方とパーツのレイアウトについて説明します。

#### ボタン
基本は1つの関数と1つのパーツが対応しています。
ボタンを表示させる`button()`関数は、関数を呼び出すことで1つボタンを追加することができます。
ボタンがクリックされると戻り値が`true`になるため、if文と組み合わせることで簡単にボタンが押されたときの処理を書くことができます。

**ソース**

```cpp
if(gui.button(U"Click!"))
{
    //ボタンがクリックされたときに実行
}
```
**実行結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581073/a8ccc2a0-4f54-e10b-a968-0698860873ab.png)

#### レイアウト
UIのパーツは左上から配置され、右方向に配置されます。(設定変更で下方向に変更も可能)
`newLine()`関数を使うことで、次の行にパーツを配置することができます。

**ソース**

```cpp
gui.button(U"ButtonA");
gui.button(U"ButtonB");

gui.newLine();

gui.button(U"ButtonC");
```
***実行結果***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581073/1cc75a2b-bba5-95e3-a80d-f29328325494.png)


### ウィンドウ
ウィンドウにパーツを追加するには、`windowBegin`と`windowEnd`の間でパーツを追加することでできます。

**ソース**

```cpp
gui.windowBegin(U"ウィンドウ名");

gui.button(U"ButtonA");
gui.button(U"ButtonB");

gui.newLine();

gui.button(U"ButtonC");

gui.windowEnd();
```
**実行結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581073/87b4ba45-75e1-3e08-1793-b1191a49b720.png)

## さいごに
SasaGUIの簡単な紹介をさせていただきました。
詳しい使い方についてはWikiに書こうと思いますが、別の開発に気力を吸われているので今現在進捗は滞っています。
リポジトリ内の`Main.cpp`に各パーツを使ったサンプルがあるので気になった方はそちらも確認してみてください。
https://github.com/sthairno/SasaGUI/blob/master/Main.cpp