GoでGUIアプリを作れる、gotronを触ってみた

## 最初に

Go API for Electronらしい、**gotron**を偶然見つけて触ってみた際の備忘録を書きます。

### github
https://github.com/Equanox/gotron


私自身はあまり`Go`に慣れていないので、ここに記載しているコードはGo的に微妙な書き方をしている可能性があります。
クロスコンパイルして各プラットフォームごとのデスクトップアプリ作れたら便利だなーというふわっとした動機で、ちょっと触ってみるかという軽い気持ちで触っています。
**結論：あまり参考にしないほうが良い**



## Getting started

```bash
go get github.com/Equanox/gotron
```


READMEに書かれているとおりに実施してみる。

```go
package main

import (
	"github.com/Equanox/gotron"
)

func main() {
	// browser window instanceを生成する
	window, err := gotron.New()
	if err != nil {
		panic(err)
	}

	// デフォルトのwindowサイズとタイトルを変更する
	window.WindowOptions.Width = 1200
	window.WindowOptions.Height = 980
	window.WindowOptions.Title = "Gotron"

	// browser window を起動
	// window objectを使ってElectronBrowserWindow をコントロールするために
	// websocketを使って go と nodejsのブリッジを確立するよう
	done, err := window.Start()
	if err != nil {
		panic(err)
	}

	// dev toolsを使う場合は下記をコメントアウトする(せっかくなのでdevtools使ってみる)
	window.OpenDevTools()

	// アプリケーションがcloseするのを待つ
	<-done
}

```

`<-done`の書き方が`?`と一瞬思ったがこれは`channel`だった。
実に初心者的で申し訳ない。

https://tour.golang.org/concurrency/2

起動する

```bash
go run main.go
```

<img width="1193" alt="スクリーンショット 2019-02-23 6.41.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/205976/712c05f1-ab79-8838-b9fb-9e610b17a343.png">

`dev tools`が開かれた状態でアプリが表示される


## WebUIを使用する

`gotron.New`するときに、引数にindex.htmlを含むディレクトリへのパスを指定することでWeb UIを使用できるよう。



```bash
mkdir webapp
touch webapp/index.html
```

サンプルとしてフォーム画面を作成する

```html
<!DOCTYPE html>
<html>
<head>
  <title>form example</title>
</head>

<body>

<form name="login">
  <input name="email" type="email">
  <input name="password" type="password">
  <button type="submit">ログイン</button>
</form>

</body>
</html>
```

goのコードを書き換える。

```go
	window, err := gotron.New("webapp")
	if err != nil {
		panic(err)
	}
```

これで起動すると、webui(フォーム画面)が表示される。

```bash
go run main.go
```


<img width="1197" alt="スクリーンショット 2019-02-23 21.28.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/205976/ea73ab72-d145-7733-521f-cecc636c709c.png">


## WebSocketを使用して、Backendとやり取りする

githubのREADMEを参考にしつつ、書き換える

```go
package main

import (
	"bytes"
	"fmt"

	"github.com/Equanox/gotron"
)

func main() {
	// browser window instanceを生成する
	window, err := gotron.New("webapp")
	if err != nil {
		panic(err)
	}

	// デフォルトのwindowサイズとタイトルを変更する
	window.WindowOptions.Width = 1200
	window.WindowOptions.Height = 980
	window.WindowOptions.Title = "Gotron"

	// browser window を起動
	// window objectを使ってElectronBrowserWindow をコントロールするために
	// websocketを使って go と nodejsのブリッジを確立するよう
	done, err := window.Start()
	if err != nil {
		panic(err)
	}

	// dev toolsを使う場合は下記をコメントアウトする
	// window.OpenDevTools()

	window.On(&gotron.Event{Event: "event-name"}, func(bin []byte) {
		// ここに処理を書いていく
		// fmt.Println(bin)
		b := []byte(bin)
		buf := bytes.NewBuffer(b)
		fmt.Println(buf)
	})

	// アプリケーションがcloseするのを待つ
	<-done
}
```



`webapp/index.html`も下記のように書き換えた


```html
<!DOCTYPE html>
<html>
<head>
  <title>websocket example</title>
</head>

<body>

<div>
  <button>イベントボタン</button>
</div>
<script>
  const ws = new WebSocket("ws://localhost:" + global.backendPort + "/web/app/events");
  console.log("Setup web socket:", ws);

  const button = document.querySelector("button");
  button.addEventListener("click", event => {
    ws.send(JSON.stringify({
	"event": "event-name",
        "AtrNameInFrontend": "Hello World!",
    }))
    console.log("Send success!!");
  });
</script>

</body>
</html>
```

アプリを起動して、`イベントボタン`を押すと、下記のようなログがサーバ側のコンソールに表示される

```bash
{"event":"event-name","AtrNameInFrontend":"Hello World!"}
```

## 最後に

まだ触り始めたばかりなので、そのうち実際にクロスコンパイルしてみて、実行ファイル叩くだけで起動できるデスクトップアプリを各プラットフォーム向けに作ったりしてみたい。