From 007b6ca2e870e607e18c0a989fcb307f7ccca096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 10 Jun 2017 02:52:12 +0200 Subject: [PATCH] environment: Add convenience method for implicit animations Setting up implicit animations is more verbose than using tweener, in particular when setting up a callbacks to run on overwrite or completion. In order to make its use more convenient, monkey-patch ClutterActor with an ease() method that works similarly to Tweener.addTween(). https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/22 --- js/ui/environment.js | 71 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/js/ui/environment.js b/js/ui/environment.js index a1ffd60e5..d36521736 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -58,6 +58,73 @@ function _patchLayoutClass(layoutClass, styleProps) { }; } +let _easingTransitions = new Map(); + +function _trackTransition(transition, callback) { + if (_easingTransitions.has(transition)) + transition.disconnect(_easingTransitions.get(transition)); + + let id = transition.connect('stopped', isFinished => { + _easingTransitions.delete(transition); + callback(isFinished); + }); + + _easingTransitions.set(transition, id); +} + +function _makeEaseCallback(params) { + let onComplete = params.onComplete; + delete params.onComplete; + + let onStopped = params.onStopped; + delete params.onStopped; + + if (!onComplete && !onStopped) + return null; + + return isFinished => { + if (onStopped) + onStopped(isFinished); + if (onComplete && isFinished) + onComplete(); + }; +} + +function _easeActor(actor, params) { + actor.save_easing_state(); + + if (params.duration != undefined) + actor.set_easing_duration(params.duration); + delete params.duration; + + if (params.delay != undefined) + actor.set_easing_delay(params.delay); + delete params.delay; + + if (params.mode != undefined) + actor.set_easing_mode(params.mode); + delete params.mode; + + let callback = _makeEaseCallback(params); + + // cancel overwritten transitions + let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g')); + animatedProps.forEach(p => actor.remove_transition(p)); + + actor.set(params); + + if (callback) { + let transition = actor.get_transition(animatedProps[0]); + + if (transition) + _trackTransition(transition, callback); + else + callback(true); + } + + actor.restore_easing_state(); +} + function _loggingFunc(...args) { let fields = { 'MESSAGE': args.join(', ') }; let domain = "GNOME Shell"; @@ -103,6 +170,10 @@ function init() { origSetEasingDelay.call(this, adjustAnimationTime(msecs)); }; + Clutter.Actor.prototype.ease = function(props, easingParams) { + _easeActor(this, props, easingParams); + }; + Clutter.Actor.prototype.toString = function() { return St.describe_actor(this); };