[cairo-commit] goocanvas/src goocanvasitem.c, 1.17,
1.18 goocanvasitem.h, 1.12, 1.13 goocanvasitemmodel.c, 1.7,
1.8 goocanvasitemmodel.h, 1.6, 1.7
Damon Chaplin
commit at pdx.freedesktop.org
Tue Feb 13 04:32:50 PST 2007
- Previous message: [cairo-commit]
goocanvas/demo Makefile.am, 1.8, 1.9 demo-animation.c,
NONE, 1.1 demo.c, 1.13, 1.14 mv-demo-animation.c, NONE,
1.1 mv-demo.c, 1.1, 1.2
- Next message: [cairo-commit] goocanvas/src goocanvas.h, 1.6, 1.7 goocanvasitem.c,
1.18, 1.19
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: damon
Update of /cvs/cairo/goocanvas/src
In directory kemper:/tmp/cvs-serv18111/src
Modified Files:
goocanvasitem.c goocanvasitem.h goocanvasitemmodel.c
goocanvasitemmodel.h
Log Message:
2007-02-13 Damon Chaplin <damon at gnome.org>
* src/goocanvasitemmodel.c (goo_canvas_item_model_animate):
* src/goocanvasitem.c (goo_canvas_item_animate): added "absolute"
parameter, and rewrote the animation code, using the same code for
GooCanvasItem and GooCanvasItemModel.
* demo/demo-animation.c:
* demo/mv-demo-animation.c: new files for animation demo pages.
* demo/mv-demo.c:
* demo/demo.c: added new animation pages and updated animation calls.
Index: goocanvasitem.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- goocanvasitem.c 12 Feb 2007 14:23:50 -0000 1.17
+++ goocanvasitem.c 13 Feb 2007 12:32:44 -0000 1.18
@@ -1030,8 +1030,12 @@
{
GooCanvasAnimateType type;
GooCanvasItem *item;
- int num_steps_left, total_steps;
- cairo_matrix_t start, step;
+ GooCanvasItemModel *model;
+ int step, total_steps;
+ cairo_matrix_t start;
+ gdouble x_start, y_start, scale_start, radians_start;
+ gdouble x_step, y_step, scale_step, radians_step;
+ gboolean absolute;
gboolean forward;
guint timeout_id;
};
@@ -1054,33 +1058,29 @@
goo_canvas_item_animate_cb (GooCanvasItemAnimation *anim)
{
GooCanvasItemIface *iface;
- cairo_matrix_t *matrix, new_matrix = { 1, 0, 0, 1, 0, 0 };
+ GooCanvasItemModelIface *model_iface;
+ cairo_matrix_t new_matrix;
gboolean keep_source = TRUE;
+ gdouble scale;
+ gint step;
GDK_THREADS_ENTER ();
- iface = GOO_CANVAS_ITEM_GET_IFACE (anim->item);
- matrix = iface->get_transform (anim->item);
- if (matrix)
- new_matrix = *matrix;
-
- new_matrix.xx += anim->step.xx;
- new_matrix.yx += anim->step.yx;
- new_matrix.xy += anim->step.xy;
- new_matrix.yy += anim->step.yy;
- new_matrix.x0 += anim->step.x0;
- new_matrix.y0 += anim->step.y0;
-
- iface->set_transform (anim->item, &new_matrix);
+ if (anim->model)
+ model_iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (anim->model);
+ else
+ iface = GOO_CANVAS_ITEM_GET_IFACE (anim->item);
- if (--anim->num_steps_left == 0)
+ if (++anim->step > anim->total_steps)
{
switch (anim->type)
{
case GOO_CANVAS_ANIMATE_RESET:
/* Reset the transform to the initial value. */
- /* FIXME: Need to wait one cycle at finish position? */
- iface->set_transform (anim->item, &anim->start);
+ if (anim->model)
+ model_iface->set_transform (anim->model, &anim->start);
+ else
+ iface->set_transform (anim->item, &anim->start);
/* Fall through.. */
case GOO_CANVAS_ANIMATE_FREEZE:
@@ -1088,31 +1088,52 @@
anim->timeout_id = 0;
/* This will result in a call to goo_canvas_item_free_animation()
above. We've set the timeout_id to 0 so it isn't removed twice. */
- g_object_set_data (G_OBJECT (anim->item), animation_key, NULL);
+ if (anim->model)
+ g_object_set_data (G_OBJECT (anim->model), animation_key, NULL);
+ else
+ g_object_set_data (G_OBJECT (anim->item), animation_key, NULL);
break;
case GOO_CANVAS_ANIMATE_RESTART:
- iface->set_transform (anim->item, &anim->start);
+ anim->step = 0;
break;
case GOO_CANVAS_ANIMATE_BOUNCE:
- /* Switch all the step values around. */
- anim->step.xx = -anim->step.xx;
- anim->step.yx = -anim->step.yx;
- anim->step.xy = -anim->step.xy;
- anim->step.yy = -anim->step.yy;
- anim->step.x0 = -anim->step.x0;
- anim->step.y0 = -anim->step.y0;
-
- /* FIXME: don't need this? Might be wise to reset to the initial
- transform each time we restart, to avoid little errors. */
anim->forward = !anim->forward;
+ anim->step = 1;
break;
}
+ }
- anim->num_steps_left = anim->total_steps;
+ step = anim->forward ? anim->step : anim->total_steps - anim->step;
+
+ if (anim->absolute)
+ {
+ cairo_matrix_init_identity (&new_matrix);
+ scale = anim->scale_start + anim->scale_step * step;
+ cairo_matrix_translate (&new_matrix,
+ anim->x_start + anim->x_step * step,
+ anim->y_start + anim->y_step * step);
+ cairo_matrix_scale (&new_matrix, scale, scale);
+ cairo_matrix_rotate (&new_matrix,
+ anim->radians_start + anim->radians_step * step);
+ }
+ else
+ {
+ new_matrix = anim->start;
+ scale = 1 + anim->scale_step * step;
+ cairo_matrix_translate (&new_matrix, anim->x_step * step,
+ anim->y_step * step);
+ cairo_matrix_scale (&new_matrix, scale, scale);
+ cairo_matrix_rotate (&new_matrix, anim->radians_step * step);
}
+ if (anim->model)
+ model_iface->set_transform (anim->model, &new_matrix);
+ else
+ iface->set_transform (anim->item, &new_matrix);
+
+
GDK_THREADS_LEAVE ();
/* Return FALSE to remove the timeout handler when we are finished. */
@@ -1120,6 +1141,90 @@
}
+void
+_goo_canvas_item_animate_internal (GooCanvasItem *item,
+ GooCanvasItemModel *model,
+ gdouble x,
+ gdouble y,
+ gdouble scale,
+ gdouble degrees,
+ gboolean absolute,
+ gint duration,
+ gint step_time,
+ GooCanvasAnimateType type)
+{
+ GObject *object;
+ cairo_matrix_t *matrix;
+ GooCanvasItemAnimation *anim;
+
+ if (item)
+ {
+ GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+ matrix = iface->get_transform (item);
+ object = (GObject*) item;
+ }
+ else
+ {
+ GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
+ matrix = iface->get_transform (model);
+ object = (GObject*) model;
+ }
+
+ anim = g_new (GooCanvasItemAnimation, 1);
+ anim->type = type;
+ anim->item = item;
+ anim->model = model;
+ anim->step = 0;
+ anim->total_steps = duration / step_time;
+ if (matrix)
+ anim->start = *matrix;
+ else
+ cairo_matrix_init_identity (&anim->start);
+ anim->absolute = absolute;
+ anim->forward = TRUE;
+
+ /* For absolute animation we have to try to calculate the current position,
+ scale and rotation. */
+ if (absolute)
+ {
+ cairo_matrix_t tmp_matrix = anim->start;
+ double x1 = 1.0, y1 = 0.0;
+
+ anim->x_start = tmp_matrix.x0;
+ anim->y_start = tmp_matrix.y0;
+
+ tmp_matrix.x0 = 0.0;
+ tmp_matrix.y0 = 0.0;
+
+ cairo_matrix_transform_point (&tmp_matrix, &x1, &y1);
+ anim->scale_start = sqrt (x1 * x1 + y1 * y1);
+ anim->radians_start = atan2 (y1, x1);
+
+ anim->x_step = (x - anim->x_start) / anim->total_steps;
+ anim->y_step = (y - anim->y_start) / anim->total_steps;
+ anim->scale_step = (scale - anim->scale_start) / anim->total_steps;
+ anim->radians_step = (degrees * (M_PI / 180) - anim->radians_start) / anim->total_steps;
+ }
+ else
+ {
+ anim->x_step = x / anim->total_steps;
+ anim->y_step = y / anim->total_steps;
+ anim->scale_step = (scale - 1.0) / anim->total_steps;
+ anim->radians_step = (degrees * (M_PI / 180)) / anim->total_steps;
+ }
+
+
+ /* Store a pointer to the new animation in the item. This will automatically
+ stop any current animation and free it. */
+ g_object_set_data_full (object, animation_key, anim,
+ (GDestroyNotify) goo_canvas_item_free_animation);
+
+ anim->timeout_id = g_timeout_add (step_time,
+ (GSourceFunc) goo_canvas_item_animate_cb,
+ anim);
+}
+
+
/**
* goo_canvas_item_animate:
* @item: an item.
@@ -1127,6 +1232,7 @@
* @y: the final y offset from the current position.
* @scale: the final scale of the item.
* @degrees: the final rotation of the item.
+ * @absolute: if the values are absolute or relative to the current transform.
* @duration: the duration of the animation, in milliseconds (1/1000ths of a
* second).
* @step_time: the time between each animation step, in milliseconds.
@@ -1141,45 +1247,13 @@
gdouble y,
gdouble scale,
gdouble degrees,
+ gboolean absolute,
gint duration,
gint step_time,
GooCanvasAnimateType type)
{
- GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
- cairo_matrix_t *matrix, identity_matrix = { 1, 0, 0, 1, 0, 0 };
- cairo_matrix_t new_matrix = { 1, 0, 0, 1, 0, 0 };
- GooCanvasItemAnimation *anim;
- double radians = degrees * (M_PI / 180);
-
- matrix = iface->get_transform (item);
- if (!matrix)
- matrix = &identity_matrix;
-
- cairo_matrix_translate (&new_matrix, x, y);
- cairo_matrix_scale (&new_matrix, scale, scale);
- cairo_matrix_rotate (&new_matrix, radians);
-
- anim = g_new (GooCanvasItemAnimation, 1);
- anim->type = type;
- anim->item = item;
- anim->total_steps = anim->num_steps_left = duration / step_time;
- anim->start = *matrix;
- anim->step.xx = (new_matrix.xx - matrix->xx) / anim->total_steps;
- anim->step.yx = (new_matrix.yx - matrix->yx) / anim->total_steps;
- anim->step.xy = (new_matrix.xy - matrix->xy) / anim->total_steps;
- anim->step.yy = (new_matrix.yy - matrix->yy) / anim->total_steps;
- anim->step.x0 = (new_matrix.x0 - matrix->x0) / anim->total_steps;
- anim->step.y0 = (new_matrix.y0 - matrix->y0) / anim->total_steps;
- anim->forward = TRUE;
-
- /* Store a pointer to the new animation in the item. This will automatically
- stop any current animation and free it. */
- g_object_set_data_full (G_OBJECT (item), animation_key, anim,
- (GDestroyNotify) goo_canvas_item_free_animation);
-
- anim->timeout_id = g_timeout_add (step_time,
- (GSourceFunc) goo_canvas_item_animate_cb,
- anim);
+ _goo_canvas_item_animate_internal (item, NULL, x, y, scale, degrees,
+ absolute, duration, step_time, type);
}
Index: goocanvasitem.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- goocanvasitem.h 9 Feb 2007 13:41:03 -0000 1.12
+++ goocanvasitem.h 13 Feb 2007 12:32:44 -0000 1.13
@@ -362,6 +362,7 @@
gdouble y,
gdouble scale,
gdouble degrees,
+ gboolean absolute,
gint duration,
gint step_time,
GooCanvasAnimateType type);
Index: goocanvasitemmodel.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitemmodel.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- goocanvasitemmodel.c 12 Feb 2007 14:27:33 -0000 1.7
+++ goocanvasitemmodel.c 13 Feb 2007 12:32:44 -0000 1.8
@@ -28,7 +28,7 @@
static GParamSpecPool *_goo_canvas_item_model_child_property_pool = NULL;
static GObjectNotifyContext *_goo_canvas_item_model_child_property_notify_context = NULL;
-static const char *animation_key = "GooCanvasItemModelAnimation";
+static const char *animation_key = "GooCanvasItemAnimation";
enum {
CHILD_ADDED,
@@ -752,100 +752,16 @@
}
-typedef struct _GooCanvasItemModelAnimation GooCanvasItemModelAnimation;
-struct _GooCanvasItemModelAnimation
-{
- GooCanvasAnimateType type;
- GooCanvasItemModel *model;
- int num_steps_left, total_steps;
- cairo_matrix_t start, step;
- gboolean forward;
- guint timeout_id;
-};
-
-
-static void
-goo_canvas_item_model_free_animation (GooCanvasItemModelAnimation *anim)
-{
- if (anim->timeout_id)
- {
- g_source_remove (anim->timeout_id);
- anim->timeout_id = 0;
- }
-
- g_free (anim);
-}
-
-
-static gboolean
-goo_canvas_item_model_animate_cb (GooCanvasItemModelAnimation *anim)
-{
- GooCanvasItemModelIface *iface;
- cairo_matrix_t *matrix, new_matrix = { 1, 0, 0, 1, 0, 0 };
- gboolean keep_source = TRUE;
-
- GDK_THREADS_ENTER ();
-
- iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (anim->model);
- matrix = iface->get_transform (anim->model);
- if (matrix)
- new_matrix = *matrix;
-
- new_matrix.xx += anim->step.xx;
- new_matrix.yx += anim->step.yx;
- new_matrix.xy += anim->step.xy;
- new_matrix.yy += anim->step.yy;
- new_matrix.x0 += anim->step.x0;
- new_matrix.y0 += anim->step.y0;
-
- iface->set_transform (anim->model, &new_matrix);
-
- if (--anim->num_steps_left == 0)
- {
- switch (anim->type)
- {
- case GOO_CANVAS_ANIMATE_RESET:
- /* Reset the transform to the initial value. */
- /* FIXME: Need to wait one cycle at finish position? */
- iface->set_transform (anim->model, &anim->start);
-
- /* Fall through.. */
- case GOO_CANVAS_ANIMATE_FREEZE:
- keep_source = FALSE;
- anim->timeout_id = 0;
- /* This will result in call to goo_canvas_item_model_free_animation()
- above. We've set the timeout_id to 0 so it isn't removed twice. */
- g_object_set_data (G_OBJECT (anim->model), animation_key, NULL);
- break;
-
- case GOO_CANVAS_ANIMATE_RESTART:
- iface->set_transform (anim->model, &anim->start);
- break;
-
- case GOO_CANVAS_ANIMATE_BOUNCE:
- /* Switch all the step values around. */
- anim->step.xx = -anim->step.xx;
- anim->step.yx = -anim->step.yx;
- anim->step.xy = -anim->step.xy;
- anim->step.yy = -anim->step.yy;
- anim->step.x0 = -anim->step.x0;
- anim->step.y0 = -anim->step.y0;
-
- /* FIXME: don't need this? Might be wise to reset to the initial
- transform each time we restart, to avoid little errors. */
- anim->forward = !anim->forward;
- break;
- }
-
- anim->num_steps_left = anim->total_steps;
- }
-
- GDK_THREADS_LEAVE ();
-
- /* Return FALSE to remove the timeout handler when we are finished. */
- return keep_source;
-}
-
+extern void _goo_canvas_item_animate_internal (GooCanvasItem *item,
+ GooCanvasItemModel *model,
+ gdouble x,
+ gdouble y,
+ gdouble scale,
+ gdouble degrees,
+ gboolean absolute,
+ gint duration,
+ gint step_time,
+ GooCanvasAnimateType type);
/**
* goo_canvas_item_model_animate:
@@ -854,6 +770,10 @@
* @y: the final y offset from the current position.
* @scale: the final scale of the model.
* @degrees: the final rotation of the model.
+ * @absolute: if the @x, @y, @scale and @degrees values are absolute, or
+ * relative to the current transform. Note that absolute animations only work
+ * if the model currently has a simple transform. If the model has a shear or
+ * some other complicated transform it may result in strange animations.
* @duration: the duration of the animation, in milliseconds (1/1000ths of a
* second).
* @step_time: the time between each animation step, in milliseconds.
@@ -868,45 +788,13 @@
gdouble y,
gdouble scale,
gdouble degrees,
+ gboolean absolute,
gint duration,
gint step_time,
GooCanvasAnimateType type)
{
- GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
- cairo_matrix_t *matrix, identity_matrix = { 1, 0, 0, 1, 0, 0 };
- cairo_matrix_t new_matrix = { 1, 0, 0, 1, 0, 0 };
- GooCanvasItemModelAnimation *anim;
- double radians = degrees * (M_PI / 180);
-
- matrix = iface->get_transform (model);
- if (!matrix)
- matrix = &identity_matrix;
-
- cairo_matrix_translate (&new_matrix, x, y);
- cairo_matrix_scale (&new_matrix, scale, scale);
- cairo_matrix_rotate (&new_matrix, radians);
-
- anim = g_new (GooCanvasItemModelAnimation, 1);
- anim->type = type;
- anim->model = model;
- anim->total_steps = anim->num_steps_left = duration / step_time;
- anim->start = *matrix;
- anim->step.xx = (new_matrix.xx - matrix->xx) / anim->total_steps;
- anim->step.yx = (new_matrix.yx - matrix->yx) / anim->total_steps;
- anim->step.xy = (new_matrix.xy - matrix->xy) / anim->total_steps;
- anim->step.yy = (new_matrix.yy - matrix->yy) / anim->total_steps;
- anim->step.x0 = (new_matrix.x0 - matrix->x0) / anim->total_steps;
- anim->step.y0 = (new_matrix.y0 - matrix->y0) / anim->total_steps;
- anim->forward = TRUE;
-
- /* Store a pointer to the new animation in the item. This will automatically
- stop any current animation and free it. */
- g_object_set_data_full (G_OBJECT (model), animation_key, anim,
- (GDestroyNotify) goo_canvas_item_model_free_animation);
-
- anim->timeout_id = g_timeout_add (step_time,
- (GSourceFunc) goo_canvas_item_model_animate_cb,
- anim);
+ _goo_canvas_item_animate_internal (NULL, model, x, y, scale, degrees,
+ absolute, duration, step_time, type);
}
@@ -920,7 +808,7 @@
void
goo_canvas_item_model_stop_animation (GooCanvasItemModel *model)
{
- /* This will result in a call to goo_canvas_item_model_free_animation(). */
+ /* This will result in a call to goo_canvas_item_free_animation() above. */
g_object_set_data (G_OBJECT (model), animation_key, NULL);
}
Index: goocanvasitemmodel.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitemmodel.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvasitemmodel.h 12 Feb 2007 14:27:33 -0000 1.6
+++ goocanvasitemmodel.h 13 Feb 2007 12:32:44 -0000 1.7
@@ -228,6 +228,7 @@
gdouble y,
gdouble scale,
gdouble degrees,
+ gboolean absolute,
gint duration,
gint step_time,
GooCanvasAnimateType type);
- Previous message: [cairo-commit]
goocanvas/demo Makefile.am, 1.8, 1.9 demo-animation.c,
NONE, 1.1 demo.c, 1.13, 1.14 mv-demo-animation.c, NONE,
1.1 mv-demo.c, 1.1, 1.2
- Next message: [cairo-commit] goocanvas/src goocanvas.h, 1.6, 1.7 goocanvasitem.c,
1.18, 1.19
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list