#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
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;
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;
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);
"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));
"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));
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;
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;
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,
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)
{
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);
if (child && GTK_WIDGET_VISIBLE (child)) {
+ hildon_pannable_area_check_scrollbars (HILDON_PANNABLE_AREA (widget));
+
hildon_pannable_area_child_allocate_calculate (widget,
allocation,
&child_allocation);
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
tx, ty, mask);
if (!selected_window) {
if (tx)
- *tx = x;
+ *tx = x-wx;
if (ty)
- *ty = y;
+ *ty = y-wy;
selected_window = child;
}
} else {
priv->scroll_indicator_alpha);
priv->last_time = event->time;
+ priv->last_press_time = event->time;
priv->last_type = 1;
priv->scroll_to_x = -1;
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) {
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);
}
}
(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);
}
}
}
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)
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)) {
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);
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;
}
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;
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);
}
/**