Détecter un clic sur la barre de titre d'une fenêtre

ChachaChacha Membre
16:42 modifié dans API AppKit #1
Salut,

Je cherche comment détecter un clic sur la barre de titre d'une fenêtre. Détecter le double-clic, à  la limite, c'est facile : ça appelle "miniaturize". Mais un simple clic ?

+
Chacha

Réponses

  • BruBru Membre
    16:42 modifié #2
    A part sous-classer NSWindow pour gérer les événements toi-même, je ne vois pas trop...

    Avec cette méthode, tu surcharges la méthode mouseDown:, puis tu vérifies que le clic eu lieu dans la structureView (view qui affiche la structure de la fenêtre) et plus particulièrement dans la barre de titre.

    .
  • 16:42 modifié #3
    En plus <i>miniaturize</i> n'est pas forcément appellé (selon les prefs. utilisateur).
  • ChachaChacha Membre
    16:42 modifié #4
    dans 1127466764:

    A part sous-classer NSWindow pour gérer les événements toi-même, je ne vois pas trop...
    Avec cette méthode, tu surcharges la méthode mouseDown:, puis tu vérifies que le clic eu lieu dans la structureView (view qui affiche la structure de la fenêtre) et plus particulièrement dans la barre de titre.

    Je suis d'accord avec toi sur le principe, mais malheureusement, sous-classer NSWindow et surcharger son mouseDown: ne concerne que l'intérieur de la fenêtre, pas la barre de titre.

    +
    Chacha
  • 16:42 modifié #5
    Si c'est pour déplacer la fenêtre et utiliser le mousedown pour point de départ, tu peux peut être te servir de mouseDragged qui lui fonctionne même depuis la barre de titre...
    Supposition : la barre de title est-elle une sous-vue ?
  • ChachaChacha Membre
    16:42 modifié #6
    dans 1127476299:

    Si c'est pour déplacer la fenêtre et utiliser le mousedown pour point de départ, tu peux peut être te servir de mouseDragged qui lui fonctionne même depuis la barre de titre...

    Ah, non, ce n'est pas pour le déplacement que j'en ai besoin, mais c'est déjà  intéressant de savoir que le mouseDragged marche et pas le mouseDown.


    Supposition : la barre de title est-elle une sous-vue ?

    Et si oui, comment y faire référence ? Je me pose aussi la question.

    +
    Chacha
  • BruBru Membre
    16:42 modifié #7
    dans 1127476606:


    Supposition : la barre de title est-elle une sous-vue ?

    Et si oui, comment y faire référence ? Je me pose aussi la question.


    La barre de titre est dessinée dans la structure view qui est la NSView de plus haut niveau. Un [tt][[window contentView] superview][/tt] permet de retourner cette vue.

    .
  • ChachaChacha Membre
    septembre 2005 modifié #8
    dans 1127476851:

    La barre de titre est dessinée dans la structure view qui est la NSView de plus haut niveau. Un [tt][[window contentView] superview][/tt] permet de retourner cette vue.

    Ah, c'était ça la structureView ? Jamais entendu parler, et pour cause :


    When it?s created, an NSWindow automatically creates two NSViews: An opaque frame view that fills the frame rectangle and draws the border, title bar, other peripheral elements, and background, and a transparent content view that fills the content rectangle. The frame view and its peripheral elements are private objects that your application can?t access directly. The content view is the ?highest? accessible NSView in the NSWindow; you can replace the default content view with an NSView of your own creation using the setContentView: method. The NSWindow determines the placement of the content view; you can?t position it using NSView?s setFrame... methods, but must use NSWindow?s placement methods, described in ?Opening and Closing Windows?.


    Du coup, a-t-on vraiment le droit de taper dedans ?
    De toutes façons, je me vois mal "remplacer" cette view par une sous-classe qui me permet de redéfinir le comportement lors d'un clic simple. Si encore NSView implémentait le NSCopying...
    Oh, j'ai une idée :
    Je fais une catégorie de NSView qui lance une notification lors d'un mouseDown !

    [edit]
    Et ben non, ça marche pas. La barre de titre ne doit pas être une NSView.
    [/edit]
    +
    Chacha
  • Eddy58Eddy58 Membre
    16:42 modifié #9
    J'ai retrouvé cette fameuse astuce made in ClicCool : :p :)

    En fait le pb vient du fait qu'une NSWindow ne propose pas d'appel possibles directement à  la barre de titre 
    Pas d'appel non plus pour personaliser la NSWindowDocumentIconButton !!  (ou alors j'ai pas trouvé)
    J'ai essayé de torpiller  _miniIcone mais cette propriété (comme les autres) est protégée ...

    J'étais à  2 doights de poster sur OC alors que je cherchais aussi à  "dévier" les boutons par défault de la barre de titre, seuls éléments dont Cocoa nous permets l'accès: (- (NSButton *)standardWindowButton:(NSWindowButton)button )

    Et tout en essayant de trifouiller ces boutons pour les "personnaliser" à  mon gout et surtout en voulant dans la foulée les repositionner ....
    ... ben j'ai fait appel à  la superView ....

    ... et Fiat Lux !

    [[maFenetre standardWindowButton:button] superview] ...

    ça renvoie la vue où est dessinée la barre de titre !!!

    Dès lors plus besoin du "button" que j'ai appellé, j'ai maintenant sa supervue ... reste plus qu'à  y glisser mon ProgressBarreIndicator et à  le positionner et le tour est joué ! (j'y ai même glissé un NSButton parfaitement opérationnel pour tester  )
  • ChachaChacha Membre
    16:42 modifié #10
    dans 1127518688:

    J'ai retrouvé cette fameuse astuce made in ClicCool : :p :)

    C'est comme le [contentView superview] de Bru, non ?

    +
    Chacha
  • Eddy58Eddy58 Membre
    16:42 modifié #11
    Non, je ne pense pas, la superview retournée dans la cas de Bru est celle de la fenêtre, tandis que dans l'autre cas, c'est la superview du bouton dans la barre de titre. Ce que je ferais, c'est récupérer cette superview de la barre de titre, y insérer un bouton invisible de la taille de cette view, et avec l'action associée à  ce bouton tu sais quand la barre de titre a été cliquée. :)
  • ChachaChacha Membre
    16:42 modifié #12
    dans 1127559176:

    Non, je ne pense pas, la superview retournée dans la cas de Bru est celle de la fenêtre, tandis que dans l'autre cas, c'est la superview du bouton dans la barre de titre. Ce que je ferais, c'est récupérer cette superview de la barre de titre, y insérer un bouton invisible de la taille de cette view, et avec l'action associée à  ce bouton tu sais quand la barre de titre a été cliquée. :)

    D'après mes essais, si, ça revient au même :
    Une fenêtre contient une "_borderView", qui est la vue recouvrant l'ensemble de la fenêtre.
    La borderView a 4 sous-vues:
    -la contentView qui laisser une marge supérieure pour la barre de titre
    -les 3 boutons

    Donc la barre de titre, ce n'est jamais que l'espace libre au-dessus de la contentView.

    Ma nouvelle idée (pas encore eu le temps d'essayer), c'est d'injecter une vue à  cet endroit, à  droite des boutons. De cette façon, je peux sous-classer et intercepter les événements. Je vous tiens au courant.

    +
    Chacha
  • BruBru Membre
    16:42 modifié #13
    dans 1127559176:

    Non, je ne pense pas, la superview retournée dans la cas de Bru est celle de la fenêtre, tandis que dans l'autre cas, c'est la superview du bouton dans la barre de titre.


    Non, la fenêtre est composée d'une NSView qui contient la contentView, et les NSButton éventuels.

    Le titre est "dessiné" dans une NSCell qui sera affichée dans cette NSView principale.

    .
  • BruBru Membre
    16:42 modifié #14
    Chacha, que cherches-tu à  faire exactement ?

    Juste détecter le clic (et déclencher une méthode personnelle) tout en laissant la fenêtre répondre à  ce clic en démarrant une session de déplacement...

    ... ou intercepter le clic pour que :
    1- la fenêtre n'entame pas une session de déplacement.
    2- une méthode personnelle se déclenche.

    ?
  • ChachaChacha Membre
    16:42 modifié #15
    dans 1127568168:

    Chacha, que cherches-tu à  faire exactement ?
    (...)
    2- une méthode personnelle se déclenche.

    Je voudrais déclencher une méthode personnelle, sans altérer les déplacements par dragging.
  • BruBru Membre
    16:42 modifié #16
    Alors, j'ai peut-être une solution.

    Le delegate windowWillMove: de NSWindow est appelé dès le clic sur la barre de titre, même sans mouvement de la souris (qui provoque le déplacement).

    Dès lors, après récupération des coords du clic, un simple test (NSMouseInRect) te permet de déclencher ce que tu veux faire...

    <br />- (void)windowWillMove:(NSNotification *)notif<br />{<br />    NSPoint p;<br /><br />    // récupération du dernier NSEvent (celui du clic)<br />    // puis récupération de la position de la souris.<br />    p=[[wnd currentEvent] locationInWindow];<br /><br />    // on soustrait la taille verticale de la fenêtre<br />    // pour inverser les coordonnées du clic<br />    // (0 pour la ligne la plus haute de la barre de tritre)<br />    p.y=[wnd frame].size.height-p.y;<br /><br />    // enfin, je fais ce que j&#39;ai à  faire...<br />&nbsp; &nbsp; if (NSMouseInRect(p, NSMakeRect(70, 4, 16, 16), NO))<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;...&quot;);<br />&nbsp; &nbsp; }<br />}<br />
    


    .
  • ChachaChacha Membre
    16:42 modifié #17
    dans 1127574663:

    Alors, j'ai peut-être une solution.

    Le delegate windowWillMove: de NSWindow est appelé dès le clic sur la barre de titre, même sans mouvement de la souris (qui provoque le déplacement).


    Oui, c'est une bonne idée !
    Mais en fait, ça ne va pas pour ce que je veux faire; j'aurais du être plus précis.
    Ce que je veux, c'est "replier" l'inspecteur quand on clique sur la barre de titre. Donc il me faut détecter mouseDown et mouseUp, car le drag annule le repliement. Il y a moyen d'accéder à  la NSCell contenant le titre de la fenêtre ?

    +
    Chacha
  • BruBru Membre
    16:42 modifié #18
    dans 1127665995:
    Mais en fait, ça ne va pas pour ce que je veux faire; j'aurais du être plus précis.


    Chacha, j'aurais su ce que tu voulais faire beaucoup plus tôt, tu aurais eu une solution beaucoup plus tôt...


    dans 1127665995:
    Il y a moyen d'accéder à  la NSCell contenant le titre de la fenêtre ?


    Veux-tu vraiment jouer avec des undocumented ?


    dans 1127665995:
    Ce que je veux, c'est "replier" l'inspecteur quand on clique sur la barre de titre. Donc il me faut détecter mouseDown et mouseUp, car le drag annule le repliement.


    Voici la solution à  ta question :
    <br />- (void)windowWillMove:(NSNotification *)notif<br />{<br />    NSPoint p;<br />    NSEvent *ev;<br /><br />    // récupération des coords du clic (Mouse-Down)<br />    p=[[wnd currentEvent] locationInWindow];<br /><br />    // maintenant, on attend le prochain événement de type Mouse-Up...<br />    ev=[wnd nextEventMatchingMask:NSLeftMouseUpMask];<br /><br />    // si les coords Mouse-Down et Mouse-Up sont identiques,<br />    // alors on peut supposer que ce n&#39;est qu&#39;un simple clic dans la barre<br />    if (NSEqualPoints(p, [ev locationInWindow]))<br />    {<br />        // simple clic : je fais ce que j&#39;ai à  faire...<br />        NSLog(@&quot;simple clic dans la barre...&quot;);<br />    }<br />}<br />
    


    .
  • ChachaChacha Membre
    16:42 modifié #19
    dans 1127668041:

        // maintenant, on attend le prochain événement de type Mouse-Up...
        ev=[wnd nextEventMatchingMask:NSLeftMouseUpMask];


    Remarquable. Je n'avais jamais travaillé comme ça avec les NSEvent, je viens d'apprendre un nouveau truc, là . Comme quoi on ne sait jamais où nos questions nous mènent.
    Et un merci respectueux, comme d'hab.

    +
    Chacha
  • AliGatorAliGator Membre, Modérateur
    16:42 modifié #20
    J'ai pas tout lu mais juste une petite question en passant : du coup une surcharge de windowShouldMove ou WindowDidMove pour détecter les mouseDown et mouseUp ? :o

    Enfin moi je dis ça je dis rien.... d'ailleurs je m'en vais de suite en fait :P
  • ChachaChacha Membre
    16:42 modifié #21
    dans 1127721568:

    J'ai pas tout lu mais juste une petite question en passant : du coup une surcharge de windowShouldMove ou WindowDidMove pour détecter les mouseDown et mouseUp ? :o

    Enfin moi je dis ça je dis rien.... d'ailleurs je m'en vais de suite en fait :P

    Non, ça ne va pas, parce qu'on peut cliquer sans déplacer la fenêtre, donc sans déclencher de WindowDidMove.
    Mais là  c'est bon, en me basant sur le code de Bru, j'ai pu faire ce que je voulais.

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