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/.
27 #include "gtkcontainer.h"
29 #include "gtkiconfactory.h"
34 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
36 static void gtk_image_class_init (GtkImageClass *klass);
37 static void gtk_image_init (GtkImage *image);
38 static gint gtk_image_expose (GtkWidget *widget,
39 GdkEventExpose *event);
40 static void gtk_image_unmap (GtkWidget *widget);
41 static void gtk_image_size_request (GtkWidget *widget,
42 GtkRequisition *requisition);
43 static void gtk_image_destroy (GtkObject *object);
44 static void gtk_image_clear (GtkImage *image);
45 static void gtk_image_reset (GtkImage *image);
46 static void gtk_image_update_size (GtkImage *image,
50 static void gtk_image_set_property (GObject *object,
54 static void gtk_image_get_property (GObject *object,
59 static gpointer parent_class;
72 PROP_PIXBUF_ANIMATION,
77 gtk_image_get_type (void)
79 static GtkType image_type = 0;
83 static const GtkTypeInfo image_info =
87 sizeof (GtkImageClass),
88 (GtkClassInitFunc) gtk_image_class_init,
89 (GtkObjectInitFunc) gtk_image_init,
90 /* reserved_1 */ NULL,
91 /* reserved_2 */ NULL,
92 (GtkClassInitFunc) NULL,
95 image_type = gtk_type_unique (GTK_TYPE_MISC, &image_info);
102 gtk_image_class_init (GtkImageClass *class)
104 GObjectClass *gobject_class;
105 GtkObjectClass *object_class;
106 GtkWidgetClass *widget_class;
108 parent_class = g_type_class_peek_parent (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;
125 g_object_class_install_property (gobject_class,
127 g_param_spec_object ("pixbuf",
129 _("A GdkPixbuf to display."),
133 g_object_class_install_property (gobject_class,
135 g_param_spec_object ("pixmap",
137 _("A GdkPixmap to display."),
141 g_object_class_install_property (gobject_class,
143 g_param_spec_object ("image",
145 _("A GdkImage to display."),
149 g_object_class_install_property (gobject_class,
151 g_param_spec_object ("mask",
153 _("Mask bitmap to use with GdkImage or GdkPixmap"),
157 g_object_class_install_property (gobject_class,
159 g_param_spec_string ("file",
161 _("Filename to load and siplay."),
166 g_object_class_install_property (gobject_class,
168 g_param_spec_string ("stock",
170 _("Stock ID for a stock image to display."),
174 g_object_class_install_property (gobject_class,
176 g_param_spec_boxed ("icon_set",
178 _("Icon set to display."),
182 g_object_class_install_property (gobject_class,
184 g_param_spec_int ("icon_size",
186 _("Size to use for stock icon or icon set."),
191 g_object_class_install_property (gobject_class,
192 PROP_PIXBUF_ANIMATION,
193 g_param_spec_object ("pixbuf_animation",
195 _("GdkPixbufAnimation to display."),
196 GDK_TYPE_PIXBUF_ANIMATION,
199 g_object_class_install_property (gobject_class,
201 g_param_spec_enum ("storage_type",
203 _("The representation being used for image data."),
210 gtk_image_init (GtkImage *image)
212 GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
214 image->storage_type = GTK_IMAGE_EMPTY;
215 image->icon_size = DEFAULT_ICON_SIZE;
220 gtk_image_destroy (GtkObject *object)
222 GtkImage *image = GTK_IMAGE (object);
224 gtk_image_clear (image);
226 GTK_OBJECT_CLASS (parent_class)->destroy (object);
230 gtk_image_set_property (GObject *object,
237 image = GTK_IMAGE (object);
242 gtk_image_set_from_pixbuf (image,
243 g_value_get_object (value));
246 gtk_image_set_from_pixmap (image,
247 g_value_get_object (value),
251 gtk_image_set_from_image (image,
252 g_value_get_object (value),
256 if (image->storage_type == GTK_IMAGE_PIXMAP)
257 gtk_image_set_from_pixmap (image,
258 image->data.pixmap.pixmap,
259 g_value_get_object (value));
260 else if (image->storage_type == GTK_IMAGE_IMAGE)
261 gtk_image_set_from_image (image,
262 image->data.image.image,
263 g_value_get_object (value));
268 mask = g_value_get_object (value);
271 g_object_ref (G_OBJECT (mask));
273 gtk_image_reset (image);
279 gtk_image_set_from_file (image,
280 g_value_get_string (value));
283 gtk_image_set_from_stock (image, g_value_get_string (value),
287 gtk_image_set_from_icon_set (image, g_value_get_boxed (value),
291 if (image->storage_type == GTK_IMAGE_STOCK)
292 gtk_image_set_from_stock (image,
293 image->data.stock.stock_id,
294 g_value_get_int (value));
295 else if (image->storage_type == GTK_IMAGE_ICON_SET)
296 gtk_image_set_from_icon_set (image,
297 image->data.icon_set.icon_set,
298 g_value_get_int (value));
300 /* Save to be used when STOCK or ICON_SET property comes in */
301 image->icon_size = g_value_get_int (value);
303 case PROP_PIXBUF_ANIMATION:
304 gtk_image_set_from_animation (image,
305 g_value_get_object (value));
309 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
315 gtk_image_get_property (GObject *object,
322 image = GTK_IMAGE (object);
324 /* The "getter" functions whine if you try to get the wrong
325 * storage type. This function is instead robust against that,
326 * so that GUI builders don't have to jump through hoops
333 if (image->storage_type != GTK_IMAGE_PIXBUF)
334 g_value_set_object (value, NULL);
336 g_value_set_object (value,
337 gtk_image_get_pixbuf (image));
340 if (image->storage_type != GTK_IMAGE_PIXMAP)
341 g_value_set_object (value, NULL);
343 g_value_set_object (value,
344 image->data.pixmap.pixmap);
347 g_value_set_object (value, image->mask);
350 if (image->storage_type != GTK_IMAGE_IMAGE)
351 g_value_set_object (value, NULL);
353 g_value_set_object (value,
354 image->data.image.image);
357 if (image->storage_type != GTK_IMAGE_STOCK)
358 g_value_set_string (value, NULL);
360 g_value_set_string (value,
361 image->data.stock.stock_id);
364 if (image->storage_type != GTK_IMAGE_ICON_SET)
365 g_value_set_boxed (value, NULL);
367 g_value_set_boxed (value,
368 image->data.icon_set.icon_set);
371 g_value_set_int (value, image->icon_size);
373 case PROP_PIXBUF_ANIMATION:
374 if (image->storage_type != GTK_IMAGE_ANIMATION)
375 g_value_set_object (value, NULL);
377 g_value_set_object (value,
378 image->data.anim.anim);
380 case PROP_STORAGE_TYPE:
381 g_value_set_enum (value, image->storage_type);
385 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
392 * gtk_image_new_from_pixmap:
393 * @pixmap: a #GdkPixmap, or %NULL
394 * @mask: a #GdkBitmap, or %NULL
396 * Creates a #GtkImage widget displaying @pixmap with a @mask.
397 * A #GdkImage is a server-side image buffer in the pixel format of the
398 * current display. The #GtkImage does not assume a reference to the
399 * pixmap or mask; you still need to unref them if you own references.
400 * #GtkImage will add its own reference rather than adopting yours.
402 * Return value: a new #GtkImage
405 gtk_image_new_from_pixmap (GdkPixmap *pixmap,
410 image = gtk_type_new (GTK_TYPE_IMAGE);
412 gtk_image_set_from_pixmap (image, pixmap, mask);
414 return GTK_WIDGET (image);
418 * gtk_image_new_from_image:
419 * @image: a #GdkImage, or %NULL
420 * @mask: a #GdkBitmap, or %NULL
422 * Creates a #GtkImage widget displaying a @image with a @mask.
423 * A #GdkImage is a client-side image buffer in the pixel format of the
425 * The #GtkImage does not assume a reference to the
426 * image or mask; you still need to unref them if you own references.
427 * #GtkImage will add its own reference rather than adopting yours.
429 * Return value: a new #GtkImage
432 gtk_image_new_from_image (GdkImage *gdk_image,
437 image = gtk_type_new (GTK_TYPE_IMAGE);
439 gtk_image_set_from_image (image, gdk_image, mask);
441 return GTK_WIDGET (image);
445 * gtk_image_new_from_file:
446 * @filename: a filename
448 * Creates a new #GtkImage displaying the file @filename. If the file
449 * isn't found or can't be loaded, the resulting #GtkImage will
450 * display a "broken image" icon. This function never returns %NULL,
451 * it always returns a valid #GtkImage widget.
453 * If the file contains an animation, the image will contain an
456 * If you need to detect failures to load the file, use
457 * gdk_pixbuf_new_from_file() to load the file yourself, then create
458 * the #GtkImage from the pixbuf. (Or for animations, use
459 * gdk_pixbuf_animation_new_from_file()).
461 * The storage type (gtk_image_get_storage_type()) of the returned
462 * image is not defined, it will be whatever is appropriate for
463 * displaying the file.
465 * Return value: a new #GtkImage
468 gtk_image_new_from_file (const gchar *filename)
472 image = gtk_type_new (GTK_TYPE_IMAGE);
474 gtk_image_set_from_file (image, filename);
476 return GTK_WIDGET (image);
480 * gtk_image_new_from_pixbuf:
481 * @pixbuf: a #GdkPixbuf, or %NULL
483 * Creates a new #GtkImage displaying @pixbuf.
484 * The #GtkImage does not assume a reference to the
485 * pixbuf; you still need to unref it if you own references.
486 * #GtkImage will add its own reference rather than adopting yours.
488 * Note that this function just creates an #GtkImage from the pixbuf. The
489 * #GtkImage created will not react to state changes. Should you want that, you
490 * should use gtk_image_new_from_icon_set().
492 * Return value: a new #GtkImage
495 gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
499 image = gtk_type_new (GTK_TYPE_IMAGE);
501 gtk_image_set_from_pixbuf (image, pixbuf);
503 return GTK_WIDGET (image);
507 * gtk_image_new_from_stock:
508 * @stock_id: a stock icon name
509 * @size: a stock icon size
511 * Creates a #GtkImage displaying a stock icon. Sample stock icon
512 * names are #GTK_STOCK_OPEN, #GTK_STOCK_EXIT. Sample stock sizes
513 * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
514 * icon name isn't known, a "broken image" icon will be displayed instead.
515 * You can register your own stock icon names, see
516 * gtk_icon_factory_add_default() and gtk_icon_factory_add().
518 * Return value: a new #GtkImage displaying the stock icon
521 gtk_image_new_from_stock (const gchar *stock_id,
526 image = gtk_type_new (GTK_TYPE_IMAGE);
528 gtk_image_set_from_stock (image, stock_id, size);
530 return GTK_WIDGET (image);
534 * gtk_image_new_from_icon_set:
535 * @icon_set: a #GtkIconSet
536 * @size: a stock icon size
538 * Creates a #GtkImage displaying an icon set. Sample stock sizes are
539 * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. Instead of using
540 * this function, usually it's better to create a #GtkIconFactory, put
541 * your icon sets in the icon factory, add the icon factory to the
542 * list of default factories with gtk_icon_factory_add_default(), and
543 * then use gtk_image_new_from_stock(). This will allow themes to
544 * override the icon you ship with your application.
546 * The #GtkImage does not assume a reference to the
547 * icon set; you still need to unref it if you own references.
548 * #GtkImage will add its own reference rather than adopting yours.
551 * Return value: a new #GtkImage
554 gtk_image_new_from_icon_set (GtkIconSet *icon_set,
559 image = gtk_type_new (GTK_TYPE_IMAGE);
561 gtk_image_set_from_icon_set (image, icon_set, size);
563 return GTK_WIDGET (image);
567 * gtk_image_new_from_animation:
568 * @animation: an animation
570 * Creates a #GtkImage displaying the given animation.
571 * The #GtkImage does not assume a reference to the
572 * animation; you still need to unref it if you own references.
573 * #GtkImage will add its own reference rather than adopting yours.
575 * Return value: a new #GtkImage widget
578 gtk_image_new_from_animation (GdkPixbufAnimation *animation)
582 g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
584 image = gtk_type_new (GTK_TYPE_IMAGE);
586 gtk_image_set_from_animation (image, animation);
588 return GTK_WIDGET (image);
592 * gtk_image_set_from_pixmap:
593 * @image: a #GtkImage
594 * @pixmap: a #GdkPixmap or %NULL
595 * @mask: a #GdkBitmap or %NULL
597 * See gtk_image_new_from_pixmap() for details.
601 gtk_image_set_from_pixmap (GtkImage *image,
605 g_return_if_fail (GTK_IS_IMAGE (image));
606 g_return_if_fail (pixmap == NULL ||
607 GDK_IS_PIXMAP (pixmap));
608 g_return_if_fail (mask == NULL ||
609 GDK_IS_PIXMAP (mask));
611 g_object_freeze_notify (G_OBJECT (image));
614 g_object_ref (G_OBJECT (pixmap));
617 g_object_ref (G_OBJECT (mask));
619 gtk_image_reset (image);
628 image->storage_type = GTK_IMAGE_PIXMAP;
630 image->data.pixmap.pixmap = pixmap;
632 gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
634 gtk_image_update_size (image, width, height);
637 g_object_notify (G_OBJECT (image), "pixmap");
638 g_object_notify (G_OBJECT (image), "mask");
640 g_object_thaw_notify (G_OBJECT (image));
644 * gtk_image_set_from_image:
645 * @image: a #GtkImage
646 * @gdk_image: a #GdkImage or %NULL
647 * @mask: a #GdkBitmap or %NULL
649 * See gtk_image_new_from_image() for details.
653 gtk_image_set_from_image (GtkImage *image,
657 g_return_if_fail (GTK_IS_IMAGE (image));
658 g_return_if_fail (gdk_image == NULL ||
659 GDK_IS_IMAGE (gdk_image));
660 g_return_if_fail (mask == NULL ||
661 GDK_IS_PIXMAP (mask));
663 g_object_freeze_notify (G_OBJECT (image));
666 g_object_ref (G_OBJECT (gdk_image));
669 g_object_ref (G_OBJECT (mask));
671 gtk_image_reset (image);
675 image->storage_type = GTK_IMAGE_IMAGE;
677 image->data.image.image = gdk_image;
680 gtk_image_update_size (image, gdk_image->width, gdk_image->height);
684 /* Clean up the mask if gdk_image was NULL */
686 g_object_unref (G_OBJECT (mask));
689 g_object_notify (G_OBJECT (image), "image");
690 g_object_notify (G_OBJECT (image), "mask");
692 g_object_thaw_notify (G_OBJECT (image));
696 * gtk_image_set_from_file:
697 * @image: a #GtkImage
698 * @filename: a filename or %NULL
700 * See gtk_image_new_from_file() for details.
704 gtk_image_set_from_file (GtkImage *image,
705 const gchar *filename)
707 GdkPixbufAnimation *anim;
709 g_return_if_fail (GTK_IS_IMAGE (image));
710 g_return_if_fail (filename != NULL);
712 g_object_freeze_notify (G_OBJECT (image));
714 gtk_image_reset (image);
716 if (filename == NULL)
718 g_object_thaw_notify (G_OBJECT (image));
722 anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
726 gtk_image_set_from_stock (image,
727 GTK_STOCK_MISSING_IMAGE,
728 GTK_ICON_SIZE_BUTTON);
729 g_object_thaw_notify (G_OBJECT (image));
733 /* We could just unconditionally set_from_animation,
734 * but it's nicer for memory if we toss the animation
735 * if it's just a single pixbuf
738 if (gdk_pixbuf_animation_is_static_image (anim))
740 gtk_image_set_from_pixbuf (image,
741 gdk_pixbuf_animation_get_static_image (anim));
745 gtk_image_set_from_animation (image, anim);
748 g_object_unref (G_OBJECT (anim));
750 g_object_thaw_notify (G_OBJECT (image));
754 * gtk_image_set_from_pixbuf:
755 * @image: a #GtkImage
756 * @pixbuf: a #GdkPixbuf or %NULL
758 * See gtk_image_new_from_pixbuf() for details.
762 gtk_image_set_from_pixbuf (GtkImage *image,
765 g_return_if_fail (GTK_IS_IMAGE (image));
766 g_return_if_fail (pixbuf == NULL ||
767 GDK_IS_PIXBUF (pixbuf));
769 g_object_freeze_notify (G_OBJECT (image));
772 g_object_ref (G_OBJECT (pixbuf));
774 gtk_image_reset (image);
778 image->storage_type = GTK_IMAGE_PIXBUF;
780 image->data.pixbuf.pixbuf = pixbuf;
782 gtk_image_update_size (image,
783 gdk_pixbuf_get_width (pixbuf),
784 gdk_pixbuf_get_height (pixbuf));
787 g_object_notify (G_OBJECT (image), "pixbuf");
789 g_object_thaw_notify (G_OBJECT (image));
793 * gtk_image_set_from_stock:
794 * @image: a #GtkImage
795 * @stock_id: a stock icon name
796 * @size: a stock icon size
798 * See gtk_image_new_from_stock for details.
802 gtk_image_set_from_stock (GtkImage *image,
803 const gchar *stock_id,
808 g_return_if_fail (GTK_IS_IMAGE (image));
810 g_object_freeze_notify (G_OBJECT (image));
812 /* in case stock_id == image->data.stock.stock_id */
813 new_id = g_strdup (stock_id);
815 gtk_image_reset (image);
819 image->storage_type = GTK_IMAGE_STOCK;
821 image->data.stock.stock_id = new_id;
822 image->icon_size = size;
824 /* Size is demand-computed in size request method
825 * if we're a stock image, since changing the
826 * style impacts the size request
830 g_object_notify (G_OBJECT (image), "stock");
831 g_object_notify (G_OBJECT (image), "icon_size");
833 g_object_thaw_notify (G_OBJECT (image));
837 * gtk_image_set_from_icon_set:
838 * @image: a #GtkImage
839 * @icon_set: a #GtkIconSet
840 * @size: a stock icon size
842 * See gtk_image_new_from_icon_set() for details.
846 gtk_image_set_from_icon_set (GtkImage *image,
847 GtkIconSet *icon_set,
850 g_return_if_fail (GTK_IS_IMAGE (image));
852 g_object_freeze_notify (G_OBJECT (image));
855 gtk_icon_set_ref (icon_set);
857 gtk_image_reset (image);
861 image->storage_type = GTK_IMAGE_ICON_SET;
863 image->data.icon_set.icon_set = icon_set;
864 image->icon_size = size;
866 /* Size is demand-computed in size request method
867 * if we're an icon set
871 g_object_notify (G_OBJECT (image), "icon_set");
872 g_object_notify (G_OBJECT (image), "icon_size");
874 g_object_thaw_notify (G_OBJECT (image));
878 * gtk_image_set_from_animation:
879 * @image: a #GtkImage
880 * @animation: the #GdkPixbufAnimation
882 * Causes the #GtkImage to display the given animation (or display
883 * nothing, if you set the animation to %NULL).
886 gtk_image_set_from_animation (GtkImage *image,
887 GdkPixbufAnimation *animation)
889 g_return_if_fail (GTK_IS_IMAGE (image));
890 g_return_if_fail (animation == NULL ||
891 GDK_IS_PIXBUF_ANIMATION (animation));
893 g_object_freeze_notify (G_OBJECT (image));
896 g_object_ref (G_OBJECT (animation));
898 gtk_image_reset (image);
900 if (animation != NULL)
902 image->storage_type = GTK_IMAGE_ANIMATION;
904 image->data.anim.anim = animation;
905 image->data.anim.frame_timeout = 0;
906 image->data.anim.iter = NULL;
908 gtk_image_update_size (image,
909 gdk_pixbuf_animation_get_width (animation),
910 gdk_pixbuf_animation_get_height (animation));
913 g_object_notify (G_OBJECT (image), "pixbuf_animation");
915 g_object_thaw_notify (G_OBJECT (image));
919 * gtk_image_get_storage_type:
920 * @image: a #GtkImage
922 * Gets the type of representation being used by the #GtkImage
923 * to store image data. If the #GtkImage has no image data,
924 * the return value will be %GTK_IMAGE_EMPTY.
926 * Return value: image representation being used
929 gtk_image_get_storage_type (GtkImage *image)
931 g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);
933 return image->storage_type;
937 * gtk_image_get_pixmap:
938 * @image: a #GtkImage
939 * @pixmap: location to store the pixmap, or %NULL
940 * @mask: location to store the mask, or %NULL
942 * Gets the pixmap and mask being displayed by the #GtkImage.
943 * The storage type of the image must be %GTK_IMAGE_EMPTY or
944 * %GTK_IMAGE_PIXMAP (see gtk_image_get_storage_type()).
945 * The caller of this function does not own a reference to the
946 * returned pixmap and mask.
950 gtk_image_get_pixmap (GtkImage *image,
954 g_return_if_fail (GTK_IS_IMAGE (image));
955 g_return_if_fail (image->storage_type == GTK_IMAGE_PIXMAP ||
956 image->storage_type == GTK_IMAGE_EMPTY);
959 *pixmap = image->data.pixmap.pixmap;
966 * gtk_image_get_image:
967 * @image: a #GtkImage
968 * @gdk_image: return location for a #GtkImage
969 * @mask: return location for a #GdkBitmap
971 * Gets the #GdkImage and mask being displayed by the #GtkImage.
972 * The storage type of the image must be %GTK_IMAGE_EMPTY or
973 * %GTK_IMAGE_IMAGE (see gtk_image_get_storage_type()).
974 * The caller of this function does not own a reference to the
975 * returned image and mask.
978 gtk_image_get_image (GtkImage *image,
979 GdkImage **gdk_image,
982 g_return_if_fail (GTK_IS_IMAGE (image));
983 g_return_if_fail (image->storage_type == GTK_IMAGE_IMAGE ||
984 image->storage_type == GTK_IMAGE_EMPTY);
987 *gdk_image = image->data.image.image;
994 * gtk_image_get_pixbuf:
995 * @image: a #GtkImage
998 * Gets the #GdkPixbuf being displayed by the #GtkImage.
999 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1000 * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
1001 * The caller of this function does not own a reference to the
1004 * Return value: the displayed pixbuf, or %NULL if the image is empty
1007 gtk_image_get_pixbuf (GtkImage *image)
1009 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1010 g_return_val_if_fail (image->storage_type == GTK_IMAGE_PIXBUF ||
1011 image->storage_type == GTK_IMAGE_EMPTY, NULL);
1013 if (image->storage_type == GTK_IMAGE_EMPTY)
1014 image->data.pixbuf.pixbuf = NULL;
1016 return image->data.pixbuf.pixbuf;
1020 * gtk_image_get_stock:
1021 * @image: a #GtkImage
1022 * @stock_id: place to store a stock icon name
1023 * @size: place to store a stock icon size
1025 * Gets the stock icon name and size being displayed by the #GtkImage.
1026 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1027 * %GTK_IMAGE_STOCK (see gtk_image_get_storage_type()).
1028 * The returned string is owned by the #GtkImage and should not
1033 gtk_image_get_stock (GtkImage *image,
1037 g_return_if_fail (GTK_IS_IMAGE (image));
1038 g_return_if_fail (image->storage_type == GTK_IMAGE_STOCK ||
1039 image->storage_type == GTK_IMAGE_EMPTY);
1041 if (image->storage_type == GTK_IMAGE_EMPTY)
1042 image->data.stock.stock_id = NULL;
1045 *stock_id = image->data.stock.stock_id;
1048 *size = image->icon_size;
1052 * gtk_image_get_icon_set:
1053 * @image: a #GtkImage
1054 * @icon_set: location to store a #GtkIconSet
1055 * @size: location to store a stock icon size
1057 * Gets the icon set and size being displayed by the #GtkImage.
1058 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1059 * %GTK_IMAGE_ICON_SET (see gtk_image_get_storage_type()).
1063 gtk_image_get_icon_set (GtkImage *image,
1064 GtkIconSet **icon_set,
1067 g_return_if_fail (GTK_IS_IMAGE (image));
1068 g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_SET ||
1069 image->storage_type == GTK_IMAGE_EMPTY);
1072 *icon_set = image->data.icon_set.icon_set;
1075 *size = image->icon_size;
1079 * gtk_image_get_animation:
1080 * @image: a #GtkImage
1083 * Gets the #GdkPixbufAnimation being displayed by the #GtkImage.
1084 * The storage type of the image must be %GTK_IMAGE_EMPTY or
1085 * %GTK_IMAGE_ANIMATION (see gtk_image_get_storage_type()).
1086 * The caller of this function does not own a reference to the
1087 * returned animation.
1089 * Return value: the displayed animation, or %NULL if the image is empty
1092 gtk_image_get_animation (GtkImage *image)
1094 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
1095 g_return_val_if_fail (image->storage_type == GTK_IMAGE_ANIMATION ||
1096 image->storage_type == GTK_IMAGE_EMPTY,
1099 if (image->storage_type == GTK_IMAGE_EMPTY)
1100 image->data.anim.anim = NULL;
1102 return image->data.anim.anim;
1107 * @void: a #GtkImage
1109 * Creates a new empty #GtkImage widget.
1111 * Return value: a newly created #GtkImage widget.
1114 gtk_image_new (void)
1116 return g_object_new (GTK_TYPE_IMAGE, NULL);
1120 gtk_image_set (GtkImage *image,
1124 g_return_if_fail (GTK_IS_IMAGE (image));
1126 gtk_image_set_from_image (image, val, mask);
1130 gtk_image_get (GtkImage *image,
1134 g_return_if_fail (GTK_IS_IMAGE (image));
1136 gtk_image_get_image (image, val, mask);
1140 gtk_image_unmap (GtkWidget *widget)
1144 image = GTK_IMAGE (widget);
1146 if (image->storage_type == GTK_IMAGE_ANIMATION)
1148 /* Reset the animation */
1150 if (image->data.anim.frame_timeout)
1152 g_source_remove (image->data.anim.frame_timeout);
1153 image->data.anim.frame_timeout = 0;
1156 if (image->data.anim.iter)
1158 g_object_unref (G_OBJECT (image->data.anim.iter));
1159 image->data.anim.iter = NULL;
1163 if (GTK_WIDGET_CLASS (parent_class)->unmap)
1164 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
1168 animation_timeout (gpointer data)
1172 GDK_THREADS_ENTER ();
1174 image = GTK_IMAGE (data);
1176 image->data.anim.frame_timeout = 0;
1178 gdk_pixbuf_animation_iter_advance (image->data.anim.iter, NULL);
1180 if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
1181 image->data.anim.frame_timeout =
1182 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
1186 gtk_widget_queue_draw (GTK_WIDGET (image));
1188 GDK_THREADS_LEAVE ();
1194 gtk_image_expose (GtkWidget *widget,
1195 GdkEventExpose *event)
1197 g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
1198 g_return_val_if_fail (event != NULL, FALSE);
1200 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&
1201 GTK_IMAGE (widget)->storage_type != GTK_IMAGE_EMPTY)
1205 GdkRectangle area, image_bound;
1207 GdkBitmap *mask = NULL;
1208 GdkPixbuf *stock_pixbuf = NULL;
1210 image = GTK_IMAGE (widget);
1211 misc = GTK_MISC (widget);
1213 x = (widget->allocation.x * (1.0 - misc->xalign) +
1214 (widget->allocation.x + widget->allocation.width
1215 - (widget->requisition.width - misc->xpad * 2)) *
1216 misc->xalign) + 0.5;
1217 y = (widget->allocation.y * (1.0 - misc->yalign) +
1218 (widget->allocation.y + widget->allocation.height
1219 - (widget->requisition.height - misc->ypad * 2)) *
1220 misc->yalign) + 0.5;
1225 switch (image->storage_type)
1227 case GTK_IMAGE_PIXMAP:
1229 gdk_drawable_get_size (image->data.pixmap.pixmap,
1231 &image_bound.height);
1234 case GTK_IMAGE_IMAGE:
1236 image_bound.width = image->data.image.image->width;
1237 image_bound.height = image->data.image.image->height;
1240 case GTK_IMAGE_PIXBUF:
1241 image_bound.width = gdk_pixbuf_get_width (image->data.pixbuf.pixbuf);
1242 image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);
1245 case GTK_IMAGE_STOCK:
1246 stock_pixbuf = gtk_widget_render_icon (widget,
1247 image->data.stock.stock_id,
1252 image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
1253 image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
1257 case GTK_IMAGE_ICON_SET:
1259 gtk_icon_set_render_icon (image->data.icon_set.icon_set,
1261 gtk_widget_get_direction (widget),
1262 GTK_WIDGET_STATE (widget),
1269 image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
1270 image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
1274 case GTK_IMAGE_ANIMATION:
1276 if (image->data.anim.iter == NULL)
1278 image->data.anim.iter = gdk_pixbuf_animation_get_iter (image->data.anim.anim, NULL);
1280 if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
1281 image->data.anim.frame_timeout =
1282 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
1287 image_bound.width = gdk_pixbuf_animation_get_width (image->data.anim.anim);
1288 image_bound.height = gdk_pixbuf_animation_get_height (image->data.anim.anim);
1298 gdk_gc_set_clip_mask (widget->style->black_gc, mask);
1299 gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
1304 if (gdk_rectangle_intersect (&area, &widget->allocation, &area) &&
1305 gdk_rectangle_intersect (&image_bound, &area, &image_bound))
1307 switch (image->storage_type)
1309 case GTK_IMAGE_PIXMAP:
1310 gdk_draw_drawable (widget->window,
1311 widget->style->black_gc,
1312 image->data.pixmap.pixmap,
1313 image_bound.x - x, image_bound.y - y,
1314 image_bound.x, image_bound.y,
1315 image_bound.width, image_bound.height);
1318 case GTK_IMAGE_IMAGE:
1319 gdk_draw_image (widget->window,
1320 widget->style->black_gc,
1321 image->data.image.image,
1322 image_bound.x - x, image_bound.y - y,
1323 image_bound.x, image_bound.y,
1324 image_bound.width, image_bound.height);
1327 case GTK_IMAGE_PIXBUF:
1328 gdk_pixbuf_render_to_drawable_alpha (image->data.pixbuf.pixbuf,
1336 GDK_PIXBUF_ALPHA_FULL,
1338 GDK_RGB_DITHER_NORMAL,
1342 case GTK_IMAGE_STOCK: /* fall thru */
1343 case GTK_IMAGE_ICON_SET:
1346 gdk_pixbuf_render_to_drawable_alpha (stock_pixbuf,
1354 GDK_PIXBUF_ALPHA_FULL,
1356 GDK_RGB_DITHER_NORMAL,
1359 g_object_unref (G_OBJECT (stock_pixbuf));
1363 case GTK_IMAGE_ANIMATION:
1364 /* don't advance the anim iter here, or we could get frame changes between two
1365 * exposes of different areas.
1368 gdk_pixbuf_render_to_drawable_alpha (gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter),
1376 GDK_PIXBUF_ALPHA_FULL,
1378 GDK_RGB_DITHER_NORMAL,
1385 } /* if rectangle intersects */
1388 gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
1389 gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
1391 } /* if widget is drawable */
1397 gtk_image_clear (GtkImage *image)
1399 g_object_freeze_notify (G_OBJECT (image));
1401 if (image->storage_type != GTK_IMAGE_EMPTY)
1402 g_object_notify (G_OBJECT (image), "storage_type");
1406 g_object_unref (G_OBJECT (image->mask));
1408 g_object_notify (G_OBJECT (image), "mask");
1411 if (image->icon_size != DEFAULT_ICON_SIZE)
1413 image->icon_size = DEFAULT_ICON_SIZE;
1414 g_object_notify (G_OBJECT (image), "icon_size");
1417 switch (image->storage_type)
1419 case GTK_IMAGE_PIXMAP:
1421 if (image->data.pixmap.pixmap)
1422 g_object_unref (G_OBJECT (image->data.pixmap.pixmap));
1423 image->data.pixmap.pixmap = NULL;
1425 g_object_notify (G_OBJECT (image), "pixmap");
1429 case GTK_IMAGE_IMAGE:
1431 if (image->data.image.image)
1432 g_object_unref (G_OBJECT (image->data.image.image));
1433 image->data.image.image = NULL;
1435 g_object_notify (G_OBJECT (image), "image");
1439 case GTK_IMAGE_PIXBUF:
1441 if (image->data.pixbuf.pixbuf)
1442 g_object_unref (G_OBJECT (image->data.pixbuf.pixbuf));
1444 g_object_notify (G_OBJECT (image), "pixbuf");
1448 case GTK_IMAGE_STOCK:
1450 g_free (image->data.stock.stock_id);
1452 image->data.stock.stock_id = NULL;
1454 g_object_notify (G_OBJECT (image), "stock");
1457 case GTK_IMAGE_ICON_SET:
1458 if (image->data.icon_set.icon_set)
1459 gtk_icon_set_unref (image->data.icon_set.icon_set);
1460 image->data.icon_set.icon_set = NULL;
1462 g_object_notify (G_OBJECT (image), "icon_set");
1465 case GTK_IMAGE_ANIMATION:
1466 if (image->data.anim.frame_timeout)
1467 g_source_remove (image->data.anim.frame_timeout);
1469 if (image->data.anim.anim)
1470 g_object_unref (G_OBJECT (image->data.anim.anim));
1472 image->data.anim.frame_timeout = 0;
1473 image->data.anim.anim = NULL;
1475 g_object_notify (G_OBJECT (image), "pixbuf_animation");
1479 case GTK_IMAGE_EMPTY:
1485 image->storage_type = GTK_IMAGE_EMPTY;
1487 memset (&image->data, '\0', sizeof (image->data));
1489 g_object_thaw_notify (G_OBJECT (image));
1493 gtk_image_reset (GtkImage *image)
1495 gtk_image_clear (image);
1497 gtk_image_update_size (image, 0, 0);
1501 gtk_image_size_request (GtkWidget *widget,
1502 GtkRequisition *requisition)
1505 GdkPixbuf *pixbuf = NULL;
1507 image = GTK_IMAGE (widget);
1509 /* We update stock/icon set on every size request, because
1510 * the theme could have affected the size; for other kinds of
1511 * image, we just update the requisition when the image data
1515 switch (image->storage_type)
1517 case GTK_IMAGE_STOCK:
1518 pixbuf = gtk_widget_render_icon (GTK_WIDGET (image),
1519 image->data.stock.stock_id,
1524 case GTK_IMAGE_ICON_SET:
1525 pixbuf = gtk_icon_set_render_icon (image->data.icon_set.icon_set,
1527 gtk_widget_get_direction (widget),
1528 GTK_WIDGET_STATE (widget),
1540 GTK_WIDGET (image)->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
1541 GTK_WIDGET (image)->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
1543 g_object_unref (G_OBJECT (pixbuf));
1546 /* Chain up to default that simply reads current requisition */
1547 GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
1551 gtk_image_update_size (GtkImage *image,
1555 GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
1556 GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
1558 if (GTK_WIDGET_VISIBLE (image))
1559 gtk_widget_queue_resize (GTK_WIDGET (image));