2013-08-13 2 views
0

Я пытаюсь создать настраиваемое всплывающее меню в виде таблицы. Насколько я понимаю, я могу быть в состоянии сделать это, вызвав метод [NSPopupButtonCell setView: myView], проходящий в пользовательском представлении (это просто NSView с NSOutlineView в нем).Пользовательский NSPopupButtonCell в NSTableView

Так что я создал подкласс NSPopupButtonCell и во время инициализации я называю setView и перейти в режим просмотра набросков ..

EDIT

В IB я поставил ячейку таблицы столбцы в ниспадающее меню Ячейка и установил класс для моего пользовательского LookupPopupButtonCell.

Я до сих пор не получаю отображение своего пользовательского представления, но мои настраиваемые классы , похоже, вызывают методы инициализации.

С тех пор я заменил этот подход с использованием метода данных NSTableViewDelegate dataCellForTableColumn. Теперь всплывающее окно показывает мой собственный tableView.

По-прежнему не радует получение методов NSOutlineViewDelegate.

EDIT 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 
+0

Могу ли я что-то отсутствует ==> код –

+0

Добавлен код. LookupPopupButtonCell является подклассом NSPopupButtonCell. Обратите внимание, что всплывающее окно работает и отображает табличное представление, но нет данных в представлении. Вызов reloadData приводит к вызову методов DataSource. Вызов selectRowIndexes также приводит к вызову outlineViewSelectionDidChange (mmm Я думаю, что это обратный вызов делегата, а не источник данных). –

ответ

0

Кажется, вы должны использовать табличный вид на основе VIEW для получения сообщений делегата. Бла, теперь, чтобы выяснить, как связать один из них с Core Data, надеюсь, это не слишком сложно!

Можно ли использовать одно и то же меню для каждой строки? Я думаю, до тех пор, пока dataSource не воссоздается каждый раз, когда это, вероятно, не так уж плохо, все же в этой иерархии может быть много строк!

Outline view in tableView popup menu