Archives

Archives pour janvier, 2009

Dis Google, qu’est-ce qui t’arrive ?

31 janvier 2009

Google très protecteurEn jouant à Guitar Hero World Tour hier soir, je me suis pris à vraiment apprécier une chanson du groupe Silversun Pickups, intitulée Lazy Eye. Ce matin midi, je me rends sur Google pour obtenir des informations à propos de ce groupe (réflexe normal, me direz-vous). Seulement voilà, pendant la nuit, Google semble être devenu un peu paranoïaque (ou tout simplement trop protecteur ?). Quelle que soit la recherche que j’effectue, il me dit, pour chaque résultat, que le site risque d’endommager mon ordinateur. Et y’a pas moyen d’accéder au site, sauf en copiant/collant l’adresse directement dans le navigateur. Ce qui est amusant, c’est que les résultats qu’il trouve sur YouTube ne semblent pas être dangereux, tandis que le service de traduction de Google semble l’être (si on cherche « translate » par exemple) ! Hum, hum.

Google a l’habitude de mettre des logos bêta pour tous ses services ; là, il en manque un sur son moteur de recherche !

Amusement

Cheetah3D : un modeleur 3D pour Mac OS X

30 janvier 2009

Logo du logiciel Cheetah3DJe connaissais Cheetah3D depuis un petit moment déjà, je l’avais essayé en version d’évaluation. Ce logiciel de modélisation 3D a été écrit spécialement pour Mac OS X : l’interface est agréable, claire et simple. La puissance de l’outil est assez impressionnante, surtout lorsque l’on sait que le logiciel ne vaut que… 149 $ ! C’est vraiment peu cher comparé aux ténors que sont 3ds Max (3495 $), Maya (1995 $) ou encore Cinema4D (995 $) dans leurs versions les moins chères. Cheetah3D n’est peut-être pas aussi complet et puissant, mais il permet toutefois de faire de belles choses (je trouve). Étant donné que je suis en train d’essayer de créer un petit jeu avec OpenGL, j’ai acheté Cheetah3D. À l’occasion de son cinquième anniversaire, Cheetah3D est en promotion en ce moment à 99 $ (soit 83 € TTC). Du coup, j’ai aussi acheté le didacticiel de 4 heures en vidéo haute définition, en anglais (27 € TTC). Et je ne suis pas déçu ! Bref, si vous voulez faire de la 3D et que vous êtes sous Mac, n’hésitez pas à soutenir l’unique développeur de ce logiciel !

LogicielsMac

Glisser-déposer de fichiers dans votre application

19 janvier 2009

Dans cet article, je vais vous montrer comment on peut très simplement gérer le drag and drop de fichiers depuis le Finder vers votre application.

Il faut créer une sous-classe de NSView, par exemple DropFilesView. Dans cette classe, il faut indiquer à Cocoa que cette vue accepte la dépose de fichiers par drag and drop. Pour cela, on implémente la méthode -awakeFromNib comme ceci :

- (void) awakeFromNib {
    [self registerForDraggedTypes:
     [NSArray arrayWithObjects: NSFilenamesPboardType, nil]
    ];
    // Attention à ne pas oublier le "nil" en dernier argument de
    // arrayWithObjects !
}

Je vous rappelle que la méthode -awakeFromNib est appelée automatiquement lorsque votre application est chargée par Cocoa : c’est donc un emplacement judicieux pour initialiser des données propres à la vue. Il faut ensuite implémenter les méthodes suivantes, en fonction des besoins :

- (NSDragOperation)draggingEntered:(id )sender {
    // Appelée UNE FOIS lorsque la souris commence à survoler la vue
    // dans un processus de drag and drop.
}
 
- (NSDragOperation)draggingExited:(id )sender {
    // Appelée lorsque la souris quitte la zone de survol de la vue
    // dans un processus de drag and drop.
}
 
- (NSDragOperation)draggingUpdated:(id )sender {
    // Appelée à chaque fois que la souris est déplacée au dessus de la vue
    // dans un processus de drag and drop.
}

Ces trois méthodes retournent toutes une valeur de type NSDragOperation, indiquant si la dépose est autorisée (NSDragOperationGeneric, …) ou pas (NSDragOperationNone). Ces méthodes peuvent donc servir à vérifier que la vue accepte bien les données qui sont sur le point d’être déposées, auquel cas on retourne une valeur autre que NSDragOperationNone ; si la dépose n’est pas permise, on retourne NSDragOperationNone.

Enfin, il faut gérer le cas où l’utilisateur dépose effectivement les fichiers, auquel cas la méthode -performDragOperation: est appelée : il convient donc de la surcharger à votre guise…

- (BOOL)performDragOperation:(id)sender {
    // Appelée lorsque l'utilisateur a déposer les fichiers sur la vue :
    // on doit alors récupérer la liste des fichiers et les traiter...
    NSPasteboard *pboard = [sender draggingPasteboard];
    if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
        NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
        // files contient maintenant la liste des fichiers (avec chemin complet)
        // qui ont été déposés sur la vue par l'utilisateur.
        // Faites donc ici ce que vous voulez avec files ;-)
    }
    return YES; // On indique que le drag and drop a été concluant.
}

