[gnome-control-center/gbsneto/background: 1/5] background: Switch to GtkFlowBox



commit 07135e3888cf0b3bd675e5e9a5a78ae58b5d647e
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed May 22 16:06:02 2019 -0300

    background: Switch to GtkFlowBox
    
    This is a major rework on how images are loaded and stored.
    Unfortunately, this is so entangled that doing each change
    as an atomic step is pretty much unfeasible.
    
    The first major change is that BgSource now returns a GListStore
    instead of a GtkListStore. This is necessary for us to bind it
    to GtkFlowBox, and pretty much signals we're not using any of
    the tree/icon views anymore.
    
    Second, the thumbnail factory was moved to BgSource itself. We
    only create factories for large thumbnails, so it's not needed
    to handle each one of them individually.
    
    At last, switch CcBackgroundChooser to GtkFlowBox, and adjust
    the signals we connect to.

 panels/background/bg-colors-source.c       |  52 ++------
 panels/background/bg-pictures-source.c     | 203 ++++++++---------------------
 panels/background/bg-source.c              |  22 +++-
 panels/background/bg-source.h              |   5 +-
 panels/background/bg-wallpapers-source.c   |  32 +----
 panels/background/cc-background-chooser.c  |  91 +++++++------
 panels/background/cc-background-chooser.ui |  11 +-
 7 files changed, 146 insertions(+), 270 deletions(-)
---
diff --git a/panels/background/bg-colors-source.c b/panels/background/bg-colors-source.c
index 3512772bb..61d8fc6f0 100644
--- a/panels/background/bg-colors-source.c
+++ b/panels/background/bg-colors-source.c
@@ -72,20 +72,11 @@ get_colors_dir (void)
 static void
 bg_colors_source_add_color (BgColorsSource               *self,
                             GnomeDesktopThumbnailFactory *thumb_factory,
-                            GtkListStore                 *store,
-                            const char                   *color,
-                            GtkTreeRowReference         **ret_row_ref)
+                            GListStore                   *store,
+                            const char                   *color)
 {
   CcBackgroundItemFlags flags;
   g_autoptr(CcBackgroundItem) item = NULL;
-  g_autoptr(GdkPixbuf) pixbuf = NULL;
-  cairo_surface_t *surface;
-  int scale_factor;
-  int thumbnail_height, thumbnail_width;
-  GtkTreeIter iter;
-
-  thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (self));
-  thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (self));
 
   item = cc_background_item_new (NULL);
   flags = CC_BACKGROUND_ITEM_HAS_PCOLOR |
@@ -106,26 +97,7 @@ bg_colors_source_add_color (BgColorsSource               *self,
   cc_background_item_load (item, NULL);
 
   /* insert the item into the liststore */
-  scale_factor = bg_source_get_scale_factor (BG_SOURCE (self));
-  pixbuf = cc_background_item_get_thumbnail (item,
-                                             thumb_factory,
-                                             thumbnail_width, thumbnail_height,
-                                             scale_factor);
-  surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
-  gtk_list_store_insert_with_values (store, &iter, 0,
-                                     0, surface,
-                                     1, item,
-                                     -1);
-  cairo_surface_destroy (surface);
-
-  if (ret_row_ref)
-    {
-      GtkTreePath *path;
-
-      path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
-      *ret_row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path);
-      gtk_tree_path_free (path);
-    }
+  g_list_store_append (store, item);
 }
 
 static void
@@ -134,7 +106,7 @@ bg_colors_source_constructed (GObject *object)
   BgColorsSource *self = BG_COLORS_SOURCE (object);
   g_autoptr(GnomeDesktopThumbnailFactory) thumb_factory = NULL;
   guint i;
-  GtkListStore *store;
+  GListStore *store;
   g_autoptr(GKeyFile) keyfile = NULL;
   g_autofree gchar *path = NULL;
 
@@ -144,9 +116,7 @@ bg_colors_source_constructed (GObject *object)
   thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
 
   for (i = 0; i < G_N_ELEMENTS (items); i++)
