]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkimage.c
Add docs for new ports.
[~andy/gtk] / gtk / gtkimage.c
index b512292779a941a5175f3a20a3f2a15e40e880fe..a2f18baca7bc3fe7c2b7f79901df2d18221c333f 100644 (file)
@@ -41,6 +41,9 @@ typedef struct _GtkImagePrivate GtkImagePrivate;
 
 struct _GtkImagePrivate
 {
+  /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
+  gchar *filename;
+
   gint pixel_size;
 };
 
@@ -62,7 +65,6 @@ static void gtk_image_style_set    (GtkWidget      *widget,
 static void gtk_image_screen_changed (GtkWidget    *widget,
                                      GdkScreen    *prev_screen);
 static void gtk_image_destroy      (GtkObject      *object);
-static void gtk_image_clear        (GtkImage       *image);
 static void gtk_image_reset        (GtkImage       *image);
 static void gtk_image_calc_size    (GtkImage       *image);
 
@@ -120,7 +122,7 @@ gtk_image_get_type (void)
        (GInstanceInitFunc) gtk_image_init,
       };
 
-      image_type = g_type_register_static (GTK_TYPE_MISC, "GtkImage",
+      image_type = g_type_register_static (GTK_TYPE_MISC, I_("GtkImage"),
                                           &image_info, 0);
     }
 
@@ -192,7 +194,7 @@ gtk_image_class_init (GtkImageClass *class)
                                                         P_("Filename"),
                                                         P_("Filename to load and display"),
                                                         NULL,
-                                                        GTK_PARAM_WRITABLE));
+                                                        GTK_PARAM_READWRITE));
   
 
   g_object_class_install_property (gobject_class,
@@ -285,6 +287,8 @@ gtk_image_init (GtkImage *image)
   image->mask = NULL;
 
   priv->pixel_size = -1;
+
+  priv->filename = NULL;
 }
 
 static void
