2011年6月5日日曜日

Cocoa NSTableView ドラッグアンドドロップ(1)

NSTreeControllerをEseに組み込んで、不具合をつぶして1日が過ぎる。ほぼ組み込む前と同じ動作をするようになったので、いよいよファイルのドラッグアンドドロップによるコピー、移動、削除その他について調べる。Eseそのものもまだまだ実験用プロジェクトなのでどんどんいろいろやってみることにしている。

ヒレガス本に「ドラッグアンドドロップは壮大なカットアンドペーストだ」という記述があったはず。それならカットアンドペーストから実装すべきだったか。(^^;)ま、いいや。

ドラッグアンドドロップについてはネット上のあちこちにたくさん情報がある。とりあえず木下誠氏のこのページあたりを出発点に、xcatsan師匠の教えを乞うたり。

NSTabViewのdatasourceのクラスで、awakeFromNibに
NSArray* array = [NSArray arrayWithObject:NSFilenamesPboardType];
[tableView registerForDraggedTypes:array];
[tableView setDraggingSourceOperationMask:NSDragOperationAll forLocal:NO];
と記述するところから出発する。
これであとは
-(BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard

を書けばいいらしい。試しに「return YES;」だけのこのメソッドを書いてみたら、あらまあなんと、ドラッグができるようになった。


NSArrayControllerに格納しているモデルのクラスは、そのままだとpboardに書き出せないので、オブジェクトからファイルのURLだけ抜き出してpboardにwriteしてみる。
    NSArray *dataArray=[arrayController selectedObjects];
    NSMutableArray *itemArray=[NSMutableArray arrayWithCapacity:[dataArray count]];
    
    for(DirectoryFile* item in dataArray){
        [itemArray addObject:[item fileURL]];
    }
    [pboard writeObjects:itemArray];
これで無事に「コピー」まではできたみたい。簡単だなあ。

次にペースト、だけどこれはかなり手がかかると思われる。本日は、ドラッグされてきたファイルがある、とTabが認識するところまで。
-(NSUInteger)draggingEntered:(id)sender{
   
    [[NSColor redColor] set];
    NSFrameRectWithWidth([self frame],2.0);

    [self displayIfNeeded];

    return NSDragOperationNone;
}

TabBarにドラッグがやってきたら、自分を赤い線で囲んでみる。

カーソルの下のTabを割り出して、そのTabをアクティブにして、それからペースト、という手順になる。
果たしてできるか・・・。

ファイルのコピーや移動になかなかとりかからなかったのは、実はこの機能が実装できなくてファイルマネージャづくりをあきらめることになるかも、という恐れがあるから。サイズの大きなファイルのコピーなどでは、マルチスレッドにしないと実用にならないだろう、と考えていて、スレッドなんていじったことも勉強したこともないから自分には無理かも、と今も考えている。

ただ、荻原本によると「グランドセントラル・ディスパッチ」を使えばけっこう簡単にマルチスレッド状態を実装できる、とあったので、ま、とにかくやってみよう、と重い腰をあげてみた。さーて、どうなるかな。

0 件のコメント:

コメントを投稿