-    {
-      bg_colors_source_add_color (self, thumb_factory, store, items[i].pcolor, NULL);
-    }
+    bg_colors_source_add_color (self, thumb_factory, store, items[i].pcolor);
 
   keyfile = g_key_file_new ();
   path = get_colors_path ();
@@ -156,9 +126,7 @@ bg_colors_source_constructed (GObject *object)
 
       colors = g_key_file_get_string_list (keyfile, "Colors", "custom-colors", NULL, NULL);
       for (i = 0; colors != NULL && colors[i] != NULL; i++)
-        {
-          bg_colors_source_add_color (self, thumb_factory, store, colors[i], NULL);
-        }
+        bg_colors_source_add_color (self, thumb_factory, store, colors[i]);
     }
 }
 
@@ -167,8 +135,8 @@ bg_colors_source_add (BgColorsSource       *self,
                       GdkRGBA              *rgba,
                       GtkTreeRowReference **ret_row_ref)
 {
-  g_autoptr(GnomeDesktopThumbnailFactory) thumb_factory = NULL;
-  GtkListStore *store;
+  GnomeDesktopThumbnailFactory *thumb_factory;
+  GListStore *store;
   g_autofree gchar *c = NULL;
   g_auto(GStrv) colors = NULL;
   gsize len;
@@ -182,10 +150,10 @@ bg_colors_source_add (BgColorsSource       *self,
                        (int)(255*rgba->green),
                        (int)(255*rgba->blue));
 
-  thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
+  thumb_factory = bg_source_get_thumbnail_factory (BG_SOURCE (self));
   store = bg_source_get_liststore (BG_SOURCE (self));
 
-  bg_colors_source_add_color (self, thumb_factory, store, c, ret_row_ref);
+  bg_colors_source_add_color (self, thumb_factory, store, c);
 
   /* Save to the keyfile */
   dir = get_colors_dir ();
diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c
index 8c0d6db34..7b2f74faf 100644
--- a/panels/background/bg-pictures-source.c
+++ b/panels/background/bg-pictures-source.c
@@ -45,8 +45,6 @@ struct _BgPicturesSource
 
   CcBackgroundGriloMiner *grl_miner;
 
-  GnomeDesktopThumbnailFactory *thumb_factory;
-
   GFileMonitor *picture_dir_monitor;
   GFileMonitor *cache_dir_monitor;
 
@@ -86,7 +84,6 @@ bg_pictures_source_dispose (GObject *object)
     }
 
   g_clear_object (&source->grl_miner);
-  g_clear_object (&source->thumb_factory);
 
   G_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object);
 }
@@ -96,8 +93,6 @@ bg_pictures_source_finalize (GObject *object)
 {
   BgPicturesSource *bg_source = BG_PICTURES_SOURCE (object);
 
-  g_clear_object (&bg_source->thumb_factory);
-
   g_clear_pointer (&bg_source->known_items, g_hash_table_destroy);
 
   g_clear_object (&bg_source->picture_dir_monitor);
@@ -116,23 +111,26 @@ bg_pictures_source_class_init (BgPicturesSourceClass *klass)
 }
 
 static void
-remove_placeholder (BgPicturesSource *bg_source, CcBackgroundItem *item)
+remove_placeholder (BgPicturesSource *bg_source,
+                    CcBackgroundItem *item)
 {
-  GtkListStore *store;
-  GtkTreeIter iter;
-  GtkTreePath *path;
-  GtkTreeRowReference *row_ref;
+  GListStore *store;
+  guint i;
 
   store = bg_source_get_liststore (BG_SOURCE (bg_source));
-  row_ref = g_object_get_data (G_OBJECT (item), "row-ref");
-  if (row_ref == NULL)
-    return;
 
-  path = gtk_tree_row_reference_get_path (row_ref);
-  if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
-    return;
+  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (store)); i++)
+    {
+      g_autoptr(CcBackgroundItem) item_n = NULL;
 
-  gtk_list_store_remove (store, &iter);
+      item_n = g_list_model_get_item (G_LIST_MODEL (store), i);
+
+      if (item_n == item)
+        {
+          g_list_store_remove (store, i);
+          break;
+        }
+    }
 }
 
 static gboolean
