
Programmation sous GNUstep (1) Nicolas Roard et Fabien Vallon 13 mars 2003 Suite a` la presentation´ du projet GNUstep parue dans le Description de l’application numer´ o 47, nous allons commencer une petite applica- tion que nous allons faire evoluer´ et etendr´ e au cours de Ce mois-ci nous allons donc commencer par quelque l’annee´ . chose de simple. Le programme que nous allons realiser´ a pour but de noter et gerer´ des tachesˆ a` faire ; le nom de l’application sera <Todo.app>. News L’interface sera pour le moment tres` simple, affichant la liste des tachesˆ dans sa partie superieure´ et le – Le nouveau <text-system> (voir l’interview pa- contenu d’une tacheˆ (description, date, etc.) dans sa partie rue dans le LMF numero´ 47) a fusionne´ avec la inferieure.´ Il sera bien surˆ possible de rajouter ou suppri- branche principale deb´ ut fevrier´ . mer une tache,ˆ et memeˆ de sauver le tout dans un fichier. – Optimisations pour gnustep-gui (AppKit), no- Cela nous permettra d’aborder l’outil de RAD1 fourni tamment les methodes´ de dessin ainsi que di- avec GNUstep, Gorm, et d’introduire quelques uns des verses corrections liees´ au focus. Design Patterns2 couramment utilises´ dans une applica- – Maintenance/Corrections mineures (du dej´ a` tion GNUstep. stable) -base et -make. Vous constaterez d’ailleurs au fil des articles que le fra- mework GNUstep utilise lui-memeˆ intensement´ nombre de patterns connus. Les commandes clavier sous GNUstep s’utilisent via la touche <commande> (pomme pour Apple), en gen´ eral´ on affecte cette touche a` <ALT> sur Modele` – Vue – Controleurˆ un clavier de type PC. Les principales actions as- sociees´ a` la touche commande sont : Commenc¸ons par le tres` classique Modele-V` ue- – q pour Quitter Controleurˆ , que l’on peut voir sur la figure 1 page – w pour Fermer la fenetreˆ qui a le focus suivante. – h pour Cacher Ce pattern consiste a` separer´ en 3 parties une application. – o pour Ouvrir un document – Le Modele` represente´ votre partie metier´ , c’est-a-dire` – n pour Ouvrir un nouveau document la partie du code independante´ de la partie graphique – s pour Sauvegarder ou de l’interaction avec l’utilisateur. – t pour Afficher le Panneau de Fontes (si il y a) – La Vue est chargee´ de representer´ a` l’utilisateur le – c pour Afficher le Panneau de Couleurs (si il y Modele.` a) – Le Controleurˆ sert de lien entre le Modele` et la Vue. – w pour Fermer la fenetreˆ qui a le focus Cette separation´ en trois unites´ permet une conception – c pour Copier plus propre : rien n’empecheˆ de reutiliser´ votre modele` – v pour Coller ailleurs (dans une application GNUstepWeb par exemple), – x pour Supprimer ou de changer completement` votre vue en etant´ surˆ de ne Par def´ aut GNUstep n’utilise qu’un seul bouton pas affecter le reste de votre application. de la souris. Par exemple, en utilisant Gorm, on Dans notre cas l’interface graphique avec laquelle l’uti- selectionne un objet par un seul clic. En double- lisateur va interagir sera la partie <Vue>. Cette interface cliquant sur l’objet on <l’ouvre> : si l’objet contient d’autres objets (cas d’une boˆıte) ou si 1Rapid Application Development 2Design Patterns de Erich Gamma, Richard Helm, Ralph Johnson, et l’objet est un conteneur, on accede` aux objets a` John Vlissides. ISBN 0201633612 l’interieur´ de celui-ci. Sinon on peut editer´ <sur place> cet objet. 1 graphique sera cre´ee´ avec Gorm. Le Modele` (interface) Notre modele` sera ici la tacheˆ a` effectuer, c’est-a-dire` un Vue L’interface est reliée au controlleur objet contenant toutes les informations liees´ a` une tacheˆ Le controlleur mets à jour l’interface donnee.´ Nous appellerons cette classe d’objets <Todo>. Agit sur l’interface Un objet Todo contiendra pour le moment trois donnees´ Affiche les informations membres : une chaˆıne de caracteres` contenant la des- Utilisateur fournit les infos au controlleur Modèle Controlleur cription de la tache,ˆ une chaˆıne de caracteres` contenant répercute les actions sur le modèle une note ev´ entuellement plus detaill´ ee,´ et enfin un entier contenant l’indice de progression de la tacheˆ (sur 100). Chaque objet pourra ev´ entuellement contenir des sous- FIG. 1 – Le pattern MVC taches,ˆ c’est-a-dire` d’autres objets de classe <Todo>. Pour simplifier les choses, nous allons permettre d’avoir plusieurs tachesˆ au niveau de l’application ; nous aurons ainsi simplement un tableau contenant un ou plusieurs ob- La Del´ egation´ jets <Todo> au niveau du controleurˆ . Voici donc l’interface de notre modele` (mis dans un fichier Ce pattern consiste a` renvoyer vers un objet <aidant>, dit Todo.h) : del´ egu´ e,´ certains travaux. L’approche classique en pro- grammation objet pour ameliorer´ ou specialiser´ un objet #ifndef TODO H est de le sous-classer. La del´ egation´ consiste a` ne pas mo- #define TODO H difier l’objet, mais a` simplement demander certaines infos #include <Foundation/Foundation.h> ou certains traitements a` un objet <d’aide>. Ce pattern permet souvent de se passer de la creation´ d’une sous- @interface Todo : NSObject classe, et simplifie d’autant le programme. f 3 Pour reprendre l’analogie donnee´ par Aaron Hillegass , NSString ∗ note; le sous-classage revient a` l’approche <Robocop> : pour NSString ∗ description; ameliorer´ le policier, on emploie des dizaines de chirur- int progress; giens, et il faut connaˆıtre parfaitement le fonctionnement NSMutableArray ∗ childs; du corps humain. C’est un outil puissant, mais qui peut id parent; etreˆ complexe a` manipuler. g La del´ egation´ revient a` l’approche <K2000> : pour // Constructeur ameliorer´ Michael, on utilise simplement un outil cre´e´ −(id) initWithDescription: (NSString∗) pour lui, la voiture Kit, ayant tout ce qu’il faut comme description andNote: (NSString∗) note; gadgets indispensables a` la vie tem´ eraire´ d’un justicier a` // modifieurs roulettes. −(void) setDescription: (NSString ∗) Par exemple, quand un widget NSTableView (affichant un description; tableau ou une liste) doit s’afficher, au lieu de le sous- −(void) setNote: (NSString ∗) note; classer pour qu’il reponde´ a` nos besoins, on lui fournit un −(void) setProgress: (int) progress; objet del´ egu´ e.´ −(void) setChilds: (id) childs; Quand le NSTableView voudra se dessiner, il demandera −(void) addChild: (id) child; simplement a` son del´ egu´ e´ des choses comme <Combien −(void) setParent: (id) parent; ai-je de lignes ?> ou <Qu’est-ce qui doit etreˆ affiche´ dans −(void) removeChild: (id) child; la premiere` colonne de la troisieme` ligne ?>. // accesseurs −(NSString ∗) desc; −(NSString ∗) note; Realisation´ −(int) progress; −(id) parent; Voyons comment nous pouvons appliquer ces patterns a` −(NSArray∗) childs; notre programme. @end 3<Cocoa Programming for Mac OS X> de Aaron Hillegass, ISBN 0-201-72683-1 #endif 2 Chaque objet Todo pourra donc contenir ev´ entuellement −(id) parent f return parent; g des sous-tachesˆ (stockees´ dans le tableau childs) ; on pourra acceder´ a` la tacheˆ parente si elle existe en envoyant /∗ Modifieurs ∗/ le message parent : id tacheParente = [maTache parent] ; −(void) setDescription : (NSString ∗) Voici le code de notre modele` (mis dans un fichier description f Todo.m) : [ description release]; description = [[NSString alloc] #include ”Todo.h” initWithString: description]; g @implementation Todo −(void) setNote : (NSString ∗) note f /∗ Constructeurs ∗/ [ note release]; note = [[NSString alloc] initWithString −(id) init f : note]; self = [super init]; g note = [[NSString alloc] init]; description = [[NSString alloc] init]; −(void) setProgress: (int) progress f childs = [[NSMutableArray alloc] init]; if ((progress >= 0) && (progress < 100)) parent = nil; f progress = 0; progress = progress; return self; g g g −(id) initWithDescription: (NSString∗) −(void) addChild: (id) child f description andNote: (NSString∗) note f [ childs addObject: child]; self = [super init]; g description = [[NSString alloc] initWithString: description]; −(void) setParent: (id) parent f note = [[NSString alloc] initWithString ASSIGN ( parent, parent); : note]; g childs = [[NSMutableArray alloc] init]; parent = nil; −(void) setChilds: (id) childs f progress = 0; ASSIGN ( childs, childs); return self; g g −(void) removeChild: (id) child f /∗ Destructeur ∗/ [ childs removeObject: child]; g −(void) dealloc f RELEASE( childs); − (void) encodeWithCoder: (NSCoder∗) coder RELEASE( note); f RELEASE( description); [coder encodeObject: description]; [super dealloc]; [coder encodeObject: note]; g [coder encodeValueOfObjCType: @encode (int) at: & progress]; /∗ Accesseurs ∗/ [coder encodeObject: parent]; [coder encodeObject: childs]; −(NSString ∗) desc f return description; g g −(NSString ∗) note f return note; g −(int) progress; f return progress; g − (id) initWithCoder: (NSCoder∗) coder f −(NSArray ∗) childs f return childs; g 3 if (self = [super init]) Creation´ de l’interface graphique f [self setDescription: [coder <Pour le novice ou l’utilisateur occasionnel, l’in- decodeObject]]; terface doit etrˆ e simple et facile a` apprendre [self setNote: [coder et a` retenir. Elle ne devrait pas necessiter´ un decodeObject]]; reapr´ entissage apres` une longue absence de l’or- [coder decodeValueOfObjCType: dinateur.> @encode (int) at: & progress (guide de l’interface NeXT) ]; [self setParent: [coder Lancez Gorm : openapp Gorm.app. decodeObject]]; Creons´ une nouvelle application : Document!New Ap- [self setChilds: [coder plication. decodeObject]]; g return self; g @end La Vue Memeˆ si il est tout a` fait possible de dev´ elopper l’in- terface
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages12 Page
-
File Size-