Programmation GTK2 en Pascal/GtkDrawingArea

Un livre de Wikilivres.
Programmation GTK2 en Pascal

Présentation[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

Hiérarchie
GObject
  └─GtkObject
      └─GtkWidget
          └─GtkDrawingArea

Utilisation de base[modifier | modifier le wikicode]

Création[modifier | modifier le wikicode]

La création est très simple :

function gtk_drawing_area_new : PGtkWidget;

Modification de la taille de la zone de dessin[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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