NSResponder affichage d'un menu (Anciennement NSResponder et les clics secondaires)

ThibautThibaut Membre
novembre 2012 modifié dans API AppKit #1
J'ai une sous-classe de NSResponder qui a besoin d'afficher un menu contextuel en cas de clic secondaire.



Réimplémenté la méthode rightMouseDown: aurait été trop simple. Apple a décidé de faire plus compliqué que cela.



Si je fais CTRL+Clic, ça passe dans mouseDown:.

Si je pose deux doigts sur mon trackpad et clic, il ne passe dans aucune des deux méthodes.

Je n'ai pas de souris sur moi, mais je suppose que si je fais un clic droit, rightMouseDown: sera appelé ?





Y a-t-il un moyen de capturer facilement tous les types de clics secondaires ?

Réponses

  • CéroceCéroce Membre, Modérateur
    novembre 2012 modifié #2
    Tu ne t'y prends pas comme il faut. Dans la logique d'Apple, ce n'est pas toi qui décide quelle action déclenche l'apparition du menu contextuel.

    Cette logique a du sens: on pourrait imaginer qu'une nouvelle version d'OS X décide que le menu s'affiche quand on met trois doigts sur le trackpad, ou un truc comme ça. Avec la technique d'Apple, ça fonctionnera.



    Regarde le chapitre Displaying a Contextual Menu de Application Menu and Pop-up List Programming Topics.

    A priori (jamais essayé), il n'y a qu'à  appeler setMenu: sur la NSView, on peut même le faire dans le XIB.
  • Malheureusement, définir le menu dans setMenu: ne fonctionne pas. Il ne se passe rien.

    J'ai un NSTextField désactivé dans mon NSResponder. Je pense que c'est lui qui doit poser problème.
  • CéroceCéroce Membre, Modérateur
    Le NSResponder serait le nextResponder du NSTextField et lui seulement ?
  • Ce n'était pas le cas, mais même en le mettant, ça ne change rien...
  • Dans ta sous classe de NSView implémente :



    menuForEvent:

    Overridden by subclasses to return a context-sensitive pop-up menu for a given mouse-down event.

    - ([url="file:///Xcode2.5/ADC%20Reference%20Library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSMenu_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSMenu"]NSMenu[/url] *)menuForEvent:([url="file:///Xcode2.5/ADC%20Reference%20Library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSEvent"]NSEvent[/url] *)theEvent

    Parameters

    theEvent

    An object representing a mouse-down event.

    Discussion



    The receiver can use information in the mouse event, such as its location over a particular element of the receiver, to determine what kind of menu to return. For example, a text object might display a text-editing menu when the cursor lies over text and a menu for changing graphics attributes when the cursor lies over an embedded image.

    The default implementation returns the receiver's normal menu
  • ça ne passe pas dedans.
  • Il faut que ta vue soit first responder.
  • ThibautThibaut Membre
    novembre 2012 modifié #9
    Et quand c'est le clic qui doit rendre la vue firstResponder et afficher le menu ?



    (À la limite, je n'ai même pas besoin que ça passe en firstResponder, mais que ça affiche tout de même le menu.)
  • mpergandmpergand Membre
    novembre 2012 modifié #10
    <br />
    -(void) rightMouseDown:(NSEvent*) event<br />
    {<br />
      [[self window] makeFirstResponder:self];<br />
    }<br />
    




    Il faut aussi retourner YES dans - (BOOL)acceptsFirstResponder
  • Sauf que le "2-fingers click", avec un trackpad, ne passe pas là  dedans. Et ça revient donc à  mon problème initial.
  • De toute manière, même en firstResponder, ça ne passe pas dedans.
  • et control-clic ?
  • Non plus.
  • mpergandmpergand Membre
    novembre 2012 modifié #15
    Montre ton code et c'est quoi ta sous classe ?



    Sinon tu le fais directement dans rightMouseDown:
    <br />
    [color=#666600]-([/color][color=#000088]void[/color][color=#666600])[/color][color=#000000] rightMouseDown[/color][color=#666600]:[/color][color=#660066]NSEvent[/color][color=#666600]*)[/color][color=#000000] [/color][color=#000088]event[/color]<br />
    [color=#666600]{[/color]<br />
    [color=#000000]  [/color][color=#666600][[[/color][color=#000088]self[/color][color=#000000] window[/color][color=#666600]][/color][color=#000000] makeFirstResponder[/color][color=#666600]:[/color][color=#000088]self[/color][color=#666600]];[/color]<br />
    										<br />
    [NSMenu popUpContextMenu:theMenu withEvent:theEvent forView:self];						<br />
    }
    
  • J'ai réadapté rapidement le concept que je cherche à  faire.

    Il y a quelques bugs sur les keyView, mais ce n'est pas ce qui m'importe pour le moment.



    En gros, dans ma vue Custom, dès que je fais "entrer" dans le texteField, il se désactive (et sera certainement remplacé par un autre textField).

    La vue devient alors firstResponder. Si l'on fait Delete, le textField redevient éditable (dans ma vraie application, la vue complète sera supprimée). Mais je veux pouvoir faire un delete avec la souris, grâce à  un menu contextuel.
  • J'ai ajouté un drawRect pour voir où se trouve ta custom view, en fait tout marche, le menu apparaà®t bien et la méthode rightMouseDown ne sert à  rien.
  • Pas chez moi. Aucun menu ne s'affiche.
  • ThibautThibaut Membre
    novembre 2012 modifié #19
    J'ai pu me pencher un peu plus sur le problème, c'est la NSImageView qui me bloque tout. Si je retire les méthodes mouseDown... ainsi que l'imageView, ça fonctionne.



    Edit:

    Du coup, le moyen de résoudre mon problème est :

    - Soit d'attribuer le menu à  l'imageView

    - Soit de changer le type de ma vue en imageView et retirer celle à  l'interieur.



    Cependant, le ctrl+clic ne fonctionne toujours pas.



    Edit 2:

    Dans mouseDown:
    <br />
    if ( theEvent.modifierFlags &amp; NSControlKeyMask )<br />
    	    [self rightMouseDown:theEvent];<br />
    




    Mais je ne trouve pas ça très propre...
Connectez-vous ou Inscrivez-vous pour répondre.