Controllerと たわむれる6
前回のつづき
今回はIKImageBrowserViewです。
まず、IKImageBrowserViewを使うために必要なFrameworkを追加します。
Quartzフレームワークです。
つぎに、IKImageBrowserViewで使うためにモデルを変更します。
モデル担当はControllersAppDelegateですね。
ControllersAppDelegate.mの一部。
- (IBAction)openRandomFolder:(id)sender { NSString *folder = [self randomFolder]; ControllersWindowController *windowController = [windowControllers objectForKey:folder]; if(windowController) { [windowController showWindow:self]; return; } NSMutableArray *array = [NSMutableArray array]; NSFileManager *fm = [NSFileManager defaultManager]; NSWorkspace *ws = [NSWorkspace sharedWorkspace]; NSArray *files = [fm contentsOfDirectoryAtPath:folder error:NULL]; for(NSString *name in files) { NSString *path = [folder stringByAppendingPathComponent:name]; NSString *filename = [fm displayNameAtPath:path]; NSImage *icon = [[[NSImage alloc] initWithContentsOfFile:path] autorelease]; if(!icon) { icon = [ws iconForFile:path]; } NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: filename, @"filename", icon, @"icon", path, @"fullpath", // 追加 nil]; [array addObject:dict]; } windowController = [[[ControllersWindowController alloc] init] autorelease]; [windowControllers setObject:windowController forKey:folder]; windowController.window.representedFilename = folder; windowController.contents = array; [windowController showWindow:self]; }
変更したのは追加一行。辞書にfullpathを持たせました。
では、IKImageBrowserViewを管理するNSViewControllerのサブクラスを作ります。
前回、ControllersListViewControllerを作った時と同じ要領で作ってください。
ヘッダはこんな感じにします。
ControllersIconViewController.h
#import <Cocoa/Cocoa.h> @interface ControllersIconViewController : NSViewController - (id)init; @end
今回も-initをオーバーライドします。
実装は後回しにして、IBでの作業に移ります。
簡単にすませるために、TableView.xibを開きます。
開いたら「File」「Decompose Interface」です。
TableView.xibはもう不要ですので閉じます。
新しく出来たXibはいきなり保存しましょう。名前はIconView.xibです。プロジェクトに追加するのをお忘れなく。
まず、File's OwnerのクラスをControllersIconViewControllerに変更します。
NSScrollViewは削除して代わりに「Custom View」を追加します。そこにIKImageBrowserViewを配置します。
IKImageBrowserViewの属性でtitledをonにします。
IKImageBrowserViewを選択して「Layout」メニューから「Enbed Objects In」「Scroll View」を選択します。
IKImageBrowserViewがスクロールビューの中に収まりました。
スクロールビューのオートリサイズフラグは次のようにしてください。
ではコネクション関係。
File's OwnerのviewをIKImageBrowserViewを包むスクロールビューに接続します。
以上。
続いてBind関係。
Bindを行うのはIKImageBrowserViewだけです。説明は面倒くさいので下の通りに!
IBでの作業は以上です。
では実装に移りましょう。
ControllersIconViewController.m
#import "ControllersIconViewController.h" #import <Quartz/Quartz.h> @implementation ControllersIconViewController - (id)init { return [super initWithNibName:@"IconView" bundle:nil]; } @end @implementation NSDictionary (ControllersIconViewController_IKImageBrowserItem) - (NSString *)imageUID { return [self objectForKey:@"fullpath"]; } - (NSString *)imageRepresentationType { return IKImageBrowserQuickLookPathRepresentationType; } - (id)imageRepresentation { return [self objectForKey:@"fullpath"]; } - (NSString *)imageTitle { return [self objectForKey:@"filename"]; } @end
何か混ざってます(w
ControllersIconViewControllerは前回のControllersListViewControllerと変わりありません。ロードすべきnib(xib)の名前が変わっただけです。
では、混ざった物ですが、これはIKImageBrowserViewに表示されるアイテムが実装すべきメソッド群です。IKImageBrowserView.hに非形式プロトコルとして宣言されてます。
本来なら、これ用のクラスを作るべきですが、今回はカテゴリで逃げてみました。
-(NSString *)imageUID は画像にユニークなIDです。(説明でもなんでもない。)フルパスがその役目としてぴったりでしたので使ってみました。
- (NSString *)imageRepresentationType は何をどのように表示するかを示すタイプを返します。NSImageをすでに持っているのでIKImageBrowserNSImageRepresentationTypeでも良かったんですが、今回はIKImageBrowserQuickLookPathRepresentationTypeにしてみました。これにしておくとダブルクリックでそれを開けるみたいです。
- (id)imageRepresentation は表示用データを返します。IKImageBrowserQuickLookPathRepresentationTypeを選びましたので返す物はフルパスです。
- (NSString *)imageTitle はそのまま表示されるタイトルです。
このままではIKImageBrowserViewは表示されませんのでControllersWindowControllerを変更します。
ただし、今回はNSTableViewとの切り替えではなく、単にIKImageBrowserViewを表示するだけです。
ControllersWindowController.m
#import "ControllersWindowController.h" #import "ControllersListViewController.h" #import "ControllersIconViewController.h" //追加 @implementation ControllersWindowController @synthesize contents; @synthesize viewController; - (id)init { return [super initWithWindowNibName:@"MainWindow"]; } - (void)dealloc { self.contents = nil; [super dealloc]; } - (void)awakeFromNib { self.viewController = [[[ControllersIconViewController alloc] init] autorelease]; //変更 self.viewController.representedObject = controller; NSView *listView = self.viewController.view; listView.frame = placeholder.frame; [listView setFrameOrigin:NSZeroPoint]; [placeholder addSubview:listView]; } @end
ControllersIconViewController.hをインポートして、生成するViewControllerのクラス名を書き換えるだけです。-(id)initのオーバーライドがじわじわ効いてきました。
次回はビューを切り替える、です。