Enlightenment CVS committal

Author  : moom
Project : e17
Module  : proto

Dir     : e17/proto/etk/src/lib


Modified Files:
        etk_image.c etk_image.h 


Log Message:
* [Etk_Image] Rewrite Etk_Image and add etk_image_set_from_data()


===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_image.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -3 -r1.26 -r1.27
--- etk_image.c 25 Dec 2006 14:04:53 -0000      1.26
+++ etk_image.c 29 Dec 2006 21:50:46 -0000      1.27
@@ -16,14 +16,14 @@
 
 enum Etk_Image_Property_Id
 {
+   ETK_IMAGE_SOURCE_PROPERTY,
    ETK_IMAGE_FILE_PROPERTY,
-   ETK_IMAGE_EDJE_FILE_PROPERTY,
-   ETK_IMAGE_EDJE_GROUP_PROPERTY,
-   ETK_IMAGE_EVAS_OBJECT_PROPERTY,     
-   ETK_IMAGE_KEEP_ASPECT_PROPERTY,
-   ETK_IMAGE_USE_EDJE_PROPERTY,
+   ETK_IMAGE_KEY_PROPERTY,
    ETK_IMAGE_STOCK_ID_PROPERTY,
-   ETK_IMAGE_STOCK_SIZE_PROPERTY
+   ETK_IMAGE_STOCK_SIZE_PROPERTY,
+   ETK_IMAGE_EVAS_OBJECT_PROPERTY,
+   ETK_IMAGE_KEEP_ASPECT_PROPERTY,
+   ETK_IMAGE_ASPECT_RATIO_PROPERTY
 };
 
 static void _etk_image_constructor(Etk_Image *image);
@@ -31,9 +31,9 @@
 static void _etk_image_property_set(Etk_Object *object, int property_id, 
Etk_Property_Value *value);
 static void _etk_image_property_get(Etk_Object *object, int property_id, 
Etk_Property_Value *value);
 static void _etk_image_realize_cb(Etk_Object *object, void *data);
-static void _etk_image_unrealize_cb(Etk_Object *object, void *data);
 static void _etk_image_size_request(Etk_Widget *widget, Etk_Size *size);
 static void _etk_image_size_allocate(Etk_Widget *widget, Etk_Geometry 
geometry);
+static void _etk_image_source_set(Etk_Image *image, Etk_Image_Source source);
 static void _etk_image_load(Etk_Image *image);
 
 /**************************
@@ -47,7 +47,7 @@
  * @brief Gets the type of an Etk_Image
  * @return Returns the type of an Etk_Image
  */
