mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-06 00:30:08 +00:00
GtkIconTheme: Allow loading icons from resources
We add a new API, gtk_icon_theme_add_resource_path, which can be used to add resource path as a base location for icon theme content, similar to gtk_icon_theme_append_search_path.
This commit is contained in:
parent
13c354db8d
commit
968ea4186d
@ -171,6 +171,7 @@ struct _GtkIconThemePrivate
|
|||||||
gchar *current_theme;
|
gchar *current_theme;
|
||||||
gchar **search_path;
|
gchar **search_path;
|
||||||
gint search_path_len;
|
gint search_path_len;
|
||||||
|
GList *resource_paths;
|
||||||
|
|
||||||
guint custom_theme : 1;
|
guint custom_theme : 1;
|
||||||
guint is_screen_singleton : 1;
|
guint is_screen_singleton : 1;
|
||||||
@ -251,6 +252,7 @@ struct _GtkIconInfo
|
|||||||
guint forced_size : 1;
|
guint forced_size : 1;
|
||||||
guint emblems_applied : 1;
|
guint emblems_applied : 1;
|
||||||
guint is_svg : 1;
|
guint is_svg : 1;
|
||||||
|
guint is_resource : 1;
|
||||||
|
|
||||||
/* Cached information if we go ahead and try to load
|
/* Cached information if we go ahead and try to load
|
||||||
* the icon.
|
* the icon.
|
||||||
@ -286,6 +288,7 @@ typedef struct
|
|||||||
gint max_size;
|
gint max_size;
|
||||||
gint threshold;
|
gint threshold;
|
||||||
gint scale;
|
gint scale;
|
||||||
|
gboolean is_resource;
|
||||||
|
|
||||||
gchar *dir;
|
gchar *dir;
|
||||||
gchar *subdir;
|
gchar *subdir;
|
||||||
@ -312,7 +315,6 @@ typedef struct
|
|||||||
{
|
{
|
||||||
gchar *dir;
|
gchar *dir;
|
||||||
time_t mtime; /* 0 == not existing or not a dir */
|
time_t mtime; /* 0 == not existing or not a dir */
|
||||||
|
|
||||||
GtkIconCache *cache;
|
GtkIconCache *cache;
|
||||||
} IconThemeDirMtime;
|
} IconThemeDirMtime;
|
||||||
|
|
||||||
@ -832,21 +834,17 @@ gtk_icon_theme_finalize (GObject *object)
|
|||||||
g_assert (priv->info_cache_lru == NULL);
|
g_assert (priv->info_cache_lru == NULL);
|
||||||
|
|
||||||
if (priv->theme_changed_idle)
|
if (priv->theme_changed_idle)
|
||||||
{
|
g_source_remove (priv->theme_changed_idle);
|
||||||
g_source_remove (priv->theme_changed_idle);
|
|
||||||
priv->theme_changed_idle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unset_screen (icon_theme);
|
unset_screen (icon_theme);
|
||||||
|
|
||||||
g_free (priv->current_theme);
|
g_free (priv->current_theme);
|
||||||
priv->current_theme = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < priv->search_path_len; i++)
|
for (i = 0; i < priv->search_path_len; i++)
|
||||||
g_free (priv->search_path[i]);
|
g_free (priv->search_path[i]);
|
||||||
|
|
||||||
g_free (priv->search_path);
|
g_free (priv->search_path);
|
||||||
priv->search_path = NULL;
|
|
||||||
|
g_list_free_full (priv->resource_paths, g_free);
|
||||||
|
|
||||||
blow_themes (icon_theme);
|
blow_themes (icon_theme);
|
||||||
|
|
||||||
@ -1000,6 +998,20 @@ gtk_icon_theme_prepend_search_path (GtkIconTheme *icon_theme,
|
|||||||
do_theme_change (icon_theme);
|
do_theme_change (icon_theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_icon_theme_add_resource_path (GtkIconTheme *icon_theme,
|
||||||
|
const gchar *path)
|
||||||
|
{
|
||||||
|
GtkIconThemePrivate *priv = icon_theme->priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_ICON_THEME (icon_theme));
|
||||||
|
g_return_if_fail (path != NULL);
|
||||||
|
|
||||||
|
priv->resource_paths = g_list_append (priv->resource_paths, g_strdup (path));
|
||||||
|
|
||||||
|
do_theme_change (icon_theme);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_icon_theme_set_custom_theme:
|
* gtk_icon_theme_set_custom_theme:
|
||||||
* @icon_theme: a #GtkIconTheme
|
* @icon_theme: a #GtkIconTheme
|
||||||
@ -2933,6 +2945,7 @@ theme_lookup_icon (IconTheme *theme,
|
|||||||
icon_info->filename = g_build_filename (min_dir->dir, file, NULL);
|
icon_info->filename = g_build_filename (min_dir->dir, file, NULL);
|
||||||
icon_info->icon_file = g_file_new_for_path (icon_info->filename);
|
icon_info->icon_file = g_file_new_for_path (icon_info->filename);
|
||||||
icon_info->is_svg = suffix == ICON_SUFFIX_SVG;
|
icon_info->is_svg = suffix == ICON_SUFFIX_SVG;
|
||||||
|
icon_info->is_resource = min_dir->is_resource;
|
||||||
g_free (file);
|
g_free (file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3032,10 +3045,8 @@ scan_directory (GtkIconThemePrivate *icon_theme,
|
|||||||
GDir *gdir;
|
GDir *gdir;
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
|
|
||||||
GTK_NOTE (ICONTHEME,
|
GTK_NOTE (ICONTHEME, g_print ("scanning directory %s\n", full_dir));
|
||||||
g_print ("scanning directory %s\n", full_dir));
|
dir->icons = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
dir->icons = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
||||||
g_free, NULL);
|
|
||||||
|
|
||||||
gdir = g_dir_open (full_dir, 0, NULL);
|
gdir = g_dir_open (full_dir, 0, NULL);
|
||||||
|
|
||||||
@ -3061,6 +3072,34 @@ scan_directory (GtkIconThemePrivate *icon_theme,
|
|||||||
g_dir_close (gdir);
|
g_dir_close (gdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scan_resources (GtkIconThemePrivate *icon_theme,
|
||||||
|
IconThemeDir *dir,
|
||||||
|
gchar *full_dir,
|
||||||
|
gchar **children)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
GTK_NOTE (ICONTHEME, g_print ("scanning resources %s\n", full_dir));
|
||||||
|
dir->icons = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
|
||||||
|
for (i = 0; children[i]; i++)
|
||||||
|
{
|
||||||
|
gchar *base_name;
|
||||||
|
IconSuffix suffix, hash_suffix;
|
||||||
|
|
||||||
|
suffix = suffix_from_name (children[i]);
|
||||||
|
if (suffix == ICON_SUFFIX_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
base_name = strip_suffix (children[i]);
|
||||||
|
|
||||||
|
hash_suffix = GPOINTER_TO_INT (g_hash_table_lookup (dir->icons, base_name));
|
||||||
|
/* takes ownership of base_name */
|
||||||
|
g_hash_table_replace (dir->icons, base_name, GUINT_TO_POINTER (hash_suffix|suffix));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
theme_subdir_load (GtkIconTheme *icon_theme,
|
theme_subdir_load (GtkIconTheme *icon_theme,
|
||||||
IconTheme *theme,
|
IconTheme *theme,
|
||||||
@ -3140,7 +3179,7 @@ theme_subdir_load (GtkIconTheme *icon_theme,
|
|||||||
if (dir_mtime->mtime == 0)
|
if (dir_mtime->mtime == 0)
|
||||||
continue; /* directory doesn't exist */
|
continue; /* directory doesn't exist */
|
||||||
|
|
||||||
full_dir = g_build_filename (dir_mtime->dir, subdir, NULL);
|
full_dir = g_build_filename (dir_mtime->dir, subdir, NULL);
|
||||||
|
|
||||||
/* First, see if we have a cache for the directory */
|
/* First, see if we have a cache for the directory */
|
||||||
if (dir_mtime->cache != NULL || g_file_test (full_dir, G_FILE_TEST_IS_DIR))
|
if (dir_mtime->cache != NULL || g_file_test (full_dir, G_FILE_TEST_IS_DIR))
|
||||||
@ -3153,6 +3192,7 @@ theme_subdir_load (GtkIconTheme *icon_theme,
|
|||||||
|
|
||||||
dir = g_new (IconThemeDir, 1);
|
dir = g_new (IconThemeDir, 1);
|
||||||
dir->type = type;
|
dir->type = type;
|
||||||
|
dir->is_resource = FALSE;
|
||||||
dir->context = context;
|
dir->context = context;
|
||||||
dir->size = size;
|
dir->size = size;
|
||||||
dir->min_size = min_size;
|
dir->min_size = min_size;
|
||||||
@ -3179,6 +3219,40 @@ theme_subdir_load (GtkIconTheme *icon_theme,
|
|||||||
else
|
else
|
||||||
g_free (full_dir);
|
g_free (full_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (d = icon_theme->priv->resource_paths; d; d = d->next)
|
||||||
|
{
|
||||||
|
gchar **children;
|
||||||
|
|
||||||
|
full_dir = g_build_filename ((const gchar *)d->data, theme->name, subdir, NULL);
|
||||||
|
children = g_resources_enumerate_children (full_dir, 0, NULL);
|
||||||
|
if (children)
|
||||||
|
{
|
||||||
|
dir = g_new (IconThemeDir, 1);
|
||||||
|
dir->type = type;
|
||||||
|
dir->is_resource = TRUE;
|
||||||
|
dir->context = context;
|
||||||
|
dir->size = size;
|
||||||
|
dir->min_size = min_size;
|
||||||
|
dir->max_size = max_size;
|
||||||
|
dir->threshold = threshold;
|
||||||
|
dir->dir = full_dir;
|
||||||
|
dir->subdir = g_strdup (subdir);
|
||||||
|
dir->scale = scale;
|
||||||
|
dir->cache = NULL;
|
||||||
|
dir->subdir_index = -1;
|
||||||
|
|
||||||
|
scan_resources (icon_theme->priv, dir, full_dir, children);
|
||||||
|
|
||||||
|
theme->dirs = g_list_prepend (theme->dirs, dir);
|
||||||
|
g_strfreev (children);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GTK_NOTE (ICONTHEME, g_print ("no resources at %s\n", full_dir));
|
||||||
|
g_free (full_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3209,6 +3283,7 @@ icon_info_new (IconThemeDirType type,
|
|||||||
icon_info->dir_scale = dir_scale;
|
icon_info->dir_scale = dir_scale;
|
||||||
icon_info->unscaled_scale = 1.0;
|
icon_info->unscaled_scale = 1.0;
|
||||||
icon_info->is_svg = FALSE;
|
icon_info->is_svg = FALSE;
|
||||||
|
icon_info->is_resource = FALSE;
|
||||||
|
|
||||||
return icon_info;
|
return icon_info;
|
||||||
}
|
}
|
||||||
@ -3645,6 +3720,24 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
|||||||
source_pixbuf = NULL;
|
source_pixbuf = NULL;
|
||||||
if (icon_info->cache_pixbuf)
|
if (icon_info->cache_pixbuf)
|
||||||
source_pixbuf = g_object_ref (icon_info->cache_pixbuf);
|
source_pixbuf = g_object_ref (icon_info->cache_pixbuf);
|
||||||
|
else if (icon_info->is_resource)
|
||||||
|
{
|
||||||
|
if (icon_info->is_svg)
|
||||||
|
{
|
||||||
|
gint size;
|
||||||
|
|
||||||
|
if (icon_info->forced_size)
|
||||||
|
size = scaled_desired_size;
|
||||||
|
else
|
||||||
|
size = icon_info->dir_size * icon_info->dir_scale * icon_info->scale;
|
||||||
|
source_pixbuf = gdk_pixbuf_new_from_resource_at_scale (icon_info->filename,
|
||||||
|
size, size, TRUE,
|
||||||
|
&icon_info->load_error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
source_pixbuf = gdk_pixbuf_new_from_resource (icon_info->filename,
|
||||||
|
&icon_info->load_error);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GInputStream *stream;
|
GInputStream *stream;
|
||||||
@ -3665,10 +3758,8 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
|||||||
else
|
else
|
||||||
size = icon_info->dir_size * icon_info->dir_scale * icon_info->scale;
|
size = icon_info->dir_size * icon_info->dir_scale * icon_info->scale;
|
||||||
source_pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
|
source_pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
|
||||||
size,
|
size, size,
|
||||||
size,
|
TRUE, NULL,
|
||||||
TRUE,
|
|
||||||
NULL,
|
|
||||||
&icon_info->load_error);
|
&icon_info->load_error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -187,6 +187,10 @@ GDK_AVAILABLE_IN_ALL
|
|||||||
void gtk_icon_theme_prepend_search_path (GtkIconTheme *icon_theme,
|
void gtk_icon_theme_prepend_search_path (GtkIconTheme *icon_theme,
|
||||||
const gchar *path);
|
const gchar *path);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
void gtk_icon_theme_add_resource_path (GtkIconTheme *icon_theme,
|
||||||
|
const gchar *path);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_icon_theme_set_custom_theme (GtkIconTheme *icon_theme,
|
void gtk_icon_theme_set_custom_theme (GtkIconTheme *icon_theme,
|
||||||
const gchar *theme_name);
|
const gchar *theme_name);
|
||||||
|
Loading…
Reference in New Issue
Block a user