14. Un méli-mélo de dessins <<< Table des matières >>> 16. Dialogues


15. Coloriez à volonté

Notre prochaine tâche dans le monde de Peter le lapin est la création d’un éditeur graphique capable de permettre à l’utilisateur de mettre de la couleur dans des images déjà prêtes . Durant ce travail, nous apprendrons comment travailler avec la souris et avec les fichiers . Le fonctionnement du programme devrait être le suivant : il trouvera toutes les images ( fichiers BMP) situées dans son dossier . L’utilisateur pourra faire son choix parmi les images et leur ajouter des couleurs en remplissant des secteurs . Le noir sera réservé au contour des images .

Quelques mots sur les fichiers et les dossiers . Un fichier est un élément séparé de donnée stocké dans l’ordinateur . Cela peut être une image, une lettre, une feuille de calcul ou un programme . Les fichiers de données utilisateur sont souvent appelés documents. Un dossier  est un « gros paquet de fichiers » . Les dossiers sont semblables aux groupes  qu’on trouve dans Peter . Si nous voulons indiquer l’emplacement d’un fichier ou d’un dossier sur le disque, nous utilisons une représentation appelée chemin (path). Un chemin est une liste des dossiers (avec parfois aussi l’indication du disque) à travers lesquels nous devons passer pour trouver le fichier (ou le dossier) recherché . Les noms des dossiers sont séparés par des traits inclinés vers l’arrière (backslashes) "/". Par exemple : C:/Program Files/Peter/Peter.exe. Remarquez l’étiquetage particulier du disque : une lettre et deux points (« colon ») . A la fin du chemin vous trouvez ici un nom de programme . Cette représentation est appelée nom complet de fichier . Celui-ci comporte le disque, les dossiers, le nom de fichier, et l’extension du nom de fichier . L’extension de nom de fichier est la partie située après le point ; elle indique le type de fichier . Par exemple, l’extension EXE désigne des programmes .

D’abord, créez un nouveau programme appelé Filler (« Remplisseur ») , ou bien utilisez le programme d’exemple déjà tout prêt dans Peter .

Nous allons ajuster la taille de la feuille . Nous éditerons des images d’une taille standard de 20 x 15 carrés  (640 x 480 points graphiques). Pour la sélection des couleurs et des images, il nous faudra une barre d’une hauteur d’un carré au bas de la fenêtre . Pour cette raison, réglons la taille de la feuille principale de programme à 20 x 16 carrés . C’est encore une bonne taille pour le mode écran (mode vidéo) 800 x 600 points qui est aussi le minimum recommandé (un mode plus élevé est préférable) pour les utilisateurs de nos programmes .

Créez deux items -- left arrow (flèche gauche)  et right arrow (flèche droite) . Dans ces items peignez les images des boutons de contrôle pour la navigation vers la gauche et vers la droite . L’arrière-plan sera gris . Déposer ces items dans le coin inférieur droit de la feuille, comme sur l’image ci-dessus .

Créez la boucle principale du programme – c’est une conditional repeating (répétition conditionnelle) sans fin (la condition du cycle contiendra un élément yes (oui) ). Le corps du cycle contiendra une commande « wait »  (attendre).

Devant (avant) la boucle principale du programme, placer un groupe appelé program initialization (initialisation du programme). Il va contenir les opérations préparatoires nécessaires au fonctionnement du programme .

La première commande placera le texte d’aide dans la barre d’état au bas de la fenêtre . Si la barre d’état ne contient aucun texte , elle est désactivée . Si vous souhaitez utiliser la barre d’état, il est recommandé de l’activer au début du programme . Ca ne fait pas très bien quand la fenêtre de programme apparaît d’abord, puis, seulement quelques moments après, la barre d’état .

Tuyau: si vous voulez utiliser un barre d’état vide, affichez le caractère « espace » .

La seconde commande va remplir la fenêtre de programme avec la couleur blanche . Dans la commande filled box (boîte pleine)  , utilisez juste un paramètre — la couleur blanche . Si nous sautons les paramètres restants, nous remplirons la feuille entière . Cette commande fait en sorte qu’un arrière-plan noir n’apparaisse pas durant le chargement de la liste d’images et avant l’affichage de la première image . Elle est utilisée ici pour des raisons purement esthétiques, mais , en général, les états transitoires des programmes ne doivent pas être négligés . Une succession de petites impressions négatives peut défavorablement influencer l’attitude des utilisateurs par rapport à un programme . S’il aperçoit quelque chose qui ne va pas, l’utilisateur aura tendance à ne pas avoir confiance dans le programme . La même chose se produit lorsque le programme ne réagit pas assez vite aux actions de l’utilisateur , ou lorsque celui-ci ne sait pas comment contrôler le programme . Cela produit des effets encore pires lorsqu’une commande intuitive produit des résultats inattendus et indésirables .

