NSRect et CGRect

beltbelt Membre
02:09 modifié dans API AppKit #1
Apparemment, NSRect et CGRect sont des structures absolument identiques. Mais le compilateur rejette un paramètre CGrect lorsqu'il attend un NSRect. Evidemment, on peut toujours faire un casting, du genre : maFonction( *(NSRect*)&rect ) si rect est de type CGRect, et le compilateur ne dit plus rien. Mais avouez que ce n'est pas très élégant !
Si quequ'un a une autre idée.....

Réponses

  • ChachaChacha Membre
    02:09 modifié #2
    C'est pourtant ce que fait Apple :
    http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaDrawingGuide/QuartzOpenGL/chapter_10_section_2.html
    section Graphics Type Conversions

    +
    Chacha
  • AliGatorAliGator Membre, Modérateur
    02:09 modifié #3
    Je n'ai pas testé personnellement mais je me souviens que Renaud m'avait demandé et que je lui avait conseillé de passer par les pointeurs : on convertit le CGRect* en NSRect* et non le CGRect en NSRect (les zones mémoires en fait), et on déréférence.

    [tt]NSRect tonNSRect = *((NSRect*)(&tonCGRect));[/tt]
  • ChachaChacha Membre
    02:09 modifié #4
    dans 1154439171:

    [tt]NSRect tonNSRect = *((NSRect*)(&tonCGRect));[/tt]

    ça ressemble vachement à  ce que disait belt !
  • AliGatorAliGator Membre, Modérateur
    02:09 modifié #5
    Oups, oui j'avais pas fait gaffe, j'avais lu un peu vite (hé ho je reviens de vacances faut que j'émerge :))
  • beltbelt Membre
    août 2006 modifié #6
    N'empêche que je trouve que ce casting fait un peu tâche !
    Une suggestion : modifier un fichier .h (si si !!) et remplacer la definition de NSRect par :
    typedef NSRect CGRect
    et le tour est joué !
    Evidemment ça devient un peu moins portable !
  • AliGatorAliGator Membre, Modérateur
    02:09 modifié #7
    Ah ben non, si tu trouves que ça fait tâche, plutôt que de modifier le .h, rajoute dans tes fonctions utilitaires des macros :
    #define CG2NSRect(x) *((NSRect*)&amp;(x))<br />#define NS2CGRect(x) *((CGRect*)&amp;(x))
    
    Je trouve ça plus propre à  utiliser ensuite !

    J'avais pensé aussi à  créer un constructeur de NSRect à  partir d'un CGRect (qui serait appellé par appel implicite lors d'un cast comme tout autre constructeur de ce type), mais il me semble que les constructeurs de structure n'existent que dans la définition C++ des [tt]stuct[/tt], et pas C (donc par extension, pas Cocoa non plus)
    Et puis on ne peux pas faire de catégorie sur les struct non plus donc de toute façon...
  • AliGatorAliGator Membre, Modérateur
    02:09 modifié #8
    En lisant le blog de ridiculous_fish que nous fait découvrir Chacha, j'ai trouvé un commentaire qui m'a fait tilter...

    Et les unions alors ?
    Je le savais bien sûr vu comme ça si on me demande ce que ça fait... mais je n'y avais plus pensé.

    Ce n'est pas forcément la solution idéale, mais c'est une solution alternative à  ce que j'ai proposé dans le post précédent.
    typedef union {<br />	NSRect ns;<br />	CGRect cg;<br />} NSCGRect;<br /><br />[...]<br /><br />NSCGRect r1;<br />r1.ns = NSMakeRect(10.f, 10.f, 30.f, 50.f); // une solution pour l&#39;initialiser, après déclaration<br />NSCGRect r2 = {.cg = CGMakeRect(0.f, 0.f, 20.f, 30.f)};  // autre solution, déclaration+initialisation en même temps<br /><br />CGRect cgr = r1.cg; // hop on choisit si on veut le cgrect ou le nsrect à  la volée<br />NSRect nsr = r2.ns; // ça marche dans les 2 sens bien sûr
    
    Bon je sais pas quelle est la meilleur méthode, je pense pas qu'il y en ait une plus qu'une autre chacune a ses avantages, à  vous de choisir, c'est selon les goûts.

    Bien sûr on peut créer ce genre d'unions autant pour les NS/CGRect que pour les NS/CGSize et tout ce qui s'y colle.
Connectez-vous ou Inscrivez-vous pour répondre.