2011年5月8日日曜日

Cocoa FileManager Cellのダブルクリック・ディレクトリの場合


画像のような状態で「アプリケーション」をダブルクリックすると、「アプリケーション」ディレクトリに入れるようにする。

OutlineViewではディレクトリのみを選択できる。右側の「FileCellView」では、OutlineViewの選択行が変更されたら(これはdelegateメソッドで通知されるので簡単)、選択ディレクトリ内のファイル一覧を取得するようになっている。

ということは、FileCellViewでディレクトリがダブルクリックされたら、そのディレクトがOutlineViewで選択状態になればいい。FileCellViewに表示されているのは、OutlineViewで選択されたディレクトリ以下のファイル・ディレクトリなので、検索する範囲も非常に限られているから具合がいい。

FileCellViewでディレクトリがダブルクリックされた、NotificationでそれをOutlineViewに通知する。
FileCellViewのmouseDownは今のところこんな風になっている。
-(void)mouseDown:(NSEvent *)theEvent{
    NSRect rect=[self bounds];
    NSPoint point = [self convertPointFromBase:[theEvent locationInWindow]];
   
    
    NSInteger cellRow,cellCollunm;
    cellRow=(rect.size.height-point.y)/maxCellSize.height;
    cellCollunm=point.x/maxCellSize.width;
   
    NSInteger max=(rect.size.height/maxCellSize.height);
 
    NSInteger index=cellRow+cellCollunm*max;
    if(index< [contentFileArray count]){
        if(index!=activeCellIndex){
            FileCell*cell=[contentFileArray objectAtIndex:index];
            if(NSPointInRect(point, [cell cellFrameRect])){
                if(activeCellIndex>-1){
                    cell=[contentFileArray objectAtIndex:activeCellIndex];
                    cell.cellState=CELL_STATE_NORMAL;
                }
                cell=[contentFileArray objectAtIndex:index];
                cell.cellState=CELL_STATE_SELECTED;
                activeCellIndex=index;
                [self setNeedsDisplay:YES];
                if([theEvent clickCount]==2){//double click
                    if ([cell isDirectory]) {
                        
                        [[NSNotificationCenter defaultCenter] postNotificationName:@"DirectoryDoubleClickedNotification" object:self];
                    }
                }
            }// else Nothing do            
        }
        else{//TODO FileName Text Edit mode(activeIndex==index)
            if([theEvent clickCount]==2){//double click
                FileCell* cell=[contentFileArray objectAtIndex:index];
             
                if ([cell isDirectory]) {
                
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"DirectoryDoubleClickedNotification" object:self];
                   
                }
            }

        }
        
    }// else Nothing do
    
}
非選択状態のCellがダブルクリックされた時、すでに選択されているCellがダブルクリックされた時、と2か所でNotificationをpostするようになっているが、実際に実行してみると「1度目のクリックで選択」、「2度目のクリックで選択状態のCellをダブルクリック」と判断されるようで、「非選択状態のCellをダブルクリック」は事実上起きないようだ。なるほどなあ。

mouseDownはこの後もっと汚くならざるを得ない運命が待っている。(^^;)どうやって切り分けていこうかなあ。

さて、Notificationを受け取った側は
-(void)directoryDoubleClicked:(id)sender{
    NSString* path= [ (FileCellView*)[sender object] activeIndexCellFullPath];
    if(path!=nil){
        FileSystemItem* item=[outLineView itemAtRow:[outLineView selectedRow]];
        FileSystemItem* newItem=[item chiledItemAtFullPath:path];
     
        NSInteger index=[outLineView rowForItem:newItem];
        NSIndexSet *indexSet=[[[NSIndexSet alloc]initWithIndex:index]autorelease];
        [outLineView selectRowIndexes:indexSet byExtendingSelection:NO];
        [outLineView scrollRowToVisible:index];
    }

}

現在の選択行の下位ディレクトリから、FileCellViewでダブルクリックされたディレクトリを特定して、それを新しい選択行にしている。

とまあ書けば簡単なんだけど、ここに至るまで細かいメソッドをたくさん書いて、それが正常に動いているか確かめて、となんだかとても時間がかかった感じがする。

で、「アプリケーション」ディレクトリをダブルクリックすると

こんな感じで左右両方のペインのViewで展開できるようになった。

0 件のコメント:

コメントを投稿