[libgd/wip/show-activity: 2/2] pixbuf-renderer: Support for progress on top of icons



commit 3b05b7b3e0e33c1fe4299331dcf2a7db097609dc
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Sun Jun 9 17:01:54 2013 +0300

    pixbuf-renderer: Support for progress on top of icons
    
    This will be useful to indicate that there is some automated activity
    going on the item the icon in question represents.
    
    The main use case I have in mind with this is Boxes indicating VMs that
    are being imported.
    
    Issues:
    
    * Theming is completely wrong. Some theme somewhere is setting the bg color to transparent so the 
progress bar's frame/background is drawn all transparent. Also the progress bar itself is drawn transparent 
if don't make the following call:
    
    gtk_style_context_set_state (context, GTK_STATE_FLAG_ACTIVE);
    
    before drawing and we really shouldn't be needing to call that.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=702212

 libgd/gd-toggle-pixbuf-renderer.c |  102 ++++++++++++++++++++++++++++++++++--
 1 files changed, 96 insertions(+), 6 deletions(-)
---
diff --git a/libgd/gd-toggle-pixbuf-renderer.c b/libgd/gd-toggle-pixbuf-renderer.c
index 39f4386..801b863 100644
--- a/libgd/gd-toggle-pixbuf-renderer.c
+++ b/libgd/gd-toggle-pixbuf-renderer.c
@@ -79,7 +79,7 @@ render_check (GdTogglePixbufRenderer *self,
 }
 
 static void
-render_activity (GdTogglePixbufRenderer *self,
+render_progress (GdTogglePixbufRenderer *self,
                  cairo_t                *cr,
                  GtkWidget              *widget,
                  const GdkRectangle     *cell_area,
@@ -87,10 +87,81 @@ render_activity (GdTogglePixbufRenderer *self,
                  gint                    xpad,
                  gint                    ypad)
 {
-  gint x, y, width, height;
+  GtkStyleContext *context;
+  gint x, y, width, height, pulse;
+  gfloat xalign, yalign;
+  GtkBorder padding;
+  GdkPixbuf *pixbuf;
+
+  g_object_get (self,
+                "pixbuf", &pixbuf,
+                "xalign", &xalign,
+                "yalign", &yalign,
+                NULL);
+  if (pixbuf != NULL)
+    {
+      int pixbuf_height;
 
-  if (self->priv->pulse == G_MAXINT)
-    return;
+      width = gdk_pixbuf_get_width (pixbuf);
+      pixbuf_height = gdk_pixbuf_get_height (pixbuf);
+      height = pixbuf_height / 4;
+
+      x = cell_area->x + ((cell_area->width - width) * xalign) + xpad;
+      y = cell_area->y + ((cell_area->height - pixbuf_height) * yalign) +
+          ypad + (pixbuf_height - height);
+    }
+  else
+    {
+      width = cell_area->width;
+      height = cell_area->height / 4;
+
+      x = cell_area->x + xpad;
+      y = cell_area->y + ypad;
+    }
+
+  context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_save (context);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);
+
+  gtk_render_background (context, cr,
+                         x, y,
+                         width, height);
+  gtk_render_frame (context, cr,
+                    x, y,
+                    width, height);
+
+  gtk_style_context_get_padding (context, GTK_STATE_FLAG_NORMAL, &padding);
+
+  x += padding.left;
+  y += padding.top;
+  width -= padding.left + padding.right;
+  height -= padding.top + padding.bottom;
+  gtk_style_context_restore (context);
+
+  gtk_style_context_save (context);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR);
+  gtk_style_context_set_state (context, GTK_STATE_FLAG_ACTIVE);
+
+  pulse = CLAMP (self->priv->pulse, 0, 100);
+  width = pulse * width / 100;
+  gtk_render_activity (context, cr,
+                       x, y,
+                       width, height);
+
+  gtk_style_context_restore (context);
+}
+
+static void
+render_spinner (GdTogglePixbufRenderer *self,
+                cairo_t                *cr,
+                GtkWidget              *widget,
+                const GdkRectangle     *cell_area,
+                gint                    icon_size,
+                gint                    xpad,
+                gint                    ypad)
+{
+  gint x, y, width, height;
 
   width = cell_area->width / 4;
   height = cell_area->height / 4;
@@ -109,6 +180,24 @@ render_activity (GdTogglePixbufRenderer *self,
 }
 
 static void
+render_activity (GdTogglePixbufRenderer *self,
+                 cairo_t                *cr,
+                 GtkWidget              *widget,
+                 const GdkRectangle     *cell_area,
+                 gint                    icon_size,
+                 gint                    xpad,
+                 gint                    ypad)
+{
+  if (self->priv->pulse == G_MAXINT)
+    return;
+
+  if (self->priv->pulse < 0)
+    render_spinner (self, cr, widget, cell_area, icon_size, xpad, ypad);
+  else
+    render_progress (self, cr, widget, cell_area, icon_size, xpad, ypad);
+}
+
+static void
 gd_toggle_pixbuf_renderer_render (GtkCellRenderer      *cell,
                                   cairo_t              *cr,
                                   GtkWidget            *widget,
@@ -236,8 +325,9 @@ gd_toggle_pixbuf_renderer_class_init (GdTogglePixbufRendererClass *klass)
   properties[PROP_PULSE] =
     g_param_spec_int ("pulse",
                       "Pulse",
-                      "Set to any value other than %G_MAXINT to display a "
-                      "spinner on top of the pixbuf.",
+                      "Set to negative values to show spinner and positive "
+                      "values to show progress bar. Set to %G_MAXINT to not "
+                      "display any activity.",
                       G_MININT,
                       G_MAXINT,
                       G_MAXINT,


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