@@ -163,6 +161,27 @@ swap_rotated_pixbuf (GdkPixbuf *pixbuf)
   return tmp_pixbuf;
 }
 
+static int
+sort_func (gconstpointer a,
+           gconstpointer b,
+           gpointer      user_data)
+{
+  CcBackgroundItem *item_a;
+  CcBackgroundItem *item_b;
+  guint64 modified_a;
+  guint64 modified_b;
+  int retval;
+
+  item_a = (CcBackgroundItem *) a;
+  item_b = (CcBackgroundItem *) b;
+  modified_a = cc_background_item_get_modified (item_a);
+  modified_b = cc_background_item_get_modified (item_b);
+
+  retval = modified_b - modified_a;
+
+  return retval;
+}
+
 static void
 picture_scaled (GObject *source_object,
                 GAsyncResult *res,
@@ -174,10 +193,7 @@ picture_scaled (GObject *source_object,
   g_autoptr(GdkPixbuf) pixbuf = NULL;
   const char *software;
   const char *uri;
-  GtkTreeIter iter;
-  GtkTreePath *path;
-  GtkTreeRowReference *row_ref;
-  GtkListStore *store;
+  GListStore *store;
   cairo_surface_t *surface = NULL;
   int scale_factor;
   gboolean rotation_applied;
@@ -238,26 +254,8 @@ picture_scaled (GObject *source_object,
   surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
   cc_background_item_load (item, NULL);
 
-  row_ref = g_object_get_data (G_OBJECT (item), "row-ref");
-  if (row_ref == NULL)
-    {
-      /* insert the item into the liststore if it did not exist */
-      gtk_list_store_insert_with_values (store, NULL, -1,
-                                         0, surface,
-                                         1, item,
-                                         -1);
-    }
-  else
-    {
-      path = gtk_tree_row_reference_get_path (row_ref);
-      if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
-        {
-          /* otherwise update the thumbnail */
-          gtk_list_store_set (store, &iter,
-                              0, surface,
-                              -1);
-        }
-    }
+  /* insert the item into the liststore */
+  g_list_store_insert_sorted (store, item, sort_func, bg_source);
 
   g_hash_table_insert (bg_source->known_items,
                        bg_pictures_source_get_unique_filename (uri),
@@ -367,16 +365,7 @@ in_content_types (const char *content_type)
        return FALSE;
 }
 
-static gboolean
-in_screenshot_types (const char *content_type)
-{
-       guint i;
-       for (i = 0; screenshot_types[i]; i++)
-               if (g_str_equal (screenshot_types[i], content_type))
-                       return TRUE;
-       return FALSE;
-}
-
+#if 0
 static cairo_surface_t *
 get_content_loading_icon (BgSource *source)
 {
@@ -427,6 +416,7 @@ get_content_loading_icon (BgSource *source)
 
   return surface;
 }
+#endif
 
 static GFile *
 bg_pictures_source_get_cache_file (void)
@@ -444,16 +434,10 @@ static gboolean
 add_single_file (BgPicturesSource     *bg_source,
                  GFile                *file,
                  const gchar          *content_type,
-                 guint64               mtime,
-                 GtkTreeRowReference **ret_row_ref)
+                 guint64               mtime)
 {
   g_autoptr(CcBackgroundItem) item = NULL;
   CcBackgroundItemFlags flags = 0;
-  GtkListStore *store;
-  GtkTreeIter iter;
-  GtkTreePath *path = NULL;
-  GtkTreeRowReference *row_ref = NULL;
-  cairo_surface_t *surface = NULL;
   g_autofree gchar *source_uri = NULL;
   g_autofree gchar *uri = NULL;
   gboolean needs_download;
@@ -501,25 +485,6 @@ add_single_file (BgPicturesSource     *bg_source,
                 "source-url", source_uri,
                NULL);
 
-  if (!ret_row_ref && in_screenshot_types (content_type))
-    goto read_file;
-
-  surface = get_content_loading_icon (BG_SOURCE (bg_source));
-  store = bg_source_get_liststore (BG_SOURCE (bg_source));
-
-  /* insert the item into the liststore */
-  gtk_list_store_insert_with_values (store, &iter, -1,
-                                     0, surface,
-                                     1, item,
-                                     -1);
-
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
-  row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path);
-  g_object_set_data_full (G_OBJECT (item), "row-ref", row_ref, (GDestroyNotify) gtk_tree_row_reference_free);
-
-
- read_file:
-
   media = g_object_get_data (G_OBJECT (file), "grl-media");
   if (media == NULL)
     {
@@ -568,30 +533,20 @@ add_single_file (BgPicturesSource     *bg_source,
   retval = TRUE;
 
  out:
-  if (ret_row_ref)
-    {
-      if (row_ref && retval != FALSE)
-        *ret_row_ref = gtk_tree_row_reference_copy (row_ref);
-      else
-        *ret_row_ref = NULL;
-    }
-  gtk_tree_path_free (path);
-  g_clear_pointer (&surface, cairo_surface_destroy);
   return retval;
 }
 
 static gboolean
-add_single_file_from_info (BgPicturesSource     *bg_source,
-                           GFile                *file,
-                           GFileInfo            *info,
-                           GtkTreeRowReference **ret_row_ref)
+add_single_file_from_info (BgPicturesSource *bg_source,
+                           GFile            *file,
+                           GFileInfo        *info)
 {
   const gchar *content_type;
   guint64 mtime;
 
   content_type = g_file_info_get_content_type (info);
   mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
-  return add_single_file (bg_source, file, content_type, mtime, ret_row_ref);
+  return add_single_file (bg_source, file, content_type, mtime);
 }
 
 static gboolean
@@ -616,7 +571,7 @@ add_single_file_from_media (BgPicturesSource *bg_source,
   else
     mtime_unix = g_get_real_time () / G_USEC_PER_SEC;
 
-  return add_single_file (bg_source, file, content_type, (guint64) mtime_unix, NULL);
+  return add_single_file (bg_source, file, content_type, (guint64) mtime_unix);
 }
 
 gboolean
@@ -633,7 +588,7 @@ bg_pictures_source_add (BgPicturesSource     *bg_source,
   if (info == NULL)
     return FALSE;
 
-  retval = add_single_file_from_info (bg_source, file, info, ret_row_ref);
+  retval = add_single_file_from_info (bg_source, file, info);
 
   return retval;
 }
@@ -642,21 +597,19 @@ gboolean
 bg_pictures_source_remove (BgPicturesSource *bg_source,
                            const char       *uri)
 {
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  gboolean cont;
+  GListStore *store;
   gboolean retval;
+  guint i;
 
   retval = FALSE;
-  model = GTK_TREE_MODEL (bg_source_get_liststore (BG_SOURCE (bg_source)));
+  store = bg_source_get_liststore (BG_SOURCE (bg_source));
 
-  cont = gtk_tree_model_get_iter_first (model, &iter);
-  while (cont)
+  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (store)); i++)
     {
       g_autoptr(CcBackgroundItem) tmp_item = NULL;
       const char *tmp_uri;
 
-      gtk_tree_model_get (model, &iter, 1, &tmp_item, -1);
+      tmp_item = g_list_model_get_item (G_LIST_MODEL (store), i);
       tmp_uri = cc_background_item_get_uri (tmp_item);
       if (g_str_equal (tmp_uri, uri))
         {
@@ -665,11 +618,10 @@ bg_pictures_source_remove (BgPicturesSource *bg_source,
           g_hash_table_insert (bg_source->known_items,
                               uuid, NULL);
 
-          gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+          g_list_store_remove (store, i);
           retval = TRUE;
           break;
         }
-      cont = gtk_tree_model_iter_next (model, &iter);
     }
   return retval;
 }
@@ -726,7 +678,7 @@ file_info_async_ready (GObject      *source,
 
       file = g_file_get_child (parent, g_file_info_get_name (info));
 
-      add_single_file_from_info (bg_source, file, info, NULL);
+      add_single_file_from_info (bg_source, file, info);
     }
 
   g_list_foreach (files, (GFunc) g_object_unref, NULL);
@@ -810,33 +762,6 @@ bg_pictures_source_is_known (BgPicturesSource *bg_source,
   return GPOINTER_TO_INT (g_hash_table_lookup (bg_source->known_items, uuid));
 }
 
-static int
-sort_func (GtkTreeModel *model,
-           GtkTreeIter *a,
-           GtkTreeIter *b,
-           BgPicturesSource *bg_source)
-{
-  g_autoptr(CcBackgroundItem) item_a = NULL;
-  g_autoptr(CcBackgroundItem) item_b = NULL;
-  guint64 modified_a;
-  guint64 modified_b;
-  int retval;
-
-  gtk_tree_model_get (model, a,
-                      1, &item_a,
-                      -1);
-  gtk_tree_model_get (model, b,
-                      1, &item_b,
-                      -1);
-
-  modified_a = cc_background_item_get_modified (item_a);
-  modified_b = cc_background_item_get_modified (item_b);
-
-  retval = modified_b - modified_a;
-
-  return retval;
-}
-
 static void
 file_info_ready (GObject      *object,
                  GAsyncResult *res,
@@ -856,7 +781,7 @@ file_info_ready (GObject      *object,
       return;
     }
 
-  add_single_file_from_info (BG_PICTURES_SOURCE (user_data), file, info, NULL);
+  add_single_file_from_info (BG_PICTURES_SOURCE (user_data), file, info);
 }
 
 static void
@@ -951,7 +876,6 @@ bg_pictures_source_init (BgPicturesSource *self)
 {
   const gchar *pictures_path;
   g_autofree gchar *cache_path = NULL;
-  GtkListStore *store;
 
   self->cancellable = g_cancellable_new ();
   self->known_items = g_hash_table_new_full (g_str_hash,
@@ -971,21 +895,6 @@ bg_pictures_source_init (BgPicturesSource *self)
   self->grl_miner = cc_background_grilo_miner_new ();
   g_signal_connect_swapped (self->grl_miner, "media-found", G_CALLBACK (media_found_cb), self);
   cc_background_grilo_miner_start (self->grl_miner);
-
-  self->thumb_factory =
-    gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
-
-  store = bg_source_get_liststore (BG_SOURCE (self));
-
-  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
-                                   1,
-                                   (GtkTreeIterCompareFunc)sort_func,
-                                   self,
-                                   NULL);
-
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
-                                        1,
-                                        GTK_SORT_ASCENDING);
 }
 
 BgPicturesSource *
diff --git a/panels/background/bg-source.c b/panels/background/bg-source.c
index 18688ff42..542e13023 100644
--- a/panels/background/bg-source.c
+++ b/panels/background/bg-source.c
@@ -28,7 +28,8 @@
 
 typedef struct
 {
-  GtkListStore *store;
+  GnomeDesktopThumbnailFactory *thumbnail_factory;
+  GListStore *store;
   GtkWidget *widget;
   gint thumbnail_height;
   gint thumbnail_width;
@@ -116,6 +117,7 @@ bg_source_dispose (GObject *object)
   BgSource *source = BG_SOURCE (object);
   BgSourcePrivate *priv = bg_source_get_instance_private (source);
 
+  g_clear_object (&priv->thumbnail_factory);
   g_clear_object (&priv->store);
 
   G_OBJECT_CLASS (bg_source_parent_class)->dispose (object);
@@ -135,7 +137,7 @@ bg_source_class_init (BgSourceClass *klass)
   pspec = g_param_spec_object ("liststore",
                                "Liststore",
                                "Liststore used in the source",
-                               GTK_TYPE_LIST_STORE,
+                               G_TYPE_LIST_STORE,
                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class, PROP_LISTSTORE, pspec);
 
@@ -151,10 +153,11 @@ static void
 bg_source_init (BgSource *self)
 {
   BgSourcePrivate *priv = bg_source_get_instance_private (self);
-  priv->store = gtk_list_store_new (3, CAIRO_GOBJECT_TYPE_SURFACE, G_TYPE_OBJECT, G_TYPE_STRING);
+  priv->store = g_list_store_new (CC_TYPE_BACKGROUND_ITEM);
+  priv->thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
 }
 
-GtkListStore*
+GListStore*
 bg_source_get_liststore (BgSource *source)
 {
   BgSourcePrivate *priv;
@@ -197,3 +200,14 @@ bg_source_get_thumbnail_width (BgSource *source)
   priv = bg_source_get_instance_private (source);
   return priv->thumbnail_width;
 }
+
+GnomeDesktopThumbnailFactory*
+bg_source_get_thumbnail_factory (BgSource *source)
+{
+  BgSourcePrivate *priv;
+
+  g_return_val_if_fail (BG_IS_SOURCE (source), NULL);
+
+  priv = bg_source_get_instance_private (source);
+  return priv->thumbnail_factory;
+}
diff --git a/panels/background/bg-source.h b/panels/background/bg-source.h
index c6f9b4005..84518d1dd 100644
--- a/panels/background/bg-source.h
+++ b/panels/background/bg-source.h
@@ -22,6 +22,7 @@
 #define _BG_SOURCE_H
 
 #include <gtk/gtk.h>
+#include <libgnome-desktop/gnome-desktop-thumbnail.h>
 
 G_BEGIN_DECLS
 
@@ -33,7 +34,7 @@ struct _BgSourceClass
   GObjectClass parent_class;
 };
 
-GtkListStore* bg_source_get_liststore (BgSource *source);
+GListStore* bg_source_get_liststore (BgSource *source);
 
 gint bg_source_get_scale_factor (BgSource *source);
 
@@ -41,6 +42,8 @@ gint bg_source_get_thumbnail_height (BgSource *source);
 
 gint bg_source_get_thumbnail_width (BgSource *source);
 
+GnomeDesktopThumbnailFactory* bg_source_get_thumbnail_factory (BgSource *source);
+
 G_END_DECLS
 
 #endif /* _BG_SOURCE_H */
diff --git a/panels/background/bg-wallpapers-source.c b/panels/background/bg-wallpapers-source.c
index 21fbba4bb..3f40650df 100644
--- a/panels/background/bg-wallpapers-source.c
+++ b/panels/background/bg-wallpapers-source.c
@@ -25,13 +25,11 @@
 #include "cc-background-xml.h"
 
 #include <cairo-gobject.h>
-#include <libgnome-desktop/gnome-desktop-thumbnail.h>
 #include <gio/gio.h>
 
 struct _BgWallpapersSource
 {
   BgSource parent_instance;
-  GnomeDesktopThumbnailFactory *thumb_factory;
   CcBackgroundXml *xml;
 };
 
@@ -42,38 +40,15 @@ load_wallpapers (gchar              *key,
                  CcBackgroundItem   *item,
                  BgWallpapersSource *source)
 {
-  GtkTreeIter iter;
-  g_autoptr(GdkPixbuf) pixbuf = NULL;
-  GtkListStore *store = bg_source_get_liststore (BG_SOURCE (source));
-  cairo_surface_t *surface;
+  GListStore *store = bg_source_get_liststore (BG_SOURCE (source));
   gboolean deleted;
-  gint scale_factor;
-  gint thumbnail_height;
-  gint thumbnail_width;
 
   g_object_get (G_OBJECT (item), "is-deleted", &deleted, NULL);
 
   if (deleted)
     return;
 
-  gtk_list_store_append (store, &iter);
-
-  scale_factor = bg_source_get_scale_factor (BG_SOURCE (source));
-  thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (source));
-  thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (source));
-  pixbuf = cc_background_item_get_thumbnail (item, source->thumb_factory,
-                                            thumbnail_width, thumbnail_height,
-                                            scale_factor);
-  if (pixbuf == NULL)
-    return;
-
-  surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
-  gtk_list_store_set (store, &iter,
-                      0, surface,
-                      1, item,
-                      2, cc_background_item_get_name (item),
-                      -1);
-  g_clear_pointer (&surface, cairo_surface_destroy);
+  g_list_store_append (store, item);
 }
 
 static void
