/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #+ #+ Glade / Gtk Programming #+ #+ Copyright (C) 2019 by Kevin C. O'Kane #+ #+ Kevin C. O'Kane #+ kc.okane@gmail.com #+ https://www.cs.uni.edu/~okane #+ http://threadsafebooks.com/ #+ #+ This program is free software; you can redistribute it and/or modify #+ it under the terms of the GNU General Public License as published by #+ the Free Software Foundation; either version 2 of the License, or #+ (at your option) any later version. #+ #+ This program is distributed in the hope that it will be useful, #+ but WITHOUT ANY WARRANTY; without even the implied warranty of #+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #+ GNU General Public License for more details. #+ #+ You should have received a copy of the GNU General Public License #+ along with this program; if not, write to the Free Software #+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #+ #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include GtkWidget *window; GtkWidget *fixed1; GtkWidget *draw1; GtkWidget *clear; GtkWidget *Red; GtkWidget *Green; GtkWidget *Blue; GtkWidget *White; GtkBuilder *builder; static void draw_brush (GtkWidget *widget, gdouble x, gdouble y); struct Point { int x; int y; double red, green, blue; struct Point *next; } *p1, *p2, *start; double red, green, blue; void on_destroy(); int main(int argc, char *argv[]) { p1 = p2 = start = NULL; red = green = blue = 0.0; gtk_init(&argc, &argv); // init Gtk builder = gtk_builder_new_from_file ("part1.glade"); window = GTK_WIDGET(gtk_builder_get_object(builder, "window")); g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), NULL); gtk_builder_connect_signals(builder, NULL); fixed1 = GTK_WIDGET(gtk_builder_get_object(builder, "fixed1")); draw1 = GTK_WIDGET(gtk_builder_get_object(builder, "draw1")); clear = GTK_WIDGET(gtk_builder_get_object(builder, "clear")); Red = GTK_WIDGET(gtk_builder_get_object(builder, "Red")); Green = GTK_WIDGET(gtk_builder_get_object(builder, "Green")); Blue = GTK_WIDGET(gtk_builder_get_object(builder, "Blue")); White = GTK_WIDGET(gtk_builder_get_object(builder, "White")); g_object_unref(builder); gtk_widget_set_events(draw1, GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK); gtk_window_set_keep_above (GTK_WINDOW(window), TRUE); gtk_widget_show(window); gtk_main(); return EXIT_SUCCESS; } void on_destroy() { gtk_main_quit(); } gboolean on_draw1_draw (GtkWidget *widget, cairo_t *cr, gpointer data) { guint width, height; width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); cairo_set_line_width(cr, 1.0); if (start == NULL) return FALSE; int old_x = start->x; int old_y = start->y; p1 = start->next; while ( p1 != NULL ) { cairo_set_source_rgb(cr, p1->red, p1->green, p1->blue); cairo_move_to (cr, (double) old_x, (double) old_y); cairo_line_to (cr, (double) p1->x, (double) p1->y); cairo_stroke (cr); old_x = p1->x; old_y = p1->y; p1 = p1 ->next; } return FALSE; } gboolean on_draw1_button_press_event (GtkWidget *widget, GdkEventButton *event) { draw_brush (widget, event->x, event->y); return TRUE; } void on_clear_clicked(GtkWidget *b1) { p1 = start; while (p1) { p2 = p1 -> next; free(p1); p1 = p2; } start = NULL; gtk_widget_queue_draw (draw1); } gboolean on_draw1_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer data) { if (event->state & GDK_BUTTON1_MASK ) draw_brush (widget, event->x, event->y); return TRUE; } static void draw_brush (GtkWidget *widget, gdouble x, gdouble y) { p1 = malloc (sizeof(struct Point)); if (p1 == NULL) { printf("out of memory\n"); abort(); } p1->x = x; p1->y = y; p1->red = red; p1->green = green; p1->blue = blue; p1->next = start; start = p1; gtk_widget_queue_draw (draw1); } void on_Red_clicked(GtkWidget *b1) { red = 1.0; green = 0.0; blue = 0.0; } void on_Green_clicked(GtkWidget *b1) { red = 0.0; green = 1.0; blue = 0.0; } void on_Blue_clicked(GtkWidget *b1) { red = 0.0; green = 0.0; blue = 1.0; } void on_White_clicked(GtkWidget *b1) { red = 1.0; green = 1.0; blue = 1.0; }