dessin d'ellipses
tethys
Membre
Bonjour,
Je tente actuellement de faire l'exercice du Chap. 18 du livre d'Hillegass,
je ne comprends pas trop l'interet d'utiliser des documents (qu'est-ce que NSDocument a de spécifique d'ailleurs ?)
alors voilà , j'ai implémenté les fonctions d'evts souris comme suit :
#pragma mark Events
-(void)mouseDown:(NSEvent*)event
{
NSLog(@mouseDown: %d, [event clickCount]);
// Chap.18
NSPoint p = [event locationInWindow];
downPoint = [self convertPoint:p fromView:nil];
currentPoint = downPoint;
path = [[NSBezierPath alloc]init];
[path moveToPoint:downPoint];
[self setNeedsDisplay:YES];
}
-(void)mouseDragged:(NSEvent*)event
{
NSPoint p = [event locationInWindow];
NSLog(@mouseDragged:%@", NSStringFromPoint(p));
// Chap. 18
currentPoint = [self convertPoint:p fromView:nil];
path = [NSBezierPath bezierPathWithOvalInRect:[self currentRect]];
[self autoscroll:event];
[self setNeedsDisplay:YES];
}
-(void)mouseUp:(NSEvent*)event
{
NSLog(@mouseUp:);
// Chap. 18
NSPoint p = [event locationInWindow];
currentPoint = [self convertPoint:p fromView:nil];
[path release];
[self setNeedsDisplay:YES];
}
et la fonction drawInRect comme ceci:
- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.
NSRect bounds = [self bounds];
[[NSColor whiteColor] set];
[NSBezierPath fillRect:bounds];
NSRect rect = [self currentRect];
if(!NSEqualRects(rect, NSZeroRect))
{
// Tracer le chemin en noir
[[NSColor blackColor] set];
path = [NSBezierPath bezierPathWithOvalInRect:rect];
[path stroke];
}
//NSLog(@currentRect : %d,%d,%d,%d, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
//[path stroke];
}
et pour le header:
@interface OvalView : NSView {
NSBezierPath *path;
NSPoint currentPoint;
NSPoint downPoint;
}
-(NSRect)currentRect;
j'arrive à dessiner ma première ellipse, et ensuite l'application freeze : SIGABRT
j'ai essayé en allouant la mémoire pour le path dans l'init mais c'est pareil.
Vincent
Je tente actuellement de faire l'exercice du Chap. 18 du livre d'Hillegass,
je ne comprends pas trop l'interet d'utiliser des documents (qu'est-ce que NSDocument a de spécifique d'ailleurs ?)
alors voilà , j'ai implémenté les fonctions d'evts souris comme suit :
#pragma mark Events
-(void)mouseDown:(NSEvent*)event
{
NSLog(@mouseDown: %d, [event clickCount]);
// Chap.18
NSPoint p = [event locationInWindow];
downPoint = [self convertPoint:p fromView:nil];
currentPoint = downPoint;
path = [[NSBezierPath alloc]init];
[path moveToPoint:downPoint];
[self setNeedsDisplay:YES];
}
-(void)mouseDragged:(NSEvent*)event
{
NSPoint p = [event locationInWindow];
NSLog(@mouseDragged:%@", NSStringFromPoint(p));
// Chap. 18
currentPoint = [self convertPoint:p fromView:nil];
path = [NSBezierPath bezierPathWithOvalInRect:[self currentRect]];
[self autoscroll:event];
[self setNeedsDisplay:YES];
}
-(void)mouseUp:(NSEvent*)event
{
NSLog(@mouseUp:);
// Chap. 18
NSPoint p = [event locationInWindow];
currentPoint = [self convertPoint:p fromView:nil];
[path release];
[self setNeedsDisplay:YES];
}
et la fonction drawInRect comme ceci:
- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.
NSRect bounds = [self bounds];
[[NSColor whiteColor] set];
[NSBezierPath fillRect:bounds];
NSRect rect = [self currentRect];
if(!NSEqualRects(rect, NSZeroRect))
{
// Tracer le chemin en noir
[[NSColor blackColor] set];
path = [NSBezierPath bezierPathWithOvalInRect:rect];
[path stroke];
}
//NSLog(@currentRect : %d,%d,%d,%d, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
//[path stroke];
}
et pour le header:
@interface OvalView : NSView {
NSBezierPath *path;
NSPoint currentPoint;
NSPoint downPoint;
}
-(NSRect)currentRect;
j'arrive à dessiner ma première ellipse, et ensuite l'application freeze : SIGABRT
j'ai essayé en allouant la mémoire pour le path dans l'init mais c'est pareil.
Vincent
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Un NSDocument est associé à une fenêtre et lit et écrit les fichiers.
C'est ce qui permet d'avoir plusieurs documents à l'écran.
Autrement, tu n'aurais qu'une seule fenêtre dans ton appli, et ce serait le délégué de l'application qui ferait la lecture et l'enregistrement.
En matière de gestion mémoire, essayer des trucs jusqu'à ce que ça marche n'est pas la bonne stratégie. Il faut comprendre exactement comment ça fonctionne.
Dans -[drawRect:], il faut redessiner toute la vue: les ellipses précédentes (qu'il faudra donc conserver) et l'ellipse en cours d'édition. Cette dernière n'a pas besoin de survivre au delà de l'exécution de -[drawRect:], alors tu peux la mettre en autorelease.
Sachant qu'une ellipse est définie par un rectangle, le plus simple est de conserver le rectangle courant, dont tu changeras l'origine dans -[mouseDown:] et la taille dans -[mouseDragged:]. Dans ces deux méthodes, tu appeleras [self setNeedsDisplay:YES], pour provoquer l'appel de -[drawRect:]
Dans -[mouseUp:], le dimensionnement de l'ellipse est terminé, alors tu peux la créer et l'ajouter à la liste des ellipses.
J'avais sauté en première lecture comme proposé la gestion mémoire avec les compteurs de référence, je vais y retourner.
Pour les documents, j'avais mal compris la notion de MVC
un document est donc utilisé dans ce type de modèlisation MVC, c ça ?
Par contre, pour ce qui est de devoir archiver les ellipses, c'est en effet logique, mais ce qui m'étonne c'est que j'ai fait l'appli de dessin avec des droites (ou des courbes en dessinant la ligne à chaque mouseDragged), et là pas besoin de stocker mes lignes dans un tableau, les lignes une fois dessinées le restent, comment expliquer cette différence ?
Simplifie-toi la vie en utilisant ARC pour la gestion mémoire :
http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html
hmm... je découvre ça avec vos posts précédents,
et d'une j'ai finalement compris les bases du mécanisme release/retain,
et puis surtout XCode trop vieux pour ARC, je vais quand même pas changer ma machine tous les 4 matins !
j'ai lu que Lion était plutôt gourmand pour mon vieux mac blanc,
j'ai Xcode 3.2.5 actuellement,
qu'apporte XCode 4.2 ? (à part ARC)
est-ce que les développements codés sous XCode 3.2.5 fonctionneront encore ?
parce que j'ai l'impression que c'est souvent un problème cette rétro-compatibilité chez Apple, non ?
Si tu as un projet développé avec Xcode 3, et que tu l'ouvres avec Xcode 4, il devrait fonctionner correctement (du moins, chez moi çà a bien fonctionné), sauf si tu as utilisé des méthodes devenues obsolètes (deprecated). Les problèmes de compatibilité sont souvent dus aux utilisateurs qui ne tiennent pas compte des avertissement d'Apple, qui préviennent des futures "deprecated method"...
Par contre, tu vas trouver un peu de changement dans la présentation de Xcode 4, par rapport au 3... :P :P
Si tu n'es pas utilisateur de Xcode depuis trop longtemps, je te recommande de faire le saut dès que possible... cela t'éviteras de trop t'habituer!
Concernant ARC, perso je ne me suis pas encore mise... je préfère encore gérer la mémoire moi-même, mais tu te feras ton avis par toi-même.
au cas où,
et est-ce que Xcode 4 consomme beaucoup ? J'ai 2go ça devrait suffire qd même
Perso, je n'ai rien fait et il a détecté tout seul qu'il y avait déjà une version ancienne de Xcode... et il l'a conservée.
Je viens de vérifier, je peux toujours lancer Xcode 3. Il suffit d'aller chercher dans le Finder car le lien du Dock a été automatiquement modifié...
Euh... Je crois que chez moi, çà prend environ 4Go... mais je suis sous Lion, peut-être que c'est différent, mais de toute façon, je pense que 2 Go, c'est un peu juste ! 8--)
Concernant la RAM, je ne sais pas trop ce qu'il faut pour Xcode 4. J'ai 4Go et çà passe sans problème... Mais cela ne t'avance pas trop ! Par contre, Draken t'a dit plus haut qu'il avait 1Go ::)
Bon courage
Faut toujours utiliser les dernières versions Xcode et fermer sa gueule en fait. C'est la politique d'Apple ;D
Oui, ça tourne très bien sur mon Mac Mini avec 1 go de RAM. J'avais peur de ramer à mort, avant de l'installer. Et au final, c'est tout bon. La compilation est parfois un peu lente, mais rien de catastrophique. Je ne regrette pas d'avoir fait le saut. De toute manière, je n'ai pas eu le choix. Sans Xcode 4.2 je ne pouvais pas développer en iOS 5 !
Un document fait partie de la couche Contrôleur. Il fait donc le lien entre des vues (la NSWindow qu'il gère) et des objets de la couche modèle.
Typiquement, la couche Modèle est un arbre d'objets, et le document pointe sur l'objet racine de l'arbre pour permettre que le contenu de l'arbre soit affiché dans la fenêtre. Dans une application basée sur des documents, il y a un arbre par fenêtre.
La vue ne se redessine que lorsqu'on lui demande par un appel à -[setNeedsDisplay:] ou -[setNeedsDisplayInRect:]. Peut-être que tu n'affichais qu'une ligne ?
j'avais dans mouseDragged
[path lineToPoint:currentPoint];
[path moveToPoint:currentPoint];
et dans drawRect:
NSRect bounds = [self bounds];
[[NSColor whiteColor] set];
[NSBezierPath fillRect:bounds];
// Tracer le chemin en noir
[[NSColor blackColor] set];
//pour dessiner une ligne
[path stroke];
ça signifie que je n'utilise qu'un seul path donc une seule ligne ?
elle est quelquefois noire et quelquefois sans teinte, c ça ?
parce que sur le dessin, j'ai plusieurs lignes de dessinées (autant que d'appui/relacher avec la souris)
(et je fais un moveToPoint dans mouseDown)
Dans l'exemple précédent, la vue avait une variable d'instance NSBezierPath *path. Il n'y avait qu'une seule courbe de Bézier à laquelle ou ajoutait des points grâce à -[moveToPoint:] et -[lineToPoint].
Dans ton cas, chaque ellipse est une courbe de Bézier différente.
ma dernière question etait relative à des courbes obtenues avec lineToPoint en fait,
merci de tes réponses en tous cas,
Un NSBezierPath n'a qu'une couleur et qu'une épaisseur de ligne, mais effectivement, les points qui le constituent peuvent être disjoints.