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/.
28 #include "gtkcontainer.h"
30 #include "gtkiconfactory.h"
35 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
37 static void gtk_image_class_init (GtkImageClass *klass);
38 static void gtk_image_init (GtkImage *image);
39 static gint gtk_image_expose (GtkWidget *widget,
40 GdkEventExpose *event);
41 static void gtk_image_unmap (GtkWidget *widget);
42 static void gtk_image_unrealize (GtkWidget *widget);
43 static void gtk_image_size_request (GtkWidget *widget,
44 GtkRequisition *requisition);
45 static void gtk_image_destroy (GtkObject *object);
46 static void gtk_image_clear (GtkImage *image);
47 static void gtk_image_reset (GtkImage *image);
48 static void gtk_image_update_size (GtkImage *image,
52 static void gtk_image_set_property (GObject *object,
56 static void gtk_image_get_property (GObject *object,
61 static gpointer parent_class;
74 PROP_PIXBUF_ANIMATION,
79 gtk_image_get_type (void)
81 static GType image_type = 0;
85 static const GTypeInfo image_info =
87 sizeof (GtkImageClass),
89 NULL, /* base_finalize */
90 (GClassInitFunc) gtk_image_class_init,
91 NULL, /* class_finalize */
92 NULL, /* class_data */
95 (GInstanceInitFunc) gtk_image_init,
98 image_type = g_type_register_static (GTK_TYPE_MISC, "GtkImage",
106 gtk_image_class_init (GtkImageClass *class)
108 GObjectClass *gobject_class;
109 GtkObjectClass *object_class;
110 GtkWidgetClass *widget_class;
112 parent_class = g_type_class_peek_parent (class);
114 gobject_class = G_OBJECT_CLASS (class);
116 gobject_class->set_property = gtk_image_set_property;
117 gobject_class->get_property = gtk_image_get_property;
119 object_class = GTK_OBJECT_CLASS (class);
121 object_class->destroy = gtk_image_destroy;
123 widget_class = GTK_WIDGET_CLASS (class);
125 widget_class->expose_event = gtk_image_expose;
126 widget_class->size_request = gtk_image_size_request;
127 widget_class->unmap = gtk_image_unmap;
128 widget_class->unrealize = gtk_image_unrealize;
130 g_object_class_install_property (gobject_class,
132 g_param_spec_object ("pixbuf",
134 _("A GdkPixbuf to display"),
138 g_object_class_install_property (gobject_class,
140 g_param_spec_object ("pixmap",
142 _("A GdkPixmap to display"),
146 g_object_class_install_property (gobject_class,
148 g_param_spec_object ("image",
150 _("A GdkImage to display"),
154 g_object_class_install_property (gobject_class,
156 g_param_spec_object ("mask",
158 _("Mask bitmap to use with GdkImage or GdkPixmap"),
162 g_object_class_install_property (gobject_class,
164 g_param_spec_string ("file",
166 _("Filename to load and display"),
171 g_object_class_install_property (gobject_class,
173 g_param_spec_string ("stock",
175 _("Stock ID for a stock image to display"),
179 g_object_class_install_property (gobject_class,
181 g_param_spec_boxed ("icon_set",
183 _("Icon set to display"),
187 g_object_class_install_property (gobject_class,
189 g_param_spec_int ("icon_size",
191 _("Size to use for stock icon or icon set"),
196 g_object_class_install_property (gobject_class,
197 PROP_PIXBUF_ANIMATION,
198 g_param_spec_object ("pixbuf_animation",
200 _("GdkPixbufAnimation to display"),
201 GDK_TYPE_PIXBUF_ANIMATION,
204 g_object_class_install_property (gobject_class,
206 g_param_spec_enum ("storage_type",
208 _("The representation being used for image data"),
215 gtk_image_init (GtkImage *image)
217 GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
219 image->storage_type = GTK_IMAGE_EMPTY;
220 image->icon_size = DEFAULT_ICON_SIZE;
225 gtk_image_destroy (GtkObject *object)
227 GtkImage *image = GTK_IMAGE (object);
229 gtk_image_clear (image);
231 GTK_OBJECT_CLASS (parent_class)->destroy (object);
235 gtk_image_set_property (GObject *object,
242 image = GTK_IMAGE (object);
247 gtk_image_set_from_pixbuf (image,
248 g_value_get_object (value));
251 gtk_image_set_from_pixmap (image,
252 g_value_get_object (value),
256 gtk_image_set_from_image (image,
257 g_value_get_object (value),
261 if (image->storage_type == GTK_IMAGE_PIXMAP)
262 gtk_image_set_from_pixmap (image,
263 image->data.pixmap.pixmap,
264 g_value_get_object (value));
265 else if (image->storage_type == GTK_IMAGE_IMAGE)
266 gtk_image_set_from_image (image,
267 image->data.image.image,
268 g_value_get_object (value));
273 mask = g_value_get_object (value);
278 gtk_image_reset (image);
284 gtk_image_set_from_file (image,
285 g_value_get_string (value));
288 gtk_image_set_from_stock (image, g_value_get_string (value),
292 gtk_image_set_from_icon_set (image, g_value_get_boxed (value),
296 if (image->storage_type == GTK_IMAGE_STOCK)
297 gtk_image_set_from_stock (image,
298 image->data.stock.stock_id,
299 g_value_get_int (value));
300 else if (image->storage_type == GTK_IMAGE_ICON_SET)
301 gtk_image_set_from_icon_set (image,
302 image->data.icon_set.icon_set,
303 g_value_get_int (value));
305 /* Save to be used when STOCK or ICON_SET property comes in */
306 image->icon_size = g_value_get_int (value);
308 case PROP_PIXBUF_ANIMATION:
309 gtk_image_set_from_animation (image,
310 g_value_get_object (value));
314 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
320 gtk_image_get_property (GObject *object,
327 image = GTK_IMAGE (object);
329 /* The "getter" functions whine if you try to get the wrong
330 * storage type. This function is instead robust against that,
331 * so that GUI builders don't have to jump through hoops
338 if (image->storage_type != GTK_IMAGE_PIXBUF)
339 g_value_set_object (value, NULL);
341 g_value_set_object (value,
342 gtk_image_get_pixbuf (image));
345 if (image->storage_type != GTK_IMAGE_PIXMAP)
346 g_value_set_object (value, NULL);
348 g_value_set_object (value,
349 image->data.pixmap.pixmap);
352 g_value_set_object (value, image->mask);
355 if (image->storage_type != GTK_IMAGE_IMAGE)
356 g_value_set_object (value, NULL);
358 g_value_set_object (value,
359 image->data.image.image);
362 if (image->storage_type != GTK_IMAGE_STOCK)
363 g_value_set_string (value, NULL);
365 g_value_set_string (value,
366 image->data.stock.stock_id);
369 if (image->storage_type != GTK_IMAGE_ICON_SET)
370 g_value_set_boxed (value, NULL);
372 g_value_set_boxed (value,
373 image->data.icon_set.icon_set);
376 g_value_set_int (value, image->icon_size);
378 case PROP_PIXBUF_ANIMATION:
379 if (image->storage_type != GTK_IMAGE_ANIMATION)
380 g_value_set_object (value, NULL);
382 g_value_set_object (value,
383 image->data.anim.anim);
385 case PROP_STORAGE_TYPE:
386 g_value_set_enum (value, image->storage_type);
390 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
397 * gtk_image_new_from_pixmap:
398 * @pixmap: a #GdkPixmap, or %NULL
399 * @mask: a #GdkBitmap, or %NULL
401 * Creates a #GtkImage widget displaying @pixmap with a @mask.
402 * A #GdkImage is a server-side image buffer in the pixel format of the
403 * current display. The #GtkImage does not assume a reference to the
404 * pixmap or mask; you still need to unref them if you own references.
405 * #GtkImage will add its own reference rather than adopting yours.
407 * Return value: a new #GtkImage
410 gtk_image_new_from_pixmap (GdkPixmap *pixmap,
415 image = g_object_new (GTK_TYPE_IMAGE, NULL);
417 gtk_image_set_from_pixmap (image, pixmap, mask);
419 return GTK_WIDGET (image);
423 * gtk_image_new_from_image:
424 * @image: a #GdkImage, or %NULL
425 * @mask: a #GdkBitmap, or %NULL
427 * Creates a #GtkImage widget displaying a @image with a @mask.
428 * A #GdkImage is a client-side image buffer in the pixel format of the
430 * The #GtkImage does not assume a reference to the
431 * image or mask; you still need to unref them if you own references.
432 * #GtkImage will add its own reference rather than adopting yours.
434 * Return value: a new #GtkImage
437 gtk_image_new_from_image (GdkImage *gdk_image,
442 image = g_object_new (GTK_TYPE_IMAGE, NULL);
444 gtk_image_set_from_image (image, gdk_image, mask);
446 return GTK_WIDGET (image);
450 * gtk_image_new_from_file:
451 * @filename: a filename
453 * Creates a new #GtkImage displaying the file @filename. If the file
454 * isn't found or can't be loaded, the resulting #GtkImage will
455 * display a "broken image" icon. This function never returns %NULL,
456 * it always returns a valid #GtkImage widget.
458 * If the file contains an animation, the image will contain an
461 * If you need to detect failures to load the file, use
462 * gdk_pixbuf_new_from_file() to load the file yourself, then create
463 * the #GtkImage from the pixbuf. (Or for animations, use
464 * gdk_pixbuf_animation_new_from_file()).
466 * The storage type (gtk_image_get_storage_type()) of the returned
467 * image is not defined, it will be whatever is appropriate for
468 * displaying the file.
470 * Return value: a new #GtkImage
473 gtk_image_new_from_file (const gchar *filename)
477 image = g_object_new (GTK_TYPE_IMAGE, NULL);
479 gtk_image_set_from_file (image, filename);
481 return GTK_WIDGET (image);
485 * gtk_image_new_from_pixbuf:
486 * @pixbuf: a #GdkPixbuf, or %NULL
488 * Creates a new #GtkImage displaying @pixbuf.
489 * The #GtkImage does not assume a reference to the
490 * pixbuf; you still need to unref it if you own references.
491 * #GtkImage will add its own reference rather than adopting yours.
493 * Note that this function just creates an #GtkImage from the pixbuf. The
494 * #GtkImage created will not react to state changes. Should you want that, you
495 * should use gtk_image_new_from_icon_set().
497 * Return value: a new #GtkImage
500 gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
504 image = g_object_new (GTK_TYPE_IMAGE, NULL);
506 gtk_image_set_from_pixbuf (image, pixbuf);
508 return GTK_WIDGET (image);
512 * gtk_image_new_from_stock:
513 * @stock_id: a stock icon name
514 * @size: a stock icon size
516 * Creates a #GtkImage displaying a stock icon. Sample stock icon
517 * names are #GTK_STOCK_OPEN, #GTK_STOCK_EXIT. Sample stock sizes
518 * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
519 * icon name isn't known, a "broken image" icon will be displayed instead.
520 * You can register your own stock icon names, see
521 * gtk_icon_factory_add_default() and gtk_icon_factory_add().
523 * Return value: a new #GtkImage displaying the stock icon
526 gtk_image_new_from_stock (const gchar *stock_id,
531 image = g_object_new (GTK_TYPE_IMAGE, NULL);
533 gtk_image_set_from_stock (image, stock_id, size);
535 return GTK_WIDGET (image);
539 * gtk_image_new_from_icon_set:
540 * @icon_set: a #GtkIconSet
541 * @size: a stock icon size
543 * Creates a #GtkImage displaying an icon set. Sample stock sizes are
544 * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. Instead of using
545 * this function, usually it's better to create a #GtkIconFactory, put
546 * your icon sets in the icon factory, add the icon factory to the
547 * list of default factories with gtk_icon_factory_add_default(), and
548 * then use gtk_image_new_from_stock(). This will allow themes to
549 * override the icon you ship with your application.
551 * The #GtkImage does not assume a reference to the
552 * icon set; you still need to unref it if you own references.
553 * #GtkImage will add its own reference rather than adopting yours.
556 * Return value: a new #GtkImage
559 gtk_image_new_from_icon_set (GtkIconSet *icon_set,
564 image = g_object_new (GTK_TYPE_IMAGE, NULL);
566 gtk_image_set_from_icon_set (image, icon_set, size);
568 return GTK_WIDGET (image);
572 * gtk_image_new_from_animation:
573 * @animation: an animation
575 * Creates a #GtkImage displaying the given animation.
576 * The #GtkImage does not assume a reference to the
577 * animation; you still need to unref it if you own references.
578 * #GtkImage will add its own reference rather than adopting yours.
580 * Return value: a new #GtkImage widget
583 gtk_image_new_from_animation (GdkPixbufAnimation *animation)
587 g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
589 image = g_object_new (GTK_TYPE_IMAGE, NULL);
591 gtk_image_set_from_animation (image, animation);
593 return GTK_WIDGET (image);
597 * gtk_image_set_from_pixmap:
598 * @image: a #GtkImage
599 * @pixmap: a #GdkPixmap or %NULL
600 * @mask: a #GdkBitmap or %NULL
602 * See gtk_image_new_from_pixmap() for details.
606 gtk_image_set_from_pixmap (GtkImage *image,
610 g_return_if_fail (GTK_IS_IMAGE (image));
611 g_return_if_fail (pixmap == NULL ||
612 GDK_IS_PIXMAP (pixmap));
613 g_return_if_fail (mask == NULL ||
614 GDK_IS_PIXMAP (mask));
616 g_object_freeze_notify (G_OBJECT (image));
619 g_object_ref (pixmap);
624 gtk_image_reset (image);
633 image->storage_type = GTK_IMAGE_PIXMAP;
635 image->data.pixmap.pixmap = pixmap;
637 gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
639 gtk_image_update_size (image, width, height);
642 g_object_notify (G_OBJECT (image), "pixmap");
643 g_object_notify (G_OBJECT (image), "mask");
645 g_object_thaw_notify (G_OBJECT (image));
649 * gtk_image_set_from_image:
650 * @image: a #GtkImage
651 * @gdk_image: a #GdkImage or %NULL
652 * @mask: a #GdkBitmap or %NULL
654 * See gtk_image_new_from_image() for details.
658 gtk_image_set_from_image (GtkImage *image,
662 g_return_if_fail (GTK_IS_IMAGE (image));
663 g_return_if_fail (gdk_image == NULL ||
664 GDK_IS_IMAGE (gdk_image));
665 g_return_if_fail (mask == NULL ||
666 GDK_IS_PIXMAP (mask));
668 g_object_freeze_notify (G_OBJECT (image));
671 g_object_ref (gdk_image);
676 gtk_image_reset (image);
680 image->storage_type = GTK_IMAGE_IMAGE;
682 image->data.image.image = gdk_image;
685 gtk_image_update_size (image, gdk_image->width, gdk_image->height);
689 /* Clean up the mask if gdk_image was NULL */
691 g_object_unref (mask);
694 g_object_notify (G_OBJECT (image), "image");
695 g_object_notify (G_OBJECT (image), "mask");
697 g_object_thaw_notify (G_OBJECT (image));
701 * gtk_image_set_from_file:
702 * @image: a #GtkImage
703 * @filename: a filename or %NULL
705 * See gtk_image_new_from_file() for details.
709 gtk_image_set_from_file (GtkImage *image,
710 const gchar *filename)
712 GdkPixbufAnimation *anim;
714 g_return_if_fail (GTK_IS_IMAGE (image));
716 g_object_freeze_notify (G_OBJECT (image));
718 gtk_image_reset (image);
720 if (filename == NULL)
722 g_object_thaw_notify (G_OBJECT (image));
726 anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
730 gtk_image_set_from_stock (image,
731 GTK_STOCK_MISSING_IMAGE,
732 GTK_ICON_SIZE_BUTTON);
733 g_object_thaw_notify (G_OBJECT (image));
737 /* We could just unconditionally set_from_animation,
738 * but it's nicer for memory if we toss the animation
739 * if it's just a single pixbuf
742 if (gdk_pixbuf_animation_is_static_image (anim))
744 gtk_image_set_from_pixbuf (image,
745 gdk_pixbuf_animation_get_static_image (anim));
749 gtk_image_set_from_animation (image, anim);
752 g_object_unref (anim);
754 g_object_thaw_notify (G_OBJECT (image));
758 * gtk_image_set_from_pixbuf:
759 * @image: a #GtkImage
760 * @pixbuf: a #GdkPixbuf or %NULL
762 * See gtk_image_new_from_pixbuf() for details.
766 gtk_image_set_from_pixbuf (GtkImage *image,
769 g_return_if_fail (GTK_IS_IMAGE (image));
770 g_return_if_fail (pixbuf == NULL ||
771 GDK_IS_PIXBUF (pixbuf));
773 g_object_freeze_notify (G_OBJECT (image));
776 g_object_ref (pixbuf);
778 gtk_image_reset (image);
782 image->storage_type = GTK_IMAGE_PIXBUF;
784 image->data.pixbuf.pixbuf = pixbuf;
786 gtk_image_update_size (image,
787 gdk_pixbuf_get_width (pixbuf),
788 gdk_pixbuf_get_height (pixbuf));
791 g_object_notify (G_OBJECT (image), "pixbuf");
793 g_object_thaw_notify (G_OBJECT (image));
797 * gtk_image_set_from_stock:
798 * @image: a #GtkImage
799 * @stock_id: a stock icon name
800 * @size: a stock icon size
802 * See gtk_image_new_from_stock() for details.
806 gtk_image_set_from_stock (GtkImage *image,
807 const gchar *stock_id,
812 g_return_if_fail (GTK_IS_IMAGE (image));
814 g_object_freeze_notify (G_OBJECT (image));
816 /* in case stock_id == image->data.stock.stock_id */
817 new_id = g_strdup (stock_id);
819 gtk_image_reset (image);
823 image->storage_type = GTK_IMAGE_STOCK;
825 image->data.stock.stock_id = new_id;
826 image->icon_size = size;
828 /* Size is demand-computed in size request method
829 * if we're a stock image, since changing the
830 * style impacts the size request
834 g_object_notify (G_OBJECT (image), "stock");
835 g_object_notify (G_OBJECT (image), "icon_size");
837 g_object_thaw_notify (G_OBJECT (image));
841 * gtk_image_set_from_icon_set:
842 * @image: a #GtkImage
843 * @icon_set: a #GtkIconSet
844 * @size: a stock icon size
846 * See gtk_image_new_from_icon_set() for details.
850 gtk_image_set_from_icon_set (GtkImage *image,
851 GtkIconSet *icon_set,
854 g_return_if_fail (GTK_IS_IMAGE (image));
856 g_object_freeze_notify (G_OBJECT (image));
859 gtk_icon_set_ref (icon_set);
861 gtk_image_reset (image);
865 image->storage_type = GTK_IMAGE_ICON_SET;
867 image->data.icon_set.icon_set = icon_set;
868 image->icon_size = size;
870 /* Size is demand-computed in size request method
871 * if we're an icon set
875 g_object_notify (G_OBJECT (image), "icon_set");
876 g_object_notify (G_OBJECT (image), "icon_size");
878 g_object_thaw_notify (G_OBJECT (image));
882 * gtk_image_set_from_animation:
883 * @image: a #GtkImage
884 * @animation: the #GdkPixbufAnimation
886 * Causes the #GtkImage to display the given animation (or display
887 * nothing, if you set the animation to %NULL).
890 gtk_image_set_from_animation (GtkImage *image,
891 GdkPixbufAnimation *animation)
893 g_return_if_fail (GTK_IS_IMAGE (image));
894 g_return_if_fail (animation == NULL ||
895 GDK_IS_PIXBUF_ANIMATION (animation));
897 g_object_freeze_notify (G_OBJECT (image));
900 g_object_ref (animation);
902 gtk_image_reset (image);
904 if (animation != NULL)
906 image->storage_type = GTK_IMAGE_ANIMATION;
908 image->data.anim.anim = animation;
909 image->data.anim.frame_timeout = 0;
910 image->data.anim.iter = NULL;
912 gtk_image_update_size (image,
913 gdk_pixbuf_animation_get_width (animation),
914 gdk_pixbuf_animation_get_height (animation));
917 g_object_notify (G_OBJECT (image), "pixbuf_animation");
919 g_object_thaw_notify (G_OBJECT (image));
923 * gtk_image_get_storage_type:
924 * @image: a #GtkImage
926 * Gets the type of representation being used by the #GtkImage
927 * to store image data. If the #GtkImage has no image data,
928 * the return value will be %GTK_IMAGE_EMPTY.
930 * Return value: image representation being used
933 gtk_image_get_storage_type (GtkImage *image)
935 g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);
937 return image->storage_type;
941 * gtk_image_get_pixmap:
942 * @image: a #GtkImage
943 * @pixmap: location to store the pixmap, or %NULL
944 * @mask: location to store the mask, or %NULL
946 * Gets the pixmap and mask being displayed by the #GtkImage.
947 * The storage type of the image must be %GTK_IMAGE_EMPTY or
948 * %GTK_IMAGE_PIXMAP (see gtk_image_get_storage_type()).
949 * The caller of this function does not own a reference to the
950 * returned pixmap and mask.
954 gtk_image_get_pixmap (GtkImage *image,
958 g_return_if_fail (GTK_IS_IMAGE (image));
959 g_return_if_fail (image->storage_type == GTK_IMAGE_PIXMAP ||
960 image->storage_type == GTK_IMAGE_EMPTY);
963 *pixmap = image->data.pixmap.pixmap;
970 * gtk_image_get_image:
971 * @image: a #GtkImage
972 * @gdk_image: return location for a #GtkImage
973 * @mask: return location for a #GdkBitmap
975 * Gets the #GdkImage and mask being displayed by the #GtkImage.
976 * The storage type of the image must be %GTK_IMAGE_EMPTY or
977 * %GTK_IMAGE_IMAGE (see gtk_image_get_storage_type()).
978 * The caller of this function does not own a reference to the
979 * returned image and mask.
982 gtk_image_get_image (GtkImage *image,
983 GdkImage **gdk_image,
986 g_return_if_fail (GTK_IS_IMAGE (image));
987 g_return_if_fail (image->storage_type == GTK_IMAGE_IMAGE ||
988 image->storage_type == GTK_IMAGE_EMPTY);
991 *gdk_image = image->data.image.image;
998 * gtk_image_get_pixbuf:
999 * @image: a #GtkImage
1002 * Gets the #GdkPixbuf being displayed by the #GtkImage.
1003 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1004 * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
1005 * The caller of this function does not own a reference to the
1008 * Return value: the displayed pixbuf, or %NULL if the image is empty
1011 gtk_image_get_pixbuf (GtkImage *image)
1013 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1014 g_return_val_if_fail (image->storage_type == GTK_IMAGE_PIXBUF ||
1015 image->storage_type == GTK_IMAGE_EMPTY, NULL);
1017 if (image->storage_type == GTK_IMAGE_EMPTY)
1018 image->data.pixbuf.pixbuf = NULL;
1020 return image->data.pixbuf.pixbuf;
1024 * gtk_image_get_stock:
1025 * @image: a #GtkImage
1026 * @stock_id: place to store a stock icon name
1027 * @size: place to store a stock icon size
1029 * Gets the stock icon name and size being displayed by the #GtkImage.
1030 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1031 * %GTK_IMAGE_STOCK (see gtk_image_get_storage_type()).
1032 * The returned string is owned by the #GtkImage and should not
1037 gtk_image_get_stock (GtkImage *image,
1041 g_return_if_fail (GTK_IS_IMAGE (image));
1042 g_return_if_fail (image->storage_type == GTK_IMAGE_STOCK ||
1043 image->storage_type == GTK_IMAGE_EMPTY);
1045 if (image->storage_type == GTK_IMAGE_EMPTY)
1046 image->data.stock.stock_id = NULL;
1049 *stock_id = image->data.stock.stock_id;
1052 *size = image->icon_size;
1056 * gtk_image_get_icon_set:
1057 * @image: a #GtkImage
1058 * @icon_set: location to store a #GtkIconSet
1059 * @size: location to store a stock icon size
1061 * Gets the icon set and size being displayed by the #GtkImage.
1062 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1063 * %GTK_IMAGE_ICON_SET (see gtk_image_get_storage_type()).
1067 gtk_image_get_icon_set (GtkImage *image,
1068 GtkIconSet **icon_set,
1071 g_return_if_fail (GTK_IS_IMAGE (image));
1072 g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_SET ||
1073 image->storage_type == GTK_IMAGE_EMPTY);
1076 *icon_set = image->data.icon_set.icon_set;
1079 *size = image->icon_size;
1083 * gtk_image_get_animation:
1084 * @image: a #GtkImage
1087 * Gets the #GdkPixbufAnimation being displayed by the #GtkImage.
1088 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1089 * %GTK_IMAGE_ANIMATION (see gtk_image_get_storage_type()).
1090 * The caller of this function does not own a reference to the
1091 * returned animation.
1093 * Return value: the displayed animation, or %NULL if the image is empty
1096 gtk_image_get_animation (GtkImage *image)
1098 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1099 g_return_val_if_fail (image->storage_type == GTK_IMAGE_ANIMATION ||
1100 image->storage_type == GTK_IMAGE_EMPTY,
1103 if (image->storage_type == GTK_IMAGE_EMPTY)
1104 image->data.anim.anim = NULL;
1106 return image->data.anim.anim;
1112 * Creates a new empty #GtkImage widget.
1114 * Return value: a newly created #GtkImage widget.
1117 gtk_image_new (void)
1119 return g_object_new (GTK_TYPE_IMAGE, NULL);
1123 gtk_image_set (GtkImage *image,
1127 g_return_if_fail (GTK_IS_IMAGE (image));
1129 gtk_image_set_from_image (image, val, mask);
1133 gtk_image_get (GtkImage *image,
1137 g_return_if_fail (GTK_IS_IMAGE (image));
1139 gtk_image_get_image (image, val, mask);
1143 gtk_image_reset_anim_iter (GtkImage *image)
1145 if (image->storage_type == GTK_IMAGE_ANIMATION)
1147 /* Reset the animation */
1149 if (image->data.anim.frame_timeout)
1151 g_source_remove (image->data.anim.frame_timeout);
1152 image->data.anim.frame_timeout = 0;
1155 if (image->data.anim.iter)
1157 g_object_unref (image->data.anim.iter);
1158 image->data.anim.iter = NULL;
1164 gtk_image_unmap (GtkWidget *widget)
1166 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1168 if (GTK_WIDGET_CLASS (parent_class)->unmap)
1169 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
1173 gtk_image_unrealize (GtkWidget *widget)
1175 gtk_image_reset_anim_iter (GTK_IMAGE (widget));
1177 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
1178 GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
1182 animation_timeout (gpointer data)
1186 GDK_THREADS_ENTER ();
1188 image = GTK_IMAGE (data);
1190 image->data.anim.frame_timeout = 0;
1192 gdk_pixbuf_animation_iter_advance (image->data.anim.iter, NULL);
1194 if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
1195 image->data.anim.frame_timeout =
1196 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
1200 gtk_widget_queue_draw (GTK_WIDGET (image));
1202 GDK_THREADS_LEAVE ();
1208 gtk_image_expose (GtkWidget *widget,
1209 GdkEventExpose *event)
1211 g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
1212 g_return_val_if_fail (event != NULL, FALSE);
1214 if (GTK_WIDGET_MAPPED (widget) &&
1215 GTK_IMAGE (widget)->storage_type != GTK_IMAGE_EMPTY)
1219 GdkRectangle area, image_bound;
1224 gboolean needs_state_transform;
1226 image = GTK_IMAGE (widget);
1227 misc = GTK_MISC (widget);
1231 if (!gdk_rectangle_intersect (&area, &widget->allocation, &area))
1234 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1235 xalign = misc->xalign;
1237 xalign = 1.0 - misc->xalign;
1239 x = floor (widget->allocation.x + misc->xpad
1240 + ((widget->allocation.width - widget->requisition.width) * xalign)
1242 y = floor (widget->allocation.y + misc->ypad
1243 + ((widget->allocation.height - widget->requisition.height) * misc->yalign)
1248 image_bound.width = 0;
1249 image_bound.height = 0;
1253 needs_state_transform = GTK_WIDGET_STATE (widget) != GTK_STATE_NORMAL;
1255 switch (image->storage_type)
1257 case GTK_IMAGE_PIXMAP:
1259 gdk_drawable_get_size (image->data.pixmap.pixmap,
1261 &image_bound.height);
1263 if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
1264 needs_state_transform)
1266 pixbuf = gdk_pixbuf_get_from_drawable (NULL,
1267 image->data.pixmap.pixmap,
1268 gtk_widget_get_colormap (widget),
1269 image_bound.x - x, image_bound.y - y,
1272 image_bound.height);
1280 case GTK_IMAGE_IMAGE:
1282 image_bound.width = image->data.image.image->width;
1283 image_bound.height = image->data.image.image->height;
1285 if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
1286 needs_state_transform)
1288 pixbuf = gdk_pixbuf_get_from_image (NULL,
1289 image->data.image.image,
1290 gtk_widget_get_colormap (widget),
1291 image_bound.x - x, image_bound.y - y,
1294 image_bound.height);
1301 case GTK_IMAGE_PIXBUF:
1302 image_bound.width = gdk_pixbuf_get_width (image->data.pixbuf.pixbuf);
1303 image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);
1305 if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
1306 needs_state_transform)
1308 pixbuf = gdk_pixbuf_new_subpixbuf (image->data.pixbuf.pixbuf,
1309 image_bound.x - x, image_bound.y - y,
1310 image_bound.width, image_bound.height);
1317 pixbuf = image->data.pixbuf.pixbuf;
1318 g_object_ref (pixbuf);
1322 case GTK_IMAGE_STOCK:
1323 pixbuf = gtk_widget_render_icon (widget,
1324 image->data.stock.stock_id,
1329 image_bound.width = gdk_pixbuf_get_width (pixbuf);
1330 image_bound.height = gdk_pixbuf_get_height (pixbuf);
1334 needs_state_transform = FALSE;
1337 case GTK_IMAGE_ICON_SET:
1339 gtk_icon_set_render_icon (image->data.icon_set.icon_set,
1341 gtk_widget_get_direction (widget),
1342 GTK_WIDGET_STATE (widget),
1349 image_bound.width = gdk_pixbuf_get_width (pixbuf);
1350 image_bound.height = gdk_pixbuf_get_height (pixbuf);
1354 needs_state_transform = FALSE;
1357 case GTK_IMAGE_ANIMATION:
1359 if (image->data.anim.iter == NULL)
1361 image->data.anim.iter = gdk_pixbuf_animation_get_iter (image->data.anim.anim, NULL);
1363 if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
1364 image->data.anim.frame_timeout =
1365 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
1370 image_bound.width = gdk_pixbuf_animation_get_width (image->data.anim.anim);
1371 image_bound.height = gdk_pixbuf_animation_get_height (image->data.anim.anim);
1373 /* don't advance the anim iter here, or we could get frame changes between two
1374 * exposes of different areas.
1377 pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter);
1378 g_object_ref (pixbuf);
1382 case GTK_IMAGE_EMPTY:
1383 g_assert_not_reached ();
1389 gdk_gc_set_clip_mask (widget->style->black_gc, mask);
1390 gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
1393 if (gdk_rectangle_intersect (&image_bound, &area, &image_bound))
1397 if (needs_state_transform)
1399 GtkIconSource *source;
1400 GdkPixbuf *rendered;
1402 source = gtk_icon_source_new ();
1403 gtk_icon_source_set_pixbuf (source, pixbuf);
1404 /* The size here is arbitrary; since size isn't
1405 * wildcarded in the souce, it isn't supposed to be
1406 * scaled by the engine function
1408 gtk_icon_source_set_size (source,
1409 GTK_ICON_SIZE_SMALL_TOOLBAR);
1410 gtk_icon_source_set_size_wildcarded (source, FALSE);
1412 rendered = gtk_style_render_icon (widget->style,
1414 gtk_widget_get_direction (widget),
1415 GTK_WIDGET_STATE (widget),
1421 gtk_icon_source_free (source);
1423 g_object_unref (pixbuf);
1429 gdk_draw_pixbuf (widget->window,
1430 widget->style->black_gc,
1438 GDK_RGB_DITHER_NORMAL,
1441 g_object_unref (pixbuf);
1447 switch (image->storage_type)
1449 case GTK_IMAGE_PIXMAP:
1450 gdk_draw_drawable (widget->window,
1451 widget->style->black_gc,
1452 image->data.pixmap.pixmap,
1453 image_bound.x - x, image_bound.y - y,
1454 image_bound.x, image_bound.y,
1455 image_bound.width, image_bound.height);
1458 case GTK_IMAGE_IMAGE:
1459 gdk_draw_image (widget->window,
1460 widget->style->black_gc,
1461 image->data.image.image,
1462 image_bound.x - x, image_bound.y - y,
1463 image_bound.x, image_bound.y,
1464 image_bound.width, image_bound.height);
1467 case GTK_IMAGE_PIXBUF:
1468 case GTK_IMAGE_STOCK:
1469 case GTK_IMAGE_ICON_SET:
1470 case GTK_IMAGE_ANIMATION:
1471 case GTK_IMAGE_EMPTY:
1472 g_assert_not_reached ();
1476 } /* if rectangle intersects */
1480 gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
1481 gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
1484 } /* if widget is drawable */
1490 gtk_image_clear (GtkImage *image)
1492 g_object_freeze_notify (G_OBJECT (image));
1494 if (image->storage_type != GTK_IMAGE_EMPTY)
1495 g_object_notify (G_OBJECT (image), "storage_type");
1499 g_object_unref (image->mask);
1501 g_object_notify (G_OBJECT (image), "mask");
1504 if (image->icon_size != DEFAULT_ICON_SIZE)
1506 image->icon_size = DEFAULT_ICON_SIZE;
1507 g_object_notify (G_OBJECT (image), "icon_size");
1510 switch (image->storage_type)
1512 case GTK_IMAGE_PIXMAP:
1514 if (image->data.pixmap.pixmap)
1515 g_object_unref (image->data.pixmap.pixmap);
1516 image->data.pixmap.pixmap = NULL;
1518 g_object_notify (G_OBJECT (image), "pixmap");
1522 case GTK_IMAGE_IMAGE:
1524 if (image->data.image.image)
1525 g_object_unref (image->data.image.image);
1526 image->data.image.image = NULL;
1528 g_object_notify (G_OBJECT (image), "image");
1532 case GTK_IMAGE_PIXBUF:
1534 if (image->data.pixbuf.pixbuf)
1535 g_object_unref (image->data.pixbuf.pixbuf);
1537 g_object_notify (G_OBJECT (image), "pixbuf");
1541 case GTK_IMAGE_STOCK:
1543 g_free (image->data.stock.stock_id);
1545 image->data.stock.stock_id = NULL;
1547 g_object_notify (G_OBJECT (image), "stock");
1550 case GTK_IMAGE_ICON_SET:
1551 if (image->data.icon_set.icon_set)
1552 gtk_icon_set_unref (image->data.icon_set.icon_set);
1553 image->data.icon_set.icon_set = NULL;
1555 g_object_notify (G_OBJECT (image), "icon_set");
1558 case GTK_IMAGE_ANIMATION:
1559 if (image->data.anim.frame_timeout)
1560 g_source_remove (image->data.anim.frame_timeout);
1562 if (image->data.anim.anim)
1563 g_object_unref (image->data.anim.anim);
1565 image->data.anim.frame_timeout = 0;
1566 image->data.anim.anim = NULL;
1568 g_object_notify (G_OBJECT (image), "pixbuf_animation");
1572 case GTK_IMAGE_EMPTY:
1578 image->storage_type = GTK_IMAGE_EMPTY;
1580 memset (&image->data, '\0', sizeof (image->data));
1582 g_object_thaw_notify (G_OBJECT (image));
1586 gtk_image_reset (GtkImage *image)
1588 gtk_image_clear (image);
1590 gtk_image_update_size (image, 0, 0);
1594 gtk_image_size_request (GtkWidget *widget,
1595 GtkRequisition *requisition)
1598 GdkPixbuf *pixbuf = NULL;
1600 image = GTK_IMAGE (widget);
1602 /* We update stock/icon set on every size request, because
1603 * the theme could have affected the size; for other kinds of
1604 * image, we just update the requisition when the image data
1608 switch (image->storage_type)
1610 case GTK_IMAGE_STOCK:
1611 pixbuf = gtk_widget_render_icon (GTK_WIDGET (image),
1612 image->data.stock.stock_id,
1617 case GTK_IMAGE_ICON_SET:
1618 pixbuf = gtk_icon_set_render_icon (image->data.icon_set.icon_set,
1620 gtk_widget_get_direction (widget),
1621 GTK_WIDGET_STATE (widget),
1633 GTK_WIDGET (image)->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
1634 GTK_WIDGET (image)->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
1636 g_object_unref (pixbuf);
1639 /* Chain up to default that simply reads current requisition */
1640 GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
1644 gtk_image_update_size (GtkImage *image,
1648 GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
1649 GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
1651 if (GTK_WIDGET_VISIBLE (image))
1652 gtk_widget_queue_resize (GTK_WIDGET (image));