Finderの場合はファイル名のみがDragImageになる。Finder並の動作にするためには、NSTableViewをサブクラス化するしかないようだ。delegateではできない動作となる。
どうせrightMouseDownも書きたいところだったので、本格的にサブクラス化することにした。本格的に、というのは、以前TBBOY'S ROOMさんのSimpleLyricsPlayer その31(NSTableViewでひとつのセルだけをD&Dする#2)のコードを拝借して、ファイル名のみのDragImageを作るようにしていたからだが、「ひとつのセルだけ」というタイトルからもわかるとおり、複数行を選択してもカーソル直下の1行分だけをDragImageにする方法だったわけで、これを改造するところから始める。
TBBOY'S ROOMさんのコードをよく読むと、NSImage上にNSCellのdrawInteriorWithFrameで描画をしているらしい。これをカーソル直下の1行分から、
- (NSImage *)dragImageForRowsWithIndexes:(NSIndexSet *)dragRows tableColumns:(NSArray *)tableColumns event:(NSEvent *)dragEvent offset:(NSPointPointer)dragImageOffset
で渡ってくる(NSIndexSet *)dragRows分描画するようにすればいいようだ、と見当がつく。
で、いろいろ試行錯誤の上に書いたコードがこれ。
- (NSImage *)dragImageForRowsWithIndexes:(NSIndexSet *)dragRows tableColumns:(NSArray *)tableColumns event:(NSEvent *)dragEvent offset:(NSPointPointer)dragImageOffset { NSInteger col =0; if ([dragRows count]<1) { return nil; } NSUInteger index=[dragRows firstIndex]; NSRect cellFrame = [self frameOfCellAtColumn:col row:index]; CGFloat cellWidth=[[self tableColumnWithIdentifier:@"fileName"] width]; CGFloat cellHeight=[self rowHeight]; //NSLog(@"image size h:%f w:%f",cellHeight,cellWidth); NSSize imageSize=NSMakeSize(cellWidth,cellHeight*[dragRows count]); NSImage *dragImage = [[[NSImage alloc] initWithSize:imageSize] autorelease]; //NSLog(@"image size w:%f h%f",[dragImage size].width,[dragImage size].height); [dragImage lockFocus]; NSRect waku = cellFrame; waku.origin.x=0; waku.origin.y=imageSize.height-cellHeight; while (index!=NSNotFound) { NSCell *dragCell = [self preparedCellAtColumn:col row:index]; [dragCell drawInteriorWithFrame:waku inView:self]; //NSLog(@"waku origin x:%f y:%f",waku.origin.x,waku.origin.y); waku.origin.y-=cellHeight; index=[dragRows indexGreaterThanIndex: index]; } [dragImage unlockFocus]; *dragImageOffset=NSZeroPoint; //NSLog(@"offset %f %f",dragImageOffset->x,dragImageOffset->y); return dragImage; }一番調べるの時間がかかったのがNSIndexSetから、どうやってindexを順次取り出すか、というところ。これはデベロッパドキュメントにちゃんと載っていた。
で、無事DragImageが思った通りに描画された。
次は右クリックのコンテキストメニューでファイルの削除(「ごみ箱に移動」)を実装する予定。とか書いても、その日の思いつきであれこれやるので未定ではあるな。
0 件のコメント:
コメントを投稿