Changement dynamique d'un type de NSCell dans une NSTableColumn

Eddy58Eddy58 Membre
19:03 modifié dans API AppKit #1
Je voudrais savoir s'il est techniquement possible de changer dynamiquement le type de sous-classe d'une NSCell dans une NSTableColumn, et cela pour une row donnée.
Là  par exemple j'ai une NSTableColumn initialisée avec des NSComboBoxCell dans IB. Dans certains cas, pour une row particulière, il me faudrait pouvoir changer la NSComboBoxCell en NSTextFieldCell pour empêcher l'utilisation du ComboBox et visualiser seulement du texte. Bon, il est tout simplement possible de régler la cell en faisant un "setEnabled:NO" dessus pour régler le problème, mais ça serait bien mieux de faire disparaà®tre la NSComboBoxCell. (En faites de la changer en NSTextFieldCell) :D
Dans une NSTableColumn avec des NSButtonCell de type switch, au lieu de faire un "setEnabled:NO" sur une cell pour empêcher l'utilisation de son bouton, je fais un "setImagePosition:NSNoImage", pour faire disparaà®tre le bouton. Donc j'aimerais appliquer le même principe pour la colonne avec les ComboBox.
Si quelqu'un a une idée ou qu'il a déjà  expérimenté la chose, qu'il me fasse signe. 8)

