前回は、プロジェクトの「Japanese.lproj」フォルダに日本語版のMainMenu.nibを追加してみました。 今回は、ShinbunShi3プロジェクトのInfo.plistを編集してアイコンを追加してみます。それから、手始めとしてアバウトを表示するようなソースコードを書き始めます。
前回、「Japanese.lproj」(日本語版nibファイルを含む)を簡単に追加する方法を発見できませんでしたが、フォルダとその中身を作るには、MainMenu.nibを選択し「情報を見る」で表示されるダイアログの「一般」タブの「ローカライゼーションを追加」ボタンを使うことを教えてもらいました(有り難うございました)。しかし、残念ながら、この方法で作成されるnibファイルのメニューも英語表記です(涙)。Interface Builderが日本語ローカライズされたnibファイルを書き出せるわけですから、Xcodeでも指示に従い適切なローカライズnibファイルを出力して欲しいものです。
ところで、プロジェクトの一覧からMainMenu.nibをダブルクリックすると、必ず英語版のnibファイルがオープンされてしまいます。 MainMenu.nibのもうひとつ下の階層に表示される「Japanese」をクリックしないと、日本語版のnibファイルはオープンできません。ならばと言うことで「English」の方を外してみると、今度は何もオープンしません(笑)。 Mac OS Xの言語環境が日本語であっても英語版が優先されてしまします。 このままだと、知らないうちに間違った言語の方のリソースを編集してしまい、再度アプリを起動して「あれ、何も変化していない?」と悩むことになりそうです。
アプリケーションがデフォルトリソース(nibファイルやローカライズ文字列)を、どのフォルダから持って来るかについては、 Info.plistの「CFBundleDevelopmentRegion」情報で決まります。例えば、ここの設定が「English」で、現在の言語環境が日本語の場合、「Japanese.lproj」が存在すればその中身が使われますが、無い場合には代わりに「English.lproj」の中身がが利用されるわけです。そんな訳で、ひょっとしてこの情報を「English」から「Japanese」に変更すれば、ダブルクリックで日本語ローカライズnibファイルの方がオープンされるのかと思ったのですが、結果は駄目でした。
このままでは日常的な操作環境として少々苦痛なので「Japanese.lproj」はとりあえずプロジェクトから外し、「English.lproj」のリソースを日本語ローカライズして使う事にしました。アプリケーションが完成したら「English.lproj」の中身を「Japanese.lproj」に複製し、英語版ローカライズをやり直すという作戦を取りたいと思います。 続いて、「しんぶんし 2.0」で利用していた、Info.plistをそのまま「しんぶんし 3.0」のプロジェクトへコピーして現状ファイルと差替えます。細かな修正は後から行うとして、とりあえずバージョン番号などの記載だけは最新版に変更してみました。
Info.plistの内容はXMLで記述されていますのでエディタで直接編集してもかまいませんが、プロジェクトのターゲットを選択し「情報を見る」で表示されるダイアログの「プロパティ」タブでも編集できます。CarbonプロジェクトからのInfo.plistには「主要クラス」と「主要Nibファイル」がないので、ここに「NSApplication」と「MainMenu」を入力しておきます。こうしておかないと、Cocoaアプリケーションとして起動できませんので注意してください。Info.plistにはアイコンファイルの名称「ShinbunShi3.icns」も記述されていますので、そのファイルをプロジェクトのResourcesグループに追加すれば、Makeされたアプリケーションにアイコンが表示されます。
さて、ようやくアプリケーション開発の本作業へ入れる準備が整いましたので、さっそくアバウト表示に挑戦します。Carbonアプリケーションの場合は、Carbon Eventとしてコマンドの'abou'を送信すると、アプリケーションクラスのDefault Handlerがスタンダードアバウトを表示してくれました(Mac OS X 10.4から)。この仕組みの実装はCocoaアプリケーションの方が早く、 NSApplicationのorderFrontStandardAboutPanel:メソッドを呼び出すことで実現できます。MainMenu.nibでは、MainMenuのアバウト(メニュー項目)はFile's Owner接続されており、上記メソッドがデフォルトでアサインされています。つまり、このメソッドを独自の物と差し替えれば良いわけです。
アバウトダイアログ(Cocoaではパネル)を表示する処理自体は大変簡単ですが、初めてCocoaで取り組む場合には考えなくては行けないポイントがあります。アバウト用パネルオブジェクトはMainMenu.nibの中に作って良いかどうかです。MainMenu.nib内のオブジェクトはアプリケーションが起動された時に、すべて読み込まれてインスタンスが生成されます。NSWindowやNSPanelの場合には、インスペクタの「Visible At Launch」オプションをオフにしておけば、アプリケーション起動時には表示されませんので、後から適切な時点で表示すれば良いことになります。
そういう訳で小規模なアプリケーションの場合には、すべてのモデル、ビュー、コントロールのオブジェクトをMainMenu.nibに詰め込んでも問題ないですし、その方が管理し易いかもしれません。しかし、大規模なアプリケーションの場合には、関連するモジュールごとにクラスを分けて、必要とされるnibファイルもMainMenu.nibから分離しておくべきでしょう。管理すべきファイルは増えますが、起動時間も短縮でき、開発作業の分担も容易になります。今回は、大規模なアプリケーションではないですが、実験的な意味合いもあるので、アバウトのビューやコントローラは別ファイル(About.nib)として編集してみることにします。
アバウトメニューの選択で呼ばれるメソッドは、アプリケーション自身のコントローラ(ApplicationController)に用意しておきます。今回は実践練習ですので(笑)アバウトには「OK」ボタンをひとつ用意し、それのクリックでアバウトを閉じるようにしてみましょう。そのためには、NSWindowControllerのサブクラスであるアバウト用のコントローラ(AboutController)も必要です。よって以下のような2つのコントローラ・クラスを準備しました。 各クラスのインスタンス変数は、ローカル変数と区別しやすくするためにアンダーバーを含むように表記しています。
@interface ApplicationConroller : NSObject
{
AboutController *about_Controller; // オープンされたアバウトパネル
}
- (IBAction)openAboutWindow:(id)sender; // アバウトパネルを開くメソッド
@end
@interface AboutController : NSWindowController
{
IBOutlet id ok_Button; // OKボタンのアウトレット
}
- (IBAction)closeAbout:(id)sender; // アバウトパネルを閉じるメソッド
@end
次回は、Interface BuilderでMainMenu.nibとAbout.nibを編集してから、ソースコードを記述し上記の2つのクラスのを実装してみます。Leopardの「Xcode Tools」に付属している「Interface Builder 3」は、以前のバージョンから操作体系が大幅に変更されていますので、その辺りを注意深く調べてみたいと思います。