Backfold debian/changelog
[hildon] / hildon / hildon-pannable-area.c
index b3f0aee..f3f9eff 100644 (file)
@@ -57,6 +57,7 @@
 #define SCROLL_FADE_TIMEOUT 100
 #define MOTION_EVENTS_PER_SECOND 25
 #define CURSOR_STOPPED_TIMEOUT 80
 #define SCROLL_FADE_TIMEOUT 100
 #define MOTION_EVENTS_PER_SECOND 25
 #define CURSOR_STOPPED_TIMEOUT 80
+#define MAX_SPEED_THRESHOLD 250
 #define PANNABLE_MAX_WIDTH 788
 #define PANNABLE_MAX_HEIGHT 378
 
 #define PANNABLE_MAX_WIDTH 788
 #define PANNABLE_MAX_HEIGHT 378
 
@@ -75,7 +76,7 @@ struct _HildonPannableAreaPrivate {
   gdouble ex;          /* Used to store mouse co-ordinates of the last */
   gdouble ey;          /* motion event in acceleration mode */
   gboolean enabled;
   gdouble ex;          /* Used to store mouse co-ordinates of the last */
   gdouble ey;          /* motion event in acceleration mode */
   gboolean enabled;
-  gboolean clicked;
+  gboolean button_pressed;
   guint32 last_time;   /* Last event time, to stop infinite loops */
   gint last_type;
   gboolean last_in;
   guint32 last_time;   /* Last event time, to stop infinite loops */
   gint last_type;
   gboolean last_in;
@@ -369,7 +370,7 @@ hildon_pannable_area_class_init (HildonPannableAreaClass * klass)
                                                        "Minimum scroll velocity",
                                                        "Minimum distance the child widget should scroll "
                                                        "per 'frame', in pixels per frame.",
                                                        "Minimum scroll velocity",
                                                        "Minimum distance the child widget should scroll "
                                                        "per 'frame', in pixels per frame.",
-                                                       0, G_MAXDOUBLE, 20,
+                                                       0, G_MAXDOUBLE, 10,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT));
 
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT));
 
@@ -440,7 +441,7 @@ hildon_pannable_area_class_init (HildonPannableAreaClass * klass)
                                                      "Threshold to consider a motion event an scroll",
                                                      "Amount of pixels to consider a motion event an scroll, if it is less"
                                                       "it is a click detected incorrectly by the touch screen.",
                                                      "Threshold to consider a motion event an scroll",
                                                      "Amount of pixels to consider a motion event an scroll, if it is less"
                                                       "it is a click detected incorrectly by the touch screen.",
-                                                     0, G_MAXUINT, 6,
+                                                     0, G_MAXUINT, 25,
                                                      G_PARAM_READWRITE |
                                                      G_PARAM_CONSTRUCT));
 
                                                      G_PARAM_READWRITE |
                                                      G_PARAM_CONSTRUCT));
 
@@ -470,7 +471,7 @@ hildon_pannable_area_class_init (HildonPannableAreaClass * klass)
                                                      "Multiplier of the calculated speed",
                                                      "Force applied to the movement, multiplies the calculated speed of the"
                                                       "user movement the cursor in the screen",
                                                      "Multiplier of the calculated speed",
                                                      "Force applied to the movement, multiplies the calculated speed of the"
                                                       "user movement the cursor in the screen",
-                                                     0, G_MAXUINT, 120,
+                                                     0, G_MAXUINT, 50,
                                                      G_PARAM_READWRITE |
                                                      G_PARAM_CONSTRUCT));
 
                                                      G_PARAM_READWRITE |
                                                      G_PARAM_CONSTRUCT));
 
@@ -630,7 +631,7 @@ hildon_pannable_area_init (HildonPannableArea * area)
   area->priv = priv;
 
   priv->moved = FALSE;
   area->priv = priv;
 
   priv->moved = FALSE;
-  priv->clicked = FALSE;
+  priv->button_pressed = FALSE;
   priv->last_time = 0;
   priv->last_type = 0;
   priv->vscroll_visible = TRUE;
   priv->last_time = 0;
   priv->last_type = 0;
   priv->vscroll_visible = TRUE;
@@ -647,7 +648,8 @@ hildon_pannable_area_init (HildonPannableArea * area)
   priv->scroll_indicator_timeout = 0;
   priv->motion_event_scroll_timeout = 0;
   priv->scroll_indicator_event_interrupt = 0;
   priv->scroll_indicator_timeout = 0;
   priv->motion_event_scroll_timeout = 0;
   priv->scroll_indicator_event_interrupt = 0;
