diff options
-rw-r--r-- | window.c | 114 |
1 files changed, 101 insertions, 13 deletions
@@ -23,6 +23,10 @@ struct Window int hadj; int vadj; + + gboolean dragging; + int drag_x; + int drag_y; }; static void * @@ -57,8 +61,8 @@ compute_size (Window *window, int *w, int *h) *h = gdk_pixbuf_get_height (window->original) * scale; } -static gboolean -on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, Window *window) +static void +paint_rect (GtkWidget *drawing_area, GdkRectangle *area, Window *window) { GdkPixbuf *tmp; GdkInterpType interp; @@ -67,12 +71,6 @@ on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, Window *window) GdkRectangle image; guint32 color1, color2; - if (!window->original) - return TRUE; - - if (!GTK_WIDGET_DRAWABLE (get_widget (window, "drawing_area"))) - return TRUE; - gdk_window_get_size (drawing_area->window, &window_width, &window_height); image.x = image.y = 0; @@ -84,8 +82,8 @@ on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, Window *window) if (image.height < window_height) image.y = (window_height - image.height) / 2; - if (!gdk_rectangle_intersect (&(expose->area), &image, &dest)) - return TRUE; + if (!gdk_rectangle_intersect (area, &image, &dest)) + return; tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, dest.width, dest.height); @@ -127,6 +125,18 @@ on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, Window *window) tmp, 0, 0, dest.x, dest.y, dest.width, dest.height, GDK_RGB_DITHER_NONE, 0, 0); g_object_unref (tmp); +} + +static gboolean +on_expose (GtkWidget *drawing_area, GdkEventExpose *expose, Window *window) +{ + if (!window->original) + return; + + if (!GTK_WIDGET_DRAWABLE (get_widget (window, "drawing_area"))) + return; + + paint_rect (drawing_area, &(expose->area), window); return TRUE; } @@ -360,6 +370,79 @@ on_scroll (GtkWidget *widget, GdkEventScroll *event, Window *window) return FALSE; } +static gboolean +on_mouse_press (GtkWidget *widget, GdkEventButton *button, Window *window) +{ + if (button->button == 1) + { + if (gdk_pointer_grab (widget->window, FALSE, + GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK, + NULL, NULL, + button->time) == GDK_GRAB_SUCCESS) + { + g_print ("You clicked\n"); + window->dragging = TRUE; + window->drag_x = button->x; + window->drag_y = button->y; + } + else + { + g_print ("grab fail\n"); + } + } +} + +static gboolean +on_mouse_release (GtkWidget *widget, GdkEventButton *button, Window *window) +{ + if (button->button == 1) + { + g_print ("You released\n"); + gdk_pointer_ungrab (button->time); + window->dragging = FALSE; + } +} + +static void +change_adjustment (GtkAdjustment *adj, int dv) +{ + double new = adj->value + dv; + + new = CLAMP (new, adj->lower, adj->upper - adj->page_size); + + gtk_adjustment_set_value (adj, new); + +} + + +static void +on_mouse_motion (GtkWidget *widget, GdkEventMotion *motion, Window *window) +{ + if (window->dragging) + { + GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment (get_widget (window, "scrolled_window")); + GtkAdjustment *hadj = gtk_scrolled_window_get_hadjustment (get_widget (window, "scrolled_window")); + int x, y; + + if (motion->is_hint) + gtk_widget_get_pointer (widget, &x, &y); + else + { + x = motion->x; + y = motion->y; + } + + change_adjustment (hadj, window->drag_x - x); + change_adjustment (vadj, window->drag_y - y); + + gdk_window_process_updates (widget->window, TRUE); + } +} + static void on_various (GtkWidget *widget, Window *window) { @@ -563,8 +646,8 @@ connect_signals (Window *window) typedef struct { - char widget[28]; - char signal[16]; + char widget[32]; + char signal[32]; GCallback callback; } Info; @@ -588,6 +671,9 @@ connect_signals (Window *window) { "drawing_area", "expose_event", G_CALLBACK (on_expose) }, { "drawing_area", "scroll_event", G_CALLBACK (on_scroll) }, { "drawing_area", "size_allocate", G_CALLBACK (on_size_allocate) }, + { "drawing_area", "button_press_event", G_CALLBACK (on_mouse_press) }, + { "drawing_area", "button_release_event", G_CALLBACK (on_mouse_release) }, + { "drawing_area", "motion_notify_event", G_CALLBACK (on_mouse_motion) }, { "menu_open", "activate", G_CALLBACK (on_open) }, { "menu_about", "activate", G_CALLBACK (on_about) }, }; @@ -797,7 +883,9 @@ window_new (App *app) window->xml = glade_xml_new (GLADE_FILE, NULL, NULL); window->app = app; - gtk_widget_add_events (get_widget (window, "drawing_area"), GDK_SCROLL_MASK); + gtk_widget_add_events (get_widget (window, "drawing_area"), + GDK_SCROLL_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); gtk_widget_set_redraw_on_allocate (get_widget (window, "drawing_area"), FALSE); gtk_widget_realize (get_widget (window, "main_window")); |