Ré actualistation affichage NSOutlineView

LeChatNoirLeChatNoir Membre, Modérateur
mars 2006 modifié dans API AppKit #1
Salut,
J'ai une outlineview dans une vue.

J'aimerai dans certains cas, pouvoir figer cette outlineview.

Je m'explique : mon outlineview est masquable. L'utilisateur peux soit la masquer, soit l'afficher. Elle se trouve dans une splitview.

Lorsqu'il faut masquer, je réduis la subview de la splitview avec animation.

Or, à  chaque redimensionnement, les méthodes de la datasource sont appelées pour rafraichir l'outline, ce qui a pour effet de ralentir l'animation.

J'ai pensé à  suprimer le datasource avant l'animation et le remettre après. Ca fonctionne mais les données disparaissent du coup.

Ce que j'aimerai en fait, c'est figer l'outline telle qu'elle est, faire l'animation sans que ca rafraichisse quoi que ce soit et "défiger" l'outline ensuite.

Pour être encore plus précis :
* lorsque je masque l'outline, je ne veux plus que les méthodes du datasource soient appelées mais il faut que les données affichées au moment du masquage demeurrent,
* lorsque j'affiche l'outline, je veux d'abord la chargée, puis faire l'animation (sans que ça rappelle les méthodes du datasource à  chaque redim) puis remettre le datasource normal.

Faut que je sous classe ?

Merci !

Réponses

  • 07:25 modifié #2
    Je ne vois pas de solution simple à  ton problème. La moins complexe serait sans doute faire un cache sous forme d'image du contenu de ton outline (par colonne éventuellement) et lorsque l'anim commence, masquer la outline et tracer en live une pseudo outline à  partir des images mises en cache. Mais c'est du chipo.
  • mars 2006 modifié #3
    Tu as essayé de désactiver drawrect lors de l'animation de la vue ?

    Mais peut être que tout est effacé au moment du drawrect (tout blanc). Dans ce cas tu pourrais en profiter pour dessiner une image de l'outline view prise au dernier moment avant l'animation.

    Ah, je viens de voir que renaud le proposait aussi...

    Et si tu lances l'animation depuis un thread ?

    Et si tu désactive le setNeedDisplay/display (qui je suppose doit être appelé par l'animation) en sous classant lorsque l'animation est active...

    Bonne chance.
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:25 modifié #4
    Ok, merci pour vos réponses rapides.

    J'avais pensé à  cette solution mais c'est pas génial...
  • 07:25 modifié #5
    dans 1142862325:

    Et si tu lances l'anim depuis un thread ?


    A éviter, les classes graphiques ne sont pas thread safe.
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:25 modifié #6
    Est ce que le fait de mettre l'outline en non scrollable et en non auto resize vertical et horizontal ne permettrai pas de faire ce que je fait.

    Si l'outline n'est pas scrollable et non redimensionnable, les méthodes n'ont pas a être appelée sur un redimensionnement si ?
  • 07:25 modifié #7
    Y'a pas moyen de "bloquer" l'outlineview tout simplement ?
    On arrive bien à  figer une application  :adios!:
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:25 modifié #8
    Autoresize no, scrollable no : les méthodes du datasource sont quand même appelées....
    chiotte...
  • AliGatorAliGator Membre, Modérateur
    07:25 modifié #9
    Et si tu cherchais la méthode qui est appelée (automatiquement) pour demander à  la OutlineView de recharger les données ? Un peu comme reloadData mais en plus "bas niveau" (car je pense que quand on fait un reloadData ça appelle une méthode interne ?)

    Si tu trouves cette méthode, tu peux alors essayer de la surcharger pour rajouter un test de flag, genre un "if (isResizing) return;" (et sinon fait le code par défaut, genre [super _reloadData] si tu as sous-classé)

    Je ne sais pas si je suis très clair, mais si au moins tu vois l'idée... En bref intercepter le message qui demande à  la OutlineView de se recharger, pour le laisser faire dans la plupart des cas, sauf quant ton "flag" indiquant qu'il faut figer la vue est à  YES
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:25 modifié #10
    ouais, very good idea !
    Vas falloir jouer du class dump mais je dois savoir faire ça maintenant grâce à  Bru  ::)

    Si quelqu'un a une piste, he's welcome ! Sinon, si par le plus grand des hasard je trouve, je vous tiens au courant.

  • 07:25 modifié #11
    reloadData n'est pas appelé dans ce cas. C'est le drawRect: de la table/outline qui fait appel aux méthodes de DataSource.
  • LeChatNoirLeChatNoir Membre, Modérateur
    mars 2006 modifié #12
    ben alors je sous-classe le drawRect de mon outline tel que :

    Si animation
    return;
    Sinon
    [super drawRect:rect];

    Trop simple ?

    Ah ouais, je pense que tu vas me dire que c'est trop simple. Si je fais ça, je vais avoir genre un carré blanc ou noir à  la place de l'outline non ?
  • 07:25 modifié #13
    blanc...

    quoique essaie:
    si animation: [[self window] restoreCachedImage] sinon [super drawRect:rect] (et éventuellement [[self window] cacheImageInRect:aRect] - aRect étant dans le système de coordonnées de la fenetre).

    Et n'oublie pas de sous classer de la meme manière la headerview s'il y en une.
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:25 modifié #14
    Cool ! Ca m'a l'air bien ça !
    J'essaye dès ce soir.
    Pas de header.
    J'vous tiens au jus.
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:25 modifié #15
    Bon j'ai essayé.
    Donc, ne rien faire si animation en cours :
    Ca marche quand je masque la vue. L'image précédente reste tracée et l'animation se passe bien.

    Pour l'affichage par contre, ca trace rien (normal). Mais à  la limite, c'est pas génant car je compte faire autrement (un fillrect blanc avec une roue d'attente dedans style "Loading in progress" puisque je recharge l'outline et que dans certains cas, ca peut être long.

    Par contre, quand je redimensionne ma plitview par une session de Drag, ca ralentit le process. Le redim est un peu feignant (genre si je me déplace vite, ca suis le curseur mais avec un tps de latence).

    Pas bien génant mais comme je vais avoir 2 outlines et 2 tableview, ca va pas mal s'alourdir et je crains un peu le résultat final.

    Bon en attendant, j'optimise la méthode objectValueForItem... car c'est uniquement celle là  qui est appelée lors des resize. Mais en même tps, elle est optimisée à  mort puisque je fais qu'un accès mémoire...

    A suivre... On verra le résultat au final...

    Merci pour votre aide !







  • 07:25 modifié #16
    Qu'est ce qu'il y a dans l'outlineviewu pour son rechargement soit si lent... ?
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:25 modifié #17
    une bête hiérarchie implémentée en mémoire.
    L'affichage en soit n'est pas long ; il est même immédiat.
    C'est juste qu'il est appelé x mille fois lors de resize et que ça ralentit les dites opérations de resize. Mais c'est tout. Pas d'affichage merdique ou de roue multicolore. Juste une lourdeur dans les resize qui me plait pas....

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