ナビゲータフラップの終了ボタンの機能を、毎回保存して終了するよう変更する

かなり久しぶりにSqueakを触ったので、メモ。

動機

ようこそ、スクイークランドへ!で配布している一般向けのSqueak (SqueakPlugin.image) では、保存して終了しようと思うと、

  1. デスクトップをCtrl-クリック
  2. "デスクトップメニュー..."をクリック
  3. "保存して終了"をクリック

とやる必要があって、とても子供 (7歳と5歳) にやらせたいとは思わない。
だからといって、プロジェクトファイルとして保存しろと言っても、ファイル名付けるなんて、とてもやらせられることとは思えない。 (←ファイル名なんて、ほんと、いらない。はやくそういう環境になってほしい。)
かといって、保存しないと、"この前描いた絵がなくなった"とか言われそう。
ということで、ナビゲータフラップの終了ボタンで強制保存できないものか、やってみた。

終了ボタンのことを知るためにインスペクタを表示する。

  1. 終了ボタンをCtrl-クリックしてメニューを表示
  2. "サブモーフ..."を選択
  3. "SimpleButtonDelayedMenuMorph"を選択
    • "ボタン"と表示されるときもあるが、どういうことだ?
  4. "デバッグ..."から"モーフの検査"を選択

これで、終了ボタンがインスペクトされた。

終了ボタンが押されたときに何が起きるのかを見る。

実際に実行をステップで追ってなくって、インスペクタの情報を見てるだけだから、推測しているだけだが。

  • インスペクタの左欄にあるtargetを見ると、"a ProjectNavigationMorph"となっている。
  • インスペクタの左欄にあるactionSelectorを見ると、"#quitSqueak"となっている。

ProjectNavigationMorph>>quitSqueakってメッセージを投げてるのかな。
どうしてここを見たかといえば、それっぽい名前だったから。

ワールドメニューの"保存して終了のことを知るためにインスペクタを表示する。

  1. デスクトップをCtrl-クリックしてメニューを表示
  2. メニュー下部にある"デスクトップメニュー..."を選択
  3. メニュー右上のピンのアイコンをクリック
    • メニューが表示されたままになる。
  4. "保存して終了"をCtrl-クリックしてメニューを表示
  5. "サブモーフ..."を選択
  6. "MenuItemMorph"を選択
  7. "デバッグ..."から"モーフの検査"を選択

これで、"保存して終了"のメニューアイテムがインスペクトされた。

"保存して終了"が押されたときに何が起きるのかを見る。

同様に、推測だが。

  • インスペクタの左欄にあるtargetを見ると、"a TheWorldMenu"となっている。
  • インスペクタの左欄にあるactionSelectorを見ると、"#doMenuItem: with:"となっている。
  • インスペクタの左欄にあるargumentsを見ると、"#(#(a TheWorldMenu #saveAndQuit))"となっている。

最終的に、TheWorldMenu>>saveAndQuitってメッセージを投げてるのかな。
どうしてここを見たかといえば、それっぽい名前だったから。

quitSqueakって何なのか見る。

デスクトップメニューの"開く..."から"メッセージ名 (W)"を選択し、入力したメッセージ名を持つクラスを表示するウィンドウを表示する。
quitSqueakと入れてみると、たしかにProjectNavigationMorphが見つかる。 (KidNavigationMorphというのも見つかる。)
ProjectNavigationMorphをクリックすると、下の欄にコードが表示される。

quitSqueak
	(self confirm: 'Are you sure you want to Quit Squeak?' translated)
		ifFalse: [^ self].
	SmalltalkImage current snapshot: false andQuit: true

最後の行のsnapshot:でtrueを渡すと保存してくれそう。

saveAndQuitって何なのかを見る。

同じくメッセージ名を検索する。今度は"saveAndQuit"。すると、TheWorldMenuが見つかる。そして、コードは、

saveAndQuit
	SmalltalkImage current snapshot: true andQuit: true

となっていて、やっぱりsnapshot:にtrueを渡してあげればよさそう。

いじる。

再度、quitSqueakのメッセージを検索し、ProjectNavigationMorphを選択する。
コードの上にある"browse"ボタンをクリックし、システムブラウザを表示する。
quitSqueakのコードの最後の行のsnapshot:でtrueを渡すよう変更したものをsaveAndQuitSqueakというメッセージ名で保存する。
最初に表示したインスペクタのactionSelectorを#saveAndQuitSqueakに書き換え、保存する。
これで、ナビゲータフラップの終了ボタンを押して"はい"と答えたときに、保存して終了するようになった。

思ったこと

  • そこに存在しているオブジェクトにメッセージを追加したり、インスペクタでいじったりすると、即座にシステムに反映されるのは、やっぱりきもちいいし、自然。
  • システムが提供しているクラスにメッセージを追加するのは、"こんなこともできるんだぁ"という自由の気持ちよさと、"お作法的によろしくないのでは?"という若干の不安・違和感がある。
    • まぁ、自分が所有しているimageなんだから、それぞれの都合にあわせて変化していくということで、納得しておけばいいのかな。