@@ -136,7 +111,6 @@ bg_wallpapers_source_dispose (GObject *object)
 {
   BgWallpapersSource *self = BG_WALLPAPERS_SOURCE (object);
 
-  g_clear_object (&self->thumb_factory);
   g_clear_object (&self->xml);
 
   G_OBJECT_CLASS (bg_wallpapers_source_parent_class)->dispose (object);
@@ -145,8 +119,6 @@ bg_wallpapers_source_dispose (GObject *object)
 static void
 bg_wallpapers_source_init (BgWallpapersSource *self)
 {
-  self->thumb_factory =
-    gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
   self->xml = cc_background_xml_new ();
 }
 
diff --git a/panels/background/cc-background-chooser.c b/panels/background/cc-background-chooser.c
index 2b01bb024..4a8dd23a9 100644
--- a/panels/background/cc-background-chooser.c
+++ b/panels/background/cc-background-chooser.c
@@ -29,7 +29,7 @@ struct _CcBackgroundChooser
 {
   GtkBox              parent;
 
-  GtkIconView        *icon_view;
+  GtkFlowBox         *flowbox;
   GtkPopover         *selection_popover;
 
   BgWallpapersSource *wallpapers_source;
@@ -49,42 +49,61 @@ static void
 emit_background_chosen (CcBackgroundChooser        *self,
                         CcBackgroundSelectionFlags  flags)
 {
-  g_autolist (GtkTreePath) list = NULL;
+  g_autoptr(GList) list = NULL;
   CcBackgroundItem *item;
-  GtkTreeModel *model;
-  GtkTreeIter iter;
 
-  model = gtk_icon_view_get_model (self->icon_view);
-  list = gtk_icon_view_get_selected_items (self->icon_view);
+  list = gtk_flow_box_get_selected_children (self->flowbox);
   g_assert (g_list_length (list) == 1);
 
-  if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) list->data) == FALSE)
-    return;
-
-  gtk_tree_model_get (model, &iter, 1, &item, -1);
+  item = g_object_get_data (list->data, "item");
 
   g_signal_emit (self, signals[BACKGROUND_CHOSEN], 0, item, flags);
 }
 
