[clutter] cairo-texture: Add the :auto-resize property
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter] cairo-texture: Add the :auto-resize property
- Date: Tue, 26 Jul 2011 13:55:32 +0000 (UTC)
commit 7f8838d7cc9fe42ce694830cd07fa0ad0c1d27db
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Tue Jul 26 14:53:26 2011 +0100
cairo-texture: Add the :auto-resize property
Keeping the backing Cairo surface of a CairoTexture canvas in sync with
the actor's allocation is tedious and prone to mistakes. We can
definitely do better by simply exposing a property that does the surface
resize and invalidation automagically on ::allocate.
clutter/clutter-cairo-texture.c | 120 +++++++++++++++++++++++++++-
clutter/clutter-cairo-texture.h | 3 +
doc/reference/clutter/clutter-sections.txt | 2 +
tests/interactive/test-cairo-clock.c | 9 ++-
4 files changed, 129 insertions(+), 5 deletions(-)
---
diff --git a/clutter/clutter-cairo-texture.c b/clutter/clutter-cairo-texture.c
index f5ec310..a6a5b88 100644
--- a/clutter/clutter-cairo-texture.c
+++ b/clutter/clutter-cairo-texture.c
@@ -67,7 +67,7 @@
#include "config.h"
#endif
-#include <string.h>
+#include <math.h>
#include <cairo-gobject.h>
@@ -88,6 +88,7 @@ enum
PROP_SURFACE_WIDTH,
PROP_SURFACE_HEIGHT,
+ PROP_AUTO_RESIZE,
PROP_LAST
};
@@ -125,6 +126,8 @@ struct _ClutterCairoTexturePrivate
guint surface_height;
cairo_t *cr_context;
+
+ guint auto_resize : 1;
};
typedef struct {
@@ -173,6 +176,9 @@ clutter_cairo_texture_set_property (GObject *object,
switch (prop_id)
{
case PROP_SURFACE_WIDTH:
+ /* we perform the resize on notify to coalesce separate
+ * surface-width/surface-height property set
+ */
priv->surface_width = g_value_get_uint (value);
break;
@@ -180,6 +186,11 @@ clutter_cairo_texture_set_property (GObject *object,
priv->surface_height = g_value_get_uint (value);
break;
+ case PROP_AUTO_RESIZE:
+ clutter_cairo_texture_set_auto_resize (CLUTTER_CAIRO_TEXTURE (object),
+ g_value_get_boolean (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -206,6 +217,10 @@ clutter_cairo_texture_get_property (GObject *object,
g_value_set_uint (value, priv->surface_height);
break;
+ case PROP_AUTO_RESIZE:
+ g_value_set_boolean (value, priv->auto_resize);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -431,6 +446,32 @@ clutter_cairo_texture_get_preferred_height (ClutterActor *actor,
*natural_height = (gfloat) priv->surface_height;
}
+static void
+clutter_cairo_texture_allocate (ClutterActor *self,
+ const ClutterActorBox *allocation,
+ ClutterAllocationFlags flags)
+{
+ ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (self)->priv;
+ ClutterActorClass *parent_class;
+
+ parent_class = CLUTTER_ACTOR_CLASS (clutter_cairo_texture_parent_class);
+ parent_class->allocate (self, allocation, flags);
+
+ if (priv->auto_resize)
+ {
+ ClutterCairoTexture *texture = CLUTTER_CAIRO_TEXTURE (self);
+ gfloat width, height;
+
+ clutter_actor_box_get_size (allocation, &width, &height);
+
+ priv->surface_width = ceilf (width + 0.5);
+ priv->surface_height = ceilf (height + 0.5);
+
+ clutter_cairo_texture_surface_resize_internal (texture);
+ clutter_cairo_texture_invalidate (texture);
+ }
+}
+
static gboolean
clutter_cairo_texture_get_paint_volume (ClutterActor *self,
ClutterPaintVolume *volume)
@@ -521,6 +562,8 @@ clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
clutter_cairo_texture_get_preferred_width;
actor_class->get_preferred_height =
clutter_cairo_texture_get_preferred_height;
+ actor_class->allocate =
+ clutter_cairo_texture_allocate;
klass->create_surface = clutter_cairo_texture_create_surface;
@@ -557,9 +600,24 @@ clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
0,
CLUTTER_PARAM_READWRITE);
- g_object_class_install_properties (gobject_class,
- PROP_LAST,
- obj_props);
+ /**
+ * ClutterCairoTexture:auto-resize:
+ *
+ * Controls whether the #ClutterCairoTexture should automatically
+ * resize the Cairo surface whenever the actor's allocation changes.
+ * If :auto-resize is set to %TRUE the surface contents will also
+ * be invalidated automatically.
+ *
+ * Since: 1.8
+ */
+ obj_props[PROP_AUTO_RESIZE] =
+ g_param_spec_boolean ("auto-resize",
+ P_("Auto Resize"),
+ P_("Whether the surface should match the allocation"),
+ FALSE,
+ CLUTTER_PARAM_READWRITE);
+
+ g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
/**
* ClutterCairoTexture::create-surface:
@@ -1058,3 +1116,57 @@ clutter_cairo_texture_clear (ClutterCairoTexture *self)
if (priv->cr_context == NULL)
cairo_destroy (cr);
}
+
+/**
+ * clutter_cairo_texture_set_auto_resize:
+ * @self: a #ClutterCairoTexture
+ * @value: %TRUE if the #ClutterCairoTexture should bind the surface
+ * size to the allocation
+ *
+ * Sets whether the #ClutterCairoTexture should ensure that the
+ * backing Cairo surface used matches the allocation assigned to
+ * the actor. If the allocation changes, the contents of the
+ * #ClutterCairoTexture will also be invalidated automatically.
+ *
+ * Since: 1.8
+ */
+void
+clutter_cairo_texture_set_auto_resize (ClutterCairoTexture *self,
+ gboolean value)
+{
+ ClutterCairoTexturePrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self));
+
+ value = !!value;
+
+ priv = self->priv;
+
+ if (priv->auto_resize == value)
+ return;
+
+ priv->auto_resize = value;
+
+ clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_AUTO_RESIZE]);
+}
+
+/**
+ * clutter_cairo_texture_get_auto_resize:
+ * @self: a #ClutterCairoTexture
+ *
+ * Retrieves the value set using clutter_cairo_texture_set_auto_resize().
+ *
+ * Return value: %TRUE if the #ClutterCairoTexture should track the
+ * allocation, and %FALSE otherwise
+ *
+ * Since: 1.8
+ */
+gboolean
+clutter_cairo_texture_get_auto_resize (ClutterCairoTexture *self)
+{
+ g_return_val_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self), FALSE);
+
+ return self->priv->auto_resize;
+}
diff --git a/clutter/clutter-cairo-texture.h b/clutter/clutter-cairo-texture.h
index 4126a62..4b65f8c 100644
--- a/clutter/clutter-cairo-texture.h
+++ b/clutter/clutter-cairo-texture.h
@@ -131,6 +131,9 @@ void clutter_cairo_texture_set_surface_size (ClutterCairoTex
void clutter_cairo_texture_get_surface_size (ClutterCairoTexture *self,
guint *width,
guint *height);
+void clutter_cairo_texture_set_auto_resize (ClutterCairoTexture *self,
+ gboolean value);
+gboolean clutter_cairo_texture_get_auto_resize (ClutterCairoTexture *self);
void clutter_cairo_texture_clear (ClutterCairoTexture *self);
diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt
index 6d35cd1..21e4da2 100644
--- a/doc/reference/clutter/clutter-sections.txt
+++ b/doc/reference/clutter/clutter-sections.txt
@@ -1756,6 +1756,8 @@ ClutterCairoTextureClass
clutter_cairo_texture_new
clutter_cairo_texture_set_surface_size
clutter_cairo_texture_get_surface_size
+clutter_cairo_texture_set_auto_resize
+clutter_cairo_texture_get_auto_resize
<SUBSECTION>
clutter_cairo_texture_create
diff --git a/tests/interactive/test-cairo-clock.c b/tests/interactive/test-cairo-clock.c
index b887723..f847e7a 100644
--- a/tests/interactive/test-cairo-clock.c
+++ b/tests/interactive/test-cairo-clock.c
@@ -78,10 +78,11 @@ test_cairo_clock_main (int argc, char *argv[])
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return EXIT_FAILURE;
- /* create a fixed size stage */
+ /* create a resizable stage */
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "2D Clock");
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_LightSkyBlue);
+ clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_size (stage, 300, 300);
clutter_actor_show (stage);
@@ -89,6 +90,12 @@ test_cairo_clock_main (int argc, char *argv[])
canvas = clutter_cairo_texture_new (300, 300);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), canvas);
+ /* bind the size of the canvas to that of the stage */
+ clutter_actor_add_constraint (canvas, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0));
+
+ /* make sure to match allocation to canvas size */
+ clutter_cairo_texture_set_auto_resize (CLUTTER_CAIRO_TEXTURE (canvas), TRUE);
+
/* quit on destroy */
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]