X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=hildon%2Fhildon-pannable-area.c;h=219810a3bf27851977f833c74e31ec54965cee4d;hb=3c231d0b4be8f81e72cd80cdc2383b6bc2ede7be;hp=abf52233ad58bb7b72aa3fa032e9d9da4f1075d7;hpb=69f848cefd5e192eea88458551a7c0c8ec0b4654;p=hildon diff --git a/hildon/hildon-pannable-area.c b/hildon/hildon-pannable-area.c index abf5223..219810a 100644 --- a/hildon/hildon-pannable-area.c +++ b/hildon/hildon-pannable-area.c @@ -56,8 +56,8 @@ #define RATIO_TOLERANCE 0.000001 #define SCROLL_FADE_TIMEOUT 100 #define MOTION_EVENTS_PER_SECOND 25 -#define CURSOR_STOPPED_TIMEOUT 80 -#define MAX_SPEED_THRESHOLD 250 +#define CURSOR_STOPPED_TIMEOUT 200 +#define MAX_SPEED_THRESHOLD 290 #define PANNABLE_MAX_WIDTH 788 #define PANNABLE_MAX_HEIGHT 378 @@ -78,6 +78,7 @@ struct _HildonPannableAreaPrivate { gboolean enabled; gboolean button_pressed; guint32 last_time; /* Last event time, to stop infinite loops */ + guint32 last_press_time; gint last_type; gboolean last_in; gboolean moved; @@ -97,6 +98,8 @@ struct _HildonPannableAreaPrivate { guint direction_error_margin; gdouble vel_x; gdouble vel_y; + gdouble old_vel_x; + gdouble old_vel_y; GdkWindow *child; gint child_width; gint child_height; @@ -198,6 +201,7 @@ static void hildon_pannable_area_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec); +static void hildon_pannable_area_remove_timeouts (GtkWidget * widget); static void hildon_pannable_area_dispose (GObject * object); static void hildon_pannable_area_realize (GtkWidget * widget); static void hildon_pannable_area_unrealize (GtkWidget * widget); @@ -432,7 +436,7 @@ hildon_pannable_area_class_init (HildonPannableAreaClass * klass) "Deceleration multiplier", "The multiplier used when decelerating when in " "acceleration scrolling mode.", - 0, 1.0, 0.93, + 0, 1.0, 0.85, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); @@ -472,7 +476,7 @@ hildon_pannable_area_class_init (HildonPannableAreaClass * klass) "Time before starting to fade the scrollbar", "Time the scrollbar is going to be visible if the widget is not in" "action in miliseconds", - 0, G_MAXUINT, 3000, + 0, G_MAXUINT, 1000, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); @@ -710,6 +714,7 @@ hildon_pannable_area_init (HildonPannableArea * area) priv->moved = FALSE; priv->button_pressed = FALSE; priv->last_time = 0; + priv->last_press_time = 0; priv->last_type = 0; priv->vscroll_visible = TRUE; priv->hscroll_visible = TRUE; @@ -721,6 +726,8 @@ hildon_pannable_area_init (HildonPannableArea * area) priv->idle_id = 0; priv->vel_x = 0; priv->vel_y = 0; + priv->old_vel_x = 0; + priv->old_vel_y = 0; priv->scroll_indicator_alpha = 0.0; priv->scroll_indicator_timeout = 0; priv->motion_event_scroll_timeout = 0; @@ -983,21 +990,7 @@ hildon_pannable_area_dispose (GObject * object) HildonPannableAreaPrivate *priv = HILDON_PANNABLE_AREA (object)->priv; GtkWidget *child = gtk_bin_get_child (GTK_BIN (object)); - if (priv->idle_id) { - g_signal_emit (object, pannable_area_signals[PANNING_FINISHED], 0); - g_source_remove (priv->idle_id); - priv->idle_id = 0; - } - - if (priv->scroll_indicator_timeout){ - g_source_remove (priv->scroll_indicator_timeout); - priv->scroll_indicator_timeout = 0; - } - - if (priv->motion_event_scroll_timeout){ - g_source_remove (priv->motion_event_scroll_timeout); - priv->motion_event_scroll_timeout = 0; - } + hildon_pannable_area_remove_timeouts (GTK_WIDGET (object)); if (child) { g_signal_handlers_disconnect_by_func (child, @@ -1092,6 +1085,29 @@ hildon_pannable_area_realize (GtkWidget * widget) gdk_gc_copy (priv->scrollbars_gc, widget->style->fg_gc[GTK_STATE_INSENSITIVE]); } + +static void +hildon_pannable_area_remove_timeouts (GtkWidget * widget) +{ + HildonPannableAreaPrivate *priv = HILDON_PANNABLE_AREA (widget)->priv; + + if (priv->idle_id) { + g_signal_emit (widget, pannable_area_signals[PANNING_FINISHED], 0); + g_source_remove (priv->idle_id); + priv->idle_id = 0; + } + + if (priv->scroll_indicator_timeout){ + g_source_remove (priv->scroll_indicator_timeout); + priv->scroll_indicator_timeout = 0; + } + + if (priv->motion_event_scroll_timeout){ + g_source_remove (priv->motion_event_scroll_timeout); + priv->motion_event_scroll_timeout = 0; + } +} + static void hildon_pannable_area_unrealize (GtkWidget * widget) { @@ -1099,6 +1115,8 @@ hildon_pannable_area_unrealize (GtkWidget * widget) priv = HILDON_PANNABLE_AREA (widget)->priv; + hildon_pannable_area_remove_timeouts (widget); + if (priv->event_window != NULL) { gdk_window_set_user_data (priv->event_window, NULL); gdk_window_destroy (priv->event_window); @@ -1604,9 +1622,11 @@ hildon_pannable_area_launch_fade_timeout (HildonPannableArea * area, if (!priv->scroll_indicator_timeout) priv->scroll_indicator_timeout = - gdk_threads_add_timeout (SCROLL_FADE_TIMEOUT, - (GSourceFunc) hildon_pannable_area_scroll_indicator_fade, - area); + gdk_threads_add_timeout_full (G_PRIORITY_HIGH_IDLE + 20, + SCROLL_FADE_TIMEOUT, + (GSourceFunc) hildon_pannable_area_scroll_indicator_fade, + area, + NULL); } static void @@ -1868,9 +1888,9 @@ hildon_pannable_area_get_topmost (GdkWindow * window, tx, ty, mask); if (!selected_window) { if (tx) - *tx = x; + *tx = x-wx; if (ty) - *ty = y; + *ty = y-wy; selected_window = child; } } else { @@ -1935,6 +1955,7 @@ hildon_pannable_area_button_press_cb (GtkWidget * widget, priv->scroll_indicator_alpha); priv->last_time = event->time; + priv->last_press_time = event->time; priv->last_type = 1; priv->scroll_to_x = -1; @@ -1963,6 +1984,8 @@ hildon_pannable_area_button_press_cb (GtkWidget * widget, priv->button_pressed = TRUE; /* Stop scrolling on mouse-down (so you can flick, then hold to stop) */ + priv->old_vel_x = priv->vel_x; + priv->old_vel_y = priv->vel_y; priv->vel_x = 0; priv->vel_y = 0; if (priv->idle_id) { @@ -2394,9 +2417,10 @@ hildon_pannable_area_motion_event_scroll (HildonPannableArea *area, priv->motion_x = 0; priv->motion_y = 0; - priv->motion_event_scroll_timeout = gdk_threads_add_timeout - ((gint) (1000.0 / (gdouble) MOTION_EVENTS_PER_SECOND), - (GSourceFunc) hildon_pannable_area_motion_event_scroll_timeout, area); + priv->motion_event_scroll_timeout = gdk_threads_add_timeout_full + (G_PRIORITY_HIGH_IDLE + 20, + (gint) (1000.0 / (gdouble) MOTION_EVENTS_PER_SECOND), + (GSourceFunc) hildon_pannable_area_motion_event_scroll_timeout, area, NULL); } } @@ -2501,10 +2525,11 @@ hildon_pannable_area_check_move (HildonPannableArea *area, (priv->mode != HILDON_PANNABLE_AREA_MODE_AUTO)) { if (!priv->idle_id) - priv->idle_id = gdk_threads_add_timeout ((gint) - (1000.0 / (gdouble) priv->sps), - (GSourceFunc) - hildon_pannable_area_timeout, area); + priv->idle_id = gdk_threads_add_timeout_full + (G_PRIORITY_HIGH_IDLE + 20, + (gint)(1000.0 / (gdouble) priv->sps), + (GSourceFunc) + hildon_pannable_area_timeout, area, NULL); } } } @@ -2682,6 +2707,7 @@ hildon_pannable_area_button_release_cb (GtkWidget * widget, gint x, y; gdouble dx, dy; GdkWindow *child; + gboolean force_fast = TRUE; if (((event->time == priv->last_time) && (priv->last_type == 3)) || (gtk_bin_get_child (GTK_BIN (widget)) == NULL) @@ -2731,6 +2757,32 @@ hildon_pannable_area_button_release_cb (GtkWidget * widget, priv->button_pressed = FALSE; + /* if widget was moving fast in the panning, increase speed even more */ + if ((event->time - priv->last_press_time < 125) && + ((ABS (priv->old_vel_x) > priv->vmin) || + (ABS (priv->old_vel_y) > priv->vmin)) && + ((ABS (priv->old_vel_x) > 40) || + (ABS (priv->old_vel_y) > 40))) + { + gint symbol = 0; + + if (priv->vel_x != 0) + symbol = ((priv->vel_x * priv->old_vel_x) > 0) ? 1 : -1; + + priv->vel_x = symbol * + (priv->old_vel_x + ((priv->old_vel_x > 0) ? priv->vmax : -priv->vmax)); + + symbol = 0; + + if (priv->vel_y != 0) + symbol = ((priv->vel_y * priv->old_vel_y) > 0) ? 1 : -1; + + priv->vel_y = symbol * + (priv->old_vel_y + ((priv->old_vel_y > 0) ? priv->vmax : -priv->vmax)); + + force_fast = FALSE; + } + if ((ABS (priv->vel_y) >= priv->vmin) || (ABS (priv->vel_x) >= priv->vmin)) { @@ -2745,16 +2797,19 @@ hildon_pannable_area_button_release_cb (GtkWidget * widget, priv->scroll_indicator_alpha = 1.0; - if (ABS (priv->vel_x) > MAX_SPEED_THRESHOLD) - priv->vel_x = (priv->vel_x > 0) ? priv->vmax : -priv->vmax; + if (force_fast) { + 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 (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) - hildon_pannable_area_timeout, widget); + priv->idle_id = gdk_threads_add_timeout_full (G_PRIORITY_HIGH_IDLE + 20, + (gint) (1000.0 / (gdouble) priv->sps), + (GSourceFunc) hildon_pannable_area_timeout, + widget, NULL); } else { if (priv->center_on_child_focus_pending) { hildon_pannable_area_center_on_child_focus (area); @@ -3171,7 +3226,9 @@ hildon_pannable_area_scroll_to (HildonPannableArea *area, g_return_if_fail (x < width || y < height); if ((x > -1)&&(hscroll_visible)) { - priv->scroll_to_x = x - priv->hadjust->page_size/2; + priv->scroll_to_x = CLAMP (x - priv->hadjust->page_size/2, + priv->hadjust->lower, + priv->hadjust->upper - priv->hadjust->page_size); dist_x = priv->scroll_to_x - priv->hadjust->value; if (dist_x == 0) { priv->scroll_to_x = -1; @@ -3183,7 +3240,9 @@ hildon_pannable_area_scroll_to (HildonPannableArea *area, } if ((y > -1)&&(vscroll_visible)) { - priv->scroll_to_y = y - priv->vadjust->page_size/2; + priv->scroll_to_y = CLAMP (y - priv->vadjust->page_size/2, + priv->vadjust->lower, + priv->vadjust->upper - priv->vadjust->page_size); dist_y = priv->scroll_to_y - priv->vadjust->value; if (dist_y == 0) { priv->scroll_to_y = -1; @@ -3194,16 +3253,17 @@ hildon_pannable_area_scroll_to (HildonPannableArea *area, priv->scroll_to_y = y; } - if ((priv->scroll_to_y == -1) && (priv->scroll_to_y == -1)) { + if ((priv->scroll_to_y == -1) && (priv->scroll_to_x == -1)) { return; } hildon_pannable_area_launch_fade_timeout (area, 1.0); if (!priv->idle_id) - priv->idle_id = gdk_threads_add_timeout ((gint) (1000.0 / (gdouble) priv->sps), - (GSourceFunc) - hildon_pannable_area_timeout, area); + priv->idle_id = gdk_threads_add_timeout_full (G_PRIORITY_HIGH_IDLE + 20, + (gint) (1000.0 / (gdouble) priv->sps), + (GSourceFunc) hildon_pannable_area_timeout, + area, NULL); } /**