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 件のコメント:
コメントを投稿