NSButton et NSUserDefaults

23:00 modifié dans API AppKit #1
Bonjour,

Voila mon problème : pour mon application (la même que dans le sujet sur la désallocation des cellules d'un NSMatrix) j'ai uen fenêtre de préférences avec des NSButtons de type switch. Suivant que l'utilisateur les active ou pas il fait passer la valeur d'une clé de NSUserDefaults à YES ou NO. Jusque là pas de problème ça marche impec.

Par défaut les valeurs de NSUserDefaults sont toutes à vrai ce qui fait que la première fois que l'utilisateur lance l'application, tout les bouttons doivent être cochés, mais les fois suivantes s'il en a décoché un il doit resté décoché, il faut donc que lorsque j'ouvre la fenêtre de préférences j'initialise l'état des NSButtons en fonction de l'état de mon NSUserDefaults. Ce que j'ai fait ainsi :

<br />-(void) windowDidBecomeKey: (NSNotification *) aNotification<br />{<br />      NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];<br /> <br />  [buttonRevenus setState: [defaults integerForKey:@&quot;displayRevenus&quot;]];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ......<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .....<br />}<br />


Et là ça ne marche pas comme je le voudrais. L'état des bouttons n'est correct que si la valeur de la clé correspondante est à NO (ie n'est pas la valeur par défaut). Des idées sur le pourquoi du comment ?

Réponses

  • BruBru Membre
    23:00 modifié #2
    Tu mélanges un booléen (YES NO) provenant des UsersDefaults avec un int réclamé par setState de NSButton.

    Pour que ça marche, il faut faire quelque chose comme ça :

    <br />...<br />† † if ([defaults boolForKey:@&quot;displayRevenus&quot;]) [buttonRevenus setState:NSOnState];<br />† † else [buttonRevenus setState:NSOffState];<br />...
    


    .
  • 23:00 modifié #3
    ou  plus court:
    [buttonRevenus setState:[defaults boolForKey:@&quot;displayRevenus&quot;]?NSOnState:NSOffState];
    
  • ClicCoolClicCool Membre
    23:00 modifié #4
    Bon, là je ramène ma fraise ;)

    Il suffirait, dans I.B. de faire un Binding entre chaque Switch et la clef associée par le NSUserDefaultsController.

    Plus besoin d'initialiser le switch, même plus besoin de modifier soi-même les UserDefaults à chaque modif du switch etc ...

    C'est de loin le plus cool (et ça marche pas seulement pour les switchs) :P
  • 23:00 modifié #5
    Seulement les bindings sont à oublier si on veut faire une application compatible avec autre chose que Panther. (et en particulier GNUStep comme c'est le cas ici...)
  • ClicCoolClicCool Membre
    23:00 modifié #6
    Fort juste,en effet† ;D
    Dans le dédale des fils de discussion, j'en avais perdu le fils du projet de notre ami (exposé en fait dans "désallocation des cellules d'un NSMatrix").
  • 23:00 modifié #7
    dans 1087407923:

    Tu mélanges un booléen (YES NO) provenant des UsersDefaults avec un int réclamé par setState de NSButton.


    Ben non, je fait un integerForKey donc ça me renvoie un int (1 pour YES et 0 pour NO). De plus si on regarde ce que sont NSOnState et NSOffState, ce sont uniquement un 1 et un 0.

    Le bout de code suivant par exemple :
    <br />   if ([defaults boolForKey:@&quot;displayRevenus&quot;])<br />    {<br />         [buttonRevenus setState: [defaults integerForKey:@&quot;displayRevenus&quot;]];<br />           NSLog(@&quot;%i&quot;,[buttonRevenus state]);<br />             if ([buttonRevenus state] == NSOnState)<br />           {<br />                 NSLog(@&quot;ok&quot;);<br />           }<br /> }<br /> NSLog(@&quot;%i&quot;,NSOnState);                       <br />  NSLog(@&quot;%i&quot;,NSOffState);      <br />
    


    va me renvoyer dans les logs :

    2004-06-17 08:50:59.500 WRP[1614] 1
    2004-06-17 08:50:59.500 WRP[1614] ok
    2004-06-17 08:50:59.500 WRP[1614] 1
    2004-06-17 08:50:59.500 WRP[1614] 0

    Bon, ceci dit je vais tout de même tester en faisant comme tu dis mais je ne comprends pas pourquoi ça ne marcherais pas selon ma méthode.

    PS : et pour ClicCool, non je ne ferais pas de binding pour deux bonnes raisons. La première c'est qu'ils ne sont pas disponibles sous Mac OS X 10.2 et la deuxième c'est qu'ils ne sont pas disponibles sous GNUstep non plus. Et la troisième, c'est qu'avant d'essayer les bindings je préfère découvrir la méthode ancestrale et donc go?ter pleinement l'intérêt des bindings le jour où je les essaierais :-)
  • ClicCoolClicCool Membre
    23:00 modifié #8
    dans 1087455043:

    PS : et pour ClicCool, non je ne ferais pas de binding pour deux bonnes raisons. La première c'est qu'ils ne sont pas disponibles sous Mac OS X 10.2 et la deuxième c'est qu'ils ne sont pas disponibles sous GNUstep non plus. Et la troisième, c'est qu'avant d'essayer les bindings je préfère découvrir la méthode ancestrale et donc go?ter pleinement l'intérêt des bindings le jour où je les essaierais :-)


    Tes trois raisons se tiennent c'est sur !
    Pour les 2 premères ce sera toujours le cas.
    Pour la troisième c'est s?r tu appréciera et maitrisera d'autant mieux que tu connais la compléxité de ce qu'ils gèrent :)
    Mais sur ce dernier point tu n'as pas l'air d'être si loin du chemin† ;D
  • BruBru Membre
    23:00 modifié #9
    dans 1087455043:
    Ben non, je fait un integerForKey donc ça me renvoie un int (1 pour YES et 0 pour NO).


    Ce n'est que partiellement exact... Un NO renvoie bien un int à 0, mais un YES ne renvoie pas toujours un int 1...
    Il faut interpréter le YES comme "une valeur différente de 0 ou non-nulle". Va savoir ce que renvoie le cast quand il y a conversion d'un booléen à YES vers un char (qui est le format de stockage du booléen) puis vers un int ?

    .
  • 23:00 modifié #10
    Oui ! Ca marche, j'ai utilisé le code donné par Bru et ça marche impec. J'ai préféré celui de Bru à celui de Arldon pour des questions de lisibilité du code.

    Merci à tous et à bientôt pour une nouvelle question (sur des problèmes d'encodage de caractère cette fois).
  • nucleusnucleus Membre
    23:00 modifié #11
    Je rajouterai que le state d'un bouton peut prendre plus que deux valeurs différentes (il y aussi NSMixedState), donc envoyer directement un boolean (qui n'a que deux valeur possible) n'était pas très recommandable à l'origine..

    Je conseillerai aussi de mettre le nom de ta clé dans une constante ou un define, car tu va probablement l'utiliser à plusieurs endroits...
Connectez-vous ou Inscrivez-vous pour répondre.