[Résolu]NSOutlineView cell based vs view based vs binding (couleur selon le niveau)
Objectif :
NSOutline à une seule colonne, 3 niveaux de couleurs différentes, capture du clic de la souris.
1. Cell based par programme
Le code suivant marche : affichage en couleurs
//DataSource
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
if (item == nil) {
return [_dataSource count];
} else if ([item isKindOfClass:[NSDictionary class]]) {
return [[item objectForKey:@children] count];
} else return 0;
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
if (item == nil) { //item is nil when the outline view wants to inquire for root level items
return [_dataSource objectAtIndex:index];
} else if ([item isKindOfClass:[NSDictionary class]]) {
return [[item objectForKey:@children] objectAtIndex:index];
} else return nil;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
if ([item isKindOfClass:[NSDictionary class]] || [item isKindOfClass:[NSArray class]]) {
return YES;
} else {
return NO;
}
}
- (id)outlineView:(NSOutlineView *)outlineView :(NSTableColumn *)tableColumn byItem:(id)item
{
if ([item isKindOfClass:[NSDictionary class]]) {
NSLog(@[;item objectForKey:@'parent'] : %@", [item objectForKey:@parent]);
return [item objectForKey:@parent];
}
return item ;
}
//Delegate
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
long level = [outlineView levelForItem:item];
[cell setTextColor:[NSColor colorWithRed:223./255. green:109./256. blue:20./255. alpha:1.0]];
if(level>0)
[cell setTextColor:[NSColor colorWithRed:30./255. green:127./256. blue:203./255. alpha:1.0]];
if(level>1)
[cell setTextColor:[NSColor colorWithRed:34./256. green:120./256. blue:15./256. alpha:1.0]];
}
- (NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tc item:(id)item mouseLocation:(NSPoint)mouseLocation {
[self action:item];
return nil;
}
Problème : méthode "toolTipForCell:(NSCell *)cell" OK. Mais il faut laisser le curseur de la souris plusieurs secondes pour que "action" soit appelée et affiche quelque chose, ce qui est trop long et peu naturel.
2. View based par programme
Avec le même code, c'est le titre de la NSTextFieldCell qui est affiché et pas en couleur.
C'est peut-être la méthode "objectValueForTableColumn" qui ne convient pas ?
J'ai essayé d'autres méthodes mais rien à faire. Et je n'ai pas réussi à adapter des bouts de code trouvés ici ou là .
L'intérêt est que le NSTextField peut être sous-classé et permettre ainsi la gestion instantanée des clics de la souris. Mais si l'affichage n'est pas le bon...
3. View based par binding dans le XIB
C'est assez facile dans le XIB et avec un NSTree, en mode view based
Je récupère les clics de la souris comme je veux.
Problème : il semble que le Delegate soit inopérant, donc pas de couleurs.
Le DataSource aussi d'ailleurs, semble-t-il ?
Réponses
Par contre, le delegate doit fonctionner.
OK pour le DataSource.
Le Delegate ne répond pas et je n'ai pas vu d'autre méthode qui semble adaptée.
La méthode n'est jamais appelée, alors que c'est la même que dans le 1.
Faut-il faire un binding sur le Delegate ? Si oui, je n'ai pas vu comment.
Bonsoir, _listeDelegate = [ListeDelegate new];
Je trouve ce code un peux bizarre, c'est quoi ListeDelegate ? ce n'est pas plutot OutlineViewCtrl le delegate de ta vue outlineView ?
Donc un truc du genre :
ListeDelegate est une sous classe de NSObject avec <NSOutlineViewDelegate> qui isole le delegate plutôt que de le fourrer dans OutlineViewCtrl.
Il y a
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
Ci-attaché, une application minimale view based + binding.
Bon, puisque je n'arrive pas à avoir fromage (clic de la souris) et dessert (couleur selon) le niveau, je choisis le fromage.
C'est à dire NSOutlineView view based avec binding.
Merci à tous.
Salut,
je pense avoir réussi à faire ce que tu veux.
En fait, dans un view-based outlineView, il n'y a pas de cell. Donc, les méthodes delegate ne sont pas appelées.
Tu peux t'en sortir avec d'autres méthodes déléguées.
ci-joint un toy project qui marche.
PS : tu aurais pu aussi t'en sortir en gérant à la main le datasource
Cola
J'ai aussitôt essayé ta modification.
Elle ne marche pas chez moi (Mavericks) : message
.../MainMenu.xib: Outlet 'delegate' of 'Text Field - Table View Cell' is connected to 'File's Owner,' an invalid destination (Objects inside view based table views may only be connected to the table view's delegate.)
Normal, car en mode binding, le NSOutlineViewDataSource est inopérant (remplacé par le binding, cf. Céroce), seul le NSOutlineViewDelegate est opérant.
Cela fait plusieurs jours que je tourne autour de la méthode :
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
Je n'arrivais pas à trouver le "level".
Miracle ! tu m'as fourni la solution :
long level = [self.outlineView levelForItem:item];
Le reste est sans problème.
Grâce à toi j'ai fromage ET dessert :
Content de t'avoir aidé
Essaye si tu veux cette nouvelle version. Elle ne devrait pas buguer.