Core Animation
Philippe49
Membre
Bon, j'essaie de débroussailler Core Animation et les autres.
On peut commencer par faire l'exemple Menu du Core Animation Programming Guide , mais c'est un peu lourd à digérer en cette période de fête.
Voici une mise en bouche plus à ma portée : CALayer (1)
Merci d'avance de vos remarques et suggestions.
On peut commencer par faire l'exemple Menu du Core Animation Programming Guide , mais c'est un peu lourd à digérer en cette période de fête.
Voici une mise en bouche plus à ma portée : CALayer (1)
Merci d'avance de vos remarques et suggestions.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Sinon, comment ta méthode -setAngle: est-elle appelée ?
voilà c'est fait.
CALayer (2)
Un Hello World avec un CATextLayer.
Il faut encore que je complète cette page en montrant que l'utilisation des contraintes graphiques CAConstraint ne sont pas faciles à adapter à la rotation du layer (ou pas au point?)Â >:D
[EDIT] Les CAConstraint seront dans la page suivante
Ben quand on est lancé ... et qu'on attend le réveillon  <br />
J'ai fait une petite modif depuis : le binding comme dans CALAyer01 n'était pas logiqueÂ
Avec un problème ( == bug ? ) restant à régler.
Au menu : disposition dans une matrice de
Mettre une image comme contenu d'un CALayer.
À la fin de la deuxième ligne, avant le slash, tu as oublié la virgule.
J'ai simplifié un peu ton code et j'obtiens des résultats très probant. J'avais d'abord essayer ton code mais si par malheur je cliquais deux fois sur "image in" ça plantais l'application...
Je pense aussi que ton -dealloc est faux, tu envoies le message -release a un objet auquel tu n'as même pas envoyé de -retain ce qui veut dire que tu n'en portes pas la responsabilité.
Voilà ce que ça peut donner comme code :
oui c'est le sujet de mon post d'aujourd'hui,
Ce phénomène disparait avec l'option du garbage collecteur. Je ne sais toujours pas pourquoi. La gestion mémoire était clairement sous-jacente, mais le lien n'est pas clair.
Tu as raison, j'ai oublié de le retirer (j'avais créé auparavant rootLayer dans le programme)
Bon j'essaie ton code. J'avais fait un essai semblable avec une NSBitmapImageRep pour la NSImage, mais cela échouait.
sans doute parce que je ne mettais pas la transformation CGImage.
Dans la doc, CGImage est une méthode de NSBitmapImageRep.
bestRepresentationForDevice renvoie non pas une NSImageRep mais une instance de la sous-classe NSBitmapRep lorsque le fichier est de l'un de ces types TIFF, BMP, JPEG, GIF, PNG, DIB, ICO, (among others).
(Cocoa Drawing Guide / image basics)
Je pense pas que ça soit un hasard, puisque je demande en fait à la méthode -bestRepresentationForDevice: en passant comme paramètre "nil", que la méthode me retourne la meilleure représentation possible pour l'afficher à l'écran, ça ne peut donc pas être l'un des autre type possible (par exemple NSEPSImageRep, NSPDFImageRep, etc.)
Donc c'est pour ça qu'ici la méthode fonctionne.
- (IBAction)orderImageIn:(id)sender
{
NSImage *image = [NSImage imageNamed:@aquadavinci_ii.jpg];
NSBitmapImageRep * bitmapImageRep=(id)[image bestRepresentationForDevice:nil] ;
CGImageRef imageRef=[bitmapImageRep CGImage] ;
rootLayer.contents =(id)imageRef;
}
Mais cela n'explique pas pourquoi le code précédent ne marchait pas sans garbage collector.
si on ne mets pas l'image en ressource ça rebug
NSString * imagePath=[NSHomeDirectory() stringByAppendingString:@/Pictures/aquadavinci_ii.jpg];
NSImage *image = [[[NSImage alloc] initWithContentsOfFile:imagePath] autorelease];
et si on retire l'autorelease ça ne bug plus.
D'autre part, la doc Cocoa Drawing Guide indique la mise en cache de la représentation.
Cela signifierait peut-être qu'il ne faut pas faire de release sur l'image (ou le data dans ma version précédente) , et le garbage collector lui gérerais tout cela ?
Bon, toujours est-il que lorsqu'on utilise le GC normalement les messages -release, -retain et -autorelease ne font strictement rien, ils sont court-circuité, donc peut-être que tu t'es trompé dans ta gestion de mémoire...
[EDIT] A ce stade, je pense qu'une CGImage est un "contrôleur" pour l'image, la CGImageSource étant le modèle.
Mise à jour de cette page.
Tu envoies sur la page Contents.
Merci, rectification faite.
Pour la suite, j'aimerais que le NSViewController prenne en charge les évènements.
Etre le delegate de l'application ou de la mainWindow n'est pas suffisant .
Bon y a la solution de renvoyer un à un les messages dans une sous-classe de NSView , mais :-\\
Deux pistes :
1. Changer de classe pour ViewController : En faire un NSResponder : pour l'instant ça n'a pas l'air de marcher
2. Créer une sous-classe ViewWithDelegate , avec un IBOutlet delegate, et la redéfinition des méthodes forwardInvocation: et methodSignatureForSelector: humm j'ai jamais fait ça
Qu'en penses-tu ?
Sinon, juste pour te rassurer, -methodSignatureForSelector: retourne bien nil si elle ne trouve pas la méthode.
À part ça, la classe NSViewController dont hérite ViewController est déjà une sous-classe de NSResponder, donc pas besoin d'en changer. ;D (il manque vraiment de smileys ce forum ).
Pour l'instant, la seule solution valable que je trouve c'est de faire une sous-classe de NSView pour gérer les événements, c'est d'ailleurs la méthode la plus logique...
Mais je vais m'y pencher un peu plus...
Comme je l'ai dit, NSViewController est déjà un NSResponder, donc ta classe l'est aussi... Donc pour que ton objet accepte les événements il faut réunir quelques conditions.
Pour commencer, en lisant la doc de NSResponder on voit que tous les événements ont pour implémentation par défaut de passer l'événement au "next responder".
Il faut aussi savoir que NSView ne surcharge aucune méthode d'événement de NSResponder, donc par conséquent il suffit de se mettre dans la chaà®ne des responders pour récupérer les événements de la vue, donc il suffit de faire, dans -awakeFromNib, un simple :
Comme ça tu récupère tous les événements que ne gère pas ta vue, c'est-à -dire tous les événement.
Avec ça il te suffit de surcharger les méthodes que tu veux... Par contre, ce n'est valable que pour les événements de souris (mouseDown:, mouseUp:, scrollWheel:, etc.) car là on sait où ça se trouve...
Mais pour les événements clavier c'est une autre affaire.
Pour répondre aux événement clavier, il faut connaà®tre l'objet qui les reçoit en premier... Il en faut bien un puisqu'à la fin ça émet un bip, alors on a le choix... Soit on sous-classe NSView et on lui dit de répondre aux événements clavier en surchargeant la méthode "-acceptsFirstResponder" soit bah on cherche un objet qui y répond...
Alors j'ai commencé par tester en utilisant le next responder de NSApp, mais il se trouve que NSApplication surcharge toutes les méthodes de NSResponder pour les mettre à sa sauce et terminer la chaà®ne, donc ça sert à rien.
En revanche, j'ai testé sur la fenêtre de notre vue, et il se trouve que ça marche...
Donc, il faut se mettre en next responder de la fenêtre pour récupérer tous ses événements...
Par contre on récupérera aussi les événements de souris qui sont hors de notre vue... Si celle-ci ne prend pas toute la fenêtre ça peut être chiant... Le seul moyen que je vois pour parer à ce problème serait de vérifier que l'événement se trouve ou non dans la frame de la vue.
D'ailleurs à ce propos, tu ajoutes toujours une nouvelle vue dans ta fenêtre, mais si tu ne mets jamais plus d'un objet dans ta fenêtre tu peux toujours utiliser la content view.
Dans la documentation d'Apple sur les événements, il est dit qu'il ne faut pas envoyer -setNextResponder: sur une NSView parce que lors de l'ajoute d'une sous-vue son next responder est directement relié à sa super-vue, et la méthode setNextResponder: de NSView ne modifie pas le next responder de son nouveau next responder, ce qui fait que si on utilise cette méthode, la chaà®ne sera coupée. Alors qu'avec NSWindow ça marche directement.
Donc, il faut faire un choix, soit on se fait chier et on se met à deux endroits de la chaà®ne en faisant attention de ne pas la couper en plein milieu (c'est-à -dire qu'il faut récupérer le next responder de la vue et se le mettre à soi avant de se mettre soi-même en next responder de la vue).
Soit, on gère uniquement les événements à partir de la NSWindow...
La deuxième solution est plus simple, est pour être sûr d'être sur la vue pour les événements de souris il suffit de tester la position de la souris...
Je ne l'avais pas vu cela. Cela simplifie tout.
NSResponder * viewNextResponder=[[self view] nextResponder];
[[self view] setNextResponder:self]
[self setNextResponder: viewNextResponder];
Ne marche pas pour les événements clavier.
On peut couper la chaà®ne au niveau de la fenêtre de l'appli ?
Au-dessus ce doit être NSApp ?Â
NSResponder * windowNextResponder=[[[self view] window] nextResponder];
[[self view] setNextResponder:self]
[self setNextResponder: windowNextResponder];Â ou [self setNextResponder: nil];Â ou rien ?