Glisser-Déposer images
muqaddar
Administrateur
Salut,
Je cherche un article sur le glisser/déposer d'images depuis le finder ds une NSImageView... mais je ne sais plus où je l'ai vu.
ça ne vous dit rien ? :why?:
Je cherche un article sur le glisser/déposer d'images depuis le finder ds une NSImageView... mais je ne sais plus où je l'ai vu.
ça ne vous dit rien ? :why?:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
http://cocoadevcentral.com/articles/000056.php
C'est celuil-là , merci !
Si je puis me permettre : pour glisser/déposer dans une NSImageView, il n'y a rien à faire, sinon s'assurer que "enabled" est bien coché dans les propriétés de la NSImageView. Donc pour une classe personnalisée, si on dérive de NSImageView, il n'y a pas plus de choses à faire.
L'article de CocoaDevCentral traite de ce problème pour les NSView quelconques, où là , il faut effectivement s'occuper soi-même du drop.
+
Chacha
A vrai dire, je m'étais posé la question et j'avais essayé... sans succès.
En fait, c'est parce que c'est editable qui doit être coché, et non enabled !
Bon, bein je passe à la question suivante.
Je dois sauvegarder cette image qui se rapporte à une clé d'un array.
Pour l'instant, toutes les données de l'array sont ds un plist.
Comment ça se passe pour les images ds un rep? C'est copié en tant qu'image ? c'est encodé ds un fichier ?
Oups ! Désolé.
heu... déjà je ne comprends pas très bien. Chaque case contient un objet plist ?
Pareil, je ne comprends pas bien la question...
+
Chacha
Il n'y a que du texte ou des nombres.
Pour sauver une image (celle de la NSImageView glissée), je suppose que je dois la convertir en NSData ?
Quelle est la marche à suivre ? Il faut un fichier en plus pour sauvegarder toutes les images ? (pour chaque ligne de mon array, il peut y avoir une image)
Bon, dis-moi si j'ai bien compris: tu as donc un dico par case, chaque dico étant un ensemble de propriétés décrivant un objet à toi. Ton tableau décrit donc l'ensemble de tes objets.
A priori, non, car une image respecte le protocole NSCoding, donc elle sait se sauvegarder/charger toute seule, dans le cas où on la sauvegarde en utilisant un NSArchiver.
Après, peut-être utilises-tu une méthode de sauvegarde particulière aux property list, et tu te demandes si elle saura gérer les NSImages ?
Note que je n'ai pas encore répondu exactement à ta question, parce qu'il me manque encore quelques détails pour être sûr de ne pas répondre à côté.
+
Chacha
[tt]
<array>
<dict>
<key>1001</key>
<string>rouge</string>
<key>1002</key>
<string></string>
<key>1003</key>
<string>fra</string>
<key>1004</key>
<string>bor</string>
<key>1005</key>
<integer>1</integer>
</dict>
</array>
[/tt]
En plus, je dois donc rajouter ma clé image, qui correspondra à l'image déposée. Comment on enregistre les images ds ce cas ?
merci !
En utilisant quelle méthode ?
[tt]
- (BOOL)save
{
NSMutableArray *tmpArray;
NSEnumerator *enumerator;
id tmpVin;
tmpArray=[NSMutableArray arrayWithCapacity:[_vins count]];
enumerator=[_vins objectEnumerator];
while (tmpVin=[enumerator nextObject]) [tmpArray addObject:[tmpVin dictionaryOfProperties]];
return [tmpArray writeToFile:[@~/Library/Application Support/Vinitheca/Vins.plist stringByExpandingTildeInPath] atomically:YES];
}
[/tt]
Le dicoOfProperties contient toutes les clés...
D'aaaaaccord.
Bon, à ma connaissance, il va effectivement y avoir un problème ici pour sauvegarder les NSImage, car une property list ne peut contenir, comme on l'a vu plus haut, que NSArray, NSDictionary, NSString, NSData ou une combinaison de ces classes.
Donc :
1ère solution)
Avant de sauvegarder, tu remplaces chaque image par un NSData qui la représente (par exemple avec -(NSData*) TIFFRepresentation). De ce fait, la sauvegarde marche car tu as vraiment une propertylist. Et au chargement, tu recrées des NSImage avec initWithData.
2ème solution)
Au lieu d'utiliser directement le writeToFile de NSArray, tu utilises un bon vieil NSArchiver. Le NSArchiver "sérialize" des objets répondant au protocole NSCoding. En pratique, on utilise souvent la sous-classe NSKeyedArchiver.
Ou même encore plus court:
Par la magie du NSCoding, (implémenté par la plupart des classes Cocoa) le encodeWithCoder de chaque objet sera bien appelé.
Dans l'autre sens, pour recharger ces données,
il faudra faire:
Ou encore plus court:
Inconvénient de cette solution, c'est que ton fichier n'est alors plus un fichier texte property list "humainement lisible". Mais pour sauvegarder une property list, il faut avoir une property list.
3ème solution) Je n'ai pas vérifié si c'était possible, mais peut-être que du fait que NSImage réponde à NSCoding, il y a une conversion automatique quand on essaye de la sauvegarder comme une propertyList. ça m'étonnerait, sinon je pense que ce serait écrit dans la doc.
Voilà , j'espère t'avoir dépanné correctement.
+
Chacha
Pour l'instant, j'ai implémenté le coding, donc la solution 2, et ça marche nikel en remplcament du plist !
Maintenant je m'attaque à l'image.
L'image récupérée ds le fichier codé doit aller là :
[(NSImageView *)controlView setImage: value];
Mais pour obtenir "value", je sèche...
value = [NSImage... quelle fonction pour récupérer l'image à partir du code et de sa clé ? ]
Et pareil dans l'autre sens pour enregistrer la NSImage pour sa clé...
Merci
Ben, j'ai cru comprendre que tu avais un dico dans chaque case. Donc dans une case d'indice " i " contenant déjà un NSMutableDictionary, tu peux utiliser les méthodes setObject:ForKey: et objectForKey:
Mais bon, je sens que ce n'est pas ça que tu voulais savoir. Je reste à l'écoute.
+
Chacha
La clé :
NSImage *_etiquette; // 1006
Ensuite 2 fonctions :
Une qui enregistre la propriété :
- (void)setProperty:(NSString *)property withValue:(id)value
{
if ([property intValue]==1006) [_etiquette setImage:value];
}
L'autre qui la lit :
- (id)valueForProperty:(NSString *)property
{
id retval;
if ([property intValue]==1006) retval=[NSImage fonction:_etiquette];
}
=> là je sais pas quoi mettre pour reconstruire l'image !
Et enfin, l'affichage et l'enregistrement dans 2 autres fct:
Affichage :
NSImage* monImage = [vin valueForProperty:[NSString stringWithFormat:@%i, 1006]];
[(NSImageView *)controlView setImage: value];
Enregsitrement :
[vin setProperty:[NSImage ... :@%d,ix] withValue: blabla];
Voilà ... avec des int et des string, ça passait comme une lettre à la poste... mais je sèche...
Oooh, mais je n'en doutais pas !
Déjà , là c'est bizarre, tu dis que _etiquette est une NSImage et tu lui envoies le message "setImage" ?!
Une clé NSData :
Pour écrire les données de la clé :
Pour lire les données de la clé :
Ensuite, pour afficher l'image :
Et pour l'enregistrer depuis l'imageView :
Voilà à quoi j'ai droit quand je lis ou que j'enregistre :
[tt]2005-06-28 22:30:45.377 MySoft[3654] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is empty; did you forget to send -finishEncoding to the NSKeyedArchiver?[/tt]
>:D :why?: :-\\
Attention, tu archives avec un NSArchiver et tu désarchives avec un NSKeyedUnarchiver. Tu aurais du archiver avec un NSKeyedArchiver.
De plus, gères-tu bien le retain nécessaire pour conserver les données récupérées par le unarchiveObjectWithData ?
Sinon, il y a quelque chose que je ne m'explique pas. Je ne connais pas ton code, mais est-ce que par hasard tu ne serais pas en train de réinventer le dictionnaire ? Cette histoire de clef, de setProperty.... ça ressemble quand même furieusement à du setObject:forKey...
+
Chacha
J'ai ajouté le Keyed... tjs le bug.
Il vient de là :
[tt]2005-06-28 22:30:45.377 MySoft[3654] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is empty; did you forget to send -finishEncoding to the NSKeyedArchiver?[/tt]
[tt]End of archive encountered prematurely at 0[/tt]
Et si je le laisse :
[tt][NSKeyedUnarchiver initForReadingWithData:]: data is empty; did you forget to send -finishEncoding to the NSKeyedArchiver?[/tt]
:why?:
Que s'affiche-t-il si tu fais :
[tt]2005-06-29 10:06:41.064 Vinitheca2[4534] retval = (null)
2005-06-29 10:06:43.182 Vinitheca2[4534] _etiquette = <62706c69 73743030 d4010203 04050607 0a592461 72636869 76657258 24766572 73696f6e 5424746f 7058246f 626a6563 74735f10 0f4e534b 65796564 41726368 69766572 12000186 a0d10809 54726f6f 748000a1 0b55246e 756c6c08 111b2429 3244494c 51535500 00000000 00010100 00000000 00000c00 00000000 00000000 00000000 00005b>[/tt]
Donc un null pour l'affichage, et de l'hexa pour l'enregsitrement. (je précise qu'à ce stade, il n'y a pas d'image)
Et si je mets une image, ça me donne, un kilo d'hexadécimal ds le run log au moment de l'enregsitrement !
2005-06-29 10:11:04.681 Vinitheca2[4559] retval = NSImage 0x3d7de0 Size={400, 341} Reps=(
  NSBitmapImageRep 0x3d8670 Size={400, 341} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=400x341 Alpha=YES Planar=NO Format=2
)
Mais toujours pas la lecture (même message de data empty).
ça ne peut pas te donner ça ! Dans le code que je t'ai donné, l'affichage de "retval" devrait se faire après celui de "_etiquette", et où est l'affichage de "value" ?
2005-06-29 10:33:55.615 Vinitheca2[4881] value = NSImage 0x3143a0 Size={400, 341} Reps=(
  NSBitmapImageRep 0x3d6d00 Size={400, 341} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=400x341 Alpha=YES Planar=NO Format=3
)
2005-06-29 10:33:55.662 Vinitheca2[4881] retval = NSImage 0x3d2c30 Size={400, 341} Reps=(
  NSBitmapImageRep 0x3d17d0 Size={400, 341} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=400x341 Alpha=YES Planar=NO Format=2
)
Je pense que l'enregsitrement a l'air de marcher. Le fichier donné est passé de 8 à 540 ko avec une image.
Mais la lecture ne marche pas du tout.
Oké.
Bon, il faut donc voir quel est ton code de sauvegarde/chargement dans un fichier. Si ça se trouve, tu as fait une faute dans le chargement, donc ça ne lit rien du tout, donc il n'y a rien à décoder et c'est normal que tu obtiennes nil.
qui donne toujours ça :
2005-06-29 10:45:14.551 Vinitheca2[4910] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is empty; did you forget to send -finishEncoding to the NSKeyedArchiver?
2005-06-29 10:45:14.551 Vinitheca2[4910] retval = (null)
Mon code pour enregistrer :
Et celui pour lire le fichier :
2005-06-29 11:10:50.355 Vinitheca2[5039] ok = 1
Et data me renvoie un paquet d'hexa...
2005-06-29 11:12:02.945 Vinitheca2[5061] data = <62706c69 73743030 d4000100 02000300 04000500 ... etc