summaryrefslogtreecommitdiff
path: root/window.c
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2008-04-28 00:17:16 -0400
committerSøren Sandmann <sandmann@redhat.com>2008-04-28 00:17:16 -0400
commit80801e6558ff00e3b1594d65d3510025a0350ed0 (patch)
treeddfe2b03cf62a42a475034eee06ebf78ad8b11de /window.c
parente20ab123d0771ed2e560280f7141cf8b81434ee5 (diff)
Support dragging
Diffstat (limited to 'window.c')
-rw-r--r--window.c114
1 files changed, 101 insertions, 13 deletions
diff --git a/window.c b/window.c
index caaeeca..4bf6bf0 100644
--- a/window.c
+++ b/window.c
@@ -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"));