mirror of
https://github.com/brl/mutter.git
synced 2025-02-19 22:54:08 +00:00
pan-action: add PanAction, to handle panning in scrollable actors
PanAction is a GestureAction-subclass that implements the panning concept for scrollable actors, with the ability to emit interpolated signals to emulate the kinetic inertia of the panning. PanAction provides: • pan signal, notifying users of the panning gesture status; • pan-stopped signal, emitted at the end of the interpolated phase of the panning gesture, if enabled; • pan-axis property, to allow constraining the dragging to a specific axis; • interpolated property, to enable or disable the inertial behaviour; • deceleration property, to customize the rate at which the momentum of the panning will be slowed down; • acceleration-factor property, applied to the inertial momentum when starting the interpolated sequence. An interactive test is also provided. https://bugzilla.gnome.org/show_bug.cgi?id=681648
This commit is contained in:
parent
436ebb2716
commit
9ca06d2895
@ -102,6 +102,7 @@ source_h = \
|
|||||||
$(srcdir)/clutter-page-turn-effect.h \
|
$(srcdir)/clutter-page-turn-effect.h \
|
||||||
$(srcdir)/clutter-paint-nodes.h \
|
$(srcdir)/clutter-paint-nodes.h \
|
||||||
$(srcdir)/clutter-paint-node.h \
|
$(srcdir)/clutter-paint-node.h \
|
||||||
|
$(srcdir)/clutter-pan-action.h \
|
||||||
$(srcdir)/clutter-path-constraint.h \
|
$(srcdir)/clutter-path-constraint.h \
|
||||||
$(srcdir)/clutter-path.h \
|
$(srcdir)/clutter-path.h \
|
||||||
$(srcdir)/clutter-property-transition.h \
|
$(srcdir)/clutter-property-transition.h \
|
||||||
@ -182,6 +183,7 @@ source_c = \
|
|||||||
$(srcdir)/clutter-page-turn-effect.c \
|
$(srcdir)/clutter-page-turn-effect.c \
|
||||||
$(srcdir)/clutter-paint-nodes.c \
|
$(srcdir)/clutter-paint-nodes.c \
|
||||||
$(srcdir)/clutter-paint-node.c \
|
$(srcdir)/clutter-paint-node.c \
|
||||||
|
$(srcdir)/clutter-pan-action.c \
|
||||||
$(srcdir)/clutter-path-constraint.c \
|
$(srcdir)/clutter-path-constraint.c \
|
||||||
$(srcdir)/clutter-path.c \
|
$(srcdir)/clutter-path.c \
|
||||||
$(srcdir)/clutter-property-transition.c \
|
$(srcdir)/clutter-property-transition.c \
|
||||||
|
@ -1002,6 +1002,25 @@ typedef enum { /*< prefix=CLUTTER_SWIPE_DIRECTION >*/
|
|||||||
CLUTTER_SWIPE_DIRECTION_RIGHT = 1 << 3
|
CLUTTER_SWIPE_DIRECTION_RIGHT = 1 << 3
|
||||||
} ClutterSwipeDirection;
|
} ClutterSwipeDirection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAxis:
|
||||||
|
* @CLUTTER_PAN_AXIS_NONE: No constraint
|
||||||
|
* @CLUTTER_PAN_X_AXIS: Set a constraint on the X axis
|
||||||
|
* @CLUTTER_PAN_Y_AXIS: Set a constraint on the Y axis
|
||||||
|
*
|
||||||
|
* The axis of the constraint that should be applied on the
|
||||||
|
* panning action
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
typedef enum { /*< prefix=CLUTTER_PAN >*/
|
||||||
|
CLUTTER_PAN_AXIS_NONE = 0,
|
||||||
|
|
||||||
|
CLUTTER_PAN_X_AXIS,
|
||||||
|
CLUTTER_PAN_Y_AXIS
|
||||||
|
} ClutterPanAxis;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterTableAlignment:
|
* ClutterTableAlignment:
|
||||||
* @CLUTTER_TABLE_ALIGNMENT_START: Align the child to the top or to the
|
* @CLUTTER_TABLE_ALIGNMENT_START: Align the child to the top or to the
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
BOOLEAN:BOXED
|
BOOLEAN:BOXED
|
||||||
BOOLEAN:BOXED,INT,INT
|
BOOLEAN:BOXED,INT,INT
|
||||||
|
BOOLEAN:OBJECT,BOOLEAN
|
||||||
BOOLEAN:OBJECT,BOXED,DOUBLE
|
BOOLEAN:OBJECT,BOXED,DOUBLE
|
||||||
BOOLEAN:OBJECT,DOUBLE
|
BOOLEAN:OBJECT,DOUBLE
|
||||||
BOOLEAN:OBJECT,ENUM
|
BOOLEAN:OBJECT,ENUM
|
||||||
|
814
clutter/clutter-pan-action.c
Normal file
814
clutter/clutter-pan-action.c
Normal file
@ -0,0 +1,814 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Intel Corporation.
|
||||||
|
* Copyright (C) 2011 Robert Bosch Car Multimedia GmbH.
|
||||||
|
* Copyright (C) 2012 Collabora Ltd.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Emanuele Aina <emanuele.aina@collabora.com>
|
||||||
|
*
|
||||||
|
* Based on ClutterDragAction, ClutterSwipeAction, and MxKineticScrollView,
|
||||||
|
* written by:
|
||||||
|
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||||
|
* Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>
|
||||||
|
* Chris Lord <chris@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:clutter-pan-action
|
||||||
|
* @Title: ClutterPanAction
|
||||||
|
* @Short_Description: Action for pan gestures
|
||||||
|
*
|
||||||
|
* #ClutterPanAction is a sub-class of #ClutterGestureAction that implements
|
||||||
|
* the logic for recognizing pan gestures.
|
||||||
|
*
|
||||||
|
* The simplest usage of #ClutterPanAction consists in adding it to
|
||||||
|
* a #ClutterActor with a child and setting it as reactive; for instance,
|
||||||
|
* the following code:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* clutter_actor_add_action (actor, clutter_pan_action_new ());
|
||||||
|
* clutter_actor_set_reactive (actor, TRUE);
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* will automatically result in the actor children to be moved
|
||||||
|
* when dragging.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "clutter-pan-action.h"
|
||||||
|
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-enum-types.h"
|
||||||
|
#include "clutter-marshal.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define FLOAT_EPSILON (1e-15)
|
||||||
|
|
||||||
|
static const gfloat min_velocity = 0.1f; // measured in px/ms
|
||||||
|
static const gfloat reference_fps = 60.0f; // the fps assumed for the deceleration rate
|
||||||
|
static const gfloat default_deceleration_rate = 0.95f;
|
||||||
|
static const gfloat default_acceleration_factor = 1.0f;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PAN_STATE_INACTIVE,
|
||||||
|
PAN_STATE_PANNING,
|
||||||
|
PAN_STATE_INTERPOLATING
|
||||||
|
} PanState;
|
||||||
|
|
||||||
|
struct _ClutterPanActionPrivate
|
||||||
|
{
|
||||||
|
ClutterPanAxis pan_axis;
|
||||||
|
|
||||||
|
PanState state;
|
||||||
|
|
||||||
|
/* Variables for storing acceleration information */
|
||||||
|
ClutterTimeline *deceleration_timeline;
|
||||||
|
gfloat target_x;
|
||||||
|
gfloat target_y;
|
||||||
|
gfloat dx;
|
||||||
|
gfloat dy;
|
||||||
|
gdouble deceleration_rate;
|
||||||
|
gdouble acceleration_factor;
|
||||||
|
|
||||||
|
/* Inertial motion tracking */
|
||||||
|
gfloat interpolated_x;
|
||||||
|
gfloat interpolated_y;
|
||||||
|
gfloat release_x;
|
||||||
|
gfloat release_y;
|
||||||
|
|
||||||
|
guint should_interpolate : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_PAN_AXIS,
|
||||||
|
PROP_INTERPOLATE,
|
||||||
|
PROP_DECELERATION,
|
||||||
|
PROP_ACCELERATION_FACTOR,
|
||||||
|
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *pan_props[PROP_LAST] = { NULL, };
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PAN,
|
||||||
|
PAN_STOPPED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint pan_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterPanAction, clutter_pan_action,
|
||||||
|
CLUTTER_TYPE_GESTURE_ACTION);
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_pan (ClutterPanAction *self,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gboolean is_interpolated)
|
||||||
|
{
|
||||||
|
gboolean retval;
|
||||||
|
g_signal_emit (self, pan_signals[PAN], 0, actor, is_interpolated, &retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_pan_stopped (ClutterPanAction *self,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
g_signal_emit (self, pan_signals[PAN_STOPPED], 0, actor);
|
||||||
|
priv->state = PAN_STATE_INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_deceleration_stopped (ClutterTimeline *timeline,
|
||||||
|
gboolean is_finished,
|
||||||
|
ClutterPanAction *self)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
ClutterActor *actor;
|
||||||
|
|
||||||
|
g_object_unref (timeline);
|
||||||
|
priv->deceleration_timeline = NULL;
|
||||||
|
|
||||||
|
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
|
||||||
|
emit_pan_stopped (self, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_deceleration_new_frame (ClutterTimeline *timeline,
|
||||||
|
gint elapsed_time,
|
||||||
|
ClutterPanAction *self)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
ClutterActor *actor;
|
||||||
|
gdouble progress;
|
||||||
|
gfloat interpolated_x, interpolated_y;
|
||||||
|
|
||||||
|
progress = clutter_timeline_get_progress (timeline);
|
||||||
|
|
||||||
|
interpolated_x = priv->target_x * progress;
|
||||||
|
interpolated_y = priv->target_y * progress;
|
||||||
|
priv->dx = interpolated_x - priv->interpolated_x;
|
||||||
|
priv->dy = interpolated_y - priv->interpolated_y;
|
||||||
|
priv->interpolated_x = interpolated_x;
|
||||||
|
priv->interpolated_y = interpolated_y;
|
||||||
|
|
||||||
|
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
|
||||||
|
emit_pan (self, actor, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gesture_begin (ClutterGestureAction *gesture,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture);
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->state == PAN_STATE_INTERPOLATING && priv->deceleration_timeline)
|
||||||
|
clutter_timeline_stop (priv->deceleration_timeline);
|
||||||
|
|
||||||
|
priv->state = PAN_STATE_PANNING;
|
||||||
|
priv->interpolated_x = priv->interpolated_y = 0.0f;
|
||||||
|
priv->dx = priv->dy = 0.0f;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gesture_progress (ClutterGestureAction *gesture,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture);
|
||||||
|
|
||||||
|
emit_pan (self, actor, FALSE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gesture_cancel (ClutterGestureAction *gesture,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture);
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
priv->state = PAN_STATE_INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gesture_end (ClutterGestureAction *gesture,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture);
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
gfloat velocity, velocity_x, velocity_y;
|
||||||
|
gfloat delta_x, delta_y;
|
||||||
|
gfloat tau;
|
||||||
|
gint duration;
|
||||||
|
|
||||||
|
clutter_gesture_action_get_release_coords (CLUTTER_GESTURE_ACTION (self), 0, &priv->release_x, &priv->release_y);
|
||||||
|
|
||||||
|
if (!priv->should_interpolate)
|
||||||
|
{
|
||||||
|
priv->state = PAN_STATE_INACTIVE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->state = PAN_STATE_INTERPOLATING;
|
||||||
|
|
||||||
|
clutter_gesture_action_get_motion_delta (gesture, 0, &delta_x, &delta_y);
|
||||||
|
velocity = clutter_gesture_action_get_velocity (gesture, 0, &velocity_x, &velocity_y);
|
||||||
|
|
||||||
|
/* Exponential timing constant v(t) = v(0) * exp(-t/tau)
|
||||||
|
* tau = 1000ms / (frame_per_second * - ln(decay_per_frame))
|
||||||
|
* with frame_per_second = 60 and decay_per_frame = 0.95, tau ~= 325ms
|
||||||
|
* see http://ariya.ofilabs.com/2011/10/flick-list-with-its-momentum-scrolling-and-deceleration.html */
|
||||||
|
tau = 1000.0f / (reference_fps * - logf (priv->deceleration_rate));
|
||||||
|
|
||||||
|
/* See where the decreasing velocity reaches $min_velocity px/ms
|
||||||
|
* v(t) = v(0) * exp(-t/tau) = min_velocity
|
||||||
|
* t = - tau * ln( min_velocity / |v(0)|) */
|
||||||
|
duration = - tau * logf (min_velocity / (ABS (velocity) * priv->acceleration_factor));
|
||||||
|
|
||||||
|
/* Target point: x(t) = v(0) * tau * [1 - exp(-t/tau)] */
|
||||||
|
priv->target_x = velocity_x * priv->acceleration_factor * tau * (1 - exp ((float)-duration / tau));
|
||||||
|
priv->target_y = velocity_y * priv->acceleration_factor * tau * (1 - exp ((float)-duration / tau));
|
||||||
|
|
||||||
|
if (ABS (velocity) * priv->acceleration_factor > min_velocity && duration > FLOAT_EPSILON)
|
||||||
|
{
|
||||||
|
priv->interpolated_x = priv->interpolated_y = 0.0f;
|
||||||
|
priv->deceleration_timeline = clutter_timeline_new (duration);
|
||||||
|
clutter_timeline_set_progress_mode (priv->deceleration_timeline, CLUTTER_EASE_OUT_EXPO);
|
||||||
|
|
||||||
|
g_signal_connect (priv->deceleration_timeline, "new_frame",
|
||||||
|
G_CALLBACK (on_deceleration_new_frame), self);
|
||||||
|
g_signal_connect (priv->deceleration_timeline, "stopped",
|
||||||
|
G_CALLBACK (on_deceleration_stopped), self);
|
||||||
|
clutter_timeline_start (priv->deceleration_timeline);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit_pan_stopped (self, actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_pan_action_real_pan (ClutterPanAction *self,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gboolean is_interpolated)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
gfloat dx, dy;
|
||||||
|
ClutterMatrix transform;
|
||||||
|
|
||||||
|
if (is_interpolated)
|
||||||
|
clutter_pan_action_get_interpolated_delta (self, &dx, &dy);
|
||||||
|
else
|
||||||
|
clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (self), 0, &dx, &dy);
|
||||||
|
|
||||||
|
switch (priv->pan_axis)
|
||||||
|
{
|
||||||
|
case CLUTTER_PAN_AXIS_NONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PAN_X_AXIS:
|
||||||
|
dy = 0.0f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PAN_Y_AXIS:
|
||||||
|
dx = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_get_child_transform (actor, &transform);
|
||||||
|
cogl_matrix_translate (&transform, dx, dy, 0.0f);
|
||||||
|
clutter_actor_set_child_transform (actor, &transform);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_pan_action_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterPanAction *self = CLUTTER_PAN_ACTION (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_PAN_AXIS:
|
||||||
|
clutter_pan_action_set_pan_axis (self, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_INTERPOLATE :
|
||||||
|
clutter_pan_action_set_interpolate (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_DECELERATION :
|
||||||
|
clutter_pan_action_set_deceleration (self, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ACCELERATION_FACTOR :
|
||||||
|
clutter_pan_action_set_acceleration_factor (self, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_pan_action_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterPanAction *self = CLUTTER_PAN_ACTION (gobject);
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_PAN_AXIS:
|
||||||
|
g_value_set_enum (value, priv->pan_axis);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_INTERPOLATE :
|
||||||
|
g_value_set_boolean (value, priv->should_interpolate);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_DECELERATION :
|
||||||
|
g_value_set_double (value, priv->deceleration_rate);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ACCELERATION_FACTOR :
|
||||||
|
g_value_set_double (value, priv->acceleration_factor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_pan_action_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv = CLUTTER_PAN_ACTION (gobject)->priv;
|
||||||
|
|
||||||
|
g_clear_object (&priv->deceleration_timeline);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (clutter_pan_action_parent_class)->dispose (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_pan_action_set_actor (ClutterActorMeta *meta,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterPanAction *self = CLUTTER_PAN_ACTION (meta);
|
||||||
|
ClutterPanActionPrivate *priv = self->priv;
|
||||||
|
ClutterActor *old_actor;
|
||||||
|
|
||||||
|
old_actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
|
||||||
|
if (old_actor != actor)
|
||||||
|
{
|
||||||
|
/* make sure we reset the state */
|
||||||
|
if (priv->state == PAN_STATE_INTERPOLATING)
|
||||||
|
g_clear_object (&priv->deceleration_timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_META_CLASS (clutter_pan_action_parent_class)->set_actor (meta, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_pan_action_class_init (ClutterPanActionClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||||
|
ClutterGestureActionClass *gesture_class =
|
||||||
|
CLUTTER_GESTURE_ACTION_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (ClutterPanActionPrivate));
|
||||||
|
|
||||||
|
klass->pan = clutter_pan_action_real_pan;
|
||||||
|
|
||||||
|
gesture_class->gesture_begin = gesture_begin;
|
||||||
|
gesture_class->gesture_progress = gesture_progress;
|
||||||
|
gesture_class->gesture_cancel = gesture_cancel;
|
||||||
|
gesture_class->gesture_end = gesture_end;
|
||||||
|
|
||||||
|
meta_class->set_actor = clutter_pan_action_set_actor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAction:pan-axis:
|
||||||
|
*
|
||||||
|
* Constraints the panning action to the specified axis
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
pan_props[PROP_PAN_AXIS] =
|
||||||
|
g_param_spec_enum ("pan-axis",
|
||||||
|
P_("Pan Axis"),
|
||||||
|
P_("Constraints the panning to an axis"),
|
||||||
|
CLUTTER_TYPE_PAN_AXIS,
|
||||||
|
CLUTTER_PAN_AXIS_NONE,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAction:interpolate:
|
||||||
|
*
|
||||||
|
* Whether interpolated events emission is enabled.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
pan_props[PROP_INTERPOLATE] =
|
||||||
|
g_param_spec_boolean ("interpolate",
|
||||||
|
P_("Interpolate"),
|
||||||
|
P_("Whether interpolated events emission is enabled."),
|
||||||
|
FALSE,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAction:deceleration:
|
||||||
|
*
|
||||||
|
* The rate at which the interpolated panning will decelerate in
|
||||||
|
*
|
||||||
|
* #ClutterPanAction will emit interpolated ::pan events with decreasing
|
||||||
|
* scroll deltas, using the rate specified by this property.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
pan_props[PROP_DECELERATION] =
|
||||||
|
g_param_spec_double ("deceleration",
|
||||||
|
P_("Deceleration"),
|
||||||
|
P_("Rate at which the interpolated panning will decelerate in"),
|
||||||
|
FLOAT_EPSILON, 1.0, default_deceleration_rate,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAction:acceleration-factor:
|
||||||
|
*
|
||||||
|
* The initial acceleration factor
|
||||||
|
*
|
||||||
|
* The kinetic momentum measured at the time of releasing the pointer will
|
||||||
|
* be multiplied by the factor specified by this property before being used
|
||||||
|
* to generate interpolated ::pan events.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
pan_props[PROP_ACCELERATION_FACTOR] =
|
||||||
|
g_param_spec_double ("acceleration-factor",
|
||||||
|
P_("Initial acceleration factor"),
|
||||||
|
P_("Factor applied to the momentum when starting the interpolated phase"),
|
||||||
|
1.0, G_MAXDOUBLE, default_acceleration_factor,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
|
gobject_class->set_property = clutter_pan_action_set_property;
|
||||||
|
gobject_class->get_property = clutter_pan_action_get_property;
|
||||||
|
gobject_class->dispose = clutter_pan_action_dispose;
|
||||||
|
g_object_class_install_properties (gobject_class,
|
||||||
|
PROP_LAST,
|
||||||
|
pan_props);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAction:pan:
|
||||||
|
* @action: the #ClutterPanAction that emitted the signal
|
||||||
|
* @actor: the #ClutterActor attached to the @action
|
||||||
|
* @is_interpolated: if the event is the result of interpolating
|
||||||
|
* the motion velocity at the end of the drag
|
||||||
|
*
|
||||||
|
* The ::pan signal is emitted to keep track of the motion during
|
||||||
|
* a pan gesture. @is_interpolated is set to %TRUE during the
|
||||||
|
* interpolation phase of the pan, after the drag has ended and
|
||||||
|
* the :interpolate property was set to %TRUE.
|
||||||
|
*
|
||||||
|
* Return value: TRUE if the pan action has been handled by one of
|
||||||
|
* the listener or %FALSE to continue the emission.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
pan_signals[PAN] =
|
||||||
|
g_signal_new (I_("pan"),
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (ClutterPanActionClass, pan),
|
||||||
|
_clutter_boolean_continue_accumulator, NULL,
|
||||||
|
_clutter_marshal_BOOLEAN__OBJECT_BOOLEAN,
|
||||||
|
G_TYPE_BOOLEAN, 2,
|
||||||
|
CLUTTER_TYPE_ACTOR,
|
||||||
|
G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAction:pan-stopped:
|
||||||
|
* @action: the #ClutterPanAction that emitted the signal
|
||||||
|
* @actor: the #ClutterActor attached to the @action
|
||||||
|
*
|
||||||
|
* The ::pan-stopped signal is emitted at the end of the interpolation
|
||||||
|
* phase of the pan action, only when :interpolate is set to %TRUE.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
pan_signals[PAN_STOPPED] =
|
||||||
|
g_signal_new (I_("pan-stopped"),
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (ClutterPanActionClass, pan_stopped),
|
||||||
|
NULL, NULL,
|
||||||
|
_clutter_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE, 1,
|
||||||
|
CLUTTER_TYPE_ACTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_pan_action_init (ClutterPanAction *self)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv = self->priv =
|
||||||
|
G_TYPE_INSTANCE_GET_PRIVATE (self, CLUTTER_TYPE_PAN_ACTION,
|
||||||
|
ClutterPanActionPrivate);
|
||||||
|
priv->deceleration_rate = default_deceleration_rate;
|
||||||
|
priv->acceleration_factor = default_acceleration_factor;
|
||||||
|
priv->state = PAN_STATE_INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_new:
|
||||||
|
*
|
||||||
|
* Creates a new #ClutterPanAction instance
|
||||||
|
*
|
||||||
|
* Return value: the newly created #ClutterPanAction
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
ClutterAction *
|
||||||
|
clutter_pan_action_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (CLUTTER_TYPE_PAN_ACTION, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_set_pan_axis:
|
||||||
|
* @self: a #ClutterPanAction
|
||||||
|
* @axis: the axis to constraint the panning to
|
||||||
|
*
|
||||||
|
* Restricts the panning action to a specific axis
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_pan_action_set_pan_axis (ClutterPanAction *self,
|
||||||
|
ClutterPanAxis axis)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_PAN_ACTION (self));
|
||||||
|
g_return_if_fail (axis >= CLUTTER_PAN_AXIS_NONE &&
|
||||||
|
axis <= CLUTTER_PAN_Y_AXIS);
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->pan_axis == axis)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->pan_axis = axis;
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_PAN_AXIS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_get_pan_axis:
|
||||||
|
* @self: a #ClutterPanAction
|
||||||
|
*
|
||||||
|
* Retrieves the axis constraint set by clutter_pan_action_set_pan_axis()
|
||||||
|
*
|
||||||
|
* Return value: the axis constraint
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
ClutterPanAxis
|
||||||
|
clutter_pan_action_get_pan_axis (ClutterPanAction *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self),
|
||||||
|
CLUTTER_PAN_AXIS_NONE);
|
||||||
|
|
||||||
|
return self->priv->pan_axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_set_interpolate:
|
||||||
|
* @self: a #ClutterPanAction
|
||||||
|
* @should_interpolate: whether to enable interpolated pan events
|
||||||
|
*
|
||||||
|
* Sets whether the action should emit interpolated ::pan events
|
||||||
|
* after the drag has ended, to emulate the gesture kinetic inertia.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_pan_action_set_interpolate (ClutterPanAction *self,
|
||||||
|
gboolean should_interpolate)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_PAN_ACTION (self));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
should_interpolate = !!should_interpolate;
|
||||||
|
|
||||||
|
if (priv->should_interpolate == should_interpolate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->should_interpolate = should_interpolate;
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_INTERPOLATE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_get_interpolate:
|
||||||
|
* @self: a #ClutterPanAction
|
||||||
|
*
|
||||||
|
* Checks if the action should emit ::pan events even after releasing
|
||||||
|
* the pointer during a panning gesture, to emulate some kind of
|
||||||
|
* kinetic inertia.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if interpolated events emission is active.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
clutter_pan_action_get_interpolate (ClutterPanAction *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
return self->priv->should_interpolate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_set_deceleration:
|
||||||
|
* @self: A #ClutterPanAction
|
||||||
|
* @rate: The deceleration rate
|
||||||
|
*
|
||||||
|
* Sets the deceleration rate of the interpolated ::pan events generated
|
||||||
|
* after a pan gesture. This is approximately the value that the momentum
|
||||||
|
* at the time of releasing the pointer is divided by every 60th of a second.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_pan_action_set_deceleration (ClutterPanAction *self,
|
||||||
|
gdouble rate)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_PAN_ACTION (self));
|
||||||
|
g_return_if_fail (rate <= 1.0);
|
||||||
|
g_return_if_fail (rate > 0.0);
|
||||||
|
|
||||||
|
self->priv->deceleration_rate = rate;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_DECELERATION]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_get_deceleration:
|
||||||
|
* @self: A #ClutterPanAction
|
||||||
|
*
|
||||||
|
* Retrieves the deceleration rate of interpolated ::pan events.
|
||||||
|
*
|
||||||
|
* Return value: The deceleration rate of the interpolated events.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
gdouble
|
||||||
|
clutter_pan_action_get_deceleration (ClutterPanAction *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), 0.95);
|
||||||
|
return self->priv->deceleration_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_set_acceleration_factor:
|
||||||
|
* @self: A #ClutterPanAction
|
||||||
|
* @factor: The acceleration factor
|
||||||
|
*
|
||||||
|
* Factor applied to the momentum velocity at the time of releasing the
|
||||||
|
* pointer when generating interpolated ::pan events.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_pan_action_set_acceleration_factor (ClutterPanAction *self,
|
||||||
|
gdouble factor)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_PAN_ACTION (self));
|
||||||
|
g_return_if_fail (factor >= 0.0);
|
||||||
|
|
||||||
|
self->priv->acceleration_factor = factor;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_ACCELERATION_FACTOR]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_get_acceleration_factor:
|
||||||
|
* @self: A #ClutterPanAction
|
||||||
|
*
|
||||||
|
* Retrieves the initial acceleration factor for interpolated ::pan events.
|
||||||
|
*
|
||||||
|
* Return value: The initial acceleration factor for interpolated events.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
gdouble
|
||||||
|
clutter_pan_action_get_acceleration_factor (ClutterPanAction *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), 1.0);
|
||||||
|
return self->priv->acceleration_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_get_interpolated_coords:
|
||||||
|
* @self: A #ClutterPanAction
|
||||||
|
* @interpolated_x: (out) (allow-none): return location for the latest
|
||||||
|
* interpolated event's X coordinate
|
||||||
|
* @interpolated_y: (out) (allow-none): return location for the latest
|
||||||
|
* interpolated event's Y coordinate
|
||||||
|
*
|
||||||
|
* Retrieves the coordinates, in stage space, of the latest interpolated
|
||||||
|
* event, analogous to clutter_gesture_action_get_motion_coords().
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_pan_action_get_interpolated_coords (ClutterPanAction *self,
|
||||||
|
gfloat *interpolated_x,
|
||||||
|
gfloat *interpolated_y)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_PAN_ACTION (self));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (interpolated_x)
|
||||||
|
*interpolated_x = priv->release_x + priv->interpolated_x;
|
||||||
|
|
||||||
|
if (interpolated_y)
|
||||||
|
*interpolated_y = priv->release_y + priv->interpolated_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pan_action_get_interpolated_delta:
|
||||||
|
* @self: A #ClutterPanAction
|
||||||
|
* @delta_x: (out) (allow-none): return location for the X delta since
|
||||||
|
* the latest interpolated event
|
||||||
|
* @delta_y: (out) (allow-none): return location for the Y delta since
|
||||||
|
* the latest interpolated event
|
||||||
|
*
|
||||||
|
* Retrieves the delta, in stage space, since the latest interpolated
|
||||||
|
* event, analogous to clutter_gesture_action_get_motion_delta().
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_pan_action_get_interpolated_delta (ClutterPanAction *self,
|
||||||
|
gfloat *delta_x,
|
||||||
|
gfloat *delta_y)
|
||||||
|
{
|
||||||
|
ClutterPanActionPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_PAN_ACTION (self));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (delta_x)
|
||||||
|
*delta_x = priv->dx;
|
||||||
|
|
||||||
|
if (delta_y)
|
||||||
|
*delta_y = priv->dy;
|
||||||
|
}
|
137
clutter/clutter-pan-action.h
Normal file
137
clutter/clutter-pan-action.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Intel Corporation.
|
||||||
|
* Copyright (C) 2011 Robert Bosch Car Multimedia GmbH.
|
||||||
|
* Copyright (C) 2012 Collabora Ltd.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Emanuele Aina <emanuele.aina@collabora.com>
|
||||||
|
*
|
||||||
|
* Based on ClutterDragAction, ClutterSwipeAction, and MxKineticScrollView,
|
||||||
|
* written by:
|
||||||
|
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||||
|
* Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>
|
||||||
|
* Chris Lord <chris@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||||
|
#error "Only <clutter/clutter.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_PAN_ACTION_H__
|
||||||
|
#define __CLUTTER_PAN_ACTION_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-gesture-action.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_PAN_ACTION (clutter_pan_action_get_type ())
|
||||||
|
#define CLUTTER_PAN_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PAN_ACTION, ClutterPanAction))
|
||||||
|
#define CLUTTER_IS_PAN_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PAN_ACTION))
|
||||||
|
#define CLUTTER_PAN_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_PAN_ACTION, ClutterPanActionClass))
|
||||||
|
#define CLUTTER_IS_PAN_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_PAN_ACTION))
|
||||||
|
#define CLUTTER_PAN_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_PAN_ACTION, ClutterPanActionClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterPanAction ClutterPanAction;
|
||||||
|
typedef struct _ClutterPanActionPrivate ClutterPanActionPrivate;
|
||||||
|
typedef struct _ClutterPanActionClass ClutterPanActionClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanAction:
|
||||||
|
*
|
||||||
|
* The <structname>ClutterPanAction</structname> structure contains
|
||||||
|
* only private data and should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
struct _ClutterPanAction
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterGestureAction parent_instance;
|
||||||
|
|
||||||
|
ClutterPanActionPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPanActionClass:
|
||||||
|
* @pan: class handler for the #ClutterPanAction::pan signal
|
||||||
|
* @pan_stopped: class handler for the #ClutterPanAction::pan-stopped signal
|
||||||
|
*
|
||||||
|
* The <structname>ClutterPanActionClass</structname> structure contains
|
||||||
|
* only private data.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
struct _ClutterPanActionClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterGestureActionClass parent_class;
|
||||||
|
|
||||||
|
/*< public >*/
|
||||||
|
gboolean (* pan) (ClutterPanAction *action,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gboolean is_interpolated);
|
||||||
|
void (* pan_stopped) (ClutterPanAction *action,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
void (* _clutter_pan_action1) (void);
|
||||||
|
void (* _clutter_pan_action2) (void);
|
||||||
|
void (* _clutter_pan_action3) (void);
|
||||||
|
void (* _clutter_pan_action4) (void);
|
||||||
|
void (* _clutter_pan_action5) (void);
|
||||||
|
void (* _clutter_pan_action6) (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
GType clutter_pan_action_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
ClutterAction * clutter_pan_action_new (void);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
void clutter_pan_action_set_pan_axis (ClutterPanAction *self,
|
||||||
|
ClutterPanAxis axis);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
ClutterPanAxis clutter_pan_action_get_pan_axis (ClutterPanAction *self);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
void clutter_pan_action_set_interpolate (ClutterPanAction *self,
|
||||||
|
gboolean should_interpolate);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
gboolean clutter_pan_action_get_interpolate (ClutterPanAction *self);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
void clutter_pan_action_set_deceleration (ClutterPanAction *self,
|
||||||
|
gdouble rate);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
gdouble clutter_pan_action_get_deceleration (ClutterPanAction *self);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
void clutter_pan_action_set_acceleration_factor (ClutterPanAction *self,
|
||||||
|
gdouble factor);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
gdouble clutter_pan_action_get_acceleration_factor (ClutterPanAction *self);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
void clutter_pan_action_get_interpolated_coords (ClutterPanAction *self,
|
||||||
|
gfloat *interpolated_x,
|
||||||
|
gfloat *interpolated_y);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_12
|
||||||
|
void clutter_pan_action_get_interpolated_delta (ClutterPanAction *self,
|
||||||
|
gfloat *delta_x,
|
||||||
|
gfloat *delta_y);
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_PAN_ACTION_H__ */
|
@ -83,6 +83,7 @@
|
|||||||
#include "clutter-page-turn-effect.h"
|
#include "clutter-page-turn-effect.h"
|
||||||
#include "clutter-paint-nodes.h"
|
#include "clutter-paint-nodes.h"
|
||||||
#include "clutter-paint-node.h"
|
#include "clutter-paint-node.h"
|
||||||
|
#include "clutter-pan-action.h"
|
||||||
#include "clutter-path-constraint.h"
|
#include "clutter-path-constraint.h"
|
||||||
#include "clutter-path.h"
|
#include "clutter-path.h"
|
||||||
#include "clutter-property-transition.h"
|
#include "clutter-property-transition.h"
|
||||||
|
@ -1051,6 +1051,19 @@ clutter_paint_volume_set_origin
|
|||||||
clutter_paint_volume_set_width
|
clutter_paint_volume_set_width
|
||||||
clutter_paint_volume_union_box
|
clutter_paint_volume_union_box
|
||||||
clutter_paint_volume_union
|
clutter_paint_volume_union
|
||||||
|
clutter_pan_axis_get_type
|
||||||
|
clutter_pan_action_get_type
|
||||||
|
clutter_pan_action_get_acceleration_factor
|
||||||
|
clutter_pan_action_get_deceleration
|
||||||
|
clutter_pan_action_get_interpolated_coords
|
||||||
|
clutter_pan_action_get_interpolated_delta
|
||||||
|
clutter_pan_action_get_interpolate
|
||||||
|
clutter_pan_action_get_pan_axis
|
||||||
|
clutter_pan_action_new
|
||||||
|
clutter_pan_action_set_acceleration_factor
|
||||||
|
clutter_pan_action_set_deceleration
|
||||||
|
clutter_pan_action_set_interpolate
|
||||||
|
clutter_pan_action_set_pan_axis
|
||||||
clutter_param_color_get_type
|
clutter_param_color_get_type
|
||||||
clutter_param_fixed_get_type
|
clutter_param_fixed_get_type
|
||||||
clutter_param_spec_color
|
clutter_param_spec_color
|
||||||
|
@ -96,6 +96,7 @@
|
|||||||
<xi:include href="xml/clutter-drag-action.xml"/>
|
<xi:include href="xml/clutter-drag-action.xml"/>
|
||||||
<xi:include href="xml/clutter-drop-action.xml"/>
|
<xi:include href="xml/clutter-drop-action.xml"/>
|
||||||
<xi:include href="xml/clutter-gesture-action.xml"/>
|
<xi:include href="xml/clutter-gesture-action.xml"/>
|
||||||
|
<xi:include href="xml/clutter-pan-action.xml"/>
|
||||||
<xi:include href="xml/clutter-swipe-action.xml"/>
|
<xi:include href="xml/clutter-swipe-action.xml"/>
|
||||||
<xi:include href="xml/clutter-rotate-action.xml"/>
|
<xi:include href="xml/clutter-rotate-action.xml"/>
|
||||||
<xi:include href="xml/clutter-zoom-action.xml"/>
|
<xi:include href="xml/clutter-zoom-action.xml"/>
|
||||||
|
@ -3449,3 +3449,32 @@ CLUTTER_ZOOM_ACTION_GET_CLASS
|
|||||||
ClutterZoomActionPrivate
|
ClutterZoomActionPrivate
|
||||||
clutter_zoom_action_get_type
|
clutter_zoom_action_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>clutter-pan-action</FILE>
|
||||||
|
ClutterPanAction
|
||||||
|
ClutterPanActionClass
|
||||||
|
clutter_pan_action_new
|
||||||
|
ClutterPanAxis
|
||||||
|
clutter_pan_action_set_pan_axis
|
||||||
|
clutter_pan_action_get_pan_axis
|
||||||
|
clutter_pan_action_set_interpolate
|
||||||
|
clutter_pan_action_get_interpolate
|
||||||
|
clutter_pan_action_set_deceleration
|
||||||
|
clutter_pan_action_get_deceleration
|
||||||
|
clutter_pan_action_set_acceleration_factor
|
||||||
|
clutter_pan_action_get_acceleration_factor
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_pan_action_get_interpolated_coords
|
||||||
|
clutter_pan_action_get_interpolated_delta
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_IS_PAN_ACTION
|
||||||
|
CLUTTER_IS_PAN_ACTION_CLASS
|
||||||
|
CLUTTER_TYPE_PAN_ACTION
|
||||||
|
CLUTTER_PAN_ACTION
|
||||||
|
CLUTTER_PAN_ACTION_CLASS
|
||||||
|
CLUTTER_PAN_ACTION_GET_CLASS
|
||||||
|
<SUBSECTION Private>
|
||||||
|
ClutterPanActionPrivate
|
||||||
|
clutter_pan_action_get_type
|
||||||
|
</SECTION>
|
||||||
|
@ -54,6 +54,7 @@ clutter_model_get_type
|
|||||||
clutter_model_iter_get_type
|
clutter_model_iter_get_type
|
||||||
clutter_offscreen_effect_get_type
|
clutter_offscreen_effect_get_type
|
||||||
clutter_page_turn_effect_get_type
|
clutter_page_turn_effect_get_type
|
||||||
|
clutter_pan_action_get_type
|
||||||
clutter_paint_node_get_type
|
clutter_paint_node_get_type
|
||||||
clutter_path_constraint_get_type
|
clutter_path_constraint_get_type
|
||||||
clutter_path_get_type
|
clutter_path_get_type
|
||||||
|
@ -11,6 +11,7 @@ all_examples = \
|
|||||||
flow-layout \
|
flow-layout \
|
||||||
grid-layout \
|
grid-layout \
|
||||||
layout-manager \
|
layout-manager \
|
||||||
|
pan-action \
|
||||||
rounded-rectangle \
|
rounded-rectangle \
|
||||||
scroll-actor \
|
scroll-actor \
|
||||||
threads
|
threads
|
||||||
|
127
examples/pan-action.c
Normal file
127
examples/pan-action.c
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
static ClutterActor *
|
||||||
|
create_content_actor (void)
|
||||||
|
{
|
||||||
|
ClutterActor *content;
|
||||||
|
ClutterContent *image;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
|
content = clutter_actor_new ();
|
||||||
|
clutter_actor_set_size (content, 720, 720);
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", NULL);
|
||||||
|
image = clutter_image_new ();
|
||||||
|
clutter_image_set_data (CLUTTER_IMAGE (image),
|
||||||
|
gdk_pixbuf_get_pixels (pixbuf),
|
||||||
|
gdk_pixbuf_get_has_alpha (pixbuf)
|
||||||
|
? COGL_PIXEL_FORMAT_RGBA_8888
|
||||||
|
: COGL_PIXEL_FORMAT_RGB_888,
|
||||||
|
gdk_pixbuf_get_width (pixbuf),
|
||||||
|
gdk_pixbuf_get_height (pixbuf),
|
||||||
|
gdk_pixbuf_get_rowstride (pixbuf),
|
||||||
|
NULL);
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
clutter_actor_set_content_scaling_filters (content,
|
||||||
|
CLUTTER_SCALING_FILTER_TRILINEAR,
|
||||||
|
CLUTTER_SCALING_FILTER_LINEAR);
|
||||||
|
clutter_actor_set_content_gravity (content, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
|
||||||
|
clutter_actor_set_content (content, image);
|
||||||
|
g_object_unref (image);
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_pan (ClutterPanAction *action,
|
||||||
|
ClutterActor *scroll,
|
||||||
|
gboolean is_interpolated,
|
||||||
|
gpointer *user_data)
|
||||||
|
{
|
||||||
|
gfloat delta_x, delta_y;
|
||||||
|
|
||||||
|
if (is_interpolated)
|
||||||
|
clutter_pan_action_get_interpolated_delta (action, &delta_x, &delta_y);
|
||||||
|
else
|
||||||
|
clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (action), 0, &delta_x, &delta_y);
|
||||||
|
|
||||||
|
g_print ("panning dx:%.2f dy:%.2f\n", delta_x, delta_y);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *
|
||||||
|
create_scroll_actor (ClutterActor *stage)
|
||||||
|
{
|
||||||
|
ClutterActor *scroll;
|
||||||
|
ClutterAction *pan_action;
|
||||||
|
|
||||||
|
/* our scrollable viewport */
|
||||||
|
scroll = clutter_actor_new ();
|
||||||
|
clutter_actor_set_name (scroll, "scroll");
|
||||||
|
|
||||||
|
clutter_actor_add_constraint (scroll, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0));
|
||||||
|
clutter_actor_add_constraint (scroll, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0));
|
||||||
|
|
||||||
|
clutter_actor_add_child (scroll, create_content_actor ());
|
||||||
|
|
||||||
|
pan_action = clutter_pan_action_new ();
|
||||||
|
clutter_pan_action_set_interpolate (CLUTTER_PAN_ACTION (pan_action), TRUE);
|
||||||
|
g_signal_connect (pan_action, "pan", G_CALLBACK (on_pan), NULL);
|
||||||
|
clutter_actor_add_action (scroll, pan_action);
|
||||||
|
|
||||||
|
clutter_actor_set_reactive (scroll, TRUE);
|
||||||
|
|
||||||
|
return scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_key_press (ClutterActor *stage,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer unused)
|
||||||
|
{
|
||||||
|
ClutterActor *scroll;
|
||||||
|
guint key_symbol;
|
||||||
|
|
||||||
|
scroll = clutter_actor_get_first_child (stage);
|
||||||
|
|
||||||
|
key_symbol = clutter_event_get_key_symbol (event);
|
||||||
|
|
||||||
|
if (key_symbol == CLUTTER_KEY_space)
|
||||||
|
clutter_actor_set_child_transform (scroll, NULL);
|
||||||
|
|
||||||
|
return CLUTTER_EVENT_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ClutterActor *stage, *scroll, *info;
|
||||||
|
|
||||||
|
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
/* create a new stage */
|
||||||
|
stage = clutter_stage_new ();
|
||||||
|
clutter_stage_set_title (CLUTTER_STAGE (stage), "Pan Action");
|
||||||
|
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
|
||||||
|
|
||||||
|
scroll = create_scroll_actor (stage);
|
||||||
|
clutter_actor_add_child (stage, scroll);
|
||||||
|
|
||||||
|
info = clutter_text_new_with_text (NULL, "Press <space> to reset the image position.");
|
||||||
|
clutter_actor_add_child (stage, info);
|
||||||
|
clutter_actor_set_position (info, 12, 12);
|
||||||
|
|
||||||
|
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||||
|
g_signal_connect (stage, "key-press-event", G_CALLBACK (on_key_press), scroll);
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_main ();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user