Quelques petites questions sur les vues.

CrazyJoCrazyJo Membre
18:37 modifié dans API AppKit #1
Bonjour,

Dans ce code:
- (NSPoint)randomPoint{<br />	NSPoint result;<br />	NSRect r;<br />	int width,height;<br />	r = [self bounds];<br />	width = round(r.size.width);<br />	height = round(r.size.height);<br />	result.x = (random() % width) + r.origin.x;<br />	result.y = (random() % height) + r.origin.y;<br />	return result;<br />}<br />

Que font ces lignes de codes :
r = [self bounds];

le self bound -> qu'est-ce que c'est ?
width = round(r.size.width);

le round et le r.size.width ?
result.x = (random() % width) + r.origin.x;

qu'est ce que + r.origin.x

et ici :
&nbsp; // Dessiner le chemin en blanc<br />&nbsp;  [[NSColor whiteColor]set];<br />&nbsp;  [path stroke];

Si j'avais voulu rajouter un deuxième chemin en rouge comment je peux faire ?

merci  :D
«1

Réponses

  • schlumschlum Membre
    mars 2008 modifié #2
    Les "bounds" c'est le système de coordonnées interne à  la vue... C'est pas un concept super facile à  comprendre...
    Enfin en général la bounds.size est égal à  la frame.size, et le bounds.origin est égal à  NSZeroPoint ; mais quand ce n'est pas le cas, ça veut dire qu'on a changé de système de coordonnées par rapport à  la vue mère.

    "round" c'est la valeur arrondie
    r.size.width et r.size.width c'est la taille interne de la vue (correspondant souvent à  la taille externe)
    r.origin.x et r.origin.y c'est l'origine interne de la vue (souvent 0,0)

    Pour le chemin en rouge, ben... redColor  :fouf):
  • CrazyJoCrazyJo Membre
    18:37 modifié #3
    ok merci pour ces quelques explications schlum
    dans 1205068492:

    Pour le chemin en rouge, ben... redColor  :fouf):

    non je veux dire que si j'ai deux paths :  path et path 2. Je dois mettre ça : ?
    <br />[[NSColor whiteColor]set];<br /> [path stroke];<br />[[NSColor redColor]set];<br /> [path2 stroke];<br />
    


  • Philippe49Philippe49 Membre
    18:37 modifié #4
    dans 1205069376:

    non je veux dire que si j'ai deux paths :  path et path 2. Je dois mettre ça : ?
    <br />[[NSColor whiteColor]set];<br /> [path stroke];<br />[[NSColor redColor]set];<br /> [path2 stroke];<br />
    


    YES
    YES
  • CrazyJoCrazyJo Membre
    18:37 modifié #5
    merci pour ces réponses.
    Autre chose , voilà  l'interface pour mieux comprendre ma question: image1ik5.th.png
    . Je voudrais que lorsqu'on modifie les champs x,y,w,h le rectangle de la nsview se modifie suivant les réglages. Je ne sais pas trop comment procéder niveau organisation du code. Dois je - avoir un ficher Controller de NSObjet et un ficher Draw de NSView ou qu'un ficher NSView suffit ? Pour le moment j'ai codé cela:
    Draw.m :
    //<br />// &nbsp;Draw.m<br />// &nbsp;ViewsEx1<br />//<br />// &nbsp;Created by Jonathan Link on 09.03.08.<br />// &nbsp;Copyright 2008 __MyCompanyName__. All rights reserved.<br />//<br /><br />#import &quot;Draw.h&quot;<br />#import &quot;Controller.h&quot;<br /><br />@implementation Draw<br /><br />- (id)initWithFrame:(NSRect)frame {<br /> &nbsp; &nbsp;self = [super initWithFrame:frame];<br /> &nbsp; &nbsp;if (self) {<br /> &nbsp; &nbsp; &nbsp; &nbsp;// Initialization code here.<br /> &nbsp; &nbsp;}<br /> &nbsp; &nbsp;return self;<br />}<br /><br />- (IBAction)sendActions:(id)sender{<br />	NSBeep();<br />}<br /><br />- (void)drawRect:(NSRect)rect {<br />	float x = [xtf floatValue];<br />	float y = [ytf floatValue];<br />	float w = [wtf floatValue];<br />	float h = [htf floatValue];<br /> &nbsp; &nbsp;NSRect r = NSMakeRect(x, y, w, h);<br />	NSBezierPath *bp = [NSBezierPath bezierPathWithRect:r];<br />	NSColor *color = [NSColor blueColor];<br />	[color set];<br />	[bp fill];<br />}<br /><br />@end<br />
    

    J'ai aussi un fichier Controller mais vide... Sous IB j'ai créé nsobjet de  Draw ... mais peut-être que l'action sendActions: aurait mieux à  faire dans COntroller. ? !  Et je ne sais pas quelle méthode employer pour que drawRect soit appelé à  chaque fois. [self drawRect]; ne fonctionne pas...
  • Philippe49Philippe49 Membre
    18:37 modifié #6
    C'est à  un fichier Controller de recevoir l'action, et de le répercuter sur la vue

    -(IBAction) changeViewFrame:(id) sender

    et de le répercuter sur la vue par un

    [myView setFrame:NSMakeRect(..............)];
    [myView setNeedsDisplay:YES];

    A priori, ton fichier Draw.m ne devrait pas avoir besoin du #import "Controller.h"
  • CrazyJoCrazyJo Membre
    18:37 modifié #7
    Ok donc maitenant j'ai ça dans Controller.m
    @implementation Controller<br />- (id)init{<br />	if (self = [super init]){<br />	}<br />	return self;<br />}<br />-(IBAction) changeViewFrame:(id) sender{<br />	float x = [xtf floatValue];<br />	float y = [ytf floatValue];<br />	float w = [wtf floatValue];<br />	float h = [htf floatValue];<br />	[myView setFrame:NSMakeRect(x, y, w, h)];<br />	[myView setNeedsDisplay:YES];<br />}<br />
    

    mais dans le Draw.m je mets quoi alors ? Avant j'avais mis cela mais x,y,w,h ne sont pas définis.
    - (void)drawRect:(NSRect)rect {<br />&nbsp; &nbsp; NSRect r = NSMakeRect(x, y, w, h);<br />	NSBezierPath *bp = [NSBezierPath bezierPathWithRect:r];<br />	NSColor *color = [NSColor blueColor];<br />	[color set];<br />	[bp fill];<br />}<br />
    
  • Philippe49Philippe49 Membre
    18:37 modifié #8
    dans 1205179529:


    mais dans le Draw.m je mets quoi alors ? Avant j'avais mis cela mais x,y,w,h ne sont pas définis.
    - (void)drawRect:(NSRect)rect {
        NSRect r = NSMakeRect(x, y, w, h);
    NSBezierPath *bp = [NSBezierPath bezierPathWithRect:r];
    NSColor *color = [NSColor blueColor];
    [color set];
    [bp fill];
    }



    Automatiquement l'argument rect correspond à  la partie de la vue qui va être dessinée.
    En standard c'est la totalité de la vue.

    Donc tu supprimes ton NSMakerect dans cette méthode et tu remplaces r par rect si tu veux n'y voir que du bleu dans ta vue (le charme du Canard WC ?)
  • CrazyJoCrazyJo Membre
    18:37 modifié #9
    dans 1205180411:

    dans 1205179529:


    mais dans le Draw.m je mets quoi alors ? Avant j'avais mis cela mais x,y,w,h ne sont pas définis.
    - (void)drawRect:(NSRect)rect {
        NSRect r = NSMakeRect(x, y, w, h);
    NSBezierPath *bp = [NSBezierPath bezierPathWithRect:r];
    NSColor *color = [NSColor blueColor];
    [color set];
    [bp fill];
    }




    Automatiquement l'argument rect correspond à  la partie de la vue qui va être dessinée.
    En standard c'est la totalité de la vue.

    Donc tu supprimes ton NSMakerect dans cette méthode et tu remplaces r par rect si tu veux n'y voir que du bleu dans ta vue (le charme du Canard WC ?)

    D'accord mais je voulais dessiner un rectangle avec les coordonnées et largeur et hauteur qui correspondent au variable des textfields, bref un recangle qui change tout seul de taille et tout suivant les variables des textfields. Parce que pour le moment j'ai bien un grand rectangle bleu (toute la nsview) mais dès que je rentre qqch dans un textfield la vue s'efface et aucun rectangle ne se dessine. Donc il me faudrait pas la vue stantard comme tu l'as dit plus haut ? non?
  • Philippe49Philippe49 Membre
    18:37 modifié #10
    dans 1205180993:

    mais dès que je rentre qqch dans un textfield la vue s'efface et aucun rectangle ne se dessine. Donc il me faudrait pas la vue stantard comme tu l'as dit plus haut ? non?


    Tu as un problème de connexion. Il faut connecter chaque textField dans IB avec l'action changeViewFrame: pour que soit pris en compte le changement dans l'interface.
  • CrazyJoCrazyJo Membre
    18:37 modifié #11
    En mettant cela comme code : Controller.m
    -(IBAction) changeViewFrame:(id) sender{<br />	NSRect zone;<br />	float x = [xtf floatValue];<br />	float y = [ytf floatValue];<br />	float w = [wtf floatValue];<br />	float h = [htf floatValue];<br />	zone = NSMakeRect(x, y, w, h);<br />	[myView setFrame:NSMakeRect(x, y, w, h)];<br />	[myView setNeedsDisplayInRect:zone];<br />}
    
    et Draw
    - (void)drawRect:(NSRect)rect {<br />	NSBezierPath *bp = [NSBezierPath bezierPathWithRect:rect];<br />	NSColor *color = [NSColor redColor];<br />	[color set];<br />	[bp fill];<br />}
    
    Un rectangle se forme correctement suivant les coordonnées x,y et respecte la largeur et la longueur des variables des textsfield mais le rectangle ne se dessine pas dans la nsview que j'ai défini mais dans la fenêtre elle - même ! ???
  • CrazyJoCrazyJo Membre
    mars 2008 modifié #12
    dans 1205182045:

    dans 1205180993:

    mais dès que je rentre qqch dans un textfield la vue s'efface et aucun rectangle ne se dessine. Donc il me faudrait pas la vue stantard comme tu l'as dit plus haut ? non?


    Tu as un problème de connexion. Il faut connecter chaque textField dans IB avec l'action changeViewFrame: pour que soit pris en compte le changement dans l'interface.


    Je l'avais fait pourtant. J'avais même mis un nslog pour en être sur. edit voir post plus bas. Avec le code du bas ça marche à  moitié maintenant. Voir en bas :
  • CrazyJoCrazyJo Membre
    18:37 modifié #13
    et avec ce code:
    -(IBAction) changeViewFrame:(id) sender{<br />	//NSRect zone;<br />	float x = [xtf floatValue];<br />	float y = [ytf floatValue];<br />	float w = [wtf floatValue];<br />	float h = [htf floatValue];<br />	//zone = NSMakeRect(x, y, w, h);<br />	[myView setFrame:NSMakeRect(x, y, w, h)];<br />	//[myView setNeedsDisplayInRect:zone];<br />	[myView setNeedsDisplay:YES];<br />}<br />
    
    et
    - (void)drawRect:(NSRect)rect {<br />	NSBezierPath *bp = [NSBezierPath bezierPathWithRect:rect];<br />	NSColor *color = [NSColor redColor];<br />	[color set];<br />	[bp fill];<br />}
    
    . Voici ce qui se passe.
    1. L'app se lance et le nsview définit se colorie en rouge.
    2. Je régle x,y,w,h et le carré rouge s'affiche mais en dehors de la nsview. Qui est pourtant bien connectée puisqu'au démarrage de l'app elle s'affiche en rouge.
  • Philippe49Philippe49 Membre
    18:37 modifié #14
    dans 1205182097:

    Un rectangle se forme correctement suivant les coordonnées x,y et respecte la largeur et la longueur des variables des textsfield mais le rectangle ne se dessine pas dans la nsview que j'ai défini mais dans la fenêtre elle - même ! ???


    Logique il n'y a qu'une seule NSView.

    Deux possibilités :
    soit tu connectes des IBOutlet vers les TextField dans drawView, et tu lis dans ta méthode drawRect la valeur de ces outlets
              NSRect r=NSMakeRect([xtf floatValue], etc..)
              .....bezierPathWithRect:r]

    soit tu crées une nouvelle custom view de frame fixe contenant ta drawView.
      
  • CrazyJoCrazyJo Membre
    18:37 modifié #15
    soit tu mets des IBOutlet vers les TextField, et tu lis dans ta méthode drawRect la valeur de ces outlets
              NSRect r=NSMakeRect([xtf floatValue], etc..)
              .....bezierPathWithRect:r]
    Et comment je la lis la méthode drawRect ?  dans IB je relie quoi à  quoi comme action ? l'action drawRect n'apparaà®t pas.
  • Philippe49Philippe49 Membre
    18:37 modifié #16
    tu connectes tes textField avec une action changeDrawing qui remplace changeViewFrame de ton Controller qui va simplement impulser un [myView setNeedsDisplay:YES]


  • fouffouf Membre
    18:37 modifié #17
    Ne jamais appeler drawRect: directement sauf dans des cas très très spéciaux.

    Pour afficher les changements, il faut utiliser display ou setNeedsDisplay: (et leurs variantes "optimisées" displayInRect: et setNeedsDisplayInRect:). Il est par ailleur conseillé d'utiliser setNeedsDisplay: plutot que display car comme ca, si au cours d'un seul "tour" de la RunLoop, drawRect: ne sera appelé qu'une fois. Si par contre, tu veux rafraichir le contenu de la vue tout de suite (au moment ou tu fais l'appel) tu dois utiliser display.
  • CrazyJoCrazyJo Membre
    18:37 modifié #18
    Oui je souhaite que la vue se rafraichise tout de suite . Bon voici le code. (ca ne marche tjrs pas.. je rage... :-\\ B) )
    Controller.h
    @interface Controller : NSObject {<br />	IBOutlet NSView *myView;<br />}<br />-(IBAction) changeDrawing:(id) sender;<br />@end<br />
    

    Controller.m
    - (id)init{<br />	if (self = [super init]){<br />	}<br />	return self;<br />}<br />-(IBAction) changeDrawing:(id) sender{<br />	[myView display:YES]; // Avec ici un WARNING -&gt; nsview ne répond pas à  display <br />}<br />
    


    Draw.h
    <br />@interface Draw : NSView {<br />	IBOutlet NSTextField&nbsp; *xtf;<br />	IBOutlet NSTextField&nbsp; *ytf;<br />	IBOutlet NSTextField&nbsp; *wtf;<br />	IBOutlet NSTextField&nbsp; *htf;<br />}<br />@end
    

    Draw.m
    - (id)initWithFrame:(NSRect)frame {<br />&nbsp; &nbsp; self = [super initWithFrame:frame];<br />&nbsp; &nbsp; if (self) {<br />&nbsp; &nbsp; &nbsp; &nbsp; // Initialization code here.<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}<br /><br /><br />- (void)drawRect:(NSRect)rect {<br />&nbsp; &nbsp; NSRect r = NSMakeRect([xtf floatValue], [ytf floatValue], [wtf floatValue], [htf floatValue]);<br />	NSBezierPath *bp = [NSBezierPath bezierPathWithRect:r];<br />	NSColor *color = [NSColor blueColor];<br />	[color set];<br />	[bp fill];<br />}<br />
    


    Dans IB, j'ai créé un nsobjet Controller, tout les textfiels sont connecté à  l'action : changeDrawing et tout les textfiels sont connecté avec leurs outlets. La NSView est relié par un outlet Myview.
  • schlumschlum Membre
    18:37 modifié #19
    C'est pas "display" qu'il faut utiliser mais "setNeedsDisplay".
  • fouffouf Membre
    18:37 modifié #20
    dans 1205184516:

    C'est pas "display" qu'il faut utiliser mais "setNeedsDisplay".


    Oui, display est de la forme
    <br />- (void)display<br />
    

    et setNeedsDisplay:
    <br />- (void)setNeedsDisplay:(BOOL)flag<br />
    
  • AntilogAntilog Membre
    18:37 modifié #21
    C'est soit
    [myView display];
    soit
    [myView setNeedsDisplay:Yes];

    Mais le mieux, c'est setNeedsDisplay, ce sera de toutes façons affiché tout de suite (pour un humain).
    Le display est pour des besoins très spécifiques (peut-être du genre animation, ...)

    Edit:
    Bon, Fouf, tu as gagné
  • Philippe49Philippe49 Membre
    18:37 modifié #22
    je dirais même plus  !! setNeedsDisplay !!  ;D ;D :brule: :brule:
  • AntilogAntilog Membre
    18:37 modifié #23
    C'est décidé, on organise un vote:

    Cochez la case la plus adaptée :

    [_] display

    [_] setNeedsDisplay:

    [_] setShadow:

    [_] Ne sait pas

    [_] De toutes façons, je n'aime pas les NSViews.

  • Philippe49Philippe49 Membre
    18:37 modifié #24
    Moi c'est la dernière case, avec la mention "je préfère le saucisson-vin rouge"
    :kicking: :kicking: :kicking:

    euh, on dévie peut-être .. ??
    
  • CrazyJoCrazyJo Membre
    18:37 modifié #25
    Bin avec display ou setNeedsDisplay ça ne marche pas :crackboom:- . Le code est toujours le même qu'au post 17 -> http://www.objective-cocoa.org/forum/index.php/topic,2605.msg25927.html#msg25927 . Je commence à  désespérer , moi qui pensez que dont je voulais faire été "simple". ???  B)
  • Philippe49Philippe49 Membre
    18:37 modifié #26
    Poste ton code qu'un regarde (sans le build)
  • AntilogAntilog Membre
    18:37 modifié #27
    Juste une petite question:

    comment as-tu relié les outlets de tes textes à  ta classe Draw?
  • Philippe49Philippe49 Membre
    mars 2008 modifié #28
    Est-ce que tu as défini dans IB la classe de la custom view en Draw ?
  • CrazyJoCrazyJo Membre
    18:37 modifié #29
    dans 1205224452:

    Est-ce que tu as défini dans IB la classe de la custom view en Draw ?

    oui c'était fait. En tout cas voilà  le projet : http://soft4mac.mac-gratuit.fr/OC/ViewEx1.zip
  • Philippe49Philippe49 Membre
    18:37 modifié #30
    Y a un problème dans le lien.
    Vérifie les connections dans ton interface !!
  • CrazyJoCrazyJo Membre
    18:37 modifié #31
    dans 1205444460:

    Y a un problème dans le lien.
    Vérifie les connections dans ton interface !!

    bin ça à  l'air de jouer , je viens de tout relier : Image%201.png
Connectez-vous ou Inscrivez-vous pour répondre.