P
'
t
i
t
e
C
h
a
t
t
e
 
spacer~ "PEOPLE SAY NOTHING IS IMPOSSIBLE, BUT I DO NOTHING EVERY DAY." Articles | Connexion
 
~Le langage Squeak

Précédent  
  Squeak  
  Suivant
 Présentation

Le terme "morph" vient du mot Grec signifiant "forme". En Squeak, les éléments graphiques se voient désignés sous cette appellation. Nous allons découvrir ce mois-ci comment modifier le comportement d'un morph existant.
 Sommaire


 Introduction

La plate-forme Squeak propose de nombreux Morphs répartis dans les catégories système dont le nom commence par "Morphic-". Les classes de bas niveaux de l'environnement des Morps prennent place dans les catégories "Morphic-Kernel" et "Morphic-Basic". Par exemple, la classe mère de tous les objets Morps s'intitule "Morph" et se trouve dans la catégorie "Morphic-Kernel". Notre première approche des Morphs consistera en l'extension d'un Morph déjà existant, le Morph ClockMorph que vous trouverez dans la catégorie "Morphic-Demo".


 Remonté comme une pendule

Ce Morph très simple dérive de la classe StringMorph qui affiche une simple chaîne de caractère en tant qu'objet graphique. L'utilisation du System Browser vous laissera l'opportunité d'explorer plus avant le contenu de ces classes. Un objet Clock Morph affiche par défaut l'heure sous forme décimale, au format anglo-saxon, en utilisant une simple couleur noire. Vous pouvez essayer ce Morph en exécutant les lignes suivantes dans la fenêtre Transcript :

clock := ClockMorph new.
clock openInWorld.
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le nouveau Morph devrait alors faire son apparition dans le coin supérieur gauche de l'écran. La réalisation d'une telle horloge ne demande pas beaucoup d'efforts. En effet, la classe parent Morph propose des méthodes dédiées à la gestion de l'écoulement du temps. Ainsi, la méthode step est appelée chaque fois qu'un intervalle donnée est écoulé. L'intervalle en question se définit par l'entremise de la méthode accesseur stepTime:. Pour démarrer ou arrêter la gestion temporelle d'un Morph, le programmeur doit employer les méthodes startStepping et stopStepping. La classe ClockMorph implémente ainsi une horloge simple affichant l'heure et les secondes (cette caractéristique peut se voir altérée grâce aux méthode showSeconds: et toggleShowingSeconds) au format "12 heures".


 Une horloge franche

Déroutés par cet affichage peu familier, nous allons nous atteler à une lourde tâche, l'affichage de l'heure au format "24 heures". En examinant la méthode step, appelée toutes les secondes puisque stepTime renvoie la valeur 1000, nous découvrons comment la classe ClockMorph crée l'affichage (voir listing 1). L'appel à la méthode statique streamContents de la classe String permet l'exécution du bloc de code passé en paramètre et son interprétation sous forme de chaîne de caractères.

step
  | time |
  super step.
  time _ String streamContents:
  [:aStrm | Time now print24: false showSeconds: 
        (showSeconds == true) on: aStrm].
  self contents: time
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le bloc de code en question emploie la classe Time (de la catégorie "Kernel-Magnitude") pour obtenir l'heure courante de la machine. Le message invoqué correspond au message print24:showSeconds:on: dont le premier argument spécifie le format de l'heure, "12 heures" ou "24 heures". Par défaut, la classe ClockMorph précise la valeur false. Nous devrons donc surcharger cette méthode pour employer la valeur true à la place. Notre nouvelle classe pourra également proposer un accesseur et un mutateur pour permettre de choisir le format d'affichage.

Dans la catégorie "Login-Squeak" créée le mois dernier, nous définissons une nouvelle classe HorlogeMorph, héritant de ClockMorph. Le listing 2 présente le code relatif à cet héritage. Vous constaterez que cette définition déclare une variable d'instance "format24h". L'utilisation de cette variable servira à ajuster l'affichage en mode "12 heures" ou "24 heures". Aussi, déclarons-nous une nouvelle catégorie de messages intitulée "accessing". Trois nouveaux messages font leur apparition : format24h, format24h: et step. Implicitement, nous surchargeons la méthode step de la classe parente ClockMorph. Le code source final de notre classe se voit reporté dans le listing 3.

