diff --git a/js/ui/environment.js b/js/ui/environment.js index eeae4bce8..4f28c9c30 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -63,6 +63,54 @@ function _adjustEasingTime(msecs) { return St.get_slow_down_factor() * msecs; } +function _easeActor(actor, props, easingParams) { + let { duration, delay, mode, + onStopped, onUpdate, onComplete } = easingParams; + + let animatedProps = Object.keys(props).map(p => p.replace('_', '-', 'g')); + + actor.save_easing_state(); + + if (duration) + actor.set_easing_duration(duration); + + if (delay) + actor.set_easing_delay(delay); + + if (mode) + actor.set_easing_mode(mode); + + actor.set(props); + + if (onUpdate || onComplete || onStopped) { + let transition = actor.get_transition(animatedProps[0]); + + if (transition) { + let updateId = 0; + if (onUpdate) + updateId = transition.connect('new-frame', onUpdate); + + let id = transition.connect('stopped', isFinished => { + if (updateId != 0) + transition.disconnect(updateId); + transition.disconnect(id); + + if (onComplete) + onComplete(); + if (onStopped) + onStopped(isFinished); + }); + } else { + if (onComplete) + onComplete(); + if (onStopped) + onStopped(true); + } + } + + actor.restore_easing_state(); +} + function _loggingFunc() { let fields = {'MESSAGE': [].join.call(arguments, ', ')}; let domain = "GNOME Shell"; @@ -108,6 +156,10 @@ function init() { origSetEasingDelay.call(this, _adjustEasingTime(msecs)); }; + Clutter.Actor.prototype.ease = function(props, easingParams) { + _easeActor(this, props, easingParams); + }; + Clutter.Actor.prototype.toString = function() { return St.describe_actor(this); };