見出し画像

Retro-gaming and so on

RacketとGUI

LispはGUIに弱い、と言う印象がある。
実の事を言うとそれは誤解ではある。ただし、今は主流からは外れてはいる。
しかし、元々ANSI Common LispはLispマシンのOSである事も想定して作られていたので、本来はGUIを操る事も視野に入れていたのだ。
そして、Lispは初期のCGの研究に良く使われてたのも事実だ(※1)。

Lispマシンと言えばかつて、シンボリクス社のワークステーションがそこそこ知名度が高く、何度か言ったが、プレステのFinal Fantasy VIIのグラフィックはシンボリクス社のLispマシンで作られている。



とは言っても、確かにこれは過去の話ではある。過ぎ去りし栄光だな。
それでもANSI Common Lispなら各実装向けに、有志によるGUIツールへのバインディングは提供されてはいる。
問題は、Schemeの方だろう。
GUI関連のツールを提供してるヤツもあれば無いヤツもある、ってカンジだ。
(SchemeはANSI Common Lispと違い、拡張性を考慮した仕様になっていない・・・・・・何事も「実装者の意図次第」と言うのが強い、とは言えるだろう)

しかしながら、「恐らく世界で一番人気がある」Lisp処理系Racketは、巨大なだけあってGUI関連のツールは豊富に取り揃えられてはいる。

RacketのGUIのベースはwxWidgetsと言うクロスプラットフォームなツールを用いてる。
これはかなり有名なツールで、Pythonなんかでもバインディングは提供されている。
RacketのIDE、DrRacketも実はこれはwxWidgets製である。かなり見た目の良いGUIになってる、ってのは全てwxWidgetsのお陰なのである。


うん、GUIのツールは提供されてはいるのだ。
しかし、GUIを書くのはメンド臭い。このメンド臭さはLispを含み、どのプログラミング言語を用いようと同じである。
定形の決まりきったプログラミングになるクセに長い。ダラダラと似たようなコードを毎回毎回書かなアカン。ハッキリ言って「プログラミング」と言う程でもない。工夫もない。でも書く量だけはやたら多い。
腹立つのがGUIのプログラムなのだ。
ユーザはGUIを使いたがるが、プログラマ泣かせ、ってのがGUIなのである。

こんなもん、マジメに書いていられるか、と言う反応になるのは正しい。
そういうツマラないコードなら自動生成すべきなんだ。
そういうGUIの「ガワ」を自動生成するツールを通称GUIビルダーと言う。
GUIをGUIで、つまり、マウスで選択してペタペタ貼って「GUIのガワ」を作り上げていく、と言うのは実に理にかなってるのだ。
あとは「実際動く心臓部」は別にプログラミングすれば良い。

そのテのGUIビルダーはRacketは提供してないが、有志がRacket用GUI Builderを作ってくれたらしい。
その名をMr.Ed Designerと言う。
インストールは簡単だ。DOS窓等の端末から

raco pkg install mred-designer

と打てば良い。
racoはRacketのコンパイラだが、raco pkg installと言うコマンドはPythonで言うpipのようなモノで、有志が作ってくれたRacket用のライブラリをネットワーク上にあるソフトウェアアーカイブからダウンロードしてインストールしてくれる。
インストールが終わったら、同じく端末から

racket -l mred-designer

と打つ。あるいは、Windowsならbatファイル、UNIXならスクリプトファイルでも作っておけば良いだろう。
いずれにせよ、上のコマンドを実行したらウィンドウが3つ立ち上がるだろう。
それがRacketのGUIビルダー、MrEd-designerである。


ウィンドウはそれぞれ

  • MrEd Designer
  • Hierarchy
  • Properties
と名前が書いてる筈だ。
それぞれの軽い説明から。
MrEd Designerはフレームやボタン、等「GUI部品を選択する」為の部分である。



そして「部品を選択する」度にどういう階層構造になってるのか、それを教えてくれるのがHierarchyパネル、つまり、ヒエラルキーだ。



wxWidgetsではフレーム等の「Containers」(コンテナ)の上にボタン等の「Controls」(コントロール)を貼っ付けていき、それが階層構造を形成するのだ。
そしてそれらの「部品」の細かいセッティング、言わば「調整」をするのがProperties(属性)ウィンドウである。ここでContainersやControlsの表示サイズやらを色々調整していくのである。