Réponses

  • mpergandmpergand Membre
    19:03 modifié #2
    Essayes dataCellForRow de NSTableColumn ;)
  • Eddy58Eddy58 Membre
    19:03 modifié #3
    Merci mpergand  :D
    Bon ça demande de sous-classer NSTableColumn, mais je vais essayer ça. ;)
  • Eddy58Eddy58 Membre
    19:03 modifié #4
    Bon koi encore que ça ? ;)
    Je fais un essai en voulant simplement remplaçer la NSTextfieldCell de la row 0 par un NSButtonCell, mais le problème est qu'au lancement de l'appli, j'ai des messages d'erreur puis un SIGTRAP pour clore le tout. :'(

    <br />[Session started at 2004-11-08 15:36:38 +0100.]<br />2004-11-08 15:37:47.379 Axe Z[514] *** -[NSButtonCell setDrawsBackground:]: selector not recognized<br />2004-11-08 15:37:47.453 Axe Z[514] An uncaught exception was raised<br />2004-11-08 15:37:47.615 Axe Z[514] *** -[NSButtonCell setDrawsBackground:]: selector not recognized<br />2004-11-08 15:37:47.616 Axe Z[514] *** Uncaught exception: &lt;NSInvalidArgumentException&gt; *** -[NSButtonCell setDrawsBackground:]: selector not recognized<br /><br />Executable ?Axe Z? has exited due to signal 5 (SIGTRAP).<br />
    


    Je ne comprend pas cet appel à  la méthode setDrawsBackground: que je ne demande pas dans mon code, et qui de plus est pour les NSTextfieldCell ?

    <br />-(id)dataCellForRow:(int)row<br />{<br />   id cell=[super dataCellForRow:row];<br />       <br />  if (row==0)<br />       {<br />         [cell release];<br />           NSButtonCell *cell2=[[NSButtonCell alloc] init];<br />          [cell2 setButtonType:NSSwitchButton];<br />             [cell2 setImagePosition:NSImageOnly];<br />             [cell2 setTitle:@&quot;&quot;];<br />           return cell2;<br />     }<br /> else<br />      {<br />         return cell;<br />      }<br />}<br />
    

    J'ai fait une sous-classe de la NSTableColumn dans IB, et elle est avec des NSTextFieldCell par défaut.
    Je commence par releaser la cell que je veux remplacer en row 0, puis ensuite j'initialise la NSButtonCell, que je retourne ensuite. Le problème est-il au niveau de la release de la NSTextfieldCell ? Je voudrais bien savoir où ça ne va pas.... :-\
  • mpergandmpergand Membre
    19:03 modifié #5
    Salut,

    Je n'ai jamais essayé ce genre de truc, mais je ne ferais pas de release sur le cell de la table, j'initialiserais un NSButtonCell au démarrage et puis dans dataCellForRow:
    <br />-(id)dataCellForRow:(int)row<br />{       <br /> if (row==0)<br />       {<br />         return buttonCell;<br />       }<br />        else<br />        {<br />          return [self dataCell];<br />       }<br />}<br /><br />
    
  • Eddy58Eddy58 Membre
    19:03 modifié #6
    Effectivement mpergand, le release de la cell n'a pas a être effectué, vu que je ne l'ai pas alloué moi-même, d'où les messages d'erreur. J'ai modifié mon code selon ta proposition, plus de messages d'erreur, mais un plantage SIGBUS maintenant...
    Je continue mes recherches....

    <br />-(id)init<br />{<br />        self=[super init];<br />        buttonCell=[[NSButtonCell alloc] init];<br />   [buttonCell setButtonType:NSSwitchButton];<br />        [buttonCell setImagePosition:NSImageOnly];<br />        [buttonCell setTitle:@&quot;&quot;];<br />      return self;<br />}<br /><br />-(void)dealloc<br />{<br />      [buttonCell release];<br />       [super dealloc];<br />}<br /><br />-(id)dataCellForRow:(int)row<br />{<br />  if (row==0)<br />       {<br />         return buttonCell;<br />        }<br /> else<br />      {<br />         return [self dataCell];<br />           //return [super dataCellForRow:row];<br />      }<br />}<br />
    
  • mpergandmpergand Membre
    19:03 modifié #7
    Je pense qu'il faut que dans objectValueForLocation, tu renvoies une valeur différente en fonction du type de cell (bool ou text)
  • BruBru Membre
    19:03 modifié #8
    Je soupçonne un problème dans ton implémentation :

    Normalement, chaque colonne possède une NSCell de référence (ou de prototype), et cette dernière est théoriquement utilisée (par copie) pour l'affichage du contenu des cellules de chaque colonne...

    Maintenant, que se passe t'il si lors de l'affichage d'une cellule, le système pense avoir affaire à  une NSTextFieldCell (qui répond au message setDrawsBackground: ) car c'est celle qui est prototype, alors que réellement, c'est une NSButtonCell qui est utilisée (et qui ne répond pas à  setDrawsBackground: )

    Cela mériterait quelques tests pour valider/invalider cette théorie...

    .
  • Eddy58Eddy58 Membre
    19:03 modifié #9
    J'ai créé un projet d'essai, avec un NSTableView de base avec deux colonnes dedans. Ensuite j'ai sous-classé la première colonne, puis inséré le code dataCellForRow: dans mon post ci-dessus.
    Pour essayer j'ai lancé l'appli, sans problème mais rien n'apparaà®t dans la colonne car il n'y a pas de datasource. Ensuite j'ai fait un contrôleur où j'ai mis des datasources minimums, et puis au lancement de nouveau plantage SIGBUS....:(
    Je voulais justement régler les valeurs selon le cas textfield ou switchbutton dans la datasource, mais apparemment il y a encore un problème dans dataCellForRow, ce qui fait planter les datasources je pense. Je vais essayer d'initialiser la NSButtonCell avec setObjectValue.
    :crackboom:-
  • Eddy58Eddy58 Membre
    19:03 modifié #10
    Haaaaa !  :D
    A la recherche d'un bout de code sur le net pour me débloquer, j'ai trouvé
    sur ce site Japonais (merci les amis Cocoaà¯stes du soleil levant :)) ce qui n'allait pas. Il faut également spécifier la fonte lors de l'initialisation de la cell, et c'est de là  que venait le plantage. Maintenant je vais pouvoir apporter les modifs qui le font bien dans mon projet. ;D :D :spot:

    <br />-(id)dataCellForRow:(int)row<br />{<br />     if (row==0 || row==2)<br />     {<br />         NSButtonCell *buttonCell=[[[NSButtonCell alloc] init] autorelease];<br />               [buttonCell setButtonType:NSSwitchButton];<br />                [buttonCell setImagePosition:NSImageOnly];<br />                [buttonCell setTitle:@&quot;&quot;];<br />              [buttonCell setFont:[[self dataCell] font]];<br />              return buttonCell;<br />        }<br /> else<br />      {<br />         return [self dataCell];<br />   }<br />}<br />
    
  • mac_manumac_manu Membre
    19:03 modifié #11
    Très intéressant ce sujet. Je me suis permis de tester pour mon appli., et ça marche. Maintenant, en ce qui me concerne, j'aimerais pouvoir utiliser un NSPopUpButtonCell à  la place du NSSwitchButton, mais je n'arrive pas à  obtenir les 2 petites flèches noires superposées comme celles qui se trouvent dans I.B. Est-ce que quelqu'un c'est comment y arriver? (actuellement, seul un NSPopUpButton type Aqua apparaà®t dans ma Cell.)
    Merci :why?:
  • 19:03 modifié #12
    Tu dois faire quand tu crées ta cellule:
    [cell setBordered:NO];
    

    Ou si c'est pour toute la colonne, c'est faisable directement dans IB.
  • mac_manumac_manu Membre
    19:03 modifié #13
    Super, ça marche et c'est exactement cela que je voulais... il ne me reste plus qu'à  écrire le code pour gèrer le changement opérer par le choix de l'utilisateur via le popUpButton!
Connectez-vous ou Inscrivez-vous pour répondre.