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"
33 static void gtk_image_class_init (GtkImageClass *klass);
34 static void gtk_image_init (GtkImage *image);
35 static gint gtk_image_expose (GtkWidget *widget,
36 GdkEventExpose *event);
37 static void gtk_image_unmap (GtkWidget *widget);
38 static void gtk_image_size_request (GtkWidget *widget,
39 GtkRequisition *requisition);
40 static void gtk_image_destroy (GtkObject *object);
41 static void gtk_image_clear (GtkImage *image);
42 static void gtk_image_reset (GtkImage *image);
43 static void gtk_image_update_size (GtkImage *image,
47 static gpointer parent_class;
50 gtk_image_get_type (void)
52 static GtkType image_type = 0;
56 static const GtkTypeInfo image_info =
60 sizeof (GtkImageClass),
61 (GtkClassInitFunc) gtk_image_class_init,
62 (GtkObjectInitFunc) gtk_image_init,
63 /* reserved_1 */ NULL,
64 /* reserved_2 */ NULL,
65 (GtkClassInitFunc) NULL,
68 image_type = gtk_type_unique (GTK_TYPE_MISC, &image_info);
75 gtk_image_class_init (GtkImageClass *class)
77 GtkObjectClass *object_class;
78 GtkWidgetClass *widget_class;
80 parent_class = g_type_class_peek_parent (class);
82 object_class = (GtkObjectClass *) class;
84 object_class->destroy = gtk_image_destroy;
86 widget_class = (GtkWidgetClass*) class;
88 widget_class->expose_event = gtk_image_expose;
89 widget_class->size_request = gtk_image_size_request;
90 widget_class->unmap = gtk_image_unmap;
94 gtk_image_init (GtkImage *image)
96 GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
98 image->storage_type = GTK_IMAGE_EMPTY;
102 gtk_image_destroy (GtkObject *object)
104 GtkImage *image = GTK_IMAGE (object);
106 gtk_image_clear (image);
108 GTK_OBJECT_CLASS (parent_class)->destroy (object);
113 * gtk_image_new_from_pixmap:
114 * @pixmap: a #GdkPixmap, or %NULL
115 * @mask: a #GdkBitmap, or %NULL
117 * Creates a #GtkImage widget displaying @pixmap with a @mask.
118 * A #GdkImage is a server-side image buffer in the pixel format of the
119 * current display. The #GtkImage does not assume a reference to the
120 * pixmap or mask; you still need to unref them if you own references.
121 * #GtkImage will add its own reference rather than adopting yours.
123 * Return value: a new #GtkImage
126 gtk_image_new_from_pixmap (GdkPixmap *pixmap,
131 image = gtk_type_new (GTK_TYPE_IMAGE);
133 gtk_image_set_from_pixmap (image, pixmap, mask);
135 return GTK_WIDGET (image);
139 * gtk_image_new_from_image:
140 * @image: a #GdkImage, or %NULL
141 * @mask: a #GdkBitmap, or %NULL
143 * Creates a #GtkImage widget displaying a @image with a @mask.
144 * A #GdkImage is a client-side image buffer in the pixel format of the
146 * The #GtkImage does not assume a reference to the
147 * image or mask; you still need to unref them if you own references.
148 * #GtkImage will add its own reference rather than adopting yours.
150 * Return value: a new #GtkImage
153 gtk_image_new_from_image (GdkImage *gdk_image,
158 image = gtk_type_new (GTK_TYPE_IMAGE);
160 gtk_image_set_from_image (image, gdk_image, mask);
162 return GTK_WIDGET (image);
166 * gtk_image_new_from_file:
167 * @filename: a filename
169 * Creates a new #GtkImage displaying the file @filename. If the file
170 * isn't found or can't be loaded, the resulting #GtkImage will
171 * display a "broken image" icon. This function never returns %NULL,
172 * it always returns a valid #GtkImage widget.
174 * If the file contains an animation, the image will contain an
177 * If you need to detect failures to load the file, use
178 * gdk_pixbuf_new_from_file() to load the file yourself, then create
179 * the #GtkImage from the pixbuf. (Or for animations, use
180 * gdk_pixbuf_animation_new_from_file()).
182 * The storage type (gtk_image_get_storage_type()) of the returned
183 * image is not defined, it will be whatever is appropriate for
184 * displaying the file.
186 * Return value: a new #GtkImage
189 gtk_image_new_from_file (const gchar *filename)
193 image = gtk_type_new (GTK_TYPE_IMAGE);
195 gtk_image_set_from_file (image, filename);
197 return GTK_WIDGET (image);
201 * gtk_image_new_from_pixbuf:
202 * @pixbuf: a #GdkPixbuf, or %NULL
204 * Creates a new #GtkImage displaying @pixbuf.
205 * The #GtkImage does not assume a reference to the
206 * pixbuf; you still need to unref it if you own references.
207 * #GtkImage will add its own reference rather than adopting yours.
209 * Note that this function just creates an #GtkImage from the pixbuf. The
210 * #GtkImage created will not react to state changes. Should you want that, you
211 * should use gtk_image_new_from_icon_set().
213 * Return value: a new #GtkImage
216 gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
220 image = gtk_type_new (GTK_TYPE_IMAGE);
222 gtk_image_set_from_pixbuf (image, pixbuf);
224 return GTK_WIDGET (image);
228 * gtk_image_new_from_stock:
229 * @stock_id: a stock icon name
230 * @size: a stock icon size
232 * Creates a #GtkImage displaying a stock icon. Sample stock icon
233 * names are #GTK_STOCK_OPEN, #GTK_STOCK_EXIT. Sample stock sizes
234 * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
235 * icon name isn't known, a "broken image" icon will be displayed instead.
236 * You can register your own stock icon names, see
237 * gtk_icon_factory_add_default() and gtk_icon_factory_add().
239 * Return value: a new #GtkImage displaying the stock icon
242 gtk_image_new_from_stock (const gchar *stock_id,
247 image = gtk_type_new (GTK_TYPE_IMAGE);
249 gtk_image_set_from_stock (image, stock_id, size);
251 return GTK_WIDGET (image);
255 * gtk_image_new_from_icon_set:
256 * @icon_set: a #GtkIconSet
257 * @size: a stock icon size
259 * Creates a #GtkImage displaying an icon set. Sample stock sizes are
260 * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. Instead of using
261 * this function, usually it's better to create a #GtkIconFactory, put
262 * your icon sets in the icon factory, add the icon factory to the
263 * list of default factories with gtk_icon_factory_add_default(), and
264 * then use gtk_image_new_from_stock(). This will allow themes to
265 * override the icon you ship with your application.
267 * The #GtkImage does not assume a reference to the
268 * icon set; you still need to unref it if you own references.
269 * #GtkImage will add its own reference rather than adopting yours.
272 * Return value: a new #GtkImage
275 gtk_image_new_from_icon_set (GtkIconSet *icon_set,
280 image = gtk_type_new (GTK_TYPE_IMAGE);
282 gtk_image_set_from_icon_set (image, icon_set, size);
284 return GTK_WIDGET (image);
288 * gtk_image_new_from_animation:
289 * @animation: an animation
291 * Creates a #GtkImage displaying the given animation.
292 * The #GtkImage does not assume a reference to the
293 * animation; you still need to unref it if you own references.
294 * #GtkImage will add its own reference rather than adopting yours.
296 * Return value: a new #GtkImage widget
299 gtk_image_new_from_animation (GdkPixbufAnimation *animation)
303 g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
305 image = gtk_type_new (GTK_TYPE_IMAGE);
307 gtk_image_set_from_animation (image, animation);
309 return GTK_WIDGET (image);
313 * gtk_image_set_from_pixmap:
314 * @image: a #GtkImage
315 * @pixmap: a #GdkPixmap or %NULL
316 * @mask: a #GdkBitmap or %NULL
318 * See gtk_image_new_from_pixmap() for details.
322 gtk_image_set_from_pixmap (GtkImage *image,
326 g_return_if_fail (GTK_IS_IMAGE (image));
327 g_return_if_fail (pixmap == NULL ||
328 GDK_IS_PIXMAP (pixmap));
329 g_return_if_fail (mask == NULL ||
330 GDK_IS_PIXMAP (mask));
333 g_object_ref (G_OBJECT (pixmap));
336 g_object_ref (G_OBJECT (mask));
338 gtk_image_reset (image);
345 image->storage_type = GTK_IMAGE_PIXMAP;
347 image->data.pixmap.pixmap = pixmap;
348 image->data.pixmap.mask = mask;
350 gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
352 gtk_image_update_size (image, width, height);
356 /* Clean up the mask if pixmap was NULL */
358 g_object_unref (G_OBJECT (mask));
363 * gtk_image_set_from_image:
364 * @image: a #GtkImage
365 * @gdk_image: a #GdkImage or %NULL
366 * @mask: a #GdkBitmap or %NULL
368 * See gtk_image_new_from_image() for details.
372 gtk_image_set_from_image (GtkImage *image,
376 g_return_if_fail (GTK_IS_IMAGE (image));
377 g_return_if_fail (gdk_image == NULL ||
378 GDK_IS_IMAGE (gdk_image));
379 g_return_if_fail (mask == NULL ||
380 GDK_IS_PIXMAP (mask));
384 g_object_ref (G_OBJECT (gdk_image));
387 g_object_ref (G_OBJECT (mask));
389 gtk_image_reset (image);
393 image->storage_type = GTK_IMAGE_IMAGE;
395 image->data.image.image = gdk_image;
396 image->data.image.mask = mask;
398 gtk_image_update_size (image, gdk_image->width, gdk_image->height);
402 /* Clean up the mask if gdk_image was NULL */
404 g_object_unref (G_OBJECT (mask));
409 * gtk_image_set_from_file:
410 * @image: a #GtkImage
411 * @filename: a filename or %NULL
413 * See gtk_image_new_from_file() for details.
417 gtk_image_set_from_file (GtkImage *image,
418 const gchar *filename)
420 GdkPixbufAnimation *anim;
422 g_return_if_fail (GTK_IS_IMAGE (image));
423 g_return_if_fail (filename != NULL);
425 gtk_image_reset (image);
427 if (filename == NULL)
430 anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
434 gtk_image_set_from_stock (image,
435 GTK_STOCK_MISSING_IMAGE,
436 GTK_ICON_SIZE_BUTTON);
440 /* We could just unconditionally set_from_animation,
441 * but it's nicer for memory if we toss the animation
442 * if it's just a single pixbuf
445 if (gdk_pixbuf_animation_is_static_image (anim))
447 gtk_image_set_from_pixbuf (image,
448 gdk_pixbuf_animation_get_static_image (anim));
452 gtk_image_set_from_animation (image, anim);
455 g_object_unref (G_OBJECT (anim));
459 * gtk_image_set_from_pixbuf:
460 * @image: a #GtkImage
461 * @pixbuf: a #GdkPixbuf or %NULL
463 * See gtk_image_new_from_pixbuf() for details.
467 gtk_image_set_from_pixbuf (GtkImage *image,
470 g_return_if_fail (GTK_IS_IMAGE (image));
471 g_return_if_fail (pixbuf == NULL ||
472 GDK_IS_PIXBUF (pixbuf));
475 g_object_ref (G_OBJECT (pixbuf));
477 gtk_image_reset (image);
481 image->storage_type = GTK_IMAGE_PIXBUF;
483 image->data.pixbuf.pixbuf = pixbuf;
485 gtk_image_update_size (image,
486 gdk_pixbuf_get_width (pixbuf),
487 gdk_pixbuf_get_height (pixbuf));
492 * gtk_image_set_from_stock:
493 * @image: a #GtkImage
494 * @stock_id: a stock icon name
495 * @size: a stock icon size
497 * See gtk_image_new_from_stock for details.
501 gtk_image_set_from_stock (GtkImage *image,
502 const gchar *stock_id,
505 g_return_if_fail (GTK_IS_IMAGE (image));
507 gtk_image_reset (image);
511 image->storage_type = GTK_IMAGE_STOCK;
513 image->data.stock.stock_id = g_strdup (stock_id);
514 image->data.stock.size = size;
516 /* Size is demand-computed in size request method
517 * if we're a stock image, since changing the
518 * style impacts the size request
524 * gtk_image_set_from_icon_set:
525 * @image: a #GtkImage
526 * @icon_set: a #GtkIconSet
527 * @size: a stock icon size
529 * See gtk_image_new_from_icon_set() for details.
533 gtk_image_set_from_icon_set (GtkImage *image,
534 GtkIconSet *icon_set,
537 g_return_if_fail (GTK_IS_IMAGE (image));
540 gtk_icon_set_ref (icon_set);
542 gtk_image_reset (image);
546 image->storage_type = GTK_IMAGE_ICON_SET;
548 image->data.icon_set.icon_set = icon_set;
549 image->data.icon_set.size = size;
551 /* Size is demand-computed in size request method
552 * if we're an icon set
558 * gtk_image_set_from_animation:
559 * @image: a #GtkImage
560 * @animation: the #GdkPixbufAnimation
562 * Causes the #GtkImage to display the given animation (or display
563 * nothing, if you set the animation to %NULL).
566 gtk_image_set_from_animation (GtkImage *image,
567 GdkPixbufAnimation *animation)
569 g_return_if_fail (GTK_IS_IMAGE (image));
570 g_return_if_fail (animation == NULL ||
571 GDK_IS_PIXBUF_ANIMATION (animation));
574 g_object_ref (G_OBJECT (animation));
576 gtk_image_reset (image);
578 if (animation != NULL)
580 image->storage_type = GTK_IMAGE_ANIMATION;
582 image->data.anim.anim = animation;
583 image->data.anim.frame_timeout = 0;
584 image->data.anim.iter = NULL;
586 gtk_image_update_size (image,
587 gdk_pixbuf_animation_get_width (animation),
588 gdk_pixbuf_animation_get_height (animation));
593 * gtk_image_get_storage_type:
594 * @image: a #GtkImage
596 * Gets the type of representation being used by the #GtkImage
597 * to store image data. If the #GtkImage has no image data,
598 * the return value will be %GTK_IMAGE_EMPTY.
600 * Return value: image representation being used
603 gtk_image_get_storage_type (GtkImage *image)
605 g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);
607 return image->storage_type;
611 * gtk_image_get_pixmap:
612 * @image: a #GtkImage
613 * @pixmap: location to store the pixmap, or %NULL
614 * @mask: location to store the mask, or %NULL
616 * Gets the pixmap and mask being displayed by the #GtkImage.
617 * The storage type of the image must be %GTK_IMAGE_EMPTY or
618 * %GTK_IMAGE_PIXMAP (see gtk_image_get_storage_type()).
619 * The caller of this function does not own a reference to the
620 * returned pixmap and mask.
624 gtk_image_get_pixmap (GtkImage *image,
628 g_return_if_fail (GTK_IS_IMAGE (image));
629 g_return_if_fail (image->storage_type == GTK_IMAGE_PIXMAP ||
630 image->storage_type == GTK_IMAGE_EMPTY);
633 *pixmap = image->data.pixmap.pixmap;
636 *mask = image->data.pixmap.mask;
640 * gtk_image_get_image:
641 * @image: a #GtkImage
642 * @gdk_image: return location for a #GtkImage
643 * @mask: return location for a #GdkBitmap
645 * Gets the #GdkImage and mask being displayed by the #GtkImage.
646 * The storage type of the image must be %GTK_IMAGE_EMPTY or
647 * %GTK_IMAGE_IMAGE (see gtk_image_get_storage_type()).
648 * The caller of this function does not own a reference to the
649 * returned image and mask.
652 gtk_image_get_image (GtkImage *image,
653 GdkImage **gdk_image,
656 g_return_if_fail (GTK_IS_IMAGE (image));
657 g_return_if_fail (image->storage_type == GTK_IMAGE_IMAGE ||
658 image->storage_type == GTK_IMAGE_EMPTY);
661 *gdk_image = image->data.image.image;
664 *mask = image->data.image.mask;
668 * gtk_image_get_pixbuf:
669 * @image: a #GtkImage
672 * Gets the #GdkPixbuf being displayed by the #GtkImage.
673 * The storage type of the image must be %GTK_IMAGE_EMPTY or
674 * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
675 * The caller of this function does not own a reference to the
678 * Return value: the displayed pixbuf, or %NULL if the image is empty
681 gtk_image_get_pixbuf (GtkImage *image)
683 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
684 g_return_val_if_fail (image->storage_type == GTK_IMAGE_PIXBUF ||
685 image->storage_type == GTK_IMAGE_EMPTY, NULL);
687 if (image->storage_type == GTK_IMAGE_EMPTY)
688 image->data.pixbuf.pixbuf = NULL;
690 return image->data.pixbuf.pixbuf;
694 * gtk_image_get_stock:
695 * @image: a #GtkImage
696 * @stock_id: place to store a stock icon name
697 * @size: place to store a stock icon size
699 * Gets the stock icon name and size being displayed by the #GtkImage.
700 * The storage type of the image must be %GTK_IMAGE_EMPTY or
701 * %GTK_IMAGE_STOCK (see gtk_image_get_storage_type()).
702 * The returned string is owned by the #GtkImage and should not
707 gtk_image_get_stock (GtkImage *image,
711 g_return_if_fail (GTK_IS_IMAGE (image));
712 g_return_if_fail (image->storage_type == GTK_IMAGE_STOCK ||
713 image->storage_type == GTK_IMAGE_EMPTY);
715 if (image->storage_type == GTK_IMAGE_EMPTY)
716 image->data.stock.stock_id = NULL;
719 *stock_id = image->data.stock.stock_id;
722 *size = image->data.stock.size;
726 * gtk_image_get_icon_set:
727 * @image: a #GtkImage
728 * @icon_set: location to store a #GtkIconSet
729 * @size: location to store a stock icon size
731 * Gets the icon set and size being displayed by the #GtkImage.
732 * The storage type of the image must be %GTK_IMAGE_EMPTY or
733 * %GTK_IMAGE_ICON_SET (see gtk_image_get_storage_type()).
737 gtk_image_get_icon_set (GtkImage *image,
738 GtkIconSet **icon_set,
741 g_return_if_fail (GTK_IS_IMAGE (image));
742 g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_SET ||
743 image->storage_type == GTK_IMAGE_EMPTY);
746 *icon_set = image->data.icon_set.icon_set;
749 *size = image->data.icon_set.size;
753 * gtk_image_get_animation:
754 * @image: a #GtkImage
757 * Gets the #GdkPixbufAnimation being displayed by the #GtkImage.
758 * The storage type of the image must be %GTK_IMAGE_EMPTY or
759 * %GTK_IMAGE_ANIMATION (see gtk_image_get_storage_type()).
760 * The caller of this function does not own a reference to the
761 * returned animation.
763 * Return value: the displayed animation, or %NULL if the image is empty
766 gtk_image_get_animation (GtkImage *image)
768 g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
769 g_return_val_if_fail (image->storage_type == GTK_IMAGE_ANIMATION ||
770 image->storage_type == GTK_IMAGE_EMPTY,
773 if (image->storage_type == GTK_IMAGE_EMPTY)
774 image->data.anim.anim = NULL;
776 return image->data.anim.anim;
780 gtk_image_new (GdkImage *val,
785 g_return_val_if_fail (val != NULL, NULL);
787 image = gtk_type_new (GTK_TYPE_IMAGE);
789 gtk_image_set (image, val, mask);
791 return GTK_WIDGET (image);
795 gtk_image_set (GtkImage *image,
799 g_return_if_fail (GTK_IS_IMAGE (image));
801 gtk_image_set_from_image (image, val, mask);
805 gtk_image_get (GtkImage *image,
809 g_return_if_fail (GTK_IS_IMAGE (image));
811 gtk_image_get_image (image, val, mask);
815 gtk_image_unmap (GtkWidget *widget)
819 image = GTK_IMAGE (widget);
821 if (image->storage_type == GTK_IMAGE_ANIMATION)
823 /* Reset the animation */
825 if (image->data.anim.frame_timeout)
827 g_source_remove (image->data.anim.frame_timeout);
828 image->data.anim.frame_timeout = 0;
831 if (image->data.anim.iter)
833 g_object_unref (G_OBJECT (image->data.anim.iter));
834 image->data.anim.iter = NULL;
838 if (GTK_WIDGET_CLASS (parent_class)->unmap)
839 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
843 animation_timeout (gpointer data)
847 GDK_THREADS_ENTER ();
849 image = GTK_IMAGE (data);
851 image->data.anim.frame_timeout = 0;
853 gdk_pixbuf_animation_iter_advance (image->data.anim.iter, NULL);
855 if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
856 image->data.anim.frame_timeout =
857 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
861 gtk_widget_queue_draw (GTK_WIDGET (image));
863 GDK_THREADS_LEAVE ();
869 gtk_image_expose (GtkWidget *widget,
870 GdkEventExpose *event)
872 g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
873 g_return_val_if_fail (event != NULL, FALSE);
875 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&
876 GTK_IMAGE (widget)->storage_type != GTK_IMAGE_EMPTY)
880 GdkRectangle area, image_bound;
882 GdkBitmap *mask = NULL;
883 GdkPixbuf *stock_pixbuf = NULL;
885 image = GTK_IMAGE (widget);
886 misc = GTK_MISC (widget);
888 x = (widget->allocation.x * (1.0 - misc->xalign) +
889 (widget->allocation.x + widget->allocation.width
890 - (widget->requisition.width - misc->xpad * 2)) *
892 y = (widget->allocation.y * (1.0 - misc->yalign) +
893 (widget->allocation.y + widget->allocation.height
894 - (widget->requisition.height - misc->ypad * 2)) *
900 switch (image->storage_type)
902 case GTK_IMAGE_PIXMAP:
903 mask = image->data.pixmap.mask;
904 gdk_drawable_get_size (image->data.pixmap.pixmap,
906 &image_bound.height);
909 case GTK_IMAGE_IMAGE:
910 mask = image->data.image.mask;
911 image_bound.width = image->data.image.image->width;
912 image_bound.height = image->data.image.image->height;
915 case GTK_IMAGE_PIXBUF:
916 image_bound.width = gdk_pixbuf_get_width (image->data.pixbuf.pixbuf);
917 image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);
920 case GTK_IMAGE_STOCK:
921 stock_pixbuf = gtk_widget_render_icon (widget,
922 image->data.stock.stock_id,
923 image->data.stock.size,
927 image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
928 image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
932 case GTK_IMAGE_ICON_SET:
934 gtk_icon_set_render_icon (image->data.icon_set.icon_set,
936 gtk_widget_get_direction (widget),
937 GTK_WIDGET_STATE (widget),
938 image->data.icon_set.size,
944 image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
945 image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
949 case GTK_IMAGE_ANIMATION:
951 if (image->data.anim.iter == NULL)
953 image->data.anim.iter = gdk_pixbuf_animation_get_iter (image->data.anim.anim, NULL);
955 if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
956 image->data.anim.frame_timeout =
957 g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
962 image_bound.width = gdk_pixbuf_animation_get_width (image->data.anim.anim);
963 image_bound.height = gdk_pixbuf_animation_get_height (image->data.anim.anim);
973 gdk_gc_set_clip_mask (widget->style->black_gc, mask);
974 gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
979 if (gdk_rectangle_intersect (&area, &widget->allocation, &area) &&
980 gdk_rectangle_intersect (&image_bound, &area, &image_bound))
982 switch (image->storage_type)
984 case GTK_IMAGE_PIXMAP:
985 gdk_draw_drawable (widget->window,
986 widget->style->black_gc,
987 image->data.pixmap.pixmap,
988 image_bound.x - x, image_bound.y - y,
989 image_bound.x, image_bound.y,
990 image_bound.width, image_bound.height);
993 case GTK_IMAGE_IMAGE:
994 gdk_draw_image (widget->window,
995 widget->style->black_gc,
996 image->data.image.image,
997 image_bound.x - x, image_bound.y - y,
998 image_bound.x, image_bound.y,
999 image_bound.width, image_bound.height);
1002 case GTK_IMAGE_PIXBUF:
1003 gdk_pixbuf_render_to_drawable_alpha (image->data.pixbuf.pixbuf,
1011 GDK_PIXBUF_ALPHA_FULL,
1013 GDK_RGB_DITHER_NORMAL,
1017 case GTK_IMAGE_STOCK: /* fall thru */
1018 case GTK_IMAGE_ICON_SET:
1021 gdk_pixbuf_render_to_drawable_alpha (stock_pixbuf,
1029 GDK_PIXBUF_ALPHA_FULL,
1031 GDK_RGB_DITHER_NORMAL,
1034 g_object_unref (G_OBJECT (stock_pixbuf));
1038 case GTK_IMAGE_ANIMATION:
1039 /* don't advance the anim iter here, or we could get frame changes between two
1040 * exposes of different areas.
1043 gdk_pixbuf_render_to_drawable_alpha (gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter),
1051 GDK_PIXBUF_ALPHA_FULL,
1053 GDK_RGB_DITHER_NORMAL,
1060 } /* if rectangle intersects */
1063 gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
1064 gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
1066 } /* if widget is drawable */
1072 gtk_image_clear (GtkImage *image)
1074 switch (image->storage_type)
1076 case GTK_IMAGE_PIXMAP:
1078 if (image->data.pixmap.pixmap)
1079 g_object_unref (G_OBJECT (image->data.pixmap.pixmap));
1081 if (image->data.pixmap.mask)
1082 g_object_unref (G_OBJECT (image->data.pixmap.mask));
1086 case GTK_IMAGE_IMAGE:
1088 if (image->data.image.image)
1089 g_object_unref (G_OBJECT (image->data.image.image));
1091 if (image->data.image.mask)
1092 g_object_unref (G_OBJECT (image->data.image.mask));
1096 case GTK_IMAGE_PIXBUF:
1098 if (image->data.pixbuf.pixbuf)
1099 g_object_unref (G_OBJECT (image->data.pixbuf.pixbuf));
1103 case GTK_IMAGE_STOCK:
1105 g_free (image->data.stock.stock_id);
1109 case GTK_IMAGE_ICON_SET:
1110 if (image->data.icon_set.icon_set)
1111 gtk_icon_set_unref (image->data.icon_set.icon_set);
1115 case GTK_IMAGE_ANIMATION:
1116 if (image->data.anim.frame_timeout)
1117 g_source_remove (image->data.anim.frame_timeout);
1119 if (image->data.anim.anim)
1120 g_object_unref (G_OBJECT (image->data.anim.anim));
1123 case GTK_IMAGE_EMPTY:
1129 image->storage_type = GTK_IMAGE_EMPTY;
1131 memset (&image->data, '\0', sizeof (image->data));
1135 gtk_image_reset (GtkImage *image)
1137 gtk_image_clear (image);
1139 gtk_image_update_size (image, 0, 0);
1143 gtk_image_size_request (GtkWidget *widget,
1144 GtkRequisition *requisition)
1147 GdkPixbuf *pixbuf = NULL;
1149 image = GTK_IMAGE (widget);
1151 /* We update stock/icon set on every size request, because
1152 * the theme could have affected the size; for other kinds of
1153 * image, we just update the requisition when the image data
1157 switch (image->storage_type)
1159 case GTK_IMAGE_STOCK:
1160 pixbuf = gtk_widget_render_icon (GTK_WIDGET (image),
1161 image->data.stock.stock_id,
1162 image->data.stock.size,
1166 case GTK_IMAGE_ICON_SET:
1167 pixbuf = gtk_icon_set_render_icon (image->data.icon_set.icon_set,
1169 gtk_widget_get_direction (widget),
1170 GTK_WIDGET_STATE (widget),
1171 image->data.icon_set.size,
1182 GTK_WIDGET (image)->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
1183 GTK_WIDGET (image)->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
1185 g_object_unref (G_OBJECT (pixbuf));
1188 /* Chain up to default that simply reads current requisition */
1189 GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
1193 gtk_image_update_size (GtkImage *image,
1197 GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
1198 GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
1200 if (GTK_WIDGET_VISIBLE (image))
1201 gtk_widget_queue_resize (GTK_WIDGET (image));