Created
March 19, 2017 22:08
-
-
Save loganek/156b6b9ce2333fd7d389f74c093a92b4 to your computer and use it in GitHub Desktop.
This file contains 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
#include <gtk/gtk.h> | |
static cairo_surface_t *tmp_surface = NULL; | |
static cairo_surface_t *base_surface = NULL; | |
static gdouble ax; | |
static gdouble ay; | |
static void | |
clear_surface (cairo_surface_t *surface) | |
{ | |
cairo_t *cr; | |
cr = cairo_create (surface); | |
cairo_set_source_rgb (cr, 1, 1, 1); | |
cairo_paint (cr); | |
cairo_destroy (cr); | |
} | |
static void | |
init_surface(cairo_surface_t **surface, GtkWidget *widget) | |
{ | |
if (*surface) | |
cairo_surface_destroy (*surface); | |
*surface = 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 (*surface); | |
} | |
static gboolean | |
configure_event_cb (GtkWidget *widget, | |
GdkEventConfigure *event, | |
gpointer data) | |
{ | |
init_surface(&tmp_surface, widget); | |
init_surface(&base_surface, widget); | |
return TRUE; | |
} | |
static gboolean | |
draw_cb (GtkWidget *widget, | |
cairo_t *cr, | |
gpointer data) | |
{ | |
cairo_set_source_surface (cr, tmp_surface, 0, 0); | |
cairo_paint (cr); | |
return FALSE; | |
} | |
static void | |
draw_brush (GtkWidget *widget, | |
gdouble x, | |
gdouble y) | |
{ | |
cairo_t * cr = cairo_create (tmp_surface); | |
cairo_move_to (cr, ax, ay); | |
cairo_line_to (cr, x, y); | |
cairo_stroke (cr); | |
cairo_destroy (cr); | |
gtk_widget_queue_draw_area (widget, 0, 0, 100, 100); | |
} | |
static gboolean | |
button_press_event_cb (GtkWidget *widget, | |
GdkEventButton *event, | |
gpointer data) | |
{ | |
cairo_t *cr = cairo_create (tmp_surface); | |
cairo_set_source_surface (cr, base_surface, 0, 0); | |
cairo_paint (cr); | |
cairo_destroy (cr); | |
ax = event->x; ay = event->y; | |
draw_brush (widget, event->x, event->y); | |
return TRUE; | |
} | |
static gboolean | |
button_release_event_cb (GtkWidget *widget, | |
GdkEventButton *event, | |
gpointer data) | |
{ | |
cairo_t *cr = cairo_create (base_surface); | |
cairo_set_source_surface (cr, tmp_surface, 0, 0); | |
cairo_paint (cr); | |
cairo_destroy (cr); | |
return TRUE; | |
} | |
static gboolean | |
motion_notify_event_cb (GtkWidget *widget, | |
GdkEventMotion *event, | |
gpointer data) | |
{ | |
if (event->state & GDK_BUTTON1_MASK) | |
{ | |
cairo_t *cr = cairo_create (tmp_surface); | |
cairo_set_source_surface (cr, base_surface, 0, 0); | |
cairo_paint (cr); | |
cairo_destroy (cr); | |
draw_brush (widget, event->x, event->y); | |
} | |
return TRUE; | |
} | |
static void | |
close_window (void) | |
{ | |
gtk_main_quit (); | |
} | |
static void | |
activate (GtkApplication *app, | |
gpointer user_data) | |
{ | |
GtkWidget *window; | |
GtkWidget *frame; | |
GtkWidget *drawing_area; | |
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); | |
gtk_container_set_border_width (GTK_CONTAINER (window), 8); | |
frame = gtk_frame_new (NULL); | |
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); | |
gtk_container_add (GTK_CONTAINER (window), frame); | |
drawing_area = gtk_drawing_area_new (); | |
gtk_widget_set_size_request (drawing_area, 100, 100); | |
gtk_container_add (GTK_CONTAINER (frame), drawing_area); | |
g_signal_connect (drawing_area, "draw", | |
G_CALLBACK (draw_cb), NULL); | |
g_signal_connect (drawing_area,"configure-event", | |
G_CALLBACK (configure_event_cb), NULL); | |
g_signal_connect (drawing_area, "motion-notify-event", | |
G_CALLBACK (motion_notify_event_cb), NULL); | |
g_signal_connect (drawing_area, "button-press-event", | |
G_CALLBACK (button_press_event_cb), NULL); | |
g_signal_connect (drawing_area, "button-release-event", | |
G_CALLBACK (button_release_event_cb), NULL); | |
gtk_widget_set_events (drawing_area, gtk_widget_get_events (drawing_area) | |
| GDK_BUTTON_PRESS_MASK | |
| GDK_BUTTON_RELEASE_MASK | |
| GDK_POINTER_MOTION_MASK); | |
gtk_widget_show_all (window); | |
} | |
int | |
main (int argc, | |
char **argv) | |
{ | |
GtkApplication *app; | |
int status; | |
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE); | |
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