ページ

2010年4月19日月曜日

Application List (5) ドラッグ&ドロップ#2

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

(前回)Cocoaの日々: Application List (4) ドラッグ&ドロップ

前回ドラッグ&ドロップができるようになったが描画がおかしかった。


コードを見直すと原因は描画方法にあることがわかった。
ApplicationCell.m

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
ApplicationEntry* entry = [self objectValue];

[controlView lockFocus];
NSPoint p1 = cellFrame.origin;
p1.x += 0;
p1.y += 0 + [entry.icon size].height;
[entry.icon compositeToPoint:p1 operation:NSCompositeSourceOver];
NSPoint p2 = cellFrame.origin;
p2.x += 20;
p2.y += 0;
NSDictionary* attrs = [NSDictionary dictionary];
[entry.name drawAtPoint:p2 withAttributes:attrs];
[controlView unlockFocus];
}

controlView を lockFocus して描いているのが問題。ドラッグ&ドロップ時にもセルの drawIneriorWithFrame:inView: が呼び出されるが、この時渡される controlView は NSTableView内のビュー。つまりドラッグ中のファイルを描画するビューではない。なのに、上記コードではドラッグ&ドロップ時の描画でも NSTableView内のビューに lockFocus をかけて描画しているためにおかしなことになった。

原因がわかれば対応は簡単。lockFocus を使わずに描画すればいい。


- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
ApplicationEntry* entry = [self objectValue];
NSSize iconSize = [entry.icon size];
NSPoint p1 = cellFrame.origin;
if ([controlView isFlipped]) {
p1.y += iconSize.height;
}
[entry.icon compositeToPoint:p1 operation:NSCompositeSourceOver];
NSRect nameRect = cellFrame;
nameRect.origin.x += iconSize.width + 4.0;
nameRect.size.width -= iconSize.width;

NSDictionary* attrs = [NSDictionary dictionary];
[entry.name drawInRect:nameRect withAttributes:attrs];
}


さて実行してみよう。


出た。ちょっとうれしい。


ソースは GitHub からどうぞ。
AppList at 2010-04-20 from xcatsan's SampleCode - GitHub

- - - -
GUI はできたが並び替えの処理はまだ書いていない。次回はこれを実装しよう。