ナビゲータフラップの終了ボタンの機能を、毎回保存して終了するよう変更する
かなり久しぶりにSqueakを触ったので、メモ。
動機
ようこそ、スクイークランドへ!で配布している一般向けのSqueak (SqueakPlugin.image) では、保存して終了しようと思うと、
- デスクトップをCtrl-クリック
- "デスクトップメニュー..."をクリック
- "保存して終了"をクリック
とやる必要があって、とても子供 (7歳と5歳) にやらせたいとは思わない。
だからといって、プロジェクトファイルとして保存しろと言っても、ファイル名付けるなんて、とてもやらせられることとは思えない。 (←ファイル名なんて、ほんと、いらない。はやくそういう環境になってほしい。)
かといって、保存しないと、"この前描いた絵がなくなった"とか言われそう。
ということで、ナビゲータフラップの終了ボタンで強制保存できないものか、やってみた。
終了ボタンのことを知るためにインスペクタを表示する。
- 終了ボタンをCtrl-クリックしてメニューを表示
- "サブモーフ..."を選択
- "SimpleButtonDelayedMenuMorph"を選択
- "ボタン"と表示されるときもあるが、どういうことだ?
- "デバッグ..."から"モーフの検査"を選択
これで、終了ボタンがインスペクトされた。
終了ボタンが押されたときに何が起きるのかを見る。
実際に実行をステップで追ってなくって、インスペクタの情報を見てるだけだから、推測しているだけだが。
- インスペクタの左欄にあるtargetを見ると、"a ProjectNavigationMorph"となっている。
- インスペクタの左欄にあるactionSelectorを見ると、"#quitSqueak"となっている。
ProjectNavigationMorph>>quitSqueakってメッセージを投げてるのかな。
どうしてここを見たかといえば、それっぽい名前だったから。
ワールドメニューの"保存して終了のことを知るためにインスペクタを表示する。
- デスクトップをCtrl-クリックしてメニューを表示
- メニュー下部にある"デスクトップメニュー..."を選択
- メニュー右上のピンのアイコンをクリック
- メニューが表示されたままになる。
- "保存して終了"をCtrl-クリックしてメニューを表示
- "サブモーフ..."を選択
- "MenuItemMorph"を選択
- "デバッグ..."から"モーフの検査"を選択
これで、"保存して終了"のメニューアイテムがインスペクトされた。
"保存して終了"が押されたときに何が起きるのかを見る。
同様に、推測だが。
- インスペクタの左欄にある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なんだから、それぞれの都合にあわせて変化していくということで、納得しておけばいいのかな。