ページ

2010年5月1日土曜日

SImpleCap - プリファレンス改修:アプリ設定 (7) アプリが多い場合の表示 #3

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: SImpleCap - プリファレンス改修:アプリ設定 (6) アプリが多い場合の表示 #2

前回のチラツキはコーディングミスが原因で、これは解消した。似たような名前の変数を作ってしまうのは良くないと反省。

さて続いてはメニューを出すためのアイコンを表示する。まずは動くものを作りたいので NSButton のサブクラスを作って貼り付ける。


menu_button = [[NSButton alloc] initWithFrame:
  NSMakeRect(0, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT)];
[menu_button setTarget:self];
[menu_button setAction:@selector(clickMenuButton:)];
[menu_button setBordered:NO];
[menu_button setImage:[NSImage imageNamed:@"viewer_more_app"]];
[menu_button setHidden:YES];


あらかじめインスタンスを作り親ビューへ貼りつけておく。その上で、条件が揃った時(アプリアイコンが表示しれないケース)に表示する。このアイコンは右下に位置を固定しておく。

if (number_of_displayed_icons < matrix_row) {

  :

[menu_button setHidden:NO];
[menu_button setFrameOrigin:menu_button_origin]; 
} else {

  :

[menu_button setHidden:YES];
}



ボタンが押されたら表示しきれないアイコンをメニューとして表示する。

-(void)clickMenuButton:(id)sender
{
NSMenu *menu = [[[NSMenu alloc] initWithTitle:@"Application Menu"] autorelease];

NSUInteger index = 0;
for (ApplicationEntry* entry in [arrayController arrangedObjects]) {
if (index >= number_of_displayed_icons) {
NSMenuItem* item = [[[NSMenuItem alloc] init] autorelease];
[item setTitle:entry.name];
[item setImage:entry.icon];
[item setTarget:self.target];
[item setAction:self.menuAction];
[item setRepresentedObject:
[NSDictionary dictionaryWithObjectsAndKeys:entry.path, @"path", nil]];
[menu addItem:item];
}
index++;
}
[NSMenu popUpContextMenu:menu withEvent:[[NSApplication sharedApplication] currentEvent] forView:nil];
}


表示できているアイコンの数はわかっているので、残りのものについて NSMenuItem を作り、NSMenuを作成する。そして最後に +[NSMenu popUpContextMenu:withEvent:] でコンテキストメニューを表示する。このメソッドは NSEventを必要とするが、持ち合わせが無いので -[NSApplication currentEvent] を渡してやる。メニュー選択時のターゲットとアクションは別途用意したプロパティを使う。

さて実行してみよう。

アイコンが表示しきれない場合、右下に >> が表示される。
ウィンドウを拡大させても同じ位置に表示される。
全部表示できるまで拡大すると、このアイコンは消える。
アイコンをクリックしてみよう。
出た。

メニューを選択するとちゃんとアプリが起動する。

- - - -
今回は安易に NSButton を使ったので、押された時に真っ黒になってしまう。この辺りの調整が必要。場合によってはカスタムビューを作ってもいい(その方が早いかもしれない)。
またアイコンは、今回のように背景がチェッカーだと識別できるが、背景が黒の場合識別できない。背景によってアイコンを差し替える必要がありそうだ。