MrEd Designerを利用したracket GUIアプリの開発

# MrEd Designerを利用したracket GUIアプリの開発

[MrEd Designer](https://github.com/Metaxal/MrEd-Designer)を利用したracketのGUIアプリ開発についてまとめます。

## インストール

MrEd Designerのインストールは`raco`を利用して、以下のコマンドで実行できます。
`raco`に関しては、私の前回の[記事](https://qiita.com/hylanger/items/0e6981042a581c892b24)を参照してください。

```sh
raco pkg install --auto --scope installation mred-designer
```

## 起動方法

以下のコマンドで起動できます。

```sh
racket -l mred-designer
```

起動すると、以下の３画面が表示されます。

1. Hierarchy
1. MrEd Designer
1. Properties

![スクリーンショット 2024-12-04 7.13.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/2baa4390-0847-df1b-3fdf-2d8689f46ad3.png)

## 使い方

基本的な使い方は公式の[README](https://github.com/Metaxal/MrEd-Designer)に書いてある通り、大体以下のような感じになります。

1. Hierarchy画面で、`project-xxxx`を選択する
2. MrEd Designer画面で、Containers の1,2番目(frame/dialog)のどちらかを選択し追加する
3. MrEd Designer画面で、追加したframe/dialogにボタンなどいろいろ追加する
   - Show/Hideで追加したframe/dialogを表示／非表示する
   - 追加したあとは `Apply & Update Preview`を押下しないと更新されないので注意

※ MrEd Designerを終了する際には、MrEd Designer画面の`Save Project`を必ず実行するようにしてください。 **忘れると直前の作業が全部消えます。**


### 保存したプロジェクトを開く

プロジェクトの終了後に、保存したプロジェクトを再度開く場合は、以下のコマンドを実行してください。
プロジェクトファイルは、`.med`という拡張子になっているファイルになります。

```sh
racket -l mred-designer プロジェクトファイル
```

### 作成したGUIをコードにする
![スクリーンショット 2024-12-04 7.20.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/8b00b92b-c44f-47c5-208c-e64fd25dff3a.png)

`To <project-id>.rkt`ボタンを押下するとコードが保存されます。
特にお知らせダイアログの類は表示されず、プロジェクトファイル(`med`ファイル)と同階層に保存されるので注意してください。

コードだけ確認したい場合は`To frame`ボタンを押下すると、別ダイアログにコードが表示されます。

## アプリの作成

実際にMrEd Designerを使ってアプリを作成していきます。

### 必要なパーツを追加する

今回は以下のような構成にします。

![スクリーンショット 2024-12-04 7.39.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/05d4d05a-f989-22af-face-7d13a9633f0f.png)

まず、`project-4872`が選択されている状態で、以下の`frame`ボタンを押下して、フレームを追加します。
追加したフレームが `frame-5028` になります。

![スクリーンショット 2024-12-04 7.40.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/93a2fd93-ed55-c3e4-aab7-085c741f8489.png)

次に `frame-5028` が選択されている状態で、以下の `canvas`ボタンを押下して、キャンバスを追加します。
追加したキャンバスが `canvas-6341` になります。

![スクリーンショット 2024-12-04 7.41.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/23453cbf-2470-1c08-cd0d-f3c13d8df2fa.png)

`canvas-6341`を選択し、Propertiesダイアログを以下のように変更します。
各項目は、それぞれ以下の用途で利用します。

- code-gen-class : マウスイベントなどの実装に必要
- print-callback : 描画処理の実装に必要
- min-width, min-height : 画面サイズの指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/72a5b063-dd7d-eda3-2d97-a2ec4e69785c.png)

Hierarchy画面で、`frame-5028`を選択し、`Show/Hide`ボタンを押下すると、以下のようにプレビューが表示されます。

![スクリーンショット 2024-12-04 7.45.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/29b3d5f1-4d08-8897-235b-1c1ed14d067c.png)

### イベントの実装

次はイベントを実装していきます。

まず、エントリポイントとなるファイルを作成します。
今回のサンプルアプリでは、`myapp.rkt`をエントリポイントとするので、空ファイルを作成してください。

ベースとしては以下のようになると思います。

`#:canvas-6341-code-gen-class`の部分がイベントコールバックで、
`#:canvas-6341-paint-callbak`の部分が描画コールバックです。

詳細に関しては省略するので、実際の実装結果は[コード](https://github.com/ripplex-soichiro-mori/racket-gui-sample/blob/main/myapp.rkt)を参照してください。

```racket
#lang racket
(require "project-4872.rkt")
(require racket/gui/base)

(project-4872-init
 #:canvas-6341-code-gen-class
 (class canvas% (super-new)
   (define/override (on-event event)
     (super on-event event)))
 #:canvas-6341-paint-callback
 (lambda (canvas dc)
    (send dc flush))
)
```

### アプリの起動

アプリは以下のコマンドで起動します。

```sh
racket myapp.rkt
```

今回作成した（しょうもない）サンプルは以下のような画面になります。
`Touch Screen`の部分をクリックすると、イベント処理が実行されるようになっています。

![スクリーンショット 2024-12-04 7.59.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588954/60b7bb98-5220-dc1e-a6f7-932c80cdd23e.png)

作成したアプリは以下になります。詳細はリンク先を参照してください。

https://github.com/ripplex-soichiro-mori/racket-gui-sample/blob/main/myapp.rkt

## 感想

- とりあえず、MrEd Designerを使ったアプリの開発手法について、理解できたので満足
- 描画処理は、DC (Device Context)に対して色々命令をするタイプの作りになっており、慣れが必要かと思います
    - ※ MFC (C++) を触ってた人であれば理解しやすいと思います。。。
- Chat GPTは、誤回答が多かったので、[マニュアル](https://docs.racket-lang.org/reference/index.html)が必読でした
- 背景画像はMicrosoftの[Image Creator](https://www.bing.com/images/create)を利用しましたが、1発でそれっぽいのができたので笑いました

## 参考リンク

- https://github.com/Metaxal/MrEd-Designer
- https://blog.goo.ne.jp/cametan_42/e/660247b14aca78e0a7e3b7d37f391e05
- https://docs.racket-lang.org/reference/index.html