Geometry 関数
NSBundle
NSDictionary
NSFileManager
NSMutableAttributedString
NSNumber
NSScanner
NSString
NSTimer
Graphic 関数
NSApplication
NSBezierPath
NSCell
NSColor
NSCursor
NSCustomImageRep
NSDocument
NSDocumentController
NSDragging
NSEvent
NSFontManager
NSGraphicsContext
NSImage
NSMenu
NSOutlineView
NSPanel
NSPopUpButton
NSResponder
NSScrollView
NSString 追加
NSTableColumn
-ポップアップメニューを表示する NSTableColumn を作る
NSTableView
NSTextStorage
NSTextView
NSToolbar
NSView
NSWindow
NSWorkspace
その他
.nib ウィンドウ
Views パレット
クラス
インスタンス変数
メソッド
CFXML
Carbon Event
Carbon Graphics
Cocoa で日本語
メソッド
その他

- Application Kit-
NSTableColumn

Application Kit - NSTableColumn
ポップアップメニューを表示する NSTableColumn を作る
Keywords: NSTableColumn, NSPopUpButtonCell

NSTableColumn は NSTableView や NSOutlineView で使われる、テーブルの列のセルを決定するためのクラスだ。ここでは、こいつを使って NSTableView にポップアップメニューを埋め込んでみよう。

ただし、全部のセルに埋め込むわけではない。普通のセルと、ポップアップメニューのセルを混在させるんだ。値を自由に設定したいセルには普通のセルを、すでに設定されている値の組から選びたいときはポップアップメニューのセルを使おう。具体的には、下の図みたいなイメージだ。'Normal Cell' は普通のセル。'Boolean value' のところは YES か NO かが選べる。'Type menu' のところは、クラスの名前のメニューから 1 つを選ぶんだ。

で、こいつを実現するには、NSTableColumn のサブクラスを作ってやる必要があるんだ。サブクラスで dataCellForRow: をオーバーライドしてやる。

Application Kit/NSTableColumn.h
- (id)dataCellForRow:(int)row;

これはセルを作るためのメソッド。指定した行のセルを作るんだ。この中で、必要に応じて普通のセルや、ポップアップボタンのセルを作ってやればいい。

では、次の問題。どうやってポップアップのセルを指定してやるか?これはアプリケーションによって最適な方法が異なると思う。このサンプルでは次のようにする。テーブルのデータソースで、次のような感じのデータを用意してやるんだ。

value.plist (sample)
{
    "name" = "Boolean value";
    "item" = {
        "value" = 0;
        "itemNames" = (
            "YES", "NO"
        );
        "itemValues" = (
            1, 0
        );
    };
}

このデータは plist 形式で、NSDictionary を表している。最初のレベルでは、'name' と 'item' っていうキーがある。'name' は、テーブルの 'name' 列に入れる文字列を表す。'item' は、ポップアップのためのデータだ。

'item' には、'value'、'itemNames'、'itemValues' の 3 つのキーがある。'itemNames' はポップアップに表示される文字列、'itemValues' はそれに対応する値、'value' は現在の値(つまりメニューで選択される値)だ。このデータでポップアップのデータを指定してやろう。

ちなみに、普通のセルを指定するときは、次のようなデータを使う。'item' がなくて 'value' があるんだ。

value.plist (sample)
{
    "name" = "Normal cell";
    "value" = 16;
}

これで、データの準備はできた。じゃ、次の問題。このデータをどうやって NSTableColumn に渡すか?NSOutlineView の場合は比較的簡単だ。outlineView:child:ofItem: で、上に示したデータを返してやればいい。NSTableColumn からは dataAtRow: で取り出せる。これは、NSOutlineView だと、表示する値と、データソースが返すオブジェクトが直接一致しないからできるんだ。(outlineView:child:ofItem: で得た item から、outlineView:objectValueForTableColumn:byItem: で表示する値に変える)。

NSTableView の場合はちょっと面倒。なぜなら、NSTableView のデータソースは、テーブルで表示する値を直接返してしまうから。そこで、データソースにメソッドを 1 つ追加することにした。ポップアップ用の NSTableColumn で使うデータを取得するための、tableView:itemForTableColumn:row: だ。

PopupTableColumn.h (sample)
@interface NSObject (NSTableDataSourceForPopupTableColumn)
- (id)tableView:(NSTableView*)tableView 
                itemForTableColumn:(NSTableColumn*)tableColumn 
                row:(int)row;
@end

これを NSTableView のデータソースで実装してやる。これでどうにかできるよ。じゃ、サンプルを。

PopupTableColumn.m (sample)
- (id)dataCellForRow:(int)row
{
    id	tableView;
    id	dataSource;
    id	item;
    id	itemNames;
    id	cell;
    
    // row のアイテムを取得
    tableView = [self tableView];
    dataSource = [tableView dataSource];
    if ([tableView isMemberOfClass:[NSTableView class]]) {
        item = [dataSource tableView:tableView 
                        itemForTableColumn:self 
                        row:row];
    }
    else if ([tableView isMemberOfClass:[NSOutlineView class]]) {
        item = [[tableView itemAtRow:row] objectForKey:@"item"];
    }
    
    // アイテムの名前を取得
    if ([item respondsToSelector:@selector(objectForKey:)] &&
        (itemNames = [item objectForKey:PopupTableColumeItemNamesKey]))
    {
        // ポップアップボタンを作る
        cell = [[[NSPopUpButtonCell alloc] 
                        initTextCell:@"" pullsDown:NO] autorelease];
        [cell setBordered:NO];
        [cell setFont:[[self dataCell] font]];
        
        // タイトルを加える
        [cell addItemsWithTitles:itemNames];
    }
    else {
        // 親クラスを呼び出す
        cell = [super dataCellForRow:row];
    }
    
    return cell;
}

まず、ポップアップ用の item を取得する。NSTableView と NSOutlineView で処理が異なるので注意。とれたらポップアップ用のセルを作る。NSPopUpButtonCell のインスタンスを作るんだ。setBordered: で NULL をセットしてやるのがコツ。そして、'itemNames' をタイトルとして設定してやるんだ。これでできあがり。

サンプルソースコードは、NSTableView 用と NSOutlineView 用の 2 つを用意したぜ。

■サンプルダウンロード:
PopupTableColumn.tar.gz
PopupTableColumnOutline.tar.gz



[Home] [Download] [Archives] [BBS] [Cocoa Programming Tips 1001] [Core Foundation の秘密] [Safari Developer Center] [はじめてのブラウザのつくり方] [Sketch BP] [スクリーンセイバーを作ろう] [Objective-C 最適化] [Authorization API 完全理解] [Mac OS X Programming Books Review] [オブジェクト指向の言語比較論] [panther-dev]

mailto: mkino@xd5.so-net.ne.jp