[résolu] Problème de focus

HerveHerve Membre
mai 2013 modifié dans API AppKit #1

Bonjour,


 


Sur le GUI de mon futur synthé, des valeurs sont programmables par slider et par NSTextField. Le problème est que le NSTextField reste actif lorsque j'ai entré ma valeur, ce qui provoque des problèmes lorsque je tape par exemple la barre espace pour lancer le host sequencer. 


Il faudrait, lorsque j'ai tapé ma valeur dans le NSTextField (et tapé "enter") que ce NSTextField ne soit plus actif, mais neutre/inactif comme au départ.


J'ai cherché dans ce forum - il me semble avoir vu par le passé une discussion sur ce sujet - et j'ai testé plusieurs méthodes (setEnabled rend la fenêtre inutilisable, resignFirstResponder ne produit pas l'effet escompté, etc.), je n'ai rien trouvé. 


 


L'un ou l'une d'entre vous connaà®trait-il le "truc"? Merci par avance...


Réponses


  • [myWindow setNextResponder:self];//?
  • berfisberfis Membre

    Bonjour,


     


    Tu lies ton TextField à  une IBAction du style



    - (IBAction)deactivateOnEndEditing:(id)sender
    {
    [sender setSelectable:NO];
    }

    Une fois que tu as à  nouveau besoin d'éditer ton TextField, tu lui envoies setSelectable:YES.


  • HerveHerve Membre

    Merci berfis,


    Le problème, c'est qu'après on ne peut plus écrire dans le text field. Or, il faudrait...


    Si il n'y a pas mieux, je vais utiliser "mouseDown" dans la fenêtre principale et y mettre un "setSelectable sur tous les textField, à  moins qu'il n'y ait une fonction spécifique.


  • berfisberfis Membre


    ce qui provoque des problèmes lorsque je tape par exemple la barre espace pour lancer le host sequencer. 




    Ce ne serait pas plus simple de lancer ton "host sequencer" de manière plus HIG, genre commande? Tu pourrais utiliser Commande-Espace, et garder les touches normales pour ce qui est texte...

  • dans controlTextDidEnd: faire


    [laFenetre makeFirstResponder:nil];


  • HerveHerve Membre

    Non, le host est le maà®tre des lieux, le plug-in est une sous-fonction dedans, le host doit conserver toutes ses fonctions.


     


    En remettant "setSelectable" à  YES, on ne peut toutefois pas modifier la valeur écrite dedans. Bizarre. On ne peut que la sélectionner.


     


    (Il y a une méthode qui affiche les valeurs indépendamment de l'action sur le slider ou le textField : le moteur audio envoie ses notifications au GUI qui alors affiche les valeurs. Aussi a t-il été facile de mettre une fonction setEditable ailleurs que dans le IBAction).


     


    (En gros :


    action -> notification à  l'audio -> notification de l'audio au GUI -> affichage de la valeur.


     


    Cela permet lorsqu'on ouvre un projet musical que le GUI soit automatiquement mis à  jour).


  • HerveHerve Membre

    Merci mPergand, nous répondions en même temps.


     


    NSTextField ne semble pas répondre à  "makeFirstResponder:nil];"


     


    Je viens d'essayer...


     


    Ah là  là !!  ??? 

  • LA FENETRE !


  • Même la fenêtre ne répond pas :(


    Désespérant :(


    Pourtant j'ai fini par trouver une solution ici



    [[sender window] performSelector:@selector(makeFirstResponder:) withObject:nil afterDelay:0.0];

    ça, ça fonctionne alors que



    [[sender window] makeFirstResponder:nil];

    Ne marche pas pour une (obscure) raison que je n'ai plus envie de chercher ...


  • mpergandmpergand Membre
    mai 2013 modifié #11

    Envoyer ce message alors que le textfield est encore en edition ne doit pas marcher ...


     


    Mais dans la notification controlTextDidEnd ça devrait le faire.


  • berfisberfis Membre
    mai 2013 modifié #12



    [[sender window] performSelector:@selector(makeFirstResponder:) withObject:nil afterDelay:0.0];



    L'obscure raison est que cette instruction est effectuée lorsque la boucle d'événements principale est terminée, alors que l'autre est effectuée avant la fin de la boucle, et il peut se passer encore bien des choses après, qui peuvent changer la donne.


    Si jamais, il y a de jolies pages (profite, elles sont rarement illustrées dans la doc) ici:


    https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html


     


    @mpergand : j'ai testé, moyennant le performSelector, ça marche.


  • HerveHerve Membre

    Merci, la méthode fonctionne en effet. Merci berfis et mpergand pour votre aide, ainsi que laudema.


     


    Effectivement, ce n'était pas si simple....


  • laudemalaudema Membre
    mai 2013 modifié #14

    Quand même ça restait obscur et j'aurais passé quelques heures à  découvrir ce qui faisait que Cocoa ne se comportait pas comme la doc dit qu'il doit se comporter. Mais j'aime comprendre ..


    Et le coupable, comme souvent dans ces cas là  : les bindings.


    Si on supprime le binding du champ au NSArrayController alors la méthode fonctionne sans souci. Si on laisse le binding, alors, après qu'on ait fini l'édition et qu'on ait envoyé le focus sur la fenêtre (makeFirstResponder:nil) ,les bindings lui redonnent ce focus... D'où la nécessité du performSelector:withObject:afterDelay: ..


    Ouf, je me sens mieux  :)


  • HerveHerve Membre
    mai 2013 modifié #15

    Je poursuis cette discussion avec un problème un peu différent.


     


    Je voudrais afficher dans les NSTextField des float, mais avec deux décimales seulement.


    Si je fais :



    [inputLevelField setFloatValue:[NSString stringWithFormat:@%1.2f,[self inputLevelVal]]];


    le logiciel reconnaà®t alors une String, et non plus un float. Du coup il met les valeurs entières en dessous de ce float. Le fait d'entrer les valeurs via le NSTextField ne sert plus à  rien. (le moteur audio renvoie ses valeurs qui s'affichent, ce qui déclenche à  nouveau la procédure d'adresse. Ceci n'est pas très malin d'ailleurs...)


     


    Si je fais :



    [inputLevelField setFloatValue:[[NSString stringWithFormat:@%1.2f,[self inputLevelVal]]floatValue]];

    //ou :
    [inputLevelField setFloatValue:[self inputLevelVal]];

    toutes les décimales s'affichent alors, y compris dans le premier cas. Là , les valeurs demeurent celles souhaitées, mais pas l'affichage.


     


    Alors, hein, il pas embêtant ce problème??? 


     


    A moins que d'aucun en connaissent la solution? ::)


  • HerveHerve Membre

    Merci berfis, je vais regarder cela.


    En fait, en mettant la méthode "anti-focus"



    [[inputLevelField window] performSelector:@selector(makeFirstResponder:) withObject:nil afterDelay:0.0];

    non pas seulement dans la méthode d'affichage, mais aussi dans celle qui traite les données (le IBAction), j'ai résolu le problème. Je la mets deux fois tout simplement.


     


    Mais je vais regarder cette doc, merci encore.


Connectez-vous ou Inscrivez-vous pour répondre.