Vous pouvez télécharger le projet complet pour Xcode : DropFilesTutorial.zip.

CocoaDéveloppementTutoriels

Données membres statiques en Objective-C

12 janvier 2009

Objective-C ne permet pas de déclarer une donnée membre statique dans une classe via l’utilisation du mot-clé static, comme en Java par exemple. En fait, il suffit de déclarer une variable statique dans la section @implementation de la classe :

@implementation MyClass
// Déclaration d'une donnée membre STATIQUE
static NSDictionary* cacheMap;
...
@end

Pour initialiser cette variable, notamment s’il s’agit d’un objet, il suffit d’implémenter la méthode statique initialize de la classe concernée et d’y initialiser la donnée statique :

+ (void) initialize {
   cacheMap = [NSDisctionary dictionary];
}

Toutes les méthodes statiques de votre classe peuvent utiliser cette donnée statique : Cocoa se charge d’envoyer le message initialize à votre classe avant tout autre appel.

Attention : cette donnée statique ne sera pas visible dans les classes qui étendent votre classe.

CocoaDéveloppementTutoriels

Dessiner dans une NSView

4 janvier 2009

Dans Interface Builder, sélectionnez la vue en question et, dans l’onglet Identity de l’Inspecteur, indiquez un nom de classe pour votre vue dans le champ Class (par exemple : GameView). Sélectionnez File > Write Class Files… dans le menu principal de Interface Builder pour générer cette classe dans le projet.

De retour dans Xcode, ouvrez le fichier de déclaration de cette classe (GameView.h) et faites étendre la classe de NSView :

@interface GameView : NSView {
   NSImage *background;
}
@end

Ensuite, éditez le fichier d’implémentation de la classe (GameView.m) et implémentez la méthode -drawRect: :

- (void)awakeFromNib {
   // La variable "background" est déclarée dans le fichier header (.h).
   background = [NSImage imageNamed:@"background.png"];
}
 
- (void)drawRect:(NSRect)rect
{
   [background dissolveToPoint:NSMakePoint(0, 0) fraction:1.0];
}

Notez que l’image est initialisée dans la méthode -awakeFromNib, qui est appelée lors de l’initialisation de la vue.

Pour animer le contenu de la vue, et donc pour forcer le rafraîchissement de la vue, il est possible d’utiliser un NSTimer pour indiquer à la vue qu’elle doit se re-dessiner :

- (void)awakeFromNib {
   background = [NSImage imageNamed:@"background.png"];
   [NSTimer
      scheduledTimerWithTimeInterval:0.01
      target:self
      selector:@selector(refresh:)
      userInfo:nil
      repeats:YES];
}
 
- (void)refresh:(NSTimer*)timer {
   [self setNeedsDisplay:YES];
}

La méthode -refresh: sera appelée toutes les 0,01 seconde (100 fois par secondes, donc) et demandera à la vue de se re-dessiner, via l’appel à setNeedsDisplay:YES. Évidemment, ceci n’a de sens que si l’image (ou sa position) change.

Côté performances, j’ai fait quelques tests : j’affiche 1000 fois la même image (26×26 pixels) toutes les 0.01 seconde en la décalant de 1 pixel et ça ne gêne pas du tout mon iMac, l’animation est impeccable !

Je précise que ce n’est pas ici une technique très avancée pour animer du contenu, car cela ne tient pas compte de la puissance de la machine. En vérité, dans la méthode -refresh:, il faudrait vérifier si l’image doit être déplacée (ou modifiée) en fonction du temps qui s’est écoulé depuis la dernière modification de cette image. Ainsi, peu importe la résolution du timer utilisée, ou la capacité de la machine à afficher du contenu graphique, l’image sera toujours correcte (en fonction du temps écoulé), même si l’animation n’est pas fluide. Il est aussi possible d’utiliser NSAnimation pour des animations complexes « finies ».

Pour terminer, si votre but est de faire de l’animation complexe (2D ou 3D), comme pour la programmation d’un jeu, je ne peux que vous conseiller de vous tourner vers OpenGL. Je suis en train de m’y mettre, je publierai donc prochainement des articles à ce propos.

CocoaDéveloppementMacTutoriels

Bonne année !

1 janvier 2009

Joyeuse année 2009Je vous souhaite à toutes et à tous une très bonne année 2009 !

Que cette nouvelle année puisse vous offrir tout ce que 2008 n’a pas eu le temps de vous apporter : bien sûr, l’incontournable triplet santé-amour-argent (ou SAA pour ceux qui aiment les abréviations), mais aussi de la créativité, du repos et du temps (ou CRT, mais rien à voir avec ceci).

Bref, éclatez-vous en 2009 !

Annonces