[epiphany] downloads: Add EphyDownloadsProgressIcon to show global progress



commit db430888f6d163a126653bda09207144f7b256a2
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Tue Oct 6 18:58:47 2015 +0200

    downloads: Add EphyDownloadsProgressIcon to show global progress

 embed/ephy-downloads-manager.c             |   53 +++++++++++++++
 embed/ephy-downloads-manager.h             |   13 ++--
 lib/widgets/Makefile.am                    |    2 +
 lib/widgets/ephy-downloads-progress-icon.c |  101 ++++++++++++++++++++++++++++
 lib/widgets/ephy-downloads-progress-icon.h |   45 ++++++++++++
 src/ephy-toolbar.c                         |   14 +++-
 6 files changed, 220 insertions(+), 8 deletions(-)
---
diff --git a/embed/ephy-downloads-manager.c b/embed/ephy-downloads-manager.c
index f8b54bb..d5feac7 100644
--- a/embed/ephy-downloads-manager.c
+++ b/embed/ephy-downloads-manager.c
@@ -25,6 +25,8 @@ enum {
   DOWNLOAD_ADDED,
   DOWNLOAD_REMOVED,
 
+  ESTIMATED_PROGRESS_CHANGED,
+
   LAST_SIGNAL
 };
 
@@ -83,6 +85,21 @@ ephy_downloads_manager_class_init (EphyDownloadsManagerClass *klass)
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1,
                   EPHY_TYPE_DOWNLOAD);
+
+  signals[ESTIMATED_PROGRESS_CHANGED] =
+    g_signal_new ("estimated-progress-changed",
+                  EPHY_TYPE_DOWNLOADS_MANAGER,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+}
+
+static void
+download_completed_cb (EphyDownload         *download,
+                       EphyDownloadsManager *manager)
+{
+  g_signal_emit (manager, signals[ESTIMATED_PROGRESS_CHANGED], 0);
 }
 
 static void
@@ -92,6 +109,13 @@ download_failed_cb (EphyDownload         *download,
 {
   if (g_error_matches (error, WEBKIT_DOWNLOAD_ERROR, WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER))
     ephy_downloads_manager_remove_download (manager, download);
+  g_signal_emit (manager, signals[ESTIMATED_PROGRESS_CHANGED], 0);
+}
+
+static void
+download_estimated_progress_changed_cb (EphyDownloadsManager *manager)
+{
+  g_signal_emit (manager, signals[ESTIMATED_PROGRESS_CHANGED], 0);
 }
 
 void
@@ -105,10 +129,17 @@ ephy_downloads_manager_add_download (EphyDownloadsManager *manager,
     return;
 
   manager->downloads = g_list_prepend (manager->downloads, g_object_ref (download));
+  g_signal_connect (download, "completed",
+                    G_CALLBACK (download_completed_cb),
+                    manager);
   g_signal_connect (download, "error",
                     G_CALLBACK (download_failed_cb),
                     manager);
+  g_signal_connect_swapped (ephy_download_get_webkit_download (download), "notify::estimated-progress",
+                            G_CALLBACK (download_estimated_progress_changed_cb),
+                            manager);
   g_signal_emit (manager, signals[DOWNLOAD_ADDED], 0, download);
+  g_signal_emit (manager, signals[ESTIMATED_PROGRESS_CHANGED], 0);
 }
 
 void
@@ -153,3 +184,25 @@ ephy_downloads_manager_get_downloads (EphyDownloadsManager *manager)
 
   return manager->downloads;
 }
+
+gdouble
+ephy_downloads_manager_get_estimated_progress (EphyDownloadsManager *manager)
+{
+  GList *l;
+  guint n_active = 0;
+  gdouble progress = 0;
+
+  g_return_val_if_fail (EPHY_IS_DOWNLOADS_MANAGER (manager), 0);
+
+  for (l = manager->downloads; l; l = g_list_next (l)) {
+    EphyDownload *download = EPHY_DOWNLOAD (l->data);
+
+    if (!ephy_download_is_active (download))
+      continue;
+
+    n_active++;
+    progress += webkit_download_get_estimated_progress (ephy_download_get_webkit_download (download));
+  }
+
+  return n_active > 0 ? progress / n_active : 1;
+}
diff --git a/embed/ephy-downloads-manager.h b/embed/ephy-downloads-manager.h
index 2763807..620168a 100644
--- a/embed/ephy-downloads-manager.h
+++ b/embed/ephy-downloads-manager.h
@@ -37,12 +37,13 @@ typedef struct _EphyDownloadsManager        EphyDownloadsManager;
 
 GType    ephy_downloads_manager_get_type             (void);
 
