I have added the transition layout into edje too. It displays an
animation when changing box state with different layouts.
I am sending the patch for edje and an edc sample file.
From 985d56788cb9053baf93b2138a295d433efc45d9 Mon Sep 17 00:00:00 2001
From: Otavio Pontes <ota...@profusion.mobi>
Date: Mon, 20 Sep 2010 17:34:53 -0300
Subject: [PATCH] Adding a transition layout animation for edje box.
To: ota...@profusion.mobi
Perform an animation when changing the layout from an edje box.
---
edje/src/lib/Makefile.am | 1 +
edje/src/lib/edje_box_layout.c | 294 ++++++++++++++++++++++++++++++++++++++++
edje/src/lib/edje_calc.c | 37 -----
edje/src/lib/edje_private.h | 2 +
4 files changed, 297 insertions(+), 37 deletions(-)
create mode 100644 edje/src/lib/edje_box_layout.c
diff --git a/edje/src/lib/Makefile.am b/edje/src/lib/Makefile.am
index b73c96f..10546ff 100644
--- a/edje/src/lib/Makefile.am
+++ b/edje/src/lib/Makefile.am
@@ -20,6 +20,7 @@ includes_HEADERS = Edje.h Edje_Edit.h
includesdir = $(includedir)/ed...@vmaj@
base_sources = \
+edje_box_layout.c \
edje_calc.c \
edje_callbacks.c \
edje_data.c \
diff --git a/edje/src/lib/edje_box_layout.c b/edje/src/lib/edje_box_layout.c
new file mode 100644
index 0000000..4b5cf4a
--- /dev/null
+++ b/edje/src/lib/edje_box_layout.c
@@ -0,0 +1,294 @@
+#include "edje_private.h"
+
+#define SIG_CHILD_ADDED "child,added"
+#define SIG_CHILD_REMOVED "child,removed"
+typedef struct _Transition_Animation_Data Transition_Animation_Data;
+struct _Transition_Animation_Data
+{
+ Evas_Object *obj;
+ struct
+ {
+ Evas_Coord x, y, w, h;
+ } start, end;
+};
+
+struct _Edje_Part_Box_Animation
+{
+ struct
+ {
+ Evas_Object_Box_Layout layout;
+ void *data;
+ void(*free_data)(void *data);
+ Edje_Alignment align;
+ Evas_Point padding;
+ } start, end;
+ Eina_List *objs;
+ Eina_Bool recalculate:1;
+ Eina_Bool restart:1;
+ Evas_Object *box;
+ double progress;
+ double start_progress;
+ int box_start_w, box_start_h;
+};
+
+static Eina_Bool
+_edje_box_layout_find_all(const char *name, const char *name_alt, Evas_Object_Box_Layout *cb, void **data, void (**free_data)(void *data))
+{
+ if (!_edje_box_layout_find(name, cb, data, free_data))
+ {
+ if ((!name_alt) ||
+ (!_edje_box_layout_find(name_alt, cb, data, free_data)))
+ {
+ ERR("box layout '%s' (fallback '%s') not available, using horizontal.",
+ name, name_alt);
+ *cb = evas_object_box_layout_horizontal;
+ *free_data = NULL;
+ *data = NULL;
+ }
+ }
+}
+
+static void
+_edje_box_layout_calculate_coords(Evas_Object *obj, Evas_Object_Box_Data *priv, Edje_Part_Box_Animation *anim)
+{
+ Eina_List *l;
+ Transition_Animation_Data *tad;
+ Evas_Coord x, y;
+
+ evas_object_geometry_get(obj, &x, &y, &anim->box_start_w, &anim->box_start_h);
+ EINA_LIST_FOREACH(anim->objs, l, tad)
+ {
+ evas_object_geometry_get(tad->obj, &tad->start.x, &tad->start.y,
+ &tad->start.w, &tad->start.h);
+ tad->start.x = tad->start.x - x;
+ tad->start.y = tad->start.y - y;
+ }
+ evas_object_box_padding_set(obj, anim->end.padding.x, anim->end.padding.y);
+ evas_object_box_align_set(obj, TO_DOUBLE(anim->end.align.x), TO_DOUBLE(anim->end.align.y));
+ anim->end.layout(obj, priv, anim->end.data);
+ EINA_LIST_FOREACH(anim->objs, l, tad)
+ {
+ evas_object_geometry_get(tad->obj, &tad->end.x, &tad->end.y,
+ &tad->end.w, &tad->end.h);
+ tad->end.x = tad->end.x - x;
+ tad->end.y = tad->end.y - y;
+ }
+}
+
+static Eina_Bool
+_edje_box_layout_load_children_list(Evas_Object_Box_Data *priv,
+ Edje_Part_Box_Animation *anim)
+{
+ Eina_List *l;
+ Evas_Object_Box_Option *opt;
+ Transition_Animation_Data *tad;
+
+ EINA_LIST_FREE(anim->objs, tad)
+ free(tad);
+
+ EINA_LIST_FOREACH(priv->children, l, opt)
+ {
+ tad = calloc(1, sizeof(Transition_Animation_Data));
+ if (!tad)
+ {
+ EINA_LIST_FREE(anim->objs, tad)
+ free(tad);
+ anim->objs = NULL;
+ return EINA_FALSE;
+ }
+ tad->obj = opt->obj;
+ anim->objs = eina_list_append(anim->objs, tad);
+
+ }
+ return EINA_TRUE;
+}
+
+static void
+_edje_box_layout_exec(Evas_Object *obj, Evas_Object_Box_Data *priv,
+ Edje_Part_Box_Animation *anim)
+{
+ Eina_List *l;
+ Transition_Animation_Data *tad;
+ Evas_Coord x, y, w, h;
+ Evas_Coord cur_x, cur_y, cur_w, cur_h;
+ evas_object_geometry_get(obj, &x, &y, &w, &h);
+ double progress = (anim->progress - anim->start_progress) / (1 - anim->start_progress);
+
+ EINA_LIST_FOREACH(anim->objs, l, tad)
+ {
+ cur_x = x + (tad->start.x + ((tad->end.x - tad->start.x) * progress)) * (w / (double)anim->box_start_w);
+ cur_y = y + (tad->start.y + ((tad->end.y - tad->start.y) * progress)) * (h / (double)anim->box_start_h);
+ cur_w = (w / (double)anim->box_start_w) * (tad->start.w + ((tad->end.w - tad->start.w) * progress));
+ cur_h = (h / (double)anim->box_start_h) * (tad->start.h + ((tad->end.h - tad->start.h) * progress));
+ evas_object_move(tad->obj, cur_x, cur_y);
+ evas_object_resize(tad->obj, cur_w, cur_h);
+ }
+}
+
+static void
+_edje_box_layout(Evas_Object *obj, Evas_Object_Box_Data *priv, void *data)
+{
+ Edje_Part_Box_Animation *anim = data;
+ if (anim->progress == 0.0)
+ {
+ evas_object_box_padding_set(obj, anim->start.padding.x, anim->start.padding.y);
+ evas_object_box_align_set(obj, TO_DOUBLE(anim->start.align.x), TO_DOUBLE(anim->start.align.y));
+ anim->start.layout(obj, priv, anim->start.data);
+ return;
+ }
+
+ if (anim->restart)
+ {
+ if (!_edje_box_layout_load_children_list(priv, anim))
+ {
+ ERR("Error when allocating memory for box animation data.\n");
+ return;
+ }
+ evas_object_box_padding_set(obj, anim->start.padding.x, anim->start.padding.y);
+ evas_object_box_align_set(obj, TO_DOUBLE(anim->start.align.x), TO_DOUBLE(anim->start.align.y));
+ anim->start.layout(obj, priv, anim->start.data);
+ _edje_box_layout_calculate_coords(obj, priv, anim);
+ anim->start_progress = 0.0;
+ anim->restart = EINA_FALSE;
+ }
+ else if (anim->recalculate)
+ {
+ _edje_box_layout_calculate_coords(obj, priv, anim);
+ anim->start_progress = anim->progress;
+ anim->recalculate = EINA_FALSE;
+ }
+
+ _edje_box_layout_exec(obj, priv, anim);
+}
+
+static void
+_edje_box_layout_child_added(void *data, Evas_Object *obj, void *event_info)
+{
+ Transition_Animation_Data *tad;
+ Evas_Object_Box_Option *opt = event_info;
+ Edje_Part_Box_Animation *anim = data;
+ tad = calloc(1, sizeof(Transition_Animation_Data));
+ if (!tad)
+ return;
+ tad->obj = opt->obj;
+ anim->objs = eina_list_append(anim->objs, tad);
+
+ anim->recalculate = EINA_TRUE;
+}
+
+static void
+_edje_box_layout_child_removed(void *data, Evas_Object *obj, void *event_info)
+{
+ Eina_List *l;
+ Transition_Animation_Data *tad;
+ Edje_Part_Box_Animation *anim = data;
+
+ EINA_LIST_FOREACH(anim->objs, l, tad)
+ {
+ if (tad->obj == event_info)
+ {
+ free(eina_list_data_get(l));
+ anim->objs = eina_list_remove_list(anim->objs, l);
+ anim->recalculate = EINA_TRUE;
+ break;
+ }
+ }
+}
+
+static void
+_edje_box_layout_free_data(void *data)
+{
+ Transition_Animation_Data *tad;
+ Edje_Part_Box_Animation *anim = data;
+ if (anim->start.free_data && anim->start.data)
+ anim->start.free_data(anim->start.data);
+ if (anim->end.free_data && anim->end.data)
+ anim->end.free_data(anim->end.data);
+ EINA_LIST_FREE(anim->objs, tad)
+ free(tad);
+ evas_object_smart_callback_del(anim->box, SIG_CHILD_ADDED, _edje_box_layout_child_added);
+ evas_object_smart_callback_del(anim->box, SIG_CHILD_REMOVED, _edje_box_layout_child_removed);
+ free(data);
+}
+
+static Edje_Part_Box_Animation *
+_edje_box_animation_new(Evas_Object *box)
+{
+ Edje_Part_Box_Animation *anim = calloc(1, sizeof(Edje_Part_Box_Animation));
+ if (!anim)
+ return NULL;
+
+ anim->box = box;
+ evas_object_smart_callback_add(anim->box, SIG_CHILD_ADDED, _edje_box_layout_child_added, anim);
+ evas_object_smart_callback_add(anim->box, SIG_CHILD_REMOVED, _edje_box_layout_child_removed, anim);
+
+ return anim;
+}
+
+void
+_edje_box_recalc_apply(Edje *ed __UNUSED__, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edje_Part_Description_Box *chosen_desc)
+{
+ Evas_Object_Box_Layout layout;
+ void (*free_data)(void *data);
+ void *data;
+ int min_w, min_h;
+
+ if (!ep->anim)
+ {
+ ep->anim = _edje_box_animation_new(ep->object);
+ if (!ep->anim)
+ {
+ ERR("Error when allocating memory for box animation data.\n");
+ goto error_calloc;
+ }
+
+ _edje_box_layout_find_all(chosen_desc->box.layout, chosen_desc->box.alt_layout, &ep->anim->start.layout, &ep->anim->start.data, &ep->anim->start.free_data);
+ ep->anim->start.padding.x = chosen_desc->box.padding.x;
+ ep->anim->start.padding.y = chosen_desc->box.padding.y;
+ ep->anim->start.align.x = chosen_desc->box.align.x;
+ ep->anim->start.align.y = chosen_desc->box.align.y;
+
+ evas_object_box_layout_set(ep->object, _edje_box_layout, ep->anim, _edje_box_layout_free_data);
+ }
+
+ if ((ep->param2) && (ep->description_pos != ZERO))
+ {
+ Edje_Part_Description_Box *param2_desc = (Edje_Part_Description_Box *)ep->param2->description;
+ if (ep->anim->end.layout == NULL)
+ {
+ _edje_box_layout_find_all(param2_desc->box.layout, param2_desc->box.alt_layout, &ep->anim->end.layout, &ep->anim->end.data, &ep->anim->end.free_data);
+ ep->anim->end.padding.x = param2_desc->box.padding.x;
+ ep->anim->end.padding.y = param2_desc->box.padding.y;
+ ep->anim->end.align.x = param2_desc->box.align.x;
+ ep->anim->end.align.y = param2_desc->box.align.y;
+ ep->anim->restart = EINA_TRUE;
+ }
+ evas_object_smart_changed(ep->object);
+ }
+ else {
+ if (ep->description_pos == ZERO)
+ {
+ _edje_box_layout_find_all(chosen_desc->box.layout, chosen_desc->box.alt_layout, &ep->anim->start.layout, &ep->anim->start.data, &ep->anim->start.free_data);
+ ep->anim->start.padding.x = chosen_desc->box.padding.x;
+ ep->anim->start.padding.y = chosen_desc->box.padding.y;
+ ep->anim->start.align.x = chosen_desc->box.align.x;
+ ep->anim->start.align.y = chosen_desc->box.align.y;
+ evas_object_smart_changed(ep->object);
+ }
+ ep->anim->end.layout = NULL;
+ }
+
+ ep->anim->progress = ep->description_pos;
+
+error_calloc:
+ if (evas_object_smart_need_recalculate_get(ep->object))
+ {
+ evas_object_smart_need_recalculate_set(ep->object, 0);
+ evas_object_smart_calculate(ep->object);
+ }
+ evas_object_size_hint_min_get(ep->object, &min_w, &min_h);
+ if (chosen_desc->box.min.h && (p3->w < min_w))
+ p3->w = min_w;
+ if (chosen_desc->box.min.v && (p3->h < min_h))
+ p3->h = min_h;
+}
diff --git a/edje/src/lib/edje_calc.c b/edje/src/lib/edje_calc.c
index 11fdfa6..ef12669 100644
--- a/edje/src/lib/edje_calc.c
+++ b/edje/src/lib/edje_calc.c
@@ -1423,43 +1423,6 @@ _edje_part_recalc_single(Edje *ed,
}
static void
-_edje_box_recalc_apply(Edje *ed __UNUSED__, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edje_Part_Description_Box *chosen_desc)
-{
- Evas_Object_Box_Layout layout;
- void (*free_data)(void *data);
- void *data;
- int min_w, min_h;
-
- if (!_edje_box_layout_find(chosen_desc->box.layout, &layout, &data, &free_data))
- {
- if ((!chosen_desc->box.alt_layout) ||
- (!_edje_box_layout_find(chosen_desc->box.alt_layout, &layout, &data, &free_data)))
- {
- ERR("box layout '%s' (fallback '%s') not available, using horizontal.",
- chosen_desc->box.layout, chosen_desc->box.alt_layout);
- layout = evas_object_box_layout_horizontal;
- free_data = NULL;
- data = NULL;
- }
- }
-
- evas_object_box_layout_set(ep->object, layout, data, free_data);
- evas_object_box_align_set(ep->object, TO_DOUBLE(chosen_desc->box.align.x), TO_DOUBLE(chosen_desc->box.align.y));
- evas_object_box_padding_set(ep->object, chosen_desc->box.padding.x, chosen_desc->box.padding.y);
-
- if (evas_object_smart_need_recalculate_get(ep->object))
- {
- evas_object_smart_need_recalculate_set(ep->object, 0);
- evas_object_smart_calculate(ep->object);
- }
- evas_object_size_hint_min_get(ep->object, &min_w, &min_h);
- if (chosen_desc->box.min.h && (p3->w < min_w))
- p3->w = min_w;
- if (chosen_desc->box.min.v && (p3->h < min_h))
- p3->h = min_h;
-}
-
-static void
_edje_table_recalc_apply(Edje *ed __UNUSED__,
Edje_Real_Part *ep,
Edje_Calc_Params *p3 __UNUSED__,
diff --git a/edje/src/lib/edje_private.h b/edje/src/lib/edje_private.h
index 8ffc141..93bbf20 100644
--- a/edje/src/lib/edje_private.h
+++ b/edje/src/lib/edje_private.h
@@ -269,6 +269,7 @@ typedef struct _Edje_Part_Description_Spec_Text Edje_Part_Description_Spec_
typedef struct _Edje_Part_Description_Spec_Box Edje_Part_Description_Spec_Box;
typedef struct _Edje_Part_Description_Spec_Table Edje_Part_Description_Spec_Table;
typedef struct _Edje_Patterns Edje_Patterns;
+typedef struct _Edje_Part_Box_Animation Edje_Part_Box_Animation;
#define EDJE_INF_MAX_W 100000
#define EDJE_INF_MAX_H 100000
@@ -1088,6 +1089,7 @@ struct _Edje_Real_Part
Edje_Rectangle req; // 16
Eina_List *items; // 4 //FIXME: only if table/box
+ Edje_Part_Box_Animation *anim; // 4 //FIXME: Used only if box
void *entry_data; // 4 // FIXME: move to entry section
Evas_Object *cursorbg_object; // 4 // FIXME: move to entry section
Evas_Object *cursorfg_object; // 4 // FIXME: move to entry section
--
1.7.2.3
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel