mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-19 13:30:02 +00:00
Add GtkIconProvider
This is a minimal interface to provide icon lookup by name. It is implemented by GtkIconTheme, but platform libraries or applications can provide their own implementation and pass it to GTK.
This commit is contained in:
parent
cda1733fc7
commit
e5fff06622
@ -163,6 +163,7 @@
|
||||
#include <gtk/gtkgridview.h>
|
||||
#include <gtk/gtkheaderbar.h>
|
||||
#include <gtk/gtkicontheme.h>
|
||||
#include <gtk/gtkiconprovider.h>
|
||||
#include <gtk/deprecated/gtkiconview.h>
|
||||
#include <gtk/gtkimage.h>
|
||||
#include <gtk/gtkimcontext.h>
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
#include "gtksymbolicpaintable.h"
|
||||
#include "gtkiconprovider.h"
|
||||
|
||||
struct _GtkIconHelper
|
||||
{
|
||||
@ -111,13 +112,25 @@ ensure_paintable_for_gicon (GtkIconHelper *self,
|
||||
return GDK_PAINTABLE (icon);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
ensure_paintable_for_icon_name (GtkIconHelper *self,
|
||||
const char *name)
|
||||
{
|
||||
int size;
|
||||
float scale;
|
||||
|
||||
size = gtk_icon_helper_get_size (self);
|
||||
scale = gtk_widget_get_scale_factor (self->owner);
|
||||
|
||||
return gtk_lookup_icon (gtk_widget_get_display (self->owner), name, size, scale);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
gtk_icon_helper_load_paintable (GtkIconHelper *self,
|
||||
gboolean preload,
|
||||
gboolean *out_symbolic)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GIcon *gicon;
|
||||
gboolean symbolic;
|
||||
|
||||
switch (gtk_image_definition_get_storage_type (self->def))
|
||||
@ -128,18 +141,12 @@ gtk_icon_helper_load_paintable (GtkIconHelper *self,
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
if (self->use_fallback)
|
||||
gicon = g_themed_icon_new_with_default_fallbacks (gtk_image_definition_get_icon_name (self->def));
|
||||
paintable = ensure_paintable_for_icon_name (self,
|
||||
gtk_image_definition_get_icon_name (self->def));
|
||||
if (GTK_IS_ICON_PAINTABLE (paintable))
|
||||
symbolic = gtk_icon_paintable_is_symbolic (GTK_ICON_PAINTABLE (paintable));
|
||||
else
|
||||
gicon = g_themed_icon_new (gtk_image_definition_get_icon_name (self->def));
|
||||
paintable = ensure_paintable_for_gicon (self,
|
||||
gtk_css_node_get_style (self->node),
|
||||
gtk_widget_get_scale_factor (self->owner),
|
||||
gtk_widget_get_direction (self->owner),
|
||||
preload,
|
||||
gicon,
|
||||
&symbolic);
|
||||
g_object_unref (gicon);
|
||||
symbolic = GTK_IS_SYMBOLIC_PAINTABLE (paintable);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_GICON:
|
||||
|
164
gtk/gtkiconprovider.c
Normal file
164
gtk/gtkiconprovider.c
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright © 2024 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkiconprovider.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkenums.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
|
||||
G_DEFINE_INTERFACE (GtkIconProvider, gtk_icon_provider, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_icon_provider_default_init (GtkIconProviderInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_provider_set_for_display (GdkDisplay *display,
|
||||
GtkIconProvider *provider)
|
||||
{
|
||||
g_object_set_data_full (G_OBJECT (display), "--gtk-icon-provider",
|
||||
g_object_ref (provider), g_object_unref);
|
||||
|
||||
gtk_system_setting_changed (display, GTK_SYSTEM_SETTING_ICON_THEME);
|
||||
}
|
||||
|
||||
GtkIconProvider *
|
||||
gtk_icon_provider_get_for_display (GdkDisplay *display)
|
||||
{
|
||||
GtkIconProvider *provider;
|
||||
|
||||
provider = g_object_get_data (G_OBJECT (display), "--gtk-icon-provider");
|
||||
|
||||
if (provider)
|
||||
return provider;
|
||||
|
||||
return GTK_ICON_PROVIDER (gtk_icon_theme_get_for_display (display));
|
||||
}
|
||||
|
||||
static GdkPaintable *gtk_lookup_builtin_icon (GdkDisplay *display,
|
||||
const char *name,
|
||||
int size,
|
||||
float scale);
|
||||
|
||||
GdkPaintable *
|
||||
gtk_lookup_icon (GdkDisplay *display,
|
||||
const char *name,
|
||||
int size,
|
||||
float scale)
|
||||
{
|
||||
GtkIconProvider *provider;
|
||||
GdkPaintable *icon;
|
||||
|
||||
provider = gtk_icon_provider_get_for_display (display);
|
||||
|
||||
icon = GTK_ICON_PROVIDER_GET_IFACE (provider)->lookup_icon (provider, name, size, scale);
|
||||
|
||||
if (!icon)
|
||||
{
|
||||
GTK_DISPLAY_DEBUG (display, ICONTHEME,
|
||||
"%s: Looking up icon %s size %d@%f: not found",
|
||||
G_OBJECT_TYPE_NAME (provider), name, size, scale);
|
||||
|
||||
icon = gtk_lookup_builtin_icon (display, name, size, scale);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
gtk_lookup_builtin_icon (GdkDisplay *display,
|
||||
const char *name,
|
||||
int size,
|
||||
float scale)
|
||||
{
|
||||
int sizes[] = { 16, 32, 64 };
|
||||
char pixel_size[24] = { 0, };
|
||||
const char *contexts[] = {
|
||||
"actions",
|
||||
"categories",
|
||||
"devices",
|
||||
"emblems",
|
||||
"emotes",
|
||||
"mimetypes",
|
||||
"places",
|
||||
"status",
|
||||
};
|
||||
const char *extension;
|
||||
GdkPaintable *icon = NULL;
|
||||
|
||||
for (int i = 0; i < G_N_ELEMENTS (sizes); i++)
|
||||
{
|
||||
if (sizes[i] >= size * scale)
|
||||
{
|
||||
size = sizes[i];
|
||||
g_snprintf (pixel_size, sizeof (pixel_size), "%dx%d", size, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pixel_size[0] == '\0')
|
||||
{
|
||||
g_snprintf (pixel_size, sizeof (pixel_size), "64x64");
|
||||
size = 64;
|
||||
}
|
||||
|
||||
if (g_str_has_suffix (name, "-symbolic"))
|
||||
extension = ".symbolic.png";
|
||||
else
|
||||
extension = ".png";
|
||||
|
||||
for (int i = 0; i < G_N_ELEMENTS (contexts); i++)
|
||||
{
|
||||
char *uri;
|
||||
GFile *file;
|
||||
|
||||
uri = g_strconcat ("resource:///org/gtk/libgtk/icons/", pixel_size, "/", contexts[i], "/", name, extension, NULL);
|
||||
file = g_file_new_for_uri (uri);
|
||||
|
||||
if (g_file_query_exists (file, NULL))
|
||||
{
|
||||
GTK_DISPLAY_DEBUG (display, ICONTHEME,
|
||||
"Looking up builtin icon %s size %d@%f: %s",
|
||||
name, size, scale, uri);
|
||||
|
||||
icon = GDK_PAINTABLE (gtk_icon_paintable_new_for_file (file, size, 1));
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
g_free (uri);
|
||||
|
||||
if (icon)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!icon)
|
||||
{
|
||||
GTK_DISPLAY_DEBUG (display, ICONTHEME,
|
||||
"Looking up builtin icon %s size %d@%f: not found",
|
||||
name, size, scale);
|
||||
|
||||
icon = GDK_PAINTABLE (gdk_texture_new_from_resource ("/org/gtk/libgtk/icons/16x16/status/image-missing.png"));
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
62
gtk/gtkiconprovider.h
Normal file
62
gtk/gtkiconprovider.h
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
/*
|
||||
* Copyright © 2024 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gdk/gdkpaintable.h>
|
||||
#include <gdk/gdkdisplay.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ICON_PROVIDER (gtk_icon_provider_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
G_DECLARE_INTERFACE (GtkIconProvider, gtk_icon_provider, GTK, ICON_PROVIDER, GObject)
|
||||
|
||||
struct _GtkIconProviderInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
GdkPaintable * (* lookup_icon) (GtkIconProvider *provider,
|
||||
const char *icon_name,
|
||||
int size,
|
||||
float scale);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
void gtk_icon_provider_set_for_display (GdkDisplay *display,
|
||||
GtkIconProvider *provider);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GtkIconProvider * gtk_icon_provider_get_for_display (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GdkPaintable * gtk_lookup_icon (GdkDisplay *display,
|
||||
const char *icon_name,
|
||||
int size,
|
||||
float scale);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "gdktextureutilsprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
#include "gtkiconprovider.h"
|
||||
|
||||
#define GDK_ARRAY_ELEMENT_TYPE char *
|
||||
#define GDK_ARRAY_NULL_TERMINATED 1
|
||||
@ -812,7 +813,25 @@ icon_cache_clear (GtkIconTheme *theme)
|
||||
|
||||
/****************** End of icon cache ***********************/
|
||||
|
||||
G_DEFINE_TYPE (GtkIconTheme, gtk_icon_theme, G_TYPE_OBJECT)
|
||||
static GdkPaintable *
|
||||
gtk_icon_theme_lookup_icon_as_provider (GtkIconProvider *provider,
|
||||
const char *name,
|
||||
int size,
|
||||
float scale)
|
||||
{
|
||||
GtkIconTheme *self = GTK_ICON_THEME (provider);
|
||||
|
||||
return GDK_PAINTABLE (gtk_icon_theme_lookup_icon (self, name, NULL, size, (int) ceilf (scale), GTK_TEXT_DIR_LTR, 0));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_provider_init (GtkIconProviderInterface *iface)
|
||||
{
|
||||
iface->lookup_icon = gtk_icon_theme_lookup_icon_as_provider;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkIconTheme, gtk_icon_theme, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ICON_PROVIDER, gtk_icon_provider_init))
|
||||
|
||||
/**
|
||||
* gtk_icon_theme_new:
|
||||
|
@ -258,6 +258,7 @@ gtk_public_sources = files([
|
||||
'gtkgridview.c',
|
||||
'gtkheaderbar.c',
|
||||
'gtkicontheme.c',
|
||||
'gtkiconprovider.c',
|
||||
'gtkimage.c',
|
||||
'gtkimagedefinition.c',
|
||||
'gtkimcontext.c',
|
||||
@ -511,6 +512,7 @@ gtk_public_headers = files([
|
||||
'gtkgridview.h',
|
||||
'gtkheaderbar.h',
|
||||
'gtkicontheme.h',
|
||||
'gtkiconprovider.h',
|
||||
'gtkimage.h',
|
||||
'gtkimcontext.h',
|
||||
'gtkimcontextsimple.h',
|
||||
|
Loading…
Reference in New Issue
Block a user