Récupérer le click d'une NSView quelconque pour effectuer une action

Bonjour,


 


Je construis une NSTableView qui est view-based.


Les éléments de cette NSTableView sont eux-mêmes d'autres vues (NSView), quelconques.


 


Je souhaiterais intercepter les clicks sur ces NSView.


 


En effet, quand on clique sur ces NSView, la ligne correspondante de la NSTableView n'est pas sélectionnée.


 


Comment dois-je faire ?


 


Voici une idée. Comme c'est nouveau pour moi (je n'ai jamais fait de protocole), je voulais avoir votre avis.


 


Dois-je passer par les @protocol et demander que les vues qui peuplent ma NSTableView se conforment au protocole ? Et, dans ce protocole, réimplémenter la méthode - mouseDown. Mais, comment le protocole va savoir qui est la NSTableView (pour setter la sélection) ? Ajouter une @property delegate et la setter à  ma NSTableView, avec une méthode déléguée pour gérer le click ?


 


Merci !


Colas


Réponses

  • CéroceCéroce Membre, Modérateur

    Je n'ai jamais travaillé avec les NSTableView basées sur des NSViews, mais je permets de douter de cette affirmation:


     




    En effet, quand on clique sur ces NSView, la ligne correspondante de la NSTableView n'est pas sélectionnée.




     


    L'implémentation par défaut de -[NSView mouseDown:] retransmets l'événement à  son next responder, ici très probablement la table. Je pense donc que la cellule est bien sélectionnée, mais que tu ne le vois pas, parce que ta vue n'est pas transparente. Dis-moi si je me trompe.


     


    (D'après ce que j'ai trouvé sur le net, la sélection se joue sur une ligne entière aussi, NSTableRowView possède bien une propriété 'selected' pour changer d'apparence quand elle est sélectionnée).


  • colas_colas_ Membre
    janvier 2014 modifié #3

    Salut Céroce.


     


    Tu ne te trompes pas et j'ai dû chercher un peu pour reproduire ce comportement sur un exemple minimal.


    Je joins le projet à  ce post.


     


    En fait tu as raison si la vue-fille contient un NSTextField et que je clique dedans.

    Mais, si j'ai un NSTextView, là  ça bugue.


     


    En fait, j'aimerais que quand je clique sur le NSTextView je rentre directement dedans (pas besoin de cliquer une fois pour sélectionner la ligne, puis une fois pour rentrer l'éditeur, comme pour le NSTextField) mais qu'en plus la ligne soit sélectionnée.


     


    Merci


  • CéroceCéroce Membre, Modérateur
    Je ne connais pas la réponse. Il semble que la méthode déléguée textView:clickedOnCell:inRect:atIndex: soit appelée quand la textview est cliquée.

    Tu pourrais alors sélectionner la cellule correspondant à  la text view, sachant que ta custom view est la superview de la textview, et je crois que NSTableView a une méthode qui renvoie la position d'une cellule en fonction de la vue qu'elle contient.
  • berfisberfis Membre
    janvier 2014 modifié #5

    Essaie de déclarer la sélection de la NSTableView à  "None".


     


    Ou alors, sous-classe NSTextView pour qu'il informe le contrôleur que la sélection a changé. Je me demande si les méthodes de délégation ne suffiraient pas dans ce but...


  • Utilise NSTableRowView ça permet d'automatiser tout ça ;)


    Le sample de chez Apple qui permet de bien comprendre comment tout cela fonctionne s'appelle HoverTableDemo.




  • Utilise NSTableRowView ça permet d'automatiser tout ça ;)


    Le sample de chez Apple qui permet de bien comprendre comment tout cela fonctionne s'appelle HoverTableDemo.




    1. NSTableRowView "n'automatise" rien du tout. Tu dois sous-classer et t'amuser un peu...  :D


    2. HoverTableDemo... prévoir une soirée calme, tout de même...

  • J'ai sous-classé NSTextView et j'ai overridé - mouseDown.


    J'ai quand même utilisé NSTableRowView que je connaissais pas mais qui semble mieux que NSTableCellView.


     


    Au passage, j'ai trouvé cette méthode (cf. http://stackoverflow.com/questions/13572547/nstableview-select-row-and-respond-to-mouse-events-immediately/13579469#13579469), qui pourra vous intéresser. Ici, elle ne me sert à  rien mais je l'ai quand même prise.




    - (BOOL)validateProposedFirstResponder:(NSResponder *)responder
                                  forEvent:(NSEvent *)event
    {
        // This allows the user to click on controls within a cell withough first having to select the cell row
        return YES;
    }
  • Du coup, je suis confronté à  un autre problème.


    En sous-classant NSTextView eten overridant - mouseDown, je ne peux plus sélectionner de texte. Cela n'est pas dû au contenu de la méthode, car je sous-classe et que j'override en ne mettant rien dans la méthode - mouseDown, le problème est encore là .


     


    Je vais voir comment régler ça.

  • CéroceCéroce Membre, Modérateur
    Appelle [super mouseDown:] dans ta méthode mouseDown:.
  • Suis-je bête... ! Merci !


  • Sinon, pour suivre les bons conseils d'Apple et éviter le sous-classement, tu peux déclarer ton contrôleur (ou tout autre objet) comme délégué de ton NSTextView et y implémenter la méthode:



    - (NSRange)textView:(NSTextView *)aTextView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange
    {
    NSLog(@Click into);
    return newSelectedCharRange;
    }

    Le (petit) problème, c'est que la méthode est appelée à  chaque frappe (puisque la sélection change). Mais au moins tu laisses NSTextView tel quel. Ne pas oublier de retourner newSelectedCharRange...


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