Effet de survol: NSTrackingArea

RocouRocou Membre
21:46 modifié dans API AppKit #1
Bonjour,

Je suis toujours sur le développement de mon application de location. Elle avance bien, je suis en train de tester les effets de survol. Cela fonctionne mais je me pose les questions suivantes:

- Pour créer mes NSTrackingArea, je ne passe pas par la méthode viewDidMoveToWindow car le nombre et la position de ces zones peuvent changer (ce sont les colonnes de mon planning, cf image ci-jointe).
Je crée ces zones dans une boucle du style:
for(i =0;i&lt;tailleCalendrier;i++)<br />	{	<br />		monRect.origin.x = ColonneX;<br />		monRect.origin.y = origineLocationY;<br />		monRect.size.height= bounds.size.height;<br />		monRect.size.width = largeurColonneDefaut;<br />		//On incrémente ColonneX pour passer à  la colonne suivante<br />		ColonneX = ColonneX + largeurColonneDefaut;<br />		<br />		//On ajoute une zone de tracking<br />		[self addTrackingRect:monRect<br />				&nbsp; &nbsp;  owner:self<br />				 userData:nil<br />			&nbsp;  assumeInside:NO];<br />		<br />	}	<br />


On est susceptible de passer plusieurs fois dans ce bout de code en fonction de la valeur de tailleCalendrier qui peut être modifiée.

Je me demande donc si toutes ces zones de tracking ne vont pas s'accumuler en mémoire et finir par me bouffer toutes mes ressources. Faut-il détruire ces zones avant de les recréer?
Si oui, comment?

Réponses

  • CéroceCéroce Membre, Modérateur
    21:46 modifié #2
    Si, évidemment, à  force de créer des objets sans les libérer, tu bouffes de la mémoire. Il y a plusieurs solutions:
    - soit tu crées une classe par colonne, qui maintiens la NSTrackingArea.
    - soit tu accumules toutes des NSTrackingArea dans un NSMutableArray, que tu vides quand il y a besoin.

    Par contre, si je dis pas de bêtises, tu mélanges deux concepts:
    les tracking Rect et les NSTrackingArea.
    Les Tracking Rect sont l'ancienne méthode. NSTrackingArea est la nouvelle, plus flexible et plus simple (mais 10.5 minimum, je crois). La doc d'Apple n'est pas très claire à  ce sujet.
  • LexxisLexxis Membre
    21:46 modifié #3
    Tu ne peux pas faire un seul NSTrackingArea et gérer l'évènement mousemouved: avec un système de 'cache' pour savoir si la souris à  changer de zone ou pas ?
    Cela allégerais peut etre un peu la charge de travail dy système dédié à  la gestion des trackingRect.
  • RocouRocou Membre
    21:46 modifié #4
    dans 1250864928:

    Tu ne peux pas faire un seul NSTrackingArea et gérer l'évènement mousemouved: avec un système de 'cache' pour savoir si la souris à  changer de zone ou pas ?
    Cela allégerais peut etre un peu la charge de travail dy système dédié à  la gestion des trackingRect.

    Oui, cela semble plus simple et sûrement plus performant. Peut-on modifier dynamiquement un NSTrackingArea?

    Effectivement, Céroce, je confondais l'ancienne méthode avec la nouvelle.
  • 21:46 modifié #5
    En plus je t'assure que NSTrackingArea est beaucoup mieux. Attention cependant car Leopard uniquement.

    Par contre tu seras effectivement forcé de supprimer pour ajouter un nouveau tracking, meme si tu veux simplement en modifier un. Du moins dans la classe je ne vois que des getter.
  • RocouRocou Membre
    août 2009 modifié #6
    dans 1250866805:

    En plus je t'assure que NSTrackingArea est beaucoup mieux. Attention cependant car Leopard uniquement.

    Par contre tu seras effectivement forcé de supprimer pour ajouter un nouveau tracking, meme si tu veux simplement en modifier un. Du moins dans la classe je ne vois que des getter.


    Bon, effectivement, ça fonctionne beaucoup mieux!  :)

    Mais j'ai encore une question. Voici mon code:
    int options = NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect;<br />	<br />	NSTrackingArea *ta;<br />	<br />	ta = [[NSTrackingArea alloc] initWithRect:monRect options:options owner:self userInfo:nil];<br />	[self addTrackingArea:ta];<br />	[ta release];<br />
    


    Bon en fait, j'ai viré toute notion* de "TrackingArea" et j'ai tout reprogrammé avec mouseMove. C'est bien plus simple et très efficace.

    J'ai juste un petit "bug". Ma vue peut "scroller". Si on utilise la roulette de la souris, la vue scrolle mais la souris ne bouge pas. Par conséquent, mon affichage géré par mouseMove ne se fait pas...

    (NB: je n'ai pas viré "toute notion" mais bon...)
  • LexxisLexxis Membre
    21:46 modifié #7
    Si la souris ne bouge pas tu n'auras pas de 'mousemouved:' par contre rien ne t'empêche d'appeler toi même cette fonction (ou toute autre fonction de redraw) dans le mousewheel:.
  • RocouRocou Membre
    21:46 modifié #8
    dans 1250882435:

    Si la souris ne bouge pas tu n'auras pas de 'mousemouved:' par contre rien ne t'empêche d'appeler toi même cette fonction (ou toute autre fonction de redraw) dans le mousewheel:.

    C'est quoi mousewheel:?
    Je suis passé par les notifications pour récupérer les données de scroll. une méthode "mousewheel:" aurait été bien pratique!  :)
  • 21:46 modifié #9
    y'a une méthode mouseWheel:

    <br />- (void)mouseWheel:(NSEvent*)theEvent<br />{<br /><br />}<br />
    


    Mouse Wheel c'est simplement un scroll avec la molette :p
  • RocouRocou Membre
    21:46 modifié #10
    dans 1250922580:

    y'a une méthode mouseWheel:

    <br />- (void)mouseWheel:(NSEvent*)theEvent<br />{<br /><br />}<br />
    


    Mouse Wheel c'est simplement un scroll avec la molette :p

    Et bien merci car de mon côté mouseWheel n'apparait pas dans la doc Apple intégrée à  xCode  :(
  • LexxisLexxis Membre
    21:46 modifié #11
    Arf... autant pour moi... c'est scrollWheel et pas mouseWheel :s
  • 21:46 modifié #12
    Ouaip  ;D T'es chiant Lexxis  :)
  • RocouRocou Membre
    août 2009 modifié #13
    dans 1250936696:

    Arf... autant pour moi... c'est scrollWheel et pas mouseWheel :s

    Ha ok  :)

    Je vais tester ça.


    EDIT: grrrr. En fait j'avais déjà  testé. ça ne fonctionne pas comme je le voudrais (ne permet pas de faire scroller les ascenseurs)
  • LexxisLexxis Membre
    21:46 modifié #14
    à‰trange.
    Tu peux tenter de surclasser ta NSScrollView et d'intercepter le scrollWheel (sans oublier l'appel à  super) et envoyer une notification à  ta vue pour quelle recalcule les trackingRect...
    à‰videmment je suis novice en programmation Cocoa il doit y avoir une solution plus élégante.
Connectez-vous ou Inscrivez-vous pour répondre.