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/.
31 #include "gtkcontainer.h"
33 #include "gtkiconfactory.h"
35 #include "gtkicontheme.h"
37 #include "gtkprivate.h"
40 typedef struct _GtkImagePrivate GtkImagePrivate;
42 struct _GtkImagePrivate
44 /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
50 #define GTK_IMAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_IMAGE, GtkImagePrivate))
53 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
54 static gint gtk_image_expose (GtkWidget *widget,
55 GdkEventExpose *event);
56 static void gtk_image_unmap (GtkWidget *widget);
57 static void gtk_image_unrealize (GtkWidget *widget);
58 static void gtk_image_size_request (GtkWidget *widget,
59 GtkRequisition *requisition);
60 static void gtk_image_style_set (GtkWidget *widget,
61 GtkStyle *prev_style);
62 static void gtk_image_screen_changed (GtkWidget *widget,
63 GdkScreen *prev_screen);
64 static void gtk_image_destroy (GtkObject *object);
65 static void gtk_image_reset (GtkImage *image);
66 static void gtk_image_calc_size (GtkImage *image);
68 static void gtk_image_update_size (GtkImage *image,
72 static void gtk_image_set_property (GObject *object,
76 static void gtk_image_get_property (GObject *object,
81 static void icon_theme_changed (GtkImage *image);
95 PROP_PIXBUF_ANIMATION,
101 G_DEFINE_TYPE (GtkImage, gtk_image, GTK_TYPE_MISC)
104 gtk_image_class_init (GtkImageClass *class)
106 GObjectClass *gobject_class;
107 GtkObjectClass *object_class;
108 GtkWidgetClass *widget_class;
110 gobject_class = G_OBJECT_CLASS (class);
112 gobject_class->set_property = gtk_image_set_property;
113 gobject_class->get_property = gtk_image_get_property;
115 object_class = GTK_OBJECT_CLASS (class);
117 object_class->destroy = gtk_image_destroy;
119 widget_class = GTK_WIDGET_CLASS (class);
121 widget_class->expose_event = gtk_image_expose;
122 widget_class->size_request = gtk_image_size_request;
123 widget_class->unmap = gtk_image_unmap;
124 widget_class->unrealize = gtk_image_unrealize;
125 widget_class->style_set = gtk_image_style_set;
126 widget_class->screen_changed = gtk_image_screen_changed;
128 g_object_class_install_property (gobject_class,
130 g_param_spec_object ("pixbuf",
132 P_("A GdkPixbuf to display"),
134 GTK_PARAM_READWRITE));
136 g_object_class_install_property (gobject_class,
138 g_param_spec_object ("pixmap",
140 P_("A GdkPixmap to display"),
142 GTK_PARAM_READWRITE));
144 g_object_class_install_property (gobject_class,
146 g_param_spec_object ("image",
148 P_("A GdkImage to display"),
150 GTK_PARAM_READWRITE));
152 g_object_class_install_property (gobject_class,
154 g_param_spec_object ("mask",
156 P_("Mask bitmap to use with GdkImage or GdkPixmap"),
158 GTK_PARAM_READWRITE));
160 g_object_class_install_property (gobject_class,
162 g_param_spec_string ("file",
164 P_("Filename to load and display"),
166 GTK_PARAM_READWRITE));
169 g_object_class_install_property (gobject_class,
171 g_param_spec_string ("stock",
173 P_("Stock ID for a stock image to display"),
175 GTK_PARAM_READWRITE));
177 g_object_class_install_property (gobject_class,
179 g_param_spec_boxed ("icon-set",
181 P_("Icon set to display"),
183 GTK_PARAM_READWRITE));
185 g_object_class_install_property (gobject_class,
187 g_param_spec_int ("icon-size",
189 P_("Symbolic size to use for stock icon, icon set or named icon"),
192 GTK_PARAM_READWRITE));
194 * GtkImage:pixel-size:
196 * The "pixel-size" property can be used to specify a fixed size
197 * overriding the #GtkImage:icon-size property for images of type
198 * %GTK_IMAGE_ICON_NAME.
202 g_object_class_install_property (gobject_class,
204 g_param_spec_int ("pixel-size",
206 P_("Pixel size to use for named icon"),
209 GTK_PARAM_READWRITE));
211 g_object_class_install_property (gobject_class,
212 PROP_PIXBUF_ANIMATION,
213 g_param_spec_object ("pixbuf-animation",
215 P_("GdkPixbufAnimation to display"),
216 GDK_TYPE_PIXBUF_ANIMATION,
217 GTK_PARAM_READWRITE));
220 * GtkImage:icon-name:
222 * The name of the icon in the icon theme. If the icon theme is
223 * changed, the image will be updated automatically.
227 g_object_class_install_property (gobject_class,
229 g_param_spec_string ("icon-name",
231 P_("The name of the icon from the icon theme"),
233 GTK_PARAM_READWRITE));
238 * The GIcon displayed in the GtkImage. For themed icons,
239 * If the icon theme is changed, the image will be updated
244 g_object_class_install_property (gobject_class,
246 g_param_spec_object ("gicon",
248 P_("The GIcon being displayed"),
250 GTK_PARAM_READWRITE));
252 g_object_class_install_property (gobject_class,
254 g_param_spec_enum ("storage-type",
256 P_("The representation being used for image data"),
259 GTK_PARAM_READABLE));
261 g_type_class_add_private (object_class, sizeof (GtkImagePrivate));
265 gtk_image_init (GtkImage *image)
267 GtkImagePrivate *priv = GTK_IMAGE_GET_PRIVATE (image);
269 GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
271 image->storage_type = GTK_IMAGE_EMPTY;
272 image->icon_size = DEFAULT_ICON_SIZE;
275 priv->pixel_size = -1;
277 priv->filename = NULL;
281 gtk_image_destroy (GtkObject *object)
283 GtkImage *image = GTK_IMAGE (object);
285 gtk_image_reset (image);
287 GTK_OBJECT_CLASS (gtk_image_parent_class)->destroy (object);
291 gtk_image_set_property (GObject *object,
298 image = GTK_IMAGE (object);
303 gtk_image_set_from_pixbuf (image,
304 g_value_get_object (value));
307 gtk_image_set_from_pixmap (image,
308 g_value_get_object (value),
312 gtk_image_set_from_image (image,
313 g_value_get_object (value),
317 if (image->storage_type == GTK_IMAGE_PIXMAP)
318 gtk_image_set_from_pixmap (image,
319 image->data.pixmap.pixmap,
320 g_value_get_object (value));
321 else if (image->storage_type == GTK_IMAGE_IMAGE)
322 gtk_image_set_from_image (image,
323 image->data.image.image,
324 g_value_get_object (value));
329 mask = g_value_get_object (value);
334 gtk_image_clear (image);
340 gtk_image_set_from_file (image, g_value_get_string (value));
343 gtk_image_set_from_stock (image, g_value_get_string (value),
347 gtk_image_set_from_icon_set (image, g_value_get_boxed (value),
351 if (image->storage_type == GTK_IMAGE_STOCK)
352 gtk_image_set_from_stock (image,
353 image->data.stock.stock_id,
354 g_value_get_int (value));
355 else if (image->storage_type == GTK_IMAGE_ICON_SET)
356 gtk_image_set_from_icon_set (image,
357 image->data.icon_set.icon_set,
358 g_value_get_int (value));
359 else if (image->storage_type == GTK_IMAGE_ICON_NAME)
360 gtk_image_set_from_icon_name (image,
361 image->data.name.icon_name,
362 g_value_get_int (value));
364 /* Save to be used when STOCK or ICON_SET property comes in */
365 image->icon_size = g_value_get_int (value);
367 case PROP_PIXEL_SIZE:
368 gtk_image_set_pixel_size (image, g_value_get_int (value));
370 case PROP_PIXBUF_ANIMATION:
371 gtk_image_set_from_animation (image,
372 g_value_get_object (value));
375 gtk_image_set_from_icon_name (image, g_value_get_string (value),
379 gtk_image_set_from_gicon (image, g_value_get_object (value),
384 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
390 gtk_image_get_property (GObject *object,
396 GtkImagePrivate *priv;
398 image = GTK_IMAGE (object);
399 priv = GTK_IMAGE_GET_PRIVATE (image);
401 /* The "getter" functions whine if you try to get the wrong
402 * storage type. This function is instead robust against that,
403 * so that GUI builders don't have to jump through hoops
410 if (image->storage_type != GTK_IMAGE_PIXBUF)
411 g_value_set_object (value, NULL);
413 g_value_set_object (value,
414 gtk_image_get_pixbuf (image));
417 if (image->storage_type != GTK_IMAGE_PIXMAP)
418 g_value_set_object (value, NULL);
420 g_value_set_object (value,
421 image->data.pixmap.pixmap);
424 g_value_set_object (value, image->mask);
427 if (image->storage_type != GTK_IMAGE_IMAGE)
428 g_value_set_object (value, NULL);
430 g_value_set_object (value,
431 image->data.image.image);
434 g_value_set_string (value, priv->filename);
437 if (image->storage_type != GTK_IMAGE_STOCK)
438 g_value_set_string (value, NULL);
440 g_value_set_string (value,
441 image->data.stock.stock_id);
444 if (image->storage_type != GTK_IMAGE_ICON_SET)
445 g_value_set_boxed (value, NULL);
447 g_value_set_boxed (value,
448 image->data.icon_set.icon_set);
451 g_value_set_int (value, image->icon_size);
453 case PROP_PIXEL_SIZE:
454 g_value_set_int (value, priv->pixel_size);
456 case PROP_PIXBUF_ANIMATION:
457 if (image->storage_type != GTK_IMAGE_ANIMATION)
458 g_value_set_object (value, NULL);
460 g_value_set_object (value,
461 image->data.anim.anim);
464 if (image->storage_type != GTK_IMAGE_ICON_NAME)
465 g_value_set_string (value, NULL);
467 g_value_set_string (value,
468 image->data.name.icon_name);
471 if (image->storage_type != GTK_IMAGE_GICON)
472 g_value_set_object (value, NULL);
474 g_value_set_object (value,
475 image->data.gicon.icon);
477 case PROP_STORAGE_TYPE:
478 g_value_set_enum (value, image->storage_type);
482 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
489 * gtk_image_new_from_pixmap:
490 * @pixmap: a #GdkPixmap, or %NULL
491 * @mask: a #GdkBitmap, or %NULL
493 * Creates a #GtkImage widget displaying @pixmap with a @mask.
494 * A #GdkPixmap is a server-side image buffer in the pixel format of the
495 * current display. The #GtkImage does not assume a reference to the
496 * pixmap or mask; you still need to unref them if you own references.
497 * #GtkImage will add its own reference rather than adopting yours.
499 * Return value: a new #GtkImage
502 gtk_image_new_from_pixmap (GdkPixmap *pixmap,
507 image = g_object_new (GTK_TYPE_IMAGE, NULL);
509 gtk_image_set_from_pixmap (image, pixmap, mask);
511 return GTK_WIDGET (image);
515 * gtk_image_new_from_image:
516 * @image: a #GdkImage, or %NULL
517 * @mask: a #GdkBitmap, or %NULL
519 * Creates a #GtkImage widget displaying a @image with a @mask.
520 * A #GdkImage is a client-side image buffer in the pixel format of the
521 * current display. The #GtkImage does not assume a reference to the
522 * image or mask; you still need to unref them if you own references.
523 * #GtkImage will add its own reference rather than adopting yours.
525 * Return value: a new #GtkImage
528 gtk_image_new_from_image (GdkImage *gdk_image,
533 image = g_object_new (GTK_TYPE_IMAGE, NULL);
535 gtk_image_set_from_image (image, gdk_image, mask);
537 return GTK_WIDGET (image);
541 * gtk_image_new_from_file:
542 * @filename: a filename
544 * Creates a new #GtkImage displaying the file @filename. If the file
545 * isn't found or can't be loaded, the resulting #GtkImage will
546 * display a "broken image" icon. This function never returns %NULL,
547 * it always returns a valid #GtkImage widget.
549 * If the file contains an animation, the image will contain an
552 * If you need to detect failures to load the file, use
553 * gdk_pixbuf_new_from_file() to load the file yourself, then create
554 * the #GtkImage from the pixbuf. (Or for animations, use
555 * gdk_pixbuf_animation_new_from_file()).
557 * The storage type (gtk_image_get_storage_type()) of the returned
558 * image is not defined, it will be whatever is appropriate for
559 * displaying the file.
561 * Return value: a new #GtkImage
564 gtk_image_new_from_file (const gchar *filename)
568 image = g_object_new (GTK_TYPE_IMAGE, NULL);
570 gtk_image_set_from_file (image, filename);
572 return GTK_WIDGET (image);
576 * gtk_image_new_from_pixbuf:
577 * @pixbuf: a #GdkPixbuf, or %NULL
579 * Creates a new #GtkImage displaying @pixbuf.
580 * The #GtkImage does not assume a reference to the
581 * pixbuf; you still need to unref it if you own references.
582 * #GtkImage will add its own reference rather than adopting yours.
584 * Note that this function just creates an #GtkImage from the pixbuf. The
585 * #GtkImage created will not react to state changes. Should you want that,
586 * you should use gtk_image_new_from_icon_set().
588 * Return value: a new #GtkImage
591 gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
595 image = g_object_new (GTK_TYPE_IMAGE, NULL);
597 gtk_image_set_from_pixbuf (image, pixbuf);
599 return GTK_WIDGET (image);
603 * gtk_image_new_from_stock:
604 * @stock_id: a stock icon name
605 * @size: a stock icon size
607 * Creates a #GtkImage displaying a stock icon. Sample stock icon
608 * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. Sample stock sizes
609 * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
610 * icon name isn't known, the image will be empty.
611 * You can register your own stock icon names, see
612 * gtk_icon_factory_add_default() and gtk_icon_factory_add().
614 * Return value: a new #GtkImage displaying the stock icon
617 gtk_image_new_from_stock (const gchar *stock_id,
622 image = g_object_new (GTK_TYPE_IMAGE, NULL);
624 gtk_image_set_from_stock (image, stock_id, size);
626 return GTK_WIDGET (image);
630 * gtk_image_new_from_icon_set:
631 * @icon_set: a #GtkIconSet
632 * @size: a stock icon size
634 * Creates a #GtkImage displaying an icon set. Sample stock sizes are
635 * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. Instead of using
636 * this function, usually it's better to create a #GtkIconFactory, put
637 * your icon sets in the icon factory, add the icon factory to the
638 * list of default factories with gtk_icon_factory_add_default(), and
639 * then use gtk_image_new_from_stock(). This will allow themes to
640 * override the icon you ship with your application.
642 * The #GtkImage does not assume a reference to the
643 * icon set; you still need to unref it if you own references.
644 * #GtkImage will add its own reference rather than adopting yours.
646 * Return value: a new #GtkImage
649 gtk_image_new_from_icon_set (GtkIconSet *icon_set,
654 image = g_object_new (GTK_TYPE_IMAGE, NULL);
656 gtk_image_set_from_icon_set (image, icon_set, size);
658 return GTK_WIDGET (image);
662 * gtk_image_new_from_animation:
663 * @animation: an animation
665 * Creates a #GtkImage displaying the given animation.
666 * The #GtkImage does not assume a reference to the
667 * animation; you still need to unref it if you own references.
668 * #GtkImage will add its own reference rather than adopting yours.
670 * Note that the animation frames are shown using a timeout with
671 * #G_PRIORITY_DEFAULT. When using animations to indicate busyness,
672 * keep in mind that the animation will only be shown if the main loop
673 * is not busy with something that has a higher priority.
675 * Return value: a new #GtkImage widget
678 gtk_image_new_from_animation (GdkPixbufAnimation *animation)
682 g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
684 image = g_object_new (GTK_TYPE_IMAGE, NULL);
686 gtk_image_set_from_animation (image, animation);
688 return GTK_WIDGET (image);
692 * gtk_image_new_from_icon_name:
693 * @icon_name: an icon name
694 * @size: a stock icon size
696 * Creates a #GtkImage displaying an icon from the current icon theme.
697 * If the icon name isn't known, a "broken image" icon will be
698 * displayed instead. If the current icon theme is changed, the icon
699 * will be updated appropriately.
701 * Return value: a new #GtkImage displaying the themed icon
706 gtk_image_new_from_icon_name (const gchar *icon_name,
711 image = g_object_new (GTK_TYPE_IMAGE, NULL);
713 gtk_image_set_from_icon_name (image, icon_name, size);
715 return GTK_WIDGET (image);
719 * gtk_image_new_from_gicon:
721 * @size: a stock icon size
723 * Creates a #GtkImage displaying an icon from the current icon theme.
724 * If the icon name isn't known, a "broken image" icon will be
725 * displayed instead. If the current icon theme is changed, the icon
726 * will be updated appropriately.
728 * Return value: a new #GtkImage displaying the themed icon
733 gtk_image_new_from_gicon (GIcon *icon,
738 image = g_object_new (GTK_TYPE_IMAGE, NULL);
740 gtk_image_set_from_gicon (image, icon, size);
742 return GTK_WIDGET (image);
746 * gtk_image_set_from_pixmap:
747 * @image: a #GtkImage
748 * @pixmap: a #GdkPixmap or %NULL
749 * @mask: a #GdkBitmap or %NULL
751 * See gtk_image_new_from_pixmap() for details.
754 gtk_image_set_from_pixmap (GtkImage *image,
758 g_return_if_fail (GTK_IS_IMAGE (image));
759 g_return_if_fail (pixmap == NULL ||
760 GDK_IS_PIXMAP (pixmap));
761 g_return_if_fail (mask == NULL ||
762 GDK_IS_PIXMAP (mask));
764 g_object_freeze_notify (G_OBJECT (image));
767 g_object_ref (pixmap);
772 gtk_image_clear (image);
781 image->storage_type = GTK_IMAGE_PIXMAP;
783 image->data.pixmap.pixmap = pixmap;
785 gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
787 gtk_image_update_size (image, width, height);
790 g_object_notify (G_OBJECT (image), "pixmap");
791 g_object_notify (G_OBJECT (image), "mask");
793 g_object_thaw_notify (G_OBJECT (image));
797 * gtk_image_set_from_image:
798 * @image: a #GtkImage
799 * @gdk_image: a #GdkImage or %NULL
800 * @mask: a #GdkBitmap or %NULL
802 * See gtk_image_new_from_image() for details.
805 gtk_image_set_from_image (GtkImage *image,
809 g_return_if_fail (GTK_IS_IMAGE (image));
810 g_return_if_fail (gdk_image == NULL ||
811 GDK_IS_IMAGE (gdk_image));
812 g_return_if_fail (mask == NULL ||
813 GDK_IS_PIXMAP (mask));
815 g_object_freeze_notify (G_OBJECT (image));
818 g_object_ref (gdk_image);
823 gtk_image_clear (image);
827 image->storage_type = GTK_IMAGE_IMAGE;
829 image->data.image.image = gdk_image;
832 gtk_image_update_size (image, gdk_image->width, gdk_image->height);
836 /* Clean up the mask if gdk_image was NULL */
838 g_object_unref (mask);
841 g_object_notify (G_OBJECT (image), "image");
842 g_object_notify (G_OBJECT (image), "mask");
844 g_object_thaw_notify (G_OBJECT (image));
848 * gtk_image_set_from_file:
849 * @image: a #GtkImage
850 * @filename: a filename or %NULL
852 * See gtk_image_new_from_file() for details.
855 gtk_image_set_from_file (GtkImage *image,
856 const gchar *filename)
858 GtkImagePrivate *priv = GTK_IMAGE_GET_PRIVATE (image);
859 GdkPixbufAnimation *anim;
861 g_return_if_fail (GTK_IS_IMAGE (image));
863 g_object_freeze_notify (G_OBJECT (image));
865 gtk_image_clear (image);
867 if (filename == NULL)
869 priv->filename = NULL;
870 g_object_thaw_notify (G_OBJECT (image));
874 anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
878 gtk_image_set_from_stock (image,
879 GTK_STOCK_MISSING_IMAGE,
880 GTK_ICON_SIZE_BUTTON);
881 g_object_thaw_notify (G_OBJECT (image));
885 /* We could just unconditionally set_from_animation,
886 * but it's nicer for memory if we toss the animation
887 * if it's just a single pixbuf
890 if (gdk_pixbuf_animation_is_static_image (anim))
891 gtk_image_set_from_pixbuf (image,
892 gdk_pixbuf_animation_get_static_image (anim));
894 gtk_image_set_from_animation (image, anim);
896 g_object_unref (anim);
898 priv->filename = g_strdup (filename);
900 g_object_thaw_notify (G_OBJECT (image));
904 * gtk_image_set_from_pixbuf:
905 * @image: a #GtkImage
906 * @pixbuf: a #GdkPixbuf or %NULL
908 * See gtk_image_new_from_pixbuf() for details.
911 gtk_image_set_from_pixbuf (GtkImage *image,
914 g_return_if_fail (GTK_IS_IMAGE (image));
915 g_return_if_fail (pixbuf == NULL ||
916 GDK_IS_PIXBUF (pixbuf));
918 g_object_freeze_notify (G_OBJECT (image));
921 g_object_ref (pixbuf);
923 gtk_image_clear (image);
927 image->storage_type = GTK_IMAGE_PIXBUF;
929 image->data.pixbuf.pixbuf = pixbuf;
931 gtk_image_update_size (image,
932 gdk_pixbuf_get_width (pixbuf),
933 gdk_pixbuf_get_height (pixbuf));
936 g_object_notify (G_OBJECT (image), "pixbuf");
938 g_object_thaw_notify (G_OBJECT (image));
942 * gtk_image_set_from_stock:
943 * @image: a #GtkImage
944 * @stock_id: a stock icon name
945 * @size: a stock icon size
947 * See gtk_image_new_from_stock() for details.
950 gtk_image_set_from_stock (GtkImage *image,
951 const gchar *stock_id,
956 g_return_if_fail (GTK_IS_IMAGE (image));
958 g_object_freeze_notify (G_OBJECT (image));
960 /* in case stock_id == image->data.stock.stock_id */
961 new_id = g_strdup (stock_id);
963 gtk_image_clear (image);
967 image->storage_type = GTK_IMAGE_STOCK;
969 image->data.stock.stock_id = new_id;
970 image->icon_size = size;
972 /* Size is demand-computed in size request method
973 * if we're a stock image, since changing the
974 * style impacts the size request
978 g_object_notify (G_OBJECT (image), "stock");
979 g_object_notify (G_OBJECT (image), "icon-size");
981 g_object_thaw_notify (G_OBJECT (image));
985 * gtk_image_set_from_icon_set:
986 * @image: a #GtkImage
987 * @icon_set: a #GtkIconSet
988 * @size: a stock icon size
990 * See gtk_image_new_from_icon_set() for details.
993 gtk_image_set_from_icon_set (GtkImage *image,
994 GtkIconSet *icon_set,
997 g_return_if_fail (GTK_IS_IMAGE (image));
999 g_object_freeze_notify (G_OBJECT (image));
1002 gtk_icon_set_ref (icon_set);
1004 gtk_image_clear (image);
1008 image->storage_type = GTK_IMAGE_ICON_SET;
1010 image->data.icon_set.icon_set = icon_set;
1011 image->icon_size = size;
1013 /* Size is demand-computed in size request method
1014 * if we're an icon set
1018 g_object_notify (G_OBJECT (image), "icon-set");
1019 g_object_notify (G_OBJECT (image), "icon-size");
1021 g_object_thaw_notify (G_OBJECT (image));
1025 * gtk_image_set_from_animation:
1026 * @image: a #GtkImage
1027 * @animation: the #GdkPixbufAnimation
1029 * Causes the #GtkImage to display the given animation (or display
1030 * nothing, if you set the animation to %NULL).
1033 gtk_image_set_from_animation (GtkImage *image,
1034 GdkPixbufAnimation *animation)
1036 g_return_if_fail (GTK_IS_IMAGE (image));
1037 g_return_if_fail (animation == NULL ||
1038 GDK_IS_PIXBUF_ANIMATION (animation));
1040 g_object_freeze_notify (G_OBJECT (image));
1043 g_object_ref (animation);
1045 gtk_image_clear (image);
1047 if (animation != NULL)
1049 image->storage_type = GTK_IMAGE_ANIMATION;
1051 image->data.anim.anim = animation;
1052 image->data.anim.frame_timeout = 0;
1053 image->data.anim.iter = NULL;
1055 gtk_image_update_size (image,
1056 gdk_pixbuf_animation_get_width (animation),
1057 gdk_pixbuf_animation_get_height (animation));
1060 g_object_notify (G_OBJECT (image), "pixbuf-animation");
1062 g_object_thaw_notify (G_OBJECT (image));
1066 * gtk_image_set_from_icon_name:
1067 * @image: a #GtkImage
1068 * @icon_name: an icon name
1069 * @size: an icon size
1071 * See gtk_image_new_from_icon_name() for details.
1076 gtk_image_set_from_icon_name (GtkImage *image,
1077 const gchar *icon_name,
1082 g_return_if_fail (GTK_IS_IMAGE (image));
1084 g_object_freeze_notify (G_OBJECT (image));
1086 /* in case icon_name == image->data.name.icon_name */
1087 new_name = g_strdup (icon_name);
1089 gtk_image_clear (image);
1093 image->storage_type = GTK_IMAGE_ICON_NAME;
1095 image->data.name.icon_name = new_name;
1096 image->icon_size = size;
1098 /* Size is demand-computed in size request method
1099 * if we're a icon theme image, since changing the
1100 * style impacts the size request
1104 g_object_notify (G_OBJECT (image), "icon-name");
1105 g_object_notify (G_OBJECT (image), "icon-size");
1107 g_object_thaw_notify (G_OBJECT (image));
1111 * gtk_image_set_from_gicon:
1112 * @image: a #GtkImage
1114 * @size: an icon size
1116 * See gtk_image_new_from_gicon() for details.
1121 gtk_image_set_from_gicon (GtkImage *image,
1125 g_return_if_fail (GTK_IS_IMAGE (image));
1127 g_object_freeze_notify (G_OBJECT (image));
1129 /* in case icon == image->data.gicon.icon */
1131 g_object_ref (icon);
1133 gtk_image_clear (image);
1137 image->storage_type = GTK_IMAGE_GICON;
1139 image->data.gicon.icon = icon;
1140 image->icon_size = size;
1142 /* Size is demand-computed in size request method
1143 * if we're a icon theme image, since changing the
1144 * style impacts the size request
1148 g_object_notify (G_OBJECT (image), "gicon");
1149 g_object_notify (G_OBJECT (image), "icon-size");
1151 g_object_thaw_notify (G_OBJECT (image));
1155 * gtk_image_get_storage_type:
1156 * @image: a #GtkImage
1158 * Gets the type of representation being used by the #GtkImage
1159 * to store image data. If the #GtkImage has no image data,
1160 * the return value will be %GTK_IMAGE_EMPTY.
1162 * Return value: image representation being used
1165 gtk_image_get_storage_type (GtkImage *image)
1167 g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);
1169 return image->storage_type;
1173 * gtk_image_get_pixmap:
1174 * @image: a #GtkImage
1175 * @pixmap: location to store the pixmap, or %NULL
1176 * @mask: location to store the mask, or %NULL
1178 * Gets the pixmap and mask being displayed by the #GtkImage.
1179 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1180 * %GTK_IMAGE_PIXMAP (see gtk_image_get_storage_type()).
1181 * The caller of this function does not own a reference to the
1182 * returned pixmap and mask.
1185 gtk_image_get_pixmap (GtkImage *image,
1189 g_return_if_fail (GTK_IS_IMAGE (image));
1190 g_return_if_fail (image->storage_type == GTK_IMAGE_PIXMAP ||
1191 image->storage_type == GTK_IMAGE_EMPTY);
1194 *pixmap = image->data.pixmap.pixmap;
1197 *mask = image->mask;
1201 * gtk_image_get_image:
1202 * @image: a #GtkImage
1203 * @gdk_image: return location for a #GtkImage
1204 * @mask: return location for a #GdkBitmap
1206 * Gets the #GdkImage and mask being displayed by the #GtkImage.
1207 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1208 * %GTK_IMAGE_IMAGE (see gtk_image_get_storage_type()).
1209 * The caller of this function does not own a reference to the
1210 * returned image and mask.
1213 gtk_image_get_image (GtkImage *image,
1214 GdkImage **gdk_image,
1217 g_return_if_fail (GTK_IS_IMAGE (image));
1218 g_return_if_fail (image->storage_type == GTK_IMAGE_IMAGE ||
1219 image->storage_type == GTK_IMAGE_EMPTY);
1222 *gdk_image = image->data.image.image;
1225 *mask = image->mask;
1229 * gtk_image_get_pixbuf:
1230 * @image: a #GtkImage
1232 * Gets the #GdkPixbuf being displayed by the #GtkImage.
1233 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1234 * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
1235 * The caller of this function does not own a reference to the
1238 * Return value: the displayed pixbuf, or %NULL if the image is empty
1241 gtk_image_get_pixbuf (GtkImage *image)
1243 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1244 g_return_val_if_fail (image->storage_type == GTK_IMAGE_PIXBUF ||
1245 image->storage_type == GTK_IMAGE_EMPTY, NULL);
1247 if (image->storage_type == GTK_IMAGE_EMPTY)
1248 image->data.pixbuf.pixbuf = NULL;
1250 return image->data.pixbuf.pixbuf;
1254 * gtk_image_get_stock:
1255 * @image: a #GtkImage
1256 * @stock_id: place to store a stock icon name
1257 * @size: place to store a stock icon size
1259 * Gets the stock icon name and size being displayed by the #GtkImage.
1260 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1261 * %GTK_IMAGE_STOCK (see gtk_image_get_storage_type()).
1262 * The returned string is owned by the #GtkImage and should not
1266 gtk_image_get_stock (GtkImage *image,
1270 g_return_if_fail (GTK_IS_IMAGE (image));
1271 g_return_if_fail (image->storage_type == GTK_IMAGE_STOCK ||
1272 image->storage_type == GTK_IMAGE_EMPTY);
1274 if (image->storage_type == GTK_IMAGE_EMPTY)
1275 image->data.stock.stock_id = NULL;
1278 *stock_id = image->data.stock.stock_id;
1281 *size = image->icon_size;
1285 * gtk_image_get_icon_set:
1286 * @image: a #GtkImage
1287 * @icon_set: location to store a #GtkIconSet
1288 * @size: location to store a stock icon size
1290 * Gets the icon set and size being displayed by the #GtkImage.
1291 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1292 * %GTK_IMAGE_ICON_SET (see gtk_image_get_storage_type()).
1295 gtk_image_get_icon_set (GtkImage *image,
1296 GtkIconSet **icon_set,
1299 g_return_if_fail (GTK_IS_IMAGE (image));
1300 g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_SET ||
1301 image->storage_type == GTK_IMAGE_EMPTY);
1304 *icon_set = image->data.icon_set.icon_set;
1307 *size = image->icon_size;
1311 * gtk_image_get_animation:
1312 * @image: a #GtkImage
1314 * Gets the #GdkPixbufAnimation being displayed by the #GtkImage.
1315 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1316 * %GTK_IMAGE_ANIMATION (see gtk_image_get_storage_type()).
1317 * The caller of this function does not own a reference to the
1318 * returned animation.
1320 * Return value: the displayed animation, or %NULL if the image is empty
1323 gtk_image_get_animation (GtkImage *image)
1325 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1326 g_return_val_if_fail (image->storage_type == GTK_IMAGE_ANIMATION ||
1327 image->storage_type == GTK_IMAGE_EMPTY,
1330 if (image->storage_type == GTK_IMAGE_EMPTY)
1331 image->data.anim.anim = NULL;
1333 return image->data.anim.anim;
1337 * gtk_image_get_icon_name:
1338 * @image: a #GtkImage
1339 * @icon_name: place to store an icon name
1340 * @size: place to store an icon size
1342 * Gets the icon name and size being displayed by the #GtkImage.
1343 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1344 * %GTK_IMAGE_ICON_NAME (see gtk_image_get_storage_type()).
1345 * The returned string is owned by the #GtkImage and should not
1351 gtk_image_get_icon_name (GtkImage *image,
1352 G_CONST_RETURN gchar **icon_name,
1355 g_return_if_fail (GTK_IS_IMAGE (image));
1356 g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_NAME ||
1357 image->storage_type == GTK_IMAGE_EMPTY);
1359 if (image->storage_type == GTK_IMAGE_EMPTY)
1360 image->data.name.icon_name = NULL;
1363 *icon_name = image->data.name.icon_name;
1366 *size = image->icon_size;
1370 * gtk_image_get_gicon:
1371 * @image: a #GtkImage
1372 * @gicon: place to store a #GIcon
1373 * @size: place to store an icon size
1375 * Gets the #GIcon and size being displayed by the #GtkImage.
1376 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1377 * %GTK_IMAGE_GICON (see gtk_image_get_storage_type()).
1378 * The caller of this function does not own a reference to the
1384 gtk_image_get_gicon (GtkImage *image,
1388 g_return_if_fail (GTK_IS_IMAGE (image));
1389 g_return_if_fail (image->storage_type == GTK_IMAGE_GICON ||
1390 image->storage_type == GTK_IMAGE_EMPTY);
1392 if (image->storage_type == GTK_IMAGE_EMPTY)
1393 image->data.gicon.icon = NULL;
1396 *gicon = image->data.gicon.icon;
1399 *size = image->icon_size;
1405 * Creates a new empty #GtkImage widget.
1407 * Return value: a newly created #GtkImage widget.
1410 gtk_image_new (void)
1412 return g_object_new (GTK_TYPE_IMAGE, NULL);
1416 gtk_image_set (GtkImage *image,
1420 g_return_if_fail (GTK_IS_IMAGE (image));
1422 gtk_image_set_from_image (image, val, mask);
1426 gtk_image_get (GtkImage *image,
1430 g_return_if_fail (GTK_IS_IMAGE (image));
1432 gtk_image_get_image (image, val, mask);
1436 gtk_image_reset_anim_iter (GtkImage *image)
1438 if (image->storage_type == GTK_IMAGE_ANIMATION)
1440 /* Reset the animation */
1442 if (image->data.anim.frame_timeout)
1444 g_source_remove (image->data.anim.frame_timeout);
1445 image->data.anim.frame_timeout = 0;
1448 if (image->data.anim.iter)
1450 g_object_unref (image->data.anim.iter);
1451 image->data.anim.iter = NULL;
1457 gtk_image_unmap (GtkWidget *widget)
1459 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1461 if (GTK_WIDGET_CLASS (gtk_image_parent_class)->unmap)
1462 GTK_WIDGET_CLASS (gtk_image_parent_class)->unmap (widget);
1466 gtk_image_unrealize (GtkWidget *widget)
1468 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1470 if (GTK_WIDGET_CLASS (gtk_image_parent_class)->unrealize)
1471 GTK_WIDGET_CLASS (gtk_image_parent_class)->unrealize (widget);
1475 animation_timeout (gpointer data)
1480 image = GTK_IMAGE (data);
1482 image->data.anim.frame_timeout = 0;
1484 gdk_pixbuf_animation_iter_advance (image->data.anim.iter, NULL);
1486 delay = gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter);
1489 image->data.anim.frame_timeout =
1490 gdk_threads_add_timeout (delay, animation_timeout, image);
1492 gtk_widget_queue_draw (GTK_WIDGET (image));
1494 if (GTK_WIDGET_DRAWABLE (image))
1495 gdk_window_process_updates (GTK_WIDGET (image)->window, TRUE);
1502 icon_theme_changed (GtkImage *image)
1504 if (image->storage_type == GTK_IMAGE_ICON_NAME)
1506 if (image->data.name.pixbuf)
1507 g_object_unref (image->data.name.pixbuf);
1508 image->data.name.pixbuf = NULL;
1510 gtk_widget_queue_draw (GTK_WIDGET (image));
1512 if (image->storage_type == GTK_IMAGE_GICON)
1514 if (image->data.gicon.pixbuf)
1515 g_object_unref (image->data.gicon.pixbuf);
1516 image->data.gicon.pixbuf = NULL;
1518 gtk_widget_queue_draw (GTK_WIDGET (image));
1523 ensure_pixbuf_for_icon_name (GtkImage *image)
1525 GtkImagePrivate *priv;
1527 GtkIconTheme *icon_theme;
1528 GtkSettings *settings;
1530 gint *sizes, *s, dist;
1531 GtkIconLookupFlags flags;
1532 GError *error = NULL;
1534 g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_NAME);
1536 priv = GTK_IMAGE_GET_PRIVATE (image);
1537 screen = gtk_widget_get_screen (GTK_WIDGET (image));
1538 icon_theme = gtk_icon_theme_get_for_screen (screen);
1539 settings = gtk_settings_get_for_screen (screen);
1540 flags = GTK_ICON_LOOKUP_USE_BUILTIN;
1541 if (image->data.name.pixbuf == NULL)
1543 if (priv->pixel_size != -1)
1545 width = height = priv->pixel_size;
1546 flags |= GTK_ICON_LOOKUP_FORCE_SIZE;
1548 else if (!gtk_icon_size_lookup_for_settings (settings,
1552 if (image->icon_size == -1)
1554 /* Find an available size close to 48 */
1555 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, image->data.name.icon_name);
1557 width = height = 48;
1558 for (s = sizes; *s; s++)
1562 width = height = 48;
1569 width = height = *s;
1577 width = height = *s;
1586 g_warning ("Invalid icon size %d\n", image->icon_size);
1587 width = height = 24;
1590 image->data.name.pixbuf =
1591 gtk_icon_theme_load_icon (icon_theme,
1592 image->data.name.icon_name,
1593 MIN (width, height), flags, &error);
1594 if (image->data.name.pixbuf == NULL)
1596 g_error_free (error);
1597 image->data.name.pixbuf =
1598 gtk_widget_render_icon (GTK_WIDGET (image),
1599 GTK_STOCK_MISSING_IMAGE,
1607 ensure_pixbuf_for_gicon (GtkImage *image)
1609 GtkImagePrivate *priv;
1611 GtkIconTheme *icon_theme;
1612 GtkSettings *settings;
1615 GtkIconLookupFlags flags;
1616 GError *error = NULL;
1618 g_return_if_fail (image->storage_type == GTK_IMAGE_GICON);
1620 priv = GTK_IMAGE_GET_PRIVATE (image);
1621 screen = gtk_widget_get_screen (GTK_WIDGET (image));
1622 icon_theme = gtk_icon_theme_get_for_screen (screen);
1623 settings = gtk_settings_get_for_screen (screen);
1624 flags = GTK_ICON_LOOKUP_USE_BUILTIN;
1625 if (image->data.gicon.pixbuf == NULL)
1627 if (priv->pixel_size != -1)
1629 width = height = priv->pixel_size;
1630 flags |= GTK_ICON_LOOKUP_FORCE_SIZE;
1632 else if (!gtk_icon_size_lookup_for_settings (settings,
1636 if (image->icon_size == -1)
1637 width = height = 48;
1640 g_warning ("Invalid icon size %d\n", image->icon_size);
1641 width = height = 24;
1645 info = gtk_icon_theme_lookup_by_gicon (icon_theme,
1646 image->data.gicon.icon,
1647 MIN (width, height), flags);
1648 image->data.gicon.pixbuf = gtk_icon_info_load_icon (info, &error);
1649 if (image->data.gicon.pixbuf == NULL)
1651 g_error_free (error);
1652 image->data.gicon.pixbuf =
1653 gtk_widget_render_icon (GTK_WIDGET (image),
1654 GTK_STOCK_MISSING_IMAGE,
1663 * Like gdk_rectangle_intersect (dest, src, dest), but make
1664 * sure that the origin of dest is moved by an "even" offset.
1665 * If necessary grow the intersection by one row or column
1668 * This is necessary since we can't pass alignment information
1669 * for the pixelation pattern down to gdk_pixbuf_saturate_and_pixelate(),
1670 * thus we have to makesure that the subimages are properly aligned.
1673 rectangle_intersect_even (GdkRectangle *src,
1681 isect = gdk_rectangle_intersect (dest, src, dest);
1683 if ((dest->x - x + dest->y - y) % 2 != 0)
1701 gtk_image_expose (GtkWidget *widget,
1702 GdkEventExpose *event)
1704 g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
1705 g_return_val_if_fail (event != NULL, FALSE);
1707 if (GTK_WIDGET_MAPPED (widget) &&
1708 GTK_IMAGE (widget)->storage_type != GTK_IMAGE_EMPTY)
1712 GdkRectangle area, image_bound;
1714 gint x, y, mask_x, mask_y;
1717 gboolean needs_state_transform;
1719 image = GTK_IMAGE (widget);
1720 misc = GTK_MISC (widget);
1724 /* For stock items and icon sets, we lazily calculate
1725 * the size; we might get here between a queue_resize()
1726 * and size_request() if something explicitely forces
1729 if (widget->requisition.width == 0 && widget->requisition.height == 0)
1730 gtk_image_calc_size (image);
1732 if (!gdk_rectangle_intersect (&area, &widget->allocation, &area))
1735 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1736 xalign = misc->xalign;
1738 xalign = 1.0 - misc->xalign;
1740 x = floor (widget->allocation.x + misc->xpad
1741 + ((widget->allocation.width - widget->requisition.width) * xalign));
1742 y = floor (widget->allocation.y + misc->ypad
1743 + ((widget->allocation.height - widget->requisition.height) * misc->yalign));
1749 image_bound.width = 0;
1750 image_bound.height = 0;
1754 needs_state_transform = GTK_WIDGET_STATE (widget) != GTK_STATE_NORMAL;
1756 switch (image->storage_type)
1758 case GTK_IMAGE_PIXMAP:
1760 gdk_drawable_get_size (image->data.pixmap.pixmap,
1762 &image_bound.height);
1763 if (rectangle_intersect_even (&area, &image_bound) &&
1764 needs_state_transform)
1766 pixbuf = gdk_pixbuf_get_from_drawable (NULL,
1767 image->data.pixmap.pixmap,
1768 gtk_widget_get_colormap (widget),
1769 image_bound.x - x, image_bound.y - y,
1772 image_bound.height);
1780 case GTK_IMAGE_IMAGE:
1782 image_bound.width = image->data.image.image->width;
1783 image_bound.height = image->data.image.image->height;
1785 if (rectangle_intersect_even (&area, &image_bound) &&
1786 needs_state_transform)
1788 pixbuf = gdk_pixbuf_get_from_image (NULL,
1789 image->data.image.image,
1790 gtk_widget_get_colormap (widget),
1791 image_bound.x - x, image_bound.y - y,
1794 image_bound.height);
1801 case GTK_IMAGE_PIXBUF:
1802 image_bound.width = gdk_pixbuf_get_width (image->data.pixbuf.pixbuf);
1803 image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);
1805 if (rectangle_intersect_even (&area, &image_bound) &&
1806 needs_state_transform)
1808 pixbuf = gdk_pixbuf_new_subpixbuf (image->data.pixbuf.pixbuf,
1809 image_bound.x - x, image_bound.y - y,
1810 image_bound.width, image_bound.height);
1817 pixbuf = image->data.pixbuf.pixbuf;
1818 g_object_ref (pixbuf);
1822 case GTK_IMAGE_STOCK:
1823 pixbuf = gtk_widget_render_icon (widget,
1824 image->data.stock.stock_id,
1829 image_bound.width = gdk_pixbuf_get_width (pixbuf);
1830 image_bound.height = gdk_pixbuf_get_height (pixbuf);
1834 needs_state_transform = FALSE;
1837 case GTK_IMAGE_ICON_SET:
1839 gtk_icon_set_render_icon (image->data.icon_set.icon_set,
1841 gtk_widget_get_direction (widget),
1842 GTK_WIDGET_STATE (widget),
1849 image_bound.width = gdk_pixbuf_get_width (pixbuf);
1850 image_bound.height = gdk_pixbuf_get_height (pixbuf);
1854 needs_state_transform = FALSE;
1857 case GTK_IMAGE_ANIMATION:
1859 if (image->data.anim.iter == NULL)
1861 image->data.anim.iter = gdk_pixbuf_animation_get_iter (image->data.anim.anim, NULL);
1863 if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
1864 image->data.anim.frame_timeout =
1865 gdk_threads_add_timeout (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
1870 image_bound.width = gdk_pixbuf_animation_get_width (image->data.anim.anim);
1871 image_bound.height = gdk_pixbuf_animation_get_height (image->data.anim.anim);
1873 /* don't advance the anim iter here, or we could get frame changes between two
1874 * exposes of different areas.
1877 pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter);
1878 g_object_ref (pixbuf);
1882 case GTK_IMAGE_ICON_NAME:
1883 ensure_pixbuf_for_icon_name (image);
1884 pixbuf = image->data.name.pixbuf;
1887 g_object_ref (pixbuf);
1888 image_bound.width = gdk_pixbuf_get_width (pixbuf);
1889 image_bound.height = gdk_pixbuf_get_height (pixbuf);
1893 case GTK_IMAGE_GICON:
1894 ensure_pixbuf_for_gicon (image);
1895 pixbuf = image->data.gicon.pixbuf;
1898 g_object_ref (pixbuf);
1899 image_bound.width = gdk_pixbuf_get_width (pixbuf);
1900 image_bound.height = gdk_pixbuf_get_height (pixbuf);
1904 case GTK_IMAGE_EMPTY:
1905 g_assert_not_reached ();
1911 gdk_gc_set_clip_mask (widget->style->black_gc, mask);
1912 gdk_gc_set_clip_origin (widget->style->black_gc, mask_x, mask_y);
1915 if (rectangle_intersect_even (&area, &image_bound))
1919 if (needs_state_transform)
1921 GtkIconSource *source;
1922 GdkPixbuf *rendered;
1924 source = gtk_icon_source_new ();
1925 gtk_icon_source_set_pixbuf (source, pixbuf);
1926 /* The size here is arbitrary; since size isn't
1927 * wildcarded in the souce, it isn't supposed to be
1928 * scaled by the engine function
1930 gtk_icon_source_set_size (source,
1931 GTK_ICON_SIZE_SMALL_TOOLBAR);
1932 gtk_icon_source_set_size_wildcarded (source, FALSE);
1934 rendered = gtk_style_render_icon (widget->style,
1936 gtk_widget_get_direction (widget),
1937 GTK_WIDGET_STATE (widget),
1943 gtk_icon_source_free (source);
1945 g_object_unref (pixbuf);
1951 gdk_draw_pixbuf (widget->window,
1952 widget->style->black_gc,
1960 GDK_RGB_DITHER_NORMAL,
1966 switch (image->storage_type)
1968 case GTK_IMAGE_PIXMAP:
1969 gdk_draw_drawable (widget->window,
1970 widget->style->black_gc,
1971 image->data.pixmap.pixmap,
1972 image_bound.x - x, image_bound.y - y,
1973 image_bound.x, image_bound.y,
1974 image_bound.width, image_bound.height);
1977 case GTK_IMAGE_IMAGE:
1978 gdk_draw_image (widget->window,
1979 widget->style->black_gc,
1980 image->data.image.image,
1981 image_bound.x - x, image_bound.y - y,
1982 image_bound.x, image_bound.y,
1983 image_bound.width, image_bound.height);
1986 case GTK_IMAGE_PIXBUF:
1987 case GTK_IMAGE_STOCK:
1988 case GTK_IMAGE_ICON_SET:
1989 case GTK_IMAGE_ANIMATION:
1990 case GTK_IMAGE_ICON_NAME:
1991 case GTK_IMAGE_EMPTY:
1992 case GTK_IMAGE_GICON:
1993 g_assert_not_reached ();
1997 } /* if rectangle intersects */
2001 gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
2002 gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
2006 g_object_unref (pixbuf);
2008 } /* if widget is drawable */
2014 gtk_image_reset (GtkImage *image)
2016 GtkImagePrivate *priv;
2018 priv = GTK_IMAGE_GET_PRIVATE (image);
2020 g_object_freeze_notify (G_OBJECT (image));
2022 if (image->storage_type != GTK_IMAGE_EMPTY)
2023 g_object_notify (G_OBJECT (image), "storage-type");
2027 g_object_unref (image->mask);
2029 g_object_notify (G_OBJECT (image), "mask");
2032 if (image->icon_size != DEFAULT_ICON_SIZE)
2034 image->icon_size = DEFAULT_ICON_SIZE;
2035 g_object_notify (G_OBJECT (image), "icon-size");
2038 switch (image->storage_type)
2040 case GTK_IMAGE_PIXMAP:
2042 if (image->data.pixmap.pixmap)
2043 g_object_unref (image->data.pixmap.pixmap);
2044 image->data.pixmap.pixmap = NULL;
2046 g_object_notify (G_OBJECT (image), "pixmap");
2050 case GTK_IMAGE_IMAGE:
2052 if (image->data.image.image)
2053 g_object_unref (image->data.image.image);
2054 image->data.image.image = NULL;
2056 g_object_notify (G_OBJECT (image), "image");
2060 case GTK_IMAGE_PIXBUF:
2062 if (image->data.pixbuf.pixbuf)
2063 g_object_unref (image->data.pixbuf.pixbuf);
2065 g_object_notify (G_OBJECT (image), "pixbuf");
2069 case GTK_IMAGE_STOCK:
2071 g_free (image->data.stock.stock_id);
2073 image->data.stock.stock_id = NULL;
2075 g_object_notify (G_OBJECT (image), "stock");
2078 case GTK_IMAGE_ICON_SET:
2079 if (image->data.icon_set.icon_set)
2080 gtk_icon_set_unref (image->data.icon_set.icon_set);
2081 image->data.icon_set.icon_set = NULL;
2083 g_object_notify (G_OBJECT (image), "icon-set");
2086 case GTK_IMAGE_ANIMATION:
2087 gtk_image_reset_anim_iter (image);
2089 if (image->data.anim.anim)
2090 g_object_unref (image->data.anim.anim);
2091 image->data.anim.anim = NULL;
2093 g_object_notify (G_OBJECT (image), "pixbuf-animation");
2097 case GTK_IMAGE_ICON_NAME:
2098 g_free (image->data.name.icon_name);
2099 image->data.name.icon_name = NULL;
2100 if (image->data.name.pixbuf)
2101 g_object_unref (image->data.name.pixbuf);
2102 image->data.name.pixbuf = NULL;
2104 g_object_notify (G_OBJECT (image), "icon-name");
2108 case GTK_IMAGE_GICON:
2109 if (image->data.gicon.icon)
2110 g_object_unref (image->data.gicon.icon);
2111 image->data.gicon.icon = NULL;
2112 if (image->data.gicon.pixbuf)
2113 g_object_unref (image->data.gicon.pixbuf);
2114 image->data.gicon.pixbuf = NULL;
2116 g_object_notify (G_OBJECT (image), "gicon");
2120 case GTK_IMAGE_EMPTY:
2128 g_free (priv->filename);
2129 priv->filename = NULL;
2130 g_object_notify (G_OBJECT (image), "file");
2133 image->storage_type = GTK_IMAGE_EMPTY;
2135 memset (&image->data, '\0', sizeof (image->data));
2137 g_object_thaw_notify (G_OBJECT (image));
2142 * @image: a #GtkImage
2144 * Resets the image to be empty.
2149 gtk_image_clear (GtkImage *image)
2151 gtk_image_reset (image);
2153 gtk_image_update_size (image, 0, 0);
2157 gtk_image_calc_size (GtkImage *image)
2159 GtkWidget *widget = GTK_WIDGET (image);
2160 GdkPixbuf *pixbuf = NULL;
2162 /* We update stock/icon set on every size request, because
2163 * the theme could have affected the size; for other kinds of
2164 * image, we just update the requisition when the image data
2167 switch (image->storage_type)
2169 case GTK_IMAGE_STOCK:
2170 pixbuf = gtk_widget_render_icon (widget,
2171 image->data.stock.stock_id,
2176 case GTK_IMAGE_ICON_SET:
2177 pixbuf = gtk_icon_set_render_icon (image->data.icon_set.icon_set,
2179 gtk_widget_get_direction (widget),
2180 GTK_WIDGET_STATE (widget),
2185 case GTK_IMAGE_ICON_NAME:
2186 ensure_pixbuf_for_icon_name (image);
2187 pixbuf = image->data.name.pixbuf;
2188 if (pixbuf) g_object_ref (pixbuf);
2190 case GTK_IMAGE_GICON:
2191 ensure_pixbuf_for_gicon (image);
2192 pixbuf = image->data.gicon.pixbuf;
2194 g_object_ref (pixbuf);
2202 widget->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
2203 widget->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
2205 g_object_unref (pixbuf);
2210 gtk_image_size_request (GtkWidget *widget,
2211 GtkRequisition *requisition)
2215 image = GTK_IMAGE (widget);
2217 gtk_image_calc_size (image);
2219 /* Chain up to default that simply reads current requisition */
2220 GTK_WIDGET_CLASS (gtk_image_parent_class)->size_request (widget, requisition);
2224 gtk_image_style_set (GtkWidget *widget,
2225 GtkStyle *prev_style)
2229 image = GTK_IMAGE (widget);
2231 if (GTK_WIDGET_CLASS (gtk_image_parent_class)->style_set)
2232 GTK_WIDGET_CLASS (gtk_image_parent_class)->style_set (widget, prev_style);
2234 icon_theme_changed (image);
2238 gtk_image_screen_changed (GtkWidget *widget,
2239 GdkScreen *prev_screen)
2243 image = GTK_IMAGE (widget);
2245 if (GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed)
2246 GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed (widget, prev_screen);
2248 icon_theme_changed (image);
2253 gtk_image_update_size (GtkImage *image,
2257 GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
2258 GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
2260 if (GTK_WIDGET_VISIBLE (image))
2261 gtk_widget_queue_resize (GTK_WIDGET (image));
2266 * gtk_image_set_pixel_size:
2267 * @image: a #GtkImage
2268 * @pixel_size: the new pixel size
2270 * Sets the pixel size to use for named icons. If the pixel size is set
2271 * to a value != -1, it is used instead of the icon size set by
2272 * gtk_image_set_from_icon_name().
2277 gtk_image_set_pixel_size (GtkImage *image,
2280 GtkImagePrivate *priv;
2282 g_return_if_fail (GTK_IS_IMAGE (image));
2284 priv = GTK_IMAGE_GET_PRIVATE (image);
2286 if (priv->pixel_size != pixel_size)
2288 priv->pixel_size = pixel_size;
2290 if (image->storage_type == GTK_IMAGE_ICON_NAME)
2292 if (image->data.name.pixbuf)
2294 g_object_unref (image->data.name.pixbuf);
2295 image->data.name.pixbuf = NULL;
2298 gtk_image_update_size (image, pixel_size, pixel_size);
2301 if (image->storage_type == GTK_IMAGE_GICON)
2303 if (image->data.gicon.pixbuf)
2305 g_object_unref (image->data.gicon.pixbuf);
2306 image->data.gicon.pixbuf = NULL;
2309 gtk_image_update_size (image, pixel_size, pixel_size);
2312 g_object_notify (G_OBJECT (image), "pixel-size");
2317 * gtk_image_get_pixel_size:
2318 * @image: a #GtkImage
2320 * Gets the pixel size used for named icons.
2322 * Returns: the pixel size used for named icons.
2327 gtk_image_get_pixel_size (GtkImage *image)
2329 GtkImagePrivate *priv;
2331 g_return_val_if_fail (GTK_IS_IMAGE (image), -1);
2333 priv = GTK_IMAGE_GET_PRIVATE (image);
2335 return priv->pixel_size;
2338 #if defined (G_OS_WIN32) && !defined (_WIN64)
2340 #undef gtk_image_new_from_file
2343 gtk_image_new_from_file (const gchar *filename)
2345 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
2348 retval = gtk_image_new_from_file_utf8 (utf8_filename);
2350 g_free (utf8_filename);
2355 #undef gtk_image_set_from_file
2358 gtk_image_set_from_file (GtkImage *image,
2359 const gchar *filename)
2361 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
2363 gtk_image_set_from_file_utf8 (image, utf8_filename);
2365 g_free (utf8_filename);
2370 #define __GTK_IMAGE_C__
2371 #include "gtkaliasdef.c"