-Etk_Type *etk_image_type_get()
+Etk_Type *etk_image_type_get(void)
 {
    static Etk_Type *image_type = NULL;
 
@@ -56,22 +56,22 @@
       image_type = etk_type_new("Etk_Image", ETK_WIDGET_TYPE, 
sizeof(Etk_Image),
          ETK_CONSTRUCTOR(_etk_image_constructor), 
ETK_DESTRUCTOR(_etk_image_destructor));
       
-      etk_type_property_add(image_type, "image_file", ETK_IMAGE_FILE_PROPERTY,
-         ETK_PROPERTY_STRING, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_string(NULL));
-      etk_type_property_add(image_type, "edje_file", 
ETK_IMAGE_EDJE_FILE_PROPERTY,
+      etk_type_property_add(image_type, "source", ETK_IMAGE_SOURCE_PROPERTY,
+         ETK_PROPERTY_INT, ETK_PROPERTY_READABLE, 
etk_property_value_int(ETK_IMAGE_FILE));
+      etk_type_property_add(image_type, "file", ETK_IMAGE_FILE_PROPERTY,
          ETK_PROPERTY_STRING, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_string(NULL));
-      etk_type_property_add(image_type, "edje_group", 
ETK_IMAGE_EDJE_GROUP_PROPERTY,
+      etk_type_property_add(image_type, "key", ETK_IMAGE_KEY_PROPERTY,
          ETK_PROPERTY_STRING, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_string(NULL));
-      etk_type_property_add(image_type, "evas_object", 
ETK_IMAGE_EVAS_OBJECT_PROPERTY,
-         ETK_PROPERTY_POINTER, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_pointer(NULL));
-      etk_type_property_add(image_type, "keep_aspect", 
ETK_IMAGE_KEEP_ASPECT_PROPERTY,
-         ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_bool(ETK_TRUE));
-      etk_type_property_add(image_type, "use_edje", 
ETK_IMAGE_USE_EDJE_PROPERTY,
-         ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE, NULL);
       etk_type_property_add(image_type, "stock_id", 
ETK_IMAGE_STOCK_ID_PROPERTY,
          ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_int(ETK_STOCK_NO_STOCK));
       etk_type_property_add(image_type, "stock_size", 
ETK_IMAGE_STOCK_SIZE_PROPERTY,
          ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_int(ETK_STOCK_SMALL));
+      etk_type_property_add(image_type, "evas_object", 
ETK_IMAGE_EVAS_OBJECT_PROPERTY,
+         ETK_PROPERTY_POINTER, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_pointer(NULL));
+      etk_type_property_add(image_type, "keep_aspect", 
ETK_IMAGE_KEEP_ASPECT_PROPERTY,
+         ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_bool(ETK_TRUE));
+      etk_type_property_add(image_type, "aspect_ratio", 
ETK_IMAGE_ASPECT_RATIO_PROPERTY,
+         ETK_PROPERTY_DOUBLE, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_double(0.0));
 
       image_type->property_set = _etk_image_property_set;
       image_type->property_get = _etk_image_property_get;
@@ -81,33 +81,56 @@
 }
 
 /**
- * @brief Creates a new image
+ * @brief Creates a new empty image
  * @return Returns the new image widget
  */
-Etk_Widget *etk_image_new()
+Etk_Widget *etk_image_new(void)
 {
    return etk_widget_new(ETK_IMAGE_TYPE, NULL);
 }
 
 /**
  * @brief Creates a new image and loads the image from an image file
- * @param filename the name of the file to load
+ * @param filename the path of the file to load
  * @return Returns the new image widget
  */
 Etk_Widget *etk_image_new_from_file(const char *filename)
 {
-   return etk_widget_new(ETK_IMAGE_TYPE, "image_file", filename, NULL);
+   Etk_Widget *image;
+   
+   image = etk_image_new();
+   etk_image_set_from_file(ETK_IMAGE(image), filename);
+   return image;
+}
+
+/**
+ * @brief Creates a new image and loads the image from an edje-file
+ * @param filename the name of the edje-file to load
+ * @param group the name of the edje-group to load
+ * @return Returns the new image widget
+ */
+Etk_Widget *etk_image_new_from_edje(const char *filename, const char *group)
+{
+   Etk_Widget *image;
+   
+   image = etk_image_new();
+   etk_image_set_from_edje(ETK_IMAGE(image), filename, group);
+   return image;
 }
 
 /**
- * @brief Creates a new image and loads the image from an edje file
- * @param edje_filename the name of the edje file to load
- * @param edje_group the name of the edje group to load
+ * @brief Creates a new image and loads the image corresponding to the stock id
+ * @param stock_id the stock id corresponding to the image
+ * @param stock_size the size of the image to load
  * @return Returns the new image widget
  */
-Etk_Widget *etk_image_new_from_edje(const char *edje_filename, const char 
*edje_group)
+Etk_Widget *etk_image_new_from_stock(Etk_Stock_Id stock_id, Etk_Stock_Size 
stock_size)
 {
-   return etk_widget_new(ETK_IMAGE_TYPE, "edje_file", edje_filename, 
"edje_group", edje_group, NULL);
+   Etk_Widget *image;
+   
+   image = etk_image_new();
+   etk_image_set_from_stock(ETK_IMAGE(image), stock_id, stock_size);
+   return image;
 }
 
 /**
@@ -117,294 +140,389 @@
  */
 Etk_Widget *etk_image_new_from_evas_object(Evas_Object *evas_object)
 {
-   return etk_widget_new(ETK_IMAGE_TYPE, "evas_object", evas_object, NULL);
+   Etk_Widget *image;
+   
+   image = etk_image_new();
+   etk_image_set_from_evas_object(ETK_IMAGE(image), evas_object);
+   return image;
 }
 
 /**
- * @brief Creates a new image and loads the image corresponding to the stock id
- * @param stock_id the stock id corresponding to the image
- * @param stock_size the size of the image to load
+ * @brief Creates a new image from the given pixel data
+ * @param width the width of the image
+ * @param height the height of the image
+ * @param data a pointer to the pixels: the pixels have to be stored in the 
premul'ed ARGB format
+ * @param copy whether the pixels should be copied or not. If you decide not 
to copy the pixels, you have to make sure
+ * the memory area where the pixels are stored is valid during all the 
lifetime of the image
  * @return Returns the new image widget
  */
-Etk_Widget *etk_image_new_from_stock(Etk_Stock_Id stock_id, Etk_Stock_Size 
stock_size)
+Etk_Widget *etk_image_new_from_data(int width, int height, void *data, 
Etk_Bool copy)
 {
-   Etk_Widget *new_image;
+   Etk_Widget *image;
    
-   new_image = etk_image_new();
-   etk_image_set_from_stock(ETK_IMAGE(new_image), stock_id, stock_size);
-   return new_image;
+   image = etk_image_new();
+   etk_image_set_from_data(ETK_IMAGE(image), width, height, data, copy);
+   return image;
 }
 
 /**
  * @brief Loads the image from a file
  * @param image an image
- * @param filename the name of the file to load
+ * @param filename the path to the file to load
  */
 void etk_image_set_from_file(Etk_Image *image, const char *filename)
 {
-   Etk_Widget *widget;
-
-   if (!(widget = ETK_WIDGET(image)) || (image->filename == filename))
+   if (!image)
       return;
-
-   free(image->filename);
-   image->filename = filename ? strdup(filename) : NULL;
-   etk_object_notify(ETK_OBJECT(image), "image_file");
-
-   if (image->edje_group)
-   {
-      free(image->edje_group);
-      image->edje_group = NULL;
-      etk_object_notify(ETK_OBJECT(image), "edje_group");
-   }
-   if (image->edje_filename)
-   {
-      free(image->edje_filename);
-      image->edje_filename = NULL;
-      etk_object_notify(ETK_OBJECT(image), "edje_file");
-   }
-   if (image->use_edje)
+   
+   _etk_image_source_set(image, ETK_IMAGE_FILE);
+   if (image->info.file.filename != filename)
    {
-      image->use_edje = ETK_FALSE;
-      image->object_type_changed = ETK_TRUE;
-      etk_object_notify(ETK_OBJECT(image), "use_edje");
-   }
-   if (image->stock_id != ETK_STOCK_NO_STOCK)
-   {
-      image->stock_id = ETK_STOCK_NO_STOCK;
-      etk_object_notify(ETK_OBJECT(image), "stock_id");
+      free(image->info.file.filename);
+      image->info.file.filename = filename ? strdup(filename) : NULL;
+      etk_object_notify(ETK_OBJECT(image), "file");
    }
 
    _etk_image_load(image);
 }
 
 /**
- * @brief Gets the name of the file used for the image
+ * @brief Gets the path to the file used by the image
  * @param image an image
- * @return Returns the name of the file used by the image (NULL on failure)
+ * @return Returns the path to the file used by the image (NULL on failure)
  */
 const char *etk_image_file_get(Etk_Image *image)
 {
-   if (!image || image->use_edje)
+   if (!image || image->source != ETK_IMAGE_FILE)
       return NULL;
-   return image->filename;
+   return image->info.file.filename;
 }
 
 /**
  * @brief Loads the image from an edje file
  * @param image an image
- * @param edje_filename the name of the edje file to load
- * @param edje_group the name of the edje group to load
+ * @param filename the path to the edje-file to load
+ * @param group the name of the edje-group to load
  */
-void etk_image_set_from_edje(Etk_Image *image, const char *edje_filename, 
const char *edje_group)
+void etk_image_set_from_edje(Etk_Image *image, const char *filename, const 
char *group)
 {
-   Etk_Widget *widget;
-
-   if (!(widget = ETK_WIDGET(image)))
+   if (!image)
       return;
-
-   if (image->edje_filename != edje_filename)
-   {
-      free(image->edje_filename);
-      image->edje_filename = edje_filename ? strdup(edje_filename) : NULL;
-      etk_object_notify(ETK_OBJECT(image), "edje_file");
-   }
-   if (image->edje_group != edje_group)
-   {
-      free(image->edje_group);
-      image->edje_group = edje_group ? strdup(edje_group) : NULL;
-      etk_object_notify(ETK_OBJECT(image), "edje_group");
-   }
-
-   if (image->filename)
-   {
-      free(image->filename);
-      image->filename = NULL;
-      etk_object_notify(ETK_OBJECT(image), "image_file");
-   }
-   if (!image->use_edje)
+   
+   _etk_image_source_set(image, ETK_IMAGE_EDJE);
+   if (image->info.edje.filename != filename)
    {
-      image->use_edje = ETK_TRUE;
-      image->object_type_changed = ETK_TRUE;
-      etk_object_notify(ETK_OBJECT(image), "use_edje");
-   }
-   if (image->stock_id != ETK_STOCK_NO_STOCK)
-   {
-      image->stock_id = ETK_STOCK_NO_STOCK;
-      etk_object_notify(ETK_OBJECT(image), "stock_id");
+      free(image->info.edje.filename);
+      image->info.edje.filename = filename ? strdup(filename) : NULL;
+      etk_object_notify(ETK_OBJECT(image), "file");
+   }
+   if (image->info.edje.group != group)
+   {
+      free(image->info.edje.group);
+      image->info.edje.group = group ? strdup(group) : NULL;
+      etk_object_notify(ETK_OBJECT(image), "key");
    }
 
    _etk_image_load(image);
 }
 
 /**
- * @brief Gets the filename and the group of the edje object used for the image
+ * @brief Gets the filename and the group of the edje-object used for the image
  * @param image an image
- * @param edje_filename the location to store the filename of the edje object
- * @param edje_group the location to store the filename of the edje group
+ * @param filename the location to store the path to the edje-file used
+ * @param group the location to store the name of the edje-group used
  */
-void etk_image_edje_get(Etk_Image *image, char **edje_filename, char 
**edje_group)
+void etk_image_edje_get(Etk_Image *image, char **filename, char **group)
 {
-   if (!image || !image->use_edje)
+   if (!image || image->source != ETK_IMAGE_EDJE)
    {
-      if (edje_filename)
-         *edje_filename = NULL;
-      if (edje_group)
-         *edje_group = NULL;
+      if (filename)
+         *filename = NULL;
+      if (group)
+         *group = NULL;
       return;
    }
 
-   if (edje_filename)
-      *edje_filename = image->edje_filename;
-   if (edje_group)
-      *edje_group = image->edje_group;
+   if (filename)
+      *filename = image->info.edje.filename;
+   if (group)
+      *group = image->info.edje.group;
 }
 
 /**
- * @brief Loads the image from an evas object
+ * @brief Loads the image corresponding to the given stock-id
  * @param image an image
- * @param evas_object the evas object to use
+ * @param stock_id the stock-id corresponding to the icon to load
+ * @param stock_size the size of the stock-icon
  */
-void etk_image_set_from_evas_object(Etk_Image *image, Evas_Object *evas_object)
+void etk_image_set_from_stock(Etk_Image *image, Etk_Stock_Id stock_id, 
Etk_Stock_Size stock_size)
 {
-   Etk_Widget *widget;
-
-   if (!(widget = ETK_WIDGET(image)) || !evas_object)
+   if (!image)
       return;
-
-   if (image->image_object != evas_object)   
+   if (image->source == ETK_IMAGE_STOCK && image->info.stock.id == stock_id && 
image->info.stock.size == stock_size)
+      return;
+   
+   _etk_image_source_set(image, ETK_IMAGE_STOCK);
+   if (image->info.stock.id != stock_id)
    {
-      if (image->image_object && (image->filename || image->use_edje))
-        evas_object_del(image->image_object);
-      image->image_object = evas_object;      
-      etk_object_notify(ETK_OBJECT(image), "evas_object");
+      image->info.stock.id = stock_id;
+      etk_object_notify(ETK_OBJECT(image), "stock_id");
    }
-
-   if (image->edje_group)
+   if (image->info.stock.size != stock_size)
    {
-      free(image->edje_group);
-      image->edje_group = NULL;
-      etk_object_notify(ETK_OBJECT(image), "edje_group");
+      image->info.stock.size = stock_size;
+      etk_object_notify(ETK_OBJECT(image), "stock_size");
    }
-   if (image->edje_filename)
+   
+   _etk_image_load(image);
+}
+
+/**
+ * @brief Gets the stock-id and the stock-size used by the image
+ * @param image an image
+ * @param stock_id the location where to store the stock id used by the image
+ * @param stock_size the location where to store the stock size used by the 
image
+ */
+void etk_image_stock_get(Etk_Image *image, Etk_Stock_Id *stock_id, 
Etk_Stock_Size *stock_size)
+{
+   if (!image || image->source != ETK_IMAGE_STOCK)
    {
-      free(image->edje_filename);
-      image->edje_filename = NULL;
-      etk_object_notify(ETK_OBJECT(image), "edje_file");
+      if (stock_id)
+         *stock_id = ETK_STOCK_NO_STOCK;
+      if (stock_size)
+         *stock_size = ETK_STOCK_SMALL;
    }
-   if (image->use_edje)
-   {
-      image->use_edje = ETK_FALSE;
-      image->object_type_changed = ETK_TRUE;
-      etk_object_notify(ETK_OBJECT(image), "use_edje");
-   }      
-   if (image->filename)
+   else
    {
-      free(image->filename);
-      image->filename = NULL;
-      etk_object_notify(ETK_OBJECT(image), "image_file");
+      if (stock_id)
+         *stock_id = image->info.stock.id;
+      if (stock_size)
+         *stock_size = image->info.stock.size;
    }
+}
+
+/**
+ * @brief Loads the image from an Evas object
+ * @param image an image
+ * @param evas_object the Evas object to use. The object can be anything 
(image, edje object, emotion object, ...)
+ */
+void etk_image_set_from_evas_object(Etk_Image *image, Evas_Object *evas_object)
+{
+   if (!image)
+      return;
    
-   if (!image->use_object)
-   {
-      image->use_object = ETK_TRUE;
-      image->object_type_changed = ETK_TRUE;
-      etk_object_notify(ETK_OBJECT(image), "use_object");
-   }
-   if (image->stock_id != ETK_STOCK_NO_STOCK)
+   _etk_image_source_set(image, ETK_IMAGE_EVAS_OBJECT);
+   if (image->object != evas_object)
    {
-      image->stock_id = ETK_STOCK_NO_STOCK;
-      etk_object_notify(ETK_OBJECT(image), "stock_id");
+      image->object = evas_object;
+      etk_object_notify(ETK_OBJECT(image), "evas_object");
    }
 
    _etk_image_load(image);
 }
 
 /**
- * @brief Gets the evas object of the image
+ * @brief Gets the Evas object used by the image. You can call this function 
even if you have not explicitly set the
+ * Evas object used by this image. For example, if you have loaded the image 
from a file, this function will return the
+ * corresponding Evas image object. You should just be careful by manipulating 
it (don't use Edje functions on an image
+ * object for example).
  * @param image an image
- * @return Returns the evas object of the image
+ * @return Returns the Evas object of the image
  */
 Evas_Object *etk_image_evas_object_get(Etk_Image *image)
 {
    if (!image)
       return NULL;
-   return image->image_object;
+   return image->object;
 }
 
 /**
- * @brief Loads the image corresponding to the stock id
+ * @brief Sets the pixels of the image
  * @param image an image
- * @param stock_id the stock id corresponding to the image
- * @param stock_size the size of the stock icon
+ * @param width the width of the image
+ * @param height the height of the image
+ * @param data a pointer to the pixels: the pixels have to be stored in the 
premul'ed ARGB format
+ * @param copy whether the pixels should be copied or not. If you decide not 
to copy the pixels, you have to make sure
+ * the memory area where the pixels are stored is valid during all the 
lifetime of the image
+ * @return Returns the new image widget
  */
-void etk_image_set_from_stock(Etk_Image *image, Etk_Stock_Id stock_id, 
Etk_Stock_Size stock_size)
+void etk_image_set_from_data(Etk_Image *image, int width, int height, void 
*data, Etk_Bool copy)
 {
-   char *key;
-
-   if (!image || ((image->stock_id == stock_id) && (image->stock_size == 
stock_size)))
+   if (!image)
       return;
    
-   if ((key = etk_stock_key_get(stock_id, stock_size)))
-      etk_image_set_from_edje(image, etk_theme_icon_get(), key);
-   image->stock_id = stock_id;
-   image->stock_size = stock_size;
+   _etk_image_source_set(image, ETK_IMAGE_DATA);
    
-   etk_object_notify(ETK_OBJECT(image), "stock_id");
-   etk_object_notify(ETK_OBJECT(image), "stock_size");
+   if (data && width > 0 && height > 0)
+   {
+      image->info.data.size.w = width;
+      image->info.data.size.h = height;
+      image->info.data.copied = copy;
+      if (copy)
+      {
+         image->info.data.pixels = malloc(sizeof(width * height * 4));
+         memcpy(image->info.data.pixels, data, width * height * 4);
+      }
+      else
+         image->info.data.pixels = data;
+   }
+   
+   _etk_image_load(image);
 }
 
 /**
- * @brief Gets the stock id used by the image
+ * @brief Gets a pointer to the image pixels. This function only works if the 
image has been loaded from a file or if
+ * you have explicitely set its pixels with etk_image_set_from_data().
  * @param image an image
- * @param stock_id the location where to store the stock id used by the image
- * @param stock_size the location where to store the stock size used by the 
image
+ * @param for_writing whether or not you want to be able to modify the pixels 
of the image. If so, call
+ * etk_image_update() once you have finished.
+ * @return Returns a pointer to the location of the pixels (stored in 
premul'ed ARGB format)
+ * @note If the image is loaded from a file, it has to be realized. Otherwise 
it will return NULL
  */
-void etk_image_stock_get(Etk_Image *image, Etk_Stock_Id *stock_id, 
Etk_Stock_Size *stock_size)
+void *etk_image_data_get(Etk_Image *image, Etk_Bool for_writing)
+{
+   if (!image)
+      return NULL;
+   
+   if (image->source == ETK_IMAGE_FILE)
+   {
+      if (image->object)
+         return evas_object_image_data_get(image->object, for_writing);
+   }
+   else if (image->source == ETK_IMAGE_DATA)
+   {
+      if (image->object)
+         return evas_object_image_data_get(image->object, for_writing);
+      else
+         return image->info.data.pixels;
+   }
+   
+   return NULL;
+}
+
+/**
+ * @brief Gets the source of the image (file, edje-file, stock, Evas object or 
pixel data)
+ * @param image an image
+ * @return Returns the source of the image
+ */
+Etk_Image_Source etk_image_source_get(Etk_Image *image)
+{
+   if (!image)
+      return ETK_IMAGE_FILE;
+   return image->source;
+}
+
+/**
+ * @brief Updates all the pixels of the image (to be called after you have 
modified the pixel buffer for example).
+ * Same as etk_image_update_rect(image, 0, 0, image_width, image_height)
+ * @param image an image
+ */
+void etk_image_update(Etk_Image *image)
 {
-   if (stock_id)
-      *stock_id = image ? image->stock_id : ETK_STOCK_NO_STOCK;
-   if (stock_size)
-      *stock_size = image ? image->stock_size : ETK_STOCK_SMALL;
+   int w, h;
+   
+   if (!image)
+      return;
+   
+   etk_image_size_get(image, &w, &h);
+   etk_image_update_rect(image, 0, 0, w, h);
 }
 
 /**
- * @brief Gets the native size of the image
+ * @brief Updates a rectangle of the pixels of the image (to be called after 
you have modified the pixel buffer
+ * for example). It only has effect on image loaded from a pixel buffer
+ * @param image an image
+ * @param x the x position of the top-left corner of the rectangle to update
+ * @param y the y position of the top-left corner of the rectangle to update
+ * @param w the width of the rectangle to update
+ * @param h the height of the rectangle to update
+ */
+void etk_image_update_rect(Etk_Image *image, int x, int y, int w, int h)
+{
+   if (!image || image->source != ETK_IMAGE_DATA || !image->object)
+      return;
+   evas_object_image_data_update_add(image->object, x, y, w, h);
+}
+
+/**
+ * @brief Copies the image @a src_image to @a dest_image
+ * @param dest_image the destination image
+ * @param src_image the image to copy
+ * @note If @a src_image is an edje image, the current state of the edje 
animation won't be copied
+ */
+void etk_image_copy(Etk_Image *dest_image, Etk_Image *src_image)
+{
+   if (!dest_image || !src_image || dest_image == src_image)
+      return;
+   
+   switch (src_image->source)
+   {
+      case ETK_IMAGE_FILE:
+         /* TODO: copy the key too.. */
+         etk_image_set_from_file(dest_image, src_image->info.file.filename);
+         break;
+      case ETK_IMAGE_EDJE:
+         etk_image_set_from_edje(dest_image, src_image->info.edje.filename, 
src_image->info.edje.group);
+         break;
+      case ETK_IMAGE_STOCK:
+         etk_image_set_from_stock(dest_image, src_image->info.stock.id, 
src_image->info.stock.size);
+         break;
+      case ETK_IMAGE_EVAS_OBJECT:
+         ETK_WARNING("You can't copy an image that is set from an Evas 
Object");
+         break;
+      case ETK_IMAGE_DATA:
+         etk_image_set_from_data(dest_image, src_image->info.data.size.w, 
src_image->info.data.size.h,
+            src_image->info.data.pixels, ETK_TRUE);
+         break;
+      default:
+         break;
+   }
+   
+   etk_image_aspect_ratio_set(dest_image, src_image->aspect_ratio);
+   etk_image_keep_aspect_set(dest_image, src_image->keep_aspect);
+}
+
+/**
+ * @brief Gets the native size of the image. If the image is loaded from a 
file or from given pixels, it returns the
+ * native size of the image. If the image is loaded from an Edje file or a 
stock-id, it returns the minimum size of the
+ * Edje object (a stock image is an Edje object). Otherwise, the returned size 
is 0x0
  * @param image an image
  * @param width the location where to set the native width of the image
  * @param height the location where to set the native height of the image
  */
 void etk_image_size_get(Etk_Image *image, int *width, int *height)
 {
-   if (!image)
+   if (width)
+      *width = 0;
+   if (height)
+      *height = 0;
+   
+   if (!image || !image->object)
       return;
    
-   if (!image)
+   if (image->source == ETK_IMAGE_FILE || image->source == ETK_IMAGE_DATA)
+      evas_object_image_size_get(image->object, width, height);
+   else if (image->source == ETK_IMAGE_EDJE || image->source == 
ETK_IMAGE_STOCK)
    {
+      Evas_Coord min_x, min_y, calc_x, calc_y;
+      
+      edje_object_size_min_get(image->object, &min_x, &min_y);
+      edje_object_size_min_calc(image->object, &calc_x, &calc_y);
       if (width)
-         *width = 0;
+         *width = ETK_MAX(min_x, calc_x);
       if (height)
-         *height = 0;
-   }
-   else
-   {
-      if (image->use_object)
-       evas_object_geometry_get(image->image_object, NULL, NULL, width, 
height);
-      else if (image->use_edje)
-       edje_object_size_min_get(image->image_object, width, height);       
-      else
-       evas_object_image_size_get(image->image_object, width, height);
+         *height = ETK_MAX(min_y, calc_y);
    }
 }
 
 /**
  * @brief Sets if the image should keep its aspect ratio when it is resized
  * @param image an image
- * @param keep_aspect if keep_aspect == ETK_TRUE, the image will keep its 
aspect ratio when itis resized
+ * @param keep_aspect if @a keep_aspect is ETK_TRUE, the image will keep its 
aspect ratio when it is resized
  */
 void etk_image_keep_aspect_set(Etk_Image *image, Etk_Bool keep_aspect)
 {
-   if (!image)
+   if (!image || image->keep_aspect == keep_aspect)
       return;
 
    image->keep_aspect = keep_aspect;
@@ -413,7 +531,7 @@
 }
 
 /**
- * @brief Get whether the image keeps its aspect ratio when it is resized
+ * @brief Gets whether the image keeps its aspect ratio when it is resized
  * @param image an image
  * @return Returns ETK_TRUE if the image keeps its aspect ratio when it is 
resized
  */
@@ -425,30 +543,33 @@
 }
 
 /**
- * @brief Copies the image @a src_image to @a dest_image
- * @param dest_image the destination image
- * @param src_image the image to copy
- * @note If @a src_image is an edje image, the state of the edje animation 
won't be copied
+ * @brief Sets (forces) the aspect ratio of the image. You can use this 
function for example to set the aspect-ratio
+ * when you set the image from an Evas object with 
etk_image_set_from_evas_object().
+ * @param image an image
+ * @param aspect_ratio the aspect ratio to set, or 0.0 to make Etk calculates 
automatically the aspect ratio
  */
-void etk_image_copy(Etk_Image *dest_image, Etk_Image *src_image)
+void etk_image_aspect_ratio_set(Etk_Image *image, double aspect_ratio)
 {
-   if (!dest_image || !src_image || dest_image == src_image)
+   if (!image || image->aspect_ratio)
       return;
    
-   free(dest_image->filename);
-   free(dest_image->edje_filename);
-   free(dest_image->edje_group);
-   
-   dest_image->filename = src_image->filename ? strdup(src_image->filename) : 
NULL;
-   dest_image->edje_group = src_image->edje_group ? 
strdup(src_image->edje_group) : NULL;
-   dest_image->edje_filename = src_image->edje_group ? 
strdup(src_image->edje_filename) : NULL;
-   dest_image->stock_id = src_image->stock_id;
-   dest_image->stock_size = src_image->stock_size;
-   dest_image->keep_aspect = src_image->keep_aspect;
-   dest_image->object_type_changed = (dest_image->use_edje != 
src_image->use_edje);
-   dest_image->use_edje = src_image->use_edje;
-   
-   _etk_image_load(dest_image);
+   image->aspect_ratio = aspect_ratio;
+   etk_widget_size_recalc_queue(ETK_WIDGET(image));
+   etk_object_notify(ETK_OBJECT(image), "aspect_ratio");
+}
+
+/**
+ * @brief Gets the aspect ratio you set to the image. If no aspect ratio has 
been set, it will return 0.0.
+ * To know the native aspect ratio, call etk_image_size_get() to get the 
native size of the image and calculate the
+ * aspect ratio from these values.
+ * @param image an image
+ * @return Returns the aspect ratio you set to the image, or 0.0 if no aspect 
ratio has been set
+ */
+double etk_image_aspect_ratio_get(Etk_Image *image)
+{
+   if (!image)
+      return 0.0;
+   return image->aspect_ratio;
 }
 
 /**************************
@@ -465,22 +586,18 @@
    if (!(widget = ETK_WIDGET(image)))
       return;
 
-   image->image_object = NULL;
-   image->filename = NULL;
-   image->edje_filename = NULL;
-   image->edje_group = NULL;
-   image->stock_id = ETK_STOCK_NO_STOCK;
-   image->stock_size = ETK_STOCK_SMALL;
+   image->object = NULL;
+   image->source = ETK_IMAGE_FILE;
+   image->info.file.filename = NULL;
+   image->info.file.key = NULL;
    image->keep_aspect = ETK_TRUE;
-   image->use_edje = ETK_FALSE;
-   image->use_object = ETK_FALSE;   
-   image->object_type_changed = ETK_FALSE;
+   image->aspect_ratio = 0.0;
 
    widget->size_request = _etk_image_size_request;
    widget->size_allocate = _etk_image_size_allocate;
 
    etk_signal_connect("realize", ETK_OBJECT(image), 
ETK_CALLBACK(_etk_image_realize_cb), NULL);
-   etk_signal_connect("unrealize", ETK_OBJECT(image), 
ETK_CALLBACK(_etk_image_unrealize_cb), NULL);
+   etk_signal_connect_swapped("unrealize", ETK_OBJECT(image), 
ETK_CALLBACK(etk_callback_set_null), &image->object);
 }
 
 /* Destroys the image */
@@ -489,9 +606,21 @@
    if (!image)
       return;
 
-   free(image->filename);
-   free(image->edje_filename);
-   free(image->edje_group);
+   if (image->source == ETK_IMAGE_FILE)
+   {
+      free(image->info.file.filename);
+      free(image->info.file.key);
+   }
+   else if (image->source == ETK_IMAGE_EDJE)
+   {
+      free(image->info.edje.filename);
+      free(image->info.edje.group);
+   }
+   else if (image->source == ETK_IMAGE_DATA)
+   {
+      if (image->info.data.copied)
+         free(image->info.data.pixels);
+   }
 }
 
 /* Sets the property whose id is "property_id" to the value "value" */
@@ -505,25 +634,39 @@
    switch (property_id)
    {
       case ETK_IMAGE_FILE_PROPERTY:
-         etk_image_set_from_file(image, etk_property_value_string_get(value));
+         if (image->source == ETK_IMAGE_EDJE)
+            etk_image_set_from_edje(image, 
etk_property_value_string_get(value), image->info.edje.group);
+         else
+         {
+            /* TODO: set the key! */
+            etk_image_set_from_file(image, 
etk_property_value_string_get(value));
+         }
+         break;
+      case ETK_IMAGE_KEY_PROPERTY:
+         if (image->source == ETK_IMAGE_FILE)
+         {
+            /* TODO: set the key! */
+            //etk_image_set_from_file(image, image->info.file.filename, 
etk_property_value_string_get(value));
+         }
+         else if (image->source == ETK_IMAGE_EDJE)
+            etk_image_set_from_edje(image, image->info.edje.filename, 
etk_property_value_string_get(value));
          break;
-      case ETK_IMAGE_EDJE_FILE_PROPERTY:
-         etk_image_set_from_edje(image, etk_property_value_string_get(value), 
image->edje_group);
+      case ETK_IMAGE_STOCK_ID_PROPERTY:
+         if (image->source == ETK_IMAGE_STOCK)
+            etk_image_set_from_stock(image, etk_property_value_int_get(value), 
image->info.stock.size);
          break;
-      case ETK_IMAGE_EDJE_GROUP_PROPERTY:
-         etk_image_set_from_edje(image, image->edje_filename, 
etk_property_value_string_get(value));
+      case ETK_IMAGE_STOCK_SIZE_PROPERTY:
+         if (image->source == ETK_IMAGE_STOCK)
+            etk_image_set_from_stock(image, image->info.stock.id, 
etk_property_value_int_get(value));
          break;
       case ETK_IMAGE_EVAS_OBJECT_PROPERTY:
          etk_image_set_from_evas_object(image, 
etk_property_value_pointer_get(value));
-         break;      
+         break;
       case ETK_IMAGE_KEEP_ASPECT_PROPERTY:
          etk_image_keep_aspect_set(image, etk_property_value_bool_get(value));
          break;
-      case ETK_IMAGE_STOCK_ID_PROPERTY:
-         etk_image_set_from_stock(image, etk_property_value_int_get(value), 
image->stock_size);
-         break;
-      case ETK_IMAGE_STOCK_SIZE_PROPERTY:
-         etk_image_set_from_stock(image, image->stock_id, 
etk_property_value_int_get(value));
+      case ETK_IMAGE_ASPECT_RATIO_PROPERTY:
+         etk_image_aspect_ratio_set(image, 
etk_property_value_double_get(value));
          break;
       default:
          break;
@@ -540,29 +683,39 @@
 
    switch (property_id)
    {
+      case ETK_IMAGE_SOURCE_PROPERTY:
+         etk_property_value_int_set(value, image->source);
+         break;
       case ETK_IMAGE_FILE_PROPERTY:
-         etk_property_value_string_set(value, image->filename);
+         if (image->source == ETK_IMAGE_FILE)
+            etk_property_value_string_set(value, image->info.file.filename);
+         else if (image->source == ETK_IMAGE_EDJE)
+            etk_property_value_string_set(value, image->info.edje.filename);
+         else
+            etk_property_value_string_set(value, NULL);
+         break;
+      case ETK_IMAGE_KEY_PROPERTY:
+         if (image->source == ETK_IMAGE_FILE)
+            etk_property_value_string_set(value, image->info.file.key);
+         else if (image->source == ETK_IMAGE_EDJE)
+            etk_property_value_string_set(value, image->info.edje.group);
+         else
+            etk_property_value_string_set(value, NULL);
          break;
-      case ETK_IMAGE_EDJE_FILE_PROPERTY:
-         etk_property_value_string_set(value, image->edje_filename);
+      case ETK_IMAGE_STOCK_ID_PROPERTY:
+         etk_property_value_int_set(value, image->info.stock.id);
          break;
-      case ETK_IMAGE_EDJE_GROUP_PROPERTY:
-         etk_property_value_string_set(value, image->edje_group);
+      case ETK_IMAGE_STOCK_SIZE_PROPERTY:
+         etk_property_value_int_set(value, image->info.stock.size);
          break;
       case ETK_IMAGE_EVAS_OBJECT_PROPERTY:
-         etk_property_value_pointer_set(value, image->image_object);
-         break;      
+         etk_property_value_pointer_set(value, image->object);
+         break;
       case ETK_IMAGE_KEEP_ASPECT_PROPERTY:
          etk_property_value_bool_set(value, image->keep_aspect);
          break;
-      case ETK_IMAGE_USE_EDJE_PROPERTY:
-         etk_property_value_bool_set(value, image->use_edje);
-         break;
-      case ETK_IMAGE_STOCK_ID_PROPERTY:
-         etk_property_value_int_set(value, image->stock_id);
-         break;
-      case ETK_IMAGE_STOCK_SIZE_PROPERTY:
-         etk_property_value_int_set(value, image->stock_size);
+      case ETK_IMAGE_ASPECT_RATIO_PROPERTY:
+         etk_property_value_double_set(value, image->aspect_ratio);
          break;
       default:
          break;
@@ -576,28 +729,7 @@
 
    if (!(image = ETK_IMAGE(widget)) || !size)
       return;
-
-   if (image->image_object)
-   {
-      if (image->use_object)
-        evas_object_geometry_get(image->image_object, NULL, NULL, &size->w, 
&size->h);
-      else if (image->use_edje)
-      {
-         Evas_Coord min_x, min_y, calc_x, calc_y;
-
-         edje_object_size_min_get(image->image_object, &min_x, &min_y);
-         edje_object_size_min_calc(image->image_object, &calc_x, &calc_y);
-         size->w = ETK_MAX(min_x, calc_x);
-         size->h = ETK_MAX(min_y, calc_y);
-      }
-      else
-         evas_object_image_size_get(image->image_object, &size->w, &size->h);
-   }
-   else
-   {
-      size->w = 0;
-      size->h = 0;
-   }
+   etk_image_size_get(image, &size->w, &size->h);
 }
 
 /* Resizes the image to the allocated size */
@@ -607,8 +739,7 @@
 
    if (!(image = ETK_IMAGE(widget)))
       return;
-
-   if (!image->image_object)
+   if (!image->object)
       return;
 
    if (image->keep_aspect)
@@ -616,20 +747,20 @@
       double aspect_ratio;
       int image_w, image_h;
       int new_size;
-
-      if (image->use_object)
-        evas_object_geometry_get(image->image_object, NULL, NULL, &image_w, 
&image_h);
-      else if (image->use_edje)
-         edje_object_size_min_get(image->image_object, &image_w, &image_h);
+      
+      if (image->aspect_ratio > 0.0)
+         aspect_ratio = image->aspect_ratio;
       else
-         evas_object_image_size_get(image->image_object, &image_w, &image_h);
-      if (image_w <= 0 || image_h <= 0)
       {
-         image_w = 1;
-         image_h = 1;
+         etk_image_size_get(image, &image_w, &image_h);
+         if (image_w <= 0 || image_h <= 0)
+         {
+            image_w = 1;
+            image_h = 1;
+         }
+         aspect_ratio = (double)image_w / (double)image_h;
       }
       
-      aspect_ratio = (double)image_w / (double)image_h;
       if (geometry.h * aspect_ratio > geometry.w)
       {
          new_size = geometry.w / aspect_ratio;
@@ -644,11 +775,11 @@
       }
    }
    
