ウィンドウを再度開き直す為に前回はメニューを追加した。今回は別の方法を実装する。
その2ではドックのアイコンをクリックしてウインドウが再度開くというアクションにしたい。
Macのシングルウィンドウアプリではウィンドウを閉じるイコール即終了というアクションのアプリが増えてきているけど、オレブラウザは終了せず閉じるとしアイコンクリックで再オープンとする。
再オープンを実装するには?これは残念ながらMainMenu.xibの編集だけでは出来ない。いよいよコーディングに入る。
アプリのアクションを記述するのはAppDelegate.applescriptで。
AppDelegateには既に何か記述されている。見ての通りスクリプトオブジェクト。プロパティが一つハンドラが二つ定義されている。これはAppDelegateに必須の記述。

ドックのアイコンをクリックして再度ウィンドウを開く為にハンドラを一つ追加する。追加するのはapplicationShouldHandleReopen_hasVisibleWindows_(sender, visible)

まずハンドラの使い方から。中身は後回し。このハンドラが動作する様子を確認できるようログ出力させる。こんな風に。

logの記述が出来たら動作確認。Build&Run!アプリが起動したらドックにもアイコンが現れる。これをクリックしてみよう。するとXcodeでログが表示されるはず。ログが表示できたらハンドラが正しくイベントを受けている証拠。今はエラーを気にせずに。

今度はウィンドウを閉じてドックのアイコンをクリック。ログの内容で0と表示される箇所があるはず。

勘のいい人ならこれがvisibleの値でフラグだと気付くはず。ボクはドキュメント読むまで気付かなかった。。。このvisibleの値でウィンドウの表示・非表示を判断し非表示の時はウィンドウを表示すれば良さそうだ。そう、前回のshowWindowで。
前回作成したWindow Controllerをコードで扱うのも簡単だ。それに関連付くするプロパティを宣言すればいい。名前は何でもオーケー。ボクはappWindowControllerとした。その値として設定するのはmissing value。こうなる。

このappWindowControllerを利用してウィンドウを再度開くようコーディングする。こうなる。

visibleでウィンドウの表示・非表示を判定。非表示ならappWindowControllerオブジェクトにshowWindow_(me)とメッセージを送る。meは自身、つまりAppDelegateを表す。これはAppDelegateがshowWeindowメッセージを送ったということ。そして最後にyesを返している。
なぜyesを返すかというとハンドラ名をよくよく見るとわかるのだがapplicationShouldHandleReopen_hasVisibleWindows_とある。つまりこのハンドラはアイコンクリックイベントを受けた時にウィンドウが表示状態かどうかを判断するハンドラ。
もう一つ注目してほしいのはメソッドにあるアンダーバー。アンダーバーは文脈の区切りのように使用されている。applicationShouldHandleReopenはリオープンメッセージが送られてきた時と言える。それはドックアイコンをクリックした時と同義だ。
このアンダーバーがあるメソッドは引数が必ずある。そしてこのapplicationShouldHandleReopenの部分に対応している引数がsender。
もう一つの文脈hasVisibleWindowsも同様。表示するウィンドウがあるか、とある。これに対応している引数がvisiblle。
アンダーバーの数だけ引数があると考えて良い。これはAppleScriptというよりCocoaと対話する為の約束事。
コーディングは以上。早速動かして確認、と行きたいところだがまだこれでは不十分。なぜならappWincowControllerはmissing valueだから。このオブジェクトをMainMenu.xibのWindow Controllerオブジェクトと関連付ける必要がある。
関連付ける為にMainMenu.xibを編集する。
Objectリストに注目。ここには前回追加したWindow Controllerの他にオブジェクトがいくつかあるけど、その中にAppDelegateスクリプトオブジェクトがある。マウスオーバーさせ確認してみるとApp Delegateという名のオブジェクトがあるはず。

App Delegateを右クリックしてメニューを表示。するとその中にappWindowControllerの表記があるはずだ。ここまでくればもう気付くだろうけど、このappWindowControllerを例によってWindow ControllerまでD&Dすると関連付け出来るわけ。


これで実装は完了。起動して動作確認。ウィンドウを閉じてドックアイコンクリックで再度開くのを確認できる。
前回は用意されているオブジェクトの用意されているアクションにGUIを関連付けた。今回は独自に定義したアクションも同様に関連付け出来るのがわかった。
これがXcode開発の肝となるバインディング。
Objectリストにあるオブジェクトはインスタンス。Xcodeによるアプリ開発はコードでそのインスタンスの定義と参照を書かずGUI操作で行う。すごいよね。関連付けがこれほど高度で簡単だとオブジェクトの再利用も本当に簡単。
オレブラウザ開発の実況が今日で3回目だけど、基本と骨はこの3回で殆ど学べた。後は用意されているCocoaオブジェクトの使い方を知るだけ。Macのアプリ開発って全然難しくないんだ。
今回はこれで終わり。次回からギアを1つ上げて思いつくままいろんなアクションを追加していくよ。
実際に作ってるオレブラウザはgithub<https://github.com/mnicovideo/My-Web-Browser>で公開してます。
0 件のコメント:
コメントを投稿