-static void
-setup_icon_view (CcBackgroundChooser *self)
+static GtkWidget*
+create_widget_func (gpointer model_item,
+                    gpointer user_data)
 {
-  GtkCellRenderer *renderer;
-  GtkListStore *model;
-
-  model = bg_source_get_liststore (BG_SOURCE (self->wallpapers_source));
+  g_autoptr(GdkPixbuf) pixbuf = NULL;
+  CcBackgroundChooser *self;
+  CcBackgroundItem *item;
+  GtkWidget *child;
+  GtkWidget *image;
+
+  self = CC_BACKGROUND_CHOOSER (user_data);
+  item = CC_BACKGROUND_ITEM (model_item);
+  pixbuf = cc_background_item_get_thumbnail (item,
+                                             bg_source_get_thumbnail_factory (BG_SOURCE 
(self->wallpapers_source)),
+                                             bg_source_get_thumbnail_width (BG_SOURCE 
(self->wallpapers_source)),
+                                             bg_source_get_thumbnail_height (BG_SOURCE 
(self->wallpapers_source)),
+                                             bg_source_get_scale_factor (BG_SOURCE 
(self->wallpapers_source)));
+  image = gtk_image_new_from_pixbuf (pixbuf);
+  gtk_widget_show (image);
+
+  child = g_object_new (GTK_TYPE_FLOW_BOX_CHILD,
+                        "halign", GTK_ALIGN_CENTER,
+                        "valign", GTK_ALIGN_CENTER,
+                        NULL);
+  gtk_container_add (GTK_CONTAINER (child), image);
+  gtk_widget_show (child);
+
+  g_object_set_data_full (G_OBJECT (child), "item", g_object_ref (item), g_object_unref);
+
+  return child;
+}
 
