diff options
Diffstat (limited to 'src/animate-timer.vala')
-rw-r--r-- | src/animate-timer.vala | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/animate-timer.vala b/src/animate-timer.vala new file mode 100644 index 0000000..d5aaf71 --- /dev/null +++ b/src/animate-timer.vala @@ -0,0 +1,154 @@ +/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 4 -*- + * + * Copyright (C) 2011,2012 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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, see <http://www.gnu.org/licenses/>. + * + * Authors: Robert Ancell <robert.ancell@canonical.com> + * Michael Terry <michael.terry@canonical.com> + */ + +private class AnimateTimer : Object +{ + /* x and y are 0.0 to 1.0 */ + public delegate double EasingFunc (double x); + + /* The following are the same intervals that Unity uses */ + public static const int INSTANT = 150; /* Good for animations that don't convey any information */ + public static const int FAST = 250; /* Good for animations that convey duplicated information */ + public static const int NORMAL = 500; + public static const int SLOW = 1000; /* Good for animations that convey information that is only presented in the animation */ + + /* speed is in milliseconds */ + public unowned EasingFunc easing_func { get; private set; } + public int speed { get; set; } + public bool is_running { get { return timeout != 0; } } + public double progress { get; private set; } + + /* progress is from 0.0 to 1.0 */ + public signal void animate (double progress); + + /* AnimateTimer requires two things: an easing function and a speed. + + The speed is just the duration of the animation in milliseconds. + + The easing function describes how fast the animation occurs at different + parts of the duration. + + See http://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html + for examples of various easing functions. + + A few are provided with this class, notably ease_in_out and + ease_out_quint. + */ + /* speed is in milliseconds */ + public AnimateTimer (EasingFunc func, int speed) + { + Object (speed: speed); + this.easing_func = func; + } + + ~AnimateTimer () + { + stop (); + } + + /* temp_speed is in milliseconds */ + public void reset (int temp_speed = -1) + { + stop (); + + timeout = Timeout.add (16, animate_cb); + progress = 0; + start_time = 0; + extra_time = 0; + extra_progress = 0; + + if (temp_speed == -1) + temp_speed = speed; + + length = temp_speed * TimeSpan.MILLISECOND; + } + + public void stop () + { + if (timeout != 0) + Source.remove (timeout); + timeout = 0; + } + + private uint timeout = 0; + private TimeSpan start_time = 0; + private TimeSpan length = 0; + private TimeSpan extra_time = 0; + private double extra_progress = 0.0; + + private bool animate_cb () + { + if (start_time == 0) + start_time = GLib.get_monotonic_time (); + + var time_progress = normalize_time (GLib.get_monotonic_time ()); + progress = calculate_progress (time_progress); + animate (progress); + + if (time_progress >= 1.0) + { + timeout = 0; + return false; + } + else + return true; + } + + /* Returns 0.0 to 1.0 where 1.0 is at or past end_time */ + private double normalize_time (TimeSpan now) + { + if (length == 0) + return 1.0f; + + return (((double)(now - start_time)) / length).clamp (0.0, 1.0); + } + + /* Returns 0.0 to 1.0 where 1.0 is done. + time is not normalized yet! */ + private double calculate_progress (double time_progress) + { + var y = easing_func (time_progress); + return y.clamp (0.0, 1.0); + } + + public static double ease_in_out (double x) + { + return (1 - Math.cos (Math.PI * x)) / 2; + } + + /*public static double ease_in_quad (double x) + { + return Math.pow (x, 2); + }*/ + /*public static double ease_out_quad (double x) + { + return -1 * Math.pow (x - 1, 2) + 1; + }*/ + + /*public static double ease_in_quint (double x) + { + return Math.pow (x, 5); + }*/ + public static double ease_out_quint (double x) + { + return Math.pow (x - 1, 5) + 1; + } +} + |