[Pkg-mozext-commits] [firetray] 368/399: use |yield| in addition to nested timers for ChatStatusIcon fading

David Prévot taffit at alioth.debian.org
Tue Oct 29 18:24:16 UTC 2013


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch dfsg-clean
in repository firetray.

commit 2e064cae9966049fcca123234d202c95eafc1aa2
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Wed May 1 15:44:52 2013 +0200

    use |yield| in addition to nested timers for ChatStatusIcon fading
    
    http://syzygy.st/javascript-coroutines/ is worth mentioning
---
 src/modules/linux/FiretrayChatStatusIcon.jsm |  129 ++++++++++++++------------
 1 file changed, 69 insertions(+), 60 deletions(-)

diff --git a/src/modules/linux/FiretrayChatStatusIcon.jsm b/src/modules/linux/FiretrayChatStatusIcon.jsm
index f953541..a8e51d0 100644
--- a/src/modules/linux/FiretrayChatStatusIcon.jsm
+++ b/src/modules/linux/FiretrayChatStatusIcon.jsm
@@ -93,14 +93,6 @@ firetray.ChatStatusIcon = {
     gtk.gtk_status_icon_set_from_pixbuf(this.trayIcon, null);
   },
 
-  /**
-   * EXPERIMENTAL fancy blinking.
-   * TODO: how to wait for last fade in to restore themedIconNameCurrent
-   */
-  startCrossFade: function() {
-    this.crossFade(this.buildPixBuf());
-  },
-
   buildPixBuf: function() {
     let icon_theme = gtk.gtk_icon_theme_get_for_screen(gdk.gdk_screen_get_default());
 
@@ -126,15 +118,10 @@ firetray.ChatStatusIcon = {
     if (n_channels != 4)
       log.error("wrong nb of channels for pixbuf");
 
-    return pixbuf;              // TO BE UNREFED WITH to g_object_unref() !!
-  },
-
-  crossFade: function(pixbuf) {
     // init transform
     let width = gdk.gdk_pixbuf_get_width(pixbuf);
     let height = gdk.gdk_pixbuf_get_height(pixbuf);
     log.debug("width="+width+", height="+height);
-    let n_channels = gdk.gdk_pixbuf_get_n_channels(pixbuf);
     let length = width*height*n_channels;
     let pixels = ctypes.cast(gdk.gdk_pixbuf_get_pixels(pixbuf),
                              gobject.guchar.array(length).ptr);
@@ -146,61 +133,83 @@ firetray.ChatStatusIcon = {
     for (let i=3; i<length; i+=n_channels)
       alpha_bak[(i-3)/n_channels] = pixels.contents[i];
 
-    const ALPHA_STEP = 5;
-    let timers = [];
-
-    function fadeIn(alpha) {
-      for(let i=3; i<length; i+=n_channels)
-        if (pixels.contents[i]+ALPHA_STEP<=alpha_bak[(i-3)/n_channels]) {
-          pixels.contents[i] += ALPHA_STEP;
-        }
-      log.info("gtk_status_icon_set_from_pixbuf="+pixbuf);
-      gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, pixbuf);
-
-      if (alpha < 255) {
-        alpha += ALPHA_STEP;
-        timers.push(firetray.Utils.timer(10, Ci.nsITimer.TYPE_ONE_SHOT,
-                                         function(){fadeIn(alpha);}));
-
-      } else {
-        if (firetray.ChatStatusIcon.events['stop-cross-fade']) {
-          delete firetray.ChatStatusIcon.events['stop-cross-fade'];
-          firetray.ChatStatusIcon.setIconImage(firetray.ChatStatusIcon.themedIconNameCurrent);
-          return;
+    let ret = {
+      pixbuf: pixbuf,           // TO BE UNREFED WITH to g_object_unref() !!
+      width: width,
+      height: height,
+      length: length,
+      n_channels: n_channels,
+      pixels: pixels,
+      buffer: buffer,
+      alpha_bak: alpha_bak
+    };
+
+    return ret;
+  },
+  dropPixBuf: function(p) {
+    gobject.g_object_unref(p.pixbuf); // FIXME: not sure if this shouldn't be done at 'stop-cross-fade'
+    log.info("pixbuf unref'd");
+  },
 
-        } else if (firetray.ChatStatusIcon.events['icon-changed']) {
-          delete firetray.ChatStatusIcon.events['icon-changed'];
-          firetray.ChatStatusIcon.crossFade(firetray.ChatStatusIcon.buildPixBuf());
-          return;
+  startCrossFade: function() {  // TODO: Foudil: rename to startFading
+    const ALPHA_STEP                    = 5;
+    const ALPHA_STEP_SLEEP_MILLISECONDS = 10;
+    const FADE_OVER_SLEEP_MILLISECONDS  = 500;
+
+    function fadeGen(p) {
+      for (let a=255; a>0; a-=ALPHA_STEP) {
+        for(let i=3; i<p.length; i+=p.n_channels)
+          if (p.pixels.contents[i]-ALPHA_STEP>0)
+            p.pixels.contents[i] -= ALPHA_STEP;
+        gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, p.pixbuf);
+        yield true;
+      }
 
-        } else {
-          timers.push(firetray.Utils.timer(500, Ci.nsITimer.TYPE_ONE_SHOT,
-                                           function(){fadeOut(255);}));
-        }
+      for (let a=255; a>0; a-=ALPHA_STEP) {
+        for(let i=3; i<p.length; i+=p.n_channels)
+          if (p.pixels.contents[i]+ALPHA_STEP<=p.alpha_bak[(i-3)/p.n_channels]) {
+            p.pixels.contents[i] += ALPHA_STEP;
+          }
+        gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, p.pixbuf);
+        yield true;
       }
     }
 
-    function fadeOut(alpha) {
-      for(let i=3; i<length; i+=n_channels)
-        if (pixels.contents[i]-ALPHA_STEP>0)
-          pixels.contents[i] -= ALPHA_STEP;
-      log.info("gtk_status_icon_set_from_pixbuf="+pixbuf);
-      gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, pixbuf);
-
-      if (alpha > 0) {
-        alpha -= ALPHA_STEP;
-        timers.push(firetray.Utils.timer(10, Ci.nsITimer.TYPE_ONE_SHOT,
-                                         function(){fadeOut(alpha);}));
+    function fadeLoop(p) {
+
+      let fadeOutfadeIn = fadeGen(p);
+      (function step() {
+        try {
+          if (fadeOutfadeIn.next())
+            firetray.Utils.timer(ALPHA_STEP_SLEEP_MILLISECONDS,
+                                 Ci.nsITimer.TYPE_ONE_SHOT, step);
+        } catch (e if e instanceof StopIteration) {
+
+          if (firetray.ChatStatusIcon.events['stop-cross-fade']) {
+            delete firetray.ChatStatusIcon.events['stop-cross-fade'];
+            firetray.ChatStatusIcon.setIconImage(firetray.ChatStatusIcon.themedIconNameCurrent);
+            return;
+          }
+
+          if (firetray.ChatStatusIcon.events['icon-changed']) {
+            delete firetray.ChatStatusIcon.events['icon-changed'];
+            firetray.ChatStatusIcon.dropPixBuf(p);
+            let newPixbufObj = firetray.ChatStatusIcon.buildPixBuf();
+            firetray.Utils.timer(FADE_OVER_SLEEP_MILLISECONDS,
+                                 Ci.nsITimer.TYPE_ONE_SHOT, function(){fadeLoop(newPixbufObj);});
+
+          } else {
+            firetray.Utils.timer(FADE_OVER_SLEEP_MILLISECONDS,
+                                 Ci.nsITimer.TYPE_ONE_SHOT, function(){fadeLoop(p);});
+          }
+        };
+      })();
 
-      } else {
-        fadeIn(0);
-      }
     }
+    let pixbufObj = this.buildPixBuf();
+    fadeLoop(pixbufObj);
 
-    fadeOut(255);
-
-    gobject.g_object_unref(pixbuf); // FIXME: not sure if this shouldn't be done at 'stop-cross-fade'
-    log.info("pixbuf unref'd");
+    firetray.ChatStatusIcon.dropPixBuf(pixbufObj);
   },
 
   startIconBlinking: function() { // gtk_status_icon_set_blinking() deprecated

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firetray.git



More information about the Pkg-mozext-commits mailing list