Une remarque pertinente ? Une critique impertinente ? Un lynchage en règle ? Une invitation sous les tropiques ? Ecrivez-moi ! |
|
Conçu et enseigné tel qu'en lui même, avec pertes, fracas et
humour de qualité supérieure par Christophe Darmangeat dans le M2 PISE du Master MECI (Université Paris 7) |
|
|
Partie 11
Les graphismes
Des graphismes avec VB.NET, il y aurait évidemment
beaucoup à dire, et cela dépasserait largement le cadre de ce cours. Mais
il y a tout de même quelques éléments de base pas si évidents, auxquels je
voudrais consacrer ce chapitre... haut en couleurs, comme il se doit.
1. Couleurs et Propriétés
Même si jusqu'ici nous ne nous sommes pas
particulièrement arrêtés sur cette question, votre proverbial sens de
l'observation vous aura sans doute indiqué que la quasi-totalité des
contrôles possèdent des propriétés désignant leur(s) couleur(s). Ainsi,
Backcolor et ForeColor permettent de modifier respectivement la couleur
d'arrière-plan et la couleur d'avant-plan (celle du texte) des contrôles.
Certes. Mais comment spécifie-t-on une couleur ? Il existe pour cela
deux grands moyens. Lorsque nous réglons une des propriétés de couleurs
à la main, dans la fenêtre design, nous voyons que s'offrent deux
possibilités : soit le choix d'une couleur prédéfinie (via les
onglets web et system), ou la composition d'une couleur entièrement
paramétrable (via l'onglet Personnaliser, suivi d'un clic droit). Eh
bien, le code nous propose globalement la même alternative.
1.1 La structure System.Drawing.Color Elle correspond au choix d'une couleur au sein d'une
palette prédéfinie (web ou system). Ces couleurs sont au nombre de
174, ce qui donne déjà un assez large choix. Les couleurs dites
web
porteront ainsi de jolis noms fleuris, tels LightCoral, Orchid ou
SeaShell. Ces couleurs
s'afficheront donc de la même manière sur toutes les machines où sera
installée l'application. Les couleurs système, elles, porteront des
noms rappelant leur utilisation dans Windows, comme InactiveBorder, ScrollBar
ou Menu. Choisir une couleur system signifie
que cette couleur variera d'une machine à l'autre, selon la manière
dont l'utilisateur aura choisi de personnaliser Windows. Bon, jusque
là, pas de problème.
En ce qui concerne le code, on retombe sur une technique déjà
abordée. Soit on se tape l'intégrale, c'est-à-dire que pour mettre le
fond de Button1 en jaune, on devra écrire quelque chose du genre :
Button1.BackColor = System.Drawing.Color.LemonChiffon
Soit on opte pour la version abrégée, ce qui supposera d'avoir
préalablement "importé" l'espace de noms par :
Imports System.Drawing
Ce qui permettra ensuite de se contenter d'un :
Button1.BackColor = Color.LemonChiffon
1.2 Définir une couleur personnalisée Tout comme on peut le faire à la main, on peut dans le code définir
sa propre couleur. Celle-ci doit respecter la structure des couleurs
prédéfinies, à savoir être composée de quatre octets. La couleur peut
donc être spécifiée par la méthode FromArgb, qui requiert en argument un
ensemble de quatre nombres de 0 à 255 séparés par des points-virgules.
Le premier de ces arguments représente le degré d'opacité de la
couleur (de 0 pour transparent, à 255 pour une couleur pleine). Les
trois nombres suivants représentent dans l'ordre la quantité de rouge,
de vert et de bleu. Ainsi, pour colorer un bouton en bleu, écrira-t-on :
Button1.BackColor = Color.FromArgb(255, 0, 0, 255)
Il est toutefois possible de passer la méthode FromArgb
uniquement avec trois paramètres. Dans ce cas, ceux-ci désignent
les couleurs, et par défaut, l'opacité est considérée comme maximale.
Et voilà de quoi s'amuser, bien qu'on soit censé avoir
passé l'âge des coloriages.
Voilà un exercice où le traitement des couleurs
sera l'occasion d'une bonne révision sur les collections et les
événements. Gymnastique mentale garantie...
2. Images et Contrôles
Là encore, il n'aura pas échappé à vos yeux de lynx qu'en mode
design, un certain nombre de contrôles acceptent volontiers que leur
fond soit constitué d'une image. C'est notamment le cas pour les Form et
les Buttons, avec la propriété BackgroundImage.
Nous parlerons plus loin de la manière dont on peut affecter cette
propriété par du code. En attendant, il faut dire quelques mots des
contrôles dont le rôle spécifique est de contenir des images.
2.1 La classe ImageList (rappel) Il y a tout d'abord l'ImageList, dont nous avons déjà fait la
connaissance. Je rappelle que ce contrôle :
Il ne peut donc servir que de "réservoir à images" pour les autres
contrôles, qui iront y puiser les images nécessaires au fur et à mesure
de leurs besoins, durant l'exécution de l'application.
2.2 La classe PictureBox Si l'on veut qu'à un endroit de la Form, se trouve
telle ou telle image, alors il faut utiliser le contrôle adéquat, à savoir
PictureBox. Celui-ci possède une propriété Image, qui indiquera son
contenu. Le contrôle PictureBox prend en charge les principaux formats
d'image : JPEG, GIF, Bitmap, métafichiers (WMF), icônes... Il ne gère
pas, en revanche, les vidéos.
Une propriété notable des PictureBox est
SizeMode. Celle-ci peut
prendre quatre valeurs, qui modifieront les propriétés du contrôle et/ou
de l'image dans le cas où ceux-ci ne possèdent pas les mêmes dimensions
:
Remarque limpide :
Le contrôle PictureBox est incapable de gérer les images transparentes, quelle que soit la manière dont on s'y prend, et même si l'image qu'il contient est elle-même transparente. Moralité, si l'on veut pouvoir gérer des images transparentes (et cela peut arriver plus souvent qu'on ne le croit), on sera obligé de faire appel à un autre contrôle que PictureBox. Rendez-vous dans ce chapitre pour en savoir plus.
3. Gérer intelligemment les images
On en vient à présent à la manière de gérer les images dans une
application. Il y a deux stratégies, possédant chacune leurs avantages
et leurs inconvénients, qu'il vaut mieux connaître avant de faire des
choix discutables et pénalisants.
Le premier mouvement, lorsqu'on veut utiliser des images, c'est
évidemment de les intégrer aux contrôles (PictureBox, ImageList, Form,
etc. en mode design, donc en tant que propriétés par défaut de ces
contrôles. C'est la manière la plus simple de procéder, qui va avoir
deux conséquences :
Voilà pourquoi cette technique, si elle a l'avantage de la facilité,
est à réserver aux petites images, et qu'elle doit être proscrite dès
qu'on a affaire à des images volumineuses et/ou trop nombreuses.
Pour celles-ci, comment faire ? Pour s'y retrouver, il va falloir en
quelque sorte raisonner à rebrousse-poil, en partant du but à atteindre
pour remonter vers les moyens à mettre en oeuvre. C'est parti :
Au final, que voulons-nous ? Que le(s) fichier(s) image(s) dont
l'exécutable va avoir besoin soient stockés indépendamment de cet
exécutable, afin de conserver à celui-ci la sveltesse qui fait toute son
élégance.
Pour cela, il faut que l'exécutable contienne une ou plusieurs
instructions donnant l'ordre de charger tel ou tel fichier image dans
tel ou tel contrôle. Cette instruction est la méthode FromFile, qui
appartient à la classe Image. On écrira ainsi :
PictureBox1.Image = Image.FromFile (nom du fichier)
C'est là qu'arrive un petit souci. Le nom du fichier, cela
sous-entend de devoir préciser le
répertoire dans lequel il se trouve. Dans le cas contraire, cette
instruction serait incapable de fonctionner et provoquerait une
erreur. Il faut donc absolument :
Pour le moment, nous ne traiterons que du premier point. Le second,
ce sera pour un peu plus tard, dans le chapitre
13 de ce cours.
Prenons un exemple. Admettons que nous choisissions de regrouper
toutes les images dont notre application aura besoin au cours de
son exécution, dans un sous-répertoire de l'exécutable, appelé "Pic".
Le chargement du fichier "Charlot.jpg" dans le contrôle
Portrait devra donc dire ; "va chercher le fichier
Charlot.jpg
qui se trouve dans le répertoire Pic, celui-ci étant un sous-répertoire de l'endroit
où tu es en train de t'exécuter." Ceci peut s'effectuer de la
manière suivante (j'ai découpé le code en plusieurs instructions plus
plus de lisibilité, mais on pourrait bien sûr aller plus vite :
Actuel = Directory.GetCurentDirectory
Fic = Actuel & "\Pic\Charlot.jpg" Portrait.Image = Image.FromFile (Fic) Et voilà. Je rappelle que cette méthode suppose de paramétrer l'installation
pour que le sous-répertoire Pic soit automatiquement créé et que
le fichier Charlot.jpg y soit déposé. Mais le gros avantage, c'est
que l'exécutable reste d'une taille raisonnable.
Remarque
généraliste :
Cette technique doit être mise en oeuvre, avec quelques aménagements, pour tous les fichiers annexes dont une application peut avoir besoin : fichiers de données, vidéos, sons, etc.
4. Deux mots sur les méthodes graphiques
Je ne m'étendrai pas sur cet aspect, qui ne peut intéresser que des
programmeurs se lançant des un type d'applications un peu spécialisé.
Mais autant savoir que VB.Net donne facilement accès aux classes et
aux méthodes de Windows qui permettent de tracer directement des points
et des formes à l'écran.
Le premier point à savoir est que l'on peut, par du code, tracer aussi
bien des graphismes en mode Bitmap (c'est à dire en faisant
du point par point) qu'en mode vectoriel (en raisonnant sur des formes).
Le second point est qu'on peut dessiner à l'écran (sur un contrôle),
à l'imprimante (sur un objet PrintDocument) ou en mémoire (le résultat
restant ensuite disponible pour n'importe quel usage, y compris être
enregistré dans un fichier).
En mode Bitmap, on peut ainsi positionner des
points, des rectangles, des ellipses, tracer des traits paramétrables
avec un crayon ou un pinceau virtuel, faire des dégradés.
En mode vectoriel, il sera possible de tracer des lignes, des polygones,
des cercles, des ellipses, des courbes de Bézier...
Bon, bref, j'avais dit que je ne serais pas long sur
le sujet, eh bien je vais tenir parole.
|