ClockMorph subclass: #HorlogeMorph
  instanceVariableNames: 'format24h'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'Login-Squeak'
       
      
JextCopier dans Jext
format24h
  format24h isNil ifTrue: [format24h := true].
  ^format24h
format24h: on
  format24h := on
step
  | time |
  super step.
  time _ String streamContents:
  [:aStrm | Time now print24: self format24h showSeconds: 
       (showSeconds == true) on: aStrm].
  self contents: time
       
      
JextCopier dans Jext
L'accesseur format24h utilise la notion d'initialisation paresseuse (ou "lazy instanciation") pour attribuer une valeur par défaut à l'attribut format24h. En surchagargeant la méthode d'initialisation de la classe nous pouvons éviter la présencde du test conditionnel dans ce message. Le message initializese voit automatiquement appelé lorsqu'une nouvelle instance de la classe est créée. Notre classe HorlogeMorph devra donc posséder le message suivant :

initialize
  super initialize.
  format24h _ true
       
      
JextCopier dans Jext
La première instruction se révèle capitale puisque son rôle consiste à invoquer les messages initialize parents et à garantir ainsi le bon fonctionnement de l'instance. Bien évidemment, libre à vous de l'omettre pour remplacer totalement l'initialisation des instances. A l'aide de ce message, le programmeur peut ainsi créer une horloge non pas noire par défaut, mais rouge :

color _ Color red.
       
      
JextCopier dans Jext
Le Transcript peut à présent se voir employé pour essayer notre nouvelle horloge :

(HorlogeMorph new) openInWorld.
       
      
JextCopier dans Jext

 Gros Quick

L'objectif suivant de notre initiation aux Morphs consiste en l'ajout d'une simple bordure bleue autour de notre horloge. Le dessin des Morphs au sein de l'environnement Squeak s'effectue au sein du message drawOn: dont l'unique paramètre constitue une instance de la classe Canvas de la catégorie "Morphic-Support". Voici l'instruction utilisée au sein de la classe StringMorph pour provoquer l'affichage d'une chaîne de caractères :

aCanvas text: contents bounds: bounds font: self fontToUse color: color.
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le message text:bounds:font:color: de la classe Canvas affiche une chaîne de caractère découpée par un rectangle "bounds", de police "font" et de couleur "color". En sus de cette méthode, la classe Canvas offre de nombreus possibilités dessin, comme l'affichage d'images, de rectangles... Nous allons pour notre part nous contenter d'ajouter un simple rectangle autour du texte. A cet effet, nous utiliserons le message frameRectangle:color: de Canvas. Le premier argument de ce message se veut une instance de la classe Rectangle de la catégorie "Graphics-Primitives". Une manière simple de déclarer un rectangle consiste à employer la syntaxe suivante : x@y corner width@height . Toutefois, la variable d'instance "bounds" de la classe Morph définit les bords du Morph et constitue une instance de Rectangle. Ainsi, nous dessinerons notre bordure de la sorte :

drawOn: aCanvas
  super drawOn: aCanvas.
  aCanvas frameRectangle: bounds color: Color blue.
       
      
JextCopier dans Jext
La prochaine étape de notre découverte des Morphs consistera en la réalisation de notre propre Morph. Vous pouvez en attendant la rentrée vous pencher sur le code source des Morphs présentés dans la catégorie "Morphic-Demo" afin d'obtenir des informations complémentaires sur leur fonctionnement.



par Romain Guy
romain.guy@jext.org
http://www.jext.org
Dernière mise à jour : 14/10/2006


Précédent  
  Squeak  
  Suivant

 
#ProgX©2005 Mathieu GINOD - Romain GUY - Erik LOUISE