-void     ephy_downloads_manager_add_download         (EphyDownloadsManager *manager,
-                                                      EphyDownload         *download);
-void     ephy_downloads_manager_remove_download      (EphyDownloadsManager *manager,
-                                                      EphyDownload         *download);
-gboolean ephy_downloads_manager_has_active_downloads (EphyDownloadsManager *manager);
-GList   *ephy_downloads_manager_get_downloads        (EphyDownloadsManager *manager);
+void     ephy_downloads_manager_add_download           (EphyDownloadsManager *manager,
+                                                        EphyDownload         *download);
+void     ephy_downloads_manager_remove_download        (EphyDownloadsManager *manager,
+                                                        EphyDownload         *download);
+gboolean ephy_downloads_manager_has_active_downloads   (EphyDownloadsManager *manager);
+GList   *ephy_downloads_manager_get_downloads          (EphyDownloadsManager *manager);
+gdouble  ephy_downloads_manager_get_estimated_progress (EphyDownloadsManager *manager);
 
 G_END_DECLS
 
diff --git a/lib/widgets/Makefile.am b/lib/widgets/Makefile.am
index 3b935fa..619e112 100644
--- a/lib/widgets/Makefile.am
+++ b/lib/widgets/Makefile.am
@@ -70,6 +70,8 @@ libephywidgets_la_SOURCES = \
        ephy-certificate-popover.h              \
        ephy-downloads-popover.h                \
        ephy-downloads-popover.c                \
+       ephy-downloads-progress-icon.h          \
+       ephy-downloads-progress-icon.c          \
        ephy-download-widget.c                  \
        ephy-download-widget.h                  \
        ephy-location-entry.c                   \
