From: Benjamin Otte Date: Sat, 4 Nov 2017 18:05:52 +0000 (+0100) Subject: image: Add the ability to set textures X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~23^2~882 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=2d959553e9de3dd11778c7fc22b8d759de90b729;p=gtk4.git image: Add the ability to set textures This also adds it to all other places that use the same infrastructure: GtkEntry and GtkCellRendererPixbuf --- diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index fdbf953720..0c5003ccf2 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -915,10 +915,12 @@ gtk_entry_set_tabs gtk_entry_get_tabs GtkEntryIconPosition gtk_entry_set_icon_from_surface +gtk_entry_set_icon_from_texture gtk_entry_set_icon_from_icon_name gtk_entry_set_icon_from_gicon gtk_entry_get_icon_storage_type gtk_entry_get_icon_surface +gtk_entry_get_icon_texture gtk_entry_get_icon_name gtk_entry_get_icon_gicon gtk_entry_set_icon_activatable @@ -1487,6 +1489,7 @@ GtkIconViewPrivate GtkImage GtkImageType gtk_image_get_surface +gtk_image_get_texture gtk_image_get_icon_name gtk_image_get_gicon gtk_image_get_storage_type @@ -1496,12 +1499,14 @@ gtk_image_new_from_icon_name gtk_image_new_from_gicon gtk_image_new_from_resource gtk_image_new_from_surface +gtk_image_new_from_texture gtk_image_set_from_file gtk_image_set_from_pixbuf gtk_image_set_from_icon_name gtk_image_set_from_gicon gtk_image_set_from_resource gtk_image_set_from_surface +gtk_image_set_from_texture gtk_image_clear gtk_image_new gtk_image_set_pixel_size diff --git a/gtk/a11y/gtkimageaccessible.c b/gtk/a11y/gtkimageaccessible.c index be2a3c5761..338d894e22 100644 --- a/gtk/a11y/gtkimageaccessible.c +++ b/gtk/a11y/gtkimageaccessible.c @@ -279,6 +279,15 @@ gtk_image_accessible_get_image_size (AtkImage *image, *width = cairo_image_surface_get_width (surface); break; } + case GTK_IMAGE_TEXTURE: + { + GdkTexture *texture; + + texture = gtk_image_get_texture (gtk_image); + *height = gdk_texture_get_height (texture); + *width = gdk_texture_get_width (texture); + break; + } case GTK_IMAGE_ICON_NAME: case GTK_IMAGE_GICON: { diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c index b53fe04389..2c7fb0a54b 100644 --- a/gtk/gtkcellrendererpixbuf.c +++ b/gtk/gtkcellrendererpixbuf.c @@ -76,6 +76,7 @@ enum { PROP_PIXBUF_EXPANDER_OPEN, PROP_PIXBUF_EXPANDER_CLOSED, PROP_SURFACE, + PROP_TEXTURE, PROP_STOCK_SIZE, PROP_STOCK_DETAIL, PROP_ICON_NAME, @@ -176,6 +177,19 @@ gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class) CAIRO_GOBJECT_TYPE_SURFACE, GTK_PARAM_READWRITE)); + /** + * GtkCellRendererPixbuf:texture: + * + * Since: 3.94 + */ + g_object_class_install_property (object_class, + PROP_TEXTURE, + g_param_spec_object ("texture", + P_("Texture"), + P_("The texture to render"), + GDK_TYPE_TEXTURE, + GTK_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_STOCK_SIZE, g_param_spec_uint ("stock-size", @@ -268,6 +282,9 @@ gtk_cell_renderer_pixbuf_get_property (GObject *object, case PROP_SURFACE: g_value_set_boxed (value, gtk_image_definition_get_surface (priv->image_def)); break; + case PROP_TEXTURE: + g_value_set_object (value, gtk_image_definition_get_texture (priv->image_def)); + break; case PROP_STOCK_SIZE: g_value_set_uint (value, priv->icon_size); break; @@ -295,6 +312,9 @@ notify_storage_type (GtkCellRendererPixbuf *cellpixbuf, case GTK_IMAGE_SURFACE: g_object_notify (G_OBJECT (cellpixbuf), "surface"); break; + case GTK_IMAGE_TEXTURE: + g_object_notify (G_OBJECT (cellpixbuf), "texture"); + break; case GTK_IMAGE_ICON_NAME: g_object_notify (G_OBJECT (cellpixbuf), "icon-name"); break; @@ -362,6 +382,9 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object, case PROP_SURFACE: take_image_definition (cellpixbuf, gtk_image_definition_new_surface (g_value_get_boxed (value))); break; + case PROP_TEXTURE: + take_image_definition (cellpixbuf, gtk_image_definition_new_texture (g_value_get_object (value))); + break; case PROP_STOCK_SIZE: priv->icon_size = g_value_get_uint (value); break; diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 941c87da59..afecb31d90 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -106,7 +106,7 @@ * icons can be activatable by clicking, can be set up as drag source and * can have tooltips. To add an icon, use gtk_entry_set_icon_from_gicon() or * one of the various other functions that set an icon from a stock id, an - * icon name, or a surface. To trigger an action when the user clicks an icon, + * icon name, or a texture. To trigger an action when the user clicks an icon, * connect to the #GtkEntry::icon-press signal. To allow DND operations * from an icon, use gtk_entry_set_icon_drag_source(). To set a tooltip on * an icon, use gtk_entry_set_icon_tooltip_text() or the corresponding function @@ -341,6 +341,8 @@ enum { PROP_PROGRESS_PULSE_STEP, PROP_SURFACE_PRIMARY, PROP_SURFACE_SECONDARY, + PROP_TEXTURE_PRIMARY, + PROP_TEXTURE_SECONDARY, PROP_ICON_NAME_PRIMARY, PROP_ICON_NAME_SECONDARY, PROP_GICON_PRIMARY, @@ -1034,6 +1036,34 @@ gtk_entry_class_init (GtkEntryClass *class) CAIRO_GOBJECT_TYPE_SURFACE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkEntry:primary-icon-texture: + * + * A #GdkTexture to use as the primary icon for the entry. + * + * Since: 3.94 + */ + entry_props[PROP_TEXTURE_PRIMARY] = + g_param_spec_object ("primary-icon-texture", + P_("Primary texture"), + P_("Primary texture for the entry"), + GDK_TYPE_TEXTURE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + + /** + * GtkEntry:secondary-icon-texture: + * + * A #GtkTexture to use as the secondary icon for the entry. + * + * Since: 3.94 + */ + entry_props[PROP_TEXTURE_SECONDARY] = + g_param_spec_object ("secondary-icon-texture", + P_("Secondary texture"), + P_("Secondary texture for the entry"), + GDK_TYPE_TEXTURE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** * GtkEntry:primary-icon-name: * @@ -2041,6 +2071,18 @@ gtk_entry_set_property (GObject *object, g_value_get_boxed (value)); break; + case PROP_TEXTURE_PRIMARY: + gtk_entry_set_icon_from_texture (entry, + GTK_ENTRY_ICON_PRIMARY, + g_value_get_boxed (value)); + break; + + case PROP_TEXTURE_SECONDARY: + gtk_entry_set_icon_from_texture (entry, + GTK_ENTRY_ICON_SECONDARY, + g_value_get_boxed (value)); + break; + case PROP_ICON_NAME_PRIMARY: gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_PRIMARY, @@ -2284,6 +2326,18 @@ gtk_entry_get_property (GObject *object, GTK_ENTRY_ICON_SECONDARY)); break; + case PROP_TEXTURE_PRIMARY: + g_value_set_boxed (value, + gtk_entry_get_icon_texture (entry, + GTK_ENTRY_ICON_PRIMARY)); + break; + + case PROP_TEXTURE_SECONDARY: + g_value_set_boxed (value, + gtk_entry_get_icon_texture (entry, + GTK_ENTRY_ICON_SECONDARY)); + break; + case PROP_ICON_NAME_PRIMARY: g_value_set_string (value, gtk_entry_get_icon_name (entry, @@ -2641,9 +2695,9 @@ gtk_entry_dispose (GObject *object) GtkEntryPrivate *priv = entry->priv; GdkKeymap *keymap; - gtk_entry_set_icon_from_surface (entry, GTK_ENTRY_ICON_PRIMARY, NULL); + gtk_entry_set_icon_from_texture (entry, GTK_ENTRY_ICON_PRIMARY, NULL); gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_PRIMARY, NULL); - gtk_entry_set_icon_from_surface (entry, GTK_ENTRY_ICON_SECONDARY, NULL); + gtk_entry_set_icon_from_texture (entry, GTK_ENTRY_ICON_SECONDARY, NULL); gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_SECONDARY, NULL); gtk_entry_set_completion (entry, NULL); @@ -6614,6 +6668,13 @@ gtk_entry_clear_icon (GtkEntry *entry, : PROP_SURFACE_SECONDARY]); break; + case GTK_IMAGE_TEXTURE: + g_object_notify_by_pspec (G_OBJECT (entry), + entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY + ? PROP_TEXTURE_PRIMARY + : PROP_TEXTURE_SECONDARY]); + break; + case GTK_IMAGE_ICON_NAME: g_object_notify_by_pspec (G_OBJECT (entry), entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY @@ -7553,6 +7614,64 @@ gtk_entry_set_icon_from_surface (GtkEntry *entry, g_object_thaw_notify (G_OBJECT (entry)); } +/** + * gtk_entry_set_icon_from_texture: + * @entry: a #GtkEntry + * @icon_pos: Icon position + * @texture: (allow-none): A #GdkTexture, or %NULL + * + * Sets the icon shown in the specified position using a #GdkTexture + * + * If @texture is %NULL, no icon will be shown in the specified position. + * + * Since: 3.94 + */ +void +gtk_entry_set_icon_from_texture (GtkEntry *entry, + GtkEntryIconPosition icon_pos, + GdkTexture *texture) +{ + GtkEntryPrivate *priv; + EntryIconInfo *icon_info; + + g_return_if_fail (GTK_IS_ENTRY (entry)); + g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); + + priv = entry->priv; + + if ((icon_info = priv->icons[icon_pos]) == NULL) + icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); + + g_object_freeze_notify (G_OBJECT (entry)); + + if (texture) + { + g_object_ref (texture); + + gtk_image_set_from_texture (GTK_IMAGE (icon_info->widget), texture); + + if (icon_pos == GTK_ENTRY_ICON_PRIMARY) + { + g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_TEXTURE_PRIMARY]); + g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_PRIMARY]); + } + else + { + g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_TEXTURE_SECONDARY]); + g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_SECONDARY]); + } + + g_object_unref (texture); + } + else + gtk_entry_clear_icon (entry, icon_pos); + + if (gtk_widget_get_visible (GTK_WIDGET (entry))) + gtk_widget_queue_resize (GTK_WIDGET (entry)); + + g_object_thaw_notify (G_OBJECT (entry)); +} + /** * gtk_entry_set_icon_from_icon_name: * @entry: A #GtkEntry @@ -7774,6 +7893,40 @@ gtk_entry_get_icon_surface (GtkEntry *entry, return gtk_image_get_surface (GTK_IMAGE (icon_info->widget)); } +/** + * gtk_entry_get_icon_texture: + * @entry: A #GtkEntry + * @icon_pos: Icon position + * + * Retrieves the #GdkTexture used for the icon. + * + * If no #GdkTexture was used for the icon, %NULL is returned. + * + * Returns: (transfer none) (nullable): A #GdkTexture, or %NULL if no icon is + * set for this position or the icon set is not a #GdkTexture. + * + * Since: 3.94 + */ +GdkTexture * +gtk_entry_get_icon_texture (GtkEntry *entry, + GtkEntryIconPosition icon_pos) +{ + GtkEntryPrivate *priv; + EntryIconInfo *icon_info; + + g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); + g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); + + priv = entry->priv; + + icon_info = priv->icons[icon_pos]; + + if (!icon_info) + return NULL; + + return gtk_image_get_texture (GTK_IMAGE (icon_info->widget)); +} + /** * gtk_entry_get_icon_gicon: * @entry: A #GtkEntry @@ -7781,7 +7934,7 @@ gtk_entry_get_icon_surface (GtkEntry *entry, * * Retrieves the #GIcon used for the icon, or %NULL if there is * no icon or if the icon was set by some other method (e.g., by - * stock, surface, or icon name). + * stock, texture, or icon name). * * Returns: (transfer none) (nullable): A #GIcon, or %NULL if no icon is set * or if the icon is not a #GIcon @@ -7818,7 +7971,7 @@ gtk_entry_get_icon_gicon (GtkEntry *entry, * * Retrieves the icon name used for the icon, or %NULL if there is * no icon or if the icon was set by some other method (e.g., by - * surface, stock or gicon). + * texture, stock or gicon). * * Returns: (nullable): An icon name, or %NULL if no icon is set or if the icon * wasn’t set from an icon name diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h index d0d4775f15..e2cbd7d605 100644 --- a/gtk/gtkentry.h +++ b/gtk/gtkentry.h @@ -287,6 +287,10 @@ GDK_AVAILABLE_IN_3_94 void gtk_entry_set_icon_from_surface (GtkEntry *entry, GtkEntryIconPosition icon_pos, cairo_surface_t *surface); +GDK_AVAILABLE_IN_3_94 +void gtk_entry_set_icon_from_texture (GtkEntry *entry, + GtkEntryIconPosition icon_pos, + GdkTexture *texture); GDK_AVAILABLE_IN_ALL void gtk_entry_set_icon_from_icon_name (GtkEntry *entry, GtkEntryIconPosition icon_pos, @@ -296,11 +300,14 @@ void gtk_entry_set_icon_from_gicon (GtkEntry * GtkEntryIconPosition icon_pos, GIcon *icon); GDK_AVAILABLE_IN_ALL -GtkImageType gtk_entry_get_icon_storage_type (GtkEntry *entry, +GtkImageType gtk_entry_get_icon_storage_type (GtkEntry *entry, GtkEntryIconPosition icon_pos); GDK_AVAILABLE_IN_3_94 cairo_surface_t*gtk_entry_get_icon_surface (GtkEntry *entry, GtkEntryIconPosition icon_pos); +GDK_AVAILABLE_IN_3_94 +GdkTexture * gtk_entry_get_icon_texture (GtkEntry *entry, + GtkEntryIconPosition icon_pos); GDK_AVAILABLE_IN_ALL const gchar* gtk_entry_get_icon_name (GtkEntry *entry, GtkEntryIconPosition icon_pos); diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c index 4836103cd6..776cbfb62e 100644 --- a/gtk/gtkiconhelper.c +++ b/gtk/gtkiconhelper.c @@ -234,6 +234,23 @@ ensure_surface_from_surface (GtkIconHelper *self, return cairo_surface_reference (orig_surface); } +static cairo_surface_t * +ensure_surface_from_texture (GtkIconHelper *self, + GdkTexture *texture) +{ + cairo_surface_t *surface; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + gdk_texture_get_width (texture), + gdk_texture_get_height (texture)); + gdk_texture_download (texture, + cairo_image_surface_get_data (surface), + cairo_image_surface_get_stride (surface)); + cairo_surface_mark_dirty (surface); + + return surface; +} + static cairo_surface_t * ensure_surface_for_gicon (GtkIconHelper *self, GtkCssStyle *style, @@ -327,6 +344,10 @@ gtk_icon_helper_load_surface (GtkIconHelper *self, surface = ensure_surface_from_surface (self, gtk_image_definition_get_surface (self->def)); break; + case GTK_IMAGE_TEXTURE: + surface = ensure_surface_from_texture (self, gtk_image_definition_get_texture (self->def)); + 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)); @@ -405,6 +426,7 @@ find_cached_texture (GtkIconHelper *self) break; case GTK_IMAGE_EMPTY: case GTK_IMAGE_SURFACE: + case GTK_IMAGE_TEXTURE: default: return NULL; } @@ -496,7 +518,14 @@ _gtk_icon_helper_get_size (GtkIconHelper *self, case GTK_IMAGE_GICON: if (self->pixel_size != -1 || self->force_scale_pixbuf) ensure_icon_size (self, &width, &height); + break; + case GTK_IMAGE_TEXTURE: + { + GdkTexture *texture = gtk_image_definition_get_texture (self->def); + width = gdk_texture_get_width (texture); + height = gdk_texture_get_height (texture); + } break; case GTK_IMAGE_EMPTY: @@ -560,6 +589,13 @@ _gtk_icon_helper_set_surface (GtkIconHelper *self, gtk_icon_helper_take_definition (self, gtk_image_definition_new_surface (surface)); } +void +_gtk_icon_helper_set_texture (GtkIconHelper *self, + GdkTexture *texture) +{ + gtk_icon_helper_take_definition (self, gtk_image_definition_new_texture (texture)); +} + gboolean _gtk_icon_helper_set_icon_size (GtkIconHelper *self, GtkIconSize icon_size) @@ -641,6 +677,12 @@ _gtk_icon_helper_peek_surface (GtkIconHelper *self) return gtk_image_definition_get_surface (self->def); } +GdkTexture * +_gtk_icon_helper_peek_texture (GtkIconHelper *self) +{ + return gtk_image_definition_get_texture (self->def); +} + const gchar * _gtk_icon_helper_get_icon_name (GtkIconHelper *self) { diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h index 5c28643c61..dbe3def51c 100644 --- a/gtk/gtkiconhelperprivate.h +++ b/gtk/gtkiconhelperprivate.h @@ -70,6 +70,8 @@ void _gtk_icon_helper_set_icon_name (GtkIconHelper *self, GtkIconSize icon_size); void _gtk_icon_helper_set_surface (GtkIconHelper *self, cairo_surface_t *surface); +void _gtk_icon_helper_set_texture (GtkIconHelper *self, + GdkTexture *texture); gboolean _gtk_icon_helper_set_icon_size (GtkIconHelper *self, GtkIconSize icon_size); @@ -85,6 +87,7 @@ gboolean _gtk_icon_helper_get_use_fallback (GtkIconHelper *self); GIcon *_gtk_icon_helper_peek_gicon (GtkIconHelper *self); cairo_surface_t *_gtk_icon_helper_peek_surface (GtkIconHelper *self); +GdkTexture *_gtk_icon_helper_peek_texture (GtkIconHelper *self); GtkImageDefinition *gtk_icon_helper_get_definition (GtkIconHelper *self); const gchar *_gtk_icon_helper_get_icon_name (GtkIconHelper *self); diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index c76bcb954c..29947e9b2e 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -115,6 +115,7 @@ enum { PROP_0, PROP_SURFACE, + PROP_TEXTURE, PROP_FILE, PROP_ICON_SIZE, PROP_PIXEL_SIZE, @@ -156,6 +157,13 @@ gtk_image_class_init (GtkImageClass *class) CAIRO_GOBJECT_TYPE_SURFACE, GTK_PARAM_READWRITE); + image_props[PROP_TEXTURE] = + g_param_spec_object ("texture", + P_("Texture"), + P_("A GdkTexture to display"), + GDK_TYPE_TEXTURE, + GTK_PARAM_READWRITE); + image_props[PROP_FILE] = g_param_spec_string ("file", P_("Filename"), @@ -309,6 +317,9 @@ gtk_image_set_property (GObject *object, case PROP_SURFACE: gtk_image_set_from_surface (image, g_value_get_boxed (value)); break; + case PROP_TEXTURE: + gtk_image_set_from_texture (image, g_value_get_object (value)); + break; case PROP_FILE: gtk_image_set_from_file (image, g_value_get_string (value)); break; @@ -357,6 +368,9 @@ gtk_image_get_property (GObject *object, case PROP_SURFACE: g_value_set_boxed (value, _gtk_icon_helper_peek_surface (&priv->icon_helper)); break; + case PROP_TEXTURE: + g_value_set_object (value, _gtk_icon_helper_peek_texture (&priv->icon_helper)); + break; case PROP_FILE: g_value_set_string (value, priv->filename); break; @@ -398,8 +412,8 @@ gtk_image_get_property (GObject *object, * it always returns a valid #GtkImage widget. * * If you need to detect failures to load the file, use - * gdk_pixbuf_new_from_file() to load the file yourself, then create - * the #GtkImage from the surface. + * gdk_texture_new_from_file() to load the file yourself, then create + * the #GtkImage from the texture. * * The storage type (gtk_image_get_storage_type()) of the returned * image is not defined, it will be whatever is appropriate for @@ -931,6 +945,42 @@ gtk_image_set_from_surface (GtkImage *image, g_object_thaw_notify (G_OBJECT (image)); } +/** + * gtk_image_set_from_texture: + * @image: a #GtkImage + * @surface: (nullable): a #GdkTexture or %NULL + * + * See gtk_image_new_from_texture() for details. + * + * Since: 3.94 + **/ +void +gtk_image_set_from_texture (GtkImage *image, + GdkTexture *texture) +{ + GtkImagePrivate *priv = gtk_image_get_instance_private (image); + + g_return_if_fail (GTK_IS_IMAGE (image)); + g_return_if_fail (texture == NULL || GDK_IS_TEXTURE (texture)); + + g_object_freeze_notify (G_OBJECT (image)); + + if (texture) + g_object_ref (texture); + + gtk_image_clear (image); + + if (texture) + { + _gtk_icon_helper_set_texture (&priv->icon_helper, texture); + g_object_unref (texture); + } + + g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_TEXTURE]); + + g_object_thaw_notify (G_OBJECT (image)); +} + /** * gtk_image_get_storage_type: * @image: a #GtkImage @@ -975,6 +1025,31 @@ gtk_image_get_surface (GtkImage *image) return _gtk_icon_helper_peek_surface (&priv->icon_helper); } +/** + * gtk_image_get_texture: + * @image: a #GtkImage + * + * Gets the image #GdkTexture being displayed by the #GtkImage. + * The storage type of the image must be %GTK_IMAGE_EMPTY or + * %GTK_IMAGE_TEXTURE (see gtk_image_get_storage_type()). + * The caller of this function does not own a reference to the + * returned texture. + * + * Returns: (nullable) (transfer none): the displayed texture, or %NULL if + * the image is empty + * + * Since: 3.94 + **/ +GdkTexture * +gtk_image_get_texture (GtkImage *image) +{ + GtkImagePrivate *priv = gtk_image_get_instance_private (image); + + g_return_val_if_fail (GTK_IS_IMAGE (image), NULL); + + return _gtk_icon_helper_peek_texture (&priv->icon_helper); +} + /** * gtk_image_get_icon_name: * @image: a #GtkImage @@ -1145,6 +1220,9 @@ gtk_image_notify_for_storage_type (GtkImage *image, case GTK_IMAGE_SURFACE: g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_SURFACE]); break; + case GTK_IMAGE_TEXTURE: + g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_TEXTURE]); + break; case GTK_IMAGE_EMPTY: default: break; diff --git a/gtk/gtkimage.h b/gtk/gtkimage.h index de270b1f8e..f7dbd3dd1f 100644 --- a/gtk/gtkimage.h +++ b/gtk/gtkimage.h @@ -57,6 +57,8 @@ typedef struct _GtkImageClass GtkImageClass; * This image type was added in GTK+ 2.14 * @GTK_IMAGE_SURFACE: the widget contains a #cairo_surface_t. * This image type was added in GTK+ 3.10 + * @GTK_IMAGE_TEXTURE: the widget contains a #GdkTexture. + * This image type was added in GTK+ 3.94 * * Describes the image data representation used by a #GtkImage. If you * want to get the image from the widget, you can only get the @@ -71,7 +73,8 @@ typedef enum GTK_IMAGE_EMPTY, GTK_IMAGE_ICON_NAME, GTK_IMAGE_GICON, - GTK_IMAGE_SURFACE + GTK_IMAGE_SURFACE, + GTK_IMAGE_TEXTURE } GtkImageType; /** @@ -107,6 +110,8 @@ GDK_AVAILABLE_IN_ALL GtkWidget* gtk_image_new_from_resource (const gchar *resource_path); GDK_AVAILABLE_IN_ALL GtkWidget* gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf); +GDK_AVAILABLE_IN_3_94 +GtkWidget* gtk_image_new_from_texture (GdkTexture *texture); GDK_AVAILABLE_IN_ALL GtkWidget* gtk_image_new_from_icon_name (const gchar *icon_name, GtkIconSize size); @@ -127,6 +132,9 @@ void gtk_image_set_from_resource (GtkImage *image, GDK_AVAILABLE_IN_ALL void gtk_image_set_from_pixbuf (GtkImage *image, GdkPixbuf *pixbuf); +GDK_AVAILABLE_IN_3_94 +void gtk_image_set_from_texture (GtkImage *image, + GdkTexture *texture); GDK_AVAILABLE_IN_ALL void gtk_image_set_from_icon_name (GtkImage *image, const gchar *icon_name, @@ -147,6 +155,8 @@ GtkImageType gtk_image_get_storage_type (GtkImage *image); GDK_AVAILABLE_IN_3_94 cairo_surface_t *gtk_image_get_surface (GtkImage *image); +GDK_AVAILABLE_IN_3_94 +GdkTexture *gtk_image_get_texture (GtkImage *image); GDK_AVAILABLE_IN_ALL void gtk_image_get_icon_name (GtkImage *image, diff --git a/gtk/gtkimagedefinition.c b/gtk/gtkimagedefinition.c index f16006cb70..d1a1c9900b 100644 --- a/gtk/gtkimagedefinition.c +++ b/gtk/gtkimagedefinition.c @@ -24,6 +24,7 @@ typedef struct _GtkImageDefinitionStock GtkImageDefinitionStock; typedef struct _GtkImageDefinitionIconName GtkImageDefinitionIconName; typedef struct _GtkImageDefinitionGIcon GtkImageDefinitionGIcon; typedef struct _GtkImageDefinitionSurface GtkImageDefinitionSurface; +typedef struct _GtkImageDefinitionTexture GtkImageDefinitionTexture; struct _GtkImageDefinitionEmpty { GtkImageType type; @@ -58,6 +59,13 @@ struct _GtkImageDefinitionSurface { cairo_surface_t *surface; }; +struct _GtkImageDefinitionTexture { + GtkImageType type; + gint ref_count; + + GdkTexture *texture; +}; + union _GtkImageDefinition { GtkImageType type; @@ -66,6 +74,7 @@ union _GtkImageDefinition GtkImageDefinitionIconName icon_name; GtkImageDefinitionGIcon gicon; GtkImageDefinitionSurface surface; + GtkImageDefinitionTexture texture; }; GtkImageDefinition * @@ -84,7 +93,8 @@ gtk_image_definition_alloc (GtkImageType type) sizeof (GtkImageDefinitionStock), sizeof (GtkImageDefinitionIconName), sizeof (GtkImageDefinitionGIcon), - sizeof (GtkImageDefinitionSurface) + sizeof (GtkImageDefinitionSurface), + sizeof (GtkImageDefinitionTexture) }; GtkImageDefinition *def; @@ -139,6 +149,20 @@ gtk_image_definition_new_surface (cairo_surface_t *surface) return def; } +GtkImageDefinition * +gtk_image_definition_new_texture (GdkTexture *texture) +{ + GtkImageDefinition *def; + + if (texture == NULL) + return NULL; + + def = gtk_image_definition_alloc (GTK_IMAGE_TEXTURE); + def->texture.texture = g_object_ref (texture); + + return def; +} + GtkImageDefinition * gtk_image_definition_ref (GtkImageDefinition *def) { @@ -164,6 +188,9 @@ gtk_image_definition_unref (GtkImageDefinition *def) case GTK_IMAGE_SURFACE: cairo_surface_destroy (def->surface.surface); break; + case GTK_IMAGE_TEXTURE: + g_object_unref (def->texture.texture); + break; case GTK_IMAGE_ICON_NAME: g_free (def->icon_name.icon_name); break; @@ -190,6 +217,7 @@ gtk_image_definition_get_scale (const GtkImageDefinition *def) g_assert_not_reached (); case GTK_IMAGE_EMPTY: case GTK_IMAGE_SURFACE: + case GTK_IMAGE_TEXTURE: case GTK_IMAGE_ICON_NAME: case GTK_IMAGE_GICON: return 1; @@ -222,3 +250,12 @@ gtk_image_definition_get_surface (const GtkImageDefinition *def) return def->surface.surface; } + +GdkTexture * +gtk_image_definition_get_texture (const GtkImageDefinition *def) +{ + if (def->type != GTK_IMAGE_TEXTURE) + return NULL; + + return def->texture.texture; +} diff --git a/gtk/gtkimagedefinitionprivate.h b/gtk/gtkimagedefinitionprivate.h index 9acf7ce876..2dac974ee8 100644 --- a/gtk/gtkimagedefinitionprivate.h +++ b/gtk/gtkimagedefinitionprivate.h @@ -29,6 +29,7 @@ GtkImageDefinition * gtk_image_definition_new_empty (void); GtkImageDefinition * gtk_image_definition_new_icon_name (const char *icon_name); GtkImageDefinition * gtk_image_definition_new_gicon (GIcon *gicon); GtkImageDefinition * gtk_image_definition_new_surface (cairo_surface_t *surface); +GtkImageDefinition * gtk_image_definition_new_texture (GdkTexture *texture); GtkImageDefinition * gtk_image_definition_ref (GtkImageDefinition *def); void gtk_image_definition_unref (GtkImageDefinition *def); @@ -38,6 +39,7 @@ gint gtk_image_definition_get_scale (const GtkImageD const gchar * gtk_image_definition_get_icon_name (const GtkImageDefinition *def); GIcon * gtk_image_definition_get_gicon (const GtkImageDefinition *def); cairo_surface_t * gtk_image_definition_get_surface (const GtkImageDefinition *def); +GdkTexture * gtk_image_definition_get_texture (const GtkImageDefinition *def); G_END_DECLS