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.
This commit is contained in:
parent
ee37d0194c
commit
c64ab472b6
7 changed files with 155 additions and 320 deletions
|
@ -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 ();
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -21,13 +21,29 @@
|
|||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkIconView" id="icon_view">
|
||||
<object class="GtkBox">
|
||||
<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="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="expand">True</property>
|
||||
<style>
|
||||
<class name="view" />
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="flowbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="min-children-per-line">1</property>
|
||||
<property name="max-children-per-line">8</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" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -37,7 +53,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">
|
||||
|
|
Loading…
Add table
Reference in a new issue