Charger des vues dans un tableau ?

muqaddarmuqaddar Administrateur
22:19 modifié dans API AppKit #1
Tout est dans le titre.
Est-ce possible de charger des vues dans les cellules d'un tableau ?
Si c'est possible, apparemment ça se fait par le code parce que IB a pas l'air OK...

:o

Réponses

  • BruBru Membre
    22:19 modifié #2
    Oui, c'est possible.

    Mais c'est extrêmement compliqué, et ça ne se fait que par programmation.
    En fait, le principe est d'ajouter ta vue via un addSubview: à  la NSTableView, à  l'endroit précis (ligne et colonne) où cette vue doit apparaà®tre.

    Que veux tu mettre comme vue ? Car il existe des alternatives plus "réalistes" :
    - créer un "image" (NSImage) de ta vue pour l'ajouter au tableau via une NSImageCell.
    - créer une cell spécifique à  ce qu'affiche ta vue.

    Ma préférée est la solution 2.

    .
  • muqaddarmuqaddar Administrateur
    22:19 modifié #3
    Et bien je veux afficher le contenu de mes casiers de bouteilles.
    Je les crée avec drawRect et je voulais m'en servir pour les afficher également, en fonction du contenu d'un plist de sauvegarde (emplacement, nombre bouteilles...etc).

    Maintenant, je voulais pas avoir à  stocker des images, peut-on créer alors des images temporaires ? C'est à  dire non gérées sur le HD, mais qui se créent à  partir de drawRect uniquement en mémoire quand l'appli est lancée ?
    Peut-on faire clignoter des cellules de tableaux ? (à  la base, je voulais changer les couleurs de ce qui était affiché par drawRect)

    Sinon, je peux p-e me passer de tableau avec des views mais ça m'oblige à  créer pleins d'outlets je pense...
  • cbrandtcbrandt Membre
    22:19 modifié #4
    je pense que le plus simple est de surclasser nsview, et en plus c'est très simple:
    <br />- (void) drawInteriorWithFrame: (NSRect) cellFrame inView: (NSView*) controlView<br />{<br />dessiner ici les bouteilles<br />}<br />
    
  • 22:19 modifié #5
    C'est pour NSCell ça ;)
  • cbrandtcbrandt Membre
    janvier 2005 modifié #6
    argh, oui oui, bien sûr, je voulais écrire NSCell !! :)beta: :)beta:

    pour me pardonner, voici ladite nscell (pas testé, mais ça doit pas être bien loin):

    .h:

    <br />//<br />//  Bouteille.h<br />//  PlaceBouteilles<br />//<br />//  Created by Alexandre Bournier on 24/01/05.<br />//  Copyright 2005 __MyCompanyName__. All rights reserved.<br />//<br /><br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br /><br />@interface Bouteille : NSCell {<br /><br />	NSNumber *nbreBouteillesL;<br />	NSNumber *nbreBouteillesH;<br />	<br />}<br /><br />- (void)bouteillesPourLargeur:(NSNumber*)l andHauteur:(NSNumber*)h;<br /><br />@end<br />
    


    et .m:

    <br />//<br />//  Bouteille.m<br />//  PlaceBouteilles<br />//<br />//  Created by Alexandre Bournier on 24/01/05.<br />//  Copyright 2005 __MyCompanyName__. All rights reserved.<br />//<br /><br />#import &quot;Bouteille.h&quot;<br /><br /><br />@implementation Bouteille<br /><br />- (id)init{<br />    self = [super init];<br />    if (self) {<br />		nbreBouteillesL = [[NSNumber alloc] initWithInt:3];<br />		nbreBouteillesH = [[NSNumber alloc] initWithInt:2];<br />    }<br />    return self;<br />}<br />- (void) dealloc<br />{<br />	[nbreBouteillesL release];<br />	[nbreBouteillesH release];<br />}<br /><br />//récupération des valeurs du controlleur<br />- (void)bouteillesPourLargeur:(NSNumber*)l andHauteur:(NSNumber*)h<br />{<br />	[l retain];<br />	[nbreBouteillesL release];<br />	nbreBouteillesL=l;<br />	[h retain];<br />	[nbreBouteillesH release];<br />	nbreBouteillesH=h;<br />	<br />	NSLog(@&quot;largeur : %@&quot;, nbreBouteillesL);<br />	NSLog(@&quot;hauteur : %@&quot;, nbreBouteillesH);<br />	[self setNeedsDisplay:YES];<br />}<br /><br />- (void) drawInteriorWithFrame: (NSRect) cellFrame inView: (NSView*) controlView<br />{<br />	NSLog(@&quot;hauteur2 : %@&quot;, nbreBouteillesH);<br />	<br />	NSColor *color = [[NSColor colorWithCalibratedRed:0.1 green:0.5 blue:0.2 alpha:1] set];<br />	int i, j;<br />	<br />	for (i=1; i&lt;=[nbreBouteillesL intValue]; i++) {<br />		for (j=1; j&lt;=[nbreBouteillesH intValue]; j++) {<br />			NSRect r = NSMakeRect((0+(25*i)), (0+(25*j)), 20, 20);<br />			NSBezierPath *bp = [NSBezierPath bezierPathWithOvalInRect:r];<br />			[bp setLineWidth:2];<br />			[bp stroke];<br />		}<br />	}	<br />}<br /><br />@end<br />
    



    EDIT:
    il faut probablement décaler l'origine de l'affichage avec la position de cellFrame:
    <br />			NSRect r = NSMakeRect((cellFrame.origin.x+(25*i)), (cellFrame.origin.y+(25*j)), 20, 20);<br />
    
  • muqaddarmuqaddar Administrateur
    22:19 modifié #7
    Merci cbrandt.

    Faut que je gère ça par NSMatrix (dixit Renaud) + sous classer NSCell
    Parce que j'ai 2 types de drawRect en fait.
    ça va être coton.
  • muqaddarmuqaddar Administrateur
    22:19 modifié #8
    :why?:

    J'ai besoin d'aide.  :o
    Apparemment, je dois afficher mes vues dans les cellules d'une matrice.
    Or j'ai jamais touché aux matrices.

    Donc dans mon Bouteille.m, j'ai :
    [tt]- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
    {
    NSColor *color = [[NSColor colorWithCalibratedRed:0.1 green:0.5 blue:0.2 alpha:1] set];
    int i, j;

    //casier rectangulaire
    if (nbreBouteillesT==0) {
    for (i=0; i<nbreBouteillesL; i++) {
    for (j=0; j<nbreBouteillesH; j++) {
    NSRect r = NSMakeRect((cellFrame.origin.x+1+(18*i)), (cellFrame.origin.x+1+(18*j)), 15, 15);
    NSBezierPath *bp = [NSBezierPath bezierPathWithOvalInRect:r];
    [bp setLineWidth:2];
    [bp stroke];
    }
    }
    [/tt]

    Et ça je dois faire comprendre à  mon controlleur qui gère la matrice de l'afficher dans les cellules de la matrice. Me fais-je comprendre ?

    Ainsi dans mon controlleur, j'ai :

    [tt][matrice addRowWithCells:_newCells];[/tt]

    où _newCells doit être un array de cellules apparemment ?

    Bon, je coince. Je rappelle que je veux afficher des instances de ma sous classe de NSCell (avec drawRect) dans les cellules de la matrice.

    Epaulez moi !  <3
  • cbrandtcbrandt Membre
    janvier 2005 modifié #9
    - utilise dans awakefromnib du controller - (void)setCellClass:(Class)aClass avec [Bouteille class] pour indiquer la classe des cellules à  utiliser et - (void)setCellSize:(NSSize)aSize pour définir leur taille.

    - utilise - (void)addRowolumn ou - (void)addColumn pour ajouter des rangées/colonnes. après appelle - (void)sizeToCells pour redimensionner la matrice de façon à  englober les cellules ajoutées et setNeedsDisplay pour raffraà®chir

    - utilise - (id)cellAtRow:(int)row column:(int)column pour accéder à  une cell spécifique, par ex. pour modifier ses caractéristiques.


    EDIT:

    tu veux une cellule par bouteille ? donc ta matrice aura largeur x hauteur nb. de cellules - dans ce cas il faut modifier ton drawInteriorWithFrame pour n'afficher qu'une bouteille...
    sinon if faudra redimensionner la cellule de façon à  afficher le nb. de bouteilles voulu...
    on manque un peu d'infos sur ce que tu veux faire exactement
  • muqaddarmuqaddar Administrateur
    janvier 2005 modifié #10
    Merci cbrandt pour ces précieuses infos.

    Je m'explique un peu mieux maintenant. :)

    Ma matrice doit contenir 5 * 4 vues dans tous les cas. Après, le contenu des vues change selon les contenu d'un plist. Les vues peuvent être vides.
    Chaque vue affiche des graphiques grâce à  drawRect qui est appelé dans chaque cellule (donc ds chaque vue). Il y a un casier par vue (ou par cellule) qui contient x bouteilles renseignées et construites d'après les données du plist.

    Voilà . J'espère que c'est un peu plus clair. ;)
  • cbrandtcbrandt Membre
    22:19 modifié #11
    on comprends un peu mieux...

    cepandant le nom de te classe prête à  confusion: en fait ta classe MaBouteille devrait plutôt s'appeler MonCasier, non ? vu que une matrice contient 20 cellules (casiers), chaque casier affichant nbLargeur x nbHauteurs bouteilles ?
    c'est ça ?
  • muqaddarmuqaddar Administrateur
    22:19 modifié #12
    Tout à  fait !
    Je corrige ce nom et t'envoie un projet par MP (juste pour que tu regardes) qui t'aidera à  comprendre.

    A tout de suite. :)
  • cbrandtcbrandt Membre
    22:19 modifié #13
    ok, je jette un oeuil
  • muqaddarmuqaddar Administrateur
    22:19 modifié #14
    Il n'y a pas une méthodes pour ajouter x lignes de y cellules ?
    Je n'ai trouvé que ça : addRowWithCells:
    qui ajoute une ligne à  chaque fois (il me suffirait de boucler) mais je suis étonné...
  • BruBru Membre
    22:19 modifié #15
    dans 1106993096:

    Il n'y a pas une méthodes pour ajouter x lignes de y cellules ?
    Je n'ai trouvé que ça : addRowWithCells:
    qui ajoute une ligne à  chaque fois (il me suffirait de boucler) mais je suis étonné...


    Si ça exite. Ca s'appelle :

    [tt]- (void)renewRows:(int)newRows columns:(int)newCols[/tt]

    .
  • muqaddarmuqaddar Administrateur
    22:19 modifié #16
    J'avais vu cette méthode mais en lisant sa doc, je suis resté "perplexe".

    "This method uses the same cells as before, creating new cells only if the new size is larger; it never frees cells."

    C'ets le "creating new cells only if the new size is larger" qui m'a troublé. Je vais essayer. merci
  • muqaddarmuqaddar Administrateur
    22:19 modifié #17
    La matrice m'affiche le contenu de la cellule que si celle-ci est en (0,0) en position.

    Pourtant , j'ai fait ça avant :

    [matrice renewRows:5 columns:4];
    [matrice sizeToCells];

    Pourquoi ça ne marche qu'avec la row 0 et column 0 ?

    [(Casier*) [matrice cellAtRow:0 column:0 bouteillesPourLargeur:5 andHauteur:6];
    marche, mais pas :
    [(Casier*) [matrice cellAtRow:1 column:1 bouteillesPourLargeur:5 andHauteur:6];
  • BruBru Membre
    22:19 modifié #18
    Chez moi ça fonctionne.

    Comment as tu créé ta NSMatrix ?

    .
  • muqaddarmuqaddar Administrateur
    22:19 modifié #19
    Comme ça :

    //configuration de la matrice principale
    [matrice setCellClass: [Casier class]];
    [matrice setCellSize: [matrice frame].size];
    [matrice renewRows:5 columns:4];
    [matrice sizeToCells];

    Ah bein oui, j'ai la réponse dans mon code :
    [matrice setCellSize: [matrice frame].size];

    Doit falloir ajouter une division pour la taille ?
  • BruBru Membre
    22:19 modifié #20
    OUI. Mais que cherches tu à  faire avec [tt][matrice setCellSize: [matrice frame].size][/tt] ?

    .
  • muqaddarmuqaddar Administrateur
    22:19 modifié #21
    Bein je cherche à  définir la taille d'une cellule. Je voudrais le faire automatiquement en fonction de la taille de la matrice vu que j'ai 4 cellules en largeur * 5 en hauteur.

    J'ai supprimé cette ligne, ça va mieux mais c'est pas encore ça, mes vues se montent dessus. :)
  • cbrandtcbrandt Membre
    22:19 modifié #22
    <br />[matrice setCellSize: [matrice frame].size]<br />
    

    c'est pour une matrice de 1 x 1... pour 4 x 5 faire quelque chose comme ça:
    <br />NSSize size;<br />size.width = [matrice frame].size.width / 4;<br />size.height = [matrice frame].size.height / 5;<br />[matrice setCellSize: size];<br />
    

  • muqaddarmuqaddar Administrateur
    22:19 modifié #23
    merci cbrandt, j'avais essayé bêtement de diviser la size comme ça :

    size.width = [matrice frame].size.x / 4;
    size.height = [matrice frame].size.y / 5;
  • Eddy58Eddy58 Membre
    22:19 modifié #24
    Révise ta structure NSRect Oxitan. ;)
    Car là  en faites tu essayais de calculer tes largeur et hauteur avec les coordonnées d'origine de ta matrice, et encore, d'une drôle de manière... ???

    [tt]
    typedef struct _NSRect {
    NSPoint origin;
    NSSize size;
    } NSRect;

    typedef struct _NSPoint {
    float x;
    float y;
    } NSPoint;

    typedef struct _NSSize {
    float width;
    float height;
    } NSSize;

    [/tt]
  • muqaddarmuqaddar Administrateur
    22:19 modifié #25
    Oui, je me suis mélangé les pinceaux entre NSSize et NSPoint...

    Pas glop.  :o :)beta: :o
  • nucleusnucleus Membre
    22:19 modifié #26
    Pour ceux qui veulent pas ré-enventer la roue: The Subview-TableView  <3
  • muqaddarmuqaddar Administrateur
    22:19 modifié #27
    Très sympa ce lien !
    Merci nucleus.
Connectez-vous ou Inscrivez-vous pour répondre.