[libchamplain] Fixes in kinetic scroll
- From: Jiří Techet <jiritechet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libchamplain] Fixes in kinetic scroll
- Date: Fri, 19 Apr 2013 19:42:41 +0000 (UTC)
commit 89be3c21f617c78e43326af8aae5b2d29de6a282
Author: Jiří Techet <techet gmail com>
Date: Wed Apr 17 11:46:51 2013 +0200
Fixes in kinetic scroll
Remove drag threshold which is not necessary for libchamplain, add sanity
check that mouse button is released during motion event.
champlain/champlain-kinetic-scroll-view.c | 183 ++++++++++++++----------------
champlain/champlain-kinetic-scroll-view.h | 3 +-
champlain/champlain-view.c | 2 +-
3 files changed, 90 insertions(+), 98 deletions(-)
---
diff --git a/champlain/champlain-kinetic-scroll-view.c b/champlain/champlain-kinetic-scroll-view.c
index c249a9f..14d0551 100644
--- a/champlain/champlain-kinetic-scroll-view.c
+++ b/champlain/champlain-kinetic-scroll-view.c
@@ -55,8 +55,7 @@ struct _ChamplainKineticScrollViewPrivate
gdouble dy;
gdouble decel_rate;
- ClutterActor *child;
- gboolean in_drag;
+ ClutterActor *viewport;
};
enum
@@ -75,6 +74,11 @@ enum
static guint signals[LAST_SIGNAL] = { 0, };
+static gboolean
+button_release_event_cb (ClutterActor *stage,
+ ClutterButtonEvent *event,
+ ChamplainKineticScrollView *scroll);
+
static void
champlain_kinetic_scroll_view_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
@@ -135,10 +139,10 @@ champlain_kinetic_scroll_view_dispose (GObject *object)
{
ChamplainKineticScrollViewPrivate *priv = CHAMPLAIN_KINETIC_SCROLL_VIEW (object)->priv;
- if (priv->child)
+ if (priv->viewport)
{
clutter_actor_remove_all_children (CLUTTER_ACTOR (object));
- priv->child = NULL;
+ priv->viewport = NULL;
}
if (priv->deceleration_timeline)
@@ -213,6 +217,59 @@ champlain_kinetic_scroll_view_class_init (ChamplainKineticScrollViewClass *klass
}
+static void
+clamp_adjustments (ChamplainKineticScrollView *scroll)
+{
+ ChamplainKineticScrollViewPrivate *priv = scroll->priv;
+
+ if (priv->viewport)
+ {
+ guint fps, n_frames;
+ ChamplainAdjustment *hadj, *vadj;
+ gboolean snap;
+
+ champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
+ &hadj, &vadj);
+
+ /* FIXME: Hard-coded value here */
+ fps = clutter_get_default_frame_rate ();
+ n_frames = fps / 6;
+
+ snap = TRUE;
+ if (champlain_adjustment_get_elastic (hadj))
+ snap = !champlain_adjustment_clamp (hadj, TRUE, n_frames, fps);
+
+ /* Snap to the nearest step increment on hadjustment */
+ if (snap)
+ {
+ gdouble d, value, lower, step_increment;
+
+ champlain_adjustment_get_values (hadj, &value, &lower, NULL,
+ &step_increment);
+ d = (rint ((value - lower) / step_increment) *
+ step_increment) + lower;
+ champlain_adjustment_set_value (hadj, d);
+ }
+
+ snap = TRUE;
+ if (champlain_adjustment_get_elastic (vadj))
+ snap = !champlain_adjustment_clamp (vadj, TRUE, n_frames, fps);
+
+ /* Snap to the nearest step increment on vadjustment */
+ if (snap)
+ {
+ gdouble d, value, lower, step_increment;
+
+ champlain_adjustment_get_values (vadj, &value, &lower, NULL,
+ &step_increment);
+ d = (rint ((value - lower) / step_increment) *
+ step_increment) + lower;
+ champlain_adjustment_set_value (vadj, d);
+ }
+ }
+}
+
+
static gboolean
motion_event_cb (ClutterActor *stage,
ClutterMotionEvent *event,
@@ -224,7 +281,22 @@ motion_event_cb (ClutterActor *stage,
if (event->type != CLUTTER_MOTION)
return FALSE;
-
+
+ if (!(event->modifier_state & CLUTTER_BUTTON1_MASK))
+ {
+ /* It sometimes -very rarely - happens that we miss the release event for some
+ * reason. This is a sanity check to disconnect the event handlers when the
+ * button is not pressed. */
+ g_signal_handlers_disconnect_by_func (stage,
+ motion_event_cb,
+ scroll);
+ g_signal_handlers_disconnect_by_func (stage,
+ button_release_event_cb,
+ scroll);
+ clamp_adjustments (scroll);
+ g_signal_emit_by_name (scroll, "panning-completed", NULL);
+ }
+
if (clutter_actor_transform_stage_point (actor,
event->x,
event->y,
@@ -232,29 +304,12 @@ motion_event_cb (ClutterActor *stage,
{
ChamplainKineticScrollViewMotion *motion;
- if (!priv->in_drag)
- {
- guint threshold = 4;
-
- motion = &g_array_index (priv->motion_buffer,
- ChamplainKineticScrollViewMotion, 0);
-
- if ((ABS (motion->x - x) >= threshold) ||
- (ABS (motion->y - y) >= threshold))
- {
- clutter_stage_set_motion_events_enabled (CLUTTER_STAGE (stage), TRUE);
- priv->in_drag = TRUE;
- }
- else
- return FALSE;
- }
-
- if (priv->child)
+ if (priv->viewport)
{
gdouble dx, dy;
ChamplainAdjustment *hadjust, *vadjust;
- champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
+ champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
&hadjust,
&vadjust);
@@ -295,59 +350,6 @@ motion_event_cb (ClutterActor *stage,
static void
-clamp_adjustments (ChamplainKineticScrollView *scroll)
-{
- ChamplainKineticScrollViewPrivate *priv = scroll->priv;
-
- if (priv->child)
- {
- guint fps, n_frames;
- ChamplainAdjustment *hadj, *vadj;
- gboolean snap;
-
- champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
- &hadj, &vadj);
-
- /* FIXME: Hard-coded value here */
- fps = clutter_get_default_frame_rate ();
- n_frames = fps / 6;
-
- snap = TRUE;
- if (champlain_adjustment_get_elastic (hadj))
- snap = !champlain_adjustment_clamp (hadj, TRUE, n_frames, fps);
-
- /* Snap to the nearest step increment on hadjustment */
- if (snap)
- {
- gdouble d, value, lower, step_increment;
-
- champlain_adjustment_get_values (hadj, &value, &lower, NULL,
- &step_increment);
- d = (rint ((value - lower) / step_increment) *
- step_increment) + lower;
- champlain_adjustment_set_value (hadj, d);
- }
-
- snap = TRUE;
- if (champlain_adjustment_get_elastic (vadj))
- snap = !champlain_adjustment_clamp (vadj, TRUE, n_frames, fps);
-
- /* Snap to the nearest step increment on vadjustment */
- if (snap)
- {
- gdouble d, value, lower, step_increment;
-
- champlain_adjustment_get_values (vadj, &value, &lower, NULL,
- &step_increment);
- d = (rint ((value - lower) / step_increment) *
- step_increment) + lower;
- champlain_adjustment_set_value (vadj, d);
- }
- }
-}
-
-
-static void
deceleration_completed_cb (ClutterTimeline *timeline,
ChamplainKineticScrollView *scroll)
{
@@ -366,14 +368,14 @@ deceleration_new_frame_cb (ClutterTimeline *timeline,
{
ChamplainKineticScrollViewPrivate *priv = scroll->priv;
- if (priv->child)
+ if (priv->viewport)
{
gdouble value, lower, upper;
ChamplainAdjustment *hadjust, *vadjust;
gint i;
gboolean stop = TRUE;
- champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
+ champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
&hadjust,
&vadjust);
@@ -434,12 +436,7 @@ button_release_event_cb (ClutterActor *stage,
button_release_event_cb,
scroll);
- if (!priv->in_drag)
- return FALSE;
-
- clutter_stage_set_motion_events_enabled (CLUTTER_STAGE (stage), TRUE);
-
- if (priv->kinetic && priv->child)
+ if (priv->kinetic && priv->viewport)
{
gfloat x, y;
@@ -454,8 +451,6 @@ button_release_event_cb (ClutterActor *stage,
glong time_diff;
gint i;
- priv->in_drag = TRUE;
-
/* Get time delta */
g_get_current_time (&release_time);
@@ -503,7 +498,7 @@ button_release_event_cb (ClutterActor *stage,
priv->dy = (y_origin - y) / frac;
/* Get adjustments to do step-increment snapping */
- champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
+ champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
&hadjust,
&vadjust);
@@ -607,7 +602,6 @@ button_release_event_cb (ClutterActor *stage,
/* Reset motion event buffer */
priv->last_motion = 0;
- priv->in_drag = FALSE;
if (!decelerating)
{
@@ -658,8 +652,6 @@ button_press_event_cb (ClutterActor *actor,
"captured-event",
G_CALLBACK (button_release_event_cb),
scroll);
-
- priv->in_drag = FALSE;
}
}
@@ -676,8 +668,7 @@ champlain_kinetic_scroll_view_init (ChamplainKineticScrollView *self)
sizeof (ChamplainKineticScrollViewMotion), 3);
g_array_set_size (priv->motion_buffer, 3);
priv->decel_rate = 1.1f;
- priv->child = NULL;
- priv->in_drag = FALSE;
+ priv->viewport = NULL;
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
g_signal_connect (self, "button-press-event",
@@ -687,14 +678,14 @@ champlain_kinetic_scroll_view_init (ChamplainKineticScrollView *self)
ClutterActor *
champlain_kinetic_scroll_view_new (gboolean kinetic,
- ClutterActor *viewport)
+ ChamplainViewport *viewport)
{
ClutterActor *scroll_view;
scroll_view = CLUTTER_ACTOR (g_object_new (CHAMPLAIN_TYPE_KINETIC_SCROLL_VIEW,
"mode", kinetic, NULL));
- CHAMPLAIN_KINETIC_SCROLL_VIEW (scroll_view)->priv->child = viewport;
- clutter_actor_add_child (CLUTTER_ACTOR (scroll_view), viewport);
+ CHAMPLAIN_KINETIC_SCROLL_VIEW (scroll_view)->priv->viewport = CLUTTER_ACTOR (viewport);
+ clutter_actor_add_child (scroll_view, CLUTTER_ACTOR (viewport));
return scroll_view;
}
diff --git a/champlain/champlain-kinetic-scroll-view.h b/champlain/champlain-kinetic-scroll-view.h
index 2045888..0557f70 100644
--- a/champlain/champlain-kinetic-scroll-view.h
+++ b/champlain/champlain-kinetic-scroll-view.h
@@ -25,6 +25,7 @@
#include <glib-object.h>
#include <clutter/clutter.h>
+#include <champlain-viewport.h>
G_BEGIN_DECLS
@@ -65,7 +66,7 @@ struct _ChamplainKineticScrollViewClass
GType champlain_kinetic_scroll_view_get_type (void) G_GNUC_CONST;
ClutterActor *champlain_kinetic_scroll_view_new (gboolean kinetic,
- ClutterActor *viewport);
+ ChamplainViewport *viewport);
void champlain_kinetic_scroll_view_stop (ChamplainKineticScrollView *self);
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 8c1340d..48add5b 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -1037,7 +1037,7 @@ champlain_view_init (ChamplainView *view)
G_CALLBACK (viewport_pos_changed_cb), view);
/* Setup kinetic scroll */
- priv->kinetic_scroll = champlain_kinetic_scroll_view_new (FALSE, priv->viewport);
+ priv->kinetic_scroll = champlain_kinetic_scroll_view_new (FALSE, CHAMPLAIN_VIEWPORT (priv->viewport));
g_signal_connect (priv->kinetic_scroll, "scroll-event",
G_CALLBACK (scroll_event), view);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]