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"
33 #include "gtkimageprivate.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 gchar *filename; /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
149 gint last_rendered_state; /* a GtkStateFlags, with -1 meaning an invalid state,
150 * only used with GTK_IMAGE_GICON, GTK_IMAGE_ICON_NAME */
153 gint required_height;
154 guint need_calc_size : 1;
155 guint use_fallback : 1;
156 guint was_symbolic : 1;
160 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
161 static gint gtk_image_draw (GtkWidget *widget,
163 static void gtk_image_unmap (GtkWidget *widget);
164 static void gtk_image_unrealize (GtkWidget *widget);
165 static void gtk_image_get_preferred_width (GtkWidget *widget,
168 static void gtk_image_get_preferred_height (GtkWidget *widget,
172 static void gtk_image_style_updated (GtkWidget *widget);
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,
210 G_DEFINE_TYPE (GtkImage, gtk_image, GTK_TYPE_MISC)
213 gtk_image_class_init (GtkImageClass *class)
215 GObjectClass *gobject_class;
216 GtkWidgetClass *widget_class;
218 gobject_class = G_OBJECT_CLASS (class);
220 gobject_class->set_property = gtk_image_set_property;
221 gobject_class->get_property = gtk_image_get_property;
223 widget_class = GTK_WIDGET_CLASS (class);
224 widget_class->draw = gtk_image_draw;
225 widget_class->destroy = gtk_image_destroy;
226 widget_class->get_preferred_width = gtk_image_get_preferred_width;
227 widget_class->get_preferred_height = gtk_image_get_preferred_height;
228 widget_class->unmap = gtk_image_unmap;
229 widget_class->unrealize = gtk_image_unrealize;
230 widget_class->style_updated = gtk_image_style_updated;
231 widget_class->screen_changed = gtk_image_screen_changed;
233 g_object_class_install_property (gobject_class,
235 g_param_spec_object ("pixbuf",
237 P_("A GdkPixbuf to display"),
239 GTK_PARAM_READWRITE));
241 g_object_class_install_property (gobject_class,
243 g_param_spec_string ("file",
245 P_("Filename to load and display"),
247 GTK_PARAM_READWRITE));
250 g_object_class_install_property (gobject_class,
252 g_param_spec_string ("stock",
254 P_("Stock ID for a stock image to display"),
256 GTK_PARAM_READWRITE));
258 g_object_class_install_property (gobject_class,
260 g_param_spec_boxed ("icon-set",
262 P_("Icon set to display"),
264 GTK_PARAM_READWRITE));
266 g_object_class_install_property (gobject_class,
268 g_param_spec_int ("icon-size",
270 P_("Symbolic size to use for stock icon, icon set or named icon"),
273 GTK_PARAM_READWRITE));
275 * GtkImage:pixel-size:
277 * The "pixel-size" property can be used to specify a fixed size
278 * overriding the #GtkImage:icon-size property for images of type
279 * %GTK_IMAGE_ICON_NAME.
283 g_object_class_install_property (gobject_class,
285 g_param_spec_int ("pixel-size",
287 P_("Pixel size to use for named icon"),
290 GTK_PARAM_READWRITE));
292 g_object_class_install_property (gobject_class,
293 PROP_PIXBUF_ANIMATION,
294 g_param_spec_object ("pixbuf-animation",
296 P_("GdkPixbufAnimation to display"),
297 GDK_TYPE_PIXBUF_ANIMATION,
298 GTK_PARAM_READWRITE));
301 * GtkImage:icon-name:
303 * The name of the icon in the icon theme. If the icon theme is
304 * changed, the image will be updated automatically.
308 g_object_class_install_property (gobject_class,
310 g_param_spec_string ("icon-name",
312 P_("The name of the icon from the icon theme"),
314 GTK_PARAM_READWRITE));
319 * The GIcon displayed in the GtkImage. For themed icons,
320 * If the icon theme is changed, the image will be updated
325 g_object_class_install_property (gobject_class,
327 g_param_spec_object ("gicon",
329 P_("The GIcon being displayed"),
331 GTK_PARAM_READWRITE));
333 g_object_class_install_property (gobject_class,
335 g_param_spec_enum ("storage-type",
337 P_("The representation being used for image data"),
340 GTK_PARAM_READABLE));
343 * GtkImage:use-fallback:
345 * Whether the icon displayed in the GtkImage will use
346 * standard icon names fallback. The value of this property
347 * is only relevant for images of type %GTK_IMAGE_ICON_NAME
348 * and %GTK_IMAGE_GICON.
352 g_object_class_install_property (gobject_class,
354 g_param_spec_boolean ("use-fallback",
356 P_("Whether to use icon names fallback"),
358 GTK_PARAM_READWRITE));
360 g_type_class_add_private (class, sizeof (GtkImagePrivate));
364 gtk_image_init (GtkImage *image)
366 GtkImagePrivate *priv;
368 image->priv = G_TYPE_INSTANCE_GET_PRIVATE (image,
373 gtk_widget_set_has_window (GTK_WIDGET (image), FALSE);
375 priv->storage_type = GTK_IMAGE_EMPTY;
376 priv->icon_size = DEFAULT_ICON_SIZE;
378 priv->pixel_size = -1;
380 priv->filename = NULL;
384 gtk_image_destroy (GtkWidget *widget)
386 GtkImage *image = GTK_IMAGE (widget);
388 gtk_image_reset (image);
390 GTK_WIDGET_CLASS (gtk_image_parent_class)->destroy (widget);
394 gtk_image_set_property (GObject *object,
399 GtkImage *image = GTK_IMAGE (object);
400 GtkImagePrivate *priv = image->priv;
405 gtk_image_set_from_pixbuf (image,
406 g_value_get_object (value));
409 gtk_image_set_from_file (image, g_value_get_string (value));
412 gtk_image_set_from_stock (image, g_value_get_string (value),
416 gtk_image_set_from_icon_set (image, g_value_get_boxed (value),
420 if (priv->storage_type == GTK_IMAGE_STOCK)
421 gtk_image_set_from_stock (image,
422 priv->data.stock.stock_id,
423 g_value_get_int (value));
424 else if (priv->storage_type == GTK_IMAGE_ICON_SET)
425 gtk_image_set_from_icon_set (image,
426 priv->data.icon_set.icon_set,
427 g_value_get_int (value));
428 else if (priv->storage_type == GTK_IMAGE_ICON_NAME)
429 gtk_image_set_from_icon_name (image,
430 priv->data.name.icon_name,
431 g_value_get_int (value));
432 else if (priv->storage_type == GTK_IMAGE_GICON)
433 gtk_image_set_from_gicon (image,
434 priv->data.gicon.icon,
435 g_value_get_int (value));
437 /* Save to be used when STOCK, ICON_SET, ICON_NAME or GICON property comes in */
438 priv->icon_size = g_value_get_int (value);
440 case PROP_PIXEL_SIZE:
441 gtk_image_set_pixel_size (image, g_value_get_int (value));
443 case PROP_PIXBUF_ANIMATION:
444 gtk_image_set_from_animation (image,
445 g_value_get_object (value));
448 gtk_image_set_from_icon_name (image, g_value_get_string (value),
452 gtk_image_set_from_gicon (image, g_value_get_object (value),
456 case PROP_USE_FALLBACK:
457 priv->use_fallback = g_value_get_boolean (value);
458 if (priv->storage_type == GTK_IMAGE_ICON_NAME)
459 gtk_image_set_from_icon_name (image,
460 priv->data.name.icon_name,
462 else if (priv->storage_type == GTK_IMAGE_GICON)
463 gtk_image_set_from_gicon (image,
464 priv->data.gicon.icon,
469 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
475 gtk_image_get_property (GObject *object,
480 GtkImage *image = GTK_IMAGE (object);
481 GtkImagePrivate *priv = image->priv;
483 /* The "getter" functions whine if you try to get the wrong
484 * storage type. This function is instead robust against that,
485 * so that GUI builders don't have to jump through hoops
492 if (priv->storage_type != GTK_IMAGE_PIXBUF)
493 g_value_set_object (value, NULL);
495 g_value_set_object (value,
496 gtk_image_get_pixbuf (image));
499 g_value_set_string (value, priv->filename);
502 if (priv->storage_type != GTK_IMAGE_STOCK)
503 g_value_set_string (value, NULL);
505 g_value_set_string (value,
506 priv->data.stock.stock_id);
509 if (priv->storage_type != GTK_IMAGE_ICON_SET)
510 g_value_set_boxed (value, NULL);
512 g_value_set_boxed (value,
513 priv->data.icon_set.icon_set);
516 g_value_set_int (value, priv->icon_size);
518 case PROP_PIXEL_SIZE:
519 g_value_set_int (value, priv->pixel_size);
521 case PROP_PIXBUF_ANIMATION:
522 if (priv->storage_type != GTK_IMAGE_ANIMATION)
523 g_value_set_object (value, NULL);
525 g_value_set_object (value,
526 priv->data.anim.anim);
529 if (priv->storage_type != GTK_IMAGE_ICON_NAME)
530 g_value_set_string (value, NULL);
532 g_value_set_string (value,
533 priv->data.name.icon_name);
536 if (priv->storage_type != GTK_IMAGE_GICON)
537 g_value_set_object (value, NULL);
539 g_value_set_object (value,
540 priv->data.gicon.icon);
542 case PROP_STORAGE_TYPE:
543 g_value_set_enum (value, priv->storage_type);
546 case PROP_USE_FALLBACK:
547 g_value_set_boolean (value, priv->use_fallback);
551 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
558 * gtk_image_new_from_file:
559 * @filename: (type filename): a filename
561 * Creates a new #GtkImage displaying the file @filename. If the file
562 * isn't found or can't be loaded, the resulting #GtkImage will
563 * display a "broken image" icon. This function never returns %NULL,
564 * it always returns a valid #GtkImage widget.
566 * If the file contains an animation, the image will contain an
569 * If you need to detect failures to load the file, use
570 * gdk_pixbuf_new_from_file() to load the file yourself, then create
571 * the #GtkImage from the pixbuf. (Or for animations, use
572 * gdk_pixbuf_animation_new_from_file()).
574 * The storage type (gtk_image_get_storage_type()) of the returned
575 * image is not defined, it will be whatever is appropriate for
576 * displaying the file.
578 * Return value: a new #GtkImage
581 gtk_image_new_from_file (const gchar *filename)
585 image = g_object_new (GTK_TYPE_IMAGE, NULL);
587 gtk_image_set_from_file (image, filename);
589 return GTK_WIDGET (image);
593 * gtk_image_new_from_pixbuf:
594 * @pixbuf: (allow-none): a #GdkPixbuf, or %NULL
596 * Creates a new #GtkImage displaying @pixbuf.
597 * The #GtkImage does not assume a reference to the
598 * pixbuf; you still need to unref it if you own references.
599 * #GtkImage will add its own reference rather than adopting yours.
601 * Note that this function just creates an #GtkImage from the pixbuf. The
602 * #GtkImage created will not react to state changes. Should you want that,
603 * you should use gtk_image_new_from_icon_set().
605 * Return value: a new #GtkImage
608 gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
612 image = g_object_new (GTK_TYPE_IMAGE, NULL);
614 gtk_image_set_from_pixbuf (image, pixbuf);
616 return GTK_WIDGET (image);
620 * gtk_image_new_from_stock:
621 * @stock_id: a stock icon name
622 * @size: (type int): a stock icon size
624 * Creates a #GtkImage displaying a stock icon. Sample stock icon
625 * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. Sample stock sizes
626 * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
627 * icon name isn't known, the image will be empty.
628 * You can register your own stock icon names, see
629 * gtk_icon_factory_add_default() and gtk_icon_factory_add().
631 * Return value: a new #GtkImage displaying the stock icon
634 gtk_image_new_from_stock (const gchar *stock_id,
639 image = g_object_new (GTK_TYPE_IMAGE, NULL);
641 gtk_image_set_from_stock (image, stock_id, size);
643 return GTK_WIDGET (image);
647 * gtk_image_new_from_icon_set:
648 * @icon_set: a #GtkIconSet
649 * @size: (type int): a stock icon size
651 * Creates a #GtkImage displaying an icon set. Sample stock sizes are
652 * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. Instead of using
653 * this function, usually it's better to create a #GtkIconFactory, put
654 * your icon sets in the icon factory, add the icon factory to the
655 * list of default factories with gtk_icon_factory_add_default(), and
656 * then use gtk_image_new_from_stock(). This will allow themes to
657 * override the icon you ship with your application.
659 * The #GtkImage does not assume a reference to the
660 * icon set; you still need to unref it if you own references.
661 * #GtkImage will add its own reference rather than adopting yours.
663 * Return value: a new #GtkImage
666 gtk_image_new_from_icon_set (GtkIconSet *icon_set,
671 image = g_object_new (GTK_TYPE_IMAGE, NULL);
673 gtk_image_set_from_icon_set (image, icon_set, size);
675 return GTK_WIDGET (image);
679 * gtk_image_new_from_animation:
680 * @animation: an animation
682 * Creates a #GtkImage displaying the given animation.
683 * The #GtkImage does not assume a reference to the
684 * animation; you still need to unref it if you own references.
685 * #GtkImage will add its own reference rather than adopting yours.
687 * Note that the animation frames are shown using a timeout with
688 * #G_PRIORITY_DEFAULT. When using animations to indicate busyness,
689 * keep in mind that the animation will only be shown if the main loop
690 * is not busy with something that has a higher priority.
692 * Return value: a new #GtkImage widget
695 gtk_image_new_from_animation (GdkPixbufAnimation *animation)
699 g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
701 image = g_object_new (GTK_TYPE_IMAGE, NULL);
703 gtk_image_set_from_animation (image, animation);
705 return GTK_WIDGET (image);
709 * gtk_image_new_from_icon_name:
710 * @icon_name: an icon name
711 * @size: (type int): a stock icon size
713 * Creates a #GtkImage displaying an icon from the current icon theme.
714 * If the icon name isn't known, a "broken image" icon will be
715 * displayed instead. If the current icon theme is changed, the icon
716 * will be updated appropriately.
718 * Return value: a new #GtkImage displaying the themed icon
723 gtk_image_new_from_icon_name (const gchar *icon_name,
728 image = g_object_new (GTK_TYPE_IMAGE, NULL);
730 gtk_image_set_from_icon_name (image, icon_name, size);
732 return GTK_WIDGET (image);
736 * gtk_image_new_from_gicon:
738 * @size: (type int): a stock icon size
740 * Creates a #GtkImage displaying an icon from the current icon theme.
741 * If the icon name isn't known, a "broken image" icon will be
742 * displayed instead. If the current icon theme is changed, the icon
743 * will be updated appropriately.
745 * Return value: a new #GtkImage displaying the themed icon
750 gtk_image_new_from_gicon (GIcon *icon,
755 image = g_object_new (GTK_TYPE_IMAGE, NULL);
757 gtk_image_set_from_gicon (image, icon, size);
759 return GTK_WIDGET (image);
763 * gtk_image_set_from_file:
764 * @image: a #GtkImage
765 * @filename: (type filename) (allow-none): a filename or %NULL
767 * See gtk_image_new_from_file() for details.
770 gtk_image_set_from_file (GtkImage *image,
771 const gchar *filename)
773 GtkImagePrivate *priv;
774 GdkPixbufAnimation *anim;
776 g_return_if_fail (GTK_IS_IMAGE (image));
780 g_object_freeze_notify (G_OBJECT (image));
782 gtk_image_clear (image);
784 if (filename == NULL)
786 priv->filename = NULL;
787 g_object_thaw_notify (G_OBJECT (image));
791 anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
795 gtk_image_set_from_stock (image,
796 GTK_STOCK_MISSING_IMAGE,
797 GTK_ICON_SIZE_BUTTON);
798 g_object_thaw_notify (G_OBJECT (image));
802 /* We could just unconditionally set_from_animation,
803 * but it's nicer for memory if we toss the animation
804 * if it's just a single pixbuf
807 if (gdk_pixbuf_animation_is_static_image (anim))
808 gtk_image_set_from_pixbuf (image,
809 gdk_pixbuf_animation_get_static_image (anim));
811 gtk_image_set_from_animation (image, anim);
813 g_object_unref (anim);
815 priv->filename = g_strdup (filename);
817 g_object_thaw_notify (G_OBJECT (image));
821 * gtk_image_set_from_pixbuf:
822 * @image: a #GtkImage
823 * @pixbuf: (allow-none): a #GdkPixbuf or %NULL
825 * See gtk_image_new_from_pixbuf() for details.
828 gtk_image_set_from_pixbuf (GtkImage *image,
831 GtkImagePrivate *priv;
833 g_return_if_fail (GTK_IS_IMAGE (image));
834 g_return_if_fail (pixbuf == NULL ||
835 GDK_IS_PIXBUF (pixbuf));
839 g_object_freeze_notify (G_OBJECT (image));
842 g_object_ref (pixbuf);
844 gtk_image_clear (image);
848 priv->storage_type = GTK_IMAGE_PIXBUF;
850 priv->data.pixbuf.pixbuf = pixbuf;
852 gtk_image_update_size (image,
853 gdk_pixbuf_get_width (pixbuf),
854 gdk_pixbuf_get_height (pixbuf));
857 g_object_notify (G_OBJECT (image), "pixbuf");
859 g_object_thaw_notify (G_OBJECT (image));
863 * gtk_image_set_from_stock:
864 * @image: a #GtkImage
865 * @stock_id: a stock icon name
866 * @size: (type int): a stock icon size
868 * See gtk_image_new_from_stock() for details.
871 gtk_image_set_from_stock (GtkImage *image,
872 const gchar *stock_id,
875 GtkImagePrivate *priv;
878 g_return_if_fail (GTK_IS_IMAGE (image));
882 g_object_freeze_notify (G_OBJECT (image));
884 /* in case stock_id == priv->data.stock.stock_id */
885 new_id = g_strdup (stock_id);
887 gtk_image_clear (image);
891 priv->storage_type = GTK_IMAGE_STOCK;
893 priv->data.stock.stock_id = new_id;
894 priv->icon_size = size;
896 /* Size is demand-computed in size request method
897 * if we're a stock image, since changing the
898 * style impacts the size request
902 g_object_notify (G_OBJECT (image), "stock");
903 g_object_notify (G_OBJECT (image), "icon-size");
905 g_object_thaw_notify (G_OBJECT (image));
909 * gtk_image_set_from_icon_set:
910 * @image: a #GtkImage
911 * @icon_set: a #GtkIconSet
912 * @size: (type int): a stock icon size
914 * See gtk_image_new_from_icon_set() for details.
917 gtk_image_set_from_icon_set (GtkImage *image,
918 GtkIconSet *icon_set,
921 GtkImagePrivate *priv;
923 g_return_if_fail (GTK_IS_IMAGE (image));
927 g_object_freeze_notify (G_OBJECT (image));
930 gtk_icon_set_ref (icon_set);
932 gtk_image_clear (image);
936 priv->storage_type = GTK_IMAGE_ICON_SET;
938 priv->data.icon_set.icon_set = icon_set;
939 priv->icon_size = size;
941 /* Size is demand-computed in size request method
942 * if we're an icon set
946 g_object_notify (G_OBJECT (image), "icon-set");
947 g_object_notify (G_OBJECT (image), "icon-size");
949 g_object_thaw_notify (G_OBJECT (image));
953 * gtk_image_set_from_animation:
954 * @image: a #GtkImage
955 * @animation: the #GdkPixbufAnimation
957 * Causes the #GtkImage to display the given animation (or display
958 * nothing, if you set the animation to %NULL).
961 gtk_image_set_from_animation (GtkImage *image,
962 GdkPixbufAnimation *animation)
964 GtkImagePrivate *priv;
966 g_return_if_fail (GTK_IS_IMAGE (image));
967 g_return_if_fail (animation == NULL ||
968 GDK_IS_PIXBUF_ANIMATION (animation));
972 g_object_freeze_notify (G_OBJECT (image));
975 g_object_ref (animation);
977 gtk_image_clear (image);
979 if (animation != NULL)
981 priv->storage_type = GTK_IMAGE_ANIMATION;
983 priv->data.anim.anim = animation;
984 priv->data.anim.frame_timeout = 0;
985 priv->data.anim.iter = NULL;
987 gtk_image_update_size (image,
988 gdk_pixbuf_animation_get_width (animation),
989 gdk_pixbuf_animation_get_height (animation));
992 g_object_notify (G_OBJECT (image), "pixbuf-animation");
994 g_object_thaw_notify (G_OBJECT (image));
998 * gtk_image_set_from_icon_name:
999 * @image: a #GtkImage
1000 * @icon_name: an icon name
1001 * @size: (type int): an icon size
1003 * See gtk_image_new_from_icon_name() for details.
1008 gtk_image_set_from_icon_name (GtkImage *image,
1009 const gchar *icon_name,
1013 GtkImagePrivate *priv;
1015 g_return_if_fail (GTK_IS_IMAGE (image));
1019 g_object_freeze_notify (G_OBJECT (image));
1021 /* in case icon_name == priv->data.name.icon_name */
1022 new_name = g_strdup (icon_name);
1024 gtk_image_clear (image);
1028 priv->storage_type = GTK_IMAGE_ICON_NAME;
1030 priv->data.name.icon_name = new_name;
1031 priv->icon_size = size;
1033 /* Size is demand-computed in size request method
1034 * if we're a icon theme image, since changing the
1035 * style impacts the size request
1039 g_object_notify (G_OBJECT (image), "icon-name");
1040 g_object_notify (G_OBJECT (image), "icon-size");
1042 g_object_thaw_notify (G_OBJECT (image));
1046 * gtk_image_set_from_gicon:
1047 * @image: a #GtkImage
1049 * @size: (type int): an icon size
1051 * See gtk_image_new_from_gicon() for details.
1056 gtk_image_set_from_gicon (GtkImage *image,
1060 GtkImagePrivate *priv;
1062 g_return_if_fail (GTK_IS_IMAGE (image));
1066 g_object_freeze_notify (G_OBJECT (image));
1068 /* in case icon == priv->data.gicon.icon */
1070 g_object_ref (icon);
1072 gtk_image_clear (image);
1076 priv->storage_type = GTK_IMAGE_GICON;
1078 priv->data.gicon.icon = icon;
1079 priv->icon_size = size;
1081 /* Size is demand-computed in size request method
1082 * if we're a icon theme image, since changing the
1083 * style impacts the size request
1087 g_object_notify (G_OBJECT (image), "gicon");
1088 g_object_notify (G_OBJECT (image), "icon-size");
1090 g_object_thaw_notify (G_OBJECT (image));
1094 * gtk_image_get_storage_type:
1095 * @image: a #GtkImage
1097 * Gets the type of representation being used by the #GtkImage
1098 * to store image data. If the #GtkImage has no image data,
1099 * the return value will be %GTK_IMAGE_EMPTY.
1101 * Return value: image representation being used
1104 gtk_image_get_storage_type (GtkImage *image)
1106 g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);
1108 return image->priv->storage_type;
1112 * gtk_image_get_pixbuf:
1113 * @image: a #GtkImage
1115 * Gets the #GdkPixbuf being displayed by the #GtkImage.
1116 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1117 * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
1118 * The caller of this function does not own a reference to the
1121 * Return value: (transfer none): the displayed pixbuf, or %NULL if
1122 * the image is empty
1125 gtk_image_get_pixbuf (GtkImage *image)
1127 GtkImagePrivate *priv;
1129 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1133 g_return_val_if_fail (priv->storage_type == GTK_IMAGE_PIXBUF ||
1134 priv->storage_type == GTK_IMAGE_EMPTY, NULL);
1136 if (priv->storage_type == GTK_IMAGE_EMPTY)
1137 priv->data.pixbuf.pixbuf = NULL;
1139 return priv->data.pixbuf.pixbuf;
1143 * gtk_image_get_stock:
1144 * @image: a #GtkImage
1145 * @stock_id: (out) (transfer none) (allow-none): place to store a
1146 * stock icon name, or %NULL
1147 * @size: (out) (allow-none) (type int): place to store a stock icon
1150 * Gets the stock icon name and size being displayed by the #GtkImage.
1151 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1152 * %GTK_IMAGE_STOCK (see gtk_image_get_storage_type()).
1153 * The returned string is owned by the #GtkImage and should not
1157 gtk_image_get_stock (GtkImage *image,
1161 GtkImagePrivate *priv;
1163 g_return_if_fail (GTK_IS_IMAGE (image));
1167 g_return_if_fail (priv->storage_type == GTK_IMAGE_STOCK ||
1168 priv->storage_type == GTK_IMAGE_EMPTY);
1170 if (priv->storage_type == GTK_IMAGE_EMPTY)
1171 priv->data.stock.stock_id = NULL;
1174 *stock_id = priv->data.stock.stock_id;
1177 *size = priv->icon_size;
1181 * gtk_image_get_icon_set:
1182 * @image: a #GtkImage
1183 * @icon_set: (out) (transfer none) (allow-none): location to store a
1184 * #GtkIconSet, or %NULL
1185 * @size: (out) (allow-none) (type int): location to store a stock
1186 * icon size, or %NULL
1188 * Gets the icon set and size being displayed by the #GtkImage.
1189 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1190 * %GTK_IMAGE_ICON_SET (see gtk_image_get_storage_type()).
1193 gtk_image_get_icon_set (GtkImage *image,
1194 GtkIconSet **icon_set,
1197 GtkImagePrivate *priv;
1199 g_return_if_fail (GTK_IS_IMAGE (image));
1203 g_return_if_fail (priv->storage_type == GTK_IMAGE_ICON_SET ||
1204 priv->storage_type == GTK_IMAGE_EMPTY);
1207 *icon_set = priv->data.icon_set.icon_set;
1210 *size = priv->icon_size;
1214 * gtk_image_get_animation:
1215 * @image: a #GtkImage
1217 * Gets the #GdkPixbufAnimation being displayed by the #GtkImage.
1218 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1219 * %GTK_IMAGE_ANIMATION (see gtk_image_get_storage_type()).
1220 * The caller of this function does not own a reference to the
1221 * returned animation.
1223 * Return value: (transfer none): the displayed animation, or %NULL if
1224 * the image is empty
1227 gtk_image_get_animation (GtkImage *image)
1229 GtkImagePrivate *priv;
1231 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1235 g_return_val_if_fail (priv->storage_type == GTK_IMAGE_ANIMATION ||
1236 priv->storage_type == GTK_IMAGE_EMPTY,
1239 if (priv->storage_type == GTK_IMAGE_EMPTY)
1240 priv->data.anim.anim = NULL;
1242 return priv->data.anim.anim;
1246 * gtk_image_get_icon_name:
1247 * @image: a #GtkImage
1248 * @icon_name: (out) (transfer none) (allow-none): place to store an
1249 * icon name, or %NULL
1250 * @size: (out) (allow-none) (type int): place to store an icon size,
1253 * Gets the icon name and size being displayed by the #GtkImage.
1254 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1255 * %GTK_IMAGE_ICON_NAME (see gtk_image_get_storage_type()).
1256 * The returned string is owned by the #GtkImage and should not
1262 gtk_image_get_icon_name (GtkImage *image,
1263 G_CONST_RETURN gchar **icon_name,
1266 GtkImagePrivate *priv;
1268 g_return_if_fail (GTK_IS_IMAGE (image));
1272 g_return_if_fail (priv->storage_type == GTK_IMAGE_ICON_NAME ||
1273 priv->storage_type == GTK_IMAGE_EMPTY);
1275 if (priv->storage_type == GTK_IMAGE_EMPTY)
1276 priv->data.name.icon_name = NULL;
1279 *icon_name = priv->data.name.icon_name;
1282 *size = priv->icon_size;
1286 * gtk_image_get_gicon:
1287 * @image: a #GtkImage
1288 * @gicon: (out) (transfer none) (allow-none): place to store a
1290 * @size: (out) (allow-none) (type int): place to store an icon size,
1293 * Gets the #GIcon and size being displayed by the #GtkImage.
1294 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1295 * %GTK_IMAGE_GICON (see gtk_image_get_storage_type()).
1296 * The caller of this function does not own a reference to the
1302 gtk_image_get_gicon (GtkImage *image,
1306 GtkImagePrivate *priv;
1308 g_return_if_fail (GTK_IS_IMAGE (image));
1312 g_return_if_fail (priv->storage_type == GTK_IMAGE_GICON ||
1313 priv->storage_type == GTK_IMAGE_EMPTY);
1315 if (priv->storage_type == GTK_IMAGE_EMPTY)
1316 priv->data.gicon.icon = NULL;
1319 *gicon = priv->data.gicon.icon;
1322 *size = priv->icon_size;
1328 * Creates a new empty #GtkImage widget.
1330 * Return value: a newly created #GtkImage widget.
1333 gtk_image_new (void)
1335 return g_object_new (GTK_TYPE_IMAGE, NULL);
1339 gtk_image_reset_anim_iter (GtkImage *image)
1341 GtkImagePrivate *priv = image->priv;
1343 if (priv->storage_type == GTK_IMAGE_ANIMATION)
1345 /* Reset the animation */
1347 if (priv->data.anim.frame_timeout)
1349 g_source_remove (priv->data.anim.frame_timeout);
1350 priv->data.anim.frame_timeout = 0;
1353 if (priv->data.anim.iter)
1355 g_object_unref (priv->data.anim.iter);
1356 priv->data.anim.iter = NULL;
1362 gtk_image_unmap (GtkWidget *widget)
1364 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1366 GTK_WIDGET_CLASS (gtk_image_parent_class)->unmap (widget);
1370 gtk_image_unrealize (GtkWidget *widget)
1372 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1374 GTK_WIDGET_CLASS (gtk_image_parent_class)->unrealize (widget);
1378 animation_timeout (gpointer data)
1380 GtkImage *image = GTK_IMAGE (data);
1381 GtkImagePrivate *priv = image->priv;
1384 priv->data.anim.frame_timeout = 0;
1386 gdk_pixbuf_animation_iter_advance (priv->data.anim.iter, NULL);
1388 delay = gdk_pixbuf_animation_iter_get_delay_time (priv->data.anim.iter);
1391 GtkWidget *widget = GTK_WIDGET (image);
1393 priv->data.anim.frame_timeout =
1394 gdk_threads_add_timeout (delay, animation_timeout, image);
1396 gtk_widget_queue_draw (widget);
1398 if (gtk_widget_is_drawable (widget))
1399 gdk_window_process_updates (gtk_widget_get_window (widget), TRUE);
1406 icon_theme_changed (GtkImage *image)
1408 GtkImagePrivate *priv = image->priv;
1410 if (priv->storage_type == GTK_IMAGE_ICON_NAME)
1412 if (priv->data.name.pixbuf)
1413 g_object_unref (priv->data.name.pixbuf);
1414 priv->data.name.pixbuf = NULL;
1416 gtk_widget_queue_draw (GTK_WIDGET (image));
1418 if (priv->storage_type == GTK_IMAGE_GICON)
1420 if (priv->data.gicon.pixbuf)
1421 g_object_unref (priv->data.gicon.pixbuf);
1422 priv->data.gicon.pixbuf = NULL;
1424 gtk_widget_queue_draw (GTK_WIDGET (image));
1429 ensure_pixbuf_for_icon_name (GtkImage *image,
1430 GtkStateFlags state)
1432 GtkImagePrivate *priv = image->priv;
1434 GtkIconTheme *icon_theme;
1435 GtkSettings *settings;
1437 gint *sizes, *s, dist;
1439 GtkIconLookupFlags flags;
1441 g_return_if_fail (priv->storage_type == GTK_IMAGE_ICON_NAME);
1443 screen = gtk_widget_get_screen (GTK_WIDGET (image));
1444 icon_theme = gtk_icon_theme_get_for_screen (screen);
1445 settings = gtk_settings_get_for_screen (screen);
1446 flags = GTK_ICON_LOOKUP_USE_BUILTIN;
1447 if (priv->use_fallback)
1448 flags |= GTK_ICON_LOOKUP_GENERIC_FALLBACK;
1449 if (priv->data.name.pixbuf == NULL ||
1450 (priv->was_symbolic && priv->last_rendered_state != state))
1452 priv->last_rendered_state = state;
1453 if (priv->data.name.pixbuf)
1455 g_object_unref (priv->data.name.pixbuf);
1456 priv->data.name.pixbuf = NULL;
1458 if (priv->pixel_size != -1)
1460 width = height = priv->pixel_size;
1461 flags |= GTK_ICON_LOOKUP_FORCE_SIZE;
1463 else if (!gtk_icon_size_lookup_for_settings (settings,
1467 if (priv->icon_size == -1)
1469 /* Find an available size close to 48 */
1470 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, priv->data.name.icon_name);
1472 width = height = 48;
1473 for (s = sizes; *s; s++)
1477 width = height = 48;
1484 width = height = *s;
1492 width = height = *s;
1501 g_warning ("Invalid icon size %d\n", priv->icon_size);
1502 width = height = 24;
1506 info = gtk_icon_theme_lookup_icon (icon_theme,
1507 priv->data.name.icon_name,
1508 MIN (width, height), flags);
1511 GtkStyleContext *context;
1512 gboolean was_symbolic;
1514 context = gtk_widget_get_style_context (GTK_WIDGET (image));
1515 priv->data.name.pixbuf =
1516 gtk_icon_info_load_symbolic_for_context (info,
1520 priv->was_symbolic = was_symbolic;
1521 gtk_icon_info_free (info);
1524 if (priv->data.name.pixbuf == NULL)
1526 priv->data.name.pixbuf =
1527 gtk_widget_render_icon_pixbuf (GTK_WIDGET (image),
1528 GTK_STOCK_MISSING_IMAGE,
1530 priv->was_symbolic = FALSE;
1536 ensure_pixbuf_for_gicon (GtkImage *image,
1537 GtkStateFlags state)
1539 GtkImagePrivate *priv = image->priv;
1541 GtkIconTheme *icon_theme;
1542 GtkSettings *settings;
1545 GtkIconLookupFlags flags;
1547 g_return_if_fail (priv->storage_type == GTK_IMAGE_GICON);
1549 screen = gtk_widget_get_screen (GTK_WIDGET (image));
1550 icon_theme = gtk_icon_theme_get_for_screen (screen);
1551 settings = gtk_settings_get_for_screen (screen);
1552 flags = GTK_ICON_LOOKUP_USE_BUILTIN;
1553 if (priv->use_fallback)
1554 flags |= GTK_ICON_LOOKUP_GENERIC_FALLBACK;
1555 if (priv->data.gicon.pixbuf == NULL ||
1556 (priv->was_symbolic && priv->last_rendered_state != state))
1558 priv->last_rendered_state = state;
1559 if (priv->data.gicon.pixbuf)
1561 g_object_unref (priv->data.gicon.pixbuf);
1562 priv->data.gicon.pixbuf = NULL;
1564 if (priv->pixel_size != -1)
1566 width = height = priv->pixel_size;
1567 flags |= GTK_ICON_LOOKUP_FORCE_SIZE;
1569 else if (!gtk_icon_size_lookup_for_settings (settings,
1573 if (priv->icon_size == -1)
1574 width = height = 48;
1577 g_warning ("Invalid icon size %d\n", priv->icon_size);
1578 width = height = 24;
1582 info = gtk_icon_theme_lookup_by_gicon (icon_theme,
1583 priv->data.gicon.icon,
1584 MIN (width, height), flags);
1587 GtkStyleContext *context;
1588 gboolean was_symbolic;
1590 context = gtk_widget_get_style_context (GTK_WIDGET (image));
1591 priv->data.gicon.pixbuf =
1592 gtk_icon_info_load_symbolic_for_context (info,
1596 priv->was_symbolic = was_symbolic;
1597 gtk_icon_info_free (info);
1600 if (priv->data.gicon.pixbuf == NULL)
1602 priv->data.gicon.pixbuf =
1603 gtk_widget_render_icon_pixbuf (GTK_WIDGET (image),
1604 GTK_STOCK_MISSING_IMAGE,
1606 priv->was_symbolic = FALSE;
1612 gtk_image_draw (GtkWidget *widget,
1616 GtkImagePrivate *priv;
1618 g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
1620 image = GTK_IMAGE (widget);
1623 if (priv->storage_type != GTK_IMAGE_EMPTY)
1628 gfloat xalign, yalign;
1630 GtkStateFlags state;
1631 gboolean needs_state_transform;
1632 GtkStyleContext *context;
1634 misc = GTK_MISC (widget);
1635 context = gtk_widget_get_style_context (widget);
1636 state = gtk_widget_get_state_flags (widget);
1638 gtk_style_context_save (context);
1639 gtk_style_context_set_state (context, state);
1641 /* For stock items and icon sets, we lazily calculate
1642 * the size; we might get here between a queue_resize()
1643 * and size_request() if something explicitely forces
1646 if (priv->need_calc_size)
1647 gtk_image_calc_size (image);
1649 gtk_misc_get_alignment (misc, &xalign, &yalign);
1650 gtk_misc_get_padding (misc, &xpad, &ypad);
1652 if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
1653 xalign = 1.0 - xalign;
1655 x = floor (xpad + ((gtk_widget_get_allocated_width (widget) - priv->required_width) * xalign));
1656 y = floor (ypad + ((gtk_widget_get_allocated_height (widget) - priv->required_height) * yalign));
1658 needs_state_transform = state != 0;
1660 switch (priv->storage_type)
1663 case GTK_IMAGE_PIXBUF:
1664 pixbuf = priv->data.pixbuf.pixbuf;
1665 g_object_ref (pixbuf);
1668 case GTK_IMAGE_STOCK:
1669 pixbuf = gtk_widget_render_icon_pixbuf (widget,
1670 priv->data.stock.stock_id,
1674 needs_state_transform = FALSE;
1677 case GTK_IMAGE_ICON_SET:
1679 gtk_icon_set_render_icon_pixbuf (priv->data.icon_set.icon_set,
1680 context, priv->icon_size);
1683 needs_state_transform = FALSE;
1686 case GTK_IMAGE_ANIMATION:
1688 if (priv->data.anim.iter == NULL)
1690 priv->data.anim.iter = gdk_pixbuf_animation_get_iter (priv->data.anim.anim, NULL);
1692 if (gdk_pixbuf_animation_iter_get_delay_time (priv->data.anim.iter) >= 0)
1693 priv->data.anim.frame_timeout =
1694 gdk_threads_add_timeout (gdk_pixbuf_animation_iter_get_delay_time (priv->data.anim.iter),
1699 /* don't advance the anim iter here, or we could get frame changes between two
1700 * exposes of different areas.
1703 pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (priv->data.anim.iter);
1704 g_object_ref (pixbuf);
1708 case GTK_IMAGE_ICON_NAME:
1709 if (state & GTK_STATE_FLAG_INSENSITIVE)
1711 ensure_pixbuf_for_icon_name (image, 0);
1715 ensure_pixbuf_for_icon_name (image, state);
1716 /* Already done by the loading function? */
1717 if (priv->was_symbolic)
1718 needs_state_transform = FALSE;
1720 pixbuf = priv->data.name.pixbuf;
1723 g_object_ref (pixbuf);
1727 case GTK_IMAGE_GICON:
1728 if (state & GTK_STATE_FLAG_INSENSITIVE)
1730 ensure_pixbuf_for_gicon (image, 0);
1734 ensure_pixbuf_for_gicon (image, state);
1735 /* Already done by the loading function? */
1736 if (priv->was_symbolic)
1737 needs_state_transform = FALSE;
1739 pixbuf = priv->data.gicon.pixbuf;
1742 g_object_ref (pixbuf);
1746 case GTK_IMAGE_EMPTY:
1748 g_assert_not_reached ();
1755 if (needs_state_transform)
1757 GtkIconSource *source;
1758 GdkPixbuf *rendered;
1760 source = gtk_icon_source_new ();
1761 gtk_icon_source_set_pixbuf (source, pixbuf);
1762 /* The size here is arbitrary; since size isn't
1763 * wildcarded in the souce, it isn't supposed to be
1764 * scaled by the engine function
1766 gtk_icon_source_set_size (source,
1767 GTK_ICON_SIZE_SMALL_TOOLBAR);
1768 gtk_icon_source_set_size_wildcarded (source, FALSE);
1770 rendered = gtk_render_icon_pixbuf (context, source, (GtkIconSize) -1);
1771 gtk_icon_source_free (source);
1773 g_object_unref (pixbuf);
1777 gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
1780 g_object_unref (pixbuf);
1783 gtk_style_context_restore (context);
1790 gtk_image_reset (GtkImage *image)
1792 GtkImagePrivate *priv = image->priv;
1794 g_object_freeze_notify (G_OBJECT (image));
1796 if (priv->storage_type != GTK_IMAGE_EMPTY)
1797 g_object_notify (G_OBJECT (image), "storage-type");
1799 if (priv->icon_size != DEFAULT_ICON_SIZE)
1801 priv->icon_size = DEFAULT_ICON_SIZE;
1802 g_object_notify (G_OBJECT (image), "icon-size");
1805 switch (priv->storage_type)
1808 case GTK_IMAGE_PIXBUF:
1810 if (priv->data.pixbuf.pixbuf)
1811 g_object_unref (priv->data.pixbuf.pixbuf);
1813 g_object_notify (G_OBJECT (image), "pixbuf");
1817 case GTK_IMAGE_STOCK:
1819 g_free (priv->data.stock.stock_id);
1821 priv->data.stock.stock_id = NULL;
1823 g_object_notify (G_OBJECT (image), "stock");
1826 case GTK_IMAGE_ICON_SET:
1827 if (priv->data.icon_set.icon_set)
1828 gtk_icon_set_unref (priv->data.icon_set.icon_set);
1829 priv->data.icon_set.icon_set = NULL;
1831 g_object_notify (G_OBJECT (image), "icon-set");
1834 case GTK_IMAGE_ANIMATION:
1835 gtk_image_reset_anim_iter (image);
1837 if (priv->data.anim.anim)
1838 g_object_unref (priv->data.anim.anim);
1839 priv->data.anim.anim = NULL;
1841 g_object_notify (G_OBJECT (image), "pixbuf-animation");
1845 case GTK_IMAGE_ICON_NAME:
1846 g_free (priv->data.name.icon_name);
1847 priv->data.name.icon_name = NULL;
1848 if (priv->data.name.pixbuf)
1849 g_object_unref (priv->data.name.pixbuf);
1850 priv->data.name.pixbuf = NULL;
1852 g_object_notify (G_OBJECT (image), "icon-name");
1856 case GTK_IMAGE_GICON:
1857 if (priv->data.gicon.icon)
1858 g_object_unref (priv->data.gicon.icon);
1859 priv->data.gicon.icon = NULL;
1860 if (priv->data.gicon.pixbuf)
1861 g_object_unref (priv->data.gicon.pixbuf);
1862 priv->data.gicon.pixbuf = NULL;
1864 g_object_notify (G_OBJECT (image), "gicon");
1868 case GTK_IMAGE_EMPTY:
1876 g_free (priv->filename);
1877 priv->filename = NULL;
1878 g_object_notify (G_OBJECT (image), "file");
1881 priv->storage_type = GTK_IMAGE_EMPTY;
1883 memset (&priv->data, '\0', sizeof (priv->data));
1885 g_object_thaw_notify (G_OBJECT (image));
1890 * @image: a #GtkImage
1892 * Resets the image to be empty.
1897 gtk_image_clear (GtkImage *image)
1899 GtkImagePrivate *priv = image->priv;
1901 priv->need_calc_size = 1;
1903 gtk_image_reset (image);
1904 gtk_image_update_size (image, 0, 0);
1908 gtk_image_calc_size (GtkImage *image)
1910 GtkWidget *widget = GTK_WIDGET (image);
1911 GtkImagePrivate *priv = image->priv;
1912 GdkPixbuf *pixbuf = NULL;
1913 GtkStyleContext *context;
1914 GtkStateFlags state;
1916 priv->need_calc_size = 0;
1917 context = gtk_widget_get_style_context (widget);
1918 state = gtk_widget_get_state_flags (widget);
1920 gtk_style_context_save (context);
1921 gtk_style_context_set_state (context, state);
1923 /* We update stock/icon set on every size request, because
1924 * the theme could have affected the size; for other kinds of
1925 * image, we just update the required width/height when the image data
1928 switch (priv->storage_type)
1930 case GTK_IMAGE_STOCK:
1931 pixbuf = gtk_widget_render_icon_pixbuf (widget,
1932 priv->data.stock.stock_id,
1936 case GTK_IMAGE_ICON_SET:
1937 pixbuf = gtk_icon_set_render_icon_pixbuf (priv->data.icon_set.icon_set,
1938 context, priv->icon_size);
1940 case GTK_IMAGE_ICON_NAME:
1941 ensure_pixbuf_for_icon_name (image, 0);
1942 pixbuf = priv->data.name.pixbuf;
1943 if (pixbuf) g_object_ref (pixbuf);
1945 case GTK_IMAGE_GICON:
1946 ensure_pixbuf_for_gicon (image, 0);
1947 pixbuf = priv->data.gicon.pixbuf;
1949 g_object_ref (pixbuf);
1959 gtk_misc_get_padding (GTK_MISC (image), &xpad, &ypad);
1961 priv->required_width = gdk_pixbuf_get_width (pixbuf) + xpad * 2;
1962 priv->required_height = gdk_pixbuf_get_height (pixbuf) + ypad * 2;
1964 g_object_unref (pixbuf);
1967 gtk_style_context_restore (context);
1971 gtk_image_get_preferred_width (GtkWidget *widget,
1976 GtkImagePrivate *priv;
1978 image = GTK_IMAGE (widget);
1981 gtk_image_calc_size (image);
1983 *minimum = *natural = priv->required_width;
1987 gtk_image_get_preferred_height (GtkWidget *widget,
1992 GtkImagePrivate *priv;
1994 image = GTK_IMAGE (widget);
1997 gtk_image_calc_size (image);
1999 *minimum = *natural = priv->required_height;
2003 gtk_image_style_updated (GtkWidget *widget)
2005 GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
2007 icon_theme_changed (GTK_IMAGE (widget));
2011 gtk_image_screen_changed (GtkWidget *widget,
2012 GdkScreen *prev_screen)
2016 image = GTK_IMAGE (widget);
2018 if (GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed)
2019 GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed (widget, prev_screen);
2021 icon_theme_changed (image);
2026 gtk_image_update_size (GtkImage *image,
2030 GtkWidget *widget = GTK_WIDGET (image);
2031 GtkImagePrivate *priv = image->priv;
2034 gtk_misc_get_padding (GTK_MISC (image), &xpad, &ypad);
2036 priv->required_width = image_width + xpad * 2;
2037 priv->required_height = image_height + ypad * 2;
2039 if (gtk_widget_get_visible (widget))
2040 gtk_widget_queue_resize (widget);
2045 * gtk_image_set_pixel_size:
2046 * @image: a #GtkImage
2047 * @pixel_size: the new pixel size
2049 * Sets the pixel size to use for named icons. If the pixel size is set
2050 * to a value != -1, it is used instead of the icon size set by
2051 * gtk_image_set_from_icon_name().
2056 gtk_image_set_pixel_size (GtkImage *image,
2059 GtkImagePrivate *priv;
2061 g_return_if_fail (GTK_IS_IMAGE (image));
2065 if (priv->pixel_size != pixel_size)
2067 priv->pixel_size = pixel_size;
2069 if (priv->storage_type == GTK_IMAGE_ICON_NAME)
2071 if (priv->data.name.pixbuf)
2073 g_object_unref (priv->data.name.pixbuf);
2074 priv->data.name.pixbuf = NULL;
2077 gtk_image_update_size (image, pixel_size, pixel_size);
2080 if (priv->storage_type == GTK_IMAGE_GICON)
2082 if (priv->data.gicon.pixbuf)
2084 g_object_unref (priv->data.gicon.pixbuf);
2085 priv->data.gicon.pixbuf = NULL;
2088 gtk_image_update_size (image, pixel_size, pixel_size);
2091 g_object_notify (G_OBJECT (image), "pixel-size");
2096 * gtk_image_get_pixel_size:
2097 * @image: a #GtkImage
2099 * Gets the pixel size used for named icons.
2101 * Returns: the pixel size used for named icons.
2106 gtk_image_get_pixel_size (GtkImage *image)
2108 g_return_val_if_fail (GTK_IS_IMAGE (image), -1);
2110 return image->priv->pixel_size;