diff --git a/c/gtk3/hide-n-seek/hidenseek.c b/c/gtk3/hide-n-seek/hidenseek.c new file mode 100644 index 0000000..4a98243 --- /dev/null +++ b/c/gtk3/hide-n-seek/hidenseek.c @@ -0,0 +1,138 @@ +#include + + +const double pi = 3.141592653589793; + +GtkWidget *window; +GtkWidget *fixed; +GtkWidget *shape; +gboolean play = TRUE; +gboolean hidden = FALSE; + +int x = 58; +int y = 75; +double mouse_x = 0.0; +double mouse_y = 0.0; + + +gboolean timeout(gpointer data) { + if (play) { + int w, h; + gtk_widget_get_size_request(shape, &w, &h); + + if (x + w/2 < mouse_x) x += 5; + if (x + w/2 > mouse_x) x -= 5; + if (y + h/2 < mouse_y) y += 5; + if (y + h/2 > mouse_y) y -= 5; + + gtk_fixed_move(GTK_FIXED(fixed), shape, x, y); + } + return TRUE; +} + +gboolean restart_timeout(gpointer data) { + play = TRUE; + gdk_window_set_cursor(gtk_widget_get_window(window), NULL); + gtk_widget_queue_draw(shape); + return FALSE; +} + +gboolean shape_draw(GtkWidget *widget, cairo_t *cr, gpointer data) { + int w, h; + gtk_widget_get_size_request(widget, &w, &h); + + cairo_set_source_rgba(cr, 0, 0, 1, 1); + cairo_fill(cr); + + cairo_arc(cr, 10, 10, 10, -pi, -pi/2); + cairo_line_to(cr, w-10, 0); + cairo_arc(cr, w-10, 10, 10, -pi/2, 0); + cairo_line_to(cr, w, h-10); + cairo_arc(cr, w-10, h-10, 10, 0, pi/2); + cairo_line_to(cr, 10, h); + cairo_arc(cr, 10, h-10, 10, pi/2, pi); + cairo_line_to(cr, 0, 10); + + if (play) cairo_set_source_rgba(cr, 1, 1, 1, 1); + else cairo_set_source_rgba(cr, 1, 0, 0, 1); + cairo_fill_preserve(cr); + + cairo_set_source_rgba(cr, 0, 0, 0, 1); + cairo_stroke(cr); + + return TRUE; +} + +gboolean shape_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) { + play = FALSE; + + GdkCursor *cursor = gdk_cursor_new_from_name(gtk_widget_get_display(widget), "none"); + gdk_window_set_cursor(gtk_widget_get_window(window), cursor); + g_object_unref(cursor); + + gtk_widget_queue_draw(shape); + g_timeout_add(500, restart_timeout, NULL); + return TRUE; +} + +gboolean window_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) { + if (!hidden) { + mouse_x = event->x; + mouse_y = event->y; + } + return TRUE; +} + +gboolean shelter_enter(GtkWidget *widget, GdkEvent *event, gpointer data) { + hidden = TRUE; + return TRUE; +} + +gboolean shelter_leave(GtkWidget *widget, GdkEvent *event, gpointer data) { + hidden = FALSE; + return TRUE; +} + +void activate(GtkApplication* app, gpointer data) { + window = gtk_application_window_new(app); + g_signal_connect(window, "motion-notify-event", G_CALLBACK(window_motion), NULL); + gtk_widget_add_events(window, GDK_POINTER_MOTION_MASK); + gtk_window_set_default_size(GTK_WINDOW(window), 700, 500); + + fixed = gtk_fixed_new(); + gtk_container_add(GTK_CONTAINER(window), fixed); + + shape = gtk_drawing_area_new(); + g_signal_connect(shape, "draw", G_CALLBACK(shape_draw), NULL); + g_signal_connect(shape, "motion-notify-event", G_CALLBACK(shape_motion), NULL); + gtk_widget_add_events(shape, GDK_POINTER_MOTION_MASK); + gtk_widget_set_size_request(shape, 86, 61); + gtk_fixed_put(GTK_FIXED(fixed), shape, x, y); + + GtkWidget *button1 = gtk_button_new_with_label("Sweet Home"); + g_signal_connect(button1, "enter-notify-event", G_CALLBACK(shelter_enter), NULL); + g_signal_connect(button1, "leave-notify-event", G_CALLBACK(shelter_leave), NULL); + gtk_widget_add_events(button1, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); + gtk_widget_set_size_request(button1, 249, 154); + gtk_fixed_put(GTK_FIXED(fixed), button1, 48, 296); + + GtkWidget *button2 = gtk_button_new_with_label("Another Safe Place"); + g_signal_connect(button2, "enter-notify-event", G_CALLBACK(shelter_enter), NULL); + g_signal_connect(button2, "leave-notify-event", G_CALLBACK(shelter_leave), NULL); + gtk_widget_add_events(button2, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); + gtk_widget_set_size_request(button2, 216, 131); + gtk_fixed_put(GTK_FIXED(fixed), button2, 344, 131); + + gtk_widget_show_all(window); + + g_timeout_add(10, timeout, NULL); +} + +int main(int argc, char **argv) { + GtkApplication *application = gtk_application_new(NULL, 0); + g_signal_connect(application, "activate", G_CALLBACK(activate), NULL); + int status = g_application_run(G_APPLICATION(application), argc, argv); + g_object_unref(application); + return status; +} +