-  gtk_icon_view_set_model (self->icon_view, GTK_TREE_MODEL (model));
+static void
+setup_flowbox (CcBackgroundChooser *self)
+{
+  GListStore *store;
 
-  renderer = gtk_cell_renderer_pixbuf_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->icon_view),
-                              renderer,
-                              FALSE);
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self->icon_view),
-                                  renderer,
-                                  "surface", 0,
-                                  NULL);
+  store = bg_source_get_liststore (BG_SOURCE (self->wallpapers_source));
 
+  gtk_flow_box_bind_model (self->flowbox,
+                           G_LIST_MODEL (store),
+                           create_widget_func,
+                           self,
+                           NULL);
 }
 
 static void
@@ -112,22 +131,11 @@ on_selection_lock_clicked_cb (GtkButton           *button,
 }
 
 static void
-on_selection_changed_cb (GtkIconView         *icon_view,
-                         CcBackgroundChooser *self)
-{
-}
-
-static void
-on_item_activated_cb (GtkIconView         *icon_view,
-                      GtkTreePath         *path,
+on_item_activated_cb (GtkFlowBox          *flowbox,
+                      GtkFlowBoxChild     *child,
                       CcBackgroundChooser *self)
 {
-  GdkRectangle rect;
-
-  g_message ("Item activated");
-
-  gtk_icon_view_get_cell_rect (icon_view, path, NULL, &rect);
-  gtk_popover_set_pointing_to (self->selection_popover, &rect);
+  gtk_popover_set_relative_to (self->selection_popover, GTK_WIDGET (child));
   gtk_popover_popup (self->selection_popover);
 }
 
@@ -162,11 +170,10 @@ cc_background_chooser_class_init (CcBackgroundChooserClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/control-center/background/cc-background-chooser.ui");
 
-  gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, icon_view);
+  gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, flowbox);
   gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, selection_popover);
 
   gtk_widget_class_bind_template_callback (widget_class, on_item_activated_cb);
