[gnome-shell] environment: Add convenience method for property transitions



commit ef18f621ac58c6ce3071572751584b7e6f833d90
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Jun 10 04:14:12 2017 +0200

    environment: Add convenience method for property transitions
    
    While we are now using implicit animations for all animatable properties,
    there are still some cases where we animate other actor properties (for
    example from a custom subclass) or associated objects like effects.
    
    Those can still be animated using Clutter animations, as long as we use
    the explicit API rather than implicit animations. Again this API is
    cumbersome and tricky enough to warrant a convenience wrapper.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/666

 js/ui/environment.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)
---
diff --git a/js/ui/environment.js b/js/ui/environment.js
index d36521736..b00b74dd9 100644
--- a/js/ui/environment.js
+++ b/js/ui/environment.js
@@ -90,6 +90,25 @@ function _makeEaseCallback(params) {
     };
 }
 
+function _getPropertyTarget(actor, propName) {
+    if (!propName.startsWith('@'))
+        return [actor, propName];
+
+    let [type, name, prop] = propName.split('.');
+    switch (type) {
+    case '@layout':
+        return [actor.layout_manager, name];
+    case '@actions':
+        return [actor.get_action(name), prop];
+    case '@constraints':
+        return [actor.get_constraint(name), prop];
+    case '@effects':
+        return [actor.get_effect(name), prop];
+    }
+
+    throw new Error(`Invalid property name ${propName}`);
+}
+
 function _easeActor(actor, params) {
     actor.save_easing_state();
 
@@ -125,6 +144,45 @@ function _easeActor(actor, params) {
     actor.restore_easing_state();
 }
 
+function _easeActorProperty(actor, propName, target, params) {
+    // Avoid pointless difference with ease()
+    if (params.mode)
+        params.progress_mode = params.mode;
+    delete params.mode;
+
+    if (params.duration)
+        params.duration = adjustAnimationTime(params.duration);
+    let duration = Math.floor(params.duration || 0);
+
+    let callback = _makeEaseCallback(params);
+
+    // cancel overwritten transition
+    actor.remove_transition(propName);
+
+    if (duration == 0) {
+        let [obj, prop] = _getPropertyTarget(actor, propName);
+        obj[prop] = target;
+
+        if (callback)
+            callback(true);
+
+        return;
+    }
+
+    let pspec = actor.find_property(propName);
+    let transition = new Clutter.PropertyTransition(Object.assign({
+        property_name: propName,
+        interval: new Clutter.Interval({ value_type: pspec.value_type }),
+        remove_on_complete: true
+    }, params));
+    actor.add_transition(propName, transition);
+
+    transition.set_to(target);
+
+    if (callback)
+        _trackTransition(transition, callback);
+}
+
 function _loggingFunc(...args) {
     let fields = { 'MESSAGE': args.join(', ') };
     let domain = "GNOME Shell";
@@ -173,6 +231,9 @@ function init() {
     Clutter.Actor.prototype.ease = function(props, easingParams) {
         _easeActor(this, props, easingParams);
     };
+    Clutter.Actor.prototype.ease_property = function(propName, target, params) {
+        _easeActorProperty(this, propName, target, params);
+    };
 
     Clutter.Actor.prototype.toString = function() {
         return St.describe_actor(this);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]