原則、Containersのうち、Frameだけは絶対必要で、Frame上に色んなモノをペタペタ貼っていってGUIを作っていく。

英語でのチュートリアルに従って、ちょっと触ってみよう。
まずは必ず、MrEd desingerのFrameかDialogを選ばないとならない。この二つのうちのどっちかを選ばないと他のボタンは選べないのだ。
ここではFrameを選ぶ。そうするとHierarchyが次のような階層を表示する。


ついでに小さいが、4つ目のウィンドウが現れるだろう。


これが「現時点でのGUIのウィンドウのデザイン」だ。こうやってリアルタイムにGUIデザインの状況が分かる。

次にHierarchyパネルの「Frame」をクリックする。



そうすると、MrEd Designerのボタンが全てアクティブになってる筈である。


今度はControlsに並んでるボタンのうち、左から2つ目、okと書いてるボタンを選ぶ。これがGUIに「Button」を付けるボタンである。
「Button」ボタンをクリックするとHierarchyパネルは次のように変化する。


Button階層をクリックすると、PropertyパネルがButtonのProperty(属性)に変化する。


Labelの項目にあるButtonをClick me!に書き換えて、下のApply & Update Previewをクリックする。
そうするとGUIデザインのウィンドウが更新されて次のようになるだろう。


MrEd DesignerのプルダウンメニューからFile->Generate Racket File...を選ぶ。my-project-GUI.rktととりあえず名付けよう。



そうすると、GUIのRacketコードが自動生成される。
(なお、チュートリアルによるとGUI生成プロジェクト自体は保存されない。プロジェクト自体を保存したい場合はSave Projectを選ぶ。)

生成したmy-project-GUI.rktをRacketから開いて実行すれば、今まで作成したボタン付きのGUIウィンドウが生成される。



さて、GUIのファイルと「GUIでどういう動きをするか」のファイルは別々にした方が良いようだ。
また、チュートリアルによると、GUIのファイルは手作業で弄らないように、との事。面倒でもMrEd Designerを開いてコードを自動生成させた方が良いらしい(この辺は、このテのGUI自動生成ツールでのお約束、ではある)。

my-project-logic.rktと言うファイルを作り、GUIのファイル(my-project-GUI.rkt)と同じフォルダに置く。
とりあえずサンプルコードは次のようなものだ。

#lang racket
(require "my-project-GUI.rkt")

(project-1488-init
#:button-1689-callback
(λ(bt ev)
 (send bt set-label "It works!")))

数値が入ってるが、これは自動生成されるものなんで、手元で生成してるproject番号はまた違うだろう。ボタン番号もその通りである。
数値等はプロジェクト名に従って変更可能、との事。この辺は自動生成なので、必要に応じてPropertyパネルで名前を弄る。Apply & Update Previewボタンを押さないと反応せんようなので、それだけは気をつける。

なお、このコードの意味は「ボタンを押せばボタンのラベルを"It works!"に変更せよ」と言うモノだ。

my-project-logic.rktを実行すると、GUIウィンドウがready-to-goになる。
ボタンを押せばそこに書いてあるメッセージが変化するだろう。


性交成功である。

これでチュートリアルは終了、である。

なお、MrEd DesignerのControlsに用意された「機能」の見た目は、左から見ていくと、次のようなカンジである。

























そしてMenuと言うのはいわゆるプルダウンメニューの事である。



wxWidgets及びMrEd Designerでは、こういう出来合いの部品を使ってGUIを組み立てて行くのである。

※1: オブジェクト指向の初心者向けの例に「図形の面積」のオブジェクト指向での実装、がある。
何故に図形?と言うのも、そもそもCGとオブジェクト指向は研究段階でそこそこ密接な関係があり、なおかつ、Lispが目指したオブジェクト指向は黎明期のオブジェクト指向の代表的な研究例の一つであった。
よって、ショボい例の採り方ではあるが、一応、この二つ(グラフィックとオブジェクト指向)は人によっては明快な例だったのである。
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事