[33mcommit bc8952403cd9c53c6f21f65d1bc513b059bfaaaa[m
Author: Vitaly Minko <vitaly.minko@gmail.com>
Date:   Wed Oct 27 23:39:32 2010 +0400

    Add auto scrolling when drag-and-dropping contacts (#619858).

[1mdiff --git a/libempathy-gtk/empathy-individual-view.c b/libempathy-gtk/empathy-individual-view.c[m
[1mindex 2ad0fc0..2e88ac2 100644[m
[1m--- a/libempathy-gtk/empathy-individual-view.c[m
[1m+++ b/libempathy-gtk/empathy-individual-view.c[m
[36m@@ -93,6 +93,15 @@[m [mtypedef struct[m
 typedef struct[m
 {[m
   EmpathyIndividualView *view;[m
[32m+[m[32m  guint timeout_id;[m
[32m+[m[32m  /* Distance between mouse pointer and the nearby border. Negative when[m
[32m+[m[32m     scrolling updards.*/[m
[32m+[m[32m  gint distance;[m
[32m+[m[32m} AutoScrollData;[m
[32m+[m
[32m+[m[32mtypedef struct[m
[32m+[m[32m{[m
[32m+[m[32m  EmpathyIndividualView *view;[m
   FolksIndividual *individual;[m
   gboolean remove;[m
 } ShowActiveData;[m
[36m@@ -549,6 +558,32 @@[m [mindividual_view_drag_motion_cb (DragMotionData *data)[m
   return FALSE;[m
 }[m
 [m
[32m+[m[32m/* Minimum distance between the mouse pointer and a horizontal border when we[m
[32m+[m[32m   start auto scrolling. */[m
[32m+[m[32m#define AUTO_SCROLL_MARGIN_SIZE 20[m
[32m+[m[32m/* How far to scroll per one tick. */[m
[32m+[m[32m#define AUTO_SCROLL_PITCH       10[m
[32m+[m
[32m+[m[32mstatic gboolean[m
[32m+[m[32mindividual_view_auto_scroll_cb (AutoScrollData *data)[m
[32m+[m[32m{[m
[32m+[m	[32mGtkAdjustment         *adj;[m
[32m+[m	[32mgdouble                new_value;[m
[32m+[m
[32m+[m	[32madj = gtk_scrollable_get_vadjustment (GTK_TREE_VIEW (data->view));[m
[32m+[m
[32m+[m	[32mif (data->distance < 0)[m
[32m+[m		[32mnew_value = adj->value - AUTO_SCROLL_PITCH;[m
[32m+[m	[32melse[m
[32m+[m		[32mnew_value = adj->value + AUTO_SCROLL_PITCH;[m
[32m+[m
[32m+[m	[32mnew_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);[m
[32m+[m
[32m+[m	[32mgtk_adjustment_set_value (adj, new_value);[m
[32m+[m
[32m+[m	[32mreturn TRUE;[m
[32m+[m[32m}[m
[32m+[m
 static gboolean[m
 individual_view_drag_motion (GtkWidget *widget,[m
     GdkDragContext *context,[m
[36m@@ -561,6 +596,7 @@[m [mindividual_view_drag_motion (GtkWidget *widget,[m
   GdkAtom target;[m
   GtkTreeIter iter;[m
   static DragMotionData *dm = NULL;[m
[32m+[m[32m  static AutoScrollData as;[m
   GtkTreePath *path;[m
   gboolean is_row;[m
   gboolean is_different = FALSE;[m
[36m@@ -570,6 +606,24 @@[m [mindividual_view_drag_motion (GtkWidget *widget,[m
   priv = GET_PRIV (EMPATHY_INDIVIDUAL_VIEW (widget));[m
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));[m
 [m
[32m+[m[32m  if (!as.view)[m
[32m+[m[32m      as.view = EMPATHY_INDIVIDUAL_VIEW (widget);[m
[32m+[m
[32m+[m[32m  if (as.timeout_id)[m
[32m+[m[32m    g_source_remove (as.timeout_id);[m
[32m+[m
[32m+[m[32m  if (y < AUTO_SCROLL_MARGIN_SIZE ||[m
[32m+[m[32m      y > (widget->allocation.height - AUTO_SCROLL_MARGIN_SIZE))[m
[32m+[m[32m    {[m
[32m+[m[32m      if (y < AUTO_SCROLL_MARGIN_SIZE)[m
[32m+[m[32m        as.distance = MIN (-y, -1);[m
[32m+[m[32m      else[m
[32m+[m[32m        as.distance = MAX (widget->allocation.height - y, 1);[m
[32m+[m
[32m+[m[32m      as.timeout_id = g_timeout_add (10 * ABS (as.distance),[m
[32m+[m[32m          (GSourceFunc) individual_view_auto_scroll_cb, &as);[m
[32m+[m[32m    }[m
[32m+[m
   is_row = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),[m
       x, y, &path, NULL, NULL, NULL);[m
 [m