diff --git a/lib/widgets/ephy-downloads-progress-icon.c b/lib/widgets/ephy-downloads-progress-icon.c
new file mode 100644
index 0000000..2539e3d
--- /dev/null
+++ b/lib/widgets/ephy-downloads-progress-icon.c
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2015 Igalia S.L.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "config.h"
+#include "ephy-downloads-progress-icon.h"
+
+#include "ephy-downloads-manager.h"
+#include "ephy-embed-shell.h"
+
+struct _EphyDownloadsProgressIcon
+{
+  GtkDrawingArea parent;
+
+  GtkWidget *downloads_box;
+};
+
+struct _EphyDownloadsProgressIconClass
+{
+  GtkDrawingAreaClass parent_class;
+};
+
+G_DEFINE_TYPE (EphyDownloadsProgressIcon, ephy_downloads_progress_icon, GTK_TYPE_DRAWING_AREA)
+
+static void
+download_added_cb (EphyDownloadsProgressIcon *progress_icon,
+                   EphyDownload         *download)
+{
+}
+
+static gboolean
+ephy_downloads_progress_icon_draw (GtkWidget *widget,
+                                   cairo_t   *cr)
+{
+  gint width, height;
+  EphyDownloadsManager *manager;
+  gdouble progress;
+
+  width = gtk_widget_get_allocated_width (widget);
+  height = gtk_widget_get_allocated_height (widget);
+
+  manager = ephy_embed_shell_get_downloads_manager (ephy_embed_shell_get_default ());
+  progress = ephy_downloads_manager_get_estimated_progress (manager);
+
+  cairo_set_source_rgba (cr, 0, 0, 0, progress == 1 ? 1 : 0.2);
+  cairo_move_to (cr, width / 4., 0);
+  cairo_line_to (cr, width - (width / 4.), 0);
+  cairo_line_to (cr, width - (width / 4.), height / 2.);
+  cairo_line_to (cr, width, height / 2.);
+  cairo_line_to (cr, width / 2., height);
+  cairo_line_to (cr, 0, height / 2.);
+  cairo_line_to (cr, width / 4., height / 2.);
+  cairo_line_to (cr, width / 4., 0);
+  cairo_fill_preserve (cr);
+
+  if (progress > 0 && progress < 1) {
+    cairo_clip (cr);
+
+    cairo_set_source_rgba (cr, 0, 0, 0, 0.7);
+    cairo_rectangle (cr, 0, 0, width, height * progress);
+    cairo_fill (cr);
+  }
+
+  return TRUE;
+}
+
+static void
+ephy_downloads_progress_icon_class_init (EphyDownloadsProgressIconClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  widget_class->draw = ephy_downloads_progress_icon_draw;
+}
+
+static void
+ephy_downloads_progress_icon_init (EphyDownloadsProgressIcon *icon)
+{
+  g_object_set (icon, "width-request", 16, "height-request", 16, NULL);
+  gtk_widget_set_valign (GTK_WIDGET (icon), GTK_ALIGN_CENTER);
+  gtk_widget_set_halign (GTK_WIDGET (icon), GTK_ALIGN_CENTER);
+}
+
+GtkWidget *ephy_downloads_progress_icon_new (void)
+{
+  return GTK_WIDGET (g_object_new (EPHY_TYPE_DOWNLOADS_PROGRESS_ICON, NULL));
+}
diff --git a/lib/widgets/ephy-downloads-progress-icon.h b/lib/widgets/ephy-downloads-progress-icon.h
new file mode 100644
index 0000000..bf1e631
--- /dev/null
+++ b/lib/widgets/ephy-downloads-progress-icon.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2015 Igalia S.L.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef EPHY_DOWNLOADS_PROGRESS_ICON_H
+#define EPHY_DOWNLOADS_PROGRESS_ICON_H
+
+#include <gtk/gtk.h>
+
+#include "ephy-download.h"
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_DOWNLOADS_PROGRESS_ICON            (ephy_downloads_progress_icon_get_type())
+#define EPHY_DOWNLOADS_PROGRESS_ICON(object)         (G_TYPE_CHECK_INSTANCE_CAST((object), 
EPHY_TYPE_DOWNLOADS_PROGRESS_ICON, EphyDownloadsProgressIcon))
+#define EPHY_IS_DOWNLOADS_PROGRESS_ICON(object)      (G_TYPE_CHECK_INSTANCE_TYPE((object), 
EPHY_TYPE_DOWNLOADS_PROGRESS_ICON))
+#define EPHY_DOWNLOADS_PROGRESS_ICON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), 
EPHY_TYPE_DOWNLOADS_PROGRESS_ICON, EphyDownloadsProgressIconClass))
+#define EPHY_IS_DOWNLOADS_PROGRESS_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), 
EPHY_TYPE_DOWNLOADS_PROGRESS_ICON))
+#define EPHY_DOWNLOADS_PROGRESS_ICON_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), 
EPHY_TYPE_DOWNLOADS_PROGRESS_ICON, EphyDownloadsProgressIconClass))
+
+typedef struct _EphyDownloadsProgressIcon        EphyDownloadsProgressIcon;
+typedef struct _EphyDownloadsProgressIconClass   EphyDownloadsProgressIconClass;
+
+GType      ephy_downloads_progress_icon_get_type (void);
+
+GtkWidget *ephy_downloads_progress_icon_new      (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ephy-toolbar.c b/src/ephy-toolbar.c
index c5c9337..1e2e4b0 100644
--- a/src/ephy-toolbar.c
+++ b/src/ephy-toolbar.c
@@ -26,6 +26,7 @@
 #include "ephy-middle-clickable-button.h"
 #include "ephy-private.h"
 #include "ephy-downloads-popover.h"
+#include "ephy-downloads-progress-icon.h"
 
 G_DEFINE_TYPE (EphyToolbar, ephy_toolbar, GTK_TYPE_HEADER_BAR)
 
@@ -77,6 +78,13 @@ download_removed_cb (EphyDownloadsManager *manager,
 }
 
 static void
+downloads_estimated_progress_cb (EphyDownloadsManager *manager,
+                                 EphyToolbar *toolbar)
+{
+  gtk_widget_queue_draw (gtk_button_get_image (toolbar->priv->downloads_button));
+}
+
+static void
 ephy_toolbar_set_property (GObject *object,
                            guint property_id,
                            const GValue *value,
@@ -230,8 +238,7 @@ ephy_toolbar_constructed (GObject *object)
                                  ephy_downloads_manager_get_downloads (downloads_manager) != NULL);
 
   priv->downloads_button = gtk_menu_button_new ();
-  gtk_button_set_image (GTK_BUTTON (priv->downloads_button),
-                        gtk_image_new_from_icon_name ("folder-download-symbolic", GTK_ICON_SIZE_BUTTON));
+  gtk_button_set_image (GTK_BUTTON (priv->downloads_button), ephy_downloads_progress_icon_new ());
   gtk_widget_set_valign (priv->downloads_button, GTK_ALIGN_CENTER);
   gtk_container_add (GTK_CONTAINER (priv->downloads_revealer), priv->downloads_button);
   gtk_widget_show (priv->downloads_button);
@@ -248,6 +255,9 @@ ephy_toolbar_constructed (GObject *object)
   g_signal_connect_object (downloads_manager, "download-removed",
                            G_CALLBACK (download_removed_cb),
                            object, 0);
+  g_signal_connect_object (downloads_manager, "estimated-progress-changed",
+                           G_CALLBACK (downloads_estimated_progress_cb),
+                           object, 0);
 
   gtk_header_bar_pack_end (GTK_HEADER_BAR (toolbar), priv->downloads_revealer);
   gtk_widget_show (priv->downloads_revealer);


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