La troisième commande est une fonction  prepare service of color selection (préparer la gestion de la sélection de couleur). Elle va définir les couleurs pour le dessin et elle affiche les champs de couleurs . Pour l’instant, préparez une fonction vide .

Ce qui vient ensuite est une commande d’attente avec le paramètre 0. Que fait-elle là ? Comme vous le savez, la commande d’attente assure l’affichage de la fenêtre . Au démarrage du programme, la fenêtre n’est pas activée immédiatement . Le programme attend la première commande d’attente . Quand celle-ci lui parvient, le programme tient pour assuré que le contenu de la fenêtre est déjà préparé . Sans ce comportement particulier, on pourrait voir des effets transitoires durant le démarrage du programme . La commande d’attente avec le paramètre 0 fait en sorte que la fenêtre soit activée immédiatement après le démarrage . Sans cette commande, la fenêtre serait activée un peu plus tard, une fois les fichiers trouvés, ce qui n’est pas un fonctionnement aberrant, mais l’utilisateur pourrait entretemps se demander si le programme a vraiment démarré  et essayer , sans attendre, de le démarrer une deuxième fois .

La fonction load picture list (charger la liste des images) trouve tous les fichiers BMP contenant des images . La fonction load picture (charger l’image) charge l’image courante dans le programme et l’affiche .  Pour l’instant, préparez seulement des fonctions vides . Les quatre dernières commandes redéfinissent l’apparence du curseur . Nous en parlerons un peu plus tard .

Si vous démarrez le programme maintenant, vous voyez une feuille blanche, deux boutons dans le coin inférieur droit, et des textes dans le titre de la fenêtre et la barre d’état .Ce n’est rien de spécial, juste le début .

Dans la fenêtre Global Variables and Functions (Variables et Fonctions Globales) , créez une nouvelle liste appelée color list (liste des couleurs). Réglez la taille de la liste à 36. Ceci sera le nombre de couleurs utilisées dans l’éditeur . Renommez le pointeur dans la liste color index (index de couleur) et l’incrément automatique color index increment (incrément de l’index de couleur). Ajoutez dans la liste un élément numérique de donnée appelé color (couleur) .

Nous allons créer le contenu de la fonction prepare service of color selection (préparer la gestion de la sélection de couleur). Passez dedans en faisant un double clic sur son icône . L’ensemble de la fonction est présenté dans l’image ci-dessous . Du côté droit, nous avons le cycle qui crée les champs de couleur .

D’abord , nous allons remplir la liste des couleurs . Réglez l’index de couleurs à  0 et l’incrément d’index de couleur à  1. Ceci fait en sorte que les couleurs seront stockées dans la liste à partir du début et que le pointeur avancera automatiquement de 1 à chaque choix de couleur . Viennent ensuite les commandes de choix de couleur . Choisissez 36 couleurs (pas le noir  — il va servir pour les contours des images) . Pourquoi 36? Pour sélectionner la couleur, nous aurons 18 carrés, et chaque carré contiendra 2 couleurs .

Les champs de sélection de couleurs seront affichés en utilisant des items . Les items conviennent mieux ici que le rendu graphique parce que , lorsque nous remplirons des surfaces, la couleur pourrait aussi aller dans les champs de couleur . Au lieu de dessiner les items à la main, nous allons les créer par programme . C’est plus facile que d’éditer 36 champs et il  sera également plus facile de conserver la correspondance entre les champs et les couleurs réelles, si on doit plus tard modifier les couleurs dans le programme .

Dans la fenêtre Global Variables and Functions (Variables et Fonctions Globales) , créez une image (pas un item) appelée color selection box (boîte de sélection de couleur) d’une taille de 1x1 carrés. A l’intérieur, dessinez des champs pour le choix de deux couleurs, comme ceci :

Pour créer des items, nous procéderons au rendu de l’image dans la fenêtre de programme , nous la remplirons avec les couleurs, l’extrairons de la fenêtre en tant qu’item, et poserons celui-ci sur la feuille . Nous utiliserons Lucy pour déposer les items sur la feuille . Nous la mettrons sur le premier champ (avec la coordonnée horizontale 0) et la tournerons vers la droite . Un cycle pour tous les items « couleur » (la moitié du nombre des couleurs) vient ensuite .

