summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2020-02-14 19:02:14 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-03-17 10:29:57 +0100
commit561906399c886ac8da22fe71d31adaf19c24b271 (patch)
tree201c96d9dc8c2adabe7c3174d2dff7b354449803
parent95a2b3457a9656c271abf93318c5e9a551d43b7b (diff)
efl_ui_spotlight: Introduce animation manager
the manager is basically not new, its just the moved fade manager, with a little bit more utilization. The manager now can be equipt with 3 animaton objects that are played when the correct reason happens. For now the fade manager is the only thing that uses that. Reviewed-by: Jaehyun Cho <jae_hyun.cho@samsung.com> Differential Revision: https://phab.enlightenment.org/D11358
-rw-r--r--src/bin/elementary/test.c3
-rw-r--r--src/bin/elementary/test_ui_spotlight.c115
-rw-r--r--src/lib/elementary/Efl_Ui.h1
-rw-r--r--src/lib/elementary/efl_ui_spotlight_animation_manager.c268
-rw-r--r--src/lib/elementary/efl_ui_spotlight_animation_manager.eo68
-rw-r--r--src/lib/elementary/efl_ui_spotlight_fade_manager.c213
-rw-r--r--src/lib/elementary/efl_ui_spotlight_fade_manager.eo10
-rw-r--r--src/lib/elementary/meson.build4
8 files changed, 470 insertions, 212 deletions
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index d52240011b..bfb505e4a3 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -398,7 +398,7 @@ void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info);
398void test_ui_spotlight_stack(void *data, Evas_Object *obj, void *event_info); 398void test_ui_spotlight_stack(void *data, Evas_Object *obj, void *event_info);
399void test_ui_spotlight_plain(void *data, Evas_Object *obj, void *event_info); 399void test_ui_spotlight_plain(void *data, Evas_Object *obj, void *event_info);
400void test_ui_spotlight_scroll(void *data, Evas_Object *obj, void *event_info); 400void test_ui_spotlight_scroll(void *data, Evas_Object *obj, void *event_info);
401 401void test_ui_spotlight_animation(void *data, Evas_Object *obj, void *event_info);
402void test_ui_relative_container(void *data, Evas_Object *obj, void *event_info); 402void test_ui_relative_container(void *data, Evas_Object *obj, void *event_info);
403void test_efl_ui_radio(void *data, Evas_Object *obj, void *event_info); 403void test_efl_ui_radio(void *data, Evas_Object *obj, void *event_info);
404void test_efl_ui_collection_list(void *data, Evas_Object *obj, void *event_info); 404void test_efl_ui_collection_list(void *data, Evas_Object *obj, void *event_info);
@@ -1173,6 +1173,7 @@ add_tests:
1173 ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Plain", test_ui_spotlight_plain); 1173 ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Plain", test_ui_spotlight_plain);
1174 ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Scroll", test_ui_spotlight_scroll); 1174 ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Scroll", test_ui_spotlight_scroll);
1175 ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Stack", test_ui_spotlight_stack); 1175 ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Stack", test_ui_spotlight_stack);
1176 ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Custom animation", test_ui_spotlight_animation);
1176 ADD_TEST_EO(NULL, "Spotlight", "Navigation stack", test_ui_stack); 1177 ADD_TEST_EO(NULL, "Spotlight", "Navigation stack", test_ui_stack);
1177 //------------------------------// 1178 //------------------------------//
1178 ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup); 1179 ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup);
diff --git a/src/bin/elementary/test_ui_spotlight.c b/src/bin/elementary/test_ui_spotlight.c
index 1d0837d9db..a5c8d141e3 100644
--- a/src/bin/elementary/test_ui_spotlight.c
+++ b/src/bin/elementary/test_ui_spotlight.c
@@ -1129,3 +1129,118 @@ test_ui_spotlight_scroll(void *data EINA_UNUSED,
1129 efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320)); 1129 efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
1130} 1130}
1131 1131
1132
1133void
1134test_ui_spotlight_animation(void *data EINA_UNUSED,
1135 Evas_Object *obj EINA_UNUSED,
1136 void *event_info EINA_UNUSED)
1137{
1138 Eo *win, *panes, *navi, *list, *layout, *spotlight, *view, *custom_animation_manager;
1139 Efl_Canvas_Animation *jump_animation, *push_animation, *pop_animation;
1140 Params *params = NULL;
1141 char buf[PATH_MAX];
1142 int i;
1143
1144 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
1145 efl_text_set(efl_added, "Efl.Ui.Spotlight Scroll"),
1146 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
1147
1148 panes = efl_add(EFL_UI_PANES_CLASS, win,
1149 efl_gfx_hint_weight_set(efl_added, 1, 1),
1150 efl_ui_panes_split_ratio_set(efl_added, 0.3),
1151 efl_content_set(win, efl_added));
1152
1153 navi = elm_naviframe_add(panes);
1154 evas_object_show(navi);
1155 efl_content_set(efl_part(panes, "first"), navi);
1156
1157 list = elm_list_add(navi);
1158 elm_list_horizontal_set(list, EINA_FALSE);
1159 elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
1160 elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
1161 evas_object_show(list);
1162
1163 snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
1164 elm_app_data_dir_get());
1165 layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
1166 efl_file_set(efl_added, buf),
1167 efl_file_key_set(efl_added, "pager"),
1168 efl_file_load(efl_added),
1169 efl_content_set(efl_part(panes, "second"), efl_added));
1170
1171
1172 jump_animation = efl_new(EFL_CANVAS_ALPHA_ANIMATION_CLASS);
1173 efl_animation_alpha_set(jump_animation, 0.0, 1.0);
1174 efl_animation_duration_set(jump_animation, 0.5);
1175
1176 push_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
1177 efl_animation_translate_set(push_animation, EINA_POSITION2D(0, 100), EINA_POSITION2D(0, 0));
1178 efl_animation_duration_set(push_animation, 0.5);
1179
1180 pop_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
1181 efl_animation_translate_set(pop_animation, EINA_POSITION2D(0, -100), EINA_POSITION2D(0, 0));
1182 efl_animation_duration_set(pop_animation, 0.5);
1183
1184 custom_animation_manager = efl_new(EFL_UI_SPOTLIGHT_ANIMATION_MANAGER_CLASS,
1185 efl_ui_spotlight_manager_animation_push_setup_set(efl_added, push_animation, jump_animation),
1186 efl_ui_spotlight_manager_animation_pop_setup_set(efl_added, jump_animation, pop_animation),
1187 efl_ui_spotlight_manager_animation_jump_setup_set(efl_added, jump_animation, jump_animation));
1188
1189 spotlight = efl_add(EFL_UI_SPOTLIGHT_CONTAINER_CLASS, layout,
1190 efl_ui_spotlight_manager_set(efl_added, custom_animation_manager),
1191 efl_content_set(efl_part(layout, "pager"), efl_added),
1192 efl_ui_spotlight_size_set(efl_added, EINA_SIZE2D(200, 300)));
1193
1194 efl_add(EFL_UI_BUTTON_CLASS, layout,
1195 efl_text_set(efl_added, "Pop"),
1196 efl_event_callback_add(efl_added,
1197 EFL_INPUT_EVENT_CLICKED, pop_btn_cb, spotlight),
1198 efl_content_set(efl_part(layout, "prev_btn"), efl_added));
1199
1200 efl_add(EFL_UI_BUTTON_CLASS, layout,
1201 efl_text_set(efl_added, "Push"),
1202 efl_event_callback_add(efl_added,
1203 EFL_INPUT_EVENT_CLICKED, push_btn_cb, spotlight),
1204 efl_content_set(efl_part(layout, "next_btn"), efl_added));
1205
1206 params = calloc(1, sizeof(Params));
1207 if (!params) return;
1208
1209 params->navi = navi;
1210 params->spotlight = spotlight;
1211 params->indicator = NULL;
1212 params->w = 200;
1213 params->h = 300;
1214 params->wfill = EINA_FALSE;
1215 params->hfill = EINA_FALSE;
1216
1217 elm_list_item_append(list, "View Size", NULL, NULL, spotlight_size, params);
1218 elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
1219 elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
1220 elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
1221 elm_list_item_append(list, "Animation", NULL, NULL, view_animation_cb, params);
1222 elm_list_item_append(list, "Scroll Block", NULL, NULL, scroll_block_cb, params);
1223 elm_list_go(list);
1224
1225 efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
1226
1227 for (i = 0; i < PAGE_NUM; i++) {
1228 switch (i % 3)
1229 {
1230 case 0:
1231 view = view_add(LAYOUT, spotlight);
1232 break;
1233
1234 case 1:
1235 view = view_add(LIST, spotlight);
1236 break;
1237
1238 case 2:
1239 view = view_add(BUTTON, spotlight);
1240 break;
1241 }
1242 efl_pack_end(spotlight, view);
1243 }
1244
1245 efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
1246}
diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h
index 81f4522c71..ffc5fd43c5 100644
--- a/src/lib/elementary/Efl_Ui.h
+++ b/src/lib/elementary/Efl_Ui.h
@@ -266,6 +266,7 @@ typedef Eo Efl_Ui_Spotlight_Indicator;
266# include <efl_ui_spotlight_icon_indicator.eo.h> 266# include <efl_ui_spotlight_icon_indicator.eo.h>
267# include <efl_ui_spotlight_scroll_manager.eo.h> 267# include <efl_ui_spotlight_scroll_manager.eo.h>
268# include <efl_ui_spotlight_fade_manager.eo.h> 268# include <efl_ui_spotlight_fade_manager.eo.h>
269# include <efl_ui_spotlight_animation_manager.eo.h>
269# include <efl_ui_spotlight_util.eo.h> 270# include <efl_ui_spotlight_util.eo.h>
270# include <efl_ui_stack.eo.h> 271# include <efl_ui_stack.eo.h>
271# include <efl_ui_pager.eo.h> 272# include <efl_ui_pager.eo.h>
diff --git a/src/lib/elementary/efl_ui_spotlight_animation_manager.c b/src/lib/elementary/efl_ui_spotlight_animation_manager.c
new file mode 100644
index 0000000000..cdf9846684
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spotlight_animation_manager.c
@@ -0,0 +1,268 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Efl_Ui.h>
6#include "elm_priv.h"
7
8
9typedef struct {
10 Efl_Ui_Spotlight_Container * container;
11 Efl_Canvas_Animation *jump_anim[2], *push_anim[2], *pop_anim[2];
12 Efl_Gfx_Entity *content[2];
13 Efl_Gfx_Entity *clipper;
14 int ids[2]; //only used when in animation
15 Eina_Size2D page_size;
16 Eina_Bool animation;
17} Efl_Ui_Spotlight_Animation_Manager_Data;
18
19#define MY_CLASS EFL_UI_SPOTLIGHT_ANIMATION_MANAGER_CLASS
20
21static void
22_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
23{
24 Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->container);
25 Eina_Rect goal = EINA_RECT_EMPTY();
26 goal.size = pd->page_size;
27 goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
28 goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
29 efl_gfx_entity_geometry_set(pd->clipper, group_pos);
30 for (int i = 0; i < 2; ++i)
31 {
32 if (pd->content[i])
33 efl_gfx_entity_geometry_set(pd->content[i], goal);
34 }
35}
36
37static void
38_running_cb(void *data, const Efl_Event *ev EINA_UNUSED)
39{
40 Efl_Ui_Spotlight_Animation_Manager_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
41 double absolut_position;
42
43 EINA_SAFETY_ON_NULL_RETURN(pd);
44 //calculate absolut position, multiply pos with 2.0 because duration is only 0.5)
45 absolut_position = pd->ids[0] + (pd->ids[1] - pd->ids[0])*(efl_canvas_object_animation_progress_get(ev->object));
46 efl_event_callback_call(data, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &absolut_position);
47}
48
49static void
50_hide_object_cb(void *data, const Efl_Event *ev)
51{
52 if (!ev->info)
53 {
54 efl_gfx_entity_visible_set(ev->object, EINA_FALSE);
55 efl_event_callback_del(ev->object, ev->desc, _hide_object_cb, data);
56 efl_event_callback_del(ev->object, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, data);
57 }
58}
59
60EOLIAN static void
61_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_bind(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Ui_Spotlight_Container *spotlight)
62{
63 if (spotlight)
64 {
65 pd->container = spotlight;
66
67 pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
68 evas_object_evas_get(pd->container));
69 evas_object_static_clip_set(pd->clipper, EINA_TRUE);
70 efl_canvas_group_member_add(spotlight, pd->clipper);
71
72 for (int i = 0; i < efl_content_count(spotlight) ; ++i) {
73 Efl_Gfx_Entity *elem = efl_pack_content_get(spotlight, i);
74 efl_key_data_set(elem, "_elm_leaveme", spotlight);
75 efl_canvas_object_clipper_set(elem, pd->clipper);
76 efl_canvas_group_member_add(pd->container, elem);
77 efl_gfx_entity_visible_set(elem, EINA_FALSE);
78 }
79 if (efl_ui_spotlight_active_element_get(spotlight))
80 {
81 pd->content[0] = efl_ui_spotlight_active_element_get(spotlight);
82 efl_gfx_entity_visible_set(pd->content[0], EINA_TRUE);
83 _geom_sync(obj, pd);
84 }
85 }
86}
87
88static void
89_update_ids(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd, int avoid_index)
90{
91 for (int i = 0; i < 2; ++i)
92 {
93 if (pd->ids[i] != -1 && pd->ids[i] != avoid_index)
94 pd->ids[i] = efl_pack_index_get(pd->container, pd->content[i]);
95 }
96 double pos = pd->ids[1];
97 efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
98}
99
100EOLIAN static void
101_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_content_add(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
102{
103 efl_key_data_set(subobj, "_elm_leaveme", pd->container);
104 efl_canvas_object_clipper_set(subobj, pd->clipper);
105 efl_canvas_group_member_add(pd->container, subobj);
106 efl_gfx_entity_visible_set(subobj, EINA_FALSE);
107 _update_ids(obj, pd, -1);
108}
109
110EOLIAN static void
111_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_content_del(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index)
112{
113 efl_key_data_set(subobj, "_elm_leaveme", NULL);
114 efl_canvas_object_clipper_set(subobj, NULL);
115 efl_canvas_group_member_remove(pd->container, subobj);
116 for (int i = 0; i < 2; ++i)
117 {
118 if (pd->content[i] == subobj)
119 pd->content[i] = NULL;
120 }
121 _update_ids(obj, pd, index);
122}
123
124static Eina_Bool
125is_valid(Eo *obj, int index)
126{
127 if (index < 0) return EINA_FALSE;
128 if (index >= efl_content_count(obj)) return EINA_FALSE;
129
130 return EINA_TRUE;
131}
132
133EOLIAN static void
134_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd,
135 int from, int to,
136 Efl_Ui_Spotlight_Manager_Switch_Reason reason EINA_UNUSED)
137{
138
139 if (efl_pack_content_get(pd->container, to) == pd->content[1])
140 return;
141
142
143 if (is_valid(pd->container, to) && is_valid(pd->container, from))
144 {
145 int tmp[2] = {from, to};
146
147 for (int i = 0; i < 2; ++i)
148 {
149 Efl_Canvas_Animation *animation = NULL;
150 pd->ids[i] = tmp[i];
151 pd->content[i] = efl_pack_content_get(pd->container, pd->ids[i]);
152 //when pushing, animate the *pushed in* content with the push animation
153 if (reason == EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_PUSH)
154 animation = pd->push_anim[i];
155 //when popping, animate the *popped in* content with the pop animation
156 else if (reason == EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_POP)
157 animation = pd->pop_anim[i];
158 if (!animation)
159 animation = pd->jump_anim[i];
160 if (pd->animation)
161 efl_canvas_object_animation_start(pd->content[i], animation, -1.0+2.0*i, 0.0);
162 efl_gfx_entity_visible_set(pd->content[i], EINA_TRUE);
163 }
164 if (pd->animation)
165 {
166 efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, _hide_object_cb, obj);
167 efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, obj);
168 efl_gfx_stack_above(pd->content[1], pd->content[0]); //Stack the "to content" above the "from content"
169 }
170 }
171 else
172 {
173 double pos = to;
174
175 pd->ids[0] = -1;
176 pd->content[0] = NULL;
177 pd->ids[1] = to;
178 pd->content[1] = efl_pack_content_get(pd->container, to);
179 efl_gfx_entity_visible_set(pd->content[1], EINA_TRUE);
180 efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
181 }
182
183 _geom_sync(obj, pd);
184}
185
186EOLIAN static void
187_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_size_set(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Eina_Size2D size)
188{
189 pd->page_size = size;
190 _geom_sync(obj, pd);
191}
192
193EOLIAN static void
194_efl_ui_spotlight_animation_manager_efl_object_invalidate(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
195{
196 efl_invalidate(efl_super(obj, MY_CLASS));
197
198 efl_del(pd->clipper);
199
200 for (int i = 0; i < efl_content_count(pd->container); ++i)
201 {
202 Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
203 for (int d = 0; d < 4; d++)
204 {
205 efl_gfx_mapping_color_set(elem, d, 255, 255, 255, 255);
206 }
207
208 efl_canvas_object_clipper_set(elem, NULL);
209 }
210}
211
212EOLIAN static void
213_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_animated_transition_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Eina_Bool animation)
214{
215 for (int i = 0; i < 2; ++i)
216 {
217 if (pd->content[i])
218 efl_canvas_object_animation_stop(pd->content[i]);
219 }
220 pd->animation = animation;
221}
222
223EOLIAN static Eina_Bool
224_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_animated_transition_get(const Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
225{
226 return pd->animation;
227}
228
229EOLIAN static void
230_efl_ui_spotlight_animation_manager_push_setup_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Canvas_Animation *in, Efl_Canvas_Animation *out)
231{
232 EINA_SAFETY_ON_NULL_RETURN(out);
233 EINA_SAFETY_ON_NULL_RETURN(in);
234
235 efl_replace(&pd->push_anim[0], out);
236 efl_replace(&pd->push_anim[1], in);
237}
238
239EOLIAN static void
240_efl_ui_spotlight_animation_manager_pop_setup_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Canvas_Animation *in, Efl_Canvas_Animation *out)
241{
242 EINA_SAFETY_ON_NULL_RETURN(out);
243 EINA_SAFETY_ON_NULL_RETURN(in);
244
245 efl_replace(&pd->pop_anim[0], out);
246 efl_replace(&pd->pop_anim[1], in);
247}
248
249EOLIAN static void
250_efl_ui_spotlight_animation_manager_jump_setup_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Canvas_Animation *in, Efl_Canvas_Animation *out)
251{
252 EINA_SAFETY_ON_NULL_RETURN(out);
253 EINA_SAFETY_ON_NULL_RETURN(in);
254
255 efl_replace(&pd->jump_anim[0], out);
256 efl_replace(&pd->jump_anim[1], in);
257}
258
259EOLIAN static Efl_Object*
260_efl_ui_spotlight_animation_manager_efl_object_finalize(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
261{
262 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->jump_anim[0], NULL);
263 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->jump_anim[1], NULL);
264
265 return efl_finalize(efl_super(obj, MY_CLASS));
266}
267
268#include "efl_ui_spotlight_animation_manager.eo.c"
diff --git a/src/lib/elementary/efl_ui_spotlight_animation_manager.eo b/src/lib/elementary/efl_ui_spotlight_animation_manager.eo
new file mode 100644
index 0000000000..c82d9666a0
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spotlight_animation_manager.eo
@@ -0,0 +1,68 @@
1class @beta Efl.Ui.Spotlight.Animation_Manager extends Efl.Ui.Spotlight.Manager
2{
3 [[A spotlight manager that uses animation objects to react to different @Efl.Ui.Spotlight.Manager.switch_to situations.
4
5 Animations are played forward when they are on the $to argument, they are played backward when they are on the $from argument.
6
7 Pop animations are always played backwards, Push animations are always played forward.
8 Reason for this is, the reusability. You should be able to pass in 1 animation to all sitatuations, which should cover the turn arround effect that "moving in" and "moving out" has. This means, when you have a alpha channel animation, the pop animation can be the same as the jump-in and out animation, and both will look like fading out.
9
10
11 ]]
12 c_prefix: efl_ui_spotlight_manager_animation;
13 methods {
14 @property push_setup{
15 [[Animation that is used to animate the $to argument of a switch_to request when the passed $reason is push.
16
17
18 If these animations are $null, then the $in and $out animation of @.jump_setup will be taken instead.
19 ]]
20 values {
21 in : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
22 out : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference. Can be the same as $in.]]
23 }
24 set { }
25 }
26 @property pop_setup{
27 [[Animation that is used to animate the $from argument of a switch_to request when the passed $reason is pop.
28
29 Note: this animations is always played backwards, see the class documentation for the reasoning.
30
31 If these animations are $null, then the $in and $out animation of @.jump_setup will be taken instead.
32 ]]
33 values {
34 in : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
35 out : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference. Can be the same as $in.]]
36 }
37 set { }
38 }
39 @property jump_setup{
40 [[Set the animation objects you want to play on a jump in or jump out.
41
42 When a switch to request is issued, two arguments are getting animated. The $from object, and the $to objects. The $from object will be playing the out animation. The $pop object will be playing the in animation.
43
44 The out animation will always be played backwards, this is to support passing the same animation object to both parameters. (A fade animation will fade in the new object, and fade out the old object).
45 ]]
46 values {
47 in : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
48 out : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference. Can be the same as $in.]]
49 }
50 set {
51
52 }
53 }
54 }
55 constructors {
56 .jump_setup;
57 }
58 implements {
59 Efl.Ui.Spotlight.Manager.bind;
60 Efl.Ui.Spotlight.Manager.content_add;
61 Efl.Ui.Spotlight.Manager.content_del;
62 Efl.Ui.Spotlight.Manager.switch_to;
63 Efl.Ui.Spotlight.Manager.size {set;}
64 Efl.Ui.Spotlight.Manager.animated_transition {set; get;}
65 Efl.Object.finalize;
66 Efl.Object.invalidate;
67 }
68}
diff --git a/src/lib/elementary/efl_ui_spotlight_fade_manager.c b/src/lib/elementary/efl_ui_spotlight_fade_manager.c
index 441bb38896..cb2fa5f0a4 100644
--- a/src/lib/elementary/efl_ui_spotlight_fade_manager.c
+++ b/src/lib/elementary/efl_ui_spotlight_fade_manager.c
@@ -5,216 +5,25 @@
5#include <Efl_Ui.h> 5#include <Efl_Ui.h>
6#include "elm_priv.h" 6#include "elm_priv.h"
7 7
8
9typedef struct { 8typedef struct {
10 Efl_Ui_Spotlight_Container * container;
11 Efl_Canvas_Animation *alpha_anim;
12 Efl_Gfx_Entity *content[2];
13 Efl_Gfx_Entity *clipper;
14 int ids[2]; //only used when in animation
15 Eina_Size2D page_size;
16 Eina_Bool animation;
17} Efl_Ui_Spotlight_Fade_Manager_Data;
18
19#define MY_CLASS EFL_UI_SPOTLIGHT_FADE_MANAGER_CLASS
20
21static void
22_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd)
23{
24 Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->container);
25 Eina_Rect goal = EINA_RECT_EMPTY();
26 goal.size = pd->page_size;
27 goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
28 goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
29 efl_gfx_entity_geometry_set(pd->clipper, goal);
30 for (int i = 0; i < 2; ++i)
31 {
32 if (pd->content[i])
33 efl_gfx_entity_geometry_set(pd->content[i], goal);
34 }
35}
36
37static void
38_running_cb(void *data, const Efl_Event *ev EINA_UNUSED)
39{
40 Efl_Ui_Spotlight_Fade_Manager_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
41 double absolut_position;
42
43 EINA_SAFETY_ON_NULL_RETURN(pd);
44 //calculate absolut position, multiply pos with 2.0 because duration is only 0.5)
45 absolut_position = pd->ids[0] + (pd->ids[1] - pd->ids[0])*(efl_canvas_object_animation_progress_get(ev->object));
46 efl_event_callback_call(data, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &absolut_position);
47}
48
49static void
50_hide_object_cb(void *data, const Efl_Event *ev)
51{
52 if (!ev->info)
53 {
54 efl_gfx_entity_visible_set(ev->object, EINA_FALSE);
55 efl_event_callback_del(ev->object, ev->desc, _hide_object_cb, data);
56 efl_event_callback_del(ev->object, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, data);
57 }
58}
59
60EOLIAN static void
61_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_bind(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Efl_Ui_Spotlight_Container *spotlight)
62{
63 if (spotlight)
64 {
65 pd->container = spotlight;
66
67 pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
68 evas_object_evas_get(pd->container));
69 evas_object_static_clip_set(pd->clipper, EINA_TRUE);
70 efl_canvas_group_member_add(spotlight, pd->clipper);
71
72 pd->alpha_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, obj);
73 efl_animation_alpha_set(pd->alpha_anim, 0.0, 1.0);
74 efl_animation_duration_set(pd->alpha_anim, 0.5);
75
76 for (int i = 0; i < efl_content_count(spotlight) ; ++i) {
77 Efl_Gfx_Entity *elem = efl_pack_content_get(spotlight, i);
78 efl_key_data_set(elem, "_elm_leaveme", spotlight);
79 efl_canvas_object_clipper_set(elem, pd->clipper);
80 efl_canvas_group_member_add(pd->container, elem);
81 efl_gfx_entity_visible_set(elem, EINA_FALSE);
82 }
83 if (efl_ui_spotlight_active_element_get(spotlight))
84 {
85 pd->content[0] = efl_ui_spotlight_active_element_get(spotlight);
86 efl_gfx_entity_visible_set(pd->content[0], EINA_TRUE);
87 _geom_sync(obj, pd);
88 }
89 }
90}
91
92static void
93_update_ids(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, int avoid_index)
94{
95 for (int i = 0; i < 2; ++i)
96 {
97 if (pd->ids[i] != -1 && pd->ids[i] != avoid_index)
98 pd->ids[i] = efl_pack_index_get(pd->container, pd->content[i]);
99 }
100 double pos = pd->ids[1];
101 efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
102}
103 9
104EOLIAN static void 10} Efl_Ui_Spotlight_Fade_Manager_Data;
105_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_content_add(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
106{
107 efl_key_data_set(subobj, "_elm_leaveme", pd->container);
108 efl_canvas_object_clipper_set(subobj, pd->clipper);
109 efl_canvas_group_member_add(pd->container, subobj);
110 efl_gfx_entity_visible_set(subobj, EINA_FALSE);
111 _update_ids(obj, pd, -1);
112}
113
114EOLIAN static void
115_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_content_del(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index)
116{
117 efl_key_data_set(subobj, "_elm_leaveme", NULL);
118 efl_canvas_object_clipper_set(subobj, NULL);
119 efl_canvas_group_member_remove(pd->container, subobj);
120 for (int i = 0; i < 2; ++i)
121 {
122 if (pd->content[i] == subobj)
123 pd->content[i] = NULL;
124 }
125 _update_ids(obj, pd, index);
126}
127
128static Eina_Bool
129is_valid(Eo *obj, int index)
130{
131 if (index < 0) return EINA_FALSE;
132 if (index >= efl_content_count(obj)) return EINA_FALSE;
133
134 return EINA_TRUE;
135}
136
137EOLIAN static void
138_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, int from, int to, Efl_Ui_Spotlight_Manager_Switch_Reason reason EINA_UNUSED)
139{
140 if (efl_pack_content_get(pd->container, to) == pd->content[1])
141 return;
142
143 if (is_valid(pd->container, to) && is_valid(pd->container, from))
144 {
145 int tmp[2] = {from, to};
146
147 for (int i = 0; i < 2; ++i)
148 {
149 pd->ids[i] = tmp[i];
150 pd->content[i] = efl_pack_content_get(pd->container, pd->ids[i]);
151 if (pd->animation)
152 efl_canvas_object_animation_start(pd->content[i], pd->alpha_anim, -1.0+2.0*i, 0.0);
153 efl_gfx_entity_visible_set(pd->content[i], EINA_TRUE);
154 }
155 if (pd->animation)
156 {
157 efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, _hide_object_cb, obj);
158 efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, obj);
159 efl_gfx_stack_above(pd->content[1], pd->content[0]); //Stack the "to content" above the "from content"
160 }
161 }
162 else
163 {
164 double pos = to;
165
166 pd->ids[0] = -1;
167 pd->content[0] = NULL;
168 pd->ids[1] = to;
169 pd->content[1] = efl_pack_content_get(pd->container, to);
170 efl_gfx_entity_visible_set(pd->content[1], EINA_TRUE);
171 efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
172 }
173
174 _geom_sync(obj, pd);
175}
176 11
177EOLIAN static void 12EOLIAN static Efl_Object*
178_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_size_set(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Eina_Size2D size) 13_efl_ui_spotlight_fade_manager_efl_object_constructor(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd EINA_UNUSED)
179{ 14{
180 pd->page_size = size; 15 Efl_Canvas_Animation *animation;
181 _geom_sync(obj, pd);
182}
183 16
184EOLIAN static void 17 obj = efl_constructor(efl_super(obj, EFL_UI_SPOTLIGHT_FADE_MANAGER_CLASS));
185_efl_ui_spotlight_fade_manager_efl_object_invalidate(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd)
186{
187 efl_invalidate(efl_super(obj, MY_CLASS));
188 18
189 efl_del(pd->clipper); 19 animation = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, obj);
20 efl_animation_alpha_set(animation, 0.0, 1.0);
21 efl_animation_duration_set(animation, 0.5);
190 22
191 for (int i = 0; i < efl_content_count(pd->container); ++i) 23 efl_ui_spotlight_manager_animation_jump_setup_set(obj, animation, animation);
192 { 24 efl_unref(animation);
193 Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
194 for (int d = 0; d < 4; d++)
195 {
196 efl_gfx_mapping_color_set(elem, d, 255, 255, 255, 255);
197 }
198 25
199 efl_canvas_object_clipper_set(elem, NULL); 26 return obj;
200 }
201}
202
203EOLIAN static void
204_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_animated_transition_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Eina_Bool animation)
205{
206 for (int i = 0; i < 2; ++i)
207 {
208 if (pd->content[i])
209 efl_canvas_object_animation_stop(pd->content[i]);
210 }
211 pd->animation = animation;
212}
213
214EOLIAN static Eina_Bool
215_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_animated_transition_get(const Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd)
216{
217 return pd->animation;
218} 27}
219 28
220 29
diff --git a/src/lib/elementary/efl_ui_spotlight_fade_manager.eo b/src/lib/elementary/efl_ui_spotlight_fade_manager.eo
index 2447d92471..6d0524fe0e 100644
--- a/src/lib/elementary/efl_ui_spotlight_fade_manager.eo
+++ b/src/lib/elementary/efl_ui_spotlight_fade_manager.eo
@@ -1,13 +1,7 @@
1class @beta Efl.Ui.Spotlight.Fade_Manager extends Efl.Ui.Spotlight.Manager 1class @beta Efl.Ui.Spotlight.Fade_Manager extends Efl.Ui.Spotlight.Animation_Manager
2{ 2{
3 c_prefix: efl_ui_spotlight_manager_fade; 3 c_prefix: efl_ui_spotlight_manager_fade;
4 implements { 4 implements {
5 Efl.Ui.Spotlight.Manager.bind; 5 Efl.Object.constructor;
6 Efl.Ui.Spotlight.Manager.content_add;
7 Efl.Ui.Spotlight.Manager.content_del;
8 Efl.Ui.Spotlight.Manager.switch_to;
9 Efl.Ui.Spotlight.Manager.size {set;}
10 Efl.Ui.Spotlight.Manager.animated_transition {set; get;}
11 Efl.Object.invalidate;
12 } 6 }
13} 7}
diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build
index 6dea02ed9f..ebaeac7d48 100644
--- a/src/lib/elementary/meson.build
+++ b/src/lib/elementary/meson.build
@@ -188,7 +188,8 @@ pub_eo_files = [
188 'efl_ui_grid_view.eo', 188 'efl_ui_grid_view.eo',
189 'efl_ui_pager.eo', 189 'efl_ui_pager.eo',
190 'efl_ui_stack.eo', 190 'efl_ui_stack.eo',
191 'efl_ui_separator.eo' 191 'efl_ui_separator.eo',
192 'efl_ui_spotlight_animation_manager.eo',
192] 193]
193 194
194foreach eo_file : pub_eo_files 195foreach eo_file : pub_eo_files
@@ -945,6 +946,7 @@ elementary_src = [
945 'efl_ui_pager.c', 946 'efl_ui_pager.c',
946 'efl_ui_stack.c', 947 'efl_ui_stack.c',
947 'efl_ui_separator.c', 948 'efl_ui_separator.c',
949 'efl_ui_spotlight_animation_manager.c',
948] 950]
949 951
950elementary_deps = [emile, eo, efl, edje, ethumb, ethumb_client, emotion, ecore_imf, ecore_con, eldbus, efreet, efreet_mime, efreet_trash, eio, atspi, dl, intl] 952elementary_deps = [emile, eo, efl, edje, ethumb, ethumb_client, emotion, ecore_imf, ecore_con, eldbus, efreet, efreet_mime, efreet_trash, eio, atspi, dl, intl]