-  gtk_widget_class_bind_template_callback (widget_class, on_selection_changed_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_selection_desktop_lock_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_selection_desktop_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_selection_lock_clicked_cb);
@@ -178,5 +185,5 @@ cc_background_chooser_init (CcBackgroundChooser *self)
   gtk_widget_init_template (GTK_WIDGET (self));
 
   self->wallpapers_source = bg_wallpapers_source_new (GTK_WIDGET (self));
-  setup_icon_view (self);
+  setup_flowbox (self);
 }
diff --git a/panels/background/cc-background-chooser.ui b/panels/background/cc-background-chooser.ui
index 7bab33f26..e91c0c9b1 100644
--- a/panels/background/cc-background-chooser.ui
+++ b/panels/background/cc-background-chooser.ui
@@ -21,10 +21,14 @@
         <property name="hscrollbar-policy">never</property>
         <property name="vscrollbar-policy">automatic</property>
         <child>
-          <object class="GtkIconView" id="icon_view">
+          <object class="GtkFlowBox" id="flowbox">
             <property name="visible">True</property>
-            <signal name="item-activated" handler="on_item_activated_cb" object="CcBackgroundChooser" 
swapped="no" />
-            <signal name="selection-changed" handler="on_selection_changed_cb" object="CcBackgroundChooser" 
swapped="no" />
+            <property name="row-spacing">6</property>
+            <property name="min-children-per-line">1</property>
+            <property name="max-children-per-line">5</property>
+            <property name="activate-on-single-click">True</property>
+            <property name="selection-mode">single</property>
+            <signal name="child-activated" handler="on_item_activated_cb" object="CcBackgroundChooser" 
swapped="no" />
             <style>
               <class name="view" />
             </style>
@@ -37,7 +41,6 @@
 
   <!-- Desktop & Lock Screen Popover -->
   <object class="GtkPopover" id="selection_popover">
-    <property name="relative-to">icon_view</property>
     <property name="position">bottom</property>
     <child>
       <object class="GtkBox">


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