La première commande du cycle dessinera l’image de la boîte de sélection des couleurs . Elle aura un seul paramètre – l’image à dessiner . Si le reste des paramètres est ignoré, l’image sera dessinée dans le coin inférieur gauche de la fenêtre .

La seconde commande va remplir le champ gauche d’une couleur de la liste . La coordonnée se réfèrera au centre du champ . D’une manière similaire, nous remplirons le second champ avec la seconde couleur . Rappelez-vous que l’index de couleur se déplace automatiquement .

Extrayez de la fenêtre l’image créée en utilisant la fonction retain cutout from sheet as item (conserver la découpe comme item) , et déposez-la à la position de Lucy . Lucy va alors aller au carré suivant .

Quand tous les champs de couleur sont créés, mettez l’index d’incrément de couleur à  0. A partir de maintenant nous n’utiliserons pas d’incrémentation automatique dans le programme .

Pensez-vous que nous réalisions trop d’opérations dans la fenêtre et que, certainement, on va les voir ? Ces opérations de dessin préparatoires sont en fait très rapides et nous avons suffisamment de temps avant que le contenu de la fenêtre ne soit rendu sur l’écran par la première commande d’attente .  L’image que nous dessinons reste cachée sous le premier item de sélection de couleur , et nous n’avons donc même pas besoin de l’effacer .

Vous pouvez maintenant démarrer le programme . Si tout est correct, une barre avec les champs de sélection de couleur va apparaître au bas de la fenêtre .

Dans la fenêtre Global Variables and Functions (Variables et Fonctions Globales) , préparez une liste qui conservera les noms de tous les fichiers qui seront trouvés (comme sur l’image ci-dessous) . Nommez-la picture names list (liste des noms des images).

Réglez la taille de la liste à 1000 . Il est possible que cela fasse beaucoup par rapport aux besoins, mais ce n’est pas très important du point de vue de la consommation en mémoire . En général chaque variable dans une liste occupe 4 bytes (octets) ; seules les variables numériques occupent 8 bytes et les variables logiques 1 byte . Notre liste utilisera donc 4000 bytes . Nous pouvons compter sur des millions de bytes de mémoire disponible .

Appelez le pointeur de liste picture index (index d’image) et renommez l’incrément automatique du pointeur  picture index increment ( incrément d’index d’image). Ajoutez dans la liste une nouvelle variable textuelle appelée picture name (nom de l’image) .

A côté de la liste des images, nous allons aussi créer une variable numérique appelée number of pictures (nombre d’images). Nous ne remplirons sans doute pas toute la liste, et cette variable conservera le nombre réel d’images se trouvant dans la liste .

A présent nous allons préparer la fonction load picture list (charger la liste des images).  Si vous avez ouvert le programme d’exemple Filler (Remplisseur), vous y voyez une fonction qui est un peu plus complexe . Le programme d’exemple fonctionne dans un environnement multi-utilisateurs et charge donc aussi des fichiers depuis le dossier hôte du programme . Nous utiliserons une simple variante qui chargera des fichiers images seulement depuis le dossier courant .

Nous allons préparer les variables locales de la fonction . Les noms des fichiers qui seront trouvés seront stockés dans une variable textuelle appelée list of names of pictures found (liste des noms des images trouvées). Nous trierons la liste par ordre alphabétique, et à cet effet, nous préparerons deux autres variables textuelles  one picture name (nom d’image unique) et one picture name 2 (nom d’image unique 2) .

L’image suivante montre le contenu de la fonction . La fonction va charger les noms des fichiers images depuis le dossier courant, ajouter ces noms à une liste et trier alphabétiquement la liste .

Pour trouver des fichiers dans le dossier, nous utiliserons la fonction file list (liste des fichiers)  . Comme paramètre de la fonction, nous utiliserons une spécification textuelle des fichiers à chercher . Cette spécification va utiliser des caractères jokers (un point d’interrogation  "?" représente n’importe quel caractère, un astérisque "*" représente n’importe quel groupe de caractères). Vous pouvez spécifier plus d’entrées . Les entrées individuelles seront séparées par un point-virgule (semicolon) « ; » . Pour trouver, par exemple, tous les fichiers d’image BMP, nous taperons  *.bmp ; pour trouver tous les fichiers  BMP et JPG (un autre format reconnu par Peter) , nous spécifierons individuellement ces deux entrées : *.bmp;*.jpg.

La fonction file list (liste des fichiers) renvoie un texte de plusieurs lignes dans lequel chaque ligne contient le nom d’un fichier trouvé, avec son extension (mais pas son chemin) . Lors de notre recherche de fichiers BMP nous pouvons par exemple obtenir le texte suivant :

