diff --git a/exec b/exec index bc4e8b4..63bf388 100755 Binary files a/exec and b/exec differ diff --git a/main.c b/main.c index e60d282..9ba033e 100755 --- a/main.c +++ b/main.c @@ -12,33 +12,180 @@ button = gtk_button_new_with_label (" I "); n fois gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1); n fois */ +//main.c: Dans la fonction « resize_cb »: +//main.c:48:7: attention: « gdk_surface_create_similar_surface » est obsolète [-Wdeprecated-declarations] +// 48 | surface = gdk_surface_create_similar_surface (gtk_native_get_surface (gtk_widget_get_native (widget)) +// Deprecated since: 4.12 > Create a suitable cairo image surface yourself. + #include -static void print (GtkWidget *widget, gpointer data) {g_print (data);} +/* Surface to store current scribbles */ +static cairo_surface_t *surface = NULL; -static void activate (GtkApplication *app, gpointer user_data) { +static void +clear_surface (void) +{ + cairo_t *cr; + + cr = cairo_create (surface); + + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + + cairo_destroy (cr); +} + +/* Create a new surface of the appropriate size to store our scribbles */ +static void +resize_cb (GtkWidget *widget, + int width, + int height, + gpointer data) +{ + if (surface) + { + cairo_surface_destroy (surface); + surface = NULL; + } + + if (gtk_native_get_surface (gtk_widget_get_native (widget))) + { + surface = gdk_surface_create_similar_surface (gtk_native_get_surface (gtk_widget_get_native (widget)), + CAIRO_CONTENT_COLOR, + gtk_widget_get_width (widget), + gtk_widget_get_height (widget)); + + /* Initialize the surface to white */ + clear_surface (); + } +} + +/* Redraw the screen from the surface. Note that the draw + * callback receives a ready-to-be-used cairo_t that is already + * clipped to only draw the exposed areas of the widget + */ +static void +draw_cb (GtkDrawingArea *drawing_area, + cairo_t *cr, + int width, + int height, + gpointer data) +{ + cairo_set_source_surface (cr, surface, 0, 0); + cairo_paint (cr); +} + +/* Draw a rectangle on the surface at the given position */ +static void +draw_brush (GtkWidget *widget, + double x, + double y) +{ + cairo_t *cr; + + /* Paint to the surface, where we store our state */ + cr = cairo_create (surface); + + cairo_rectangle (cr, x - 3, y - 3, 6, 6); + cairo_fill (cr); + + cairo_destroy (cr); + + /* Now invalidate the drawing area. */ + gtk_widget_queue_draw (widget); +} + +static double start_x; +static double start_y; + +static void +drag_begin (GtkGestureDrag *gesture, + double x, + double y, + GtkWidget *area) +{ + start_x = x; + start_y = y; + + draw_brush (area, x, y); +} + +static void +drag_update (GtkGestureDrag *gesture, + double x, + double y, + GtkWidget *area) +{ + draw_brush (area, start_x + x, start_y + y); +} + +static void +drag_end (GtkGestureDrag *gesture, + double x, + double y, + GtkWidget *area) +{ + draw_brush (area, start_x + x, start_y + y); +} + +static void +pressed (GtkGestureClick *gesture, + int n_press, + double x, + double y, + GtkWidget *area) +{ + clear_surface (); + gtk_widget_queue_draw (area); +} + +static void +close_window (void) +{ + if (surface) + cairo_surface_destroy (surface); +} + +static void +activate (GtkApplication *app, + gpointer user_data) +{ GtkWidget *window; - GtkWidget *grid; - GtkWidget *button; + GtkWidget *frame; + GtkWidget *drawing_area; + GtkGesture *drag; + GtkGesture *press; window = gtk_application_window_new (app); - gtk_window_set_title (GTK_WINDOW (window), "Window"); + gtk_window_set_title (GTK_WINDOW (window), "Drawing Area"); - grid = gtk_grid_new (); - gtk_window_set_child (GTK_WINDOW (window), grid); + g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL); - button = gtk_button_new_with_label (" I "); - g_signal_connect (button, "clicked", G_CALLBACK (print), "I'm n°1\n"); - gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1); + frame = gtk_frame_new (NULL); + gtk_window_set_child (GTK_WINDOW (window), frame); - button = gtk_button_new_with_label (" II "); - g_signal_connect (button, "clicked", G_CALLBACK (print), "I'm n°2\n"); - gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1); + drawing_area = gtk_drawing_area_new (); + /* set a minimum size */ + gtk_widget_set_size_request (drawing_area, 100, 100); - button = gtk_button_new_with_label ("Quit"); - g_signal_connect (button, "clicked", G_CALLBACK (print), "bye !...\n"); - g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window); - gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1); + gtk_frame_set_child (GTK_FRAME (frame), drawing_area); + + gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw_cb, NULL, NULL); + + g_signal_connect_after (drawing_area, "resize", G_CALLBACK (resize_cb), NULL); + + drag = gtk_gesture_drag_new (); + gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY); + gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (drag)); + g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), drawing_area); + g_signal_connect (drag, "drag-update", G_CALLBACK (drag_update), drawing_area); + g_signal_connect (drag, "drag-end", G_CALLBACK (drag_end), drawing_area); + + press = gtk_gesture_click_new (); + gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (press), GDK_BUTTON_SECONDARY); + gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (press)); + + g_signal_connect (press, "pressed", G_CALLBACK (pressed), drawing_area); gtk_window_present (GTK_WINDOW (window)); } @@ -58,3 +205,4 @@ main (int argc, return status; } +