Barre de tri

laurrislaurris Membre
06:54 modifié dans API AppKit #1
Bonjour,

Je cherche à  refaire un élément d'interface semblable à  la barre qui apparaà®t dans Mail ou iTunes quand on écrit dans le searchField.
Bien sûr, ça ne doit pas être difficile à  faire mais j'aimerais avoir les bonnes couleur et les bons bindings.

J'ai bien cherché dans ce forum ou sur la liste Apple. Problème: je ne sais même pas par quel terme désigner cette chose.

Connaissez-vous des exemples de code pour cette "barre" ou alors juste son petit nom pour que je puisse chercher efficacement moi-même ?





[Fichier joint supprimé par l'administrateur]

Réponses

  • 06:54 modifié #2
    Je dirais une NSMatrix (custom pour permettre d'avoir des tailles différentes de cellules) avec des NSButtonCell dedans (pour qu'elles aient l'apparence recherchée, c'est setBezelStyle:NSRecessedBezelStyle)
  • laurrislaurris Membre
    06:54 modifié #3
    Merci Renaud.
    Bizarre que ce style n'existe pas dans IB. J'ai aussi trouvé ça d'intéressant sur le même sujet , à  cocoadev:  http://www.cocoadev.com/index.pl?ITunesSearchFilterBar

    Maintenant, le plus dur est de binder le array controller à  la matrix pour faire le filtrage. Et binder une Matrix, je trouve ça galère surtout que je dois le faire à  la main.
  • avril 2006 modifié #4
    Ah? tout dépend de la manière de tourner le problème.

    1. tu rajoutes un array controller pour ta matrice (predicateArrayController)
    2. une variable d'instance ton controller principal de type tableau  (qui contient par exemple un dico avec pour la clé "value" la valeur à  afficher par le bouton et à  la clé "predicate" un nspredicate qui contient les critères de tri). je vais supposer que ce tableau s'appelle predicateArray.
    3. tu bindes le content de ta matrice à  la clé predicateArray de ton controller principal
    4. tu bindes le contentValues de la matrice au keypath predicateArray.value

    6. tu bindes le filterpredicate de ton arraycontroller de la table principale à  ton predicateArrayController (controllerKey: selection, keypath: predicate)

    (petite précision, je n'ai pas testé)
  • laurrislaurris Membre
    avril 2006 modifié #5
    Merci Renaud, j'ai fait ce que tu me conseilles et ça presque marche.
    La seule différence est que j'ai bindé la matrice non pas à  une variable d'instance predicateArray mais au ArrayController qui lui-même lui binde son contentArray.

    <br />	[predicateArrayController bind:@&quot;contentArray&quot; toObject:self withKeyPath:@&quot;predicateArray&quot; options:NULL];<br />	<br />	[matrix bind:@&quot;content&quot; toObject:predicateArrayController withKeyPath:@&quot;arrangedObjects&quot; options:NULL];<br /><br />	[matrix bind:@&quot;contentValues&quot; toObject:predicateArrayController withKeyPath:@&quot;arrangedObjects.title&quot; options:NULL];<br /><br />
    


    J'ai aussi bindé le "filterPredicate" du arrayController de la table à  trier à  la selection de la matrix. Problème: quand je change la sélection de la matrice, rien ne se passe (je le sais parce que j'ai enregistré des observers et placé le delegate approprié).
    J'imagine que cela vient du fait que la selection de la matrice n'est pas bindé. J'ai donc essayé de le faire ça "raise des exceptions" !
    Que ce soit pour le binding "selectedObject" ou "selectedIndex", la console me dit que le chemin de ce binding n'est pas défini pour la matrix. Pourtant ils existent.

    Je ne vois pas trop pourquoi ce binding est considéré comme indéfini. Problème de chronologie des différents bindings, ou d'options ?
    Dès que j'ai résolu, je poste mes résultats avec un projet test.

  • avril 2006 modifié #6
    Tu as essayé en faisant comme j'ai dit dans mon point 6? Sans rentrer dans les détails, un controle bindé à  un controller n'a pas de sélection, il ne fait que refléter la sélection du controller dont il dépend. Donc pas vraiment de raison de binder quelque chose à  un controle, autant le faire directement au controller (sans compter que ça tu peux le faire direct dans IB, pas besoin de passer par du code).
  • laurrislaurris Membre
    avril 2006 modifié #7
    Oui, le point 6 marche. J'ai bien le (filterPredicate de l'array controller qui gère la table) égal au (predicate de l'objet de la matrice). Je le vois avec un log. Le arraycontroller sélectionne tout seul le premier objet, c'est pour ça que ça marche.
    Mon problème c'est ensuite, pour changer la sélection de predicateArrayController  à  partir de l'UI matrice. Mais c'est surtout que je n'arrive pas à  binder correctement la selection de la matrice sans avoir une erreur.

    [edit] Si je comprends bien, d'après toi pas besoin de binder la selection de la matrix ?
    Je ne comprends pas bien ta dernière phrase.
  • 06:54 modifié #8
    ce que je veux dire c'est que tout controle (table, matrice, popup,....) bindé à  un array controller ne fait que refléter l'état de l'array controller. Le contenu affiché sera les arrangedObjects de l'array controller, la sélection sera celle de l'array controller. Donc binder un objet à  la sélection est un "détour" (et en plus ce n'est pas possible si je ne m'abuse), autant binder directement à  l'array controller.

    Sinon j'ai bien fait de laisser laisser de la place pour un 5... J'avais bien entendu oublié quelque chose: binder le selectedIndex de la matrice au predicateArrayController, controller key: selectionIndex.
  • laurrislaurris Membre
    06:54 modifié #9
    Ton 5 je l'essaie, je l'essaie ... sans succès depuis tout à  l'heure. Un truc m'échappe.
    Je fais ce binding là  :
    <br />	[matrix bind:@&quot;selectedIndex&quot; toObject:sortKeysController withKeyPath:@&quot;selectionIndex&quot; options:NULL];<br />
    


    et je me prends ça:
    <br />Uncaught exception - [&lt;NSMatrix 0x4f3b810&gt; valueForUndefinedKey:]: this class is not key value coding-compliant for the key selectedIndex.<br />
    


    L'erreur vient sûrement de quelque chose d'évident mais pour l'instant je bloque.
  • avril 2006 modifié #10
    je ne pige pas pourquoi tu tiens à  le faire par code (ta ligne me semble correcte pourtant - mais bon, ça ne change rien au fait que ça devrait marcher). Ci joint mon projet de test, tu verras que le code n'est vraiment nécessaire que pour changer le style des boutons dans la matrice et créer les predicate, pour le reste tout se fait dans IB.

    Sinon petit truc, si tu veux binder par code, utilise les constantes (NSSelectedIndexBinding par exemple, même si dans le cas présent ça ne changerait rien).

    [Fichier joint supprimé par l'administrateur]
  • LeChatNoirLeChatNoir Membre, Modérateur
    06:54 modifié #11
    Alors là , je suis soufflé !  o:)
    Ca a l'air sympa Core Data !
  • laurrislaurris Membre
    avril 2006 modifié #12
    Renaud, merci pour ton exemple !

    Je viens de comprendre le problème et effectivement je l'aurais compris bien plus vite si j'avais bindé dans IB. Le binding "selectedIndex" n'est disponible que si la matrice se trouve en mode NSRadioModeMatrix.
    ( je ne comprends pas bien cette limitation puisqu'en mode List on peut aussi avoir une sélection dans l'UI, mais bon)

  • 06:54 modifié #13
    En mode liste, il peut y avoir plusieurs éléments sélectionnés, donc ce binding est trop restrictif.
  • laurrislaurris Membre
    06:54 modifié #14
    OK. Bon maintenant tout marche. Mais ... j'ai encore une petite question même si je pense que je devrais créer un sujet dans le forum "bindings" plutôt que de continuer ici.
    Apparemment, la matrice ne crée pas les cellules à  la volée en fonction du nombre d'objets dans le array controller. Or mes objets contenus par la matrice sont dynamiques donc je me demandais si on pouvait obtenir ce comportement.
    Est-ce qu'il faudrait sous-classer le array controller pour qu'il modifie le nombre de colonnes de la matrice quand le nombre d'objets dans le contentArray change ? ou se débrouiller avec les observers et leur delegate ? . Je me tate avant de commencer sur une de ces pistes.


  • 06:54 modifié #15
    contrairement aux tables, le nombre de cellules des matrices est prédéterminée, donc t'as pas trop le choix à  ce niveau. S'il y a changement à  faire, c'est au niveau de la matrice si tu veux savoir (sinon pas propre), mais mieux vaut créer un nouveau sujet
Connectez-vous ou Inscrivez-vous pour répondre.