Icones et text dans OutlineView editables

LeChatNoirLeChatNoir Membre, Modérateur
13:15 modifié dans API AppKit #1
Salut,

Bon je fais une OutlineView avec icone+texte.

D'après ce que j'ai compris, ca se fait facilement (et je l'ai fait) avec une NSBrowserCell comme colonne de la OutlineView.

Mais dès qu'on veut que ca soit editable (c'est à  dire que l'utilisateur peut double cliquer sur un élément et changer le text), j'ai cru comprendre qu'il fallait sous classer une NSTextFieldCell (peut être que c'est possible aussi avec une NSBrowserCell d'ailleurs) pour redéfinir la méthode "selectWithFrame:inView:editor:delegate:start:length:" afin de découper la cellule en 2 et ne sélectionner que le texte.

Bon pourquoi pas.

Mais maintenant, je veux aller un peu plus loin.
Cette méthode rend "éditable" le text en le mettant en surbrillance mais le rectangle part du début du texte et va jusqu'au bout de la colonne de mon outlineview.

Or j'aimerai qu'il n'encadre que le texte ! Comme dans le Finder par exemple.

Et je me demande bien comment on peut faire vue que dans ces méthodes, on n'a pas accès au text...

Qqu'un a t il compris ? Et si oui, des pistes ? Merci !

Réponses

  • ChachaChacha Membre
    13:15 modifié #2
    Salut,

    J'ai déjà  utilisé les ImageAndTextCell

    [url=http://www.objective-cocoa.org/forum/index.php?topic=893.msg10250#msg10250<br />]
    http://www.objective-cocoa.org/forum/index.php?topic=893.msg10250#msg10250
    [/url]

    Pas besoin d'utiliser NSBrowserquoiquecesoit
    Quand on édite une telle cellule, seul le texte est sélectionné.

    +
    Chacha
  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #3
    Ben
    dans 1128344048:

    Quand on édite une telle cellule, seul le texte est sélectionné.
    +
    Chacha


    Ben pas vraiment en fait.
    Effectivement, seul le texte est sélectionné mais le rectangle s'étend du début du texte jusqu'au bout de la colonne.

    Alors que quand on veut renommer un fichier dans le finder par ex, le rectangle fait pile poil la longueur du texte...

    Si je prend l'exemple Apple de l'outlineview avec drag and drop, le rectangle fait la taille de la colonne, quelle que soit la longueur du texte.

    Et là  est toute la différence. C'est que je me demande comment on peut faire, sachant que dans les méthodes utilisées pour dessiner cette zone d'édition, on a pas accès à  l'item de l'outlineview...  :(
  • ChachaChacha Membre
    octobre 2005 modifié #4
    Effectivement, seul le texte est sélectionné mais le rectangle s'étend du début du texte jusqu'au bout de la colonne.

    Ah, pardon, j'avais mal compris; effectivement, ce que tu demandes n'a pas l'air évident. Pour l'instant je ne sais pas, désolé. Je vais regarder...

    +
    Chacha
  • octobre 2005 modifié #5
    J'ai essayé de faire ce truc. Beaucoup de chipo, pour au final pas grand chose. Lors de la fusion des données de mes deux anciens ordis vers l'actuel, j'ai perdu les sources donc... Bon si tu veux une piste:

    Les NSTextField, NSTableView sont incapables d'éditer du texte, l'édition est déléguée à  une NSTextView créée spécialement pour l'occasion, qui s'obtient par la méthode [tt]- (NSText *)fieldEditor:(BOOL)createFlag forObject:(id)anObject[/tt] de NSWindow, méthode qui fait elle même appel au delegate  de la fenêtre, s'il existe, par la méthode suivante: [tt]- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject[/tt]. Avec ces méthodes tu peux facilement utiliser un autre éditeur que celui par défaut, qui devra être une sous-classe de NSTextView. Cette sous-classe de NSTextView devra se redimensionner en cours de frappe, mais le problème est qu'elle est elle même encapsulée dans une autre vue (d'une classe privée), qui a elle la taille de la cell que tu veux éditer, si ta textview devient trop grande, il faut redimensionner sa superview pour arriver à  la bonne taille.

    EDIT: pour une fois c'est moi :p
  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #6
    aà¯e, ça fait mal  :brule:
    Bon je vais relire ta réponse en boucle pendant quelques jours afin de tenter de comprendre.
    En tous cas, merci !  :-*
  • ChachaChacha Membre
    13:15 modifié #7
    Un début de piste :
    Dans le code d'Apple de ImageAndTextCell, il y a une surcharge de selectWithFrame et editWithFrame. Si on triture la taille à  ce moment là , il y a moyen de faire quelque chose


    -(void) selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength
    {
      theControlView = controlView;
      NSRect textFrame, imageFrame;
      NSDivideRect (aRect, &imageFrame, &textFrame, 3 + [image size].width, NSMinXEdge);

      //je rajoute ça
      textFrame.size.width = [[self attributedStringValue] size].width;

      [super selectWithFrame: textFrame inView: controlView editor:textObj delegate:anObject start:selStart length:selLength];
    }


    Problème : la taille ne change pas pendant qu'on tape le texte.
    On peut surcharger "textDidChange" pour intercepter, mais je ne sais pas comment retailler la cellule à  ce moment là .

    +
    Chacha

    [edit]
    ah, tiens, grilled.
    En mixant ces deux réponses, y'a peut-être moyen d'arriver à  un truc ?
    [/edit]
  • LeChatNoirLeChatNoir Membre, Modérateur
    octobre 2005 modifié #8
    Bon merci à  vous 2,
    Je vais essayer de regarder.
    Dans l'idéal, j'aimerai que ca se passe comme dans le finder à  savoir :

    * En affichage, si le texte est plus grand que la colonne, mettre des "..." au milieu,

    En modification :
    * quand le texte est plus petit que la colonne, le rectangle de sélection doit coller au texte,
    * si ajout de caractères, le rectangle s'aggrandit en même temps,
    * si on arrive en bout de colonne, passage à  la ligne suivante.

    Une outlineview qui marcherait comme ça serait classieuse.

    Mais ca me parait compliqué... Suis pas un pro des vues moi  :'(
    a+
  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #9
    Salut,
    Je relance le sujet car j'ai un peu creusé...

    Grâce à  Chacha, j'ai découvert les AttributedString. J'arrive donc, au double-clique, à  ce que mon rectangle de sélection couvre juste le texte et ne soit pas aussi large que la colonne de mon outlineView.

    Pour ce qui est du redimensionnement en cours de frappe par contre, c'est une autre histoire...

    En fait, mon objet delegate de ma NSOutlineView arrive à  trapper les évènement clavier (textDidChange, shouldBeginEditing...).
    Dans ces évènements, j'arrive à  chopper l'objet qui envoit la notification qui est un NSText (sous classe de NSView).

    Cela me permet il de bosser sur le redimensionnement dynamique ?
    J'ai l'impression que non car il faudrait que j'arrive à  redéclencher les "DrawMachinChose" de ma NSCell perso qui peuple la NSOutLineView et ça, j'arrive pas à  le faire...

    Je n'arrive pas non plus à  faire en sorte que ca soit ma sous classe perso de NSTextFieldCell qui trappe la notification (c'est l'outlineview qui la choppe et ne la repasse pas à  ses cellules apparemment).

    Bref, je suis un peu perdu et j'ai du mal à  comprendre les autres objets dont Apple parle pour ce genre de chose à  savoir les NSLayoutManager, NSInputManager, NSTextContainer, etc, etc...

    Si quelqu'un peut me remettre sur le droit chemin avant que je me noie...

    Merci !
  • ChachaChacha Membre
    13:15 modifié #10
    dans 1128671408:

    Pour ce qui est du redimensionnement en cours de frappe par contre, c'est une autre histoire...

    Salut,
    Si ça peut te rassurer, j'ai rencontré tous les problèmes que tu décris. En fait, j'arrive à  peu près à  redimensionner le champs de saisie à  la volée, mais je n'arrive pas à  redimensionner la zone qui a le ring focus, par exemple - et pourtant, j'en ai essayé, des NSView et des NSCell, pour ça !


    Je n'arrive pas non plus à  faire en sorte que ca soit ma sous classe perso de NSTextFieldCell qui trappe la notification (c'est l'outlineview qui la choppe et ne la repasse pas à  ses cellules apparemment).

    Là  par contre, je suis un peu surpris; si tu rajoute la méthode -(void)textDidChange:(NSNotification*) dans ta sous-classe, elle est déclenchée à  chaque frappe de clavier; et dans ce cas, la cellule, c'est "self".

    +
    Chacha
  • LeChatNoirLeChatNoir Membre, Modérateur
    octobre 2005 modifié #11
    Ah ben je suis déçu :-(
    je vais devoir creuser seul alors... snif...

    Pour le 2eme point, moi aussi je suis surpris.
    J'ai pourtant mis la méthode dans ma NSCell perso et dans outlineview mais la première ne se déclenche pas.

    J'ai tenté de virer celle de la NSOutlineview mais pas mieux...

    Là  encore, je vais creuser...

    a+

    [edit] en plus, je viens de voir que les champs du carnet d'adresse fonctionnent comme ça mais c'est encore plus top puisqu'il sont dans une sorte de TextField avec une ombre du plus bel effet ! [/edit]
  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #12
    Re, re,

    ben apparemment, y a les réponses dans, je cite, " Cocoa Tips & Tricks session this past June (session 424)" de la WWDC 2003.    :o

    Quelqu'un a accès à  ce truc ?


  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #13
    Re,
    Un peu avancé...
    J'arrive à  mettre ma classe perso em observeur de la notification "TestDidChange". Je sais, c'est pas gd chose mais pour moi, c'est une grande victoire :-)

    Je me dit qu'alors, je pourrai lancer un DrawMachinChose qui va bien.
    Seulement voilà , le texte récupéré après avoir inséré un caractère (ou plus) resdte celui d'origine ! Comme si ce qui était affiché à  l'écran n'était pas encore "inséré" dans la NSCell....

    Une idée ?
  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #14
    Slt,
    bon je continue mon monologue !

    Alors finalement, j'arrive à  trapper un TextDidChange et dans le delegate de mon outlineview, et dans la NSCell perso de l'outlineview qui est sélectionnée en la mettant observeur de l'évènement.

    Première observation et question :

    * Dans le delegate, j'arrive à  récup' le texte (par un stringValue) qui me donne bien le texte avec le caractère fraichement saisi.
    * Dans ma cellule perso, je ne trouve que le texte d'origine...
    => Comment ça se fait ?


    2eme observation :
    * dans le delegate, vu que j'ai le nouveau texte, j'essaye de retailler la cellule en faisant appel à  "selectWithFrame:inView:editor:delegate:start:length:". En paramètre, je passe la frame que je récupère grâce à  un frame sur la cellule sélectionnée ; j'augmente le width pour que ça prenne en compte le nouveau caractère.
    Ensuite, je passe l'outlineView pour controlView, nil pour Editor (car la cellule comporte text+image), l'outlineview comme delegate et 0 + with de ma cellule en longueur.

    Et devinez quoi, ca marche pas :-(

    Est ce que quelqu'un a compris ?
    Faut il que je poste le code ?

    Merci de votre aide !




  • ChachaChacha Membre
    13:15 modifié #15
    dans 1128935598:

    * Dans le delegate, j'arrive à  récup' le texte (par un stringValue) qui me donne bien le texte avec le caractère fraichement saisi.
    * Dans ma cellule perso, je ne trouve que le texte d'origine...
    => Comment ça se fait ?

    La cellule ne contiendra le nouveau texte que lorsqu'il aura été validé. Le texte courant est contenu dans le field editor créé à  la volée.


    2eme observation :
    * dans le delegate, vu que j'ai le nouveau texte, j'essaye de retailler la cellule en faisant appel à  "selectWithFrame:inView:editor:delegate:start:length:". En paramètre, je passe la frame que je récupère grâce à  un frame sur la cellule sélectionnée ; j'augmente le width pour que ça prenne en compte le nouveau caractère.

    J'avais essayé aussi de rappeler selectWithFrame, ou editWithFrame, mais ça ne marchait pas non plus. Je ne sais pas ce qu'il faut faire pour retailler la cellule.
    ça va, tu ne te sens pas trop seul ?
    Bon courage, en tous cas.

    +
    Chacha
  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #16
    dans 1128935977:

    ça va, tu ne te sens pas trop seul ?
    Bon courage, en tous cas.

    +
    Chacha



    Ben nan, maintenant que tu m'as répondu  ;)
    Merci pour l'explication du 1er point.
    Pour le 2nd, je vais continuer à  chercher mais dans un petit moment (contre temps oblige)...

    Mais si Renaud ou d'autres ont une idée, ils sont les bienvenus !
    Et, sait on jamais, si je trouve, je vous tiens au courant.

    a+
  • LeChatNoirLeChatNoir Membre, Modérateur
    13:15 modifié #17
    Salut !

    Bon ben je patauge.

    Je me suis plongé dans "Text System Architecture" avec les NSLayoutManager, NSTextContainer, NSTextStorage...

    Ne comprenant pas tout, j'ai vu que Sketch traitait le sujet (on peut glisser du texte et le comportement est un peu celui que j'attend) mais dans des vues complètements personnalisées.

    Bref, j'avance un peu mais je m'enfonce  :-\\

    Quelqu'un peut il m'éclairer un peu sur ces classes.

    J'ai compris que le texte brut était géré dans NSTextStorage, que NSTextContainer définit des zones d'affichage, que NSTextView les dessine à  l'écran et que NSLayoutManager "manage" tout ça...

    Mais comment l'implémenter dans les cellules d'une outlineview ?

    Rappel : je cherche à  faire en sorte que la cellule dans laquelle je suis en train de saisir s'agrandisse au fur et à  mesure de la frappe.

    Bref, j'avoue que je suis un peu noyé et l'exemple de Sketch est bien compliqué... J'arrive pas à  distinguer ce que font les layoutManager et compagnie de ce que font les vues...

    Merci de votre aide !


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