summaryrefslogtreecommitdiff
path: root/src/lib/evas/canvas/evas_object_main.c
diff options
context:
space:
mode:
authorJaehyun Cho <jae_hyun.cho@samsung.com>2017-08-30 16:16:18 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2017-10-12 21:03:49 +0900
commita6e03da5f0a9942d18bfb98058f33d3547585c9b (patch)
treea19a81f1b3731628165e18ea94db7ebf5f3ecb9f /src/lib/evas/canvas/evas_object_main.c
parent4112a68e321a4f65a6c867251192f2095a29208d (diff)
efl_animation: Support event animation
Register an animation for an event. Start the animation when the event happens.
Diffstat (limited to '')
-rw-r--r--src/lib/evas/canvas/evas_object_main.c333
1 files changed, 333 insertions, 0 deletions
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index e6f36ec280..45b47906c9 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -46,6 +46,19 @@ Eina_Cow *evas_object_3d_cow = NULL;
46Eina_Cow *evas_object_mask_cow = NULL; 46Eina_Cow *evas_object_mask_cow = NULL;
47Eina_Cow *evas_object_events_cow = NULL; 47Eina_Cow *evas_object_events_cow = NULL;
48 48
49typedef struct _Event_Animation
50{
51 Efl_Animation *anim;
52 Efl_Animation_Object *anim_obj;
53} Event_Animation;
54
55typedef struct _Hide_Anim_Data
56{
57 Efl_Canvas_Object *target;
58 Eina_Bool anim_started;
59 Eina_Bool anim_ended;
60} Hide_Anim_Data;
61
49static Eina_Bool 62static Eina_Bool
50_init_cow(void) 63_init_cow(void)
51{ 64{
@@ -164,6 +177,33 @@ _evas_object_pointer_data_get(Evas_Pointer_Data *evas_pdata,
164 return pdata; 177 return pdata;
165} 178}
166 179
180static void
181_init_event_anims(Evas_Object_Protected_Data *obj)
182{
183 obj->event_anims = eina_array_new(EFL_ANIMATION_EVENT_TYPE_COUNT);
184
185 int i;
186 for (i = 0; i < EFL_ANIMATION_EVENT_TYPE_COUNT; i++)
187 {
188 Event_Animation *event_anims = calloc(1, sizeof(Event_Animation));
189 eina_array_push(obj->event_anims, event_anims);
190 }
191}
192
193static void
194_free_event_anims(Evas_Object_Protected_Data *obj)
195{
196 int i;
197 for (i = 0; i < EFL_ANIMATION_EVENT_TYPE_COUNT; i++)
198 {
199 Event_Animation *event_anims = eina_array_pop(obj->event_anims);
200 if (event_anims) free(event_anims);
201 }
202
203 eina_array_free(obj->event_anims);
204 obj->event_anims = NULL;
205}
206
167EOLIAN static Eo * 207EOLIAN static Eo *
168_efl_canvas_object_efl_object_constructor(Eo *eo_obj, Evas_Object_Protected_Data *obj) 208_efl_canvas_object_efl_object_constructor(Eo *eo_obj, Evas_Object_Protected_Data *obj)
169{ 209{
@@ -192,6 +232,7 @@ _efl_canvas_object_efl_object_constructor(Eo *eo_obj, Evas_Object_Protected_Data
192 obj->data_3d = eina_cow_alloc(evas_object_3d_cow); 232 obj->data_3d = eina_cow_alloc(evas_object_3d_cow);
193 obj->mask = eina_cow_alloc(evas_object_mask_cow); 233 obj->mask = eina_cow_alloc(evas_object_mask_cow);
194 obj->events = eina_cow_alloc(evas_object_events_cow); 234 obj->events = eina_cow_alloc(evas_object_events_cow);
235 _init_event_anims(obj);
195 236
196 evas_object_inject(eo_obj, obj, evas); 237 evas_object_inject(eo_obj, obj, evas);
197 evas_object_callback_init(eo_obj, obj); 238 evas_object_callback_init(eo_obj, obj);
@@ -502,6 +543,7 @@ evas_object_free(Evas_Object *eo_obj, Eina_Bool clean_layer)
502 eina_cow_free(evas_object_3d_cow, (const Eina_Cow_Data**) &obj->data_3d); 543 eina_cow_free(evas_object_3d_cow, (const Eina_Cow_Data**) &obj->data_3d);
503 eina_cow_free(evas_object_mask_cow, (const Eina_Cow_Data**) &obj->mask); 544 eina_cow_free(evas_object_mask_cow, (const Eina_Cow_Data**) &obj->mask);
504 eina_cow_free(evas_object_events_cow, (const Eina_Cow_Data**) &obj->events); 545 eina_cow_free(evas_object_events_cow, (const Eina_Cow_Data**) &obj->events);
546 _free_event_anims(obj);
505 efl_data_unref(eo_obj, obj->private_data); 547 efl_data_unref(eo_obj, obj->private_data);
506 obj->private_data = NULL; 548 obj->private_data = NULL;
507 549
@@ -1028,6 +1070,81 @@ _is_event_blocked(Eo *eo_obj, const Efl_Event_Description *desc,
1028 return EINA_FALSE; 1070 return EINA_FALSE;
1029} 1071}
1030 1072
1073static Eina_Bool
1074_efl_animation_event_type_is_inform_call(Efl_Animation_Event_Type event)
1075{
1076 if ((event == EFL_ANIMATION_EVENT_TYPE_SHOW) ||
1077 (event == EFL_ANIMATION_EVENT_TYPE_HIDE))
1078 return EINA_TRUE;
1079
1080 return EINA_FALSE;
1081}
1082
1083//These macros are matched to Efl_Animation_Event_Type enum values.
1084#define EFL_ANIMATION_EVENT_TYPE_SHOW_STR "show"
1085#define EFL_ANIMATION_EVENT_TYPE_HIDE_STR "hide"
1086#define EFL_ANIMATION_EVENT_TYPE_CLICKED_STR "clicked"
1087
1088static Efl_Animation_Event_Type
1089_efl_animation_event_type_get(const char *event_str)
1090{
1091 if (!event_str) return -1;
1092
1093 if (!strncmp(event_str, EFL_ANIMATION_EVENT_TYPE_SHOW_STR,
1094 strlen(EFL_ANIMATION_EVENT_TYPE_SHOW_STR)))
1095 return EFL_ANIMATION_EVENT_TYPE_SHOW;
1096
1097 else if (!strncmp(event_str, EFL_ANIMATION_EVENT_TYPE_HIDE_STR,
1098 strlen(EFL_ANIMATION_EVENT_TYPE_HIDE_STR)))
1099 return EFL_ANIMATION_EVENT_TYPE_HIDE;
1100
1101 else if (!strncmp(event_str, EFL_ANIMATION_EVENT_TYPE_CLICKED_STR,
1102 strlen(EFL_ANIMATION_EVENT_TYPE_CLICKED_STR)))
1103 return EFL_ANIMATION_EVENT_TYPE_CLICKED;
1104
1105 return -1;
1106}
1107
1108static Eina_Bool
1109_efl_animation_event_type_is_valid(Efl_Animation_Event_Type event)
1110{
1111 if ((event < 0) || (event >= EFL_ANIMATION_EVENT_TYPE_COUNT))
1112 return EINA_FALSE;
1113
1114 return EINA_TRUE;
1115}
1116
1117static Efl_Animation_Object *
1118_event_animation_object_get(Eo *eo_obj, Efl_Animation_Event_Type event_type)
1119{
1120 Evas_Object_Protected_Data *pd = efl_data_scope_get(eo_obj, MY_CLASS);
1121 if (!pd) return NULL;
1122
1123 if (!_efl_animation_event_type_is_valid(event_type))
1124 return NULL;
1125
1126 Event_Animation *event_anim = eina_array_data_get(pd->event_anims,
1127 event_type);
1128 if (event_anim && event_anim->anim_obj)
1129 return event_anim->anim_obj;
1130
1131 return NULL;
1132}
1133
1134static void
1135_all_animation_objects_cancel(Eo *eo_obj)
1136{
1137 Efl_Animation_Event_Type event_type;
1138 for (event_type = EFL_ANIMATION_EVENT_TYPE_SHOW;
1139 event_type < EFL_ANIMATION_EVENT_TYPE_COUNT; event_type++)
1140 {
1141 Efl_Animation_Object *anim_obj =
1142 _event_animation_object_get(eo_obj, event_type);
1143 if (anim_obj)
1144 efl_animation_object_cancel(anim_obj);
1145 }
1146}
1147
1031EOLIAN static Eina_Bool 1148EOLIAN static Eina_Bool
1032_efl_canvas_object_efl_object_event_callback_call(Eo *eo_obj, 1149_efl_canvas_object_efl_object_event_callback_call(Eo *eo_obj,
1033 Evas_Object_Protected_Data *obj EINA_UNUSED, 1150 Evas_Object_Protected_Data *obj EINA_UNUSED,
@@ -1035,6 +1152,25 @@ _efl_canvas_object_efl_object_event_callback_call(Eo *eo_obj,
1035 void *event_info) 1152 void *event_info)
1036{ 1153{
1037 if (_is_event_blocked(eo_obj, desc, event_info)) return EINA_FALSE; 1154 if (_is_event_blocked(eo_obj, desc, event_info)) return EINA_FALSE;
1155
1156 //Start animation corresponding to the current event
1157 if (desc && desc->name)
1158 {
1159 Efl_Animation_Event_Type event_type =
1160 _efl_animation_event_type_get(desc->name);
1161
1162 if (!_efl_animation_event_type_is_inform_call(event_type))
1163 {
1164 Efl_Animation_Object *anim_obj =
1165 _event_animation_object_get(eo_obj, event_type);
1166 if (anim_obj)
1167 {
1168 _all_animation_objects_cancel(eo_obj);
1169 efl_animation_object_start(anim_obj);
1170 }
1171 }
1172 }
1173
1038 return efl_event_callback_call(efl_super(eo_obj, MY_CLASS), 1174 return efl_event_callback_call(efl_super(eo_obj, MY_CLASS),
1039 desc, event_info); 1175 desc, event_info);
1040} 1176}
@@ -1046,6 +1182,25 @@ _efl_canvas_object_efl_object_event_callback_legacy_call(Eo *eo_obj,
1046 void *event_info) 1182 void *event_info)
1047{ 1183{
1048 if (_is_event_blocked(eo_obj, desc, event_info)) return EINA_FALSE; 1184 if (_is_event_blocked(eo_obj, desc, event_info)) return EINA_FALSE;
1185
1186 //Start animation corresponding to the current event
1187 if (desc && desc->name)
1188 {
1189 Efl_Animation_Event_Type event_type =
1190 _efl_animation_event_type_get(desc->name);
1191
1192 if (!_efl_animation_event_type_is_inform_call(event_type))
1193 {
1194 Efl_Animation_Object *anim_obj =
1195 _event_animation_object_get(eo_obj, event_type);
1196 if (anim_obj)
1197 {
1198 _all_animation_objects_cancel(eo_obj);
1199 efl_animation_object_start(anim_obj);
1200 }
1201 }
1202 }
1203
1049 return efl_event_callback_legacy_call(efl_super(eo_obj, MY_CLASS), 1204 return efl_event_callback_legacy_call(efl_super(eo_obj, MY_CLASS),
1050 desc, event_info); 1205 desc, event_info);
1051} 1206}
@@ -1065,6 +1220,15 @@ _efl_canvas_object_efl_object_destructor(Eo *eo_obj, Evas_Object_Protected_Data
1065 int event_id; 1220 int event_id;
1066 1221
1067 edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS); 1222 edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS);
1223
1224 //Unset event animations
1225 efl_canvas_object_event_animation_set(eo_obj, EFL_ANIMATION_EVENT_TYPE_SHOW,
1226 NULL);
1227 efl_canvas_object_event_animation_set(eo_obj, EFL_ANIMATION_EVENT_TYPE_HIDE,
1228 NULL);
1229 efl_canvas_object_event_animation_set(eo_obj,
1230 EFL_ANIMATION_EVENT_TYPE_CLICKED,
1231 NULL);
1068 evas_object_hide(eo_obj); 1232 evas_object_hide(eo_obj);
1069 1233
1070 if (obj->events) EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events) 1234 if (obj->events) EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
@@ -1689,6 +1853,39 @@ evas_object_hide(Evas_Object *eo_obj)
1689 efl_gfx_visible_set(eo_obj, EINA_FALSE); 1853 efl_gfx_visible_set(eo_obj, EINA_FALSE);
1690} 1854}
1691 1855
1856static void _animation_intercept_hide(void *data, Evas_Object *eo_obj);
1857
1858static void
1859_animation_hide_end_cb(void *data, const Efl_Event *event EINA_UNUSED)
1860{
1861 Hide_Anim_Data *hide_anim_data = data;
1862
1863 hide_anim_data->anim_ended = EINA_TRUE;
1864
1865 _animation_intercept_hide(hide_anim_data, hide_anim_data->target);
1866
1867 hide_anim_data->anim_started = EINA_FALSE;
1868 hide_anim_data->anim_ended = EINA_FALSE;
1869}
1870
1871static void
1872_animation_intercept_hide(void *data, Evas_Object *eo_obj)
1873{
1874 Hide_Anim_Data *hide_anim_data = data;
1875
1876 Efl_Animation_Object *anim_obj =
1877 _event_animation_object_get(eo_obj, EFL_ANIMATION_EVENT_TYPE_HIDE);
1878 if (anim_obj && !hide_anim_data->anim_started && !hide_anim_data->anim_ended)
1879 {
1880 hide_anim_data->anim_started = EINA_TRUE;
1881
1882 _all_animation_objects_cancel(eo_obj);
1883 efl_animation_object_start(anim_obj);
1884 }
1885 else
1886 efl_gfx_visible_set(eo_obj, EINA_FALSE);
1887}
1888
1692EAPI Eina_Bool 1889EAPI Eina_Bool
1693evas_object_visible_get(const Evas_Object *obj) 1890evas_object_visible_get(const Evas_Object *obj)
1694{ 1891{
@@ -1730,6 +1927,15 @@ _show(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
1730 } 1927 }
1731 evas_object_update_bounding_box(eo_obj, obj, NULL); 1928 evas_object_update_bounding_box(eo_obj, obj, NULL);
1732 evas_object_inform_call_show(eo_obj); 1929 evas_object_inform_call_show(eo_obj);
1930
1931 //Start animation
1932 Efl_Animation_Object *anim_obj =
1933 _event_animation_object_get(eo_obj, EFL_ANIMATION_EVENT_TYPE_SHOW);
1934 if (anim_obj)
1935 {
1936 _all_animation_objects_cancel(eo_obj);
1937 efl_animation_object_start(anim_obj);
1938 }
1733} 1939}
1734 1940
1735static void 1941static void
@@ -2524,6 +2730,133 @@ _efl_canvas_object_legacy_ctor(Eo *eo_obj, Evas_Object_Protected_Data *obj)
2524 obj->legacy.ctor = EINA_TRUE; 2730 obj->legacy.ctor = EINA_TRUE;
2525} 2731}
2526 2732
2733EOLIAN void
2734_efl_canvas_object_event_animation_set(Eo *eo_obj,
2735 Evas_Object_Protected_Data *pd,
2736 Efl_Animation_Event_Type event_type,
2737 Efl_Animation *animation)
2738{
2739 if (!_efl_animation_event_type_is_valid(event_type))
2740 return;
2741
2742 Event_Animation *event_anim =
2743 eina_array_data_get(pd->event_anims, event_type);
2744 if (!event_anim) return;
2745
2746 Efl_Animation *cur_anim = event_anim->anim;
2747 Efl_Animation_Object *cur_anim_obj = event_anim->anim_obj;
2748
2749 //Unset for current event animation
2750 if (cur_anim)
2751 {
2752 Efl_Canvas_Object *prev_target = efl_animation_target_get(cur_anim);
2753
2754 //Deallocate memory and Unset callbacks for Hide event
2755 if (event_type == EFL_ANIMATION_EVENT_TYPE_HIDE)
2756 {
2757 Hide_Anim_Data *hide_anim_data
2758 = evas_object_intercept_hide_callback_del(prev_target,
2759 _animation_intercept_hide);
2760 if (hide_anim_data)
2761 {
2762 efl_event_callback_del(cur_anim_obj,
2763 EFL_ANIMATION_OBJECT_EVENT_ENDED,
2764 _animation_hide_end_cb,
2765 hide_anim_data);
2766
2767 if (hide_anim_data->anim_started &&
2768 !hide_anim_data->anim_ended)
2769 efl_gfx_visible_set(prev_target, EINA_FALSE);
2770
2771 free(hide_anim_data);
2772 }
2773 }
2774
2775 //Stop animation
2776 efl_animation_object_cancel(cur_anim_obj);
2777
2778 /* Delete current animation object because animation object is
2779 * created in efl_canvas_object_event_animation_set(). */
2780 efl_del(cur_anim_obj);
2781 }
2782
2783 Efl_Animation *new_anim = animation;
2784 Efl_Animation_Object *new_anim_obj = NULL;
2785
2786 //Set for new event animation
2787 if (new_anim)
2788 {
2789 //Set target object for the given animation
2790 Efl_Canvas_Object *target = efl_animation_target_get(new_anim);
2791 if (!target)
2792 target = eo_obj;
2793 efl_animation_target_set(new_anim, target);
2794
2795 new_anim_obj = efl_animation_object_create(new_anim);
2796
2797 /* Event animation object should not be deleted after animation is
2798 * cancelled or finished */
2799 efl_animation_object_auto_del_set(new_anim_obj, EINA_FALSE);
2800
2801 //Allocate memory and Set callbacks for Hide event
2802 if (event_type == EFL_ANIMATION_EVENT_TYPE_HIDE)
2803 {
2804 Hide_Anim_Data *hide_anim_data = calloc(1, sizeof(Hide_Anim_Data));
2805 hide_anim_data->target = target;
2806 hide_anim_data->anim_started = EINA_FALSE;
2807 hide_anim_data->anim_ended = EINA_FALSE;
2808
2809 evas_object_intercept_hide_callback_add(target,
2810 _animation_intercept_hide,
2811 hide_anim_data);
2812
2813 efl_event_callback_add(new_anim_obj,
2814 EFL_ANIMATION_OBJECT_EVENT_ENDED,
2815 _animation_hide_end_cb,
2816 hide_anim_data);
2817 }
2818 }
2819
2820 //Replace current event animation with new event animation
2821 event_anim->anim = new_anim;
2822 event_anim->anim_obj = new_anim_obj;
2823}
2824
2825EOLIAN Efl_Animation *
2826_efl_canvas_object_event_animation_get(Eo *eo_obj EINA_UNUSED,
2827 Evas_Object_Protected_Data *pd,
2828 Efl_Animation_Event_Type event_type)
2829{
2830 if (!_efl_animation_event_type_is_valid(event_type))
2831 return NULL;
2832
2833 Event_Animation *event_anim = eina_array_data_get(pd->event_anims,
2834 event_type);
2835 if (event_anim && event_anim->anim)
2836 return event_anim->anim;
2837
2838 return NULL;
2839}
2840
2841/* This function is to show object if show is called during hide animation.
2842 * If show is called during hide animation is running, then the running hide
2843 * animation is cancelled and show operation is proceeded. */
2844Eina_Bool
2845_efl_canvas_object_event_animation_is_running(Eo *eo_obj,
2846 Efl_Animation_Event_Type event)
2847{
2848 if (_event_animation_object_get(eo_obj, event))
2849 return EINA_TRUE;
2850
2851 return EINA_FALSE;
2852}
2853
2854void
2855_efl_canvas_object_event_animation_cancel(Eo *eo_obj)
2856{
2857 _all_animation_objects_cancel(eo_obj);
2858}
2859
2527 2860
2528/* legacy */ 2861/* legacy */
2529 2862