(前回)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 はできたが並び替えの処理はまだ書いていない。次回はこれを実装しよう。