Programmation GTK2 en Pascal/GtkDrawingArea

Programmation GTK2 en Pascal

Présentation

modifier

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
Hiérarchie
GObject
  └─GtkObject
      └─GtkWidget
          └─GtkDrawingArea

Utilisation de base

modifier

Création

modifier

La création est très simple :

function gtk_drawing_area_new : PGtkWidget;

Modification de la taille de la zone de dessin

modifier

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

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

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

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