1 /** 2 * Minimal GTK bindings by Steve Teale 3 * 4 * License: Boost License 1.0 5 * 6 * Warning: 7 * The GTK here is as simple as possible, but not useable for real world code. 8 * At least the following features are missing: 9 * * Drawing should be done to a Pixmap, then clipped onto the GTKWindow 10 * * We always draw everything! Real code should determine the area that needs to be redrawn! 11 * * Resizing support 12 */ 13 module cairo.examples.gtk; 14 15 version(GTK): 16 17 import cairo, cairo.c; 18 import core.stdc.config; 19 import cairo.example; 20 21 struct GtkWidget; 22 struct GtkWindow; 23 struct GtkContainer; 24 struct GdkWindow; 25 enum GTK_WINDOW_TOPLEVEL = 0; 26 enum GTK_WIN_POS_CENTER = 1; 27 28 extern(C) GtkWidget* gtk_window_new (int type); 29 extern(C) GtkWidget* gtk_drawing_area_new(); 30 extern(C) void gtk_container_add(GtkContainer *container, GtkWidget *widget); 31 extern(C) c_ulong g_signal_connect_data (void* instance, 32 const char *detailed_signal, 33 void* c_handler, 34 void* data, 35 void* destroy_data, 36 int connect_flags); 37 extern(C) void gtk_window_set_position (GtkWindow *window, int position); 38 extern(C) void gtk_window_set_default_size (GtkWindow *window, int width, int height); 39 extern(C) void gtk_window_set_title (GtkWindow *window, const char *title); 40 extern(C) void gtk_widget_show_all (GtkWidget *widget); 41 extern(C) void gtk_main(); 42 extern(C) void gtk_init(int*, char***); 43 extern(C) void gtk_main_quit(); 44 extern(C) cairo_t* gdk_cairo_create (GdkWindow *window); 45 extern(C) GdkWindow * gtk_widget_get_window (GtkWidget *widget); 46 47 version(GTK3) 48 { 49 extern(C) nothrow bool on_draw_event(GtkWidget *widget, cairo_t *cr, void* user_data) 50 { 51 import std.stdio; 52 53 try 54 { 55 cairo_reference(cr); 56 auto ctx = Context(cr); 57 (cast(DrawFunction)user_data)(ctx); 58 } 59 catch(Throwable t) 60 { 61 import std.stdio; 62 try{writefln("Unhandled exception: %s", t);}catch(Throwable){} 63 } 64 return false; 65 } 66 } 67 else 68 { 69 extern(C) nothrow bool on_draw_event(GtkWidget *widget, void * event, void* user_data) 70 { 71 import std.stdio; 72 73 try 74 { 75 auto cr = gdk_cairo_create(gtk_widget_get_window (widget)); 76 //cairo_reference(cr); 77 auto ctx = Context(cr); 78 (cast(DrawFunction)user_data)(ctx); 79 } 80 catch(Throwable t) 81 { 82 import std.stdio; 83 try{writefln("Unhandled exception: %s", t);}catch(Throwable){} 84 } 85 return false; 86 } 87 } 88 89 void gtkRunExample(DrawFunction draw) 90 { 91 import std.stdio; 92 version(GTK3) 93 writeln("Using GTK3"); 94 else 95 writeln("Using GTK2"); 96 import core.runtime; 97 int argc = Runtime.cArgs.argc; 98 char** argv = Runtime.cArgs.argv; 99 100 gtk_init(&argc, &argv); 101 102 auto window = cast(GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL); 103 104 auto darea = gtk_drawing_area_new(); 105 gtk_container_add(cast(GtkContainer*)window, darea); 106 107 version(GTK3) 108 { 109 g_signal_connect_data(darea, "draw".ptr, 110 &on_draw_event, draw, null, 1); 111 } 112 else 113 { 114 g_signal_connect_data(darea, "expose_event".ptr, 115 &on_draw_event, draw, null, 1); 116 } 117 g_signal_connect_data(window, "destroy".ptr, 118 >k_main_quit, null, null, 1); 119 120 gtk_window_set_position(window, GTK_WIN_POS_CENTER); 121 gtk_window_set_default_size(window, 400, 400); 122 gtk_window_set_title(window, "GTK window"); 123 124 gtk_widget_show_all(cast(GtkWidget*)window); 125 126 gtk_main(); 127 }