diff options
Diffstat (limited to 'plugins/mouse/gsd-timeline.c')
-rw-r--r-- | plugins/mouse/gsd-timeline.c | 848 |
1 files changed, 0 insertions, 848 deletions
diff --git a/plugins/mouse/gsd-timeline.c b/plugins/mouse/gsd-timeline.c deleted file mode 100644 index 9bcfd2f..0000000 --- a/plugins/mouse/gsd-timeline.c +++ /dev/null @@ -1,848 +0,0 @@ -/* msd-timeline.c - * - * Copyright (C) 2008 Carlos Garnacho <[email protected]> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <glib.h> -#include <gtk/gtk.h> -#include <math.h> -#include "msd-timeline.h" - -#define MSD_TIMELINE_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MSD_TYPE_TIMELINE, MsdTimelinePriv)) -#define MSECS_PER_SEC 1000 -#define FRAME_INTERVAL(nframes) (MSECS_PER_SEC / nframes) -#define DEFAULT_FPS 30 - -typedef struct MsdTimelinePriv MsdTimelinePriv; - -struct MsdTimelinePriv -{ - guint duration; - guint fps; - guint source_id; - - GTimer *timer; - - GdkScreen *screen; - MsdTimelineProgressType progress_type; - MsdTimelineProgressFunc progress_func; - - guint loop : 1; - guint direction : 1; -}; - -enum { - PROP_0, - PROP_FPS, - PROP_DURATION, - PROP_LOOP, - PROP_DIRECTION, - PROP_SCREEN, - PROP_PROGRESS_TYPE, -}; - -enum { - STARTED, - PAUSED, - FINISHED, - FRAME, - LAST_SIGNAL -}; - -static guint signals [LAST_SIGNAL] = { 0, }; - - -static void msd_timeline_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void msd_timeline_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void msd_timeline_finalize (GObject *object); - - -G_DEFINE_TYPE (MsdTimeline, msd_timeline, G_TYPE_OBJECT) - - -GType -msd_timeline_direction_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GEnumValue values[] = { - { MSD_TIMELINE_DIRECTION_FORWARD, "MSD_TIMELINE_DIRECTION_FORWARD", "forward" }, - { MSD_TIMELINE_DIRECTION_BACKWARD, "MSD_TIMELINE_DIRECTION_BACKWARD", "backward" }, - { 0, NULL, NULL } - }; - - type = g_enum_register_static (g_intern_static_string ("MsdTimelineDirection"), values); - } - - return type; -} - -GType -msd_timeline_progress_type_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GEnumValue values[] = { - { MSD_TIMELINE_PROGRESS_LINEAR, "MSD_TIMELINE_PROGRESS_LINEAR", "linear" }, - { MSD_TIMELINE_PROGRESS_SINUSOIDAL, "MSD_TIMELINE_PROGRESS_SINUSOIDAL", "sinusoidal" }, - { MSD_TIMELINE_PROGRESS_EXPONENTIAL, "MSD_TIMELINE_PROGRESS_EXPONENTIAL", "exponential" }, - { 0, NULL, NULL } - }; - - type = g_enum_register_static (g_intern_static_string ("MsdTimelineProgressType"), values); - } - - return type; -} - -static void -msd_timeline_class_init (MsdTimelineClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->set_property = msd_timeline_set_property; - object_class->get_property = msd_timeline_get_property; - object_class->finalize = msd_timeline_finalize; - - g_object_class_install_property (object_class, - PROP_FPS, - g_param_spec_uint ("fps", - "FPS", - "Frames per second for the timeline", - 1, - G_MAXUINT, - DEFAULT_FPS, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_DURATION, - g_param_spec_uint ("duration", - "Animation Duration", - "Animation Duration", - 0, - G_MAXUINT, - 0, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_LOOP, - g_param_spec_boolean ("loop", - "Loop", - "Whether the timeline loops or not", - FALSE, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_DIRECTION, - g_param_spec_enum ("direction", - "Direction", - "Whether the timeline moves forward or backward in time", - MSD_TYPE_TIMELINE_DIRECTION, - MSD_TIMELINE_DIRECTION_FORWARD, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_DIRECTION, - g_param_spec_enum ("progress-type", - "Progress type", - "Type of progress through the timeline", - MSD_TYPE_TIMELINE_PROGRESS_TYPE, - MSD_TIMELINE_PROGRESS_LINEAR, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_SCREEN, - g_param_spec_object ("screen", - "Screen", - "Screen to get the settings from", - GDK_TYPE_SCREEN, - G_PARAM_READWRITE)); - - signals[STARTED] = - g_signal_new ("started", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MsdTimelineClass, started), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[PAUSED] = - g_signal_new ("paused", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MsdTimelineClass, paused), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[FINISHED] = - g_signal_new ("finished", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MsdTimelineClass, finished), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[FRAME] = - g_signal_new ("frame", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MsdTimelineClass, frame), - NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, - G_TYPE_NONE, 1, - G_TYPE_DOUBLE); - - g_type_class_add_private (class, sizeof (MsdTimelinePriv)); -} - -static void -msd_timeline_init (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - priv->fps = DEFAULT_FPS; - priv->duration = 0; - priv->direction = MSD_TIMELINE_DIRECTION_FORWARD; - priv->screen = gdk_screen_get_default (); -} - -static void -msd_timeline_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MsdTimeline *timeline; - MsdTimelinePriv *priv; - - timeline = MSD_TIMELINE (object); - priv = MSD_TIMELINE_GET_PRIV (timeline); - - switch (prop_id) - { - case PROP_FPS: - msd_timeline_set_fps (timeline, g_value_get_uint (value)); - break; - case PROP_DURATION: - msd_timeline_set_duration (timeline, g_value_get_uint (value)); - break; - case PROP_LOOP: - msd_timeline_set_loop (timeline, g_value_get_boolean (value)); - break; - case PROP_DIRECTION: - msd_timeline_set_direction (timeline, g_value_get_enum (value)); - break; - case PROP_SCREEN: - msd_timeline_set_screen (timeline, - GDK_SCREEN (g_value_get_object (value))); - break; - case PROP_PROGRESS_TYPE: - msd_timeline_set_progress_type (timeline, g_value_get_enum (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -msd_timeline_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MsdTimeline *timeline; - MsdTimelinePriv *priv; - - timeline = MSD_TIMELINE (object); - priv = MSD_TIMELINE_GET_PRIV (timeline); - - switch (prop_id) - { - case PROP_FPS: - g_value_set_uint (value, priv->fps); - break; - case PROP_DURATION: - g_value_set_uint (value, priv->duration); - break; - case PROP_LOOP: - g_value_set_boolean (value, priv->loop); - break; - case PROP_DIRECTION: - g_value_set_enum (value, priv->direction); - break; - case PROP_SCREEN: - g_value_set_object (value, priv->screen); - break; - case PROP_PROGRESS_TYPE: - g_value_set_enum (value, priv->progress_type); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -msd_timeline_finalize (GObject *object) -{ - MsdTimelinePriv *priv; - - priv = MSD_TIMELINE_GET_PRIV (object); - - if (priv->source_id) - { - g_source_remove (priv->source_id); - priv->source_id = 0; - } - - if (priv->timer) - g_timer_destroy (priv->timer); - - G_OBJECT_CLASS (msd_timeline_parent_class)->finalize (object); -} - -/* Sinusoidal progress */ -static gdouble -sinusoidal_progress (gdouble progress) -{ - return (sinf ((progress * G_PI) / 2)); -} - -static gdouble -exponential_progress (gdouble progress) -{ - return progress * progress; -} - -static MsdTimelineProgressFunc -progress_type_to_func (MsdTimelineProgressType type) -{ - if (type == MSD_TIMELINE_PROGRESS_SINUSOIDAL) - return sinusoidal_progress; - else if (type == MSD_TIMELINE_PROGRESS_EXPONENTIAL) - return exponential_progress; - - return NULL; -} - -static gboolean -msd_timeline_run_frame (MsdTimeline *timeline, - gboolean enable_animations) -{ - MsdTimelinePriv *priv; - gdouble linear_progress, progress; - guint elapsed_time; - MsdTimelineProgressFunc progress_func = NULL; - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - if (enable_animations) - { - elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000); - - linear_progress = (gdouble) elapsed_time / priv->duration; - - if (priv->direction == MSD_TIMELINE_DIRECTION_BACKWARD) - linear_progress = 1 - linear_progress; - - linear_progress = CLAMP (linear_progress, 0., 1.); - - if (priv->progress_func) - progress_func = priv->progress_func; - else if (priv->progress_type) - progress_func = progress_type_to_func (priv->progress_type); - - if (progress_func) - progress = (progress_func) (linear_progress); - else - progress = linear_progress; - } - else - progress = (priv->direction == MSD_TIMELINE_DIRECTION_FORWARD) ? 1.0 : 0.0; - - g_signal_emit (timeline, signals [FRAME], 0, - CLAMP (progress, 0.0, 1.0)); - - if ((priv->direction == MSD_TIMELINE_DIRECTION_FORWARD && progress >= 1.0) || - (priv->direction == MSD_TIMELINE_DIRECTION_BACKWARD && progress <= 0.0)) - { - if (!priv->loop) - { - if (priv->source_id) - { - g_source_remove (priv->source_id); - priv->source_id = 0; - } - - g_signal_emit (timeline, signals [FINISHED], 0); - return FALSE; - } - else - msd_timeline_rewind (timeline); - } - - return TRUE; -} - -static gboolean -msd_timeline_frame_idle_func (MsdTimeline *timeline) -{ - return msd_timeline_run_frame (timeline, TRUE); -} - -/** - * msd_timeline_new: - * @duration: duration in milliseconds for the timeline - * - * Creates a new #MsdTimeline with the specified number of frames. - * - * Return Value: the newly created #MsdTimeline - **/ -MsdTimeline * -msd_timeline_new (guint duration) -{ - return g_object_new (MSD_TYPE_TIMELINE, - "duration", duration, - NULL); -} - -MsdTimeline * -msd_timeline_new_for_screen (guint duration, - GdkScreen *screen) -{ - return g_object_new (MSD_TYPE_TIMELINE, - "duration", duration, - "screen", screen, - NULL); -} - -/** - * msd_timeline_start: - * @timeline: A #MsdTimeline - * - * Runs the timeline from the current frame. - **/ -void -msd_timeline_start (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - GtkSettings *settings; - gboolean enable_animations = FALSE; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - if (priv->screen) - { - settings = gtk_settings_get_for_screen (priv->screen); - g_object_get (settings, "gtk-enable-animations", &enable_animations, NULL); - } - - if (enable_animations) - { - if (!priv->source_id) - { - if (priv->timer) - g_timer_continue (priv->timer); - else - priv->timer = g_timer_new (); - - /* sanity check */ - g_assert (priv->fps > 0); - - g_signal_emit (timeline, signals [STARTED], 0); - - priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps), - (GSourceFunc) msd_timeline_frame_idle_func, - timeline); - } - } - else - { - /* If animations are not enabled, only run the last frame, - * it take us instantaneously to the last state of the animation. - * The only potential flaw happens when people use the ::finished - * signal to trigger another animation, or even worse, finally - * loop into this animation again. - */ - g_signal_emit (timeline, signals [STARTED], 0); - msd_timeline_run_frame (timeline, FALSE); - } -} - -/** - * msd_timeline_pause: - * @timeline: A #MsdTimeline - * - * Pauses the timeline. - **/ -void -msd_timeline_pause (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - if (priv->source_id) - { - g_source_remove (priv->source_id); - priv->source_id = 0; - g_timer_stop (priv->timer); - g_signal_emit (timeline, signals [PAUSED], 0); - } -} - -/** - * msd_timeline_rewind: - * @timeline: A #MsdTimeline - * - * Rewinds the timeline. - **/ -void -msd_timeline_rewind (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - /* destroy and re-create timer if neccesary */ - if (priv->timer) - { - g_timer_destroy (priv->timer); - - if (msd_timeline_is_running (timeline)) - priv->timer = g_timer_new (); - else - priv->timer = NULL; - } -} - -/** - * msd_timeline_is_running: - * @timeline: A #MsdTimeline - * - * Returns whether the timeline is running or not. - * - * Return Value: %TRUE if the timeline is running - **/ -gboolean -msd_timeline_is_running (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), FALSE); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - return (priv->source_id != 0); -} - -/** - * msd_timeline_get_fps: - * @timeline: A #MsdTimeline - * - * Returns the number of frames per second. - * - * Return Value: frames per second - **/ -guint -msd_timeline_get_fps (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), 1); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - return priv->fps; -} - -/** - * msd_timeline_set_fps: - * @timeline: A #MsdTimeline - * @fps: frames per second - * - * Sets the number of frames per second that - * the timeline will play. - **/ -void -msd_timeline_set_fps (MsdTimeline *timeline, - guint fps) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - g_return_if_fail (fps > 0); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - priv->fps = fps; - - if (msd_timeline_is_running (timeline)) - { - g_source_remove (priv->source_id); - priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps), - (GSourceFunc) msd_timeline_run_frame, - timeline); - } - - g_object_notify (G_OBJECT (timeline), "fps"); -} - -/** - * msd_timeline_get_loop: - * @timeline: A #MsdTimeline - * - * Returns whether the timeline loops to the - * beginning when it has reached the end. - * - * Return Value: %TRUE if the timeline loops - **/ -gboolean -msd_timeline_get_loop (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), FALSE); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - return priv->loop; -} - -/** - * msd_timeline_set_loop: - * @timeline: A #MsdTimeline - * @loop: %TRUE to make the timeline loop - * - * Sets whether the timeline loops to the beginning - * when it has reached the end. - **/ -void -msd_timeline_set_loop (MsdTimeline *timeline, - gboolean loop) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - priv->loop = loop; - - g_object_notify (G_OBJECT (timeline), "loop"); -} - -void -msd_timeline_set_duration (MsdTimeline *timeline, - guint duration) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - priv->duration = duration; - - g_object_notify (G_OBJECT (timeline), "duration"); -} - -guint -msd_timeline_get_duration (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), 0); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - return priv->duration; -} - -/** - * msd_timeline_get_direction: - * @timeline: A #MsdTimeline - * - * Returns the direction of the timeline. - * - * Return Value: direction - **/ -MsdTimelineDirection -msd_timeline_get_direction (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), MSD_TIMELINE_DIRECTION_FORWARD); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - return priv->direction; -} - -/** - * msd_timeline_set_direction: - * @timeline: A #MsdTimeline - * @direction: direction - * - * Sets the direction of the timeline. - **/ -void -msd_timeline_set_direction (MsdTimeline *timeline, - MsdTimelineDirection direction) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - priv->direction = direction; - - g_object_notify (G_OBJECT (timeline), "direction"); -} - -GdkScreen * -msd_timeline_get_screen (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), NULL); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - return priv->screen; -} - -void -msd_timeline_set_screen (MsdTimeline *timeline, - GdkScreen *screen) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - g_return_if_fail (GDK_IS_SCREEN (screen)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - if (priv->screen) - g_object_unref (priv->screen); - - priv->screen = g_object_ref (screen); - - g_object_notify (G_OBJECT (timeline), "screen"); -} - -void -msd_timeline_set_progress_type (MsdTimeline *timeline, - MsdTimelineProgressType type) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - priv->progress_type = type; - - g_object_notify (G_OBJECT (timeline), "progress-type"); -} - -MsdTimelineProgressType -msd_timeline_get_progress_type (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), MSD_TIMELINE_PROGRESS_LINEAR); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - if (priv->progress_func) - return MSD_TIMELINE_PROGRESS_LINEAR; - - return priv->progress_type; -} - -/** - * msd_timeline_set_progress_func: - * @timeline: A #MsdTimeline - * @progress_func: progress function - * - * Sets the progress function. This function will be used to calculate - * a different progress to pass to the ::frame signal based on the - * linear progress through the timeline. Setting progress_func - * to %NULL will make the timeline use the default function, - * which is just a linear progress. - * - * All progresses are in the [0.0, 1.0] range. - **/ -void -msd_timeline_set_progress_func (MsdTimeline *timeline, - MsdTimelineProgressFunc progress_func) -{ - MsdTimelinePriv *priv; - - g_return_if_fail (MSD_IS_TIMELINE (timeline)); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - priv->progress_func = progress_func; -} - -gdouble -msd_timeline_get_progress (MsdTimeline *timeline) -{ - MsdTimelinePriv *priv; - MsdTimelineProgressFunc progress_func = NULL; - gdouble linear_progress, progress; - guint elapsed_time; - - g_return_val_if_fail (MSD_IS_TIMELINE (timeline), 0.0); - - priv = MSD_TIMELINE_GET_PRIV (timeline); - - if (!priv->timer) - return 0.; - - elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000); - - linear_progress = (gdouble) elapsed_time / priv->duration; - - if (priv->direction == MSD_TIMELINE_DIRECTION_BACKWARD) - linear_progress = 1 - linear_progress; - - linear_progress = CLAMP (linear_progress, 0., 1.); - - if (priv->progress_func) - progress_func = priv->progress_func; - else if (priv->progress_type) - progress_func = progress_type_to_func (priv->progress_type); - - if (progress_func) - progress = (progress_func) (linear_progress); - else - progress = linear_progress; - - return CLAMP (progress, 0., 1.); -} |