[clutter/wip/actor-content: 8/33] image: Add ::image-changed signal and clean up
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/actor-content: 8/33] image: Add ::image-changed signal and clean up
- Date: Wed, 18 May 2011 11:11:05 +0000 (UTC)
commit fd3d64e05032004a6d6713d75be894a46e480ed6
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Tue Dec 7 15:48:54 2010 +0000
image: Add ::image-changed signal and clean up
clutter/clutter-image.c | 248 +++++++++++++++++++++++++++++++++++++++++++++--
clutter/clutter-image.h | 9 ++-
2 files changed, 248 insertions(+), 9 deletions(-)
---
diff --git a/clutter/clutter-image.c b/clutter/clutter-image.c
index ed6ab66..80cd96e 100644
--- a/clutter/clutter-image.c
+++ b/clutter/clutter-image.c
@@ -34,6 +34,7 @@ static GParamSpec *image_props[LAST_PROP] = { NULL, };
enum
{
SIZE_CHANGED,
+ IMAGE_CHANGED,
LAST_SIGNAL
};
@@ -84,6 +85,11 @@ clutter_image_real_size_changed (ClutterImage *image,
}
static void
+clutter_image_real_image_changed (ClutterImage *image)
+{
+}
+
+static void
clutter_image_get_property (GObject *gobject,
guint prop_id,
GValue *value,
@@ -113,6 +119,13 @@ clutter_image_class_init (ClutterImageClass *klass)
g_type_class_add_private (klass, sizeof (ClutterImagePrivate));
+ /**
+ * ClutterImage:width:
+ *
+ * The width of the image data, in pixels.
+ *
+ * Since: 1.6
+ */
image_props[PROP_WIDTH] =
g_param_spec_int ("width",
P_("Width"),
@@ -121,6 +134,13 @@ clutter_image_class_init (ClutterImageClass *klass)
0,
CLUTTER_PARAM_READABLE);
+ /**
+ * ClutterImage:height:
+ *
+ * The height of the image data, in pixels.
+ *
+ * Since: 1.6
+ */
image_props[PROP_HEIGHT] =
g_param_spec_int ("height",
P_("Height"),
@@ -135,6 +155,20 @@ clutter_image_class_init (ClutterImageClass *klass)
gobject_class->dispose = clutter_image_dispose;
+ /**
+ * ClutterImage::size-changed:
+ * @image: a #ClutterImage
+ * @width: the width of the image data, in pixels
+ * @height: the height of the image data, in pixels
+ *
+ * The ::size-changed signal is emitted each time the size of the
+ * image data held by the #ClutterImage changes.
+ *
+ * The default implementation will automatically invalidate @image
+ * and queue a redraw.
+ *
+ * Since: 1.6
+ */
image_signals[SIZE_CHANGED] =
g_signal_new (I_("size-changed"),
G_TYPE_FROM_CLASS (klass),
@@ -146,7 +180,29 @@ clutter_image_class_init (ClutterImageClass *klass)
G_TYPE_INT,
G_TYPE_INT);
+ /**
+ * ClutterImage::image-changed:
+ * @image: the #ClutterImage that emitted the signal
+ *
+ * The ::image-changed signal is emitted each time the image data
+ * held by the #ClutterImage changes.
+ *
+ * The default implementation will automatically invalidate @image
+ * and queue a redraw.
+ *
+ * Since: 1.6
+ */
+ image_signals[IMAGE_CHANGED] =
+ g_signal_new (I_("image-changed"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ClutterImageClass, image_changed),
+ NULL, NULL,
+ _clutter_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
klass->size_changed = clutter_image_real_size_changed;
+ klass->image_changed = clutter_image_real_image_changed;
}
static void
@@ -158,12 +214,34 @@ clutter_image_init (ClutterImage *image)
image->priv->material = copy_template_material ();
}
+/**
+ * clutter_image_new:
+ *
+ * Creates a new, empty #ClutterImage instance.
+ *
+ * Image data should be loaded using one of the clutter_image_load* family
+ * of functions.
+ *
+ * Return value: the newly created #ClutterImage instance
+ *
+ * Since: 1.6
+ */
ClutterImage *
clutter_image_new (void)
{
return g_object_new (CLUTTER_TYPE_IMAGE, NULL);
}
+/**
+ * clutter_image_get_size:
+ * @image: a #ClutterImage
+ * @width: (out): return location for the image width, or %NULL
+ * @height: (out): return location for the image height, or %NULL
+ *
+ * Retrieves the size of the image data held by @image.
+ *
+ * Since: 1.6
+ */
void
clutter_image_get_size (ClutterImage *image,
gint *width,
@@ -178,6 +256,23 @@ clutter_image_get_size (ClutterImage *image,
*height = image->priv->image_height;
}
+/**
+ * clutter_image_load_from_data:
+ * @image: a #ClutterImage
+ * @data: image data
+ * @format: the pixel format of @data
+ * @width: the width of the image data, in pixels
+ * @height: the height of the image data, in pixels
+ * @rowstride: the distance between rows starting addresses
+ * @error: return location for a #GError, or %NULL
+ *
+ * Sets the image data from an existing array.
+ *
+ * Return value: %TRUE if the image data was successfully loaded
+ * and %FALSE otherwise
+ *
+ * Since: 1.6
+ */
gboolean
clutter_image_load_from_data (ClutterImage *image,
const guchar *data,
@@ -185,11 +280,11 @@ clutter_image_load_from_data (ClutterImage *image,
gint width,
gint height,
gint rowstride,
- gint bpp,
GError **error)
{
ClutterImagePrivate *priv;
CoglHandle texture;
+ gboolean width_changed, height_changed;
g_return_val_if_fail (CLUTTER_IS_IMAGE (image), FALSE);
g_return_val_if_fail (data != NULL, FALSE);
@@ -213,9 +308,62 @@ clutter_image_load_from_data (ClutterImage *image,
cogl_material_set_layer (priv->material, 0, texture);
cogl_handle_unref (texture);
+ g_object_freeze_notify (G_OBJECT (image));
+
+ if (width != priv->image_width)
+ {
+ priv->image_width = width;
+ g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_WIDTH]);
+ width_changed = TRUE;
+ }
+ else
+ width_changed = FALSE;
+
+ if (height != priv->image_height)
+ {
+ priv->image_height = height;
+ g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_HEIGHT]);
+ height_changed = TRUE;
+ }
+ else
+ height_changed = FALSE;
+
+ g_signal_emit (image, image_signals[IMAGE_CHANGED], 0);
+
+ if (width_changed || height_changed)
+ g_signal_emit (image, image_signals[SIZE_CHANGED], 0,
+ priv->image_width,
+ priv->image_height);
+
+ g_object_thaw_notify (G_OBJECT (image));
+
return TRUE;
}
+/**
+ * clutter_image_load:
+ * @image: a #ClutterImage
+ * @gfile: a #GFile
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @width: (out): return location for the width of the image, or %NULL
+ * @height: (out): return location for the height of the image, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Synchronously loads image data available to the location pointed
+ * by @gfile.
+ *
+ * This function will block the execution until the image data has
+ * been loaded, or an error was encountered.
+ *
+ * It is possible to cancel the loading by using the @cancellable
+ * instance.
+ *
+ * In case of error, the #GError structure will be filled accordingly.
+ *
+ * Return value: %TRUE if the loading was successful, and %FALSE otherwise
+ *
+ * Since: 1.6
+ */
gboolean
clutter_image_load (ClutterImage *image,
GFile *gfile,
@@ -229,6 +377,8 @@ clutter_image_load (ClutterImage *image,
GFileInputStream *stream;
CoglHandle texture;
gboolean res;
+ gint old_image_width, old_image_height;
+ gboolean width_changed, height_changed;
g_return_val_if_fail (CLUTTER_IS_IMAGE (image), FALSE);
g_return_val_if_fail (G_IS_FILE (gfile), FALSE);
@@ -255,6 +405,8 @@ clutter_image_load (ClutterImage *image,
return FALSE;
}
+ old_image_width = priv->image_width;
+ old_image_height = priv->image_height;
_clutter_image_loader_get_image_size (loader,
&priv->image_width,
&priv->image_height);
@@ -268,9 +420,32 @@ clutter_image_load (ClutterImage *image,
cogl_material_set_layer (priv->material, 0, texture);
- g_signal_emit (image, image_signals[SIZE_CHANGED], 0,
- priv->image_width,
- priv->image_height);
+ g_object_freeze_notify (G_OBJECT (image));
+
+ if (priv->image_width != old_image_width)
+ {
+ g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_WIDTH]);
+ width_changed = TRUE;
+ }
+ else
+ width_changed = FALSE;
+
+ if (priv->image_height != old_image_height)
+ {
+ g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_HEIGHT]);
+ height_changed = TRUE;
+ }
+ else
+ height_changed = FALSE;
+
+ g_signal_emit (image, image_signals[IMAGE_CHANGED], 0);
+
+ if (width_changed || height_changed)
+ g_signal_emit (image, image_signals[SIZE_CHANGED], 0,
+ priv->image_width,
+ priv->image_height);
+
+ g_object_thaw_notify (G_OBJECT (image));
if (width)
*width = priv->image_width;
@@ -397,6 +572,23 @@ async_read_complete (GObject *gobject,
closure);
}
+/**
+ * clutter_image_load_async:
+ * @image: a #ClutterImage
+ * @gfile: a #GFile
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: (scope async): a callback function
+ * @user_data: closure to pass to @callback
+ *
+ * Asynchronously loads image data from the resource pointed by @gfile
+ * into @image.
+ *
+ * When the image data has been loaded the @callback function will be
+ * called; it is the responsability of the developer to call
+ * clutter_image_load_finish() inside @callback.
+ *
+ * Since: 1.6
+ */
void
clutter_image_load_async (ClutterImage *image,
GFile *gfile,
@@ -430,6 +622,21 @@ clutter_image_load_async (ClutterImage *image,
closure);
}
+/**
+ * clutter_image_load_finish:
+ * @image: a #ClutterImage
+ * @res: a #GAsyncResult
+ * @width: (out): return location for the width of the image data, or %NULL
+ * @height: (out): return location for the height of the image data, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Terminates the asynchronous loading started by clutter_image_load_async()
+ *
+ * Return value: %TRUE if the image data was loaded successfully
+ * and %FALSE otherwise
+ *
+ * Since: 1.6
+ */
gboolean
clutter_image_load_finish (ClutterImage *image,
GAsyncResult *res,
@@ -441,6 +648,8 @@ clutter_image_load_finish (ClutterImage *image,
GSimpleAsyncResult *simple;
ClutterImagePrivate *priv;
CoglHandle texture;
+ gint old_image_width, old_image_height;
+ gboolean width_changed, height_changed;
g_return_val_if_fail (CLUTTER_IS_IMAGE (image), FALSE);
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
@@ -469,6 +678,8 @@ clutter_image_load_finish (ClutterImage *image,
priv = image->priv;
+ old_image_width = priv->image_width;
+ old_image_height = priv->image_height;
_clutter_image_loader_get_image_size (closure->loader,
&priv->image_width,
&priv->image_height);
@@ -476,9 +687,32 @@ clutter_image_load_finish (ClutterImage *image,
texture = _clutter_image_loader_get_texture_handle (closure->loader);
cogl_material_set_layer (priv->material, 0, texture);
- g_signal_emit (image, image_signals[SIZE_CHANGED], 0,
- priv->image_width,
- priv->image_height);
+ g_object_freeze_notify (G_OBJECT (image));
+
+ if (priv->image_width != old_image_width)
+ {
+ g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_WIDTH]);
+ width_changed = TRUE;
+ }
+ else
+ width_changed = FALSE;
+
+ if (priv->image_height != old_image_height)
+ {
+ g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_HEIGHT]);
+ height_changed = TRUE;
+ }
+ else
+ height_changed = FALSE;
+
+ g_signal_emit (image, image_signals[IMAGE_CHANGED], 0);
+
+ if (width_changed || height_changed)
+ g_signal_emit (image, image_signals[SIZE_CHANGED], 0,
+ priv->image_width,
+ priv->image_height);
+
+ g_object_thaw_notify (G_OBJECT (image));
if (width)
*width = priv->image_width;
diff --git a/clutter/clutter-image.h b/clutter/clutter-image.h
index 4f5e061..9941e61 100644
--- a/clutter/clutter-image.h
+++ b/clutter/clutter-image.h
@@ -54,7 +54,9 @@ struct _ClutterImage
/**
* ClutterImageClass:
- * @size_changes: class handler for the #ClutterImage::size-changed signal
+ * @size_changed: class handler for the #ClutterImage::size-changed signal
+ * @image_changed: class handler for the #ClutterImage::image-changed
+ * signal
*
* The <structname>ClutterImageClass</structname> structure contains only
* private data.
@@ -71,6 +73,9 @@ struct _ClutterImageClass
gint new_width,
gint new_height);
+ void (* image_changed) (ClutterImage *image);
+
+ /*< private >*/
void (* _clutter_image_padding1) (void);
void (* _clutter_image_padding2) (void);
void (* _clutter_image_padding3) (void);
@@ -78,6 +83,7 @@ struct _ClutterImageClass
void (* _clutter_image_padding5) (void);
void (* _clutter_image_padding6) (void);
void (* _clutter_image_padding7) (void);
+ void (* _clutter_image_padding8) (void);
};
GQuark clutter_image_error_quark (void);
@@ -91,7 +97,6 @@ gboolean clutter_image_load_from_data (ClutterImage *image,
gint width,
gint height,
gint rowstride,
- gint bpp,
GError **error);
gboolean clutter_image_load (ClutterImage *image,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]