Bull.bmp
Car.bmp
House.bmp
Kite.bmp
Ram.bmp

Nous allons ajouter les noms des fichiers individuels dans la liste des noms des images . Au départ nous règlerons le picture index (index d’image) à 0  et le picture index increment (incrément d’index d’image)  à 1 (nous utiliserons des incréments automatiques de l’index de la liste). Comme numéro de ligne, nous pouvons prendre l’index d’image . L’index sera automatiquement augmenté après que le nom aura été sauvegardé .

Après avoir sauvegardé tous les noms de fichiers dans la liste, nous utiliserons l’état final de l’index d’image pour régler la variable number of pictures (nombre d’images), et mettrons l’incrément d’index d’image à zéro .

Ensuite, nous ferons un tri alphabétique de la liste des noms des images . Nous irons du début à la fin de la liste et, à chaque fois, nous comparerons deux noms voisins . Si nous trouvons une paire de noms non triés , nous changerons les positions de ces noms et retournerons à la paire précédente afin de nous assurer que le premier nom selon l’ordre alphabétique soit déplacé aussi loin qu’il convient vers le début de la liste .

Le tri va être réalisé dans un cycle conditionnel . Dans la condition du cycle, nous testerons s’il y a encore une autre paire de noms . Dans le début du cycle, nous stockerons le premier nom dans une variable textuelle appelée one picture name (nom d’image unique) . Nous allons faire aller le pointeur sur le nom suivant dans la liste et tester si le premier nom est alphabétiquement plus loin que le second nom . Si c’est le cas, nous permuterons les positions des deux noms .

Pour opérer ce remplacement , nous stockerons le second nom (sur lequel est à présent le pointeur) dans la variable one picture name 2 (nom d’image unique 2) . Nous allons ramener le pointeur sur le premier nom et sauvegarder le nom qui était le second à la position du premier nom . Les positions sont à présent permutées .