-  priv->scroll_delay_counter = priv->scrollbar_fade_delay;
+  priv->scroll_delay_counter = 0;
+  priv->scrollbar_fade_delay = 0;
   priv->scroll_to_x = -1;
   priv->scroll_to_y = -1;
   priv->first_drag = TRUE;
   priv->scroll_to_x = -1;
   priv->scroll_to_y = -1;
   priv->first_drag = TRUE;
@@ -823,7 +825,20 @@ hildon_pannable_area_set_property (GObject * object,
     priv->sps = g_value_get_uint (value);
     break;
   case PROP_PANNING_THRESHOLD:
     priv->sps = g_value_get_uint (value);
     break;
   case PROP_PANNING_THRESHOLD:
-    priv->panning_threshold = g_value_get_uint (value);
+    {
+      GtkSettings *settings = gtk_settings_get_default ();
+      GtkSettingsValue svalue = { NULL, { 0, }, };
+
+      priv->panning_threshold = g_value_get_uint (value);
+
+      /* insure gtk dnd is the same we are using, not allowed
+         different thresholds in the same application */
+      svalue.origin = "panning_threshold";
+      g_value_init (&svalue.value, G_TYPE_LONG);
+      g_value_set_long (&svalue.value, priv->panning_threshold);
+      gtk_settings_set_property_value (settings, "gtk-dnd-drag-threshold", &svalue);
+      g_value_unset (&svalue.value);
+    }
     break;
   case PROP_SCROLLBAR_FADE_DELAY:
     /* convert to miliseconds */
     break;
   case PROP_SCROLLBAR_FADE_DELAY:
     /* convert to miliseconds */
@@ -1469,22 +1484,15 @@ static void
 hildon_pannable_area_initial_effect (GtkWidget * widget)
 {
   HildonPannableAreaPrivate *priv = HILDON_PANNABLE_AREA (widget)->priv;
 hildon_pannable_area_initial_effect (GtkWidget * widget)
 {
   HildonPannableAreaPrivate *priv = HILDON_PANNABLE_AREA (widget)->priv;
-  gboolean hscroll_visible, vscroll_visible;
-
-  if (priv->initial_hint) {
 
 
-    vscroll_visible = (priv->vadjust->upper - priv->vadjust->lower >
-                       priv->vadjust->page_size);
-    hscroll_visible = (priv->hadjust->upper - priv->hadjust->lower >
-                       priv->hadjust->page_size);
+  if (priv->vscroll_visible || priv->hscroll_visible) {
 
 
-    if (priv->vscroll_visible || priv->hscroll_visible) {
+    priv->scroll_indicator_event_interrupt = 0;
+    priv->scroll_delay_counter = priv->scrollbar_fade_delay;
 
 
-      priv->scroll_indicator_event_interrupt = 0;
-      priv->scroll_delay_counter = priv->scrollbar_fade_delay;
+    hildon_pannable_area_launch_fade_timeout (HILDON_PANNABLE_AREA (widget), 1.0);
 
 
-      hildon_pannable_area_launch_fade_timeout (HILDON_PANNABLE_AREA (widget), 1.0);
-    }
+    priv->initial_effect = FALSE;
   }
 }
 
   }
 }
 
@@ -1554,8 +1562,8 @@ hildon_pannable_area_scroll_indicator_fade(HildonPannableArea * area)
   HildonPannableAreaPrivate *priv = area->priv;
 
   /* if moving do not fade out */
   HildonPannableAreaPrivate *priv = area->priv;
 
   /* if moving do not fade out */
-  if (((ABS (priv->vel_y)>1.0)||
-       (ABS (priv->vel_x)>1.0))&&(!priv->clicked)) {
+  if (((ABS (priv->vel_y)>priv->vmin)||
+       (ABS (priv->vel_x)>priv->vmin))&&(!priv->button_pressed)) {
 
     return TRUE;
   }
 
     return TRUE;
   }
@@ -1614,6 +1622,10 @@ hildon_pannable_area_expose_event (GtkWidget * widget,
   GdkColor scroll_color = widget->style->fg[GTK_STATE_INSENSITIVE];
 #endif
 
   GdkColor scroll_color = widget->style->fg[GTK_STATE_INSENSITIVE];
 #endif
 
+  if (G_UNLIKELY ((priv->initial_hint) && (priv->initial_effect))) {
+    hildon_pannable_area_initial_effect (widget);
+  }
+
   if (gtk_bin_get_child (GTK_BIN (widget))) {
 
     if (priv->scroll_indicator_alpha > 0.1) {
   if (gtk_bin_get_child (GTK_BIN (widget))) {
 
     if (priv->scroll_indicator_alpha > 0.1) {
@@ -1702,13 +1714,6 @@ hildon_pannable_area_expose_event (GtkWidget * widget,
 
   }
 
 
   }
 
-  if (G_UNLIKELY (priv->initial_effect)) {
-
-    hildon_pannable_area_initial_effect (widget);
-
-    priv->initial_effect = FALSE;
-  }
-
   return GTK_WIDGET_CLASS (hildon_pannable_area_parent_class)->expose_event (widget, event);
 }
 
   return GTK_WIDGET_CLASS (hildon_pannable_area_parent_class)->expose_event (widget, event);
 }
 
@@ -1826,7 +1831,7 @@ hildon_pannable_area_button_press_cb (GtkWidget * widget,
   priv->scroll_to_x = -1;
   priv->scroll_to_y = -1;
 
   priv->scroll_to_x = -1;
   priv->scroll_to_y = -1;
 
-  if (priv->clicked && priv->child) {
+  if (priv->button_pressed && priv->child) {
     /* Widget stole focus on last click, send crossing-out event */
     synth_crossing (priv->child, 0, 0, event->x_root, event->y_root,
                    event->time, FALSE);
     /* Widget stole focus on last click, send crossing-out event */
     synth_crossing (priv->child, 0, 0, event->x_root, event->y_root,
                    event->time, FALSE);
@@ -1846,7 +1851,7 @@ hildon_pannable_area_button_press_cb (GtkWidget * widget,
   else
     priv->child = NULL;
 
   else
     priv->child = NULL;
 
-  priv->clicked = TRUE;
+  priv->button_pressed = TRUE;
 
   /* Stop scrolling on mouse-down (so you can flick, then hold to stop) */
   priv->vel_x = 0;
 
   /* Stop scrolling on mouse-down (so you can flick, then hold to stop) */
   priv->vel_x = 0;
@@ -2021,7 +2026,7 @@ hildon_pannable_axis_scroll (HildonPannableArea *area,
 
     gtk_adjustment_set_value (adjust, dist);
   } else {
 
     gtk_adjustment_set_value (adjust, dist);
   } else {
-    if (!priv->clicked) {
+    if (!priv->button_pressed) {
 
       /* When the overshoot has started we continue for
        * PROP_BOUNCE_STEPS more steps into the overshoot before we
 
       /* When the overshoot has started we continue for
        * PROP_BOUNCE_STEPS more steps into the overshoot before we
@@ -2147,7 +2152,7 @@ hildon_pannable_area_timeout (HildonPannableArea * area)
     return FALSE;
   }
 
     return FALSE;
   }
 
-  if (!priv->clicked) {
+  if (!priv->button_pressed) {
     /* Decelerate gradually when pointer is raised */
     if ((!priv->overshot_dist_y) &&
         (!priv->overshot_dist_x)) {
     /* Decelerate gradually when pointer is raised */
     if ((!priv->overshot_dist_y) &&
         (!priv->overshot_dist_x)) {
@@ -2264,7 +2269,7 @@ hildon_pannable_area_motion_notify_cb (GtkWidget * widget,
   if (gtk_bin_get_child (GTK_BIN (widget)) == NULL)
     return TRUE;
 
   if (gtk_bin_get_child (GTK_BIN (widget)) == NULL)
     return TRUE;
 
-  if ((!priv->enabled) || (!priv->clicked) ||
+  if ((!priv->enabled) || (!priv->button_pressed) ||
       ((event->time == priv->last_time) && (priv->last_type == 2))) {
     gdk_window_get_pointer (widget->window, NULL, NULL, 0);
     return TRUE;
       ((event->time == priv->last_time) && (priv->last_type == 2))) {
     gdk_window_get_pointer (widget->window, NULL, NULL, 0);
     return TRUE;
@@ -2500,7 +2505,7 @@ hildon_pannable_area_button_release_cb (GtkWidget * widget,
 
   if  (((event->time == priv->last_time) && (priv->last_type == 3))
        || (gtk_bin_get_child (GTK_BIN (widget)) == NULL)
 
   if  (((event->time == priv->last_time) && (priv->last_type == 3))
        || (gtk_bin_get_child (GTK_BIN (widget)) == NULL)
-       || (!priv->clicked) || (!priv->enabled) || (event->button != 1))
+       || (!priv->button_pressed) || (!priv->enabled) || (event->button != 1))
     return TRUE;
 
   priv->scroll_indicator_event_interrupt = 0;
     return TRUE;
 
   priv->scroll_indicator_event_interrupt = 0;
@@ -2559,15 +2564,15 @@ hildon_pannable_area_button_release_cb (GtkWidget * widget,
     }
   }
 
     }
   }
 
-  if ((ABS (priv->vel_y) > 1.0)||
-      (ABS (priv->vel_x) > 1.0)) {
+  if ((ABS (priv->vel_y) > priv->vmin)||
+      (ABS (priv->vel_x) > priv->vmin)) {
     priv->scroll_indicator_alpha = 1.0;
   }
 
   hildon_pannable_area_launch_fade_timeout (HILDON_PANNABLE_AREA (widget),
                                             priv->scroll_indicator_alpha);
 
     priv->scroll_indicator_alpha = 1.0;
   }
 
   hildon_pannable_area_launch_fade_timeout (HILDON_PANNABLE_AREA (widget),
                                             priv->scroll_indicator_alpha);
 
-  priv->clicked = FALSE;
+  priv->button_pressed = FALSE;
 
   if (priv->mode == HILDON_PANNABLE_AREA_MODE_AUTO ||
       priv->mode == HILDON_PANNABLE_AREA_MODE_ACCEL) {
 
   if (priv->mode == HILDON_PANNABLE_AREA_MODE_AUTO ||
       priv->mode == HILDON_PANNABLE_AREA_MODE_ACCEL) {
@@ -2586,6 +2591,12 @@ hildon_pannable_area_button_release_cb (GtkWidget * widget,
     if ((ABS (priv->vel_y) >= priv->vmin) ||
         (ABS (priv->vel_x) >= priv->vmin)) {
 
     if ((ABS (priv->vel_y) >= priv->vmin) ||
         (ABS (priv->vel_x) >= priv->vmin)) {
 
+      if (ABS (priv->vel_x) > MAX_SPEED_THRESHOLD)
+        priv->vel_x = (priv->vel_x > 0) ? priv->vmax : -priv->vmax;
+
+      if (ABS (priv->vel_y) > MAX_SPEED_THRESHOLD)
+        priv->vel_y = (priv->vel_y > 0) ? priv->vmax : -priv->vmax;
+
       if (!priv->idle_id)
         priv->idle_id = gdk_threads_add_timeout ((gint) (1000.0 / (gdouble) priv->sps),
                                                  (GSourceFunc)
       if (!priv->idle_id)
         priv->idle_id = gdk_threads_add_timeout ((gint) (1000.0 / (gdouble) priv->sps),
                                                  (GSourceFunc)
@@ -2743,17 +2754,43 @@ hildon_pannable_area_remove (GtkContainer *container, GtkWidget *child)
   GTK_CONTAINER_CLASS (hildon_pannable_area_parent_class)->remove (container, child);
 }
 
   GTK_CONTAINER_CLASS (hildon_pannable_area_parent_class)->remove (container, child);
 }
 
+/**
+ * This method calculates a factor necessary to determine the initial distance
+ * to jump in hildon_pannable_area_scroll_to(). For fixed time and frames per
+ * second, we know in how many frames 'n' we need to reach the destination
+ * point. We know that, for a distance d,
+ *
+ *   d = d_0 + d_1 + ... + d_n
+ *
+ * where d_i is the distance travelled in the i-th frame and decel_factor is
+ * the deceleration factor. This can be rewritten as
+ *
+ *   d = d_0 + (d_0 * decel_factor) + ... + (d_n-1 * decel_factor),
+ *
+ * since the distance travelled on each frame is the distance travelled in the
+ * previous frame reduced by the deceleration factor. Reducing this and
+ * factoring d_0 out, we get
+ *
+ *   d = d_0 (1 + decel_factor + ... + decel_factor^(n-1)).
+ *
+ * Since the sum is independent of the distance to be travelled, we can define
+ * vel_factor as
+ *
+ *   vel_factor = 1 + decel_factor + ... + decel_factor^(n-1).
+ *
+ * That's the gem we calculate in this method.
+ **/
 static void
 hildon_pannable_calculate_vel_factor (HildonPannableArea * self)
 {
   HildonPannableAreaPrivate *priv = self->priv;
 static void
 hildon_pannable_calculate_vel_factor (HildonPannableArea * self)
 {
   HildonPannableAreaPrivate *priv = self->priv;
-  gfloat fct = 0;
+  gfloat fct = 1;
   gfloat fct_i = 1;
   gint i, n;
 
   n = ceil (priv->sps * priv->scroll_time);
 
   gfloat fct_i = 1;
   gint i, n;
 
   n = ceil (priv->sps * priv->scroll_time);
 
-  for (i = 0; i < n && fct_i >= RATIO_TOLERANCE; i++) {
+  for (i = 1; i < n && fct_i >= RATIO_TOLERANCE; i++) {
     fct_i *= priv->decel;
     fct += fct_i;
   }
     fct_i *= priv->decel;
     fct += fct_i;
   }