| Programmation GTK2 en Pascal |
|
Présentation
Le contrôle GtkDrawingArea est un contrôle basique qui n'a pas d'aspect par défaut et dont l'affichage est complètement géré par nos soins. Il permet donc d'afficher des images, des formes, et / ou du texte.
Hiérarchie
| Hiérarchie |
GObject
└─GtkObject
└─GtkWidget
└─GtkDrawingArea |
Utilisation de base
Création
La création est très simple :
function gtk_drawing_area_new : PGtkWidget;
Modification de la taille de la zone de dessin
Une fonction permet de choisir ou de modifier la taille de la zone de dessin :
procedure gtk_drawing_area_size(darea : PGtkDrawingArea; width : gint; height : gint);
Utilisation des signaux
Le signal realize est émis lors du premier affichage de la GtkDrawingArea.
Le signal expose_event est émis lorsque celle-ci à besoin d'un rafraichissement (lorsque la fenêtre devient cachée par une autre, puis revient au premier plan par exemple).
Il faut connecter ces deux signaux à des fonctions qui vont réaliser le dessin. Plusieurs méthodes sont possibles : soit on dessine systématiquement et à ce moment on peut se permettre de ne connecter que expose_event, soit on dessine dans une image (pixmap) à l'appel du signal realize puis lors de l'appel expose_event on ne redessine que l'image mémorisée.
Le dessin
Il va être réalisé avec des fonctions du Gdk, Gimp Drawing Kit, les outils de dessin de Gimp. Cf le chapitre Dessiner avec le Gdk.
Programme exemple
On va dessiner dans une zone de dessin une ligne, puis un rectangle, une moitié de ballon de rugby et enfin un quadrilatère, tout cela en noir sur fond blanc.
Voilà le fichier gtk019.pas :
program gtk019;
uses glib2, gtk2, gdk2;
var
Pixmap : PGdkPixmap;
procedure OnZoneDessinRealize(APWidget : PGtkwidget; AData : PGdkEventConfigure); cdecl;
var
Quadrilatere : array[0..3] of TGdkPoint;
begin
Pixmap := gdk_pixmap_new(APWidget^.window,
APWidget^.allocation.width, APWidget^.allocation.height, -1);
gdk_draw_rectangle(Pixmap, APWidget^.style^.white_gc, 1, 0, 0,
APWidget^.allocation.width, APWidget^.allocation.height);
gdk_draw_line(Pixmap, APWidget^.style^.black_gc, 0, 0, 50, 50);
gdk_draw_rectangle(Pixmap, APWidget^.style^.black_gc, 1, 50, 50, 100, 10);
gdk_draw_arc(Pixmap, APWidget^.style^.black_gc, 1, 101, 101, 100, 50, 0, 180*64);
Quadrilatere[0].x := 200;
Quadrilatere[0].y := 20;
Quadrilatere[1].x := Quadrilatere[0].x + 70;
Quadrilatere[1].y := Quadrilatere[0].y;
Quadrilatere[2].x := Quadrilatere[1].x + 50;
Quadrilatere[2].y := Quadrilatere[0].y + 70;
Quadrilatere[3].x := Quadrilatere[0].x/50;
Quadrilatere[3].y := Quadrilatere[2].y;
gdk_draw_polygon(Pixmap, APWidget^.style^.black_gc, 1, Quadrilatere, 4);
gtk_widget_queue_draw(APWidget);
end;
procedure OnZoneDessinRafraichir(APWidget : PGtkwidget; AData : PGdkEventExpose); cdecl;
begin
gdk_draw_drawable(APWidget^.window,
APWidget^.style^.fg_gc[GTK_WIDGET_STATE(APWidget)], Pixmap,
AData^.area.x, AData^.area.y, AData^.area.x, AData^.area.y, -1, -1);
end;
var
pFenetre : PGtkWidget;
pZoneDessin : PGtkWidget;
begin
gtk_init(@argc, @argv);
pFenetre := gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(pFenetre), 320, 200);
gtk_container_set_border_width(GTK_CONTAINER(pFenetre), 4);
gtk_window_set_title(GTK_WINDOW(pFenetre), 'Gtk019 : Zone de dessin');
gtk_signal_connect(pGTKOBJECT(pFenetre), 'destroy', GTK_SIGNAL_FUNC(@gtk_main_quit), NULL);
pZoneDessin := gtk_drawing_area_new;
gtk_container_add(GTK_CONTAINER(pFenetre), pZoneDessin);
g_signal_connect(pGTKOBJECT(pZoneDessin), 'realize', GTK_SIGNAL_FUNC(@OnZoneDessinRealize), NULL);
g_signal_connect(pGTKOBJECT(pZoneDessin), 'expose_event', GTK_SIGNAL_FUNC(@OnZoneDessinRafraichir), NULL);
gtk_widget_show_all(pFenetre);
gtk_main;
end.
Voilà ce que donne l'exécution du programme gtk019 :

|
Visuels : GtkLabel ~ GtkImage ~ GtkStatusBar ~ GtkProgressBar ~ GtkDrawingArea |