







第62回
■
■SqueakではじめるSmalltalk入門 第62回
■
本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。前回は、ワークスペースというアプリケーション(ウインドウ)がどんなモーフの組み合わせでできているのかを“破壊”して調べてみました。今度は逆に、モーフを組み合わせるスクリプトを記述し、ウインドウを組み立ててみましょう。
まずは、ワークスペースがどのように組み立てられているのか、その“出生”をたどってみることにします。
ワークスペースは、デスクトップメニューの「開く…」サブメニューの「ワークスペース (k)」を選んで起動します。ちなみに「(k)」とあるのは、デスクトップメニューをポップアップしたり、それを閉じた直後などに「cmd + K」でワークスペースを呼び出すことが可能であることを示しています。
さて、復習を兼ねて、この「開く…」サブメニューの「ワークスペース(k)」項目をインスペクトして、ワークスペースを開くために、どんなメソッドが起動されているのかを調べてみましょう。具体的には「開く…」サブメニューの「ワークスペース (k)」項目を、shift + cmd + クリック(あるいは、複数回 cmd + クリック)してモーフとして選択し、右側の灰色ハロー(デバッグハロー)を shift クリックしてインスペクタを呼び出します。
[fig.A]モーフとして選択された「ワークスペース (k)」項目

[fig.B]「ワークスペース (k)」項目のインスペクタ

インスペクタの左側のリストペインにある、target、selector、argumentsの内容から、このメニュー項目が選択されたときに誰にどんなメッセージが送られるのかが分かります。簡単のため、ここでは#doMenuItem:with:についての詳しい解説は省きますが、その名前とメソッドの定義から、どうやらargumentsの配列内配列の第一要素に対して、第二要素のセレクタを持つメッセージを送信していることが分かります。そこで引き続き、第二要素の#openWorkspaceというメソッドの定義を調べてみることにします。念のため補足しておくと、メソッドの定義を閲覧するには、メソッド名の文字列「openWorkspace」を選択してbrowse it(cmd + B)を使うのでしたね。
#openWorkspaceには、レガシーなScreenCoontroller >> #openWorkspaceもあり、これがブラウザの起動時に選択されていますが、今は二番目のTheWorldMenu >> #openWorkspaceのほうをクリックして選択しましょう。ここから、implementorsボタンを用いてStringHolder >> #openAsMorphLabel:inWorld:の定義を見ると、具体的にどんな手続きを踏んでワークスペースを表示してるのかが分かります。ちなみに、StringHolderはWorkspaceのスーパークラスです。
[fig.C]「StringHolder >> #openAsMorphLabel:inWorld:」の定義

では、この定義に倣って、ワークスペースっぽいウインドウを“作る”スク
リプトを書き起こしてみましょう。
| window textMorph |
window := SystemWindow labelled: 'My Text Window'.
textMorph := PluggableTextMorph on: nil text: nil accept: nil.
window addMorph: textMorph frame: (0@0 corner: 1@1).
window openInWorld: World
このウインドウは、見た目こそワークスペースに似ていますが、それは同じ種類のパーツを組み合わせた結果にすぎず、ワークスペースとしては機能しません。ちょうどInterface Builderで組み立てただけのUIと同じく、“魂”である「モデル」を欠いている状態です。テキストを入力したり、その編集(cmd + Z/X/C/V)や、do it(cmd + D)、print it(cmd + P)などのキーショートカットは機能しますが、黄ボタンメニューを呼び出すことはできません。ちなみに、オリジナルのStringHolder >> #openAsMorphLabel:inWorld:では、#model:や#on:text:accept:readSelection:menu:が、このUIと“魂”とを接続する作業をしています。とりあえず今は、次の#addMorph:frame:のほうに注目してください。
SystemWindow >> #addMorph:frame:は、Morph >> #addMorph:同様、サブモーフ(GUIウィジェット)をオーナー(システムウインドウ)に組み込むためのメソッドです。ただ、新しく設けられた第二パラメータとして添えるaRectangle情報により、常にオーナーのどの範囲に位置するのかを指定することができます。#addMoprh:ではどうして駄目なのかは、実際に試してみればわかります。
| window textMorph |
window := SystemWindow labelled: 'My Text Window'.
textMorph := PluggableTextMorph on: nil text: nil accept: nil.
window addMorph: textMorph.
window openInWorld: World
[fig.D]#addMorph:では正常なウインドウを作ることができない…

たしかに#addMorph:でもa PluggableTextMorph はサブモーフとして登録されますが、オーナーモーフであるウインドウの左上に固定されていて、ウインドウサイズ変更にも追従してくれません。これではウインドウとして使いものになりませんね。
他方で、次のようにa PluggableTextMorphを二つ用意し、それぞれを#addMoprh:frame:するときに、適切なa Rectangle情報を与えることで、2ペイン(2つのテキスト編集欄)を持つウインドウを組み立てることが可能です。
| window textMorph1 textMorph2 |
window := SystemWindow labelled: 'Two Pane Text Window'.
textMorph1 := PluggableTextMorph on: nil text: nil accept: nil.
textMorph2 := PluggableTextMorph on: nil text: nil accept: nil.
window addMorph: textMorph1 frame: (0@0 corner: 1@0.5).
window addMorph: textMorph2 frame: (0@0.5 corner: 1@1).
window openInWorld: World
[fig.E]2ペインのウインドウ

現在、残念ながらSqueakシステムには、OS XのInterface Builderのような優れたUIデザインユーティリティは組み込まれていません。したがって、ウインドウのデザインは、いちいちこうして、Smalltalkコードとして記述する必要があります。ちょっと面倒ですね。
このページを編集 (5112 bytes)
 |
以下の 1 ページから参照されています。 |
This page has been visited 680 times.