0

テーブルビューでカスタム ポップアップ メニューを作成しようとしています。私が理解しているように、[NSPopupButtonCell setView:myView] メソッドを呼び出してカスタム ビュー (NSOutlineView を含む NSView のみ) を渡すことで、これを行うことができるはずです。

そこで、NSPopupButtonCell サブクラスを作成し、初期化中に setView を呼び出して、カスタム アウトライン ビューを渡します。

編集

IB では、表の列セルをポップアップ ボタン セルに設定し、クラスをカスタム LookupPopupButtonCell に設定しました。

カスタム ビューはまだ表示されませんが、カスタム クラスの初期化メソッドが呼び出されているようです。

それ以来、このアプローチを NSTableViewDelegate メソッド dataCellForTableColumn の使用に置き換えました。これで、ポップアップにカスタム tableView が表示されます。

ただし、NSOutlineViewDelegate メソッドを呼び出すことにはまだ喜びはありません。

編集 OK ビューで NSPopupButton を使用して動作させることができました。デリゲートは検索を機能させ、テーブルビューは問題なく表示されます。NSPopupButtonCell を使用すると、デリゲート メソッドが呼び出されないようです。

@implementation LookupPopupButtonCell

- (id)init
{
    LOG(@"init called");
    self = [super init];
    if (self) {
        [self initialise];
    }
    return self;
}
- (void)initialise
{
    LOG(@"initialise called");
    
    [self setFont:[NSFont fontWithName:@"System Regular" size:11]];
    [self setBordered:NO];
    [self setBezeled:NO];
    
    // Set the Task Lookup Popup Menu
    NSMenu *newLookupMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Custom"];
    
    NSMenuItem *newItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:@"Lookup" action:nil keyEquivalent:@""];
    [newItem setEnabled:YES];
    
    TaskLookupViewController *viewController = [[TaskLookupViewController alloc] initWithNibName:@"TaskLookupViewController" bundle:nil];
    
    [newItem setView:[viewController view]];
    
    [newLookupMenu addItem:newItem];
    [newItem release];
    
    [self setMenu:newLookupMenu];
}
@end

@implementation TaskLookupViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Initialization code here.
        [self initialise];
    }
    
    return self;
}
- (void)awakeFromNib{
    LOG(@"awakeFromNib called...");
    [self viewDidLoad];
}

- (void)viewDidLoad {
    FLOG(@"viewDidLoad called for %@", self);
    /*
    FLOG(@" _outlineView is %@", _outlineView);
    FLOG(@" _outlineView is %@", [_outlineView identifier]);
    FLOG(@" _outlineView delegate is %@", [_outlineView delegate]);
    FLOG(@" _outlineView dataSource is %@", [_outlineView dataSource]);
     */
    [_outlineView setDataSource:self];
    [_outlineView setDelegate:self];
    [_outlineView reloadData];
    [_outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
    [_outlineView setNeedsDisplay];
    [_outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:2] byExtendingSelection:NO];
    /*
    FLOG(@" _outlineView delegate is %@", [_outlineView delegate]);
    FLOG(@" _outlineView dataSource is %@", [_outlineView dataSource]);
    */
    //NSTableColumn *tableColumn = [[_outlineView tableColumns] objectAtIndex:0];
    
    //LOG(@" setting bindings");
    
    //[tableColumn bind: @"value" toObject: _treeController withKeyPath: @"arrangedObjects.displayName" options: nil];

}
- (void)initialise {
    LOG(@"initialise called");
    
    _topLevelItems = [[NSArray arrayWithObjects:@"Project", @"Tasks and Deliverables", @"Finance", nil] retain];
    
    _childrenDictionary = [NSMutableDictionary new];
    
    [_childrenDictionary setObject:[NSArray arrayWithObjects:@"Scope", nil] forKey:@"Project"];
    
    //[_childrenDictionary setObject:[NSArray arrayWithObjects:@"Issues", @"Risks", nil] forKey:@"Quality"];

    [_childrenDictionary setObject:[NSArray arrayWithObjects:@"WBS", @"Functions", nil] forKey:@"Tasks and Deliverables"];
    
    [_childrenDictionary setObject:[NSArray arrayWithObjects:@"Expenses", @"Ongoing Costs", @"Timesheets", nil] forKey:@"Finance"];
    
    //[_childrenDictionary setObject:[NSArray arrayWithObjects:@"Applications", @"Interfaces", nil] forKey:@"IT Systems"];
    
    //[_childrenDictionary setObject:[NSArray arrayWithObjects:@"People", @"Setup", nil] forKey:@"Administration"];
    
}

- (NSArray *)_childrenForItem:(id)item {
    LOG(@"_childrenForItem called");
    NSArray *children;
    if (item == nil) {
        children = _topLevelItems;
    } else {
        children = [_childrenDictionary objectForKey:item];
    }
    //FLOG(@" children are %@", children);
    
    return children;
}
@end

@implementation TaskLookupViewController (NSOutlineViewDataSource)

- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
    LOG(@"outlineViewSelectionDidChange: called");
    if ([_outlineView selectedRow] != -1) {
        NSObject *item = [_outlineView itemAtRow:[_outlineView selectedRow]];
        if ([_outlineView parentForItem:item] != nil) {
            // Only change things for non-root items (root items can be selected, but are ignored)
            FLOG(@" selected item is %@", item);
        }
    }
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    FLOG(@"outlineView:child:ofItem: called for item %@", item);
    return [[self _childrenForItem:item] objectAtIndex:index];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    LOG(@"outlineView:isItemExpandable: called");
    if ([outlineView parentForItem:item] == nil) {
        return YES;
    } else {
        return YES;
    }
}

- (NSInteger) outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    LOG(@"outlineView:numberOfChildrenOfItem: called");
    FLOG(@" children count is %d", [[self _childrenForItem:item] count]);
    return [[self _childrenForItem:item] count];
}
@end

@implementation TaskLookupViewController (NSOutlineViewDelegate)

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
    LOG(@"outlineView:isGroupItem: called");
    return [_topLevelItems containsObject:item];
}

- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    LOG(@"willDisplayCell called");
    [cell setTitle:@"Cell Title"];
}

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    LOG(@"outlineView:viewForTableColumn called");
    // We just return a regular text view.

    if ([_topLevelItems containsObject:item]) {
        NSTextField *result = [outlineView makeViewWithIdentifier:@"HeaderTextField" owner:self];
        // Uppercase the string value, but don't set anything else. NSOutlineView automatically applies attributes as necessary
        NSString *value = [item uppercaseString];
        [result setStringValue:value];
        return result;
    } else  {

        NSTextField *result = [outlineView makeViewWithIdentifier:@"ItemTextField" owner:self];
        [result setStringValue:value];
        return result;
    }
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item;
{
    LOG(@"outlineView:shouldExpandItem: called");
        return YES;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item;
{
    LOG(@"outlineView:shouldSelectItem: called");
    return YES;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldCollapseItem:(id)item;
{
    LOG(@"outlineView:shouldCollapseItem: called");
    return NO;
}
@end

@implementation TaskLookupViewController (NSTableViewDelegate)
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    LOG(@"tableView:dataCellForTableColumn:row: called");

    NSString *identifier = [tableColumn identifier];
    
    if ([identifier isEqualToString:@"task"]) {
        //LOG(@" task column setting the cell");

        LookupPopupButtonCell *cellView = [[LookupPopupButtonCell alloc] init];
        return cellView;
    }
    
    NSTextFieldCell *cellView = [tableView makeViewWithIdentifier:@"hoursCell" owner:self];
    return cellView;
    
}
@end
4

1 に答える 1