Savoir quand une vue apparaà®t

CéroceCéroce Membre, Modérateur
11:52 modifié dans API AppKit #1
Bonjour à  tous.

Voilà  mon soucis: j'ai besoin d'initialiser des rectangles à  chaque fois que ma vue apparaà®t, et non pas à  chaque fois que ma vue est créée.

Le problème, c'est que cette vue est comprise dans un NSPanel (utilisé en Sheet) qui est conservé en mémoire après son premier chargement. Quand le panneau est masqué, la vue n'est donc pas détruite, et donc sa méthode -initWithFrame: n'est pas rappelée lors du prochain affichage du panneau.

Je n'ai pas trouvé de notification ou de méthode appelées lorsque la vue s'affiche. Quelqu'un aurait-il une suggestion ?


Merci d'avance,
Céroce

Réponses

  • fouffouf Membre
    11:52 modifié #2
    Il faut que tu utilise la methode drawRect: .

    Elle est appelee a chaque fois que l'on a besoin de redessiner toute ou une partie de la vue.
  • mpergandmpergand Membre
    11:52 modifié #3
    et ces méthodes déléguées de NSWindow:
    - windowWillBeginSheet:
    - windowDidEndSheet:

  • ClicCoolClicCool Membre
    11:52 modifié #4
    Une autre approche possible est dans la notification et méthode déléguée (void)windowDidBecomeKey que ton Pannel (dérivé de NSWidow) doit exploiter à  chaque fois que ta sheet (c'est pas pour toi Fouf hein ?  :fouf): ) s'affiche ...
  • fouffouf Membre
    11:52 modifié #5
    dans 1108470041:

    Une autre approche possible est dans la notification et méthode déléguée (void)windowDidBecomeKey que ton Pannel (dérivé de NSWidow) doit exploiter à  chaque fois que ta sheet (c'est pas pour toi Fouf hein ?  :fouf): ) s'affiche ...


    Ici le moderateur. Les blagues concernant le cannabis ne doivent pas enfumer les discutions sur la programmation.

    Bon, blagues a part, les methodes donnees par mpergand et ClicCool sont meilleures tant que ta vue est dans une (pas de ClicCool a l'horizon) shit.
  • CéroceCéroce Membre, Modérateur
    11:52 modifié #6
    Merci de vos réponses !
    Je ne m'y suis pas encore remis, mais j'ai étudié vos 3 propositions:

    La méthode drawRect: de fouf
    Non, c'est pas possible. Comme je l'écrivais, je veux initialiser les coordonnées de rectangles (d'un rectangle de sélection dans ma vue, en particulier) quand la vue s'affiche. Hors, drawRect: est appelée à  chaque fois que la vue doit être redessinée, par exemple si tu changes la taille de la fenêtre, ou que tu la fais passer au 1er plan.

    La méthode windowDidBecomeKey de ClicCool
    Pas possible non plus. Si tu fais passer la fenêtre en arrière plan (par exemple en sélection une autre fenêtre de l'appli) et que tu la ramène au 1er plan, les rectangles vont être initialisés, alors qu'ils devraient rester tels quels.


    La méthode - windowWillBeginSheet: de mpergand
    Celle qu'il faut que j'étudie de + près.


    En fait, au départ, je me demandais surtout s'il n'existait pas une méthode du style viewDidDisplay: que j'aurais loupée...

    Encore merci de vos réponses rapides et de qualité.


  • BruBru Membre
    11:52 modifié #7
    Le problème n'est il pas posé à  l'envers ?

    Une vue n'a faire que ce qu'elle sait faire : monter/afficher des choses... Je ne vois donc pas pourquoi on y mettrait du code d'initialisation qui n'est pas lié à  la vue elle même (si ce n'est que pour en afficher le résultat).

    C'est bien toi, à  travers ton programme, qui commande l'apparition du panel (sheet). Donc c'est bien à  ce moment que tu dois déclancher cette initialisation.

    Le code d'initialisation peut être contenu dans une méthode spécifique ajoutée à  ta sous classe (pardon à  ta classe dérivée) que tu appelles avant le beginSheet...

    Les drawRect: suivant auront alors leurs rectangles correctement initialisés.

    .
  • CéroceCéroce Membre, Modérateur
    11:52 modifié #8
    dans 1108628008:

    Le problème n'est il pas posé à  l'envers ?

    Une vue n'a faire que ce qu'elle sait faire : monter/afficher des choses... Je ne vois donc pas pourquoi on y mettrait du code d'initialisation qui n'est pas lié à  la vue elle même (si ce n'est que pour en afficher le résultat).


    Oui, c'est bien la méthode qu'il faut utiliser, mais ça n'a rien d'évident.
    La vraie difficulté de la programmation objet reste toujours de répartir les responsabilités de chaque objet.


    Une vue ne fait pas qu'afficher des choses. Elle gère aussi des évenements: clics, entrées dans la vue du curseur, saisies au clavier, glisser-déposers...
    Mon objet permet de faire la sélection d'une zone d'une image pour la recadrer. D'ailleurs, au départ, ça m'avait semblé plus logique que ce soit un NSControl.
    Pourquoi le fait que la vue positionne elle-même un rectangle de sélection par défaut ne serait pas de son ressort ?

    Cocoa requiert une certaine tournure d'esprit que je n'ai pas encore bien intégrée, mais il n'y a rien d'évident.
  • BruBru Membre
    11:52 modifié #9
    dans 1108732877:

    Une vue ne fait pas qu'afficher des choses. Elle gère aussi des évenements: clics, entrées dans la vue du curseur, saisies au clavier, glisser-déposers...
    Mon objet permet de faire la sélection d'une zone d'une image pour la recadrer. D'ailleurs, au départ, ça m'avait semblé plus logique que ce soit un NSControl.


    C'est clair, j'ai simplifié le concept de view à  des fins d'exemple... Mias il faut bien voir la view comme une NSResponder, donc susceptible d'interagir avec l'utilisateur.

    dans 1108732877:

    Pourquoi le fait que la vue positionne elle-même un rectangle de sélection par défaut ne serait pas de son ressort ?


    Ce n'est que dans ce message n°7 que tu nous expliques un peu mieux ce que tu veux faire... Excuse-nous alors d'avoir été imprécise auparavant !

    dans 1108732877:

    Cocoa requiert une certaine tournure d'esprit que je n'ai pas encore bien intégrée, mais il n'y a rien d'évident.


    J'en profite pour rebondir, sachant un peu mieux ce que tu veux réaliser.

    Pour ton projet, je passerai plutôt par la création d'un objet spécifique dont la NSView est une composante (celle qui permet l'affichage à  des fins de visualisation, mais aussi d'interaction avec l'utilisateur). C'est du moins comme cela que procède Apple pour beaucoup de ses classes (Comme les NSControl, qui délèguent leur affichage une NSCell).
    Cet objet s'occuperait de tout ce qui est traitement d'image (recadrage, mais aussi tout ce que tu veux) et ferait appel à  sa view attachée pour afficher et attendre les actions de l'utilisateurs.

    .
  • CéroceCéroce Membre, Modérateur
    février 2005 modifié #10
    Pardonne-moi Bru, mais j'ai préféré vous passer les détails, justement pour avoir une réponse précise à  une question précise: "Comment sait-on qu'une vue s'affiche". La réponse est "on sait pas, mais il y a toujours un autre objet qui demande son affichage".

    Pour ce qui est de ta suggestion, c'est bien ainsi que c'est fait. C'est mon objet au niveau modèle qui va effectivement réaliser le recadrage. La vue ne fait que renvoyer les coordonnées du rectangle de sélection. En relisant ce que j'avais écrit, on peut effectivement croire que je voudrais que la vue elle-même fasse le recadrage.
  • Eddy58Eddy58 Membre
    11:52 modifié #11
    Tu peux aussi essayer quelque chose en surchargeant la méthode -(BOOL)becomeFirstResponder de ta view : :)
    [tt]
    -(BOOL)becomeFirstResponder
    {
           [self setNeedsDisplay:YES];
           return [super becomeFirstResponder];
    }
    [/tt]
  • CéroceCéroce Membre, Modérateur
    11:52 modifié #12
    dans 1108835137:

    Tu peux aussi essayer quelque chose en surchargeant la méthode -(BOOL)becomeFirstResponder de ta view : :)



    Non, c'est pas la bonne solution:

    1 - Rien ne dit qu'il n'y aura pas d'autre Responder dans la Sheet, par exemple un Text Field.
    2 - Ramener la fenêtre contenant la Sheet au 1er plan appelerait cette méthode, alors que le but est d'initialiser la vue uniquement lorsqu'elle apparaà®t.



    Merci toutefois de ta suggestion.
  • 11:52 modifié #13
    Et pourquoi tu ne rajoutes pas une méthode genre -initializeRects ou n'importe qui d'équivalent que ton contrôlleur avant de charger la feuille, puisque si j'ai bien compris il ne faut faire ça que lorsque la feuille apparaà®t?
  • Eddy58Eddy58 Membre
    11:52 modifié #14
    Oui je suis d'accord avec toi Renaud, et c'est ce que je ferais : Avant d'ouvrir la sheet, appeler une méthode adéquate.... :)
  • ClicCoolClicCool Membre
    11:52 modifié #15
    dans 1108907047:

    Et pourquoi tu ne rajoutes pas une méthode genre -initializeRects ou n'importe qui d'équivalent que ton contrôlleur avant de charger la feuille, puisque si j'ai bien compris il ne faut faire ça que lorsque la feuille apparaà®t?


    dans 1108919345:

    Oui je suis d'accord avec toi Renaud, et c'est ce que je ferais : Avant d'ouvrir la sheet, appeler une méthode adéquate.... :)


    Il me semble que c'est ce que Bru avait suggéré plus haut  ::)
Connectez-vous ou Inscrivez-vous pour répondre.