NSOutlineView & Trees

muqaddarmuqaddar Administrateur
février 2007 modifié dans Actualités #1
Phillipe49 s'est encore fait plaisir, et nous fait plaisir.

Le premier pdf décrit la notion d'arborescence en faisant une visualisation dans une NSTextView et en vérifiant la gestion de la mémoire lors de la suppression.

Le second présente les NSOutlineView, version data source-delegate, avec ajout, suppression, et déplacement par drag&drop.

[Fichier joint supprimé par l'administrateur]
«1

Réponses

  • Philippe49Philippe49 Membre
    avril 2008 modifié #2
    [glow=red,2,300][size=14pt]Pour détailler/Améliorer/Mettre à  jour ces PDF, j'installe un site sur quelques aspects de la manipulation des arborescences sous Cocoa .[/size][/glow]

    1) Arborescence
    Cela commence par un tutoriel détaillé qui peut servir à  tout débutant, correspondant au premier PDF : mise en place d'une arborescence, visualisation dans une NSTextView. Simple_Tree

    2) Data Source
    Une page sur NSOutlineView et data-source

    3) Challenge :
    data-source par NSMutableDictionary
    Challenge : Réponse  à  data-source par NSMutableDictionary
          Débuter avec les categories, comment mettre une fonction dans du code objective-C

    4) Property List
    Stocker les données sous forme de property list  
    Tutoriel sur NSOutlineView et property list
    Au passage un petit rafraichissement sur le savePanel et openPanel.

    5) Drag and Drop
    Le drag and drop sur Outline View
    (dont le code dépend de la classe Node implémentée)


    [size=14pt] NSBrowser avec un Active Delegate [/size]
    1) NSBrowser et property list
    NSBrowser et Property List
    Initialiser le contenu d'un NSBrowser avec une plist.

    2) Adding and removing in NSBrowser
    Gestion (précise) du changement dans l'arborescence

    3) Edition dans les cellules d'un NSBrowser
    Edition des cellules d'un NSBrowser via le Field Editor partagé par les contrôles de la fenêtre de l'application.

    4) Drag and Drop Browser
    drag and drop dans un NSBrowser . Il faut rentrer un peu dans les NSMatrix (regroupant des cellules) qui sont dans chaque colonne, manipuler des NSIndexSet.
    C'est assez précis comme traitement, et je trouve que Drag&Drop Browser, cela sonne un peu comme Rock&Roll.
    D'ailleurs je n'ai pas trouvé de doc sur Internet ...

    5) Un Browser éditeur de documents (1)
    NSBrowser Document
    Cela peut servir de tuto pour les Document-Based Cocoa Applications avec XCode 3.0
    Enregistrement de property list sous deux formats.

    [size=14pt] NSBrowser avec un Passive Delegate [/size]

    1) NSBrowser et property list
    • Les bases de fonctionnement du delegate, la classe BrowserController.
    • La classe BrowserTreeNode héritée de NSTreeNode.
    • La classe NodeInfo portant les infos du NSTreeNode.
    • Lecture et affichage à  partir d'une property list.

    Un tutoriel sur NSBrowser et property list Sur cette page

    2) Add Remove
    • Quelques catégories sur NSArray, NSIndexPath, NSIndexSet.
    • Utilisation d'un NSUndoManager pour gérer les options Undo et Redo du menu Edit dans une application Cocoa-Application (sans NSDocument).
    • ajouter/supprimer de s noe“uds

    Sur cette page

    3) Archiving:
    • Implémentation de Save, Open dans une Cocoa-Application (sans NSDocument) .
    • Enregistrement d'une property list en XML ou en Binary
    • Une option de menu pour effacer la pile des Undo et la pile des redo.
    • Vérification de la gestion de la mémoire au niveau de l'arborescence.
    • Mise en place de l'option de recherche dans l'arbre via le NSSearchField.

    Sur cette page

    4) Editing
    • Edition avec utilisation du fieldEditor de la fenêtre.
    • Gestion du Undo/Redo lors de cette édition.
    • Action associée au double clic dans le Browser.

    Sur cette page

    5) Drag and Drop
    • Basée sur l'utilisation des NSIndexPath en pensant à  NSTreeController
    • Gestion du Undo/Redo.

    Sur cette page


    [size=14pt] NSBrowser avec un NSTreeController [/size]

    1) Premier Pas
    Un tutoriel sur les bindings, NSTreeController, NSBrowser
    • Les bindings du NSTreeController avec le NSBrowser
    • Sous-classe de NSTreeNode
    • Ajouter un noe“ud et mettre à  jour le MVC

    Sur cette page

    2) Property List
    • Lire / Enregistrer une property list
    • Gestion de la mémoire
    • Bindings



    En cours




    4 Février 2008
    Mac OS 10.5.1 / 10.5.2

    Il s'agit ici d'une introduction, l'auteur ne s'engage pas sur la qualité professionnelle de ce tutoriel.
    Toute proposition d'amélioration est la bienvenue.
  • Paisible.frPaisible.fr Membre
    02:24 modifié #3
    Excellent travail ! J'ai passé tout le WE à¡ essayer de faire fonctionner une NSOutlineView sans succés.
  • Paisible.frPaisible.fr Membre
    02:24 modifié #4
    Bonjour,

    J'ai essayé de suivre pas à¡ pas le tutorial hier soir. Voici le résultat de mon expériences

    1) Au chapitre "Définition de l'interface Node.h et de l'implémentation Node.m" il y a une incohérence entre la déclaration et l'implementation. Dans le Node.h on parle d'un :
    (id) initWithName:(NSString*) aString parent:(Node *) aParent;
    

    alor que dans le Node.m on parler d'un :
    -(id) initWithString:(NSString*) aString parent:(Node *) aParent
    


    2) Au chapitre "Définition d'un contrôleur pour l'application." il n'est dis nul part que dans l'implementation il faut faire un include de "Node.h". C'est pas bien grave car on s'en rend tres vite compte mais ca va mieux en le disant

    3) Pour ma part je n'ai jamais réussi à¡ avoir le NSTextView rempli au lancement de l'application. La TextView ne se remplit qu'au premier clic sur le bouton. J'ai essayé de déporter tout cela dans un init() comme indiqué dans les anciens PDF sans succés.

    4) Au chapitre "Réalisation de l'interface graphique dans IB" vous invitez à¡ définir le déployement de l'application sur "Mac OS 10.5". Pourquoi pas. Mais je trouve pas cela coherent, pour moi ce serait logique si le code etait en Objective 2.0 dans ce cas on fait une appli pure 10.5, sinon si ce n'est pour tirer aucun avantage de 10.5 a quoi bon ? (avis personnel qui n'engage que moi)

    5) Et enfin, dernière grosse remarque : c'est bien gentil de mettre tout cela dans une NSTextView mais cela ne présente que peut d'intérêt. L'idéal eu été dà¡ voir le display dans une NSOutlineView. Chose que j'ai essayée de faire en me basant sur les anciens PDF sans succés. Mais peut-être cela fera t'il l'objet d'une autre page web par la suite ...

    Quoi qu'il en soit c'est un excellent travail, merci à¡ toi Philippe49
  • Philippe49Philippe49 Membre
    février 2008 modifié #5
    Merci de ces remarques, je corrige les coquilles.


    dans 1202196937:

    3) Pour ma part je n'ai jamais réussi à¡ avoir le NSTextView rempli au lancement de l'application. La TextView ne se remplit qu'au premier clic sur le bouton. J'ai essayé de déporter tout cela dans un init() comme indiqué dans les anciens PDF sans succés.

    Cela devrait pourtant. Tu as mis [self updateTextView] dans awakeFromNib ?

    dans 1202196937:

    4) Au chapitre "Réalisation de l'interface graphique dans IB" vous invitez à¡ définir le déployement de l'application sur "Mac OS 10.5". Pourquoi pas. Mais je trouve pas cela coherent, pour moi ce serait logique si le code etait en Objective 2.0 dans ce cas on fait une appli pure 10.5, sinon si ce n'est pour tirer aucun avantage de 10.5 a quoi bon ? (avis personnel qui n'engage que moi)

    En 10.4, on a des messages désagréables pour certains choix du bouton. Mais il suffit d'en changer. Je tiens compte de ta remarque, en changeant le laà¯us à  cet endroit


    dans 1202196937:

    5) Et enfin, dernière grosse remarque : c'est bien gentil de mettre tout cela dans une NSTextView mais cela ne présente que peut d'intérêt. L'idéal eu été dà¡ voir le display dans une NSOutlineView. Chose que j'ai essayée de faire en me basant sur les anciens PDF sans succés. Mais peut-être cela fera t'il l'objet d'une autre page web par la suite ...

    Cela suit effectivement (je pense à  faire des pages sur NSOutlineView, NSBrowserView, les bindings, les property list)

    Encore merci de tes remarques.

  • Paisible.frPaisible.fr Membre
    février 2008 modifié #6
    dans 1202200983:

    En 10.4, on a des messages désagréables pour certains choix du bouton. Mais il suffit d'en changer. Je tiens compte de ta remarque, en changeant le laà¯us à  cet endroit

    C'est pas grand chose à¡ changer et cela évite de limiter l'application à¡ 10.5.
    Un petit effort qui est grandement payant à¡ mon avis.

    dans 1202200983:

    Cela suit effectivement (je pense à  faire des pages sur NSOutlineView, NSBrowserView, les bindings, les property list)

    Super, j'ai hate de pouvoir lire cela.

    Sinon j'ai vu que tu avais mis le projet et l'application en téléchargement. C'est super (bien que les liens ne sautent vraiment pas aux yeux)
  • Philippe49Philippe49 Membre
    02:24 modifié #7
    dans 1202196937:

    3) Pour ma part je n'ai jamais réussi à¡ avoir le NSTextView rempli au lancement de l'application. La TextView ne se remplit qu'au premier clic sur le bouton. J'ai essayé de déporter tout cela dans un init() comme indiqué dans les anciens PDF sans succés.

    cela passe maintenant ?

  • Paisible.frPaisible.fr Membre
    02:24 modifié #8
    dans 1202208354:

    dans 1202196937:

    3) Pour ma part je n'ai jamais réussi à¡ avoir le NSTextView rempli au lancement de l'application. La TextView ne se remplit qu'au premier clic sur le bouton. J'ai essayé de déporter tout cela dans un init() comme indiqué dans les anciens PDF sans succés.

    cela passe maintenant ?


    Je te dirais cela ce soir après avoir essayé.
  • Paisible.frPaisible.fr Membre
    02:24 modifié #9
    dans 1202208603:

    dans 1202208354:

    dans 1202196937:

    3) Pour ma part je n'ai jamais réussi à¡ avoir le NSTextView rempli au lancement de l'application. La TextView ne se remplit qu'au premier clic sur le bouton. J'ai essayé de déporter tout cela dans un init() comme indiqué dans les anciens PDF sans succés.

    cela passe maintenant ?


    Je te dirais cela ce soir après avoir essayé.



    Effectivement en rajoutant :
    [self updateTextView];
    
    dans le awakeFromNib cela fonctionne.

    Donc à  mettre à  jour dans le AppController.m et ajouter la "déclaration" du awakeFromNib() dans le AppControler.h

    Merci Philippe pour ton travail, ta réactivité et tes réponses.
    En espérant lire bientôt la suite pour remplir le NSOutlineView.
  • Philippe49Philippe49 Membre
    02:24 modifié #10
  • Philippe49Philippe49 Membre
    février 2008 modifié #12
    Challenge : Réponse  à  data-source par NSMutableDictionary
          Débuter avec les categories, comment mettre une fonction dans du code objective-C

  • psychoh13psychoh13 Mothership Developer Membre
    février 2008 modifié #13
    Fais attention, ton lien est crade. :D

    Sinon je doute que ce soit une très bonne idée de rajouter, sous forme de catégories ce genre de méthode à  NSMutableDictionary... ça donne un comportement spécifique à  une classe à  but générique...
    Ensuite, je suis pas sûr que se passer d'une classe Node soit bien non plus. Les classes dans le cas des NSTableView et NSOutlineView, permettent de donner des comportements spécifiques aux objets... Par exemple, une colonne pourrait être l'addition des valeurs de plusieurs autres colonnes... Et dans ce cas, le modèle objet préconise de mettre tout le code de gestion dans une classe précise.
  • Philippe49Philippe49 Membre
    02:24 modifié #14
    dans 1202659468:

    Sinon je doute que ce soit une très bonne idée de rajouter, sous forme de catégories ce genre de méthode à  NSMutableDictionary... ça donne un comportement spécifique à  une classe à  but générique...




    dans 1202659468:

    Ensuite, je suis pas sûr que se passer d'une classe Node soit bien non plus. Les classes dans le cas des NSTableView et NSOutlineView, permettent de donner des comportements spécifiques aux objets... Par exemple, une colonne pourrait être l'addition des valeurs de plusieurs autres colonnes... Et dans ce cas, le modèle objet préconise de mettre tout le code de gestion dans une classe précise.


    En même temps dans un NSTreeController, c'est NSMutableDictionary qui est proposé comme modèle de classe, ça me laisse songeur.
    J'étais justement en train de me demander ce genre de choses, notamment pour l'archivage, les property lists (voir initWithContentsOfURL )

  • Philippe49Philippe49 Membre
    02:24 modifié #15
    dans 1202659468:

    Sinon je doute que ce soit une très bonne idée de rajouter, sous forme de catégories ce genre de méthode à  NSMutableDictionary... ça donne un comportement spécifique à  une classe à  but générique...


    Ta phrase me gêne : d'une part t'as pas tort, d'autre part ça m'amuse pas de refaire ma page  ;D , et enfin pour moi une catégorie peut être simplement une facilité dans un code et pas forcément quelque chose que l'on réutilisera forcément. Ceci dit ce n'est certes pas le meilleur premier exemple de catégorie. :o  
  • psychoh13psychoh13 Mothership Developer Membre
    02:24 modifié #16
    Tiens voilà  ton exemple de catégorie :
    @interface NSString (PSYObjectCountAddition)<br /><br />- (unsigned)numberOfOccurrencesOfString:(NSString *)aString;<br /><br />@end<br /><br />@implementation&nbsp; NSString (PSYObjectCountAddition)<br /><br />- (unsigned)numberOfOccurrencesOfString:(NSString *)aString {<br />&nbsp; &nbsp; NSRange range = [self rangeOfString:aString];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; unsigned length = [self length];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; unsigned count = 0;<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; while(range.location != NSNotFound)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; count++;<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; NSRange testRange;<br />&nbsp; &nbsp; &nbsp; &nbsp; testRange.location = range.location + range.length;<br />&nbsp; &nbsp; &nbsp; &nbsp; testRange.length = length - testRange.location;<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; range = [self rangeOfString:aString options:0 range:testRange];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; return count;<br />}<br /><br />@end
    


    :D
  • Philippe49Philippe49 Membre
    02:24 modifié #17
    Excellent exemple .
    Les catégories de ce type sont en quelque sorte des méthodes qui font souvent défaut. Pas assez pour être dans la bibliothèque générale, suffisamment pour qu'on prenne la peine d'en faire des fichiers optimisés et réutilisables.

    Mais cela n'empêche pas, à  mon avis, l'utilisation des catégories pour bien équilibrer son projet. Ici la méthode nodeWithName: parent: isLeaf: withCapacity: est très moche sous le modèle d'une fonction C, l'ajouter dans le contrôleur ce n'est pas très beau non plus ... 
  • psychoh13psychoh13 Mothership Developer Membre
    02:24 modifié #18
    Justement, en programmation objet et dans le modèle MVC, c'est plus propre d'ajouter la méthode au controller, ça correspond à  une modularisation du code.
  • Philippe49Philippe49 Membre
    02:24 modifié #19
    Créer un dictionnaire, c'est bien le rôle de la classe dictionnaire. Celui qui utilise une instance d'une classe en demande la création à  la classe ...
    Quand on demande la création d'un dictionnaire par ses entrées, on n'est pas loin de la méthode que je pose.

    Mais je pense que tu as raison sur l'ambiguité de ma présentation, qui tend à  faire passer la classe Node comme une utilisation directe des NSMutableDictionary, ce qu'elle ne doit pouvoir être que dans des cas simplistes. Il faut donc que cette page reste la réponse au challenge, et disparaisse de la barre de menus.
  • Philippe49Philippe49 Membre
    02:24 modifié #20

    La suite c'est l'enregistrement des arborescences:
    Stocker les données sous forme de property list
  • Philippe49Philippe49 Membre
    02:24 modifié #21
    Avec un challenge dont la réponse est sur cette page
  • Philippe49Philippe49 Membre
    02:24 modifié #22
    Le drag and drop sur Outline View
    (dont le code dépend de la classe Node implémentée)
  • Philippe49Philippe49 Membre
    02:24 modifié #23
    6) Browser et property list
    Browser et Property List
    Initialiser le contenu d'un browser avec une plist.


  • Philippe49Philippe49 Membre
    02:24 modifié #24
    7) Adding and removing in NSBrowser
    Gestion (précise) du changement dans l'arborescence

  • Philippe49Philippe49 Membre
    02:24 modifié #25
    8) Edition dans les cellules du browser

    Edition
    via le Field Editor partagé par les contrôles de la fenêtre de l'appli
  • Philippe49Philippe49 Membre
    02:24 modifié #26
    Mercredi 27 Février :
    Une clarification && simplification dans les trois dernières pages.
  • Philippe49Philippe49 Membre
    02:24 modifié #27
    9) Drag and Drop Browser
    drag and drop . Il faut rentrer un peu dans les NSMatrix (regroupant des cellules) qui sont dans chaque colonne, manipuler des NSIndexSet.
    C'est assez précis comme traitement, et je trouve que Drag&Drop Browser, cela sonne un peu comme Rock&Roll.
    D'ailleurs je n'ai pas trouvé de doc sur Internet ...
  • Philippe49Philippe49 Membre
    02:24 modifié #28
    10) Un Browser éditeur de documents (1)
    NSBrowser Document
    Cela peut servir de tuto pour les Document-Based Cocoa Applications avec XCode 3.0
    Enregistrement de property list sous deux formats.

    Une question :
    A quoi sert "OS Types"  dans les properties des documents ?


  • AliGatorAliGator Membre, Modérateur
    02:24 modifié #29
    Heu c'est pas juste pour dire quels types de documents on a le droit de browser ?
    au sens "document word" ou "document Pages" ou "Image JPEG", etc ? (sans doute les codes type (FOURCC) des documents autorisés ?)
    Enfin ce n'est qu'une supposition, ça commence à  faire quelques temps que j'ai pas lancé Xcode, alors :P
  • Philippe49Philippe49 Membre
    mars 2008 modifié #30
    Tu as sans doute raison
    La question que je me pose c'est de savoir si il y a une nomenclature officielle à  respecter

    Voilà  les properties pour Text Edit (clic sur l'image pour agrandir)
  • AliGatorAliGator Membre, Modérateur
    02:24 modifié #31
    J'avoue ne pas avoir le courage de rechercher sur le site Apple, mais du temps d'OS9, c'était ces codes FOURCC qui étaient utilisés pour définir le type de document (puisqu'à  l'époque MacOS n'utilisait pas les extensions de fichier, mais ces codes FOURCC pour déterminer le type du document et son application créatrice).
    Et à  l'époque, toujours, lorsque l'on publiais un logiciel, la plupart des gens choisissaient arbitrairement leur code type et créateur en mettant 4 caractères dont ils étaient à  peu près sûrs qu'ils n'étaient pas pris... Mais la démarche officielle consistait à  s'inscrire sur le site d'Apple en rentrant les codes FOURCC qu'on voulait réserver (y'avait une page dédiée pour ça sur l'ADC). Et ça nous disait si c'était déjà  pris ou pas, et s'ils étaient disponibles du coup il mémorisait qu'on les avait pris pour pas que d'autres les utilisent.

    Bon, depuis les choses ont bien changé, avec OSX et tout, les codes type ne sont plus ce qu'ils étaient. Je me demande même si la page pour réserver les codes type/créateur existe toujours. Cependant, on en a encore les traces, y compris dans le fichier PkgInfo (qui est à  côté du Info.plist dans le dossier Contents du Bundle des applis Cocoa) : il te suffit d'ouvrir un fichier PkgInfo avec un éditeur de texte pour voir lesdits codes.

    Bon après j'en sais pas plus, genre si aujourd'hui il faut continuer de les utiliser voire de les réserver, alors qu'il me semble que ce n'est plus trop d'actualité avec les extensions & co. Voir peut-être la doc sur l'ADC concernant les LaunchServices (ce sont eux qui déterminent avec quelle appli tel document doit s'ouvrir si on double-clic dessus entre autres, donc c'est typiquement eux qui se serviraient éventuellement encore des FOURCC et OSTypes)
Connectez-vous ou Inscrivez-vous pour répondre.