Created
March 9, 2023 06:34
-
-
Save angstyloop/3bc856751f0312993db76665b64a4f38 to your computer and use it in GitHub Desktop.
Official GTK4 example 3 (https://docs.gtk.org/gtk4/getting_started.html)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** example-3.c | |
| * | |
| * COMPILE | |
| * | |
| * gcc `pkg-config --cflags gtk4` -o example-3 example-3.c `pkg-config --libs gtk4` | |
| * | |
| * EXAMPLE | |
| * | |
| * ./example-3 | |
| * | |
| * SOURCE | |
| * | |
| * https://docs.gtk.org/gtk4/getting_started.html | |
| */ | |
| #include <gtk/gtk.h> | |
| #if GLIB_CHECK_VERSION(2, 74, 0) | |
| static int app_flags = G_APPLICATION_DEFAULT_FLAGS; | |
| #else | |
| static int app_flags = G_APPLICATION_FLAGS_NONE; | |
| #endif | |
| static cairo_surface_t *surface = NULL; | |
| 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); | |
| } | |
| 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)); | |
| clear_surface (); | |
| } | |
| } | |
| 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); | |
| } | |
| static void | |
| draw_brush (GtkWidget *widget, | |
| double x, | |
| double y) | |
| { | |
| cairo_t *cr; | |
| cr = cairo_create (surface); | |
| cairo_rectangle (cr, x - 3, y - 3, 6, 6); | |
| cairo_fill (cr); | |
| cairo_destroy (cr); | |
| 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, | |
| double x, | |
| double y, | |
| GtkWidget *area) | |
| { | |
| clear_surface (); | |
| gtk_widget_queue_draw (area); | |
| } | |
| static void | |
| close_window(GtkApplication *app, | |
| gpointer user_data) | |
| { | |
| if (surface) | |
| cairo_surface_destroy (surface); | |
| } | |
| static void | |
| activate (GtkApplication *app, | |
| gpointer user_data) | |
| { | |
| GtkWidget *window, *frame, *drawing_area, *drag, *press; | |
| window = gtk_application_window_new (app); | |
| gtk_window_set_title (GTK_WINDOW (window), "Drawing Area"); | |
| g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL); | |
| frame = gtk_frame_new (NULL); | |
| gtk_window_set_child (GTK_WINDOW (window), frame); | |
| drawing_area = gtk_drawing_area_new (); | |
| gtk_widget_set_size_request (drawing_area, 100, 100); | |
| 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_WIDGET (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_WIDGET (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_widget_show (window); | |
| } | |
| int | |
| main (int argc, char **argv) | |
| { | |
| GtkApplication *app; | |
| int status; | |
| app = gtk_application_new ("org.gtk.example", app_flags); | |
| g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); | |
| status = g_application_run (G_APPLICATION (app), argc, argv); | |
| g_object_unref (app); | |
| return status; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment