gtkimage.c 55.7 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
Elliot Lee's avatar
Elliot Lee committed
2 3 4
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10 11
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
16
 */
17 18

/*
19
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20 21 22 23 24
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

25
#include "config.h"
26

27
#include <math.h>
28
#include <string.h>
29
#include <cairo-gobject.h>
30

Elliot Lee's avatar
Elliot Lee committed
31
#include "gtkcontainer.h"
32
#include "gtkiconhelperprivate.h"
33
#include "gtkimageprivate.h"
34 35
#include "deprecated/gtkiconfactory.h"
#include "deprecated/gtkstock.h"
36
#include "gtkicontheme.h"
37
#include "gtksizerequest.h"
Havoc Pennington's avatar
Havoc Pennington committed
38
#include "gtkintl.h"
39
#include "gtkprivate.h"
40
#include "gtktypebuiltins.h"
41 42 43
#include "gtkcssshadowsvalueprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtkwidgetprivate.h"
Elliot Lee's avatar
Elliot Lee committed
44

45 46
#include "a11y/gtkimageaccessible.h"

47 48 49 50 51 52 53 54 55
/**
 * SECTION:gtkimage
 * @Short_description: A widget displaying an image
 * @Title: GtkImage
 * @See_also:#GdkPixbuf
 *
 * The #GtkImage widget displays an image. Various kinds of object
 * can be displayed as an image; most typically, you would load a
 * #GdkPixbuf ("pixel buffer") from a file, and then display that.
56
 * There’s a convenience function to do this, gtk_image_new_from_file(),
57
 * used as follows:
58
 * |[<!-- language="C" -->
59 60
 *   GtkWidget *image;
 *   image = gtk_image_new_from_file ("myfile.png");
61
 * ]|
62
 * If the file isn’t loaded successfully, the image will contain a
63
 * “broken image” icon similar to that used in many web browsers.
64 65 66 67 68 69 70 71 72 73 74 75
 * If you want to handle errors in loading the file yourself,
 * for example by displaying an error message, then load the image with
 * gdk_pixbuf_new_from_file(), then create the #GtkImage with
 * gtk_image_new_from_pixbuf().
 *
 * The image file may contain an animation, if so the #GtkImage will
 * display an animation (#GdkPixbufAnimation) instead of a static image.
 *
 * #GtkImage is a subclass of #GtkMisc, which implies that you can
 * align it (center, left, right) and add padding to it, using
 * #GtkMisc methods.
 *
76
 * #GtkImage is a “no window” widget (has no #GdkWindow of its own),
77 78 79
 * so by default does not receive events. If you want to receive events
 * on the image, such as button clicks, place the image inside a
 * #GtkEventBox, then connect to the event signals on the event box.
80 81 82
 *
 * ## Handling button press events on a #GtkImage.
 *
83
 * |[<!-- language="C" -->
84 85 86 87 88
 *   static gboolean
 *   button_press_callback (GtkWidget      *event_box,
 *                          GdkEventButton *event,
 *                          gpointer        data)
 *   {
89
 *     g_print ("Event box clicked at coordinates %f,%f\n",
90 91
 *              event->x, event->y);
 *
92 93 94
 *     // Returning TRUE means we handled the event, so the signal
 *     // emission should be stopped (don’t call any further callbacks
 *     // that may be connected). Return FALSE to continue invoking callbacks.
95 96 97 98 99 100 101 102 103 104 105
 *     return TRUE;
 *   }
 *
 *   static GtkWidget*
 *   create_image (void)
 *   {
 *     GtkWidget *image;
 *     GtkWidget *event_box;
 *
 *     image = gtk_image_new_from_file ("myfile.png");
 *
106
 *     event_box = gtk_event_box_new ();
107 108 109 110 111 112 113 114 115 116
 *
 *     gtk_container_add (GTK_CONTAINER (event_box), image);
 *
 *     g_signal_connect (G_OBJECT (event_box),
 *                       "button_press_event",
 *                       G_CALLBACK (button_press_callback),
 *                       image);
 *
 *     return image;
 *   }
117
 * ]|
118 119 120 121 122 123 124 125 126 127
 *
 * When handling events on the event box, keep in mind that coordinates
 * in the image may be different from event box coordinates due to
 * the alignment and padding settings on the image (see #GtkMisc).
 * The simplest way to solve this is to set the alignment to 0.0
 * (left/top), and set the padding to zero. Then the origin of
 * the image will be the same as the origin of the event box.
 *
 * Sometimes an application will want to avoid depending on external data
 * files, such as image files. GTK+ comes with a program to avoid this,
128
 * called “gdk-pixbuf-csource”. This library
129 130 131 132 133
 * allows you to convert an image into a C variable declaration, which
 * can then be loaded into a #GdkPixbuf using
 * gdk_pixbuf_new_from_inline().
 */

134

135
struct _GtkImagePrivate
136
{
137 138 139
  GtkIconHelper *icon_helper;

  GdkPixbufAnimationIter *animation_iter;
140 141 142
  gint animation_timeout;

  float baseline_align;
143 144

  gchar                *filename;       /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
145
  gchar                *resource_path;  /* Only used with GTK_IMAGE_PIXBUF */
146 147
};

148

Havoc Pennington's avatar
Havoc Pennington committed
149
#define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
150 151
static gint gtk_image_draw                 (GtkWidget    *widget,
                                            cairo_t      *cr);
152 153
static void gtk_image_size_allocate        (GtkWidget    *widget,
                                            GtkAllocation*allocation);
154
static void gtk_image_unmap                (GtkWidget    *widget);
155
static void gtk_image_realize              (GtkWidget    *widget);
156 157 158 159 160 161 162
static void gtk_image_unrealize            (GtkWidget    *widget);
static void gtk_image_get_preferred_width  (GtkWidget    *widget,
                                            gint         *minimum,
                                            gint         *natural);
static void gtk_image_get_preferred_height (GtkWidget    *widget,
                                            gint         *minimum,
                                            gint         *natural);
163 164 165 166 167 168
static void gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
								   gint       width,
								   gint      *minimum,
								   gint      *natural,
								   gint      *minimum_baseline,
								   gint      *natural_baseline);
169

170
static void gtk_image_style_updated        (GtkWidget    *widget);
171 172
static void gtk_image_screen_changed       (GtkWidget    *widget,
                                            GdkScreen    *prev_screen);
173
static void gtk_image_finalize             (GObject      *object);
174 175 176 177 178 179 180 181 182 183 184 185
static void gtk_image_reset                (GtkImage     *image);

static void gtk_image_set_property         (GObject      *object,
                                            guint         prop_id,
                                            const GValue *value,
                                            GParamSpec   *pspec);
static void gtk_image_get_property         (GObject      *object,
                                            guint         prop_id,
                                            GValue       *value,
                                            GParamSpec   *pspec);

static void icon_theme_changed             (GtkImage     *image);
186

Havoc Pennington's avatar
Havoc Pennington committed
187 188 189 190
enum
{
  PROP_0,
  PROP_PIXBUF,
191
  PROP_SURFACE,
Havoc Pennington's avatar
Havoc Pennington committed
192 193 194 195
  PROP_FILE,
  PROP_STOCK,
  PROP_ICON_SET,
  PROP_ICON_SIZE,
196
  PROP_PIXEL_SIZE,
Havoc Pennington's avatar
Havoc Pennington committed
197
  PROP_PIXBUF_ANIMATION,
198
  PROP_ICON_NAME,
199
  PROP_STORAGE_TYPE,
200
  PROP_GICON,
201
  PROP_RESOURCE,
202
  PROP_USE_FALLBACK
Havoc Pennington's avatar
Havoc Pennington committed
203 204
};

Matthias Clasen's avatar
Matthias Clasen committed
205
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
206
G_DEFINE_TYPE_WITH_PRIVATE (GtkImage, gtk_image, GTK_TYPE_MISC)
Matthias Clasen's avatar
Matthias Clasen committed
207
G_GNUC_END_IGNORE_DEPRECATIONS
Elliot Lee's avatar
Elliot Lee committed
208 209 210 211

