dessin d'ellipses

tethystethys Membre
09:11 modifié dans API AppKit #1
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

Réponses

  • CéroceCéroce Membre, Modérateur
    09:11 modifié #2
    dans 1324588465:

    je ne comprends pas trop l'interet d'utiliser des documents (qu'est-ce que NSDocument a de spécifique d'ailleurs ?)


    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.

    dans 1324588465:

    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.

    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.
  • tethystethys Membre
    09:11 modifié #3
    ok, merci de ta réponse
    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 ?
  • DrakenDraken Membre
    décembre 2011 modifié #4
    dans 1324684672:

    J'avais sauté en première lecture comme proposé la gestion mémoire avec les compteurs de référence, je vais y retourner.

    Simplifie-toi la vie en utilisant ARC pour la gestion mémoire :

    http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html

  • tethystethys Membre
    09:11 modifié #5
    dans 1324686499:


    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,
  • DrakenDraken Membre
    09:11 modifié #6
    Euh, je n'ai pas tout compris, là . Pour ma part j'utilise Xcode 4.2 sur un Mac Mini de 2008 tournant sur Snow Leopard, et doté de seulement 1 Go de RAM. Bien que ce soit une vieille machine, la dernière version de Xcode tourne parfaitement dessus.

  • tethystethys Membre
    09:11 modifié #7
    j'avais du tomber sur XCode 4.2.1 qui necessite Lion,
    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 ?
  • Alf1996Alf1996 Membre
    09:11 modifié #8
    Bonjour,


    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!  B)

    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.
  • tethystethys Membre
    09:11 modifié #9
    Que faut-il copier comme répertoire pour sauvegarder XCode 3 ?
    au cas où,
    et est-ce que Xcode 4 consomme beaucoup ? J'ai 2go ça devrait suffire qd même
  • Alf1996Alf1996 Membre
    09:11 modifié #10

    Que faut-il copier comme répertoire pour sauvegarder XCode 3 ?
    au cas où,

    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é...

    et est-ce que Xcode 4 consomme beaucoup ? J'ai 2go ça devrait suffire qd même

    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--)
  • tethystethys Membre
    09:11 modifié #11
    Je parlais de 2Go de ram ;)
  • Alf1996Alf1996 Membre
    09:11 modifié #12
    Ah OK... Je me disais aussi que c'était pas grand chose comme place dispo !  :P :P

    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

  • 09:11 modifié #13
    dans 1324828735:

    Que faut-il copier comme répertoire pour sauvegarder XCode 3 ?
    au cas où,
    et est-ce que Xcode 4 consomme beaucoup ? J'ai 2go ça devrait suffire qd même

    Faut toujours utiliser les dernières versions Xcode et fermer sa gueule en fait. C'est la politique d'Apple  ;D
  • DrakenDraken Membre
    09:11 modifié #14
    dans 1324843098:

    Ah OK... Je me disais aussi que c'était pas grand chose comme place dispo !  :P :P

    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

    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 !
  • CéroceCéroce Membre, Modérateur
    09:11 modifié #15
    dans 1324684672:

    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 ?


    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.

    dans 1324684672:

    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 ?

    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 ?
  • tethystethys Membre
    09:11 modifié #16
    dans 1324972419:

    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)
  • CéroceCéroce Membre, Modérateur
    09:11 modifié #17
    Je viens de regarder le livre.

    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.
  • tethystethys Membre
    09:11 modifié #18
    ok,
    ma dernière question etait relative à  des courbes obtenues avec lineToPoint en fait,
    merci de tes réponses en tous cas,
  • CéroceCéroce Membre, Modérateur
    09:11 modifié #19
    Oui, j'ai répondu à  moitié.
    Un NSBezierPath n'a qu'une couleur et qu'une épaisseur de ligne, mais effectivement, les points qui le constituent peuvent être disjoints.
Connectez-vous ou Inscrivez-vous pour répondre.