-   if (!image->use_edje && !image->use_object)
-      evas_object_image_fill_set(image->image_object, 0, 0, geometry.w, 
geometry.h);
+   if (image->source == ETK_IMAGE_FILE || image->source == ETK_IMAGE_DATA)
+      evas_object_image_fill_set(image->object, 0, 0, geometry.w, geometry.h);
    
-   evas_object_move(image->image_object, geometry.x, geometry.y);
-   evas_object_resize(image->image_object, geometry.w, geometry.h);
+   evas_object_move(image->object, geometry.x, geometry.y);
+   evas_object_resize(image->object, geometry.w, geometry.h);
 }
 
 /**************************
@@ -667,104 +798,147 @@
    _etk_image_load(image);
 }
 
-/* Called when the image is unrealized */
-static void _etk_image_unrealize_cb(Etk_Object *object, void *data)
-{
-   Etk_Image *image;
-
-   if (!(image = ETK_IMAGE(object)))
-      return;
-   image->image_object = NULL;
-}
-
 /**************************
  *
  * Private functions
  *
  **************************/
 
+/* Sets the source of the image */
+static void _etk_image_source_set(Etk_Image *image, Etk_Image_Source source)
+{
+   if (!image || image->source == source)
+      return;
+   
+   switch (image->source)
+   {
+      case ETK_IMAGE_FILE:
+         free(image->info.file.filename);
+         free(image->info.file.key);
+         break;
+      case ETK_IMAGE_EDJE:
+         free(image->info.edje.filename);
+         free(image->info.edje.group);
+         break;
+      case ETK_IMAGE_DATA:
+         if (image->info.data.copied)
+            free(image->info.data.pixels);
+         break;
+      default:
+         break;
+   }
+   
+   switch (source)
+   {
+      case ETK_IMAGE_FILE:
+         image->info.file.filename = NULL;
+         image->info.file.key = NULL;
+         break;
+      case ETK_IMAGE_EDJE:
+         image->info.edje.filename = NULL;
+         image->info.edje.group = NULL;
+         break;
+      case ETK_IMAGE_STOCK:
+         image->info.stock.id = ETK_STOCK_NO_STOCK;
+         image->info.stock.size = ETK_STOCK_SMALL;
+         break;
+      case ETK_IMAGE_DATA:
+         image->info.data.size.w = 0;
+         image->info.data.size.h = 0;
+         image->info.data.copied = ETK_FALSE;
+         image->info.data.pixels = NULL;
+         break;
+      default:
+         break;
+   }
+   
+   if (image->object && image->source != ETK_IMAGE_EVAS_OBJECT)
+      evas_object_del(image->object);
+   image->object = NULL;
+   
+   image->source = source;
+   etk_object_notify(ETK_OBJECT(image), "source");
+}
+
 /* Load the image from the image or the edje file */
 static void _etk_image_load(Etk_Image *image)
 {
-   Etk_Widget *widget;
-
-   if (!(widget = ETK_WIDGET(image)))
+   Evas *evas;
+   
+   if (!image || !(evas = etk_widget_toplevel_evas_get(ETK_WIDGET(image))))
       return;
-
-   if (image->image_object && image->object_type_changed)
+   
+   /* Create the Evas object */
+   if (!image->object)
    {
-      if (!image->use_object)
+      switch (image->source)
       {
-        etk_widget_member_object_del(widget, image->image_object);
-        evas_object_del(image->image_object);
-        image->image_object = NULL;
+         case ETK_IMAGE_FILE:
+         case ETK_IMAGE_DATA:
+            image->object = evas_object_image_add(evas);
+            break;
+         case ETK_IMAGE_EDJE:
+         case ETK_IMAGE_STOCK:
+            image->object = edje_object_add(evas);
+            break;
+         default:
+            break;
       }
-      image->object_type_changed = ETK_FALSE;
    }
-   if (image->filename)
+   
+   if (!image->object)
+      return;
+   etk_widget_member_object_add(ETK_WIDGET(image), image->object);
+   
+   /* Load the image */
+   switch (image->source)
    {
-      int error_code;
-      Evas *evas;
-
-      if (!image->image_object && (evas = 
etk_widget_toplevel_evas_get(widget)))
-      {
-         /* TODO: FIXME: the image might not be realized here... */
-         image->image_object = evas_object_image_add(evas);
-         etk_widget_member_object_add(widget, image->image_object);
-      }
-      if (image->image_object)
+      case ETK_IMAGE_FILE:
       {
          const char *image_file;
+         int error_code;
          
-         evas_object_image_file_get(image->image_object, &image_file, NULL);
-         if (!image_file || strcmp(image_file, image->filename) != 0)
+         evas_object_image_file_get(image->object, &image_file, NULL);
+         if (!image_file || !image->info.file.filename || strcmp(image_file, 
image->info.file.filename) != 0)
          {
-            evas_object_image_file_set(image->image_object, image->filename, 
NULL);
-            if ((error_code = 
evas_object_image_load_error_get(image->image_object)))
-            {
-               ETK_WARNING("Unable to load image from file \"%s\", error %d", 
image->filename, error_code);
-               evas_object_hide(image->image_object);
-            }
-            else
-               evas_object_show(image->image_object);
+            evas_object_image_file_set(image->object, 
image->info.file.filename, image->info.file.key);
+            if ((error_code = evas_object_image_load_error_get(image->object)))
+               ETK_WARNING("Unable to load image from file \"%s\", error %d", 
image->info.file.filename, error_code);
          }
+         break;
       }
-   }
-   else if (image->edje_filename && image->edje_group)
-   {
-      int error_code;
-      Evas *evas;
-
-      if (!image->image_object && (evas = 
etk_widget_toplevel_evas_get(widget)))
-      {
-         image->image_object = edje_object_add(evas);
-         etk_widget_member_object_add(widget, image->image_object);
-      }
-      if (image->image_object)
+      case ETK_IMAGE_EDJE:
+      case ETK_IMAGE_STOCK:
       {
-         const char *edje_file, *edje_group;
+         const char *file, *key;
+         int error_code;
          
-         edje_object_file_get(image->image_object, &edje_file, &edje_group);
-         if (!edje_file || !edje_group || strcmp(edje_file, 
image->edje_filename) != 0 || strcmp(edje_group, image->edje_group) != 0)
+         if (image->source == ETK_IMAGE_STOCK)
          {
-            edje_object_file_set(image->image_object, image->edje_filename, 
image->edje_group);
-            if ((error_code = edje_object_load_error_get(image->image_object)))
-            {
-               ETK_WARNING("Unable to load image from edje file \"%s\"/\"%s\", 
error %d", image->edje_filename, image->edje_group, error_code);
-               evas_object_hide(image->image_object);
-            }
-            else
-               evas_object_show(image->image_object);
+            file = etk_theme_icon_get();
+            key = etk_stock_key_get(image->info.stock.id, 
image->info.stock.size);
          }
-      }      
-   }
-   else if (image->image_object && image->use_object)
-   {
-      etk_widget_member_object_add(widget, image->image_object);
-      evas_object_show(image->image_object);      
+         else
+         {
+            file = image->info.edje.filename;
+            key = image->info.edje.group;
+         }
+         
+         edje_object_file_set(image->object, file, key);
+         if ((error_code = edje_object_load_error_get(image->object)))
+            ETK_WARNING("Unable to load image from edje-file  \"%s\"/\"%s\", 
error %d", file, key, error_code);
+         break;
+      }
+      case ETK_IMAGE_DATA:
+         evas_object_image_size_set(image->object, image->info.data.size.w, 
image->info.data.size.h);
+         evas_object_image_data_set(image->object, image->info.data.pixels);
+         break;
+      default:
+         break;
    }
-
-   etk_widget_size_recalc_queue(widget);
+   
+   evas_object_show(image->object);
+   etk_widget_size_recalc_queue(ETK_WIDGET(image));
 }
 
 /** @} */
@@ -780,7 +954,7 @@
  *
  * @image html widgets/image.png
  * The image can be loaded from several sources: image files (png, jpg, and 
the other formats supported by evas), edje
- * files (edj), or from stock IDs.
+ * files (edj), stock-icons, data pixels or given Evas objects.
  * 
  * \par Object Hierarchy:
  * - Etk_Object
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_image.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -3 -r1.11 -r1.12
--- etk_image.h 25 Dec 2006 14:04:53 -0000      1.11
+++ etk_image.h 29 Dec 2006 21:50:46 -0000      1.12
@@ -6,10 +6,6 @@
 #include "etk_widget.h"
 #include "etk_stock.h"
 
-/* TODO/FIXME list:
- * - Add new/set_from_data()
- */
-
 /**
  * @defgroup Etk_Image Etk_Image
  * @brief An Etk_Image is a widget that can load and display an image from 
various sources
@@ -23,6 +19,16 @@
 /** Check if the object is an Etk_Image */
 #define ETK_IS_IMAGE(obj)     (ETK_OBJECT_CHECK_TYPE((obj), ETK_IMAGE_TYPE))
 
+/** @brief The different sources that an Etk_Image can use */
+typedef enum Etk_Image_Source
+{
+   ETK_IMAGE_FILE,              /**< The image is loaded from an image file */
+   ETK_IMAGE_EDJE,              /**< The image is loaded from an Edje file */
+   ETK_IMAGE_STOCK,             /**< The image is loaded from a stock id */
+   ETK_IMAGE_EVAS_OBJECT,       /**< The image shows an existing Evas Object */
+   ETK_IMAGE_DATA               /**< The image uses pixel data given by the 
user */
+} Etk_Image_Source;
+
 /**
  * @brief @widget A widget that can load and display an image
  * @structinfo
@@ -33,44 +39,72 @@
    /* Inherit from Etk_Widget */
    Etk_Widget widget;
 
-   Evas_Object *image_object;
-   char *filename;
-   char *edje_group;
-   char *edje_filename;
+   Evas_Object *object;
    
-   Etk_Stock_Id stock_id;
-   Etk_Stock_Size stock_size;
+   Etk_Image_Source source;
+   union
+   {
+      struct
+      {
+         char *filename;
+         char *key;
+      } file;
+      
+      struct
+      {
+         char *filename;
+         char *group;
+      } edje;
+      
+      struct
+      {
+         Etk_Stock_Id id;
+         Etk_Stock_Size size;
+      } stock;
+      
+      struct
+      {
+         void *pixels;
+         Etk_Size size;
+         Etk_Bool copied;
+      } data;
+   } info;
    
+   double aspect_ratio;
    Etk_Bool keep_aspect;
-   Etk_Bool use_edje;
-   Etk_Bool use_object;
-   Etk_Bool object_type_changed;
 };
 
