/*----------------------------------------------------------------------------*/ #include /** * From, * https://developer.gnome.org/gtk3/stable/ch01s05.html * * - my rewrite to understand these new gtk3 stuffs (cairo surface! :o) **/ /*----------------------------------------------------------------------------*/ #define MY1APP_FULL "org.my1.gtktest" #define MY1APP_NAME "GTK Test" /*----------------------------------------------------------------------------*/ typedef struct _my1gtk_app_t { int stat; cairo_surface_t *surf; GtkApplication *main; GtkWidget *gwin; GtkWidget *view; GtkWidget *draw; } my1gtk_app_t; /*----------------------------------------------------------------------------*/ void my1gtk_app_destroy(gpointer data) { my1gtk_app_t* gapp = (my1gtk_app_t*)data; if (gapp->surf) cairo_surface_destroy(gapp->surf); } /*----------------------------------------------------------------------------*/ gboolean my1gtk_app_draw_cb(GtkWidget *widget,cairo_t *cr,gpointer data) { my1gtk_app_t* gapp = (my1gtk_app_t*)data; cairo_set_source_surface(cr,gapp->surf,0,0); cairo_paint(cr); return FALSE; } /*----------------------------------------------------------------------------*/ void clear_surface(my1gtk_app_t* gapp) { cairo_t *cr = cairo_create(gapp->surf); cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint(cr); cairo_destroy(cr); } /*----------------------------------------------------------------------------*/ gboolean my1gtk_app_conf_cb(GtkWidget *widget, GdkEventConfigure *event, gpointer data) { my1gtk_app_t* gapp = (my1gtk_app_t*)data; if (gapp->surf) cairo_surface_destroy(gapp->surf); gapp->surf = gdk_window_create_similar_surface( gtk_widget_get_window(widget), CAIRO_CONTENT_COLOR, gtk_widget_get_allocated_width(widget), gtk_widget_get_allocated_height (widget)); clear_surface(gapp); return TRUE; } /*----------------------------------------------------------------------------*/ void draw_brush(GtkWidget *widget, gdouble x, gdouble y, gpointer data) { my1gtk_app_t* gapp = (my1gtk_app_t*)data; cairo_t *cr = cairo_create (gapp->surf); cairo_rectangle (cr,x-3,y-3,6,6); cairo_fill (cr); cairo_destroy (cr); gtk_widget_queue_draw_area(widget,x-3,y-3,6,6); } /*----------------------------------------------------------------------------*/ gboolean my1gtk_app_motion_cb(GtkWidget *widget, GdkEventMotion *event, gpointer data) { my1gtk_app_t* gapp = (my1gtk_app_t*)data; if (!gapp->surf) return FALSE; if (event->state&GDK_BUTTON1_MASK) draw_brush(widget,event->x,event->y,data); return TRUE; } /*----------------------------------------------------------------------------*/ gboolean my1gtk_app_bpress_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) { my1gtk_app_t* gapp = (my1gtk_app_t*)data; if (!gapp->surf) return FALSE; if (event->button == GDK_BUTTON_PRIMARY) draw_brush (widget,event->x,event->y,data); else if (event->button == GDK_BUTTON_SECONDARY) { clear_surface(gapp); gtk_widget_queue_draw(widget); } return TRUE; } /*----------------------------------------------------------------------------*/ void my1gtk_app_activate(GtkApplication *app, gpointer data) { my1gtk_app_t* gapp = (my1gtk_app_t*)data; /** app === gapp->main! assert?*/ gapp->gwin = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(gapp->gwin),MY1APP_NAME); g_signal_connect_swapped(gapp->gwin,"destroy", G_CALLBACK(my1gtk_app_destroy),data); gtk_container_set_border_width(GTK_CONTAINER(gapp->gwin),4); gapp->view = gtk_frame_new(0x0); gtk_frame_set_shadow_type(GTK_FRAME(gapp->view),GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(gapp->gwin),gapp->view); gapp->draw = gtk_drawing_area_new(); /* set a minimum size */ gtk_widget_set_size_request(gapp->draw,100,100); gtk_container_add(GTK_CONTAINER(gapp->view),gapp->draw); g_signal_connect(gapp->draw,"draw", G_CALLBACK(my1gtk_app_draw_cb),data); g_signal_connect(gapp->draw,"configure-event", G_CALLBACK(my1gtk_app_conf_cb),data); g_signal_connect(gapp->draw,"motion-notify-event", G_CALLBACK(my1gtk_app_motion_cb),data); g_signal_connect(gapp->draw,"button-press-event", G_CALLBACK(my1gtk_app_bpress_cb),data); gtk_widget_set_events(gapp->draw,gtk_widget_get_events(gapp->draw) | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); gtk_widget_show_all(gapp->gwin); } /*----------------------------------------------------------------------------*/ void my1gtk_app_init(my1gtk_app_t* gapp) { gapp->stat = 0; gapp->surf = 0x0; gapp->main = gtk_application_new(MY1APP_FULL,G_APPLICATION_FLAGS_NONE); g_signal_connect(gapp->main,"activate", G_CALLBACK(my1gtk_app_activate),(gpointer)gapp); } /*----------------------------------------------------------------------------*/ void my1gtk_app_exec(my1gtk_app_t* gapp, int argc, char* argv[]) { gapp->stat = g_application_run(G_APPLICATION(gapp->main),argc,argv); g_object_unref(gapp->main); } /*----------------------------------------------------------------------------*/ int main (int argc, char **argv) { my1gtk_app_t gapp; my1gtk_app_init(&gapp); my1gtk_app_exec(&gapp,argc,argv); return gapp.stat; } /*----------------------------------------------------------------------------*/