Survol d'une fenêtre

olivier555olivier555 Membre
12:17 modifié dans API AppKit #1
Bonjour!
Je voudrais savoir s'il est possible de détecter le simple survol de la souris au dessus d'une fenêtre (sans cliquer donc), sachant que la fenêtre en question est flottante et n'est jamais la keyWindow (c'est une palette d'outil). J'ai bo chercher dans la doc d'Apple ou sur les forums, je ne trouve pas la solution. Merci d'avance!

Réponses

  • Eddy58Eddy58 Membre
    12:17 modifié #2
    As-tu essayé de sous-classer ta fenêtre et de surcharger la méthode mouseMoved de NSResponder ? :o
  • olivier555olivier555 Membre
    12:17 modifié #3
    Merci de m'aider!
    Oui j'ai essayé, mais il n'y a aucune réaction... J'ai ajouté dans le awakeFromNib la méthode setAcceptsMouseMovedEvents, ça marche pas non plus.
  • olivier555olivier555 Membre
    12:17 modifié #4
    J'ai aussi essayé de recouvrir cette fenêtre par une vue invisible et de faire réagir cette vue à  la souris, mais même comme ça je n'y arrive pas...
  • Eddy58Eddy58 Membre
    12:17 modifié #5
    Et c'est pour faire quoi exactement ? Tu veux surveiller les coordonnées ? Le survol des controles ?
  • 12:17 modifié #6
    Le mouseMoved n'est actif sur le une fenêtre ayant accepté d'être firstResponder. Si tu utilise mouseMoved fenêtre dans la fenêtre active tu peux essayer de calculer si le pointeur est dans la zone de ta fenêtre palette. Dis en un peu plus, à  quoi sert le mouseMoved, tu ne peux pas faire autrement comme comportement ?
  • olivier555olivier555 Membre
    12:17 modifié #7
    OK. C'est bien ce que je pensais en fait.
    Pour tout vous dire, je voudrais faire une palette transparente qui devient opaque lorsqu'on la survole, de la même manière que sur Word.


    Si tu utilise mouseMoved fenêtre dans la fenêtre active tu peux essayer de calculer si le pointeur est dans la zone de ta fenêtre palette.


    Mon apli fait pas mal de calculs aussi bien au niveau affichage qu'au niveau son (MIDI, lecture de samples). Ta suggestion ne bouffe t-elle pas trop de ressources? Si c'est le cas, je préfère abandonner cette idée et faire une palette opaque, comme n'importe quel soft Windows...  :(

    Merci les gars en tout cas!
  • septembre 2005 modifié #8
    Pourquoi :(? D'un côté tu dis que tu ne veux pas faire comme Windows en ayant des fenêtres opaques et de l'autre tu veux faire comme Microsoft :P. Ceci dit, je ne savais pas que les fenêtres opaques étaient une caractéristique de Windows, et voyant les captures de Vista, j'aurais plutôt dit que les fenêtres opaques allaient être une caractéristique de Mac OS (ou Linux).

    Mais si tu t'inquiètes de la consommation processeur, il y a des chances qu'une fenêtre translucide consomme plus dans l'ensemble que 4 comparaisons de nombres à  chaque mouvement de souris.
  • Eddy58Eddy58 Membre
    12:17 modifié #9
    Tu peux regarder du côté des mouse events de Carbon, mais je pense que ça doit être aussi lié à  la key window, ou bien alors du côté des Games Sprockets, avec la fonction DSpGetMouse() que tu peux appeler dans un timer et ainsi recueillir les coordonnées globales de la souris, mais bon ce ne sont que des pistes, faut essayer. :)
  • olivier555olivier555 Membre
    12:17 modifié #10

    Ceci dit, je ne savais pas que les fenêtres opaques étaient une caractéristique de Windows


    Je parlais de Word sur Mac bien sûr, qui a une palette d'outils très sympa!
    OK merci pour les pistes, j'essaye bientôt!
  • 12:17 modifié #11
    Oui oui, j'avais bien compris, c'était du second degré.

    Sinon une piste: à  la place de dessiner les contrôles de la palette dans la fenêtre IB représentant ton inspecteur, tu les dessines dans une CustomView (placée dans la fenêtre IB avec le File's Owner, First Responder,...). Cette vue doit être une sous-classe de NSView, pour laquelle l'implémentation contient le code suivant:
    [tt]- (void) viewDidMoveToWindow {
    [self addTrackingRect:[self bounds]
    owner:self
    userData:nil
    assumeInside:NO];
    }

    - (void)mouseEntered:(NSEvent *)event {
    NSPoint point = [event locationInWindow];
    point = [self convertPoint:point toView:nil];
    NSLog(@entered:%@",NSStringFromPoint(point));

    }

    - (void)mouseExited:(NSEvent *)event {
    NSPoint point = [event locationInWindow];
    point = [self convertPoint:point toView:nil];
    NSLog(@exited:%@",NSStringFromPoint(point));

    }[/tt]

    Et dans le awakeFromNib du contrôleur, tu rajoutes:
    [tt][inspectorWindow setContentView:lOutletVersTaVuePerso];[/tt]

    ça fonctionne même si l'application n'est pas au premier plan (donc à  priori que la fenêtre n'est pas active).
  • olivier555olivier555 Membre
    12:17 modifié #12
    Haha désolé j'ai plus trop d'humour là ... Ca à  l'air pas mal ce que tu proposes là , j'essaye ce soir!! Je te tiens au courant.
  • olivier555olivier555 Membre
    12:17 modifié #13
    Super!! Ca marche! Merci beaucoup ma palette est presqu'aussi stylée que celle de Word!
  • 12:17 modifié #14
    Comment peut on faire pour ajouter (et mettre à  jour) un trackingRect lorsque la vue n'est pas active ? Le viewDidMoveToWindow est pas mal, comment faire dans le cas d'une mise à  jour de la frame de la fenêtre sans quelle soit au premier plan ? Cocoa ne semble pas trop permettre ce genre de bidouille...
  • BruBru Membre
    12:17 modifié #15
    dans 1135114524:

    Comment peut on faire pour ajouter (et mettre à  jour) un trackingRect lorsque la vue n'est pas active ? Le viewDidMoveToWindow est pas mal, comment faire dans le cas d'une mise à  jour de la frame de la fenêtre sans quelle soit au premier plan ? Cocoa ne semble pas trop permettre ce genre de bidouille...


    J'ai définitivement arrêté d'utiliser les trackingRect que je trouve trop restrictif, rigide d'emploi, et pas très au point.

    Maintenant, je gère mes propres trackingRect en utilisant mouseMoved de NSResponder.

    .
  • 12:17 modifié #16
    C'est bien ce que j'ai fait jusqu'à  présent sans problème. Mais je souhaiterais savoir quand l'user passe au dessus d'une fenêtre quand le programme n'est pas au premier plan... Je peux m'en passer parce que quand l'utilisateur clic la fenêtre je retombe sur le mousemoved mais j'aurais préféré pouvoir éviter le clic.

    Aucune piste même Carbon ?
  • Eddy58Eddy58 Membre
    12:17 modifié #17
    Avec Carbon il y a les Mouse Events, mais comme ils sont attachés aux fenêtres, je pense que ça doit fonctionner de la même manière que sous Cocoa.
    Un moyen, dont je parle déjà  plus haut, est de récupérer les coordonnées globales de la souris en appelant la fonction DSpGetMouse() du framework DrawSprocket via un timer. Aprés tu peux comparer ces coordonnées avec les frames de tes fenêtres. Ce n'est pas trés propre il est vrai car DrawSprocket est maintenant considérée comme une "legacy" API donc elle doit fonctionner mais ces fonctions sont plus ou moins supportées. :)
  • 12:17 modifié #18
    Ce qui revient à  un [... mouseLocation] Pas très propre, pas très réactif.
  • Eddy58Eddy58 Membre
    12:17 modifié #19
    Pas trés propre, d'accord, mais en tout cas c'est réactif et ça fonctionne bien. :)

    [Fichier joint supprimé par l'administrateur]
  • décembre 2005 modifié #20
    Marcher oui... mais ça bouffe 1.0% de CPU en continue sur un G4 1.5 !! Bon, avec un timer de .01

    Je disais moins réactif pour un timer qui suce moins (0.5/sec).

    Mais je sais pas ce que ça peut donner sur un système qui tourne pendant plusieurs semaines... des avis ?
  • Eddy58Eddy58 Membre
    12:17 modifié #21
    Sur G4 1.42/256Mb : Timer=0.01 : 3,5% de temps CPU.
                                 Timer=0.1   : 0,3 %
                                 Timer=0.25 : 0,1 %
                                 Timer=0.5   :    0 %
    Le timer réglé sur 0.25 donne un rapport correct, bien que je trouve que ça fonctionne trés bien aussi avec un réglage de 0.5. :P
    En ce qui concerne le fonctionnement sur plusieurs semaines (voir même beaucoup plus), je vois pas où pourrait être le problème, mais le mieux est toujours de tester. :)
  • 12:17 modifié #22
    Ok, mais je me demandais pourquoi tu n'utilisais pas un simple [NSEvent mouseLocation].

    Résultat du grand test :

    NSPoint pt=[NSEvent mouseLocation]; // 1.2 à  1.3%
    struct Point globalMouse;DSpGetMouse(&globalMouse); // 1.0 à  1.1%

    Je vais peut être faire comme ça... merci @+
  • Eddy58Eddy58 Membre
    décembre 2005 modifié #23
    dans 1135204434:

    Ok, mais je me demandais pourquoi tu n'utilisais pas un simple [NSEvent mouseLocation].

    NSEvent risque sûrement de ne pas être pris en compte dans les cas où l'appli n'est plus en premier plan et/ou les fenêtres visées ne sont pas key/main windows (ce qui est normal car ce n'est pas le but), et en plus, avec DSp, cela permet de prendre en compte l'intégralitée des fenêtres (barre de titre comprise), qu'elles soient partiellement cachées ou non. :o

    [EDIT] J'avais oublié que mouseLocation était une méthode de classe, ça fonctionne bien aussi avec, bien qu'un poil plus gourmand en CPU c'est vrai. ;)
  • 12:17 modifié #24
    Comment peut on faire pour ajouter (et mettre à  jour) un trackingRect lorsque la vue n'est pas active ? Le viewDidMoveToWindow est pas mal, comment faire dans le cas d'une mise à  jour de la frame de la fenêtre sans quelle soit au premier plan ? Cocoa ne semble pas trop permettre ce genre de bidouille...

    ben peut-être comme cela :

    - (void)awakeFromNib
    {
    NSRect  r;

    tracking_tag = [self addTrackingRect:imageRect owner: self userData:nil assumeInside: NO];

    }
    - (void)changeTrackingRectangle
    {
    if (nil!=tracking_tag)
    [self removeTrackingRect:tracking_tag];
    tracking_tag = [self addTrackingRect:[self bounds] owner: self userData: 0 assumeInside: FALSE];
    }
  • décembre 2005 modifié #25
    Non... tu penses bien que j'ai essayé 10 fois même avant de me rendre compte que ça ne marchait que sur les vues actives.
Connectez-vous ou Inscrivez-vous pour répondre.