static void
gtk_image_class_init (GtkImageClass *class)
{
Havoc Pennington's avatar
Havoc Pennington committed
212
  GObjectClass *gobject_class;
Elliot Lee's avatar
Elliot Lee committed
213 214
  GtkWidgetClass *widget_class;

Havoc Pennington's avatar
Havoc Pennington committed
215 216 217 218
  gobject_class = G_OBJECT_CLASS (class);
  
  gobject_class->set_property = gtk_image_set_property;
  gobject_class->get_property = gtk_image_get_property;
219
  gobject_class->finalize = gtk_image_finalize;
220

Havoc Pennington's avatar
Havoc Pennington committed
221
  widget_class = GTK_WIDGET_CLASS (class);
222
  widget_class->draw = gtk_image_draw;
223 224
  widget_class->get_preferred_width = gtk_image_get_preferred_width;
  widget_class->get_preferred_height = gtk_image_get_preferred_height;
225
  widget_class->get_preferred_height_and_baseline_for_width = gtk_image_get_preferred_height_and_baseline_for_width;
226
  widget_class->size_allocate = gtk_image_size_allocate;
Havoc Pennington's avatar
Havoc Pennington committed
227
  widget_class->unmap = gtk_image_unmap;
228
  widget_class->realize = gtk_image_realize;
229
  widget_class->unrealize = gtk_image_unrealize;
230
  widget_class->style_updated = gtk_image_style_updated;
231
  widget_class->screen_changed = gtk_image_screen_changed;
Havoc Pennington's avatar
Havoc Pennington committed
232 233 234 235
  
  g_object_class_install_property (gobject_class,
                                   PROP_PIXBUF,
                                   g_param_spec_object ("pixbuf",
236 237
                                                        P_("Pixbuf"),
                                                        P_("A GdkPixbuf to display"),
Havoc Pennington's avatar
Havoc Pennington committed
238
                                                        GDK_TYPE_PIXBUF,
239
                                                        GTK_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
240

241 242 243 244 245 246 247 248
  g_object_class_install_property (gobject_class,
                                   PROP_SURFACE,
                                   g_param_spec_boxed ("surface",
						       P_("Surface"),
						       P_("A cairo_surface_t to display"),
						       CAIRO_GOBJECT_TYPE_SURFACE,
						       GTK_PARAM_READWRITE));

Havoc Pennington's avatar
Havoc Pennington committed
249 250 251
  g_object_class_install_property (gobject_class,
                                   PROP_FILE,
                                   g_param_spec_string ("file",
252 253
                                                        P_("Filename"),
                                                        P_("Filename to load and display"),
Havoc Pennington's avatar
Havoc Pennington committed
254
                                                        NULL,
255
                                                        GTK_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
256 257
  

258 259 260 261 262
  /**
   * GtkImage:stock:
   *
   * Deprecated: 3.10: Use #GtkImage:icon-name instead.
   */
Havoc Pennington's avatar
Havoc Pennington committed
263 264 265
  g_object_class_install_property (gobject_class,
                                   PROP_STOCK,
                                   g_param_spec_string ("stock",
266 267
                                                        P_("Stock ID"),
                                                        P_("Stock ID for a stock image to display"),
Havoc Pennington's avatar
Havoc Pennington committed
268
                                                        NULL,
269
                                                        GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
Havoc Pennington's avatar
Havoc Pennington committed
270
  
271 272 273 274 275 276
  /**
   * GtkImage:icon-set:
   *
   * Deprecated: 3.10: Use #GtkImage:icon-name instead.
   */
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
Havoc Pennington's avatar
Havoc Pennington committed
277 278
  g_object_class_install_property (gobject_class,
                                   PROP_ICON_SET,
279
                                   g_param_spec_boxed ("icon-set",
280 281
                                                       P_("Icon set"),
                                                       P_("Icon set to display"),
Havoc Pennington's avatar
Havoc Pennington committed
282
                                                       GTK_TYPE_ICON_SET,
283
                                                       GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
284 285
  G_GNUC_END_IGNORE_DEPRECATIONS;

Havoc Pennington's avatar
Havoc Pennington committed
286 287
  g_object_class_install_property (gobject_class,
                                   PROP_ICON_SIZE,
288
                                   g_param_spec_int ("icon-size",
289
                                                     P_("Icon size"),
290
                                                     P_("Symbolic size to use for stock icon, icon set or named icon"),
Havoc Pennington's avatar
Havoc Pennington committed
291 292
                                                     0, G_MAXINT,
                                                     DEFAULT_ICON_SIZE,
293
                                                     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
294 295 296
  /**
   * GtkImage:pixel-size:
   *
297 298
   * The "pixel-size" property can be used to specify a fixed size
   * overriding the #GtkImage:icon-size property for images of type 
299 300 301 302 303 304
   * %GTK_IMAGE_ICON_NAME. 
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
				   PROP_PIXEL_SIZE,
305
				   g_param_spec_int ("pixel-size",
306 307 308 309
						     P_("Pixel size"),
						     P_("Pixel size to use for named icon"),
						     -1, G_MAXINT,
						     -1,
310
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
311
  
Havoc Pennington's avatar
Havoc Pennington committed
312 313
  g_object_class_install_property (gobject_class,
                                   PROP_PIXBUF_ANIMATION,
314
                                   g_param_spec_object ("pixbuf-animation",
315 316
                                                        P_("Animation"),
                                                        P_("GdkPixbufAnimation to display"),
Havoc Pennington's avatar
Havoc Pennington committed
317
                                                        GDK_TYPE_PIXBUF_ANIMATION,
318
                                                        GTK_PARAM_READWRITE));
319 320 321 322

  /**
   * GtkImage:icon-name:
   *
323
   * The name of the icon in the icon theme. If the icon theme is
324 325 326 327 328 329
   * changed, the image will be updated automatically.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
                                   PROP_ICON_NAME,
330
                                   g_param_spec_string ("icon-name",
331 332 333
                                                        P_("Icon Name"),
                                                        P_("The name of the icon from the icon theme"),
                                                        NULL,
334
                                                        GTK_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
335
  
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
  /**
   * GtkImage:gicon:
   *
   * The GIcon displayed in the GtkImage. For themed icons,
   * If the icon theme is changed, the image will be updated
   * automatically.
   *
   * Since: 2.14
   */
  g_object_class_install_property (gobject_class,
                                   PROP_GICON,
                                   g_param_spec_object ("gicon",
                                                        P_("Icon"),
                                                        P_("The GIcon being displayed"),
                                                        G_TYPE_ICON,
                                                        GTK_PARAM_READWRITE));
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367

  /**
   * GtkImage:resource:
   *
   * A path to a resource file to display.
   *
   * Since: 3.8
   */
  g_object_class_install_property (gobject_class,
                                   PROP_RESOURCE,
                                   g_param_spec_string ("resource",
                                                        P_("Resource"),
                                                        P_("The resource path being displayed"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));

Havoc Pennington's avatar
Havoc Pennington committed
368 369
  g_object_class_install_property (gobject_class,
                                   PROP_STORAGE_TYPE,
Matthias Clasen's avatar
Matthias Clasen committed
370
                                   g_param_spec_enum ("storage-type",
371 372
                                                      P_("Storage type"),
                                                      P_("The representation being used for image data"),
Havoc Pennington's avatar
Havoc Pennington committed
373 374
                                                      GTK_TYPE_IMAGE_TYPE,
                                                      GTK_IMAGE_EMPTY,
375
                                                      GTK_PARAM_READABLE));
376

377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
  /**
   * GtkImage:use-fallback:
   *
   * Whether the icon displayed in the GtkImage will use
   * standard icon names fallback. The value of this property
   * is only relevant for images of type %GTK_IMAGE_ICON_NAME
   * and %GTK_IMAGE_GICON.
   *
   * Since: 3.0
   */
  g_object_class_install_property (gobject_class,
                                   PROP_USE_FALLBACK,
                                   g_param_spec_boolean ("use-fallback",
                                                         P_("Use Fallback"),
                                                         P_("Whether to use icon names fallback"),
                                                         FALSE,
393
                                                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
394

395
  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_IMAGE_ACCESSIBLE);
Elliot Lee's avatar
Elliot Lee committed
396 397 398 399 400
}

static void
gtk_image_init (GtkImage *image)
{
401
  GtkImagePrivate *priv;
402

403
  image->priv = gtk_image_get_instance_private (image);
404
  priv = image->priv;
405

406
  gtk_widget_set_has_window (GTK_WIDGET (image), FALSE);
407
  priv->icon_helper = _gtk_icon_helper_new ();
408
  _gtk_icon_helper_set_icon_size (priv->icon_helper, DEFAULT_ICON_SIZE);
409 410

  priv->filename = NULL;
Elliot Lee's avatar
Elliot Lee committed
411 412
}

413
static void
414
gtk_image_finalize (GObject *object)
415
{
416
  GtkImage *image = GTK_IMAGE (object);
417

418
  g_clear_object (&image->priv->icon_helper);
419
  
420 421
  g_free (image->priv->filename);

422 423
  G_OBJECT_CLASS (gtk_image_parent_class)->finalize (object);
};
424

Havoc Pennington's avatar
Havoc Pennington committed
425 426 427 428 429 430
static void 
gtk_image_set_property (GObject      *object,
			guint         prop_id,
			const GValue *value,
			GParamSpec   *pspec)
{
431
  GtkImage *image = GTK_IMAGE (object);
432
  GtkImagePrivate *priv = image->priv;
433
  GtkIconSize icon_size = _gtk_icon_helper_get_icon_size (priv->icon_helper);
Havoc Pennington's avatar
Havoc Pennington committed
434

435 436 437
  if (icon_size == GTK_ICON_SIZE_INVALID)
    icon_size = DEFAULT_ICON_SIZE;

Havoc Pennington's avatar
Havoc Pennington committed
438 439 440
  switch (prop_id)
    {
    case PROP_PIXBUF:
441
      gtk_image_set_from_pixbuf (image, g_value_get_object (value));
Havoc Pennington's avatar
Havoc Pennington committed
442
      break;
443
    case PROP_SURFACE:
444
      gtk_image_set_from_surface (image, g_value_get_boxed (value));
445
      break;
Havoc Pennington's avatar
Havoc Pennington committed
446
    case PROP_FILE:
447
      gtk_image_set_from_file (image, g_value_get_string (value));
Havoc Pennington's avatar
Havoc Pennington committed
448 449
      break;
    case PROP_STOCK:
450
      G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
451
      gtk_image_set_from_stock (image, g_value_get_string (value), icon_size);
452
      G_GNUC_END_IGNORE_DEPRECATIONS;
Havoc Pennington's avatar
Havoc Pennington committed
453 454
      break;
    case PROP_ICON_SET:
455
      G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
456
      gtk_image_set_from_icon_set (image, g_value_get_boxed (value), icon_size);
457
      G_GNUC_END_IGNORE_DEPRECATIONS;
Havoc Pennington's avatar
Havoc Pennington committed
458 459
      break;
    case PROP_ICON_SIZE:
460 461
      if (_gtk_icon_helper_set_icon_size (priv->icon_helper, g_value_get_int (value)))
        g_object_notify_by_pspec (object, pspec);
Havoc Pennington's avatar
Havoc Pennington committed
462
      break;
463
    case PROP_PIXEL_SIZE:
464
      gtk_image_set_pixel_size (image, g_value_get_int (value));
465
      break;
Havoc Pennington's avatar
Havoc Pennington committed
466
    case PROP_PIXBUF_ANIMATION:
467
      gtk_image_set_from_animation (image, g_value_get_object (value));
Havoc Pennington's avatar
Havoc Pennington committed
468
      break;
469
    case PROP_ICON_NAME:
470
      gtk_image_set_from_icon_name (image, g_value_get_string (value), icon_size);
471
      break;
472
    case PROP_GICON:
473
      gtk_image_set_from_gicon (image, g_value_get_object (value), icon_size);
474
      break;
475 476 477
    case PROP_RESOURCE:
      gtk_image_set_from_resource (image, g_value_get_string (value));
      break;
478

479
    case PROP_USE_FALLBACK:
480 481
      if (_gtk_icon_helper_set_use_fallback (priv->icon_helper, g_value_get_boolean (value)))
        g_object_notify_by_pspec (object, pspec);
482 483
      break;

Havoc Pennington's avatar
Havoc Pennington committed
484 485 486 487 488 489 490 491 492 493 494 495
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void 
gtk_image_get_property (GObject     *object,
			guint        prop_id,
			GValue      *value,
			GParamSpec  *pspec)
{
496
  GtkImage *image = GTK_IMAGE (object);
497
  GtkImagePrivate *priv = image->priv;
Havoc Pennington's avatar
Havoc Pennington committed
498 499 500 501

  switch (prop_id)
    {
    case PROP_PIXBUF:
Cosimo Cecchi's avatar
Cosimo Cecchi committed
502
      g_value_set_object (value, _gtk_icon_helper_peek_pixbuf (priv->icon_helper));
Havoc Pennington's avatar
Havoc Pennington committed
503
      break;
504 505 506
    case PROP_SURFACE:
      g_value_set_boxed (value, _gtk_icon_helper_peek_surface (priv->icon_helper));
      break;
507 508 509
    case PROP_FILE:
      g_value_set_string (value, priv->filename);
      break;
Havoc Pennington's avatar
Havoc Pennington committed
510
    case PROP_STOCK:
511
      g_value_set_string (value, _gtk_icon_helper_get_stock_id (priv->icon_helper));
Havoc Pennington's avatar
Havoc Pennington committed
512 513
      break;
    case PROP_ICON_SET:
514
      G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
Cosimo Cecchi's avatar
Cosimo Cecchi committed
515
      g_value_set_boxed (value, _gtk_icon_helper_peek_icon_set (priv->icon_helper));
516 517
      G_GNUC_END_IGNORE_DEPRECATIONS;
      break;
Havoc Pennington's avatar
Havoc Pennington committed
518
    case PROP_ICON_SIZE:
519
      g_value_set_int (value, _gtk_icon_helper_get_icon_size (priv->icon_helper));
Havoc Pennington's avatar
Havoc Pennington committed
520
      break;
521
    case PROP_PIXEL_SIZE:
522
      g_value_set_int (value, _gtk_icon_helper_get_pixel_size (priv->icon_helper));
523
      break;
Havoc Pennington's avatar
Havoc Pennington committed
524
    case PROP_PIXBUF_ANIMATION:
Cosimo Cecchi's avatar
Cosimo Cecchi committed
525
      g_value_set_object (value, _gtk_icon_helper_peek_animation (priv->icon_helper));
Havoc Pennington's avatar
Havoc Pennington committed
526
      break;
527
    case PROP_ICON_NAME:
Cosimo Cecchi's avatar
Cosimo Cecchi committed
528
      g_value_set_string (value, _gtk_icon_helper_get_icon_name (priv->icon_helper));
529
      break;
530
    case PROP_GICON:
Cosimo Cecchi's avatar
Cosimo Cecchi committed
531
      g_value_set_object (value, _gtk_icon_helper_peek_gicon (priv->icon_helper));
Havoc Pennington's avatar
Havoc Pennington committed
532
      break;
533 534 535
    case PROP_RESOURCE:
      g_value_set_string (value, priv->resource_path);
      break;
536
    case PROP_USE_FALLBACK:
537
      g_value_set_boolean (value, _gtk_icon_helper_get_use_fallback (priv->icon_helper));
538
      break;
539 540 541
    case PROP_STORAGE_TYPE:
      g_value_set_enum (value, _gtk_icon_helper_get_storage_type (priv->icon_helper));
      break;
Havoc Pennington's avatar
Havoc Pennington committed
542 543 544 545 546 547
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

548

549 550
/**
 * gtk_image_new_from_file:
551
 * @filename: (type filename): a filename
552
 * 
Havoc Pennington's avatar
Havoc Pennington committed
553
 * Creates a new #GtkImage displaying the file @filename. If the file
554
 * isn’t found or can’t be loaded, the resulting #GtkImage will
555
 * display a “broken image” icon. This function never returns %NULL,
Havoc Pennington's avatar
Havoc Pennington committed
556 557 558 559 560 561 562 563 564 565 566 567 568
 * it always returns a valid #GtkImage widget.
 *
 * If the file contains an animation, the image will contain an
 * animation.
 *
 * If you need to detect failures to load the file, use
 * gdk_pixbuf_new_from_file() to load the file yourself, then create
 * the #GtkImage from the pixbuf. (Or for animations, use
 * gdk_pixbuf_animation_new_from_file()).
 *
 * The storage type (gtk_image_get_storage_type()) of the returned
 * image is not defined, it will be whatever is appropriate for
 * displaying the file.
569
 * 
570
 * Returns: a new #GtkImage
571
 **/
572 573 574 575 576
GtkWidget*
gtk_image_new_from_file   (const gchar *filename)
{
  GtkImage *image;

Manish Singh's avatar
Manish Singh committed
577
  image = g_object_new (GTK_TYPE_IMAGE, NULL);
578 579 580 581 582 583

  gtk_image_set_from_file (image, filename);

  return GTK_WIDGET (image);
}

584 585 586 587 588
/**
 * gtk_image_new_from_resource:
 * @resource_path: a resource path
 *
 * Creates a new #GtkImage displaying the resource file @resource_path. If the file
589
 * isn’t found or can’t be loaded, the resulting #GtkImage will
590
 * display a “broken image” icon. This function never returns %NULL,
591 592 593 594 595 596 597 598 599 600 601 602 603 604
 * it always returns a valid #GtkImage widget.
 *
 * If the file contains an animation, the image will contain an
 * animation.
 *
 * If you need to detect failures to load the file, use
 * gdk_pixbuf_new_from_file() to load the file yourself, then create
 * the #GtkImage from the pixbuf. (Or for animations, use
 * gdk_pixbuf_animation_new_from_file()).
 *
 * The storage type (gtk_image_get_storage_type()) of the returned
 * image is not defined, it will be whatever is appropriate for
 * displaying the file.
 *
605
 * Returns: a new #GtkImage
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
 *
 * Since: 3.4
 **/
GtkWidget*
gtk_image_new_from_resource (const gchar *resource_path)
{
  GtkImage *image;

  image = g_object_new (GTK_TYPE_IMAGE, NULL);

  gtk_image_set_from_resource (image, resource_path);

  return GTK_WIDGET (image);
}

621 622
/**
 * gtk_image_new_from_pixbuf:
623 624
 * @pixbuf: (allow-none): a #GdkPixbuf, or %NULL
 *
625 626 627 628 629
 * Creates a new #GtkImage displaying @pixbuf.
 * The #GtkImage does not assume a reference to the
 * pixbuf; you still need to unref it if you own references.
 * #GtkImage will add its own reference rather than adopting yours.
 * 
630 631
 * Note that this function just creates an #GtkImage from the pixbuf. The
 * #GtkImage created will not react to state changes. Should you want that, 
632
 * you should use gtk_image_new_from_icon_name().
633
 * 
634
 * Returns: a new #GtkImage
635
 **/
636 637 638 639 640
GtkWidget*
gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
{
  GtkImage *image;

Manish Singh's avatar
Manish Singh committed
641
  image = g_object_new (GTK_TYPE_IMAGE, NULL);
642 643 644 645 646 647

  gtk_image_set_from_pixbuf (image, pixbuf);

  return GTK_WIDGET (image);  
}

648 649 650 651 652 653 654 655 656
/**
 * gtk_image_new_from_surface:
 * @surface: (allow-none): a #cairo_surface_t, or %NULL
 *
 * Creates a new #GtkImage displaying @surface.
 * The #GtkImage does not assume a reference to the
 * surface; you still need to unref it if you own references.
 * #GtkImage will add its own reference rather than adopting yours.
 * 
657
 * Returns: a new #GtkImage
658 659
 *
 * Since: 3.10
660 661 662 663 664 665 666 667 668 669 670 671 672
 **/
GtkWidget*
gtk_image_new_from_surface (cairo_surface_t *surface)
{
  GtkImage *image;

  image = g_object_new (GTK_TYPE_IMAGE, NULL);

  gtk_image_set_from_surface (image, surface);

  return GTK_WIDGET (image);  
}

673 674 675
/**
 * gtk_image_new_from_stock:
 * @stock_id: a stock icon name
676
 * @size: (type int): a stock icon size
677 678
 * 
 * Creates a #GtkImage displaying a stock icon. Sample stock icon
679
 * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. Sample stock sizes
680
 * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
681
 * icon name isn’t known, the image will be empty.
682 683
 * You can register your own stock icon names, see
 * gtk_icon_factory_add_default() and gtk_icon_factory_add().
684
 * 
685
 * Returns: a new #GtkImage displaying the stock icon
686 687
 *
 * Deprecated: 3.10: Use gtk_image_new_from_icon_name() instead.
688
 **/
689 690
GtkWidget*
gtk_image_new_from_stock (const gchar    *stock_id,
691
                          GtkIconSize     size)
692 693 694
{
  GtkImage *image;

Manish Singh's avatar
Manish Singh committed
695
  image = g_object_new (GTK_TYPE_IMAGE, NULL);
696

697
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
698
  gtk_image_set_from_stock (image, stock_id, size);
699
  G_GNUC_END_IGNORE_DEPRECATIONS;
700 701 702 703

  return GTK_WIDGET (image);
}

704 705 706
/**
 * gtk_image_new_from_icon_set:
 * @icon_set: a #GtkIconSet
707
 * @size: (type int): a stock icon size
708 709 710
 *
 * Creates a #GtkImage displaying an icon set. Sample stock sizes are
 * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. Instead of using
711
 * this function, usually it’s better to create a #GtkIconFactory, put
712 713 714 715 716 717 718 719 720
 * your icon sets in the icon factory, add the icon factory to the
 * list of default factories with gtk_icon_factory_add_default(), and
 * then use gtk_image_new_from_stock(). This will allow themes to
 * override the icon you ship with your application.
 *
 * The #GtkImage does not assume a reference to the
 * icon set; you still need to unref it if you own references.
 * #GtkImage will add its own reference rather than adopting yours.
 * 
721
 * Returns: a new #GtkImage
722 723
 *
 * Deprecated: 3.10: Use gtk_image_new_from_icon_name() instead.
724
 **/
725 726
GtkWidget*
gtk_image_new_from_icon_set (GtkIconSet     *icon_set,
727
                             GtkIconSize     size)
728 729 730
{
  GtkImage *image;

Manish Singh's avatar
Manish Singh committed
731
  image = g_object_new (GTK_TYPE_IMAGE, NULL);
732

733 734
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;

735
  gtk_image_set_from_icon_set (image, icon_set, size);
Elliot Lee's avatar
Elliot Lee committed
736

737 738
  G_GNUC_END_IGNORE_DEPRECATIONS;

Elliot Lee's avatar
Elliot Lee committed
739 740 741
  return GTK_WIDGET (image);
}

Havoc Pennington's avatar
Havoc Pennington committed
742 743 744 745 746 747 748 749
/**
 * gtk_image_new_from_animation:
 * @animation: an animation
 * 
 * Creates a #GtkImage displaying the given animation.
 * The #GtkImage does not assume a reference to the
 * animation; you still need to unref it if you own references.
 * #GtkImage will add its own reference rather than adopting yours.
750 751 752 753 754 755
 *
 * Note that the animation frames are shown using a timeout with
 * #G_PRIORITY_DEFAULT. When using animations to indicate busyness,
 * keep in mind that the animation will only be shown if the main loop
 * is not busy with something that has a higher priority.
 *
756
 * Returns: a new #GtkImage widget
Havoc Pennington's avatar
Havoc Pennington committed
757 758 759 760 761 762 763 764
 **/
GtkWidget*
gtk_image_new_from_animation (GdkPixbufAnimation *animation)
{
  GtkImage *image;

  g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
  
Manish Singh's avatar
Manish Singh committed
765
  image = g_object_new (GTK_TYPE_IMAGE, NULL);
Havoc Pennington's avatar
Havoc Pennington committed
766 767 768 769 770 771

  gtk_image_set_from_animation (image, animation);

  return GTK_WIDGET (image);
}

772 773 774
/**
 * gtk_image_new_from_icon_name:
 * @icon_name: an icon name
775
 * @size: (type int): a stock icon size
776 777
 * 
 * Creates a #GtkImage displaying an icon from the current icon theme.
778
 * If the icon name isn’t known, a “broken image” icon will be
779 780 781
 * displayed instead.  If the current icon theme is changed, the icon
 * will be updated appropriately.
 * 
782
 * Returns: a new #GtkImage displaying the themed icon
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
 *
 * Since: 2.6
 **/
GtkWidget*
gtk_image_new_from_icon_name (const gchar    *icon_name,
			      GtkIconSize     size)
{
  GtkImage *image;

  image = g_object_new (GTK_TYPE_IMAGE, NULL);

  gtk_image_set_from_icon_name (image, icon_name, size);

  return GTK_WIDGET (image);
}

799 800 801
/**
 * gtk_image_new_from_gicon:
 * @icon: an icon
802
 * @size: (type int): a stock icon size
803 804
 * 
 * Creates a #GtkImage displaying an icon from the current icon theme.
805
 * If the icon name isn’t known, a “broken image” icon will be
806 807 808
 * displayed instead.  If the current icon theme is changed, the icon
 * will be updated appropriately.
 * 
809
 * Returns: a new #GtkImage displaying the themed icon
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
 *
 * Since: 2.14
 **/
GtkWidget*
gtk_image_new_from_gicon (GIcon *icon,
			  GtkIconSize     size)
{
  GtkImage *image;

  image = g_object_new (GTK_TYPE_IMAGE, NULL);

  gtk_image_set_from_gicon (image, icon, size);

  return GTK_WIDGET (image);
}

826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
typedef struct {
  GtkImage *image;
  gint scale_factor;
} LoaderData;

static void
on_loader_size_prepared (GdkPixbufLoader *loader,
			 gint             width,
			 gint             height,
			 gpointer         user_data)
{
  LoaderData *loader_data = user_data;
  gint scale_factor;
  GdkPixbufFormat *format;

  /* Let the regular icon helper code path handle non-scalable images */
  format = gdk_pixbuf_loader_get_format (loader);
  if (!gdk_pixbuf_format_is_scalable (format))
    {
      loader_data->scale_factor = 1;
      return;
    }

  scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (loader_data->image));
  gdk_pixbuf_loader_set_size (loader, width * scale_factor, height * scale_factor);
  loader_data->scale_factor = scale_factor;
}

static GdkPixbufAnimation *
load_scalable_with_loader (GtkImage    *image,
			   const gchar *file_path,
			   const gchar *resource_path,
			   gint        *scale_factor_out)
{
  GdkPixbufLoader *loader;
  GBytes *bytes;
  char *contents;
  gsize length;
  gboolean res;
  GdkPixbufAnimation *animation;
  LoaderData loader_data;

  animation = NULL;
  bytes = NULL;

  loader = gdk_pixbuf_loader_new ();
  loader_data.image = image;

  g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), &loader_data);

  if (resource_path != NULL)
    {
      bytes = g_resources_lookup_data (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
    }
  else if (file_path != NULL)
    {
      res = g_file_get_contents (file_path, &contents, &length, NULL);
      if (res)
	bytes = g_bytes_new_take (contents, length);
    }
  else
    {
      g_assert_not_reached ();
    }

  if (!bytes)
    goto out;

  if (!gdk_pixbuf_loader_write_bytes (loader, bytes, NULL))
    goto out;

  if (!gdk_pixbuf_loader_close (loader, NULL))
    goto out;

  animation = gdk_pixbuf_loader_get_animation (loader);
  if (animation != NULL)
    {
      g_object_ref (animation);
      if (scale_factor_out != NULL)
	*scale_factor_out = loader_data.scale_factor;
    }

 out:
909
  gdk_pixbuf_loader_close (loader, NULL);
910 911 912 913 914 915
  g_object_unref (loader);
  g_bytes_unref (bytes);

  return animation;
}

916 917 918
/**
 * gtk_image_set_from_file:
 * @image: a #GtkImage
919
 * @filename: (type filename) (allow-none): a filename or %NULL
920 921 922
 *
 * See gtk_image_new_from_file() for details.
 **/
923 924 925 926
void
gtk_image_set_from_file   (GtkImage    *image,
                           const gchar *filename)
{
927
  GtkImagePrivate *priv;
Havoc Pennington's avatar
Havoc Pennington committed
928
  GdkPixbufAnimation *anim;
929
  gint scale_factor;
930 931
  
  g_return_if_fail (GTK_IS_IMAGE (image));
Havoc Pennington's avatar
Havoc Pennington committed
932

933 934
  priv = image->priv;

Havoc Pennington's avatar
Havoc Pennington committed
935
  g_object_freeze_notify (G_OBJECT (image));
936
  
937
  gtk_image_clear (image);
938 939

  if (filename == NULL)
Havoc Pennington's avatar
Havoc Pennington committed
940
    {
941
      priv->filename = NULL;
Havoc Pennington's avatar
Havoc Pennington committed
942 943 944
      g_object_thaw_notify (G_OBJECT (image));
      return;
    }
945

946
  anim = load_scalable_with_loader (image, filename, NULL, &scale_factor);
947

Havoc Pennington's avatar
Havoc Pennington committed
948
  if (anim == NULL)
949
    {
950 951 952
      gtk_image_set_from_icon_name (image,
                                    "image-missing",
                                    DEFAULT_ICON_SIZE);
Havoc Pennington's avatar
Havoc Pennington committed
953
      g_object_thaw_notify (G_OBJECT (image));
954 955
      return;
    }
956

Havoc Pennington's avatar
Havoc Pennington committed
957 958 959 960
  /* We could just unconditionally set_from_animation,
   * but it's nicer for memory if we toss the animation
   * if it's just a single pixbuf
   */
961

Havoc Pennington's avatar
Havoc Pennington committed
962
  if (gdk_pixbuf_animation_is_static_image (anim))
963 964
    gtk_image_set_from_pixbuf (image,
			       gdk_pixbuf_animation_get_static_image (anim));
Havoc Pennington's avatar
Havoc Pennington committed
965
  else
966
    gtk_image_set_from_animation (image, anim);
Havoc Pennington's avatar
Havoc Pennington committed
967

968 969
  _gtk_icon_helper_set_pixbuf_scale (priv->icon_helper, scale_factor);

Manish Singh's avatar
Manish Singh committed
970
  g_object_unref (anim);
Havoc Pennington's avatar
Havoc Pennington committed
971

972 973
  priv->filename = g_strdup (filename);
  
Havoc Pennington's avatar
Havoc Pennington committed
974
  g_object_thaw_notify (G_OBJECT (image));
975 976
}

977 978 979 980 981 982 983 984
/**
 * gtk_image_set_from_resource:
 * @image: a #GtkImage
 * @resource_path: (allow-none): a resource path or %NULL
 *
 * See gtk_image_new_from_resource() for details.
 **/
void
Benjamin Otte's avatar
Benjamin Otte committed
985 986
gtk_image_set_from_resource (GtkImage    *image,
			     const gchar *resource_path)
987
{
988
  GtkImagePrivate *priv;
989
  GdkPixbufAnimation *animation;
990
  gint scale_factor;
991 992 993

  g_return_if_fail (GTK_IS_IMAGE (image));

994 995
  priv = image->priv;

996 997 998 999 1000 1001 1002 1003 1004 1005
  g_object_freeze_notify (G_OBJECT (image));

  gtk_image_clear (image);

  if (resource_path == NULL)
    {
      g_object_thaw_notify (G_OBJECT (image));
      return;
    }

1006
  animation = load_scalable_with_loader (image, NULL, resource_path, &scale_factor);
1007

1008
  if (animation == NULL)
1009
    {
1010 1011 1012
      gtk_image_set_from_icon_name (image,
                                    "image-missing",
                                    DEFAULT_ICON_SIZE);
1013 1014 1015 1016
      g_object_thaw_notify (G_OBJECT (image));
      return;
    }

1017 1018
  priv->resource_path = g_strdup (resource_path);

1019 1020 1021 1022
  if (gdk_pixbuf_animation_is_static_image (animation))
    gtk_image_set_from_pixbuf (image, gdk_pixbuf_animation_get_static_image (animation));
  else
    gtk_image_set_from_animation (image, animation);
1023 1024

  _gtk_icon_helper_set_pixbuf_scale (priv->icon_helper, scale_factor);
1025

1026 1027
  g_object_notify (G_OBJECT (image), "resource");

1028
  g_object_unref (animation);
1029 1030 1031 1032 1033

  g_object_thaw_notify (G_OBJECT (image));
}


1034 1035 1036
/**
 * gtk_image_set_from_pixbuf:
 * @image: a #GtkImage
1037
 * @pixbuf: (allow-none): a #GdkPixbuf or %NULL
1038
 *
1039
 * See gtk_image_new_from_pixbuf() for details.
1040
 **/
1041 1042 1043 1044
void
gtk_image_set_from_pixbuf (GtkImage  *image,
                           GdkPixbuf *pixbuf)
{
1045
  GtkImagePrivate *priv;
1046

1047 1048 1049
  g_return_if_fail (GTK_IS_IMAGE (image));
  g_return_if_fail (pixbuf == NULL ||
                    GDK_IS_PIXBUF (pixbuf));
Havoc Pennington's avatar
Havoc Pennington committed
1050

1051 1052
  priv = image->priv;

Havoc Pennington's avatar
Havoc Pennington committed
1053
  g_object_freeze_notify (G_OBJECT (image));
1054
  
1055
  gtk_image_clear (image);
1056 1057

  if (pixbuf != NULL)
1058
    _gtk_icon_helper_set_pixbuf (priv->icon_helper, pixbuf);
Havoc Pennington's avatar
Havoc Pennington committed
1059 1060 1061 1062

  g_object_notify (G_OBJECT (image), "pixbuf");
  
  g_object_thaw_notify (G_OBJECT (image));
1063 1064
}

1065 1066 1067 1068
/**
 * gtk_image_set_from_stock:
 * @image: a #GtkImage
 * @stock_id: a stock icon name
1069
 * @size: (type int): a stock icon size
1070
 *
1071
 * See gtk_image_new_from_stock() for details.
1072 1073
 *
 * Deprecated: 3.10: Use gtk_image_set_from_icon_name() instead.
1074
 **/
1075 1076 1077
void
gtk_image_set_from_stock  (GtkImage       *image,
                           const gchar    *stock_id,
1078
                           GtkIconSize     size)
1079
{
1080
  GtkImagePrivate *priv;
Havoc Pennington's avatar
Havoc Pennington committed
1081
  gchar *new_id;
1082

1083
  g_return_if_fail (GTK_IS_IMAGE (image));
Havoc Pennington's avatar
Havoc Pennington committed
1084

1085 1086
  priv = image->priv;

Havoc Pennington's avatar
Havoc Pennington committed
1087 1088 1089
  g_object_freeze_notify (G_OBJECT (image));

  new_id = g_strdup (stock_id);
1090
  gtk_image_clear (image);
1091

Havoc Pennington's avatar
Havoc Pennington committed
1092 1093
  if (new_id)
    {
1094 1095
      _gtk_icon_helper_set_stock_id (priv->icon_helper, new_id, size);
      g_free (new_id);
1096
    }
Havoc Pennington's avatar
Havoc Pennington committed
1097 1098

  g_object_notify (G_OBJECT (image), "stock");
1099
  g_object_notify (G_OBJECT (image), "icon-size");
Havoc Pennington's avatar
Havoc Pennington committed
1100 1101
  
  g_object_thaw_notify (G_OBJECT (image));
1102 1103
}

1104 1105 1106 1107
/**
 * gtk_image_set_from_icon_set:
 * @image: a #GtkImage
 * @icon_set: a #GtkIconSet
1108
 * @size: (type int): a stock icon size
1109 1110
 *
 * See gtk_image_new_from_icon_set() for details.
1111 1112
 *
 * Deprecated: 3.10: Use gtk_image_set_from_icon_name() instead.
1113
 **/
1114 1115 1116
void
gtk_image_set_from_icon_set  (GtkImage       *image,
                              GtkIconSet     *icon_set,
1117
                              GtkIconSize     size)
1118
{
1119
  GtkImagePrivate *priv;
1120

1121 1122
  g_return_if_fail (GTK_IS_IMAGE (image));

1123 1124
  priv = image->priv;

Havoc Pennington's avatar
Havoc Pennington committed
1125
  g_object_freeze_notify (G_OBJECT (image));
1126

1127 1128
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;

1129 1130 1131
  if (icon_set)
    gtk_icon_set_ref (icon_set);
  
1132
  gtk_image_clear (image);
1133 1134 1135

  if (icon_set)
    {      
1136 1137
      _gtk_icon_helper_set_icon_set (priv->icon_helper, icon_set, size);
      gtk_icon_set_unref (icon_set);
1138
    }
1139 1140 1141

  G_GNUC_END_IGNORE_DEPRECATIONS;

1142 1143
  g_object_notify (G_OBJECT (image), "icon-set");
  g_object_notify (G_OBJECT (image), "icon-size");
Havoc Pennington's avatar
Havoc Pennington committed
1144 1145
  
  g_object_thaw_notify (G_OBJECT (image));
1146 1147
}

Havoc Pennington's avatar
Havoc Pennington committed
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
/**
 * gtk_image_set_from_animation:
 * @image: a #GtkImage
 * @animation: the #GdkPixbufAnimation
 * 
 * Causes the #GtkImage to display the given animation (or display
 * nothing, if you set the animation to %NULL).
 **/
void
gtk_image_set_from_animation (GtkImage           *image,
                              GdkPixbufAnimation *animation)
{
1160
  GtkImagePrivate *priv;
1161

Havoc Pennington's avatar
Havoc Pennington committed
1162 1163 1164
  g_return_if_fail (GTK_IS_IMAGE (image));
  g_return_if_fail (animation == NULL ||
                    GDK_IS_PIXBUF_ANIMATION (animation));
Havoc Pennington's avatar
Havoc Pennington committed
1165

1166 1167
  priv = image->priv;

Havoc Pennington's avatar
Havoc Pennington committed
1168
  g_object_freeze_notify (G_OBJECT (image));
Havoc Pennington's avatar
Havoc Pennington committed
1169 1170
  
  if (animation)
Manish Singh's avatar
Manish Singh committed
1171
    g_object_ref (animation);
Havoc Pennington's avatar
Havoc Pennington committed
1172

1173
  gtk_image_clear (image);
Havoc Pennington's avatar
Havoc Pennington committed
1174 1175 1176

  if (animation != NULL)
    {
1177 1178
      _gtk_icon_helper_set_animation (priv->icon_helper, animation);
      g_object_unref (animation);
Havoc Pennington's avatar
Havoc Pennington committed
1179
    }
Havoc Pennington's avatar
Havoc Pennington committed
1180

1181
  g_object_notify (G_OBJECT (image), "pixbuf-animation");
Havoc Pennington's avatar
Havoc Pennington committed
1182 1183
  
  g_object_thaw_notify (G_OBJECT (image));
Havoc Pennington's avatar
Havoc Pennington committed
1184 1185
}

1186 1187 1188 1189
/**
 * gtk_image_set_from_icon_name:
 * @image: a #GtkImage
 * @icon_name: an icon name
1190
 * @size: (type int): an icon size
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
 *
 * See gtk_image_new_from_icon_name() for details.
 * 
 * Since: 2.6
 **/
void
gtk_image_set_from_icon_name  (GtkImage       *image,
			       const gchar    *icon_name,
			       GtkIconSize     size)
{
1201
  GtkImagePrivate *priv;
1202
  gchar *new_name;
1203

1204 1205
  g_return_if_fail (GTK_IS_IMAGE (image));

1206 1207
  priv = image->priv;

1208 1209 1210
  g_object_freeze_notify (G_OBJECT (image));

  new_name = g_strdup (icon_name);
1211
  gtk_image_clear (image);
1212 1213 1214

  if (new_name)
    {
1215 1216
      _gtk_icon_helper_set_icon_name (priv->icon_helper, new_name, size);
      g_free (new_name);
1217 1218
    }

1219 1220
  g_object_notify (G_OBJECT (image), "icon-name");
  g_object_notify (G_OBJECT (image), "icon-size");
1221 1222 1223 1224
  
  g_object_thaw_notify (G_OBJECT (image));
}

1225 1226 1227 1228
/**
 * gtk_image_set_from_gicon:
 * @image: a #GtkImage
 * @icon: an icon
1229
 * @size: (type int): an icon size
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239
 *
 * See gtk_image_new_from_gicon() for details.
 * 
 * Since: 2.14
 **/
void
gtk_image_set_from_gicon  (GtkImage       *image,
			   GIcon          *icon,
			   GtkIconSize     size)
{
1240
  GtkImagePrivate *priv;
1241

1242 1243
  g_return_if_fail (GTK_IS_IMAGE (image));

1244 1245
  priv = image->priv;

1246 1247 1248 1249
  g_object_freeze_notify (G_OBJECT (image));

  if (icon)
    g_object_ref (icon);
1250

1251 1252 1253 1254
  gtk_image_clear (image);

  if (icon)
    {
1255 1256
      _gtk_icon_helper_set_gicon (priv->icon_helper, icon, size);
      g_object_unref (icon);
1257 1258 1259 1260 1261 1262 1263 1264
    }

  g_object_notify (G_OBJECT (image), "gicon");
  g_object_notify (G_OBJECT (image), "icon-size");
  
  g_object_thaw_notify (G_OBJECT (image));
}

1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
/**
 * gtk_image_set_from_surface:
 * @image: a #GtkImage
 * @surface: a cairo_surface_t
 *
 * See gtk_image_new_from_surface() for details.
 * 
 * Since: 3.10
 **/
void
gtk_image_set_from_surface (GtkImage       *image,
			    cairo_surface_t *surface)
{
  GtkImagePrivate *priv;

  g_return_if_fail (GTK_IS_IMAGE (image));

  priv = image->priv;

  g_object_freeze_notify (G_OBJECT (image));

  if (surface)
    cairo_surface_reference (surface);

  gtk_image_clear (image);

  if (surface)
    {
      _gtk_icon_helper_set_surface (priv->icon_helper, surface);
      cairo_surface_destroy (surface);
    }

  g_object_notify (G_OBJECT (image), "surface");
  
  g_object_thaw_notify (G_OBJECT (image));
}

1302 1303 1304 1305 1306 1307 1308 1309
/**
 * gtk_image_get_storage_type:
 * @image: a #GtkImage
 * 
 * Gets the type of representation being used by the #GtkImage
 * to store image data. If the #GtkImage has no image data,
 * the return value will be %GTK_IMAGE_EMPTY.
 * 
1310
 * Returns: image representation being used
1311
 **/
1312 1313 1314 1315 1316
GtkImageType
gtk_image_get_storage_type (GtkImage *image)
{
  g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);

1317
  return _gtk_icon_helper_get_storage_type (image->priv->icon_helper);
1318 1319
}

1320 1321 1322 1323 1324 1325 1326 1327 1328 1329
/**
 * gtk_image_get_pixbuf:
 * @image: a #GtkImage
 *
 * Gets the #GdkPixbuf being displayed by the #GtkImage.
 * The storage type of the image must be %GTK_IMAGE_EMPTY or
 * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
 * The caller of this function does not own a reference to the
 * returned pixbuf.
 * 
1330
 * Returns: (transfer none): the displayed pixbuf, or %NULL if
1331
 * the image is empty
1332
 **/
1333 1334 1335 1336 1337
GdkPixbuf*
gtk_image_get_pixbuf (GtkImage *image)
{
  g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);

1338
  return _gtk_icon_helper_peek_pixbuf (image->priv->icon_helper);
1339 1340
}

1341 1342 1343
/**
 * gtk_image_get_stock:
 * @image: a #GtkImage
1344 1345
 * @stock_id: (out) (transfer none) (allow-none): place to store a
 *     stock icon name, or %NULL
1346 1347
 * @size: (out) (allow-none) (type int): place to store a stock icon
 *     size, or %NULL
1348 1349 1350 1351
 *
 * Gets the stock icon name and size being displayed by the #GtkImage.
 * The storage type of the image must be %GTK_IMAGE_EMPTY or
 * %GTK_IMAGE_STOCK (see gtk_image_get_storage_type()).
1352
 * The returned string is owned by the #GtkImage and should not
1353
 * be freed.
1354 1355
 *
 * Deprecated: 3.10: Use gtk_image_get_icon_name() instead.
1356
 **/
1357 1358 1359
void
gtk_image_get_stock  (GtkImage        *image,
                      gchar          **stock_id,
1360
                      GtkIconSize     *size)
1361
{