Pour finir, nous ramènerons le pointeur en arrière dans la liste afin de pouvoir déplacer le premier nom vers le début de la liste (s’il n’est pas encore à la position appropriée .

Regardez la méthode de tri et assurez-vous que vous comprenez comment cela fonctionne . Ce n’est pas la méthode la plus rapide, mais elle est simple et plutôt satisfaisante .

La dernière commande dans la fonction load picture list (charger la liste des images) règle le pointeur de la liste d’images à  0. Ceci sera l’image à afficher par défaut .

Nous allons créer le contenu de la fonction load picture (charger l’image) . C’est tout à fait simple, comme vous le voyez ci-dessous . Il nous faut une paire d’éléments permettant de travailler avec des fichiers ; nous les trouverons dans le groupe files (fichiers) . D’abord, nous allons régler l’active file/folder for reading (fichier/dossier actif pour la lecture) en fonction du nom d’image provenant de la liste . Puis nous mettrons l’élément picture (image)  (sous-groupe data (données) ) dans la commande « draw picture » (dessiner l’image) . Et voilà !

Vous vous demandez peut-être ce qui arrivera si aucun fichier d’image n’est trouvé . Dans ce cas, le nom d’image va contenir un texte vide et les fonctions de chargement ou de sauvegarde d’image ne seront pas exécutées . Dans le programme d’exemple, ceci est complété par l’affichage d’un texte informant l’utilisateur qu’aucune image n’a été trouvée .

Maintenant il faudrait que nous préparions quelques images, ou au moins une image . Nous pouvons utiliser l’éditeur graphique de Peter pour cela . Réglez la taille d’image à  20x15 steps (pas) (c’est-à-dire 640x480 points). Dessinez les contours en noir . Vérifiez que les contours sont composés de secteurs parfaitement clos . Car, sinon, la couleur coulera … Après avoir dessiné l’image, sauvegardez-la dans la Library of Variables and Functions (Bibliothèque de Variables et Fonctions) et utiliser l’Explorateur Windows pour la déplacer (normalement, depuis le dossier C:/Mes Documents/Peter/Picture (Image)) vers le dossier contenant le programme Filler (Remplisseur) . Vous pouvez aussi utiliser les images d’exemple de Peter ; elles sont dans le groupe [examples]/Drawing ([exemples]/Dessin).

Lorsque vous avez au moins une image dans le même dossier que le programme Filler (Remplisseur), vous pouvez tester le programme . L’image qui est la première selon l’ordre alphabétique devrait apparaître .

Dans le programme, nous utiliserons Peter comme indicateur de la couleur sélectionnée . Faites un double clic sur l’icône Peter dans les Global Variables and Functions (Variables et Fonctions Globales) pour éditer le sprite . Modifiez les paramètres du sprite (en cliquant sur le bouton Properties (Propriétés) ) et donnez-leur les valeurs suivantes : Delay Between Phases (Délai entre phases = 110, Phases per Step (Phases par pas) = 0, Standstill Phases (Phases d’immobilité) = 4, Moving Phases (Phases de mouvement) = 0, Directions = 1, Picture Width (Largeur de l’image) = 0.5. Effacez du sprite les images de Peter et faites un double clic sur la première image pour l’éditer . Dessinez un cadre dans l’image en utilisant une séquence de couleurs blanc-gris-noir-gris . Copiez l’image vers les champs restants du sprite . A chaque fois , déplacez les points d’1 point dans le sens horaire . Lorsque vous testerez le sprite, vous verrez le cadre se déplacer en  « flottant «  dans les limites de l’image .

Pour indiquer la couleur se trouvant sous le pointeur de la souris, nous utiliserons Lucy . Commençons par éditer le sprite de Lucy et à régler les paramètres suivants : Phases per Step (Phases par pas) = 0, Moving Phases (Phases de mouvement) = 0, Directions = 1, Picture Width (Largeur de l’image) = 0.5. Redessinez l’image dans le sprite pour créer une impression de rehaussement , de relief, pour le champ de sélection de couleur. Laissez transparente la partie centrale .

Dans la boucle principale du programme (avant l’instruction d’attente), préparez un groupe appelé detect and test validity of the color under cursor (détecter et tester la validité de la couleur sous le curseur). Ici, nous testerons continuellement la couleur située sous le pointeur de la souris , ce qui nous permettra d’indiquer la couleur appropriée . La couleur détectée sera aussi utilisée dans d’autres structures faisant partie du programme .

Dans la fenêtre Global Variables (Variables globales), préparez deux variables numériques :  color under mouse cursor (couleur sous le curseur de la souris) et index of color under cursor (index de la couleur sous le curseur). Au début du groupe, régler ces deux variables à –1 pour indiquer qu’il n’y a aucune couleur valide sous le curseur . Ce qui suit est une commande conditionnelle qui teste si le pointeur de la souris est au dessus de l’image . Le test va commencer par un élément mouse test in the region (test de la souris dans la zone)  (groupe controls (contrôles) , sous-groupe mouse (souris) ), avec des paramètres règlés en fonction de l’image dans la fenêtre . Si le pointeur est au dessus de l’image , nous obtiendrons la couleur située sous ce pointeur en utilisant la fonction get color of pixel (obtenir la couleur du pixel)  (groupe graphic (graphismes) ). Nous stockerons la couleur dans la variable color under mouse cursor (couleur sous le curseur de la souris). Les coordonnées du point à partir duquel obtenir la couleur seront les mêmes que celles de la souris : mouse position in horizontal direction (position de la souris dans la direction horizontale)  et mouse position in vertical direction (position de la souris dans la direction verticale) . Dans les programmes de Peter, l’information concernant la souris (et les autres accessoires) ne change pas jusqu’à la prochaine commande d’attente .

Après avoir opéré une lecture d’information à partir du point, nous allons essayer de trouver la couleur dans la table des couleurs . Le cycle qui permet de réaliser cette action est sur la droite dans l’image ci-dessus . Le cycle parcourt toute la table des couleurs , comparant chaque couleur avec celle située sous le pointeur . S’il trouve la couleur correspondante , il stocke son index dans la variable index of color under cursor (index de la couleur sous le curseur), place Lucy (comme indicateur de la couleur sous le pointeur) au dessus du champ de cette couleur , puis active la visibilité de Lucy .

Observez attentivement le cycle que nous venons d’utiliser . L’index de couleur dans la liste des couleurs identifie la couleur sélectionnée par l’utilisateur . Le cycle parcourt l’ensemble de la liste des couleurs , et après que le cycle ait été terminé, l’index de couleur aura exactement la même valeur qu’avant que le cycle ait commencé . Nous avons utilisé un retour automatique du pointeur au début de la liste après que la fin de celle-ci ait été atteinte .

Regardons Lucy . Tout au long du programme, sa coordonnée verticale conserve par défaut la valeur 0 . Sa coordonnée horizontale est réglée à la moitié de l’index de la couleur sous le pointeur , car les champs de couleur sont large d’un demi-carré . Si vous vous demandez si Lucy peut aussi se trouver entre des carrés , alors la réponse est oui . Lorsque nous réglons les coordonnées de Lucy, nous pouvons utiliser une valeur quelconque, y compris des valeurs en dehors de la fenêtre , car Lucy est un sprite normal . C’est seulement lorsqu’on la déplace par une commande step (pas) que Lucy est limitée à la feuille de la fenêtre , et la coordonnée cible est ramenée au carré le plus proche . La même chose s’applique à Peter .

Après la commande conditionnelle qui permet d’obtenir la couleur il y a une commande conditionnelle qui désactive l’indicateur de couleur lorsqu’il n’y a pas de couleur valide sous le  pointeur . Ceci peut se produire si le pointeur n’est pas au dessus de l’image ou s’il y a du noir (ou une couleur inconnue) sous ce pointeur .

Démarrez et testez le programme . L’indication de la couleur sous le pointeur devrait maintenant fonctionner . Si vous immobilisez le pointeur de la souris au dessus d’une couleur dans l’image , le champ de la couleur correspondante devrait apparaître en relief par rapport à la surface de la fenêtre .

Nous allons commencer à travailler sur le contrôle du programme . Commençons par le contrôle à partir du clavier . Après la structure qui détecte la couleur, insérez une multibranch control structure (structure de contrôle multibranche)  appelée keyboard service (gestion du clavier). Comme valeur testée, utilisez la fonction key input (does not wait for press) (entrée touche (n’attend pas de pression)) .

La première branche de la structure va s’occuper de la touche Esc (Echap) . Ici, nous utiliserons la commande break executing (interrompre l’exécution) , ce qui nous fera quitter la boucle principale du programme .

La seconde branche se chargera de la touche Left (Gauche) . Créez une fonction vide appelée « image précédente » et insérez-la dans la branche . Derrière (après), mettez une commande flush out of key buffer (vider le tampon clavier)  . Le chargement d’une image prend un certain temps. Si l’utilisateur maintient la touche appuyée, les codes de touche arrivent trop vite pour que le programme puisse changer d’image . Pour cette raison, le programme se déplacerait encore parmi les images alors même que la touche ne serait plus pressée . Le contrôle serait sujet à de l’inertie, ce qui serait peu agréable .

La branche pour la touche Right (Droite)  sera similaire, mais cette fois-ci nous utiliserons une fonction next picture (image suivante) . Vous pouvez aussi ajouter de branches pour d’autres touches de direction, par exemple Home pour sauter à la première image, End pour aller immédiatement à la dernière, et  Ctrl+Left/Right  pour bouger de 10 images dans la direction désirée .

La dernière touche sera Back Space (Retour Arrière) . L’utilisateur peut s’en servir pour ramener l’image à son état initial  (avant qu’on ne commence à l’éditer, à la modifier) . Ceci sera réalisé par la fonction load picture (charger l’image) qui lira à nouveau l’image à partir du fichier . Ensuite vient une autre commande de vidage du tampon clavier .

Les images ci-dessous montrent le contenu des fonctions previous picture (image précédente) (à gauche) et next picture (image suivante) (à droite) . Au début de ces fonctions, l’image courante est sauvegardée  (si elle a été modifiée) . Pour l’instant, vous pouvez juste créer une fonction save picture (sauvegarder l’image).

Dans la fonction previous picture (image précédente), nous vérifierons que nous ne sommes pas en train de travailler sur la première image . Si ce n’est pas notre cas, nous pouvons déplacer le pointeur d’image vers l’image précédente et charger puis afficher la nouvelle image . Si c’est avec la première image que nous travaillons, rien ne se passera, mais nous pourrions régler le pointeur sur la dernière image (dont le numéro d’index correspond à number of pictures – 1 (nombre d’images –1)) et nous déplacer parmi les images par des mouvements de balayage circulaire .

Dans la fonction next picture (image suivante) , nous vérifierons de la même façon que nous n’en sommes pas à la dernière image . Le nombre correspondant à la dernière image est le nombre d’images moins 1 . Si nous n’en sommes pas à la dernière image, nous ferons avancer le pointeur à l’image suivante et chargerons celle-ci . Dans le cas de la dernière image, nous pourrions aller à la première image pour assurer une exploration cyclique .

Testez le programme . Vous pouvez vous déplacer parmi les images en utilisant les touches Left/Right (Gauche/Droite) , ou appuyer sur Esc (Echap)  pour quitter le programme .

Nous ne créerons pas pour l’instant de fonction de sauvegarde de l’image . Autrement nous pourrions, par accident, écrire sur une image . D’abord nous allons créer la structure servant au contrôle de la souris . Dans la boucle principale du programme , insérez une commande conditionnelle appelée click by left mouse button (clic avec bouton gauche de la souris) derrière (après) la structure de gestion du clavier .

Insérez un drapeau  click by left mouse button (clic par bouton gauche de la souris)  dans le test de réalisation de la condition . C’est un drapeau logique, et il est modifié chaque fois que l’utilisateur fait un clic gauche dans la fenêtre de programme . Le drapeau est désactivé une fois qu’on l’a lu , par exemple en l’utilisant dans une condition . Si vous voulez testez le drapeau « left click » (clic gauche) plus de fois, stockez-le dans une variable logique  .

Si le test de la condition détecte un clic gauche de l’utilisateur , nous utilisons alors une autre commande conditionnelle pour distinguer (à l’aide de la coordonnée verticale de la souris) si l’utilisateur a cliqué dans l’image ou dans la barre comportant des couleurs et des boutons . Un point sur la  bordure a ici la valeur  1, car la barre a une hauteur d’ 1 carré.

Pour la sélection de couleur, nous allons créer une nouvelle fonction appelée color selection (sélection de la couleur). Dans les variables d’entrée de la fonction, nous insèrerons une variable numérique appelée mouse cursor X position (position X du curseur de la souris) . Elle transmettra à la fonction la coordonnée horizontale de la souris dans la barre de sélection de couleur .

Dans la fonction, nous prendrons la valeur de la variable d’entrée, la multiplierons par 2 pour convertir la coordonnée en un nombre correspondant à une couleur, utiliserons la fonction integer part (partie entière) pour supprimer la partie décimale inutile , et nous utiliserons le résultat pour un nouvel index de couleur . Nous réglerons la coordonnée horizontale de Peter à la moitié de la valeur de l’index de couleur, ce qui correspond à la position du champ de couleur . Peter est utilisé dans le programme comme indicateur de la couleur sélectionnée . Sa coordonnée verticale demeure réglée de  manière permanente à , et nous ne nous en préoccuperons donc pas .

Si la coordonnée verticale de la souris nous dit que l’utilisateur a cliqué dans la barre avec des boutons et des couleurs, nous utiliserons la coordonnée horizontale pour distinguer s’il a cliqué sur un champ de couleur ou sur un bouton . Si la coordonnée horizontale est inférieure à 18, alors l’utilisateur est en train de sélectionner une couleur . Nous ferons appel à la fonction color selection (sélection de couleur) et utiliserons la coordonnée comme paramètre de cette fonction . Dans d’autres cas, l’utilisateur aura cliqué sur un bouton de déplacement parmi les images . Une coordonnée horizontale en dessous de 19 indique le bouton de gauche, et nous ferons appel à la fonction previous picture (image précédente). Dans les autres cas, nous utiliserons la fonction next picture (image suivante). L’ensemble de la structure utilisée pour les champs de sélection de couleur et les boutons de direction figure sur l’image ci-dessous :

Vous pouvez tester le programme . Le bouton gauche de la souris peut maintenant être utilisé pour permuter les images  ou pour changer la couleur sélectionnée dans la barre de sélection de couleur .

Nous allons à présent nous occuper des cas où l’utilisateur fait un clic gauche dans l’image . La structure sera basée sur une commande conditionnelle  fill picture with color (remplir l’image avec la couleur) (voir l’image ci-dessous). Le test de la condition vérifiera s’il y a du noir sous le pointeur de la souris . Le noir est utilisé pour les contours, et ne peut être utilisé pour le remplissage . La couleur sous le pointeur a été sauvegardée dans une variable au début de la boucle principale du programme .

Maintenant nous pouvons remplir l’image avec une commande Filler (Remplisseur) . La couleur est fixée par la variable color (couleur) de la liste des couleurs . Les coordonnées pour le remplissage seront celles de la souris . Enfin, nous mettrons un picture change flag (drapeau de modification d’image) que nous préparerons dans la fenêtre Global Variables and Functions (Variables et Fonctions Globales). Le drapeau indique que l’image peut être sauvegardée .

Démarrez le programme et essayez de remplir l’image avec une couleur que vous aurez sélectionnée ; vérifiez qu’il vous est impossible de remplir l’image avec du noir .

La structure pour le bouton droit de la souris sera similaire ; nous pouvons donc copier toute la structure concernant le bouton gauche . Dans le test de la condition , nous remplacerons l’élément de test du bouton gauche  par un élément pour le bouton droit . La structure pour les boutons et la sélection de couleur demeure inchangée . La structure de remplissage sera supprimée et remplacée par une structure pick color under mouse cursor (prélever la couleur sous le curseur de la souris). Ici, nous testerons la variable index of color under cursor (index de la couleur sous le curseur) afin de vérifier s’il y a une couleur valide sous le pointeur  (afin d’être certains que ce n’est pas du noir ou une couleur non-standard). Si le pointeur est au dessus d’une couleur valide , nous établirons celle-ci comme nouvelle couleur sélectionnée, recalculant la couleur  à la coordonnée X .

Démarrez le programme et testez si vous pouvez contrôler la sélection de couleurs et d’images avec le bouton droit de la souris de la même façon qu’avec le bouton gauche . D’un clic droit dans l’image, vous pouvez prélever la couleur sous le pointeur et l’établir comme couleur sélectionnée .

Finalement, nous pouvons nous intéresser à la fonction save picture (sauvegarder l’image) . Son contenu figure dans l’image ci-dessous . D’abord, nous testerons si l’image a été modifiée et a besoin d’être sauvegardée . Si c’est le cas , nous utiliserons le nom de l’image (depuis la liste des noms des images) comme active file/folder for writing (fichier/dossier actif pour l’écriture) . Puis nous fixerons la size of file (taille du fichier)  à 0  afin d’être sûrs qu’aucune donnée ancienne ne peut rester dans le fichier derrière (après) l’image . Pour sauvegarder l’image, nous extrairons , par découpage, l’image de la fenêtre  grâce à la fonction retain cutout from sheet as picture (conserver comme image la découpe extraite de la feuille)  , puis nous écrirons l’image dans un fichier en la transférant vers un élément picture (image)  . Finalement, nous désactiverons le picture change flag (drapeau de modification d’image).

En ajoutant la fonction save picture (sauvegarder l’image) après la boucle principale du programme , nous serons sûrs , quand nous quitterons le programme avec la touche Esc (Echap), que l’image aura été sauvegardée . Le programme est à présent totalement fonctionnel et vous pouvez le tester . Vérifiez que les modifications opérées dans les images sont enregistrées à la fois lorsque l’on passe à une autre image et lorsque l’on quitte le programme en appuyant sur la touche Esc (Echap).

Nous pouvons apporter d’autres amélioration à notre programme .  Nous pouvons par exemple afficher dans le titre de la fenêtre le nom de l’image, le numéro de l’image et le nombre total d’images . La structure qui va nous permettre de le faire sera mise au début de la fonction load picture (charger l’image), comme illustré sur l’image qui suit . Ceci aboutira à un texte comme, par exemple, celui-ci :  "Filler(Remplisseur) — Maison (image 4 sur 50)". Vous ne pouvez pas le voir sur l’image ci-dessous, mais il est important de ne pas oublier les espaces aux endroits appropriés dans le texte (après le trait dans "Filler — " et des deux côtés d ‘ " (image " et de " sur ").Nous afficherons le nom de l’image sans son extension, et donc nous tronquerons le nom complet de l’image de ses quatre derniers caractères (le point et l’extension BMP) .

Une autre amélioration : la redéfinition de l’apparence du pointeur . Dans la fenêtre Global Variables and Functions (Variables et Fonctions Globales), préparez quatre items avec des images de pointeurs — deux flèches, une pipette et un remplisseur .

Les images ont des contours noirs, l’encadrement est transparent, et l’intérieur est blanc . A la pointe de la pipette et du pointeur de remplissage, ajouter un point jaune comme indicateur de position (avec inversion des couleurs) . Dans les flèches, l’indicateur de position demeure au centre , ce qui est le réglage par défaut ..

Dans le groupe program initialization (initialisation du programme) , nous utiliserons les commandes setting shape of mouse cursor (définir la forme du curseur de la souris)  pour spécifier l’apparence du pointeur dans les différentes parties de la fenêtre . Nous définirons la pipette pour les champs de sélection de couleur, les flèches pour les boutons de mouvement, et le pointeur de remplissage pour la zone image .

Pour bien comprendre la fonction de la commande qui définit l’apparence du pointeur , vous pouvez vous représenter les zones correspondant à diverses définitions de l’apparence comme des rectangles qui, lorsqu’ils sont ajoutés, écrivent par-dessus les vieilles définitions . Les définitions situées le plus haut sont toujours en vigueur . Si nous ne précisons aucune image pour le pointeur , alors c’est l’apparence standard d’un pointeur de souris dans une fenêtre qui sera utilisée . Si un pointeur coloré est spécifié dans Windows, alors le programme utilisera ce pointeur coloré . Si nous n’indiquons aucune zone, alors la définition du pointeur de la souris vaudra dans l’ensemble de la fenêtre . On peut annuler toutes les définitions en insérant cette commande sans la munir du moindre paramètre .


14. Un méli-mélo de dessins <<< Table des matières >>> 16. Dialogues