1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #include "gtkcontainer.h"
34 #include "gtkiconfactory.h"
36 #include "gtkicontheme.h"
37 #include "gtksizerequest.h"
39 #include "gtkprivate.h"
40 #include "gtktypebuiltins.h"
44 * @Short_description: A widget displaying an image
46 * @See_also:#GdkPixbuf
48 * The #GtkImage widget displays an image. Various kinds of object
49 * can be displayed as an image; most typically, you would load a
50 * #GdkPixbuf ("pixel buffer") from a file, and then display that.
51 * There's a convenience function to do this, gtk_image_new_from_file(),
53 * <informalexample><programlisting>
55 * image = gtk_image_new_from_file ("myfile.png");
56 * </programlisting></informalexample>
57 * If the file isn't loaded successfully, the image will contain a
58 * "broken image" icon similar to that used in many web browsers.
59 * If you want to handle errors in loading the file yourself,
60 * for example by displaying an error message, then load the image with
61 * gdk_pixbuf_new_from_file(), then create the #GtkImage with
62 * gtk_image_new_from_pixbuf().
64 * The image file may contain an animation, if so the #GtkImage will
65 * display an animation (#GdkPixbufAnimation) instead of a static image.
67 * #GtkImage is a subclass of #GtkMisc, which implies that you can
68 * align it (center, left, right) and add padding to it, using
71 * #GtkImage is a "no window" widget (has no #GdkWindow of its own),
72 * so by default does not receive events. If you want to receive events
73 * on the image, such as button clicks, place the image inside a
74 * #GtkEventBox, then connect to the event signals on the event box.
76 * <title>Handling button press events on a
77 * <structname>GtkImage</structname>.</title>
80 * button_press_callback (GtkWidget *event_box,
81 * GdkEventButton *event,
84 * g_print ("Event box clicked at coordinates %f,%f\n",
85 * event->x, event->y);
87 * /<!---->* Returning TRUE means we handled the event, so the signal
88 * * emission should be stopped (don't call any further
89 * * callbacks that may be connected). Return FALSE
90 * * to continue invoking callbacks.
99 * GtkWidget *event_box;
101 * image = gtk_image_new_from_file ("myfile.png");
103 * event_box = gtk_event_box_new (<!-- -->);
105 * gtk_container_add (GTK_CONTAINER (event_box), image);
107 * g_signal_connect (G_OBJECT (event_box),
108 * "button_press_event",
109 * G_CALLBACK (button_press_callback),
117 * When handling events on the event box, keep in mind that coordinates
118 * in the image may be different from event box coordinates due to
119 * the alignment and padding settings on the image (see #GtkMisc).
120 * The simplest way to solve this is to set the alignment to 0.0
121 * (left/top), and set the padding to zero. Then the origin of
122 * the image will be the same as the origin of the event box.
124 * Sometimes an application will want to avoid depending on external data
125 * files, such as image files. GTK+ comes with a program to avoid this,
126 * called <application>gdk-pixbuf-csource</application>. This program
127 * allows you to convert an image into a C variable declaration, which
128 * can then be loaded into a #GdkPixbuf using
129 * gdk_pixbuf_new_from_inline().
133 struct _GtkImagePrivate
135 GtkIconSize icon_size; /* Only used with GTK_IMAGE_STOCK, GTK_IMAGE_ICON_SET, GTK_IMAGE_ICON_NAME */
136 GtkImageType storage_type;
140 GtkImagePixbufData pixbuf;
141 GtkImageStockData stock;
142 GtkImageIconSetData icon_set;
143 GtkImageAnimationData anim;
144 GtkImageIconNameData name;
145 GtkImageGIconData gicon;
148 gboolean was_symbolic;
149 gchar *filename; /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
150 gint last_rendered_state; /* a GtkStateType, with -1 meaning an invalid state,
151 * only used with GTK_IMAGE_GICON, GTK_IMAGE_ICON_NAME */
153 guint need_calc_size : 1;
155 gint required_height;
159 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
160 static gint gtk_image_draw (GtkWidget *widget,
162 static void gtk_image_unmap (GtkWidget *widget);
163 static void gtk_image_unrealize (GtkWidget *widget);
164 static void gtk_image_get_preferred_width (GtkWidget *widget,
167 static void gtk_image_get_preferred_height (GtkWidget *widget,
171 static void gtk_image_style_set (GtkWidget *widget,
172 GtkStyle *prev_style);
173 static void gtk_image_screen_changed (GtkWidget *widget,
174 GdkScreen *prev_screen);
175 static void gtk_image_destroy (GtkWidget *widget);
176 static void gtk_image_reset (GtkImage *image);
177 static void gtk_image_calc_size (GtkImage *image);
179 static void gtk_image_update_size (GtkImage *image,
183 static void gtk_image_set_property (GObject *object,
187 static void gtk_image_get_property (GObject *object,
192 static void icon_theme_changed (GtkImage *image);
203 PROP_PIXBUF_ANIMATION,
209 G_DEFINE_TYPE (GtkImage, gtk_image, GTK_TYPE_MISC)
212 gtk_image_class_init (GtkImageClass *class)
214 GObjectClass *gobject_class;
215 GtkWidgetClass *widget_class;
217 gobject_class = G_OBJECT_CLASS (class);
219 gobject_class->set_property = gtk_image_set_property;
220 gobject_class->get_property = gtk_image_get_property;
222 widget_class = GTK_WIDGET_CLASS (class);
223 widget_class->draw = gtk_image_draw;
224 widget_class->destroy = gtk_image_destroy;
225 widget_class->get_preferred_width = gtk_image_get_preferred_width;
226 widget_class->get_preferred_height = gtk_image_get_preferred_height;
227 widget_class->unmap = gtk_image_unmap;
228 widget_class->unrealize = gtk_image_unrealize;
229 widget_class->style_set = gtk_image_style_set;
230 widget_class->screen_changed = gtk_image_screen_changed;
232 g_object_class_install_property (gobject_class,
234 g_param_spec_object ("pixbuf",
236 P_("A GdkPixbuf to display"),
238 GTK_PARAM_READWRITE));
240 g_object_class_install_property (gobject_class,
242 g_param_spec_string ("file",
244 P_("Filename to load and display"),
246 GTK_PARAM_READWRITE));
249 g_object_class_install_property (gobject_class,
251 g_param_spec_string ("stock",
253 P_("Stock ID for a stock image to display"),
255 GTK_PARAM_READWRITE));
257 g_object_class_install_property (gobject_class,
259 g_param_spec_boxed ("icon-set",
261 P_("Icon set to display"),
263 GTK_PARAM_READWRITE));
265 g_object_class_install_property (gobject_class,
267 g_param_spec_int ("icon-size",
269 P_("Symbolic size to use for stock icon, icon set or named icon"),
272 GTK_PARAM_READWRITE));
274 * GtkImage:pixel-size:
276 * The "pixel-size" property can be used to specify a fixed size
277 * overriding the #GtkImage:icon-size property for images of type
278 * %GTK_IMAGE_ICON_NAME.
282 g_object_class_install_property (gobject_class,
284 g_param_spec_int ("pixel-size",
286 P_("Pixel size to use for named icon"),
289 GTK_PARAM_READWRITE));
291 g_object_class_install_property (gobject_class,
292 PROP_PIXBUF_ANIMATION,
293 g_param_spec_object ("pixbuf-animation",
295 P_("GdkPixbufAnimation to display"),
296 GDK_TYPE_PIXBUF_ANIMATION,
297 GTK_PARAM_READWRITE));
300 * GtkImage:icon-name:
302 * The name of the icon in the icon theme. If the icon theme is
303 * changed, the image will be updated automatically.
307 g_object_class_install_property (gobject_class,
309 g_param_spec_string ("icon-name",
311 P_("The name of the icon from the icon theme"),
313 GTK_PARAM_READWRITE));
318 * The GIcon displayed in the GtkImage. For themed icons,
319 * If the icon theme is changed, the image will be updated
324 g_object_class_install_property (gobject_class,
326 g_param_spec_object ("gicon",
328 P_("The GIcon being displayed"),
330 GTK_PARAM_READWRITE));
332 g_object_class_install_property (gobject_class,
334 g_param_spec_enum ("storage-type",
336 P_("The representation being used for image data"),
339 GTK_PARAM_READABLE));
341 g_type_class_add_private (class, sizeof (GtkImagePrivate));
345 gtk_image_init (GtkImage *image)
347 GtkImagePrivate *priv;
349 image->priv = G_TYPE_INSTANCE_GET_PRIVATE (image,
354 gtk_widget_set_has_window (GTK_WIDGET (image), FALSE);
356 priv->storage_type = GTK_IMAGE_EMPTY;
357 priv->icon_size = DEFAULT_ICON_SIZE;
359 priv->pixel_size = -1;
361 priv->filename = NULL;
365 gtk_image_destroy (GtkWidget *widget)
367 GtkImage *image = GTK_IMAGE (widget);
369 gtk_image_reset (image);
371 GTK_WIDGET_CLASS (gtk_image_parent_class)->destroy (widget);
375 gtk_image_set_property (GObject *object,
380 GtkImage *image = GTK_IMAGE (object);
381 GtkImagePrivate *priv = image->priv;
386 gtk_image_set_from_pixbuf (image,
387 g_value_get_object (value));
390 gtk_image_set_from_file (image, g_value_get_string (value));
393 gtk_image_set_from_stock (image, g_value_get_string (value),
397 gtk_image_set_from_icon_set (image, g_value_get_boxed (value),
401 if (priv->storage_type == GTK_IMAGE_STOCK)
402 gtk_image_set_from_stock (image,
403 priv->data.stock.stock_id,
404 g_value_get_int (value));
405 else if (priv->storage_type == GTK_IMAGE_ICON_SET)
406 gtk_image_set_from_icon_set (image,
407 priv->data.icon_set.icon_set,
408 g_value_get_int (value));
409 else if (priv->storage_type == GTK_IMAGE_ICON_NAME)
410 gtk_image_set_from_icon_name (image,
411 priv->data.name.icon_name,
412 g_value_get_int (value));
413 else if (priv->storage_type == GTK_IMAGE_GICON)
414 gtk_image_set_from_gicon (image,
415 priv->data.gicon.icon,
416 g_value_get_int (value));
418 /* Save to be used when STOCK, ICON_SET, ICON_NAME or GICON property comes in */
419 priv->icon_size = g_value_get_int (value);
421 case PROP_PIXEL_SIZE:
422 gtk_image_set_pixel_size (image, g_value_get_int (value));
424 case PROP_PIXBUF_ANIMATION:
425 gtk_image_set_from_animation (image,
426 g_value_get_object (value));
429 gtk_image_set_from_icon_name (image, g_value_get_string (value),
433 gtk_image_set_from_gicon (image, g_value_get_object (value),
438 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
444 gtk_image_get_property (GObject *object,
449 GtkImage *image = GTK_IMAGE (object);
450 GtkImagePrivate *priv = image->priv;
452 /* The "getter" functions whine if you try to get the wrong
453 * storage type. This function is instead robust against that,
454 * so that GUI builders don't have to jump through hoops
461 if (priv->storage_type != GTK_IMAGE_PIXBUF)
462 g_value_set_object (value, NULL);
464 g_value_set_object (value,
465 gtk_image_get_pixbuf (image));
468 g_value_set_string (value, priv->filename);
471 if (priv->storage_type != GTK_IMAGE_STOCK)
472 g_value_set_string (value, NULL);
474 g_value_set_string (value,
475 priv->data.stock.stock_id);
478 if (priv->storage_type != GTK_IMAGE_ICON_SET)
479 g_value_set_boxed (value, NULL);
481 g_value_set_boxed (value,
482 priv->data.icon_set.icon_set);
485 g_value_set_int (value, priv->icon_size);
487 case PROP_PIXEL_SIZE:
488 g_value_set_int (value, priv->pixel_size);
490 case PROP_PIXBUF_ANIMATION:
491 if (priv->storage_type != GTK_IMAGE_ANIMATION)
492 g_value_set_object (value, NULL);
494 g_value_set_object (value,
495 priv->data.anim.anim);
498 if (priv->storage_type != GTK_IMAGE_ICON_NAME)
499 g_value_set_string (value, NULL);
501 g_value_set_string (value,
502 priv->data.name.icon_name);
505 if (priv->storage_type != GTK_IMAGE_GICON)
506 g_value_set_object (value, NULL);
508 g_value_set_object (value,
509 priv->data.gicon.icon);
511 case PROP_STORAGE_TYPE:
512 g_value_set_enum (value, priv->storage_type);
516 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
523 * gtk_image_new_from_file:
524 * @filename: a filename
526 * Creates a new #GtkImage displaying the file @filename. If the file
527 * isn't found or can't be loaded, the resulting #GtkImage will
528 * display a "broken image" icon. This function never returns %NULL,
529 * it always returns a valid #GtkImage widget.
531 * If the file contains an animation, the image will contain an
534 * If you need to detect failures to load the file, use
535 * gdk_pixbuf_new_from_file() to load the file yourself, then create
536 * the #GtkImage from the pixbuf. (Or for animations, use
537 * gdk_pixbuf_animation_new_from_file()).
539 * The storage type (gtk_image_get_storage_type()) of the returned
540 * image is not defined, it will be whatever is appropriate for
541 * displaying the file.
543 * Return value: a new #GtkImage
546 gtk_image_new_from_file (const gchar *filename)
550 image = g_object_new (GTK_TYPE_IMAGE, NULL);
552 gtk_image_set_from_file (image, filename);
554 return GTK_WIDGET (image);
558 * gtk_image_new_from_pixbuf:
559 * @pixbuf: (allow-none): a #GdkPixbuf, or %NULL
561 * Creates a new #GtkImage displaying @pixbuf.
562 * The #GtkImage does not assume a reference to the
563 * pixbuf; you still need to unref it if you own references.
564 * #GtkImage will add its own reference rather than adopting yours.
566 * Note that this function just creates an #GtkImage from the pixbuf. The
567 * #GtkImage created will not react to state changes. Should you want that,
568 * you should use gtk_image_new_from_icon_set().
570 * Return value: a new #GtkImage
573 gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
577 image = g_object_new (GTK_TYPE_IMAGE, NULL);
579 gtk_image_set_from_pixbuf (image, pixbuf);
581 return GTK_WIDGET (image);
585 * gtk_image_new_from_stock:
586 * @stock_id: a stock icon name
587 * @size: (type int): a stock icon size
589 * Creates a #GtkImage displaying a stock icon. Sample stock icon
590 * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. Sample stock sizes
591 * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
592 * icon name isn't known, the image will be empty.
593 * You can register your own stock icon names, see
594 * gtk_icon_factory_add_default() and gtk_icon_factory_add().
596 * Return value: a new #GtkImage displaying the stock icon
599 gtk_image_new_from_stock (const gchar *stock_id,
604 image = g_object_new (GTK_TYPE_IMAGE, NULL);
606 gtk_image_set_from_stock (image, stock_id, size);
608 return GTK_WIDGET (image);
612 * gtk_image_new_from_icon_set:
613 * @icon_set: a #GtkIconSet
614 * @size: (type int): a stock icon size
616 * Creates a #GtkImage displaying an icon set. Sample stock sizes are
617 * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. Instead of using
618 * this function, usually it's better to create a #GtkIconFactory, put
619 * your icon sets in the icon factory, add the icon factory to the
620 * list of default factories with gtk_icon_factory_add_default(), and
621 * then use gtk_image_new_from_stock(). This will allow themes to
622 * override the icon you ship with your application.
624 * The #GtkImage does not assume a reference to the
625 * icon set; you still need to unref it if you own references.
626 * #GtkImage will add its own reference rather than adopting yours.
628 * Return value: a new #GtkImage
631 gtk_image_new_from_icon_set (GtkIconSet *icon_set,
636 image = g_object_new (GTK_TYPE_IMAGE, NULL);
638 gtk_image_set_from_icon_set (image, icon_set, size);
640 return GTK_WIDGET (image);
644 * gtk_image_new_from_animation:
645 * @animation: an animation
647 * Creates a #GtkImage displaying the given animation.
648 * The #GtkImage does not assume a reference to the
649 * animation; you still need to unref it if you own references.
650 * #GtkImage will add its own reference rather than adopting yours.
652 * Note that the animation frames are shown using a timeout with
653 * #G_PRIORITY_DEFAULT. When using animations to indicate busyness,
654 * keep in mind that the animation will only be shown if the main loop
655 * is not busy with something that has a higher priority.
657 * Return value: a new #GtkImage widget
660 gtk_image_new_from_animation (GdkPixbufAnimation *animation)
664 g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
666 image = g_object_new (GTK_TYPE_IMAGE, NULL);
668 gtk_image_set_from_animation (image, animation);
670 return GTK_WIDGET (image);
674 * gtk_image_new_from_icon_name:
675 * @icon_name: an icon name
676 * @size: (type int): a stock icon size
678 * Creates a #GtkImage displaying an icon from the current icon theme.
679 * If the icon name isn't known, a "broken image" icon will be
680 * displayed instead. If the current icon theme is changed, the icon
681 * will be updated appropriately.
683 * Return value: a new #GtkImage displaying the themed icon
688 gtk_image_new_from_icon_name (const gchar *icon_name,
693 image = g_object_new (GTK_TYPE_IMAGE, NULL);
695 gtk_image_set_from_icon_name (image, icon_name, size);
697 return GTK_WIDGET (image);
701 * gtk_image_new_from_gicon:
703 * @size: (type int): a stock icon size
705 * Creates a #GtkImage displaying an icon from the current icon theme.
706 * If the icon name isn't known, a "broken image" icon will be
707 * displayed instead. If the current icon theme is changed, the icon
708 * will be updated appropriately.
710 * Return value: a new #GtkImage displaying the themed icon
715 gtk_image_new_from_gicon (GIcon *icon,
720 image = g_object_new (GTK_TYPE_IMAGE, NULL);
722 gtk_image_set_from_gicon (image, icon, size);
724 return GTK_WIDGET (image);
728 * gtk_image_set_from_file:
729 * @image: a #GtkImage
730 * @filename: (allow-none): a filename or %NULL
732 * See gtk_image_new_from_file() for details.
735 gtk_image_set_from_file (GtkImage *image,
736 const gchar *filename)
738 GtkImagePrivate *priv;
739 GdkPixbufAnimation *anim;
741 g_return_if_fail (GTK_IS_IMAGE (image));
745 g_object_freeze_notify (G_OBJECT (image));
747 gtk_image_clear (image);
749 if (filename == NULL)
751 priv->filename = NULL;
752 g_object_thaw_notify (G_OBJECT (image));
756 anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
760 gtk_image_set_from_stock (image,
761 GTK_STOCK_MISSING_IMAGE,
762 GTK_ICON_SIZE_BUTTON);
763 g_object_thaw_notify (G_OBJECT (image));
767 /* We could just unconditionally set_from_animation,
768 * but it's nicer for memory if we toss the animation
769 * if it's just a single pixbuf
772 if (gdk_pixbuf_animation_is_static_image (anim))
773 gtk_image_set_from_pixbuf (image,
774 gdk_pixbuf_animation_get_static_image (anim));
776 gtk_image_set_from_animation (image, anim);
778 g_object_unref (anim);
780 priv->filename = g_strdup (filename);
782 g_object_thaw_notify (G_OBJECT (image));
786 * gtk_image_set_from_pixbuf:
787 * @image: a #GtkImage
788 * @pixbuf: (allow-none): a #GdkPixbuf or %NULL
790 * See gtk_image_new_from_pixbuf() for details.
793 gtk_image_set_from_pixbuf (GtkImage *image,
796 GtkImagePrivate *priv;
798 g_return_if_fail (GTK_IS_IMAGE (image));
799 g_return_if_fail (pixbuf == NULL ||
800 GDK_IS_PIXBUF (pixbuf));
804 g_object_freeze_notify (G_OBJECT (image));
807 g_object_ref (pixbuf);
809 gtk_image_clear (image);
813 priv->storage_type = GTK_IMAGE_PIXBUF;
815 priv->data.pixbuf.pixbuf = pixbuf;
817 gtk_image_update_size (image,
818 gdk_pixbuf_get_width (pixbuf),
819 gdk_pixbuf_get_height (pixbuf));
822 g_object_notify (G_OBJECT (image), "pixbuf");
824 g_object_thaw_notify (G_OBJECT (image));
828 * gtk_image_set_from_stock:
829 * @image: a #GtkImage
830 * @stock_id: a stock icon name
831 * @size: (type int): a stock icon size
833 * See gtk_image_new_from_stock() for details.
836 gtk_image_set_from_stock (GtkImage *image,
837 const gchar *stock_id,
840 GtkImagePrivate *priv;
843 g_return_if_fail (GTK_IS_IMAGE (image));
847 g_object_freeze_notify (G_OBJECT (image));
849 /* in case stock_id == priv->data.stock.stock_id */
850 new_id = g_strdup (stock_id);
852 gtk_image_clear (image);
856 priv->storage_type = GTK_IMAGE_STOCK;
858 priv->data.stock.stock_id = new_id;
859 priv->icon_size = size;
861 /* Size is demand-computed in size request method
862 * if we're a stock image, since changing the
863 * style impacts the size request
867 g_object_notify (G_OBJECT (image), "stock");
868 g_object_notify (G_OBJECT (image), "icon-size");
870 g_object_thaw_notify (G_OBJECT (image));
874 * gtk_image_set_from_icon_set:
875 * @image: a #GtkImage
876 * @icon_set: a #GtkIconSet
877 * @size: (type int): a stock icon size
879 * See gtk_image_new_from_icon_set() for details.
882 gtk_image_set_from_icon_set (GtkImage *image,
883 GtkIconSet *icon_set,
886 GtkImagePrivate *priv;
888 g_return_if_fail (GTK_IS_IMAGE (image));
892 g_object_freeze_notify (G_OBJECT (image));
895 gtk_icon_set_ref (icon_set);
897 gtk_image_clear (image);
901 priv->storage_type = GTK_IMAGE_ICON_SET;
903 priv->data.icon_set.icon_set = icon_set;
904 priv->icon_size = size;
906 /* Size is demand-computed in size request method
907 * if we're an icon set
911 g_object_notify (G_OBJECT (image), "icon-set");
912 g_object_notify (G_OBJECT (image), "icon-size");
914 g_object_thaw_notify (G_OBJECT (image));
918 * gtk_image_set_from_animation:
919 * @image: a #GtkImage
920 * @animation: the #GdkPixbufAnimation
922 * Causes the #GtkImage to display the given animation (or display
923 * nothing, if you set the animation to %NULL).
926 gtk_image_set_from_animation (GtkImage *image,
927 GdkPixbufAnimation *animation)
929 GtkImagePrivate *priv;
931 g_return_if_fail (GTK_IS_IMAGE (image));
932 g_return_if_fail (animation == NULL ||
933 GDK_IS_PIXBUF_ANIMATION (animation));
937 g_object_freeze_notify (G_OBJECT (image));
940 g_object_ref (animation);
942 gtk_image_clear (image);
944 if (animation != NULL)
946 priv->storage_type = GTK_IMAGE_ANIMATION;
948 priv->data.anim.anim = animation;
949 priv->data.anim.frame_timeout = 0;
950 priv->data.anim.iter = NULL;
952 gtk_image_update_size (image,
953 gdk_pixbuf_animation_get_width (animation),
954 gdk_pixbuf_animation_get_height (animation));
957 g_object_notify (G_OBJECT (image), "pixbuf-animation");
959 g_object_thaw_notify (G_OBJECT (image));
963 * gtk_image_set_from_icon_name:
964 * @image: a #GtkImage
965 * @icon_name: an icon name
966 * @size: (type int): an icon size
968 * See gtk_image_new_from_icon_name() for details.
973 gtk_image_set_from_icon_name (GtkImage *image,
974 const gchar *icon_name,
978 GtkImagePrivate *priv;
980 g_return_if_fail (GTK_IS_IMAGE (image));
984 g_object_freeze_notify (G_OBJECT (image));
986 /* in case icon_name == priv->data.name.icon_name */
987 new_name = g_strdup (icon_name);
989 gtk_image_clear (image);
993 priv->storage_type = GTK_IMAGE_ICON_NAME;
995 priv->data.name.icon_name = new_name;
996 priv->icon_size = size;
998 /* Size is demand-computed in size request method
999 * if we're a icon theme image, since changing the
1000 * style impacts the size request
1004 g_object_notify (G_OBJECT (image), "icon-name");
1005 g_object_notify (G_OBJECT (image), "icon-size");
1007 g_object_thaw_notify (G_OBJECT (image));
1011 * gtk_image_set_from_gicon:
1012 * @image: a #GtkImage
1014 * @size: (type int): an icon size
1016 * See gtk_image_new_from_gicon() for details.
1021 gtk_image_set_from_gicon (GtkImage *image,
1025 GtkImagePrivate *priv;
1027 g_return_if_fail (GTK_IS_IMAGE (image));
1031 g_object_freeze_notify (G_OBJECT (image));
1033 /* in case icon == priv->data.gicon.icon */
1035 g_object_ref (icon);
1037 gtk_image_clear (image);
1041 priv->storage_type = GTK_IMAGE_GICON;
1043 priv->data.gicon.icon = icon;
1044 priv->icon_size = size;
1046 /* Size is demand-computed in size request method
1047 * if we're a icon theme image, since changing the
1048 * style impacts the size request
1052 g_object_notify (G_OBJECT (image), "gicon");
1053 g_object_notify (G_OBJECT (image), "icon-size");
1055 g_object_thaw_notify (G_OBJECT (image));
1059 * gtk_image_get_storage_type:
1060 * @image: a #GtkImage
1062 * Gets the type of representation being used by the #GtkImage
1063 * to store image data. If the #GtkImage has no image data,
1064 * the return value will be %GTK_IMAGE_EMPTY.
1066 * Return value: image representation being used
1069 gtk_image_get_storage_type (GtkImage *image)
1071 g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);
1073 return image->priv->storage_type;
1077 * gtk_image_get_pixbuf:
1078 * @image: a #GtkImage
1080 * Gets the #GdkPixbuf being displayed by the #GtkImage.
1081 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1082 * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
1083 * The caller of this function does not own a reference to the
1086 * Return value: (transfer none): the displayed pixbuf, or %NULL if
1087 * the image is empty
1090 gtk_image_get_pixbuf (GtkImage *image)
1092 GtkImagePrivate *priv;
1094 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1098 g_return_val_if_fail (priv->storage_type == GTK_IMAGE_PIXBUF ||
1099 priv->storage_type == GTK_IMAGE_EMPTY, NULL);
1101 if (priv->storage_type == GTK_IMAGE_EMPTY)
1102 priv->data.pixbuf.pixbuf = NULL;
1104 return priv->data.pixbuf.pixbuf;
1108 * gtk_image_get_stock:
1109 * @image: a #GtkImage
1110 * @stock_id: (out) (transfer none) (allow-none): place to store a
1111 * stock icon name, or %NULL
1112 * @size: (out) (allow-none) (type int): place to store a stock icon
1115 * Gets the stock icon name and size being displayed by the #GtkImage.
1116 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1117 * %GTK_IMAGE_STOCK (see gtk_image_get_storage_type()).
1118 * The returned string is owned by the #GtkImage and should not
1122 gtk_image_get_stock (GtkImage *image,
1126 GtkImagePrivate *priv;
1128 g_return_if_fail (GTK_IS_IMAGE (image));
1132 g_return_if_fail (priv->storage_type == GTK_IMAGE_STOCK ||
1133 priv->storage_type == GTK_IMAGE_EMPTY);
1135 if (priv->storage_type == GTK_IMAGE_EMPTY)
1136 priv->data.stock.stock_id = NULL;
1139 *stock_id = priv->data.stock.stock_id;
1142 *size = priv->icon_size;
1146 * gtk_image_get_icon_set:
1147 * @image: a #GtkImage
1148 * @icon_set: (out) (transfer none) (allow-none): location to store a
1149 * #GtkIconSet, or %NULL
1150 * @size: (out) (allow-none) (type int): location to store a stock
1151 * icon size, or %NULL
1153 * Gets the icon set and size being displayed by the #GtkImage.
1154 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1155 * %GTK_IMAGE_ICON_SET (see gtk_image_get_storage_type()).
1158 gtk_image_get_icon_set (GtkImage *image,
1159 GtkIconSet **icon_set,
1162 GtkImagePrivate *priv;
1164 g_return_if_fail (GTK_IS_IMAGE (image));
1168 g_return_if_fail (priv->storage_type == GTK_IMAGE_ICON_SET ||
1169 priv->storage_type == GTK_IMAGE_EMPTY);
1172 *icon_set = priv->data.icon_set.icon_set;
1175 *size = priv->icon_size;
1179 * gtk_image_get_animation:
1180 * @image: a #GtkImage
1182 * Gets the #GdkPixbufAnimation being displayed by the #GtkImage.
1183 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1184 * %GTK_IMAGE_ANIMATION (see gtk_image_get_storage_type()).
1185 * The caller of this function does not own a reference to the
1186 * returned animation.
1188 * Return value: (transfer none): the displayed animation, or %NULL if
1189 * the image is empty
1192 gtk_image_get_animation (GtkImage *image)
1194 GtkImagePrivate *priv;
1196 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1200 g_return_val_if_fail (priv->storage_type == GTK_IMAGE_ANIMATION ||
1201 priv->storage_type == GTK_IMAGE_EMPTY,
1204 if (priv->storage_type == GTK_IMAGE_EMPTY)
1205 priv->data.anim.anim = NULL;
1207 return priv->data.anim.anim;
1211 * gtk_image_get_icon_name:
1212 * @image: a #GtkImage
1213 * @icon_name: (out) (transfer none) (allow-none): place to store an
1214 * icon name, or %NULL
1215 * @size: (out) (allow-none) (type int): place to store an icon size,
1218 * Gets the icon name and size being displayed by the #GtkImage.
1219 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1220 * %GTK_IMAGE_ICON_NAME (see gtk_image_get_storage_type()).
1221 * The returned string is owned by the #GtkImage and should not
1227 gtk_image_get_icon_name (GtkImage *image,
1228 G_CONST_RETURN gchar **icon_name,
1231 GtkImagePrivate *priv;
1233 g_return_if_fail (GTK_IS_IMAGE (image));
1237 g_return_if_fail (priv->storage_type == GTK_IMAGE_ICON_NAME ||
1238 priv->storage_type == GTK_IMAGE_EMPTY);
1240 if (priv->storage_type == GTK_IMAGE_EMPTY)
1241 priv->data.name.icon_name = NULL;
1244 *icon_name = priv->data.name.icon_name;
1247 *size = priv->icon_size;
1251 * gtk_image_get_gicon:
1252 * @image: a #GtkImage
1253 * @gicon: (out) (transfer none) (allow-none): place to store a
1255 * @size: (out) (allow-none) (type int): place to store an icon size,
1258 * Gets the #GIcon and size being displayed by the #GtkImage.
1259 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1260 * %GTK_IMAGE_GICON (see gtk_image_get_storage_type()).
1261 * The caller of this function does not own a reference to the
1267 gtk_image_get_gicon (GtkImage *image,
1271 GtkImagePrivate *priv;
1273 g_return_if_fail (GTK_IS_IMAGE (image));
1277 g_return_if_fail (priv->storage_type == GTK_IMAGE_GICON ||
1278 priv->storage_type == GTK_IMAGE_EMPTY);
1280 if (priv->storage_type == GTK_IMAGE_EMPTY)
1281 priv->data.gicon.icon = NULL;
1284 *gicon = priv->data.gicon.icon;
1287 *size = priv->icon_size;
1293 * Creates a new empty #GtkImage widget.
1295 * Return value: a newly created #GtkImage widget.
1298 gtk_image_new (void)
1300 return g_object_new (GTK_TYPE_IMAGE, NULL);
1304 gtk_image_reset_anim_iter (GtkImage *image)
1306 GtkImagePrivate *priv = image->priv;
1308 if (priv->storage_type == GTK_IMAGE_ANIMATION)
1310 /* Reset the animation */
1312 if (priv->data.anim.frame_timeout)
1314 g_source_remove (priv->data.anim.frame_timeout);
1315 priv->data.anim.frame_timeout = 0;
1318 if (priv->data.anim.iter)
1320 g_object_unref (priv->data.anim.iter);
1321 priv->data.anim.iter = NULL;
1327 gtk_image_unmap (GtkWidget *widget)
1329 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1331 GTK_WIDGET_CLASS (gtk_image_parent_class)->unmap (widget);
1335 gtk_image_unrealize (GtkWidget *widget)
1337 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1339 GTK_WIDGET_CLASS (gtk_image_parent_class)->unrealize (widget);
1343 animation_timeout (gpointer data)
1345 GtkImage *image = GTK_IMAGE (data);
1346 GtkImagePrivate *priv = image->priv;
1349 priv->data.anim.frame_timeout = 0;
1351 gdk_pixbuf_animation_iter_advance (priv->data.anim.iter, NULL);
1353 delay = gdk_pixbuf_animation_iter_get_delay_time (priv->data.anim.iter);
1356 GtkWidget *widget = GTK_WIDGET (image);
1358 priv->data.anim.frame_timeout =
1359 gdk_threads_add_timeout (delay, animation_timeout, image);
1361 gtk_widget_queue_draw (widget);
1363 if (gtk_widget_is_drawable (widget))
1364 gdk_window_process_updates (gtk_widget_get_window (widget), TRUE);
1371 icon_theme_changed (GtkImage *image)
1373 GtkImagePrivate *priv = image->priv;
1375 if (priv->storage_type == GTK_IMAGE_ICON_NAME)
1377 if (priv->data.name.pixbuf)
1378 g_object_unref (priv->data.name.pixbuf);
1379 priv->data.name.pixbuf = NULL;
1381 gtk_widget_queue_draw (GTK_WIDGET (image));
1383 if (priv->storage_type == GTK_IMAGE_GICON)
1385 if (priv->data.gicon.pixbuf)
1386 g_object_unref (priv->data.gicon.pixbuf);
1387 priv->data.gicon.pixbuf = NULL;
1389 gtk_widget_queue_draw (GTK_WIDGET (image));
1394 ensure_pixbuf_for_icon_name (GtkImage *image,
1397 GtkImagePrivate *priv = image->priv;
1399 GtkIconTheme *icon_theme;
1400 GtkSettings *settings;
1402 gint *sizes, *s, dist;
1404 GtkIconLookupFlags flags;
1406 g_return_if_fail (priv->storage_type == GTK_IMAGE_ICON_NAME);
1408 screen = gtk_widget_get_screen (GTK_WIDGET (image));
1409 icon_theme = gtk_icon_theme_get_for_screen (screen);
1410 settings = gtk_settings_get_for_screen (screen);
1411 flags = GTK_ICON_LOOKUP_USE_BUILTIN;
1412 if (priv->data.name.pixbuf == NULL ||
1413 (priv->was_symbolic && priv->last_rendered_state != state))
1415 priv->last_rendered_state = state;
1416 if (priv->data.name.pixbuf)
1418 g_object_unref (priv->data.name.pixbuf);
1419 priv->data.name.pixbuf = NULL;
1421 if (priv->pixel_size != -1)
1423 width = height = priv->pixel_size;
1424 flags |= GTK_ICON_LOOKUP_FORCE_SIZE;
1426 else if (!gtk_icon_size_lookup_for_settings (settings,
1430 if (priv->icon_size == -1)
1432 /* Find an available size close to 48 */
1433 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, priv->data.name.icon_name);
1435 width = height = 48;
1436 for (s = sizes; *s; s++)
1440 width = height = 48;
1447 width = height = *s;
1455 width = height = *s;
1464 g_warning ("Invalid icon size %d\n", priv->icon_size);
1465 width = height = 24;
1469 info = gtk_icon_theme_lookup_icon (icon_theme,
1470 priv->data.name.icon_name,
1471 MIN (width, height), flags);
1474 GtkStyleContext *context;
1475 gboolean was_symbolic;
1477 context = gtk_widget_get_style_context (GTK_WIDGET (image));
1478 priv->data.name.pixbuf =
1479 gtk_icon_info_load_symbolic_for_context (info,
1483 priv->was_symbolic = was_symbolic;
1484 gtk_icon_info_free (info);
1487 if (priv->data.name.pixbuf == NULL)
1489 priv->data.name.pixbuf =
1490 gtk_widget_render_icon_pixbuf (GTK_WIDGET (image),
1491 GTK_STOCK_MISSING_IMAGE,
1493 priv->was_symbolic = FALSE;
1499 ensure_pixbuf_for_gicon (GtkImage *image,
1502 GtkImagePrivate *priv = image->priv;
1504 GtkIconTheme *icon_theme;
1505 GtkSettings *settings;
1508 GtkIconLookupFlags flags;
1510 g_return_if_fail (priv->storage_type == GTK_IMAGE_GICON);
1512 screen = gtk_widget_get_screen (GTK_WIDGET (image));
1513 icon_theme = gtk_icon_theme_get_for_screen (screen);
1514 settings = gtk_settings_get_for_screen (screen);
1515 flags = GTK_ICON_LOOKUP_USE_BUILTIN;
1516 if (priv->data.gicon.pixbuf == NULL ||
1517 (priv->was_symbolic && priv->last_rendered_state != state))
1519 priv->last_rendered_state = state;
1520 if (priv->data.gicon.pixbuf)
1522 g_object_unref (priv->data.gicon.pixbuf);
1523 priv->data.gicon.pixbuf = NULL;
1525 if (priv->pixel_size != -1)
1527 width = height = priv->pixel_size;
1528 flags |= GTK_ICON_LOOKUP_FORCE_SIZE;
1530 else if (!gtk_icon_size_lookup_for_settings (settings,
1534 if (priv->icon_size == -1)
1535 width = height = 48;
1538 g_warning ("Invalid icon size %d\n", priv->icon_size);
1539 width = height = 24;
1543 info = gtk_icon_theme_lookup_by_gicon (icon_theme,
1544 priv->data.gicon.icon,
1545 MIN (width, height), flags);
1548 GtkStyleContext *context;
1549 gboolean was_symbolic;
1551 context = gtk_widget_get_style_context (GTK_WIDGET (image));
1552 priv->data.gicon.pixbuf =
1553 gtk_icon_info_load_symbolic_for_context (info,
1557 priv->was_symbolic = was_symbolic;
1558 gtk_icon_info_free (info);
1561 if (priv->data.gicon.pixbuf == NULL)
1563 priv->data.gicon.pixbuf =
1564 gtk_widget_render_icon_pixbuf (GTK_WIDGET (image),
1565 GTK_STOCK_MISSING_IMAGE,
1567 priv->was_symbolic = FALSE;
1573 gtk_image_draw (GtkWidget *widget,
1577 GtkImagePrivate *priv;
1579 g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
1581 image = GTK_IMAGE (widget);
1584 if (priv->storage_type != GTK_IMAGE_EMPTY)
1589 gfloat xalign, yalign;
1592 gboolean needs_state_transform;
1594 misc = GTK_MISC (widget);
1596 /* For stock items and icon sets, we lazily calculate
1597 * the size; we might get here between a queue_resize()
1598 * and size_request() if something explicitely forces
1601 if (priv->need_calc_size)
1602 gtk_image_calc_size (image);
1604 gtk_misc_get_alignment (misc, &xalign, &yalign);
1605 gtk_misc_get_padding (misc, &xpad, &ypad);
1607 if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
1608 xalign = 1.0 - xalign;
1610 x = floor (xpad + ((gtk_widget_get_allocated_width (widget) - priv->required_width) * xalign));
1611 y = floor (ypad + ((gtk_widget_get_allocated_height (widget) - priv->required_height) * yalign));
1613 needs_state_transform = gtk_widget_get_state (widget) != GTK_STATE_NORMAL;
1615 switch (priv->storage_type)
1618 case GTK_IMAGE_PIXBUF:
1619 pixbuf = priv->data.pixbuf.pixbuf;
1620 g_object_ref (pixbuf);
1623 case GTK_IMAGE_STOCK:
1624 pixbuf = gtk_widget_render_icon_pixbuf (widget,
1625 priv->data.stock.stock_id,
1629 needs_state_transform = FALSE;
1632 case GTK_IMAGE_ICON_SET:
1634 gtk_icon_set_render_icon (priv->data.icon_set.icon_set,
1635 gtk_widget_get_style (widget),
1636 gtk_widget_get_direction (widget),
1637 gtk_widget_get_state (widget),
1643 needs_state_transform = FALSE;
1646 case GTK_IMAGE_ANIMATION:
1648 if (priv->data.anim.iter == NULL)
1650 priv->data.anim.iter = gdk_pixbuf_animation_get_iter (priv->data.anim.anim, NULL);
1652 if (gdk_pixbuf_animation_iter_get_delay_time (priv->data.anim.iter) >= 0)
1653 priv->data.anim.frame_timeout =
1654 gdk_threads_add_timeout (gdk_pixbuf_animation_iter_get_delay_time (priv->data.anim.iter),
1659 /* don't advance the anim iter here, or we could get frame changes between two
1660 * exposes of different areas.
1663 pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (priv->data.anim.iter);
1664 g_object_ref (pixbuf);
1668 case GTK_IMAGE_ICON_NAME:
1669 state = gtk_widget_get_state (widget);
1670 if (state == GTK_STATE_INSENSITIVE)
1672 ensure_pixbuf_for_icon_name (image, GTK_STATE_NORMAL);
1676 ensure_pixbuf_for_icon_name (image, state);
1677 /* Already done by the loading function? */
1678 if (priv->was_symbolic)
1679 needs_state_transform = FALSE;
1681 pixbuf = priv->data.name.pixbuf;
1684 g_object_ref (pixbuf);
1688 case GTK_IMAGE_GICON:
1689 state = gtk_widget_get_state (widget);
1690 if (state == GTK_STATE_INSENSITIVE)
1692 ensure_pixbuf_for_gicon (image, GTK_STATE_NORMAL);
1696 ensure_pixbuf_for_gicon (image, state);
1697 /* Already done by the loading function? */
1698 if (priv->was_symbolic)
1699 needs_state_transform = FALSE;
1701 pixbuf = priv->data.gicon.pixbuf;
1704 g_object_ref (pixbuf);
1708 case GTK_IMAGE_EMPTY:
1710 g_assert_not_reached ();
1717 if (needs_state_transform)
1719 GtkIconSource *source;
1720 GdkPixbuf *rendered;
1722 source = gtk_icon_source_new ();
1723 gtk_icon_source_set_pixbuf (source, pixbuf);
1724 /* The size here is arbitrary; since size isn't
1725 * wildcarded in the souce, it isn't supposed to be
1726 * scaled by the engine function
1728 gtk_icon_source_set_size (source,
1729 GTK_ICON_SIZE_SMALL_TOOLBAR);
1730 gtk_icon_source_set_size_wildcarded (source, FALSE);
1732 rendered = gtk_style_render_icon (gtk_widget_get_style (widget),
1734 gtk_widget_get_direction (widget),
1735 gtk_widget_get_state (widget),
1741 gtk_icon_source_free (source);
1743 g_object_unref (pixbuf);
1747 gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
1750 g_object_unref (pixbuf);
1758 gtk_image_reset (GtkImage *image)
1760 GtkImagePrivate *priv = image->priv;
1762 g_object_freeze_notify (G_OBJECT (image));
1764 if (priv->storage_type != GTK_IMAGE_EMPTY)
1765 g_object_notify (G_OBJECT (image), "storage-type");
1767 if (priv->icon_size != DEFAULT_ICON_SIZE)
1769 priv->icon_size = DEFAULT_ICON_SIZE;
1770 g_object_notify (G_OBJECT (image), "icon-size");
1773 switch (priv->storage_type)
1776 case GTK_IMAGE_PIXBUF:
1778 if (priv->data.pixbuf.pixbuf)
1779 g_object_unref (priv->data.pixbuf.pixbuf);
1781 g_object_notify (G_OBJECT (image), "pixbuf");
1785 case GTK_IMAGE_STOCK:
1787 g_free (priv->data.stock.stock_id);
1789 priv->data.stock.stock_id = NULL;
1791 g_object_notify (G_OBJECT (image), "stock");
1794 case GTK_IMAGE_ICON_SET:
1795 if (priv->data.icon_set.icon_set)
1796 gtk_icon_set_unref (priv->data.icon_set.icon_set);
1797 priv->data.icon_set.icon_set = NULL;
1799 g_object_notify (G_OBJECT (image), "icon-set");
1802 case GTK_IMAGE_ANIMATION:
1803 gtk_image_reset_anim_iter (image);
1805 if (priv->data.anim.anim)
1806 g_object_unref (priv->data.anim.anim);
1807 priv->data.anim.anim = NULL;
1809 g_object_notify (G_OBJECT (image), "pixbuf-animation");
1813 case GTK_IMAGE_ICON_NAME:
1814 g_free (priv->data.name.icon_name);
1815 priv->data.name.icon_name = NULL;
1816 if (priv->data.name.pixbuf)
1817 g_object_unref (priv->data.name.pixbuf);
1818 priv->data.name.pixbuf = NULL;
1820 g_object_notify (G_OBJECT (image), "icon-name");
1824 case GTK_IMAGE_GICON:
1825 if (priv->data.gicon.icon)
1826 g_object_unref (priv->data.gicon.icon);
1827 priv->data.gicon.icon = NULL;
1828 if (priv->data.gicon.pixbuf)
1829 g_object_unref (priv->data.gicon.pixbuf);
1830 priv->data.gicon.pixbuf = NULL;
1832 g_object_notify (G_OBJECT (image), "gicon");
1836 case GTK_IMAGE_EMPTY:
1844 g_free (priv->filename);
1845 priv->filename = NULL;
1846 g_object_notify (G_OBJECT (image), "file");
1849 priv->storage_type = GTK_IMAGE_EMPTY;
1851 memset (&priv->data, '\0', sizeof (priv->data));
1853 g_object_thaw_notify (G_OBJECT (image));
1858 * @image: a #GtkImage
1860 * Resets the image to be empty.
1865 gtk_image_clear (GtkImage *image)
1867 GtkImagePrivate *priv = image->priv;
1869 priv->need_calc_size = 1;
1871 gtk_image_reset (image);
1872 gtk_image_update_size (image, 0, 0);
1876 gtk_image_calc_size (GtkImage *image)
1878 GtkWidget *widget = GTK_WIDGET (image);
1879 GtkImagePrivate *priv = image->priv;
1880 GdkPixbuf *pixbuf = NULL;
1882 priv->need_calc_size = 0;
1884 /* We update stock/icon set on every size request, because
1885 * the theme could have affected the size; for other kinds of
1886 * image, we just update the required width/height when the image data
1889 switch (priv->storage_type)
1891 case GTK_IMAGE_STOCK:
1892 pixbuf = gtk_widget_render_icon_pixbuf (widget,
1893 priv->data.stock.stock_id,
1897 case GTK_IMAGE_ICON_SET:
1898 pixbuf = gtk_icon_set_render_icon (priv->data.icon_set.icon_set,
1899 gtk_widget_get_style (widget),
1900 gtk_widget_get_direction (widget),
1901 gtk_widget_get_state (widget),
1906 case GTK_IMAGE_ICON_NAME:
1907 ensure_pixbuf_for_icon_name (image, GTK_STATE_NORMAL);
1908 pixbuf = priv->data.name.pixbuf;
1909 if (pixbuf) g_object_ref (pixbuf);
1911 case GTK_IMAGE_GICON:
1912 ensure_pixbuf_for_gicon (image, GTK_STATE_NORMAL);
1913 pixbuf = priv->data.gicon.pixbuf;
1915 g_object_ref (pixbuf);
1925 gtk_misc_get_padding (GTK_MISC (image), &xpad, &ypad);
1927 priv->required_width = gdk_pixbuf_get_width (pixbuf) + xpad * 2;
1928 priv->required_height = gdk_pixbuf_get_height (pixbuf) + ypad * 2;
1930 g_object_unref (pixbuf);
1935 gtk_image_get_preferred_width (GtkWidget *widget,
1940 GtkImagePrivate *priv;
1942 image = GTK_IMAGE (widget);
1945 gtk_image_calc_size (image);
1947 *minimum = *natural = priv->required_width;
1951 gtk_image_get_preferred_height (GtkWidget *widget,
1956 GtkImagePrivate *priv;
1958 image = GTK_IMAGE (widget);
1961 gtk_image_calc_size (image);
1963 *minimum = *natural = priv->required_height;
1967 gtk_image_style_set (GtkWidget *widget,
1968 GtkStyle *prev_style)
1972 image = GTK_IMAGE (widget);
1974 GTK_WIDGET_CLASS (gtk_image_parent_class)->style_set (widget, prev_style);
1976 icon_theme_changed (image);
1980 gtk_image_screen_changed (GtkWidget *widget,
1981 GdkScreen *prev_screen)
1985 image = GTK_IMAGE (widget);
1987 if (GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed)
1988 GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed (widget, prev_screen);
1990 icon_theme_changed (image);
1995 gtk_image_update_size (GtkImage *image,
1999 GtkWidget *widget = GTK_WIDGET (image);
2000 GtkImagePrivate *priv = image->priv;
2003 gtk_misc_get_padding (GTK_MISC (image), &xpad, &ypad);
2005 priv->required_width = image_width + xpad * 2;
2006 priv->required_height = image_height + ypad * 2;
2008 if (gtk_widget_get_visible (widget))
2009 gtk_widget_queue_resize (widget);
2014 * gtk_image_set_pixel_size:
2015 * @image: a #GtkImage
2016 * @pixel_size: the new pixel size
2018 * Sets the pixel size to use for named icons. If the pixel size is set
2019 * to a value != -1, it is used instead of the icon size set by
2020 * gtk_image_set_from_icon_name().
2025 gtk_image_set_pixel_size (GtkImage *image,
2028 GtkImagePrivate *priv;
2030 g_return_if_fail (GTK_IS_IMAGE (image));
2034 if (priv->pixel_size != pixel_size)
2036 priv->pixel_size = pixel_size;
2038 if (priv->storage_type == GTK_IMAGE_ICON_NAME)
2040 if (priv->data.name.pixbuf)
2042 g_object_unref (priv->data.name.pixbuf);
2043 priv->data.name.pixbuf = NULL;
2046 gtk_image_update_size (image, pixel_size, pixel_size);
2049 if (priv->storage_type == GTK_IMAGE_GICON)
2051 if (priv->data.gicon.pixbuf)
2053 g_object_unref (priv->data.gicon.pixbuf);
2054 priv->data.gicon.pixbuf = NULL;
2057 gtk_image_update_size (image, pixel_size, pixel_size);
2060 g_object_notify (G_OBJECT (image), "pixel-size");
2065 * gtk_image_get_pixel_size:
2066 * @image: a #GtkImage
2068 * Gets the pixel size used for named icons.
2070 * Returns: the pixel size used for named icons.
2075 gtk_image_get_pixel_size (GtkImage *image)
2077 g_return_val_if_fail (GTK_IS_IMAGE (image), -1);
2079 return image->priv->pixel_size;