-Etk_Type   *etk_image_type_get();
-Etk_Widget *etk_image_new();
+Etk_Type *etk_image_type_get(void);
+
+Etk_Widget *etk_image_new(void);
 Etk_Widget *etk_image_new_from_file(const char *filename);
-Etk_Widget *etk_image_new_from_edje(const char *edje_filename, const char 
*edje_group);
-Etk_Widget *etk_image_new_from_evas_object(Evas_Object *evas_object);
+Etk_Widget *etk_image_new_from_edje(const char *filename, const char *group);
 Etk_Widget *etk_image_new_from_stock(Etk_Stock_Id stock_id, Etk_Stock_Size 
stock_size);
+Etk_Widget *etk_image_new_from_evas_object(Evas_Object *evas_object);
+Etk_Widget *etk_image_new_from_data(int width, int height, void *data, 
Etk_Bool copy);
 
-void        etk_image_set_from_file(Etk_Image *image, const char *filename);
-const char *etk_image_file_get(Etk_Image *image);
-
-void etk_image_set_from_edje(Etk_Image *image, const char *edje_filename, 
const char *edje_group);
-void etk_image_edje_get(Etk_Image *image, char **edje_filename, char 
**edje_group);
-
+void         etk_image_set_from_file(Etk_Image *image, const char *filename);
+const char  *etk_image_file_get(Etk_Image *image);
+void         etk_image_set_from_edje(Etk_Image *image, const char *filename, 
const char *group);
+void         etk_image_edje_get(Etk_Image *image, char **filename, char 
**group);
+void         etk_image_set_from_stock(Etk_Image *image, Etk_Stock_Id stock_id, 
Etk_Stock_Size stock_size);
+void         etk_image_stock_get(Etk_Image *image, Etk_Stock_Id *stock_id, 
Etk_Stock_Size *stock_size);
 void         etk_image_set_from_evas_object(Etk_Image *image, Evas_Object 
*evas_object);
 Evas_Object *etk_image_evas_object_get(Etk_Image *image);
+void         etk_image_set_from_data(Etk_Image *image, int width, int height, 
void *data, Etk_Bool copy);
+void        *etk_image_data_get(Etk_Image *image, Etk_Bool for_writing);
 
-void etk_image_set_from_stock(Etk_Image *image, Etk_Stock_Id stock_id, 
Etk_Stock_Size stock_size);
-void etk_image_stock_get(Etk_Image *image, Etk_Stock_Id *stock_id, 
Etk_Stock_Size *stock_size);
+Etk_Image_Source etk_image_source_get(Etk_Image *image);
 
+void etk_image_update(Etk_Image *image);
+void etk_image_update_rect(Etk_Image *image, int x, int y, int w, int h);
 void etk_image_copy(Etk_Image *dest_image, Etk_Image *src_image);
 
 void     etk_image_size_get(Etk_Image *image, int *width, int *height);
 void     etk_image_keep_aspect_set(Etk_Image *image, Etk_Bool keep_aspect);
 Etk_Bool etk_image_keep_aspect_get(Etk_Image *image);
+void     etk_image_aspect_ratio_set(Etk_Image *image, double aspect_ratio);
+double   etk_image_aspect_ratio_get(Etk_Image *image);
 
 /** @} */
 



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to