Hello, Jérôme!

On Fri, 2008-02-22 at 08:42 +0100, [EMAIL PROTECTED] wrote:
> I first tried the method you described with drawing qith pycairo.
> Unfortunately - it certainly due to my inexperience - I noticed while
> it's easy to draw a rectangle on a pixmap (bit image), it was more
> complicated on a pixbuf (vectorial image, like the icon is and should
> stay), and I did not succed. 
> Show me the way then I'll try again and we will compare the 2 methods.
> 
> On the other side, composing with svg with so simple image seems to be
> efficient, and one who would change the progress bar appareance would
> only have to deal with svg images and not with python coding.

Attached is the patch that does the progress bar on the tray icon thing
using Cairo. Please have a look. I am not sure about the colors, maybe
you can come up with better-suited ones (changeable in
src/gpodder/draw.py in 0.0-1.0 RGBA values).

Also, there seems to be a mysterious bug that doesn't remove the arrow
from the icon when stopping downloads.

Enjoy,
Thomas
Index: src/gpodder/trayicon.py
===================================================================
--- src/gpodder/trayicon.py	(revision 579)
+++ src/gpodder/trayicon.py	(working copy)
@@ -38,6 +38,7 @@
 
 from gpodder import services
 from gpodder import util
+from gpodder import draw
 
 from libgpodder import gPodderLib
 
@@ -88,6 +89,8 @@
             self.__icon = gtk.icon_theme_get_default().load_icon(gtk.STOCK_DIALOG_QUESTION, 30, 30)
 
         # Reset trayicon (default icon, default tooltip)
+        self.__current_pixbuf = None
+        self.__last_ratio = 0.0
         self.set_status()
 
         self.connect('activate', self.__on_left_click)
@@ -215,6 +218,8 @@
                 tooltip.append(self.format_episode_list(self.__finished_downloads, _('Finished downloads:')))
 
             self.set_status(self.STATUS_DOWNLOAD_IN_PROGRESS, ''.join(tooltip))
+            
+            self.progress_bar(float(percentage)/100.)
         else:
             self.__is_downloading = False
             self.__download_start_time = None
@@ -306,7 +311,8 @@
             else:
                 tooltip = 'gPodder - %s' % tooltip
             if self.__current_icon is not None:
-                self.set_from_pixbuf(self.__icon)
+                self.current_pixbuf = self.__icon
+                self.set_from_pixbuf(self.__current_pixbuf)
                 self.__current_icon = None
         else:
             (status_tooltip, icon) = status
@@ -315,17 +321,26 @@
             else:
                 tooltip = 'gPodder - %s' % tooltip
             if self.__current_icon != icon:
-                self.set_from_pixbuf(self.__get_status_icon(icon))
+                self.__current_pixbuf = self.__get_status_icon(icon)
+                self.set_from_pixbuf(self.__current_pixbuf)
                 self.__current_icon = icon
         self.set_tooltip(tooltip)
 
     def format_episode_list(self, episode_list, caption=''):
-        """Format a list of episodes for tooltips and notifications
-        The parameter "episode_list" can either be a list containing
-        podcastItem objects or a list of strings.
+        """
+        Format a list of episodes for tooltips and notifications
+        Return a listing of episodes title separated by a line break.
+        Long title are troncated: "xxxx...xxxx"
+        If the list is too long, it is cut and the string "x others episodes" is append
+        
+        episode_list
+            can be either a list containing podcastItem objects 
+            or a list of strings of episode's title.
 
-        A formatted list of episodes is returned.
+        return
+            the formatted list of episodes as a string
         """
+        
         MAX_EPISODES = 10
         MAX_TITLE_LENGTH = 100
 
@@ -384,5 +399,24 @@
             self.send_notification(_('Your device has been updated by gPodder.'), _('Operation finished'))
         self.set_status()
         
+    def progress_bar(self, ratio):
+        """
+        draw a progress bar on top of the tray icon.
+        Be sure to call this method the first time with ratio=0
+        in order to initialise background image
+            
+        ratio
+            value between 0 and 1 (inclusive) indicating the ratio 
+            of the progress bar to be drawn
+                
+        """
+        if ratio == self.__last_ratio:
+            return
 
+        icon = self.__current_pixbuf.copy()
+        progressbar = draw.progressbar_pixbuf(icon.get_width(), icon.get_height(), ratio)
+        progressbar.composite(icon, 0, 0, icon.get_width(), icon.get_height(), 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
         
+        self.set_from_pixbuf(icon)
+        self.__last_ratio = ratio
+
Index: src/gpodder/draw.py
===================================================================
--- src/gpodder/draw.py	(revision 579)
+++ src/gpodder/draw.py	(working copy)
@@ -125,7 +125,14 @@
 
 
 def draw_pill_pixbuf(left_text, right_text):
-    s = draw_text_pill(left_text, right_text)
+    return cairo_surface_to_pixbuf(draw_text_pill(left_text, right_text))
+
+
+def cairo_surface_to_pixbuf(s):
+    """
+    Converts a Cairo surface to a Gtk Pixbuf by
+    encoding it as PNG and using the PixbufLoader.
+    """
     sio = StringIO.StringIO()
     try:
         s.write_to_png(sio)
@@ -144,3 +151,39 @@
     pixbuf = pbl.get_pixbuf()
     return pixbuf
 
+
+def progressbar_pixbuf(width, height, percentage):
+    COLOR_BG = (.4, .4, .4, .4)
+    COLOR_FG = (.2, .9, .2, 1.)
+    COLOR_FG_HIGH = (1., 1., 1., .5)
+    COLOR_BORDER = (0., 0., 0., 1.)
+
+    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+    ctx = cairo.Context(surface)
+
+    padding = int(float(width)/8.0)
+    bar_width = 2*padding
+    bar_height = height - 2*padding
+    bar_height_fill = bar_height*percentage
+
+    # Background
+    ctx.rectangle(padding, padding, bar_width, bar_height)
+    ctx.set_source_rgba(*COLOR_BG)
+    ctx.fill()
+
+    # Foreground
+    ctx.rectangle(padding, padding+bar_height-bar_height_fill, bar_width, bar_height_fill)
+    ctx.set_source_rgba(*COLOR_FG)
+    ctx.fill()
+    ctx.rectangle(padding+bar_width/3, padding+bar_height-bar_height_fill, bar_width/4, bar_height_fill)
+    ctx.set_source_rgba(*COLOR_FG_HIGH)
+    ctx.fill()
+
+    # Border
+    ctx.rectangle(padding-.5, padding-.5, bar_width+1, bar_height+1)
+    ctx.set_source_rgba(*COLOR_BORDER)
+    ctx.set_line_width(1.)
+    ctx.stroke()
+
+    return cairo_surface_to_pixbuf(surface)
+

<<attachment: tray-icon-test.png>>

_______________________________________________
gpodder-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/gpodder-devel

Reply via email to