@@ -304,10 +308,8 @@ gtk_image_set_property (GObject      *object,
                        GParamSpec   *pspec)
 {
   GtkImage *image;
-  GtkImagePrivate *priv;
 
   image = GTK_IMAGE (object);
-  priv = GTK_IMAGE_GET_PRIVATE (image);
   
   switch (prop_id)
     {
@@ -349,8 +351,7 @@ gtk_image_set_property (GObject      *object,
         }
       break;
     case PROP_FILE:
-      gtk_image_set_from_file (image,
-                               g_value_get_string (value));
+      gtk_image_set_from_file (image, g_value_get_string (value));
       break;
     case PROP_STOCK:
       gtk_image_set_from_stock (image, g_value_get_string (value),
@@ -439,6 +440,9 @@ gtk_image_get_property (GObject     *object,
         g_value_set_object (value,
                             image->data.image.image);
       break;
+    case PROP_FILE:
+      g_value_set_string (value, priv->filename);
+      break;
     case PROP_STOCK:
       if (image->storage_type != GTK_IMAGE_STOCK)
         g_value_set_string (value, NULL);
@@ -605,9 +609,9 @@ gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
  * @size: a stock icon size
  * 
  * Creates a #GtkImage displaying a stock icon. Sample stock icon
- * names are #GTK_STOCK_OPEN, #GTK_STOCK_EXIT. Sample stock sizes
+ * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. Sample stock sizes
  * are #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_SMALL_TOOLBAR. If the stock
- * icon name isn't known, a "broken image" icon will be displayed instead.
+ * icon name isn't known, the image will be empty.
  * You can register your own stock icon names, see
  * gtk_icon_factory_add_default() and gtk_icon_factory_add().
  * 
@@ -667,7 +671,12 @@ gtk_image_new_from_icon_set (GtkIconSet     *icon_set,
  * 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.
- * 
+ *
+ * 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.
+ *
  * Return value: a new #GtkImage widget
  **/
 GtkWidget*
@@ -827,6 +836,7 @@ void
 gtk_image_set_from_file   (GtkImage    *image,
                            const gchar *filename)
 {
+  GtkImagePrivate *priv = GTK_IMAGE_GET_PRIVATE (image);
   GdkPixbufAnimation *anim;
   
   g_return_if_fail (GTK_IS_IMAGE (image));
@@ -837,10 +847,11 @@ gtk_image_set_from_file   (GtkImage    *image,
 
   if (filename == NULL)
     {
+      priv->filename = NULL;
       g_object_thaw_notify (G_OBJECT (image));
       return;
     }
-  
+
   anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
 
   if (anim == NULL)
@@ -858,17 +869,15 @@ gtk_image_set_from_file   (GtkImage    *image,
    */
 
   if (gdk_pixbuf_animation_is_static_image (anim))
-    {
-      gtk_image_set_from_pixbuf (image,
-                                 gdk_pixbuf_animation_get_static_image (anim));
-    }
+    gtk_image_set_from_pixbuf (image,
+                              gdk_pixbuf_animation_get_static_image (anim));
   else
-    {
-      gtk_image_set_from_animation (image, anim);
-    }
+    gtk_image_set_from_animation (image, anim);
 
   g_object_unref (anim);
 
+  priv->filename = g_strdup (filename);
+  
   g_object_thaw_notify (G_OBJECT (image));
 }
 
@@ -1392,9 +1401,12 @@ animation_timeout (gpointer data)
       g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
                      animation_timeout,
                      image);
-  
+
   gtk_widget_queue_draw (GTK_WIDGET (image));
 
+  if (GTK_WIDGET_DRAWABLE (image))
+    gdk_window_process_updates (GTK_WIDGET (image)->window, TRUE);
+
   GDK_THREADS_LEAVE ();
 
   return FALSE;
@@ -1547,10 +1559,7 @@ gtk_image_expose (GtkWidget      *widget,
       GdkBitmap *mask;
       GdkPixbuf *pixbuf;
       gboolean needs_state_transform;
-      GtkStockItem item;
-      gchar *stock_id;
-         
-      
+
       image = GTK_IMAGE (widget);
       misc = GTK_MISC (widget);
 
@@ -1573,11 +1582,9 @@ gtk_image_expose (GtkWidget      *widget,
        xalign = 1.0 - misc->xalign;
   
       x = floor (widget->allocation.x + misc->xpad
-                + ((widget->allocation.width - widget->requisition.width) * xalign)
-                + 0.5);
+                + ((widget->allocation.width - widget->requisition.width) * xalign));
       y = floor (widget->allocation.y + misc->ypad 
-                + ((widget->allocation.height - widget->requisition.height) * misc->yalign)
-                + 0.5);
+                + ((widget->allocation.height - widget->requisition.height) * misc->yalign));
       mask_x = x;
       mask_y = y;
       
@@ -1657,12 +1664,8 @@ gtk_image_expose (GtkWidget      *widget,
           break;
 
         case GTK_IMAGE_STOCK:
-         if (gtk_stock_lookup (image->data.stock.stock_id, &item))
-           stock_id = image->data.stock.stock_id;
-         else
-           stock_id = GTK_STOCK_MISSING_IMAGE;
           pixbuf = gtk_widget_render_icon (widget,
-                                           stock_id,
+                                           image->data.stock.stock_id,
                                            image->icon_size,
                                            NULL);
           if (pixbuf)
@@ -1789,9 +1792,6 @@ gtk_image_expose (GtkWidget      *widget,
                                   image_bound.height,
                                   GDK_RGB_DITHER_NORMAL,
                                   0, 0);
-
-                  g_object_unref (pixbuf);
-                  pixbuf = NULL;
                 }
             }
           else
@@ -1834,14 +1834,31 @@ gtk_image_expose (GtkWidget      *widget,
           gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
         }
       
+      if (pixbuf)
+       g_object_unref (pixbuf);
+
     } /* if widget is drawable */
 
   return FALSE;
 }
 
-static void
+/**
+ * gtk_image_clear:
+ * @image: a #GtkImage
+ *
+ * Resets the image to be empty.
+ *
+ * Since: 2.8
+ */
+void
 gtk_image_clear (GtkImage *image)
 {
+  GtkImagePrivate *priv;
+
+  g_return_if_fail (GTK_IS_IMAGE (image));
+
+  priv = GTK_IMAGE_GET_PRIVATE (image);
+
   g_object_freeze_notify (G_OBJECT (image));
   
   if (image->storage_type != GTK_IMAGE_EMPTY)
@@ -1937,6 +1954,13 @@ gtk_image_clear (GtkImage *image)
       
     }
 
+  if (priv->filename)
+    {
+      g_free (priv->filename);
+      priv->filename = NULL;
+      g_object_notify (G_OBJECT (image), "file");
+    }
+
   image->storage_type = GTK_IMAGE_EMPTY;
 
   memset (&image->data, '\0', sizeof (image->data));
@@ -1957,8 +1981,6 @@ gtk_image_calc_size (GtkImage *image)
 {
   GtkWidget *widget = GTK_WIDGET (image);
   GdkPixbuf *pixbuf = NULL;
-  GtkStockItem item;
-  gchar *stock_id;
   
   /* We update stock/icon set on every size request, because
    * the theme could have affected the size; for other kinds of
@@ -1968,12 +1990,8 @@ gtk_image_calc_size (GtkImage *image)
   switch (image->storage_type)
     {
     case GTK_IMAGE_STOCK:
-      if (gtk_stock_lookup (image->data.stock.stock_id, &item))
-       stock_id = image->data.stock.stock_id;
-      else
-       stock_id = GTK_STOCK_MISSING_IMAGE;
       pixbuf = gtk_widget_render_icon (widget,
-                                       stock_id,
+                                      image->data.stock.stock_id,
                                        image->icon_size,
                                        NULL);
       break;