From c64ab472b6931236065ef369264613ca66410bab Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 22 May 2019 16:06:02 -0300 Subject: [PATCH] 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 | 252 +++++---------------- 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 | 89 ++++---- panels/background/cc-background-chooser.ui | 23 +- 7 files changed, 155 insertions(+), 320 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..faafd93bd 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,67 +365,6 @@ 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; -} - -static cairo_surface_t * -get_content_loading_icon (BgSource *source) -{ - GtkIconTheme *theme; - g_autoptr(GtkIconInfo) icon_info = NULL; - g_autoptr(GdkPixbuf) pixbuf = NULL; - g_autoptr(GdkPixbuf) ret = NULL; - g_autoptr(GError) error = NULL; - int scale_factor; - cairo_surface_t *surface; - int thumbnail_height; - int thumbnail_width; - - theme = gtk_icon_theme_get_default (); - icon_info = gtk_icon_theme_lookup_icon (theme, - "content-loading-symbolic", - 16, - GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_GENERIC_FALLBACK); - if (icon_info == NULL) - { - g_warning ("Failed to find placeholder icon"); - return NULL; - } - - pixbuf = gtk_icon_info_load_icon (icon_info, &error); - if (pixbuf == NULL) - { - g_warning ("Failed to load placeholder icon: %s", error->message); - return NULL; - } - - thumbnail_height = bg_source_get_thumbnail_height (source); - thumbnail_width = bg_source_get_thumbnail_width (source); - ret = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - TRUE, - 8, thumbnail_width, thumbnail_height); - gdk_pixbuf_fill (ret, 0x00000000); - - /* Put the icon in the middle */ - gdk_pixbuf_copy_area (pixbuf, 0, 0, - gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), - ret, - (thumbnail_width - gdk_pixbuf_get_width (pixbuf)) / 2, - (thumbnail_height - gdk_pixbuf_get_height (pixbuf)) / 2); - - scale_factor = bg_source_get_scale_factor (source); - surface = gdk_cairo_surface_create_from_pixbuf (ret, scale_factor, NULL); - - return surface; -} - static GFile * bg_pictures_source_get_cache_file (void) { @@ -444,16 +381,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 +432,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 +480,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 +518,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 +535,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 +544,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 +565,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 +625,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 +709,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 +728,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 +823,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 +842,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 +#include 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 -#include #include 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; + g_autoptr(GdkPixbuf) pixbuf = NULL; + CcBackgroundChooser *self; + CcBackgroundItem *item; + GtkWidget *child; + GtkWidget *image; - model = bg_source_get_liststore (BG_SOURCE (self->wallpapers_source)); + 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); - gtk_icon_view_set_model (self->icon_view, GTK_TREE_MODEL (model)); + 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); - 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); + g_object_set_data_full (G_OBJECT (child), "item", g_object_ref (item), g_object_unref); + return child; +} + +static void +setup_flowbox (CcBackgroundChooser *self) +{ + GListStore *store; + + 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..12e111a20 100644 --- a/panels/background/cc-background-chooser.ui +++ b/panels/background/cc-background-chooser.ui @@ -21,13 +21,29 @@ never automatic - + True - - + False + vertical + True + + + True + 12 + 12 + 12 + True + center + 1 + 8 + True + single + + + @@ -37,7 +53,6 @@ - icon_view bottom