summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-04-28 12:28:55 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-05-30 11:48:16 +0200
commit79fe0121eec5772fca8771d19d3265ad6a7d3117 (patch)
tree02837b3f2ff81798912ce262101937dd50d0fc4d
parentcdfcd02886857d980fe12525b4e4b5a72f8f37ba (diff)
efl_ui_active_view: introduce a experimental new widget
this widget tries to replace efl.ui.stack efl.ui.flip & efl.ui.pager In general those widgets do the same thing, they get content. And display them with some sort of animations. The new idea here is, that the basic widget active_view only handles the ownership etc. of the content that gets added to this. Then there is a view_manager object. The view_manager object gets notified over the new contents, and requests for displaying particular contents. The transition then handles those things. The version here is feature complete with Efl.Ui.Stack and Efl.Ui.Pager. Additional features can be implemented in the corresponsing transition classes. Examples and tests will follow Reviewed-by: Jaehyun Cho <jae_hyun.cho@samsung.com> Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Differential Revision: https://phab.enlightenment.org/D8784
-rw-r--r--src/Makefile_Elementary.am16
-rw-r--r--src/bin/elementary/meson.build1
-rw-r--r--src/bin/elementary/test.c7
-rw-r--r--src/bin/elementary/test_ui_active_view.c1070
-rw-r--r--src/examples/elementary/efl_ui_slideshow_example.c118
-rw-r--r--src/examples/elementary/meson.build3
-rw-r--r--src/lib/elementary/Efl_Ui.h12
-rw-r--r--src/lib/elementary/efl_ui_active_view_container.c647
-rw-r--r--src/lib/elementary/efl_ui_active_view_container.eo79
-rw-r--r--src/lib/elementary/efl_ui_active_view_indicator.c15
-rw-r--r--src/lib/elementary/efl_ui_active_view_indicator.eo49
-rw-r--r--src/lib/elementary/efl_ui_active_view_indicator_icon.c114
-rw-r--r--src/lib/elementary/efl_ui_active_view_indicator_icon.eo8
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager.c15
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager.eo65
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager_plain.c166
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager_plain.eo12
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager_scroll.c316
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager_scroll.eo12
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager_stack.c265
-rw-r--r--src/lib/elementary/efl_ui_active_view_view_manager_stack.eo12
-rw-r--r--src/lib/elementary/meson.build14
-rw-r--r--src/tests/elementary/efl_ui_suite.c4
-rw-r--r--src/tests/elementary/efl_ui_suite.h4
-rw-r--r--src/tests/elementary/efl_ui_test_active_view.c571
-rw-r--r--src/tests/elementary/efl_ui_test_widget.c2
-rw-r--r--src/tests/elementary/meson.build1
-rw-r--r--src/tests/elementary/spec/efl_test_pack_linear.c2
28 files changed, 3596 insertions, 4 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 972edc7274..06209a7bc5 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -119,6 +119,13 @@ elm_public_eolian_files = \
119 lib/elementary/efl_ui_dnd_container.eo \ 119 lib/elementary/efl_ui_dnd_container.eo \
120 lib/elementary/efl_ui_focus_manager_window_root.eo \ 120 lib/elementary/efl_ui_focus_manager_window_root.eo \
121 lib/elementary/efl_ui_pager.eo \ 121 lib/elementary/efl_ui_pager.eo \
122 lib/elementary/efl_ui_active_view_container.eo \
123 lib/elementary/efl_ui_active_view_view_manager.eo \
124 lib/elementary/efl_ui_active_view_view_manager_plain.eo \
125 lib/elementary/efl_ui_active_view_view_manager_scroll.eo \
126 lib/elementary/efl_ui_active_view_view_manager_stack.eo \
127 lib/elementary/efl_ui_active_view_indicator.eo \
128 lib/elementary/efl_ui_active_view_indicator_icon.eo \
122 lib/elementary/efl_page_transition.eo \ 129 lib/elementary/efl_page_transition.eo \
123 lib/elementary/efl_page_transition_scroll.eo \ 130 lib/elementary/efl_page_transition_scroll.eo \
124 lib/elementary/efl_page_indicator.eo \ 131 lib/elementary/efl_page_indicator.eo \
@@ -1197,6 +1204,13 @@ lib_elementary_libelementary_la_SOURCES = \
1197 static_libs/buildsystem/buildsystem.h \ 1204 static_libs/buildsystem/buildsystem.h \
1198 static_libs/buildsystem/buildsystem_autotools.c \ 1205 static_libs/buildsystem/buildsystem_autotools.c \
1199 lib/elementary/efl_ui_pager.c \ 1206 lib/elementary/efl_ui_pager.c \
1207 lib/elementary/efl_ui_active_view_container.c \
1208 lib/elementary/efl_ui_active_view_view_manager.c \
1209 lib/elementary/efl_ui_active_view_view_manager_plain.c \
1210 lib/elementary/efl_ui_active_view_view_manager_scroll.c \
1211 lib/elementary/efl_ui_active_view_view_manager_stack.c \
1212 lib/elementary/efl_ui_active_view_indicator.c \
1213 lib/elementary/efl_ui_active_view_indicator_icon.c \
1200 lib/elementary/efl_page_transition.c \ 1214 lib/elementary/efl_page_transition.c \
1201 lib/elementary/efl_page_transition_scroll.c \ 1215 lib/elementary/efl_page_transition_scroll.c \
1202 lib/elementary/efl_page_indicator.c \ 1216 lib/elementary/efl_page_indicator.c \
@@ -1435,6 +1449,7 @@ bin/elementary/test_gesture_framework.c \
1435bin/elementary/test_ui_tab_pager.c \ 1449bin/elementary/test_ui_tab_pager.c \
1436bin/elementary/test_ui_pager.c \ 1450bin/elementary/test_ui_pager.c \
1437bin/elementary/test_ui_pager_scroll.c \ 1451bin/elementary/test_ui_pager_scroll.c \
1452bin/elementary/test_ui_active_view.c \
1438bin/elementary/test_ui_relative_layout.c \ 1453bin/elementary/test_ui_relative_layout.c \
1439bin/elementary/test.h 1454bin/elementary/test.h
1440 1455
@@ -1963,6 +1978,7 @@ tests_elementary_efl_ui_suite_SOURCES = \
1963 tests/elementary/efl_ui_test_image_zoomable.c \ 1978 tests/elementary/efl_ui_test_image_zoomable.c \
1964 tests/elementary/efl_ui_test_layout.c \ 1979 tests/elementary/efl_ui_test_layout.c \
1965 tests/elementary/efl_ui_test_widget.c \ 1980 tests/elementary/efl_ui_test_widget.c \
1981 tests/elementary/efl_ui_test_active_view.c \
1966 tests/elementary/efl_ui_suite.h \ 1982 tests/elementary/efl_ui_suite.h \
1967 tests/elementary/efl_ui_model.c 1983 tests/elementary/efl_ui_model.c
1968 1984
diff --git a/src/bin/elementary/meson.build b/src/bin/elementary/meson.build
index cfc5071ea2..29e98f9ff5 100644
--- a/src/bin/elementary/meson.build
+++ b/src/bin/elementary/meson.build
@@ -101,6 +101,7 @@ elementary_test_src = [
101 'test_ui_panel.c', 101 'test_ui_panel.c',
102 'test_ui_pager.c', 102 'test_ui_pager.c',
103 'test_ui_pager_scroll.c', 103 'test_ui_pager_scroll.c',
104 'test_ui_active_view.c',
104 'test_part_bg.c', 105 'test_part_bg.c',
105 'test_part_shadow.c', 106 'test_part_shadow.c',
106 'test_photo.c', 107 'test_photo.c',
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 80af598173..1409831cd3 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -387,7 +387,11 @@ void test_gesture_framework(void *data, Evas_Object *obj, void *event_info);
387 387
388void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info); 388void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info);
389void test_ui_pager(void *data, Evas_Object *obj, void *event_info); 389void test_ui_pager(void *data, Evas_Object *obj, void *event_info);
390void test_ui_pager_stack(void *data, Evas_Object *obj, void *event_info);
390void test_ui_pager_scroll(void *data, Evas_Object *obj, void *event_info); 391void test_ui_pager_scroll(void *data, Evas_Object *obj, void *event_info);
392void test_ui_active_view_stack(void *data, Evas_Object *obj, void *event_info);
393void test_ui_active_view_plain(void *data, Evas_Object *obj, void *event_info);
394void test_ui_active_view_scroll(void *data, Evas_Object *obj, void *event_info);
391 395
392void test_ui_relative_layout(void *data, Evas_Object *obj, void *event_info); 396void test_ui_relative_layout(void *data, Evas_Object *obj, void *event_info);
393 397
@@ -1117,6 +1121,9 @@ add_tests:
1117 ADD_TEST_EO(NULL, "Tab Pager", "Efl.Ui.Tab_Pager", test_ui_tab_pager); 1121 ADD_TEST_EO(NULL, "Tab Pager", "Efl.Ui.Tab_Pager", test_ui_tab_pager);
1118 ADD_TEST_EO(NULL, "Pager", "Efl.Ui.Pager", test_ui_pager); 1122 ADD_TEST_EO(NULL, "Pager", "Efl.Ui.Pager", test_ui_pager);
1119 ADD_TEST_EO(NULL, "Scroll Pager", "Efl.Ui.Pager (Scroll)", test_ui_pager_scroll); 1123 ADD_TEST_EO(NULL, "Scroll Pager", "Efl.Ui.Pager (Scroll)", test_ui_pager_scroll);
1124 ADD_TEST_EO(NULL, "Active View", "Efl.Ui.Active_View Plain", test_ui_active_view_plain);
1125 ADD_TEST_EO(NULL, "Active View", "Efl.Ui.Active_View Scroll", test_ui_active_view_scroll);
1126 ADD_TEST_EO(NULL, "Active View", "Efl.Ui.Active_View Stack", test_ui_active_view_stack);
1120 1127
1121 //------------------------------// 1128 //------------------------------//
1122 ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup); 1129 ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup);
diff --git a/src/bin/elementary/test_ui_active_view.c b/src/bin/elementary/test_ui_active_view.c
new file mode 100644
index 0000000000..71fc9ba0b0
--- /dev/null
+++ b/src/bin/elementary/test_ui_active_view.c
@@ -0,0 +1,1070 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4#define EO_BETA_API
5#define EFL_UI_WIDGET_PROTECTED
6
7#include <Efl_Ui.h>
8#include <Elementary.h>
9
10typedef enum _Page_Type {
11 LAYOUT,
12 LIST,
13 BUTTON
14} Page_Type;
15
16typedef enum _Pack_Type {
17 PACK_BEGIN,
18 PACK_END,
19 PACK_BEFORE,
20 PACK_AFTER,
21 PACK_AT,
22 UNPACK_AT,
23 CLEAR
24} Pack_Type;
25
26typedef struct _Params {
27 Evas_Object *navi;
28 Eo *active_view;
29 Eo *indicator;
30 int w, h;
31 Eina_Bool wfill, hfill;
32} Params;
33
34typedef struct _Page_Set_Params {
35 Eo *active_view;
36 Eo *spinner;
37} Page_Set_Params;
38
39typedef struct _Pack_Params {
40 Pack_Type type;
41 Eo *active_view;
42 Eo *pack_sp;
43 Eo *unpack_sp;
44 Eo *unpack_btn;
45} Pack_Params;
46
47typedef struct _Size_Params {
48 Eo *active_view;
49 Eo *slider;
50 Params *params;
51} Size_Params;
52
53#define PAGE_NUM 3
54
55static Eo*
56page_add(Page_Type p, Eo *parent)
57{
58 Eo *page;
59 char buf[PATH_MAX];
60 int i;
61
62 switch (p) {
63 case LAYOUT:
64 snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
65 elm_app_data_dir_get());
66 page = efl_add(EFL_UI_LAYOUT_CLASS, parent,
67 efl_file_set(efl_added, buf),
68 efl_file_key_set(efl_added, "page"),
69 efl_file_load(efl_added),
70 efl_text_set(efl_part(efl_added, "text"), "Layout Page"));
71 efl_gfx_hint_fill_set(page, EINA_TRUE, EINA_TRUE);
72 break;
73 case LIST:
74 page = elm_list_add(parent);
75 elm_list_select_mode_set(page, ELM_OBJECT_SELECT_MODE_ALWAYS);
76 evas_object_show(page);
77 for (i = 0; i < 20; i++) {
78 snprintf(buf, sizeof(buf), "List Page - Item #%d", i);
79 elm_list_item_append(page, buf, NULL, NULL, NULL, NULL);
80 }
81 evas_object_size_hint_weight_set(page, EVAS_HINT_EXPAND,
82 EVAS_HINT_EXPAND);
83 evas_object_size_hint_align_set(page, EVAS_HINT_FILL,
84 EVAS_HINT_FILL);
85 break;
86 case BUTTON:
87 page = efl_add(EFL_UI_BUTTON_CLASS, parent,
88 efl_text_set(efl_added, "Button Page"));
89 efl_gfx_hint_fill_set(page, EINA_TRUE, EINA_TRUE);
90 break;
91 default:
92 snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
93 elm_app_data_dir_get());
94 page = efl_add(EFL_UI_LAYOUT_CLASS, parent,
95 efl_file_set(efl_added, buf),
96 efl_file_key_set(efl_added, "page"),
97 efl_file_load(efl_added),
98 efl_text_set(efl_part(efl_added, "text"), "Layout Page"));
99 efl_gfx_hint_fill_set(page, EINA_TRUE, EINA_TRUE);
100 break;
101 }
102
103 return page;
104}
105
106static void
107prev_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
108{
109 Eo *active_view = data;
110 int active_index = efl_ui_active_view_active_index_get(active_view);
111
112 if (active_index - 1 > -1)
113 efl_ui_active_view_active_index_set(active_view, active_index -1);
114}
115
116static void
117next_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
118{
119 Eo *active_view = data;
120 int active_index = efl_ui_active_view_active_index_get(active_view);
121
122 if (active_index + 1 < efl_content_count(active_view))
123 efl_ui_active_view_active_index_set(active_view, active_index +1);
124}
125
126static void
127back_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
128{
129 elm_naviframe_item_pop(data);
130}
131
132static void
133list_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
134{
135 free(data);
136}
137
138static void
139width_slider_cb(void *data, const Efl_Event *ev)
140{
141 Params *params = data;
142 int h;
143
144 if (params->hfill) h = -1;
145 else h = params->h;
146
147 params->w = efl_ui_range_value_get(ev->object);
148 efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(params->w, h));
149}
150
151static void
152height_slider_cb(void *data, const Efl_Event *ev)
153{
154 Params *params = data;
155 int w;
156
157 if (params->wfill) w = -1;
158 else w = params->w;
159
160 params->h = efl_ui_range_value_get(ev->object);
161 efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(w, params->h));
162}
163
164static void
165width_check_cb(void *data, const Efl_Event *ev)
166{
167 Size_Params *params = data;
168 Eina_Bool ck = elm_check_selected_get(ev->object);
169 int w, h;
170
171 elm_object_disabled_set(params->slider, ck);
172
173 params->params->wfill = ck;
174
175 if (params->params->wfill) w = -1;
176 else w = params->params->w;
177
178 if (params->params->hfill) h = -1;
179 else h = params->params->h;
180
181 efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(w, h));
182}
183
184static void
185height_check_cb(void *data, const Efl_Event *ev)
186{
187 Size_Params *params = data;
188 Eina_Bool ck = elm_check_selected_get(ev->object);
189 int w, h;
190
191 elm_object_disabled_set(params->slider, ck);
192
193 params->params->hfill = ck;
194
195 if (params->params->wfill) w = -1;
196 else w = params->params->w;
197
198 if (params->params->hfill) h = -1;
199 else h = params->params->h;
200
201 efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(w, h));
202}
203
204static void
205check_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
206{
207 free(data);
208}
209
210static void
211pack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
212{
213 Pack_Params *param = data;
214 Eo *active_view = param->active_view;
215 Eo *page = NULL, *curr_page;
216 int index, cnt;
217
218 if ((param->type != UNPACK_AT) && (param->type != CLEAR)) {
219 index = efl_content_count(active_view);
220
221 switch (index % 3) {
222 case 0:
223 page = page_add(LAYOUT, active_view);
224 break;
225 case 1:
226 page = page_add(LIST, active_view);
227 break;
228 case 2:
229 page = page_add(BUTTON, active_view);
230 break;
231 default:
232 page = page_add(LAYOUT, active_view);
233 break;
234 }
235 }
236
237 switch (param->type) {
238 case PACK_BEGIN:
239 efl_pack_begin(active_view, page);
240 break;
241 case PACK_END:
242 efl_pack_end(active_view, page);
243 break;
244 case PACK_BEFORE:
245 index = efl_ui_active_view_active_index_get(active_view);
246 curr_page = efl_pack_content_get(active_view, index);
247 efl_pack_before(active_view, page, curr_page);
248 break;
249 case PACK_AFTER:
250 index = efl_ui_active_view_active_index_get(active_view);
251 curr_page = efl_pack_content_get(active_view, index);
252 efl_pack_after(active_view, page, curr_page);
253 break;
254 case PACK_AT:
255 index = efl_ui_range_value_get(param->pack_sp);
256 efl_pack_at(active_view, page, index);
257 break;
258 case UNPACK_AT:
259 index = efl_ui_range_value_get(param->unpack_sp);
260 page = efl_pack_unpack_at(active_view, index);
261 efl_del(page);
262 break;
263 case CLEAR:
264 efl_pack_clear(active_view);
265 break;
266 }
267
268 cnt = efl_content_count(active_view);
269
270 index = efl_ui_range_value_get(param->pack_sp);
271 if (index > cnt)
272 efl_ui_range_value_set(param->pack_sp, cnt);
273 efl_ui_range_min_max_set(param->pack_sp, 0, cnt);
274
275 if (cnt > 0)
276 {
277 elm_object_disabled_set(param->unpack_btn, EINA_FALSE);
278 elm_object_disabled_set(param->unpack_sp, EINA_FALSE);
279
280 cnt -= 1;
281 index = efl_ui_range_value_get(param->unpack_sp);
282 if (index > cnt)
283 efl_ui_range_value_set(param->unpack_sp, cnt);
284 efl_ui_range_min_max_set(param->unpack_sp, 0, cnt);
285 }
286 else
287 {
288 elm_object_disabled_set(param->unpack_btn, EINA_TRUE);
289 elm_object_disabled_set(param->unpack_sp, EINA_TRUE);
290 }
291}
292
293static void
294pack_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
295{
296 free(data);
297}
298
299static void
300page_set_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
301{
302 Page_Set_Params *psp = data;
303
304 efl_ui_active_view_active_index_set(psp->active_view,
305 efl_ui_range_value_get(psp->spinner));
306}
307
308static void
309page_set_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
310{
311 free(data);
312}
313
314static void
315indicator_icon_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
316{
317 Params *params = data;
318
319 params->indicator = efl_add(EFL_UI_ACTIVE_VIEW_INDICATOR_ICON_CLASS, params->active_view);
320 efl_ui_active_view_indicator_set(params->active_view, params->indicator);
321}
322
323static void
324indicator_none_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
325{
326 Params *params = data;
327 efl_ui_active_view_indicator_set(params->active_view, NULL);
328}
329
330static void
331active_view_size(void *data,
332 Evas_Object *obj EINA_UNUSED,
333 void *event_info EINA_UNUSED)
334{
335 Params *params = data;
336 Size_Params *size_params;
337 Evas_Object *navi = params->navi;
338 Eo *btn, *box, *fr, *inbox, *ck, *sl;
339
340 btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
341 efl_text_set(efl_added, "Back"),
342 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
343 back_btn_cb, navi));
344
345 box = efl_add(EFL_UI_BOX_CLASS, navi,
346 elm_naviframe_item_push(navi, "View Size", btn, NULL,
347 efl_added, NULL));
348
349 // Width
350 fr = elm_frame_add(box);
351 elm_object_text_set(fr, "Width");
352 efl_gfx_hint_align_set(fr, -1, -1);
353 efl_gfx_hint_weight_set(fr, 1, 1);
354 efl_pack(box, fr);
355 efl_gfx_entity_visible_set(fr, 1);
356
357 inbox = efl_add(EFL_UI_BOX_CLASS, fr,
358 efl_content_set(fr, efl_added));
359
360 ck = elm_check_add(inbox);
361 elm_object_text_set(ck, "Fill");
362 efl_pack_end(inbox, ck);
363 efl_gfx_entity_visible_set(ck, 1);
364
365 sl = efl_add(EFL_UI_SLIDER_CLASS, inbox,
366 efl_ui_range_min_max_set(efl_added, 100, 200),
367 efl_ui_range_value_set(efl_added, params->w),
368 efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(100, 0)),
369 efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED,
370 width_slider_cb, params),
371 efl_pack_end(inbox, efl_added));
372
373 size_params = calloc(1, sizeof(Size_Params));
374 if (!size_params) return;
375
376 size_params->slider = sl;
377 size_params->active_view = params->active_view;
378 size_params->params = params;
379
380 efl_event_callback_add(ck, EFL_UI_CHECK_EVENT_CHANGED, width_check_cb,
381 size_params);
382 efl_event_callback_add(ck, EFL_EVENT_DEL, check_del_cb, size_params);
383
384 if (params->wfill)
385 {
386 elm_check_state_set(ck, EINA_TRUE);
387 elm_object_disabled_set(sl, EINA_TRUE);
388 }
389
390 // Height
391 fr = elm_frame_add(box);
392 elm_object_text_set(fr, "Height");
393 efl_gfx_hint_align_set(fr, -1, -1);
394 efl_gfx_hint_weight_set(fr, 1, 1);
395 efl_pack(box, fr);
396 efl_gfx_entity_visible_set(fr, 1);
397
398 inbox = efl_add(EFL_UI_BOX_CLASS, fr,
399 efl_content_set(fr, efl_added));
400
401 ck = elm_check_add(inbox);
402 elm_object_text_set(ck, "Fill");
403 efl_pack_end(inbox, ck);
404 efl_gfx_entity_visible_set(ck, 1);
405
406 sl = efl_add(EFL_UI_SLIDER_CLASS, inbox,
407 efl_ui_range_min_max_set(efl_added, 100, 300),
408 efl_ui_range_value_set(efl_added, params->h),
409 efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(100, 0)),
410 efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED,
411 height_slider_cb, params),
412 efl_pack_end(inbox, efl_added));
413
414 size_params = calloc(1, sizeof(Size_Params));
415 if (!size_params) return;
416
417 size_params->slider = sl;
418 size_params->active_view = params->active_view;
419 size_params->params = params;
420
421 efl_event_callback_add(ck, EFL_UI_CHECK_EVENT_CHANGED, height_check_cb,
422 size_params);
423 efl_event_callback_add(ck, EFL_EVENT_DEL, check_del_cb, size_params);
424
425 if (params->hfill)
426 {
427 elm_check_state_set(ck, EINA_TRUE);
428 elm_object_disabled_set(sl, EINA_TRUE);
429 }
430}
431
432static void
433_gravity_changed_cb(void *data, const Efl_Event *ev)
434{
435 Params *params = data;
436
437 if (efl_ui_nstate_value_get(ev->object) == 0)
438 {
439 efl_ui_active_view_gravity_set(params->active_view, EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_INDEX);
440 }
441 else
442 {
443 efl_ui_active_view_gravity_set(params->active_view, EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT);
444 }
445}
446
447static void
448view_index_gravity_cb(void *data,
449 Evas_Object *obj EINA_UNUSED,
450 void *event_info EINA_UNUSED)
451{
452 Params *params = data;
453 Evas_Object *navi = params->navi;
454 Eo *btn, *box, *ck;
455
456 btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
457 efl_text_set(efl_added, "Back"),
458 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
459 back_btn_cb, navi));
460
461 box = efl_add(EFL_UI_BOX_CLASS, navi,
462 elm_naviframe_item_push(navi, "View Index Gravity", btn, NULL,
463 efl_added, NULL));
464
465 // Width
466
467 ck = efl_add(EFL_UI_CHECK_CLASS, box);
468 efl_event_callback_add(ck, EFL_UI_NSTATE_EVENT_CHANGED, _gravity_changed_cb, params);
469 efl_text_set(ck, "Content Index Gravity");
470 efl_pack_end(box, ck);
471 efl_gfx_entity_visible_set(ck, 1);
472 if (efl_ui_active_view_gravity_get(params->active_view) == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT)
473 {
474 efl_ui_nstate_value_set(ck, 1);
475 }
476 else
477 {
478 efl_ui_nstate_value_set(ck, 0);
479 }
480}
481
482static void
483_animation_cb(void *data, const Efl_Event *ev)
484{
485 Params *params = data;
486
487 efl_ui_active_view_view_manager_animation_enabled_set(efl_ui_active_view_manager_get(params->active_view), efl_ui_nstate_value_get(ev->object));
488}
489
490static void
491view_animation_cb(void *data,
492 Evas_Object *obj EINA_UNUSED,
493 void *event_info EINA_UNUSED)
494{
495 Params *params = data;
496 Evas_Object *navi = params->navi;
497 Eo *btn, *box, *ck;
498
499 btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
500 efl_text_set(efl_added, "Back"),
501 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
502 back_btn_cb, navi));
503
504 box = efl_add(EFL_UI_BOX_CLASS, navi,
505 elm_naviframe_item_push(navi, "View Manager animation", btn, NULL,
506 efl_added, NULL));
507
508 ck = efl_add(EFL_UI_CHECK_CLASS, box);
509 efl_event_callback_add(ck, EFL_UI_NSTATE_EVENT_CHANGED, _animation_cb, params);
510 efl_ui_nstate_value_set(ck, efl_ui_active_view_view_manager_animation_enabled_get(efl_ui_active_view_manager_get(params->active_view)));
511 efl_text_set(ck, "Animation");
512 efl_pack_end(box, ck);
513 efl_gfx_entity_visible_set(ck, 1);
514}
515
516static void
517pack_cb(void *data,
518 Evas_Object *obj EINA_UNUSED,
519 void *event_info EINA_UNUSED)
520{
521 Params *params = (Params *)data;
522 Evas_Object *navi = params->navi;
523 Eo *active_view = params->active_view;
524 Eo *btn, *box, *in_box1, *in_box2, *sp1, *sp2;
525 Pack_Params *pack_param;
526
527 btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
528 efl_text_set(efl_added, "Back"),
529 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
530 back_btn_cb, navi));
531
532 box = efl_add(EFL_UI_BOX_CLASS, navi,
533 efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
534 elm_naviframe_item_push(navi, "Pack", btn, NULL,
535 efl_added, NULL));
536
537 in_box1 = efl_add(EFL_UI_BOX_CLASS, box,
538 efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
539 efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL));
540
541 sp1 = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box1,
542 efl_ui_range_min_max_set(efl_added, 0,
543 efl_content_count(active_view)),
544 efl_ui_range_value_set(efl_added,
545 efl_ui_active_view_active_index_get(active_view)));
546
547 in_box2 = efl_add(EFL_UI_BOX_CLASS, box,
548 efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
549 efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL));
550
551 sp2 = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box2);
552
553 btn = efl_add(EFL_UI_BUTTON_CLASS, in_box2,
554 efl_text_set(efl_added, "Unpack At"));
555
556 // Pack Begin
557 pack_param = calloc(1, sizeof(Pack_Params));
558 if (!pack_param) return;
559
560 pack_param->active_view = active_view;
561 pack_param->pack_sp = sp1;
562 pack_param->unpack_sp = sp2;
563 pack_param->unpack_btn = btn;
564 pack_param->type = PACK_BEGIN;
565
566 efl_add(EFL_UI_BUTTON_CLASS, box,
567 efl_text_set(efl_added, "Pack Begin"),
568 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
569 pack_btn_cb, pack_param),
570 efl_event_callback_add(efl_added, EFL_EVENT_DEL,
571 pack_btn_del_cb, pack_param),
572 efl_pack_end(box, efl_added));
573
574 // Pack End
575 pack_param = calloc(1, sizeof(Pack_Params));
576 if (!pack_param) return;
577
578 pack_param->active_view = active_view;
579 pack_param->pack_sp = sp1;
580 pack_param->unpack_sp = sp2;
581 pack_param->unpack_btn = btn;
582 pack_param->type = PACK_END;
583
584 efl_add(EFL_UI_BUTTON_CLASS, box,
585 efl_text_set(efl_added, "Pack End"),
586 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
587 pack_btn_cb, pack_param),
588 efl_event_callback_add(efl_added, EFL_EVENT_DEL,
589 pack_btn_del_cb, pack_param),
590 efl_pack_end(box, efl_added));
591
592 // Pack Before
593 pack_param = calloc(1, sizeof(Pack_Params));
594 if (!pack_param) return;
595
596 pack_param->active_view = active_view;
597 pack_param->pack_sp = sp1;
598 pack_param->unpack_sp = sp2;
599 pack_param->unpack_btn = btn;
600 pack_param->type = PACK_BEFORE;
601
602 efl_add(EFL_UI_BUTTON_CLASS, box,
603 efl_text_set(efl_added, "Pack Before Current Page"),
604 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
605 pack_btn_cb, pack_param),
606 efl_event_callback_add(efl_added, EFL_EVENT_DEL,
607 pack_btn_del_cb, pack_param),
608 efl_pack_end(box, efl_added));
609
610 // Pack After
611 pack_param = calloc(1, sizeof(Pack_Params));
612 if (!pack_param) return;
613
614 pack_param->active_view = active_view;
615 pack_param->pack_sp = sp1;
616 pack_param->unpack_sp = sp2;
617 pack_param->unpack_btn = btn;
618 pack_param->type = PACK_AFTER;
619
620 efl_add(EFL_UI_BUTTON_CLASS, box,
621 efl_text_set(efl_added, "Pack After Current Page"),
622 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
623 pack_btn_cb, pack_param),
624 efl_event_callback_add(efl_added, EFL_EVENT_DEL,
625 pack_btn_del_cb, pack_param),
626 efl_pack_end(box, efl_added));
627
628 // Pack At
629 pack_param = calloc(1, sizeof(Pack_Params));
630 if (!pack_param) return;
631
632 pack_param->active_view = active_view;
633 pack_param->pack_sp = sp1;
634 pack_param->unpack_sp = sp2;
635 pack_param->unpack_btn = btn;
636 pack_param->type = PACK_AT;
637
638 efl_add(EFL_UI_BUTTON_CLASS, in_box1,
639 efl_text_set(efl_added, "Pack At"),
640 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
641 pack_btn_cb, pack_param),
642 efl_event_callback_add(efl_added, EFL_EVENT_DEL,
643 pack_btn_del_cb, pack_param),
644 efl_pack_end(in_box1, efl_added));
645
646 efl_pack_end(box, in_box1);
647 efl_pack_end(in_box1, sp1);
648
649 // Unpack At
650 pack_param = calloc(1, sizeof(Pack_Params));
651 if (!pack_param) return;
652
653 pack_param->active_view = active_view;
654 pack_param->pack_sp = sp1;
655 pack_param->unpack_sp = sp2;
656 pack_param->unpack_btn = btn;
657 pack_param->type = UNPACK_AT;
658
659 efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED,
660 pack_btn_cb, pack_param);
661 efl_event_callback_add(btn, EFL_EVENT_DEL,
662 pack_btn_del_cb, pack_param);
663
664 if (efl_content_count(active_view) > 0)
665 {
666 efl_ui_range_min_max_set(sp2, 0,
667 (efl_content_count(active_view) - 1));
668 efl_ui_range_value_set(sp2,
669 efl_ui_active_view_active_index_get(active_view));
670 }
671 else
672 {
673 elm_object_disabled_set(btn, EINA_TRUE);
674 elm_object_disabled_set(sp2, EINA_TRUE);
675 }
676
677 efl_pack_end(box, in_box2);
678 efl_pack_end(in_box2, btn);
679 efl_pack_end(in_box2, sp2);
680
681 // Clear
682 pack_param = calloc(1, sizeof(Pack_Params));
683 if (!pack_param) return;
684
685 pack_param->active_view = active_view;
686 pack_param->pack_sp = sp1;
687 pack_param->unpack_sp = sp2;
688 pack_param->unpack_btn = btn;
689 pack_param->type = CLEAR;
690
691 efl_add(EFL_UI_BUTTON_CLASS, box,
692 efl_text_set(efl_added, "Clear"),
693 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
694 pack_btn_cb, pack_param),
695 efl_event_callback_add(efl_added, EFL_EVENT_DEL,
696 pack_btn_del_cb, pack_param),
697 efl_pack_end(box, efl_added));
698
699}
700
701static void
702active_index_cb(void *data,
703 Evas_Object *obj EINA_UNUSED,
704 void *event_info EINA_UNUSED)
705{
706 Params *params = (Params *)data;
707 Evas_Object *navi = params->navi;
708 Eo *active_view = params->active_view;
709 Eo *btn, *box, *sp;
710 Page_Set_Params *psp = calloc(1, sizeof(Page_Set_Params));
711 if (!psp) return;
712
713 btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
714 efl_text_set(efl_added, "Back"),
715 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
716 back_btn_cb, navi));
717
718 box = efl_add(EFL_UI_BOX_CLASS, navi,
719 efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
720 elm_naviframe_item_push(navi, "Active Index", btn, NULL,
721 efl_added, NULL));
722
723 btn = efl_add(EFL_UI_BUTTON_CLASS, box,
724 efl_text_set(efl_added, "Set Active Index"),
725 efl_pack_end(box, efl_added));
726
727 sp = efl_add(EFL_UI_SPIN_BUTTON_CLASS, box,
728 efl_gfx_hint_align_set(efl_added, -1, -1),
729 efl_pack_end(box, efl_added));
730
731 if (efl_content_count(active_view) > 0)
732 {
733 efl_ui_range_min_max_set(sp, 0,
734 (efl_content_count(active_view) - 1));
735 efl_ui_range_value_set(sp,
736 efl_ui_active_view_active_index_get(active_view));
737 }
738 else
739 {
740 elm_object_disabled_set(btn, EINA_TRUE);
741 elm_object_disabled_set(sp, EINA_TRUE);
742 }
743
744 psp->active_view = active_view;
745 psp->spinner = sp;
746
747 efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, page_set_btn_cb, psp);
748 efl_event_callback_add(btn, EFL_EVENT_DEL, page_set_btn_del_cb, psp);
749}
750
751static void
752indicator_cb(void *data,
753 Evas_Object *obj EINA_UNUSED,
754 void *event_info EINA_UNUSED)
755{
756 Params *params = (Params *)data;
757 Evas_Object *navi = params->navi;
758 Eo *btn, *box;
759
760 btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
761 efl_text_set(efl_added, "Back"),
762 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
763 back_btn_cb, navi));
764
765 box = efl_add(EFL_UI_BOX_CLASS, navi,
766 efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
767 elm_naviframe_item_push(navi, "Indicator", btn, NULL,
768 efl_added, NULL));
769
770 efl_add(EFL_UI_BUTTON_CLASS, box,
771 efl_text_set(efl_added, "Icon Type"),
772 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
773 indicator_icon_btn_cb, params),
774 efl_pack_end(box, efl_added));
775
776 efl_add(EFL_UI_BUTTON_CLASS, box,
777 efl_text_set(efl_added, "None"),
778 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
779 indicator_none_btn_cb, params),
780 efl_pack_end(box, efl_added));
781}
782
783void test_ui_active_view_stack(void *data EINA_UNUSED,
784 Evas_Object *obj EINA_UNUSED,
785 void *event_info EINA_UNUSED)
786{
787 Eo *win, *panes, *navi, *list, *layout, *active_view, *page;
788 Params *params = NULL;
789 char buf[PATH_MAX];
790 int i;
791
792 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
793 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
794 efl_text_set(efl_added, "Efl.Ui.Active_View Stack"),
795 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
796
797 panes = efl_add(EFL_UI_PANES_CLASS, win,
798 efl_gfx_hint_weight_set(efl_added, 1, 1),
799 efl_ui_panes_split_ratio_set(efl_added, 0.3),
800 efl_content_set(win, efl_added));
801
802 navi = elm_naviframe_add(panes);
803 evas_object_show(navi);
804 efl_content_set(efl_part(panes, "first"), navi);
805
806 list = elm_list_add(navi);
807 elm_list_horizontal_set(list, EINA_FALSE);
808 elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
809 elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
810 evas_object_show(list);
811
812 snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
813 elm_app_data_dir_get());
814 layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
815 efl_file_set(efl_added, buf),
816 efl_file_key_set(efl_added, "pager"),
817 efl_file_load(efl_added),
818 efl_content_set(efl_part(panes, "second"), efl_added));
819
820 active_view = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, layout,
821 efl_content_set(efl_part(layout, "pager"), efl_added),
822 efl_ui_active_view_size_set(efl_added, EINA_SIZE2D(200, 300)));
823
824 efl_ui_active_view_manager_set(active_view, efl_new(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_STACK_CLASS));
825
826 efl_add(EFL_UI_BUTTON_CLASS, layout,
827 efl_text_set(efl_added, "Prev"),
828 efl_event_callback_add(efl_added,
829 EFL_UI_EVENT_CLICKED, prev_btn_cb, active_view),
830 efl_content_set(efl_part(layout, "prev_btn"), efl_added));
831
832 efl_add(EFL_UI_BUTTON_CLASS, layout,
833 efl_text_set(efl_added, "Next"),
834 efl_event_callback_add(efl_added,
835 EFL_UI_EVENT_CLICKED, next_btn_cb, active_view),
836 efl_content_set(efl_part(layout, "next_btn"), efl_added));
837
838 params = calloc(1, sizeof(Params));
839 if (!params) return;
840
841 params->navi = navi;
842 params->active_view = active_view;
843 params->indicator = NULL;
844 params->w = 200;
845 params->h = 300;
846 params->wfill = EINA_FALSE;
847 params->hfill = EINA_FALSE;
848
849 elm_list_item_append(list, "View Size", NULL, NULL, active_view_size, params);
850 elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
851 elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
852 elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
853 elm_list_item_append(list, "View Index Gravity", NULL, NULL, view_index_gravity_cb, params);
854 elm_list_item_append(list, "Animation", NULL, NULL, view_animation_cb, params);
855 elm_list_go(list);
856
857 efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
858
859 for (i = 0; i < PAGE_NUM; i++) {
860 switch (i % 3) {
861 case 0:
862 page = page_add(LAYOUT, active_view);
863 break;
864 case 1:
865 page = page_add(LIST, active_view);
866 break;
867 case 2:
868 page = page_add(BUTTON, active_view);
869 break;
870 default:
871 page = page_add(LAYOUT, active_view);
872 break;
873 }
874 efl_pack_end(active_view, page);
875 }
876
877 efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
878}
879
880void test_ui_active_view_plain(void *data EINA_UNUSED,
881 Evas_Object *obj EINA_UNUSED,
882 void *event_info EINA_UNUSED)
883{
884 Eo *win, *panes, *navi, *list, *layout, *active_view, *page;
885 Params *params = NULL;
886 char buf[PATH_MAX];
887 int i;
888
889 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
890 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
891 efl_text_set(efl_added, "Efl.Ui.Active_View Plain"),
892 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
893
894 panes = efl_add(EFL_UI_PANES_CLASS, win,
895 efl_gfx_hint_weight_set(efl_added, 1, 1),
896 efl_ui_panes_split_ratio_set(efl_added, 0.3),
897 efl_content_set(win, efl_added));
898
899 navi = elm_naviframe_add(panes);
900 evas_object_show(navi);
901 efl_content_set(efl_part(panes, "first"), navi);
902
903 list = elm_list_add(navi);
904 elm_list_horizontal_set(list, EINA_FALSE);
905 elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
906 elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
907 evas_object_show(list);
908
909 snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
910 elm_app_data_dir_get());
911 layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
912 efl_file_set(efl_added, buf),
913 efl_file_key_set(efl_added, "pager"),
914 efl_file_load(efl_added),
915 efl_content_set(efl_part(panes, "second"), efl_added));
916
917 active_view = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, layout,
918 efl_content_set(efl_part(layout, "pager"), efl_added),
919 efl_ui_active_view_size_set(efl_added, EINA_SIZE2D(200, 300)));
920
921 efl_add(EFL_UI_BUTTON_CLASS, layout,
922 efl_text_set(efl_added, "Prev"),
923 efl_event_callback_add(efl_added,
924 EFL_UI_EVENT_CLICKED, prev_btn_cb, active_view),
925 efl_content_set(efl_part(layout, "prev_btn"), efl_added));
926
927 efl_add(EFL_UI_BUTTON_CLASS, layout,
928 efl_text_set(efl_added, "Next"),
929 efl_event_callback_add(efl_added,
930 EFL_UI_EVENT_CLICKED, next_btn_cb, active_view),
931 efl_content_set(efl_part(layout, "next_btn"), efl_added));
932
933 params = calloc(1, sizeof(Params));
934 if (!params) return;
935
936 params->navi = navi;
937 params->active_view = active_view;
938 params->indicator = NULL;
939 params->w = 200;
940 params->h = 300;
941 params->wfill = EINA_FALSE;
942 params->hfill = EINA_FALSE;
943
944 elm_list_item_append(list, "View Size", NULL, NULL, active_view_size, params);
945 elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
946 elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
947 elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
948 elm_list_item_append(list, "View Index Gravity", NULL, NULL, view_index_gravity_cb, params);
949 elm_list_go(list);
950
951 efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
952
953 for (i = 0; i < PAGE_NUM; i++) {
954 switch (i % 3) {
955 case 0:
956 page = page_add(LAYOUT, active_view);
957 break;
958 case 1:
959 page = page_add(LIST, active_view);
960 break;
961 case 2:
962 page = page_add(BUTTON, active_view);
963 break;
964 default:
965 page = page_add(LAYOUT, active_view);
966 break;
967 }
968 efl_pack_end(active_view, page);
969 }
970
971 efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
972}
973
974
975void test_ui_active_view_scroll(void *data EINA_UNUSED,
976 Evas_Object *obj EINA_UNUSED,
977 void *event_info EINA_UNUSED)
978{
979 Eo *win, *panes, *navi, *list, *layout, *active_view, *page;
980 Params *params = NULL;
981 char buf[PATH_MAX];
982 int i;
983
984 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
985 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
986 efl_text_set(efl_added, "Efl.Ui.Active_View Scroll"),
987 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
988
989 panes = efl_add(EFL_UI_PANES_CLASS, win,
990 efl_gfx_hint_weight_set(efl_added, 1, 1),
991 efl_ui_panes_split_ratio_set(efl_added, 0.3),
992 efl_content_set(win, efl_added));
993
994 navi = elm_naviframe_add(panes);
995 evas_object_show(navi);
996 efl_content_set(efl_part(panes, "first"), navi);
997
998 list = elm_list_add(navi);
999 elm_list_horizontal_set(list, EINA_FALSE);
1000 elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
1001 elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
1002 evas_object_show(list);
1003
1004 snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
1005 elm_app_data_dir_get());
1006 layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
1007 efl_file_set(efl_added, buf),
1008 efl_file_key_set(efl_added, "pager"),
1009 efl_file_load(efl_added),
1010 efl_content_set(efl_part(panes, "second"), efl_added));
1011
1012 active_view = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, layout,
1013 efl_content_set(efl_part(layout, "pager"), efl_added),
1014 efl_ui_active_view_size_set(efl_added, EINA_SIZE2D(200, 300)));
1015
1016 efl_ui_active_view_manager_set(active_view, efl_new(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS));
1017
1018 efl_add(EFL_UI_BUTTON_CLASS, layout,
1019 efl_text_set(efl_added, "Prev"),
1020 efl_event_callback_add(efl_added,
1021 EFL_UI_EVENT_CLICKED, prev_btn_cb, active_view),
1022 efl_content_set(efl_part(layout, "prev_btn"), efl_added));
1023
1024 efl_add(EFL_UI_BUTTON_CLASS, layout,
1025 efl_text_set(efl_added, "Next"),
1026 efl_event_callback_add(efl_added,
1027 EFL_UI_EVENT_CLICKED, next_btn_cb, active_view),
1028 efl_content_set(efl_part(layout, "next_btn"), efl_added));
1029
1030 params = calloc(1, sizeof(Params));
1031 if (!params) return;
1032
1033 params->navi = navi;
1034 params->active_view = active_view;
1035 params->indicator = NULL;
1036 params->w = 200;
1037 params->h = 300;
1038 params->wfill = EINA_FALSE;
1039 params->hfill = EINA_FALSE;
1040
1041 elm_list_item_append(list, "View Size", NULL, NULL, active_view_size, params);
1042 elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
1043 elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
1044 elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
1045 elm_list_item_append(list, "View Index Gravity", NULL, NULL, view_index_gravity_cb, params);
1046 elm_list_item_append(list, "Animation", NULL, NULL, view_animation_cb, params);
1047 elm_list_go(list);
1048
1049 efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
1050
1051 for (i = 0; i < PAGE_NUM; i++) {
1052 switch (i % 3) {
1053 case 0:
1054 page = page_add(LAYOUT, active_view);
1055 break;
1056 case 1:
1057 page = page_add(LIST, active_view);
1058 break;
1059 case 2:
1060 page = page_add(BUTTON, active_view);
1061 break;
1062 default:
1063 page = page_add(LAYOUT, active_view);
1064 break;
1065 }
1066 efl_pack_end(active_view, page);
1067 }
1068
1069 efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
1070}
diff --git a/src/examples/elementary/efl_ui_slideshow_example.c b/src/examples/elementary/efl_ui_slideshow_example.c
new file mode 100644
index 0000000000..fdf236e000
--- /dev/null
+++ b/src/examples/elementary/efl_ui_slideshow_example.c
@@ -0,0 +1,118 @@
1#include <Efl_Ui.h>
2
3#include <Elementary.h>
4
5static Efl_Ui_Active_View_Container *container;
6static Eina_Bool play_state = EINA_FALSE;
7static Efl_Loop_Timer *show_timer = NULL;
8
9char *img_files[] = {
10 "logo.png",
11 "plant_01.jpg",
12 "rock_01.jpg",
13 "rock_02.jpg",
14 "sky_01.jpg",
15 "wood_01.jpg",
16 "mystrale.jpg",
17 "mystrale_2.jpg"
18};
19#define IMG_NUM 8
20
21static void
22_show_next(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
23{
24 if (!show_timer) return;
25 efl_del(show_timer);
26 show_timer = NULL;
27
28 int current_index = efl_ui_active_view_active_index_get(container);
29 int new_index = (current_index + 1) % efl_content_count(container);
30 efl_ui_active_view_active_index_set(container, new_index);
31}
32
33static void
34put_play(void)
35{
36 play_state = EINA_TRUE;
37 show_timer = efl_add(EFL_LOOP_TIMER_CLASS, container,
38 efl_loop_timer_interval_set(efl_added, 2.0),
39 efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _show_next, NULL));
40}
41
42static void
43put_pause(void)
44{
45 play_state = EINA_FALSE;
46 if (show_timer)
47 efl_del(show_timer);
48 show_timer = NULL;
49
50}
51
52static void
53_container_end(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
54{
55 if (play_state)
56 {
57 show_timer = efl_add(EFL_LOOP_TIMER_CLASS, efl_app_main_get(),
58 efl_loop_timer_interval_set(efl_added, 2.0),
59 efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _show_next, NULL));
60 }
61}
62
63static void
64_play_toggle(void *data EINA_UNUSED, const Efl_Event *ev)
65{
66 if (play_state)
67 {
68 put_pause();
69 efl_text_set(ev->object, "Play");
70 }
71 else
72 {
73 put_play();
74 efl_text_set(ev->object, "Pause");
75 }
76}
77
78static void
79efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
80{
81 Efl_Ui_Win *win;
82 Efl_Ui_Table *table;
83
84 elm_app_info_set(efl_main, "elementary", "images");
85
86 win = efl_new(EFL_UI_WIN_CLASS,
87 efl_ui_win_autodel_set(efl_added, EINA_TRUE),
88 efl_text_set(efl_added, "Slideshow Example")
89 );
90 table = efl_add(EFL_UI_TABLE_CLASS, win);
91 efl_content_set(win, table);
92
93 container = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, win,
94 efl_event_callback_add(efl_added, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_END, _container_end, NULL),
95 efl_pack_table(table, efl_added, 0, 0, 1, 1));
96 efl_ui_active_view_indicator_set(container, efl_new(EFL_UI_ACTIVE_VIEW_INDICATOR_ICON_CLASS));
97 efl_ui_active_view_manager_set(container, efl_new(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_STACK_CLASS));
98
99 for (int i = 0; i < IMG_NUM; i++)
100 {
101 char path[PATH_MAX];
102 snprintf(path, PATH_MAX, "%s/images/%s", elm_app_data_dir_get(), img_files[i]);
103 efl_add(EFL_UI_IMAGE_CLASS, container,
104 efl_file_set(efl_added, path),
105 efl_file_load(efl_added),
106 efl_pack_end(container, efl_added));
107 }
108
109 efl_add(EFL_UI_BUTTON_CLASS, table,
110 efl_gfx_hint_weight_set(efl_added, 1.0, 0.0),
111 efl_pack_table(table, efl_added, 0, 1, 1, 1),
112 efl_text_set(efl_added, "Play"),
113 efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _play_toggle, NULL));
114
115 efl_gfx_entity_size_set(win, EINA_SIZE2D(200, 200));
116}
117
118EFL_MAIN();
diff --git a/src/examples/elementary/meson.build b/src/examples/elementary/meson.build
index 5286fb80ff..35a7eeac03 100644
--- a/src/examples/elementary/meson.build
+++ b/src/examples/elementary/meson.build
@@ -116,7 +116,8 @@ examples = [
116 'efl_ui_list_view_example_3', 116 'efl_ui_list_view_example_3',
117 'efl_canvas_layout_text', 117 'efl_canvas_layout_text',
118 'efl_ui_theme_example_01', 118 'efl_ui_theme_example_01',
119 'efl_ui_theme_example_02' 119 'efl_ui_theme_example_02',
120 'efl_ui_slideshow_example'
120] 121]
121 122
122foreach example : examples 123foreach example : examples
diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h
index 0b64b0405e..bf11cb215d 100644
--- a/src/lib/elementary/Efl_Ui.h
+++ b/src/lib/elementary/Efl_Ui.h
@@ -231,6 +231,18 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel);
231# include <efl_ui_panes_eo.h> 231# include <efl_ui_panes_eo.h>
232# include <efl_ui_panes_part.eo.h> 232# include <efl_ui_panes_part.eo.h>
233 233
234#define _EFL_UI_ACTIVE_VIEW_VIEW_MANAGEREO_CLASS_TYPE
235typedef Eo Efl_Ui_Active_View_View_Manager;
236#define _EFL_UI_ACTIVE_VIEW_INDICATOR_EO_CLASS_TYPE
237typedef Eo Efl_Ui_Active_View_Indicator;
238
239# include <efl_ui_active_view_container.eo.h>
240# include <efl_ui_active_view_view_manager.eo.h>
241# include <efl_ui_active_view_indicator.eo.h>
242# include <efl_ui_active_view_indicator_icon.eo.h>
243# include <efl_ui_active_view_view_manager_scroll.eo.h>
244# include <efl_ui_active_view_view_manager_stack.eo.h>
245
234# include <efl_ui_navigation_bar.eo.h> 246# include <efl_ui_navigation_bar.eo.h>
235# include <efl_ui_navigation_bar_part.eo.h> 247# include <efl_ui_navigation_bar_part.eo.h>
236# include <efl_ui_navigation_bar_part_back_button.eo.h> 248# include <efl_ui_navigation_bar_part_back_button.eo.h>
diff --git a/src/lib/elementary/efl_ui_active_view_container.c b/src/lib/elementary/efl_ui_active_view_container.c
new file mode 100644
index 0000000000..7a264691e8
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_container.c
@@ -0,0 +1,647 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Efl_Ui.h>
6#include "elm_priv.h"
7#include "efl_ui_active_view_view_manager_plain.eo.h"
8
9typedef struct _Efl_Ui_Active_View_Container_Data
10{
11 Eina_List *content_list;
12 Eo *page_root, *event;
13 struct {
14 Eina_Size2D sz;
15 } page_spec;
16 struct {
17 int page;
18 double pos;
19 } curr;
20 struct {
21 int from;
22 int to;
23 double last_pos;
24 Eina_Bool active;
25 } show_request;
26 Efl_Ui_Active_View_View_Manager *transition;
27 Efl_Ui_Active_View_Indicator *indicator;
28 double position;
29 Eina_Bool fill_width: 1;
30 Eina_Bool fill_height: 1;
31 Eina_Bool prevent_transition_interaction : 1;
32 Efl_Ui_Active_View_Container_Gravity gravity;
33} Efl_Ui_Active_View_Container_Data;
34
35#define MY_CLASS EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS
36
37static void _unpack(Eo *obj, Efl_Ui_Active_View_Container_Data *pd, Efl_Gfx_Entity *subobj, int index);
38static void _unpack_all(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Eina_Bool clear);
39
40static int
41clamp_index(Efl_Ui_Active_View_Container_Data *pd, int index)
42{
43 if (index < ((int)eina_list_count(pd->content_list)) * -1)
44 return -1;
45 else if (index > (int)eina_list_count(pd->content_list) - 1)
46 return 1;
47 return 0;
48}
49
50static int
51index_rollover(Efl_Ui_Active_View_Container_Data *pd, int index)
52{
53 int c = eina_list_count(pd->content_list);
54 if (index < c * -1)
55 return 0;
56 else if (index > c - 1)
57 return c - 1;
58 else if (index < 0)
59 return index + c;
60 return index;
61}
62
63static void
64_transition_end(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
65{
66 Efl_Ui_Active_View_Transition_Event ev;
67
68 if (pd->prevent_transition_interaction) return;
69
70 ev.from = pd->show_request.from;
71 ev.to = pd->show_request.to;
72 efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_END, &ev);
73 pd->show_request.active = EINA_FALSE;
74 pd->show_request.from = -1;
75 pd->show_request.to = -1;
76}
77
78static void
79_transition_start(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, int from, int to, double progress)
80{
81 Efl_Ui_Active_View_Transition_Event ev;
82
83 if (pd->prevent_transition_interaction) return;
84
85 if (pd->show_request.active)
86 _transition_end(obj, pd);
87
88 pd->show_request.active = EINA_TRUE;
89 pd->show_request.from = from;
90 pd->show_request.to = to;
91 pd->show_request.last_pos = progress;
92 ev.from = pd->show_request.from;
93 ev.to = pd->show_request.to;
94 efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_START, &ev);
95}
96
97static void
98_position_set(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, double progress)
99{
100 if (progress < -1.0) progress = -1.0;
101 if (progress > eina_list_count(pd->content_list)) progress = eina_list_count(pd->content_list);
102 if (pd->indicator)
103 {
104 efl_ui_active_view_indicator_position_update(pd->indicator, progress);
105 }
106 pd->position = progress;
107}
108
109static void
110_transition_event_emission(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
111{
112 if (pd->show_request.active)
113 {
114 if ((pd->show_request.to != -1 || pd->show_request.from != -1) &&
115 fabs(pd->show_request.last_pos - pd->show_request.to) < fabs(pd->position - pd->show_request.to))
116 {
117 //abort event here, movement is not in the direction we request
118 pd->show_request.to = -1;
119 _transition_end(obj, pd);
120 }
121 if (pd->position == pd->show_request.to)
122 {
123 //successfully there
124 _transition_end(obj, pd);
125 }
126 }
127 else
128 {
129 //the progress changed without a show_request beeing active. instaciate a new one
130 _transition_start(obj, pd, -1, -1, pd->position);
131 }
132}
133
134static void
135_resize_cb(void *data, const Efl_Event *ev)
136{
137 Efl_Ui_Active_View_Container_Data *pd = data;
138 Eina_Size2D sz;
139
140 sz = efl_gfx_entity_size_get(ev->object);
141
142 if (pd->fill_width) pd->page_spec.sz.w = sz.w;
143 if (pd->fill_height) pd->page_spec.sz.h = sz.h;
144
145 if (pd->transition)
146 efl_ui_active_view_view_manager_view_size_set(pd->transition, pd->page_spec.sz);
147}
148
149EOLIAN static Eo *
150_efl_ui_active_view_container_efl_object_constructor(Eo *obj,
151 Efl_Ui_Active_View_Container_Data *pd)
152{
153 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
154
155 if (!elm_widget_theme_klass_get(obj))
156 elm_widget_theme_klass_set(obj, "pager");
157
158 obj = efl_constructor(efl_super(obj, MY_CLASS));
159
160 if (elm_widget_theme_object_set(obj, wd->resize_obj,
161 elm_widget_theme_klass_get(obj),
162 elm_widget_theme_element_get(obj),
163 elm_widget_theme_style_get(obj)) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
164 CRI("Failed to set layout!");
165
166 pd->position = -1;
167 pd->curr.page = -1;
168 pd->curr.pos = 0.0;
169
170 pd->transition = NULL;
171 pd->indicator = NULL;
172
173 pd->fill_width = EINA_TRUE;
174 pd->fill_height = EINA_TRUE;
175
176 efl_ui_active_view_size_set(obj, EINA_SIZE2D(-1, -1));
177 efl_ui_active_view_gravity_set(obj, EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT);
178
179 elm_widget_can_focus_set(obj, EINA_FALSE);
180
181 pd->page_root = efl_add(EFL_CANVAS_GROUP_CLASS, evas_object_evas_get(obj));
182 efl_content_set(efl_part(obj, "efl.page_root"), pd->page_root);
183
184 efl_event_callback_add(pd->page_root, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, pd);
185
186 pd->event = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
187 evas_object_evas_get(obj));
188 evas_object_color_set(pd->event, 0, 0, 0, 0);
189 evas_object_repeat_events_set(pd->event, EINA_TRUE);
190 efl_content_set(efl_part(obj, "efl.event"), pd->event);
191
192 return obj;
193}
194
195EOLIAN static Efl_Object*
196_efl_ui_active_view_container_efl_object_finalize(Eo *obj, Efl_Ui_Active_View_Container_Data *pd EINA_UNUSED)
197{
198 Efl_Ui_Active_View_View_Manager *manager;
199
200 obj = efl_finalize(efl_super(obj, MY_CLASS));
201
202 manager = efl_ui_active_view_manager_get(obj);
203 //set a view manager in case nothing is here
204 if (!manager)
205 {
206 Eo *plain;
207 plain = efl_add(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS, obj);
208 efl_ui_active_view_manager_set(obj, plain);
209 }
210 else
211 {
212 efl_ui_active_view_view_manager_animation_enabled_set(manager, EINA_TRUE);
213 }
214
215 return obj;
216}
217
218EOLIAN static void
219_efl_ui_active_view_container_efl_object_invalidate(Eo *obj,
220 Efl_Ui_Active_View_Container_Data *pd)
221{
222 _unpack_all(obj, pd, EINA_TRUE);
223 efl_invalidate(efl_super(obj, MY_CLASS));
224}
225
226EOLIAN static int
227_efl_ui_active_view_container_efl_container_content_count(Eo *obj EINA_UNUSED,
228 Efl_Ui_Active_View_Container_Data *pd)
229{
230 return eina_list_count(pd->content_list);
231}
232
233static void
234_child_inv(void *data, const Efl_Event *ev)
235{
236 Efl_Ui_Active_View_Container_Data *pd = efl_data_scope_get(data, MY_CLASS);
237 int index = eina_list_data_idx(pd->content_list, ev->object);
238 _unpack(data, pd, ev->object, index);
239}
240
241static Eina_Bool
242_register_child(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Efl_Gfx_Entity *subobj)
243{
244 EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE);
245 if (eina_list_data_find(pd->content_list, subobj))
246 {
247 ERR("Object %p is already part of this!", subobj);
248 return EINA_FALSE;
249 }
250 if (!efl_ui_widget_sub_object_add(obj, subobj))
251 return EINA_FALSE;
252
253 efl_event_callback_add(subobj, EFL_EVENT_INVALIDATE, _child_inv, obj);
254
255 return EINA_TRUE;
256}
257
258
259EOLIAN static void
260_efl_ui_active_view_container_active_view_gravity_set(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Efl_Ui_Active_View_Container_Gravity gravity)
261{
262 pd->gravity = gravity;
263}
264
265EOLIAN static Efl_Ui_Active_View_Container_Gravity
266_efl_ui_active_view_container_active_view_gravity_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
267{
268 return pd->gravity;
269}
270
271static void
272_update_internals(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index)
273{
274 Eina_Bool curr_page_update = EINA_FALSE;
275
276 if (pd->gravity == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT && pd->curr.page >= index)
277 {
278 pd->curr.page++;
279 curr_page_update = EINA_TRUE;
280 }
281
282 pd->prevent_transition_interaction = EINA_TRUE;
283 if (pd->transition)
284 efl_ui_active_view_view_manager_content_add(pd->transition, subobj, index);
285 if (pd->indicator)
286 efl_ui_active_view_indicator_content_add(pd->indicator, subobj, index);
287 if (curr_page_update && !pd->transition && eina_list_count(pd->content_list) != 1)
288 _position_set(obj, pd, pd->curr.page);
289 pd->prevent_transition_interaction = EINA_FALSE;
290 if (eina_list_count(pd->content_list) == 1)
291 efl_ui_active_view_active_index_set(obj, 0);
292}
293
294EOLIAN static Eina_Bool
295_efl_ui_active_view_container_efl_pack_linear_pack_begin(Eo *obj EINA_UNUSED,
296 Efl_Ui_Active_View_Container_Data *pd,
297 Efl_Gfx_Entity *subobj)
298{
299 if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
300 pd->content_list = eina_list_prepend(pd->content_list, subobj);
301 _update_internals(obj, pd, subobj, 0);
302 return EINA_TRUE;
303}
304
305EOLIAN static Eina_Bool
306_efl_ui_active_view_container_efl_pack_linear_pack_end(Eo *obj EINA_UNUSED,
307 Efl_Ui_Active_View_Container_Data *pd,
308 Efl_Gfx_Entity *subobj)
309{
310 if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
311 pd->content_list = eina_list_append(pd->content_list, subobj);
312 _update_internals(obj, pd, subobj, eina_list_count(pd->content_list) - 1);
313 return EINA_TRUE;
314}
315
316EOLIAN static Eina_Bool
317_efl_ui_active_view_container_efl_pack_linear_pack_before(Eo *obj EINA_UNUSED,
318 Efl_Ui_Active_View_Container_Data *pd,
319 Efl_Gfx_Entity *subobj,
320 const Efl_Gfx_Entity *existing)
321{
322 if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
323 int index = eina_list_data_idx(pd->content_list, (void *)existing);
324 if (index == -1) return EINA_FALSE;
325 pd->content_list = eina_list_prepend_relative(pd->content_list, subobj, existing);
326 _update_internals(obj, pd, subobj, index);
327 return EINA_TRUE;
328}
329
330EOLIAN static Eina_Bool
331_efl_ui_active_view_container_efl_pack_linear_pack_after(Eo *obj EINA_UNUSED,
332 Efl_Ui_Active_View_Container_Data *pd,
333 Efl_Gfx_Entity *subobj,
334 const Efl_Gfx_Entity *existing)
335{
336 if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
337 int index = eina_list_data_idx(pd->content_list, (void *)existing);
338 if (index == -1) return EINA_FALSE;
339 pd->content_list = eina_list_append_relative(pd->content_list, subobj, existing);
340 _update_internals(obj, pd, subobj, index + 1);
341 return EINA_TRUE;
342}
343
344EOLIAN static Eina_Bool
345_efl_ui_active_view_container_efl_pack_linear_pack_at(Eo *obj,
346 Efl_Ui_Active_View_Container_Data *pd,
347 Efl_Gfx_Entity *subobj,
348 int index)
349{
350 Efl_Gfx_Entity *existing = NULL;
351
352 if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
353 int clamp = clamp_index(pd, index);
354 int pass_index = -1;
355 if (clamp == 0)
356 {
357 existing = eina_list_nth(pd->content_list, index_rollover(pd, index));
358 pd->content_list = eina_list_prepend_relative(
359 pd->content_list, subobj, existing);
360 }
361 else if (clamp == 1)
362 {
363 pd->content_list = eina_list_append(pd->content_list, subobj);
364 pass_index = eina_list_count(pd->content_list);
365 }
366 else
367 {
368 pd->content_list = eina_list_prepend(pd->content_list, subobj);
369 pass_index = 0;
370 }
371 _update_internals(obj, pd, subobj, pass_index);
372
373 return EINA_TRUE;
374}
375
376EOLIAN static Efl_Gfx_Entity *
377_efl_ui_active_view_container_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED,
378 Efl_Ui_Active_View_Container_Data *pd,
379 int index)
380{
381 return eina_list_nth(pd->content_list, index_rollover(pd, index));
382}
383
384EOLIAN static int
385_efl_ui_active_view_container_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
386 Efl_Ui_Active_View_Container_Data *pd,
387 const Efl_Gfx_Entity *subobj)
388{
389 return eina_list_data_idx(pd->content_list, (void *)subobj);
390}
391
392EOLIAN static void
393_efl_ui_active_view_container_active_index_set(Eo *obj EINA_UNUSED,
394 Efl_Ui_Active_View_Container_Data *pd,
395 int index)
396{
397 int before;
398
399 if ((index < 0) || (index > ((int)eina_list_count(pd->content_list) - 1)))
400 {
401 ERR("index %d out of range", index);
402 return;
403 }
404
405 before = pd->curr.page;
406 pd->show_request.last_pos = pd->curr.page;
407 pd->show_request.from = pd->curr.page;
408 pd->show_request.to = index;
409
410 if (pd->show_request.active && pd->show_request.from == -1 && pd->show_request.to)
411 pd->show_request.to = index; //we just edit this here, a user animation will end when the progress is at the goal.
412 else
413 {
414 _transition_start(obj, pd, before, index, before);
415 }
416
417 int old_curr_page = pd->curr.page;
418 pd->curr.page = index;
419 efl_ui_active_view_view_manager_switch_to(pd->transition, old_curr_page, pd->curr.page);
420}
421
422EOLIAN static int
423_efl_ui_active_view_container_active_index_get(const Eo *obj EINA_UNUSED,
424 Efl_Ui_Active_View_Container_Data *pd)
425{
426 return pd->curr.page;
427}
428
429EOLIAN Eina_Size2D
430_efl_ui_active_view_container_active_view_size_get(const Eo *obj EINA_UNUSED,
431 Efl_Ui_Active_View_Container_Data *pd)
432{
433 return pd->page_spec.sz;
434}
435
436EOLIAN static void
437_efl_ui_active_view_container_active_view_size_set(Eo *obj,
438 Efl_Ui_Active_View_Container_Data *pd,
439 Eina_Size2D sz)
440{
441 Eina_Size2D size;
442 if (sz.w < -1 || sz.h < -1) return;
443
444 pd->page_spec.sz = sz;
445 pd->fill_width = sz.w == -1 ? EINA_TRUE : EINA_FALSE;
446 pd->fill_height = sz.h == -1 ? EINA_TRUE : EINA_FALSE;
447
448 size = efl_gfx_entity_size_get(obj);
449 if (pd->fill_height)
450 pd->page_spec.sz.h = size.h;
451 if (pd->fill_width)
452 pd->page_spec.sz.w = size.w;
453
454 if (pd->transition)
455 efl_ui_active_view_view_manager_view_size_set(pd->transition, pd->page_spec.sz);
456}
457
458static void
459_unpack_all(Eo *obj EINA_UNUSED,
460 Efl_Ui_Active_View_Container_Data *pd,
461 Eina_Bool clear)
462{
463 pd->curr.page = -1;
464
465 while(pd->content_list)
466 {
467 Eo *content = eina_list_data_get(pd->content_list);
468
469 _unpack(obj, pd, content, 0);
470
471 if (clear)
472 efl_del(content);
473
474 pd->content_list = eina_list_remove(pd->content_list, content);
475 }
476}
477
478EOLIAN static Eina_Bool
479_efl_ui_active_view_container_efl_pack_pack_clear(Eo *obj EINA_UNUSED,
480 Efl_Ui_Active_View_Container_Data *pd)
481{
482 _unpack_all(obj, pd, EINA_TRUE);
483
484 return EINA_TRUE;
485}
486
487EOLIAN static Eina_Bool
488_efl_ui_active_view_container_efl_pack_unpack_all(Eo *obj EINA_UNUSED,
489 Efl_Ui_Active_View_Container_Data *pd)
490{
491 _unpack_all(obj, pd, EINA_FALSE);
492
493 return EINA_TRUE;
494}
495
496static void
497_unpack(Eo *obj,
498 Efl_Ui_Active_View_Container_Data *pd,
499 Efl_Gfx_Entity *subobj,
500 int index)
501{
502 int early_curr_page = pd->curr.page;
503
504 pd->content_list = eina_list_remove(pd->content_list, subobj);
505 _elm_widget_sub_object_redirect_to_top(obj, subobj);
506
507 if (pd->gravity == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT && index < pd->curr.page)
508 pd->curr.page--;
509
510 if (pd->transition)
511 efl_ui_active_view_view_manager_content_del(pd->transition, subobj, index);
512 if (pd->indicator)
513 efl_ui_active_view_indicator_content_del(pd->indicator, subobj, index);
514
515 //we deleted the current index
516 if (pd->gravity == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT && early_curr_page == index)
517 {
518 int new_curr_page = MIN(MAX(early_curr_page, 0), (int)eina_list_count(pd->content_list) - 1);
519 pd->curr.page = -1;
520 if (eina_list_count(pd->content_list) > 0 && efl_alive_get(obj))
521 efl_ui_active_view_active_index_set(obj, new_curr_page);
522 }
523 //position has updated
524 if (early_curr_page != pd->curr.page && early_curr_page != index &&
525 pd->indicator && !pd->transition)
526 efl_ui_active_view_indicator_position_update(pd->indicator, pd->curr.page);
527
528 efl_event_callback_del(subobj, EFL_EVENT_INVALIDATE, _child_inv, obj);
529}
530
531EOLIAN static Eina_Bool
532_efl_ui_active_view_container_efl_pack_unpack(Eo *obj,
533 Efl_Ui_Active_View_Container_Data *pd,
534 Efl_Gfx_Entity *subobj)
535{
536 if (!subobj) return EINA_FALSE;
537
538 int index = eina_list_data_idx(pd->content_list, subobj);
539 if (index == -1)
540 {
541 ERR("Item %p is not part of this container", subobj);
542 return EINA_FALSE;
543 }
544
545 _unpack(obj, pd, subobj, index);
546
547 return EINA_TRUE;
548}
549
550EOLIAN static Efl_Gfx_Entity *
551_efl_ui_active_view_container_efl_pack_linear_pack_unpack_at(Eo *obj,
552 Efl_Ui_Active_View_Container_Data *pd,
553 int index)
554{
555 Efl_Gfx_Entity *subobj = eina_list_nth(pd->content_list, index_rollover(pd, index_rollover(pd, index)));
556
557 _unpack(obj, pd, subobj, index);
558
559 return subobj;
560}
561
562EOLIAN static Eina_Bool
563_efl_ui_active_view_container_efl_pack_pack(Eo *obj, Efl_Ui_Active_View_Container_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
564{
565 return efl_pack_begin(obj, subobj);
566}
567
568EOLIAN static Eina_Iterator*
569_efl_ui_active_view_container_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
570{
571 return eina_list_iterator_new(pd->content_list);
572}
573
574static void
575_pos_updated(void *data, const Efl_Event *event)
576{
577 Efl_Ui_Active_View_Container_Data *pd = efl_data_scope_get(data, MY_CLASS);
578 double progress = *((double*)event->info);
579 //ignore this here, this could result in unintendet transition,start / end calls
580 if (EINA_DBL_EQ(progress, pd->position))
581 return;
582 _position_set(data, pd, progress);
583 _transition_event_emission(data, pd);
584}
585
586EOLIAN static void
587_efl_ui_active_view_container_view_manager_set(Eo *obj, Efl_Ui_Active_View_Container_Data *pd, Efl_Ui_Active_View_View_Manager *transition)
588{
589 if (!transition)
590 pd->transition = efl_add(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS, obj);
591 else
592 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(transition, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_CLASS));
593
594 if (pd->transition)
595 {
596 efl_ui_active_view_view_manager_bind(pd->transition, NULL, NULL);
597 efl_del(pd->transition);
598 }
599
600 pd->transition = transition;
601
602 if (pd->transition)
603 {
604 efl_parent_set(pd->transition, obj);
605 //disable animation when not finalized yet, this help reducing the overhead of scheduling a animation that will not be displayed
606 efl_ui_active_view_view_manager_animation_enabled_set(pd->transition, efl_finalized_get(obj));
607 efl_ui_active_view_view_manager_bind(pd->transition, obj,
608 pd->page_root);
609 efl_ui_active_view_view_manager_view_size_set(pd->transition, pd->page_spec.sz);
610 efl_event_callback_add(pd->transition, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, _pos_updated, obj);
611 }
612
613}
614
615EOLIAN static Efl_Ui_Active_View_View_Manager*
616_efl_ui_active_view_container_view_manager_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
617{
618 if (efl_isa(pd->transition, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS))
619 return NULL;
620 else
621 return pd->transition;
622}
623
624EOLIAN static void
625_efl_ui_active_view_container_indicator_set(Eo *obj, Efl_Ui_Active_View_Container_Data *pd, Efl_Ui_Active_View_Indicator *indicator)
626{
627 if (pd->indicator)
628 {
629 efl_ui_active_view_indicator_bind(pd->indicator, obj);
630 efl_del(pd->indicator);
631 }
632 pd->indicator = indicator;
633 if (pd->indicator)
634 {
635 efl_ui_active_view_indicator_bind(pd->indicator, obj);
636 if (pd->position != -1)
637 efl_ui_active_view_indicator_position_update(pd->indicator, pd->position);
638 }
639}
640
641EOLIAN static Efl_Ui_Active_View_Indicator*
642_efl_ui_active_view_container_indicator_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
643{
644 return pd->indicator;
645}
646
647#include "efl_ui_active_view_container.eo.c"
diff --git a/src/lib/elementary/efl_ui_active_view_container.eo b/src/lib/elementary/efl_ui_active_view_container.eo
new file mode 100644
index 0000000000..db51332cf0
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_container.eo
@@ -0,0 +1,79 @@
1struct @beta Efl.Ui.Active_View.Transition_Event {
2 from : int; [[The id from where the transition started, -1 if not known]]
3 to : int; [[The id from where the transition started, -1 if not known]]
4}
5
6enum Efl.Ui.Active_View.Container_Gravity {
7 content = 0, [[In case the internal list of content is changed, then the $active_index will always point to the same content]]
8 index = 1, [[In case the internal list of content is changed, then the $active_index will keep its value]]
9}
10
11class @beta Efl.Ui.Active_View.Container extends Efl.Ui.Layout_Base implements Efl.Pack_Linear
12{
13 [[ The active view widget can be used to display the added content in some animated way. The details of the animation and way of displaying depends on the transition object.
14 The size of the displayed content can be controlled via $active_view_size. The content with the main attraction can be setted with $active_index.
15
16 Without a transition object this widget will just display the content with the id set with $active_index. On page changes,
17 ]]
18 c_prefix: efl_ui_active_view;
19 methods {
20 @property view_manager {
21 [[The transition object which defines the animation and exact position of the content]]
22 values {
23 transition : Efl.Ui.Active_View.View_Manager @owned;
24 }
25 }
26 @property indicator {
27 [[A indicator object which can be used to display the state and position of the content in this widget
28 When this object here is set, the position of the indicator object is immidiatly called to the current position of the widget
29 ]]
30 values {
31 indicator : Efl.Ui.Active_View.Indicator @owned;
32 }
33 }
34 @property active_index {
35 [[Selects which is the maincontent to display by this widget. The exact positioning depends on the $transition object]]
36 values {
37 index: int;
38 }
39 }
40 @property active_view_gravity {
41 [[active_view can be used to set the currently active viewed content.
42
43 This property can be used to switch_to the semantic of the function. If gravity is content, then newly added content will change the index, but keep the content. If the gravity is set to index, then the index will stay when new content is added, which might show new content.
44 ]]
45 values {
46 gravity : Efl.Ui.Active_View.Container_Gravity;
47 }
48 }
49 @property active_view_size {
50 [[The size that is give to each content when displayed]]
51 values {
52 size: Eina.Size2D;
53 }
54 }
55 }
56 events {
57 transition,start : Efl.Ui.Active_View.Transition_Event;
58 transition,end : Efl.Ui.Active_View.Transition_Event;
59 }
60 implements {
61 Efl.Object.constructor;
62 Efl.Object.finalize;
63 Efl.Object.invalidate;
64 Efl.Container.content_count;
65 Efl.Container.content_iterate;
66 Efl.Pack.pack_clear;
67 Efl.Pack.unpack_all;
68 Efl.Pack.unpack;
69 Efl.Pack.pack;
70 Efl.Pack_Linear.pack_begin;
71 Efl.Pack_Linear.pack_end;
72 Efl.Pack_Linear.pack_before;
73 Efl.Pack_Linear.pack_after;
74 Efl.Pack_Linear.pack_at;
75 Efl.Pack_Linear.pack_content_get;
76 Efl.Pack_Linear.pack_index_get;
77 Efl.Pack_Linear.pack_unpack_at;
78 }
79}
diff --git a/src/lib/elementary/efl_ui_active_view_indicator.c b/src/lib/elementary/efl_ui_active_view_indicator.c
new file mode 100644
index 0000000000..3d227f4d16
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_indicator.c
@@ -0,0 +1,15 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_PACK_LAYOUT_PROTECTED
6
7#include <Elementary.h>
8#include "elm_priv.h"
9
10typedef struct {
11
12} Efl_Ui_Active_View_Indicator_Data;
13
14
15#include "efl_ui_active_view_indicator.eo.c"
diff --git a/src/lib/elementary/efl_ui_active_view_indicator.eo b/src/lib/elementary/efl_ui_active_view_indicator.eo
new file mode 100644
index 0000000000..053b56ab3f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_indicator.eo
@@ -0,0 +1,49 @@
1abstract @beta Efl.Ui.Active_View.Indicator extends Efl.Object {
2 [[Indicator object that is used by @Efl.Ui.Active_View.Container]]
3 methods {
4 bind @pure_virtual {
5 [[Initial call to flush the required objects of the active view to the transition object
6
7 This call can be used to setup the indicator part of $active_view.
8
9 if there is a position of the widget, then after this call, $position_update will be called.
10 ]]
11 params {
12 active_view : Efl.Ui.Active_View.Container;
13 }
14 }
15 content_add @pure_virtual {
16 [[Content has been added to the container passed in .bind. The $subobj is at position $index.
17
18 While in the call, the $current_page property of the active_view might change.
19 If such a change is happening. No animation should be displayed, and the new state should be applied.
20 ]]
21 params {
22 subobj : Efl.Gfx.Entity;
23 index : int;
24 }
25 }
26 content_del @pure_virtual {
27 [[Content has been removed from the container passed in .bind. The $subobj at position $index is now removed.
28
29 While in the call, the $current_page property of the active_view might change.
30 If such a change is happening. No animation should be displayed, and the new state should be applied.
31 ]]
32 params {
33 subobj : Efl.Gfx.Entity;
34 index : int;
35 }
36 }
37 position_update @pure_virtual {
38 [[The position between the content has been changed.
39
40 The position is absolut and ranges from [-1,x + 1] where x is the number of contents in the active_view.
41
42 Values between two actaul positions must be expected as this is the way the animation of the transition object populates to the indicator
43 ]]
44 params {
45 position : double; [[The position the transition object is currently in]]
46 }
47 }
48 }
49}
diff --git a/src/lib/elementary/efl_ui_active_view_indicator_icon.c b/src/lib/elementary/efl_ui_active_view_indicator_icon.c
new file mode 100644
index 0000000000..15fa6250e3
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_indicator_icon.c
@@ -0,0 +1,114 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_PACK_LAYOUT_PROTECTED
6
7#include <Elementary.h>
8#include "elm_priv.h"
9
10typedef struct {
11 Efl_Ui_Box *indicator;
12 Efl_Ui_Active_View_Container *container;
13 double last_position;
14} Efl_Ui_Active_View_Indicator_Icon_Data;
15
16static void
17_flush_state(Eo *item, double val)
18{
19 Eina_Value v = eina_value_double_init(val);
20
21 efl_layout_signal_message_send(item, 1, v);
22}
23
24static void
25_add_item(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Indicator_Icon_Data *pd)
26{
27 Efl_Canvas_Layout *item;
28
29 item = efl_add(EFL_CANVAS_LAYOUT_CLASS, pd->indicator);
30 elm_widget_theme_object_set(pd->indicator, item,
31 "pager", "indicator", "default");
32 efl_gfx_hint_align_set(item, 0.5, 0.5);
33 efl_gfx_hint_weight_set(item, 0, 0);
34 efl_gfx_hint_fill_set(item, 0, 0);
35 efl_pack_end(pd->indicator, item);
36 _flush_state(item, 0.0);
37}
38
39static void
40_flush_position(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Indicator_Icon_Data *pd)
41{
42 int next = -1, closer;
43 double closer_val;
44
45 for (int i = 0; i < efl_content_count(pd->indicator); ++i)
46 {
47 _flush_state(efl_pack_content_get(pd->indicator, i), 0.0f);
48 }
49
50 closer = MIN(MAX(round(pd->last_position), 0), efl_content_count(pd->container) - 1);
51 closer_val = fabs(1.0f - fabs(closer - pd->last_position));
52
53 _flush_state(efl_pack_content_get(pd->indicator, closer), closer_val);
54
55 if (pd->last_position > closer)
56 next = closer + 1;
57 else if (pd->last_position < closer)
58 next = closer - 1;
59 else
60 {
61 next = closer + 1;
62 if (next < efl_content_count(pd->container))
63 _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
64 next = closer - 1;
65 if (next >= 0)
66 _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
67 }
68
69 if (next >= 0 && next < efl_content_count(pd->container))
70 _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
71}
72
73EOLIAN static void
74_efl_ui_active_view_indicator_icon_efl_ui_active_view_indicator_bind(Eo *obj, Efl_Ui_Active_View_Indicator_Icon_Data *pd, Efl_Ui_Active_View_Container *active_view)
75{
76 if (active_view)
77 {
78 pd->container = active_view;
79 pd->indicator = efl_add(EFL_UI_BOX_CLASS, active_view);
80 efl_ui_widget_internal_set(pd->indicator, EINA_TRUE);
81 efl_content_set(efl_part(pd->container, "efl.indicator"), pd->indicator);
82 efl_gfx_entity_visible_set(pd->indicator, EINA_TRUE);
83 efl_ui_layout_orientation_set(pd->indicator, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL);
84 efl_gfx_arrangement_content_padding_set(pd->indicator, 15, 15, EINA_TRUE);
85
86 for (int i = 0; i < efl_content_count(pd->container); ++i)
87 {
88 _add_item(obj, pd);
89 }
90 }
91}
92
93EOLIAN static void
94_efl_ui_active_view_indicator_icon_efl_ui_active_view_indicator_content_add(Eo *obj, Efl_Ui_Active_View_Indicator_Icon_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index EINA_UNUSED)
95{
96 _add_item(obj, pd);
97 _flush_position(obj, pd);
98}
99
100EOLIAN static void
101_efl_ui_active_view_indicator_icon_efl_ui_active_view_indicator_content_del(Eo *obj, Efl_Ui_Active_View_Indicator_Icon_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index EINA_UNUSED)
102{
103 efl_del(efl_pack_content_get(pd->indicator, 0));
104 _flush_position(obj, pd);
105}
106
107EOLIAN static void
108_efl_ui_active_view_indicator_icon_efl_ui_active_view_indicator_position_update(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Indicator_Icon_Data *pd, double position)
109{
110 pd->last_position = position;
111 _flush_position(obj, pd);
112}
113
114#include "efl_ui_active_view_indicator_icon.eo.c"
diff --git a/src/lib/elementary/efl_ui_active_view_indicator_icon.eo b/src/lib/elementary/efl_ui_active_view_indicator_icon.eo
new file mode 100644
index 0000000000..02d89cddcc
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_indicator_icon.eo
@@ -0,0 +1,8 @@
1class @beta Efl.Ui.Active_View.Indicator_Icon extends Efl.Ui.Active_View.Indicator {
2 implements {
3 Efl.Ui.Active_View.Indicator.bind;
4 Efl.Ui.Active_View.Indicator.content_del;
5 Efl.Ui.Active_View.Indicator.content_add;
6 Efl.Ui.Active_View.Indicator.position_update;
7 }
8}
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager.c b/src/lib/elementary/efl_ui_active_view_view_manager.c
new file mode 100644
index 0000000000..e66cd136a4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager.c
@@ -0,0 +1,15 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_PACK_LAYOUT_PROTECTED
6
7#include <Elementary.h>
8#include "elm_priv.h"
9
10typedef struct {
11
12} Efl_Ui_Active_View_View_Manager_Data;
13
14
15#include "efl_ui_active_view_view_manager.eo.c"
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager.eo b/src/lib/elementary/efl_ui_active_view_view_manager.eo
new file mode 100644
index 0000000000..a97fc4078f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager.eo
@@ -0,0 +1,65 @@
1abstract @beta Efl.Ui.Active_View.View_Manager extends Efl.Object {
2 [[Transition object which is used by active_view.
3
4 The transition object can display changes to the active view with animations.
5 This object can also implement behavior user interaction in a animation manner. For example: Mouse dragging content, to get to a new $current_page. If this is the case, such a user interaction should terminate with a call to $current_page. The position of the content should be exposed by emitting pos_update.
6 ]]
7 methods {
8 bind @pure_virtual {
9 [[Initial call to flush the required objects of the active view to the transition object]]
10 params {
11 active_view : Efl.Ui.Active_View.Container;
12 group : Efl.Canvas.Group;
13 }
14 }
15 content_add @pure_virtual {
16 [[Content has been added to the container passed in .bind. The $subobj is at position $index.
17
18 While in the call, the $current_page property of the active_view might change.
19 If such a change is happening. No animation should be displayed, and the new state should be applied.
20 ]]
21 params {
22 subobj : Efl.Gfx.Entity;
23 index : int;
24 }
25 }
26 content_del @pure_virtual {
27 [[Content has been removed from the container passed in .bind. The $subobj at position $index is now removed.
28
29 While in the call, the $current_page property of the active_view might change.
30 If such a change is happening. No animation should be displayed, and the new state should be applied.
31 ]]
32 params {
33 subobj : Efl.Gfx.Entity;
34 index : int;
35 }
36 }
37 switch_to @pure_virtual {
38 [[Switch from one side to another, if there has been no side before, from is -1.
39 This function should, if the transition object supports this, display a animation.
40 ]]
41 params {
42 from : int;
43 to : int;
44 }
45 }
46 @property view_size @pure_virtual {
47 [[Will be called whenever the page size changes]]
48 set {
49
50 }
51 values {
52 size : Eina.Size2D; [[The size of the page, real coordiates at any time]]
53 }
54 }
55 @property animation_enabled @pure_virtual {
56 [[This flag can be used to indicate that no animations should be done]]
57 values {
58 enable : bool; [[$true if you want animations to happen, $false if otherwise]]
59 }
60 }
61 }
62 events {
63 pos_update : double; [[The absolut position where the state of the content currently is. So if there is a animation from 2 to 3 the event will go from 2.0 to 3.0. If there is a $switch_to from 2 to 3, then this event should go in one direction from 2 to 3. Not following this, will result in a event to abort the transition, and instanciating a new one.]]
64 }
65}
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager_plain.c b/src/lib/elementary/efl_ui_active_view_view_manager_plain.c
new file mode 100644
index 0000000000..32c530d827
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager_plain.c
@@ -0,0 +1,166 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Efl_Ui.h>
6#include "elm_priv.h"
7#include "efl_ui_active_view_view_manager_plain.eo.h"
8
9typedef struct {
10 Efl_Ui_Active_View_Container * container;
11 Efl_Gfx_Entity *group;
12 Eina_Size2D page_size;
13 int current_content;
14 Eina_Bool animation;
15} Efl_Ui_Active_View_View_Manager_Plain_Data;
16
17#define MY_CLASS EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS
18
19static void
20_emit_position(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Plain_Data *pd)
21{
22 double absolut_position = pd->current_content;
23 efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &absolut_position);
24}
25
26static void
27_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Plain_Data *pd)
28{
29 Efl_Gfx_Entity *entity = efl_pack_content_get(pd->container, pd->current_content);
30 Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->group);
31 Eina_Rect goal = EINA_RECT_EMPTY();
32
33 goal.size = pd->page_size;
34 goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
35 goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
36 efl_gfx_entity_geometry_set(entity, goal);
37}
38
39static void
40_resize_cb(void *data, const Efl_Event *ev EINA_UNUSED)
41{
42 _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
43}
44
45static void
46_move_cb(void *data, const Efl_Event *ev EINA_UNUSED)
47{
48 _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
49}
50
51EFL_CALLBACKS_ARRAY_DEFINE(group_callback,
52 {EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb},
53 {EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb},
54)
55
56EOLIAN static void
57_efl_ui_active_view_view_manager_plain_efl_ui_active_view_view_manager_bind(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd, Efl_Ui_Active_View_Container *active_view, Efl_Canvas_Group *group)
58{
59 if (active_view && group)
60 {
61 int index;
62
63 pd->container = active_view;
64 pd->group = group;
65
66 efl_event_callback_array_add(pd->group, group_callback(), obj);
67
68 for (int i = 0; i < efl_content_count(active_view) ; ++i) {
69 Efl_Gfx_Entity *elem = efl_pack_content_get(active_view, i);
70 efl_canvas_group_member_add(pd->group, elem);
71 efl_gfx_entity_visible_set(elem, EINA_FALSE);
72 }
73 index = efl_ui_active_view_active_index_get(active_view);
74 if (index != -1)
75 {
76 pd->current_content = index;
77 efl_gfx_entity_visible_set(efl_pack_content_get(pd->container, pd->current_content), EINA_TRUE);
78 _geom_sync(obj, pd);
79 _emit_position(obj, pd);
80 }
81 }
82}
83
84static void
85_content_changed(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd)
86{
87 if (efl_ui_active_view_active_index_get(pd->container) != pd->current_content)
88 {
89 pd->current_content = efl_ui_active_view_active_index_get(pd->container);
90 efl_gfx_entity_visible_set(efl_pack_content_get(pd->container, pd->current_content), EINA_FALSE);
91 _geom_sync(obj, pd);
92 _emit_position(obj, pd);
93 }
94}
95
96EOLIAN static void
97_efl_ui_active_view_view_manager_plain_efl_ui_active_view_view_manager_content_add(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
98{
99 efl_canvas_group_member_add(pd->group, subobj);
100 efl_gfx_entity_visible_set(subobj, EINA_FALSE);
101 _content_changed(obj, pd);
102}
103
104EOLIAN static void
105_efl_ui_active_view_view_manager_plain_efl_ui_active_view_view_manager_content_del(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
106{
107 efl_canvas_group_member_remove(pd->group, subobj);
108 _content_changed(obj, pd);
109}
110EOLIAN static void
111_efl_ui_active_view_view_manager_plain_efl_ui_active_view_view_manager_switch_to(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd, int from EINA_UNUSED, int to)
112{
113 Efl_Gfx_Entity *to_obj, *from_obj;
114 to_obj = efl_pack_content_get(pd->container, to);
115 from_obj = efl_pack_content_get(pd->container, from);
116 if (from_obj)
117 {
118 efl_gfx_entity_visible_set(from_obj, EINA_FALSE);
119 pd->current_content = -1;
120 }
121
122 if (to_obj)
123 {
124 efl_gfx_entity_visible_set(to_obj, EINA_TRUE);
125 pd->current_content = to;
126 }
127
128 _emit_position(obj, pd);
129 _geom_sync(obj, pd);
130}
131
132EOLIAN static void
133_efl_ui_active_view_view_manager_plain_efl_ui_active_view_view_manager_view_size_set(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd, Eina_Size2D size)
134{
135 pd->page_size = size;
136 _geom_sync(obj, pd);
137}
138
139EOLIAN static void
140_efl_ui_active_view_view_manager_plain_efl_object_destructor(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd EINA_UNUSED)
141{
142 efl_destructor(efl_super(obj, MY_CLASS));
143
144 efl_event_callback_array_del(pd->group, group_callback(), obj);
145
146 for (int i = 0; i < efl_content_count(pd->container); ++i)
147 {
148 Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
149 efl_gfx_entity_visible_set(elem, EINA_TRUE);
150 }
151}
152
153EOLIAN static void
154_efl_ui_active_view_view_manager_plain_efl_ui_active_view_view_manager_animation_enabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Plain_Data *pd, Eina_Bool animation)
155{
156 pd->animation = animation;
157}
158
159EOLIAN static Eina_Bool
160_efl_ui_active_view_view_manager_plain_efl_ui_active_view_view_manager_animation_enabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Plain_Data *pd)
161{
162 return pd->animation;
163}
164
165
166#include "efl_ui_active_view_view_manager_plain.eo.c"
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager_plain.eo b/src/lib/elementary/efl_ui_active_view_view_manager_plain.eo
new file mode 100644
index 0000000000..6c99a3d29a
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager_plain.eo
@@ -0,0 +1,12 @@
1class @beta Efl.Ui.Active_View.View_Manager_Plain extends Efl.Ui.Active_View.View_Manager
2{
3 implements {
4 Efl.Ui.Active_View.View_Manager.bind;
5 Efl.Ui.Active_View.View_Manager.content_add;
6 Efl.Ui.Active_View.View_Manager.content_del;
7 Efl.Ui.Active_View.View_Manager.switch_to;
8 Efl.Ui.Active_View.View_Manager.view_size {set;}
9 Efl.Ui.Active_View.View_Manager.animation_enabled {set; get;}
10 Efl.Object.destructor;
11 }
12}
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager_scroll.c b/src/lib/elementary/efl_ui_active_view_view_manager_scroll.c
new file mode 100644
index 0000000000..ff185a6586
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager_scroll.c
@@ -0,0 +1,316 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Efl_Ui.h>
6#include "elm_priv.h"
7
8typedef struct {
9 Efl_Ui_Active_View_Container * container;
10 Efl_Gfx_Entity *group, *foreclip, *backclip;
11 Eina_Size2D page_size;
12 struct {
13 Eina_Bool active;
14 int to;
15 double from, progress;
16 double start_time;
17 double max_time;
18 } transition;
19 struct {
20 Eina_Bool active;
21 int from;
22 Eina_Position2D mouse_start;
23 } mouse_move;
24 Eina_Bool animation;
25} Efl_Ui_Active_View_View_Manager_Scroll_Data;
26
27#define MY_CLASS EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS
28
29static void _page_set_animation(void *data, const Efl_Event *event);
30
31static void
32_propagate_progress(Eo *obj, double pos)
33{
34 efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &pos);
35}
36
37static void
38_apply_box_properties(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd)
39{
40 Eina_Rect geometry = EINA_RECT_EMPTY();
41 Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->group);
42 double current_pos;
43
44 if (pd->transition.active)
45 current_pos = pd->transition.from + ((double)pd->transition.to - pd->transition.from)*pd->transition.progress;
46 else
47 current_pos = efl_ui_active_view_active_index_get(pd->container);
48
49 efl_gfx_entity_geometry_set(pd->foreclip, group_pos);
50 //first calculate the size
51 geometry.h = pd->page_size.h;
52 geometry.w = (pd->page_size.w);
53
54 //calculate the position
55 geometry.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
56
57 for (int i = 0; i < efl_content_count(pd->container) ; ++i)
58 {
59 double diff = i - current_pos;
60 Efl_Gfx_Entity *elem = efl_pack_content_get(pd->container, i);
61
62 geometry.x = (group_pos.x + group_pos.w/2)-(pd->page_size.w/2 - diff*pd->page_size.w);
63 if (!eina_rectangles_intersect(&geometry.rect, &group_pos.rect))
64 {
65 efl_canvas_object_clipper_set(elem, pd->backclip);
66 }
67 else
68 {
69 efl_gfx_entity_geometry_set(elem, geometry);
70 efl_canvas_object_clipper_set(elem, pd->foreclip);
71 }
72 }
73
74 //Propagate progress
75 _propagate_progress(obj, current_pos);
76}
77
78static void
79_resize_cb(void *data, const Efl_Event *ev EINA_UNUSED)
80{
81 _apply_box_properties(data, efl_data_scope_get(data, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS));
82}
83
84static void
85_move_cb(void *data, const Efl_Event *ev EINA_UNUSED)
86{
87 _apply_box_properties(data, efl_data_scope_get(data, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS));
88}
89
90static void
91_mouse_down_cb(void *data,
92 const Efl_Event *event)
93{
94 Efl_Input_Pointer *ev = event->info;
95 Eo *obj = data;
96 Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(obj, MY_CLASS);
97
98 if (efl_input_pointer_button_get(ev) != 1) return;
99 if (efl_input_event_flags_get(ev) & EFL_INPUT_FLAGS_PROCESSED) return;
100
101 if (efl_content_count(pd->container) == 0) return;
102
103 efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
104
105 pd->mouse_move.active = EINA_TRUE;
106 pd->mouse_move.from = efl_ui_active_view_active_index_get(pd->container);
107 pd->mouse_move.mouse_start = efl_input_pointer_position_get(ev);
108}
109
110static void
111_mouse_move_cb(void *data,
112 const Efl_Event *event)
113{
114 Efl_Input_Pointer *ev = event->info;
115 Eo *obj = data;
116 Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(obj, MY_CLASS);
117 Eina_Position2D pos;
118 int pos_y_diff;
119
120 if (efl_input_event_flags_get(ev) & EFL_INPUT_FLAGS_PROCESSED) return;
121 if (!pd->mouse_move.active) return;
122
123 pos = efl_input_pointer_position_get(ev);
124 pos_y_diff = pd->mouse_move.mouse_start.x - pos.x;
125
126 pd->transition.active = EINA_TRUE;
127 pd->transition.from = pd->mouse_move.from;
128 pd->transition.progress = (double)pos_y_diff / (double)pd->page_size.w;
129 pd->transition.to = pd->transition.from + 1;
130
131 _propagate_progress(data, pd->transition.from + pd->transition.progress);
132
133 _apply_box_properties(obj, pd);
134}
135
136static void
137_mouse_up_cb(void *data,
138 const Efl_Event *event)
139{
140 Efl_Input_Pointer *ev = event->info;
141 Eo *obj = data;
142 Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(obj, MY_CLASS);
143
144 if (efl_input_event_flags_get(ev) & EFL_INPUT_FLAGS_PROCESSED) return;
145 if (!pd->mouse_move.active) return;
146
147 double absolut_current_position = (double)pd->transition.from + pd->transition.progress;
148 int result = round(absolut_current_position);
149
150 efl_ui_active_view_active_index_set(pd->container, MIN(MAX(result, 0), efl_content_count(pd->container) - 1));
151}
152
153EFL_CALLBACKS_ARRAY_DEFINE(mouse_listeners,
154 {EFL_EVENT_POINTER_DOWN, _mouse_down_cb},
155 {EFL_EVENT_POINTER_UP, _mouse_up_cb},
156 {EFL_EVENT_POINTER_MOVE, _mouse_move_cb},
157);
158
159EOLIAN static void
160_efl_ui_active_view_view_manager_scroll_efl_ui_active_view_view_manager_bind(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, Efl_Ui_Active_View_Container *active_view, Efl_Canvas_Group *group)
161{
162 if (active_view && group)
163 {
164 pd->container = active_view;
165 pd->group = group;
166 efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
167 efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
168
169 pd->foreclip = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
170 evas_object_evas_get(group));
171 evas_object_static_clip_set(pd->foreclip, EINA_TRUE);
172
173 pd->backclip = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
174 evas_object_evas_get(group));
175 evas_object_static_clip_set(pd->backclip, EINA_TRUE);
176 efl_gfx_entity_visible_set(pd->backclip, EINA_FALSE);
177
178 for (int i = 0; i < efl_content_count(active_view) ; ++i) {
179 Efl_Gfx_Entity *elem = efl_pack_content_get(active_view, i);
180 efl_canvas_object_clipper_set(elem, pd->backclip);
181 efl_canvas_group_member_add(pd->group, elem);
182 efl_gfx_entity_visible_set(elem, EINA_TRUE);
183 }
184 _apply_box_properties(obj, pd);
185
186 efl_event_callback_array_add(efl_content_get(efl_part(pd->container, "efl.event")), mouse_listeners(), obj);
187 }
188
189}
190
191EOLIAN static void
192_efl_ui_active_view_view_manager_scroll_efl_ui_active_view_view_manager_content_add(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
193{
194 efl_gfx_entity_visible_set(subobj, EINA_TRUE);
195 efl_canvas_object_clipper_set(subobj, pd->backclip);
196 efl_canvas_group_member_add(pd->group, subobj);
197
198 if (!pd->transition.active)
199 _apply_box_properties(obj, pd);
200}
201
202
203EOLIAN static void
204_efl_ui_active_view_view_manager_scroll_efl_ui_active_view_view_manager_content_del(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
205{
206 efl_canvas_object_clipper_set(subobj, NULL);
207 efl_canvas_group_member_remove(pd->group, subobj);
208
209 if (!pd->transition.active)
210 _apply_box_properties(obj, pd);
211}
212
213static void
214_page_set_animation(void *data, const Efl_Event *event EINA_UNUSED)
215{
216 Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(data, MY_CLASS);
217 double p = (ecore_loop_time_get() - pd->transition.start_time) / pd->transition.max_time;
218
219 if (p >= 1.0) p = 1.0;
220 p = ecore_animator_pos_map(p, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
221
222 pd->transition.progress = p;
223
224 if (EINA_DBL_EQ(p, 1.0))
225 {
226 efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK,
227 _page_set_animation, data);
228 pd->transition.active = EINA_FALSE;
229 }
230 _apply_box_properties(data, pd);
231}
232
233static void
234_animation_request_switch(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, int from, int to)
235{
236 efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
237 //if there is a ongoing transition, try to guess a better time, and try copy over the position where we are right now
238 if (pd->transition.active || pd->mouse_move.active)
239 {
240 pd->transition.from = MIN(pd->transition.from, pd->transition.to) + pd->transition.progress;
241 pd->transition.max_time = MIN(MAX(fabs(pd->transition.progress), 0.2), 0.5f);
242 pd->mouse_move.active = EINA_FALSE;
243 pd->transition.progress = 0.0f;
244 }
245 else
246 {
247 pd->transition.from = from;
248 pd->transition.max_time = 0.5;
249 }
250 pd->transition.start_time = ecore_loop_time_get();
251 pd->transition.active = EINA_TRUE;
252 pd->transition.to = to;
253 efl_event_callback_add(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
254}
255
256EOLIAN static void
257_efl_ui_active_view_view_manager_scroll_efl_ui_active_view_view_manager_switch_to(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, int from, int to)
258{
259 if (pd->animation)
260 {
261 _animation_request_switch(obj, pd, from, to);
262 }
263 else
264 {
265 pd->mouse_move.active = EINA_FALSE;
266 pd->transition.active = EINA_FALSE;
267 _apply_box_properties(obj, pd);
268 }
269}
270
271EOLIAN static void
272_efl_ui_active_view_view_manager_scroll_efl_ui_active_view_view_manager_view_size_set(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, Eina_Size2D size)
273{
274 pd->page_size = size;
275 if (!pd->transition.active)
276 _apply_box_properties(obj, pd);
277}
278
279EOLIAN static void
280_efl_ui_active_view_view_manager_scroll_efl_ui_active_view_view_manager_animation_enabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, Eina_Bool animation)
281{
282 pd->animation = animation;
283 if (pd->transition.active && !animation)
284 {
285 efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
286 _apply_box_properties(obj, pd);
287 pd->transition.active = EINA_FALSE;
288 }
289}
290
291EOLIAN static Eina_Bool
292_efl_ui_active_view_view_manager_scroll_efl_ui_active_view_view_manager_animation_enabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd)
293{
294 return pd->animation;
295}
296
297
298EOLIAN static void
299_efl_ui_active_view_view_manager_scroll_efl_object_destructor(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd EINA_UNUSED)
300{
301 efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
302 efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
303 efl_event_callback_array_del(efl_content_get(efl_part(pd->container, "efl.event")), mouse_listeners(), obj);
304 efl_del(pd->backclip);
305 efl_del(pd->foreclip);
306
307 for (int i = 0; i < efl_content_count(pd->container); ++i)
308 {
309 efl_canvas_object_clipper_set(efl_pack_content_get(pd->container, i), NULL);
310 }
311
312 efl_destructor(efl_super(obj, MY_CLASS));
313}
314
315
316#include "efl_ui_active_view_view_manager_scroll.eo.c"
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager_scroll.eo b/src/lib/elementary/efl_ui_active_view_view_manager_scroll.eo
new file mode 100644
index 0000000000..cf90d11349
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager_scroll.eo
@@ -0,0 +1,12 @@
1class @beta Efl.Ui.Active_View.View_Manager_Scroll extends Efl.Ui.Active_View.View_Manager
2{
3 implements {
4 Efl.Ui.Active_View.View_Manager.bind;
5 Efl.Ui.Active_View.View_Manager.content_add;
6 Efl.Ui.Active_View.View_Manager.content_del;
7 Efl.Ui.Active_View.View_Manager.switch_to;
8 Efl.Ui.Active_View.View_Manager.view_size {set;}
9 Efl.Ui.Active_View.View_Manager.animation_enabled {set; get;}
10 Efl.Object.destructor;
11 }
12}
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager_stack.c b/src/lib/elementary/efl_ui_active_view_view_manager_stack.c
new file mode 100644
index 0000000000..65e8790d1f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager_stack.c
@@ -0,0 +1,265 @@
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_Active_View_Container * container;
11 Efl_Gfx_Entity *group;
12 Efl_Canvas_Animation_Player *hide, *show;
13 int from, to;
14 Efl_Gfx_Entity *content;
15 Eina_Size2D page_size;
16 Eina_Bool animation;
17} Efl_Ui_Active_View_View_Manager_Stack_Data;
18
19#define MY_CLASS EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_STACK_CLASS
20
21static void
22_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Stack_Data *pd)
23{
24 Eina_Array *array = eina_array_new(2);
25 Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->group);
26 if (efl_player_play_get(pd->hide))
27 {
28 //we are currently in animation, sync the geometry of the targets
29 eina_array_push(array, efl_animation_player_target_get(pd->hide));
30 eina_array_push(array, efl_animation_player_target_get(pd->show));
31 }
32 else
33 {
34 //we only have our content right now, or nothing
35 eina_array_push(array, pd->content);
36 }
37 Eina_Rect goal = EINA_RECT_EMPTY();
38 goal.size = pd->page_size;
39 goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
40 goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
41 while (eina_array_count(array) > 0)
42 {
43 Efl_Gfx_Entity *subobj = eina_array_pop(array);
44 efl_gfx_entity_geometry_set(subobj, goal);
45 }
46 eina_array_free(array);
47}
48
49static void
50_resize_cb(void *data, const Efl_Event *ev EINA_UNUSED)
51{
52 _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
53}
54
55static void
56_move_cb(void *data, const Efl_Event *ev EINA_UNUSED)
57{
58 _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
59}
60
61static void
62_running_cb(void *data, const Efl_Event *ev EINA_UNUSED)
63{
64 Efl_Ui_Active_View_View_Manager_Stack_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
65
66 //calculate absolut position, multiply pos with 2.0 because duration is only 0.5)
67 double absolut_position = pd->from + (pd->to - pd->from)*(efl_player_pos_get(pd->show)*2.0);
68 efl_event_callback_call(data, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &absolut_position);
69}
70
71static void
72_anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event)
73{
74 Efl_Canvas_Object *content;
75
76 content = efl_animation_player_target_get(event->object);
77 efl_gfx_entity_visible_set(content, EINA_TRUE);
78}
79
80static void
81_hide_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
82{
83 Efl_Ui_Active_View_View_Manager_Stack_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
84 Efl_Canvas_Object *content;
85
86 EINA_SAFETY_ON_NULL_RETURN(pd);
87 content = efl_animation_player_target_get(pd->hide);
88 efl_gfx_entity_visible_set(content, EINA_FALSE);
89}
90
91static void
92_show_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
93{
94 Efl_Ui_Active_View_View_Manager_Stack_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
95 Efl_Canvas_Object *content;
96
97 EINA_SAFETY_ON_NULL_RETURN(pd);
98 content = efl_animation_player_target_get(pd->show);
99 efl_gfx_entity_visible_set(content, EINA_TRUE);
100 pd->content = content;
101}
102
103EFL_CALLBACKS_ARRAY_DEFINE(_anim_show_event_cb,
104 {EFL_ANIMATION_PLAYER_EVENT_RUNNING, _running_cb},
105 {EFL_ANIMATION_PLAYER_EVENT_STARTED, _anim_started_cb},
106 {EFL_ANIMATION_PLAYER_EVENT_ENDED, _show_anim_ended_cb},
107)
108
109EFL_CALLBACKS_ARRAY_DEFINE(_anim_hide_event_cb,
110 {EFL_ANIMATION_PLAYER_EVENT_STARTED, _anim_started_cb},
111 {EFL_ANIMATION_PLAYER_EVENT_ENDED, _hide_anim_ended_cb},
112)
113
114EOLIAN static void
115_efl_ui_active_view_view_manager_stack_efl_ui_active_view_view_manager_bind(Eo *obj, Efl_Ui_Active_View_View_Manager_Stack_Data *pd, Efl_Ui_Active_View_Container *active_view, Efl_Canvas_Group *group)
116{
117 if (active_view && group)
118 {
119 Efl_Canvas_Animation_Alpha *show_anim, *hide_anim;
120 pd->container = active_view;
121 pd->group = group;
122
123 efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
124 efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
125
126 show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj);
127 efl_animation_alpha_set(show_anim, 0.0, 1.0);
128 efl_animation_duration_set(show_anim, 0.5);
129 efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
130
131 pd->show = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj);
132 efl_animation_player_animation_set(pd->show, show_anim);
133 efl_player_play_set(pd->show, EINA_FALSE);
134 efl_event_callback_array_add(pd->show, _anim_show_event_cb(), obj);
135
136 //Default Hide Animation
137 hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj);
138 efl_animation_alpha_set(hide_anim, 1.0, 0.0);
139 efl_animation_duration_set(hide_anim, 0.5);
140 efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
141
142 pd->hide = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj);
143 efl_animation_player_animation_set(pd->hide, hide_anim);
144 efl_player_play_set(pd->hide, EINA_FALSE);
145 efl_event_callback_array_add(pd->hide, _anim_hide_event_cb(), obj);
146
147 for (int i = 0; i < efl_content_count(active_view) ; ++i) {
148 Efl_Gfx_Entity *elem = efl_pack_content_get(active_view, i);
149 efl_canvas_group_member_add(pd->group, elem);
150 efl_gfx_entity_visible_set(elem, EINA_FALSE);
151 }
152 if (efl_ui_active_view_active_index_get(active_view) != -1)
153 {
154 pd->content = efl_pack_content_get(pd->container, efl_ui_active_view_active_index_get(active_view));
155 efl_gfx_entity_visible_set(pd->content, EINA_TRUE);
156 _geom_sync(obj, pd);
157 }
158 }
159}
160
161EOLIAN static void
162_efl_ui_active_view_view_manager_stack_efl_ui_active_view_view_manager_content_add(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Stack_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
163{
164 efl_canvas_group_member_add(pd->group, subobj);
165 efl_gfx_entity_visible_set(subobj, EINA_FALSE);
166}
167
168EOLIAN static void
169_efl_ui_active_view_view_manager_stack_efl_ui_active_view_view_manager_content_del(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Stack_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
170{
171 efl_canvas_group_member_remove(pd->group, subobj);
172}
173
174static void
175_setup_anim(Efl_Animation_Player *player, Efl_Gfx_Entity *entity)
176{
177 efl_player_stop(player);
178 efl_animation_player_target_set(player, entity);
179 efl_player_start(player);
180}
181
182EOLIAN static void
183_efl_ui_active_view_view_manager_stack_efl_ui_active_view_view_manager_switch_to(Eo *obj, Efl_Ui_Active_View_View_Manager_Stack_Data *pd, int from, int to)
184{
185 if (from != -1)
186 {
187 if (pd->animation)
188 {
189 pd->from = from;
190 pd->to = to;
191 pd->content = NULL;
192 _setup_anim(pd->hide, efl_pack_content_get(pd->container, from));
193 _setup_anim(pd->show, efl_pack_content_get(pd->container, to));
194 }
195 else
196 {
197 efl_gfx_entity_visible_set(efl_pack_content_get(pd->container, from), EINA_FALSE);
198 pd->content = efl_pack_content_get(pd->container, to);
199 efl_gfx_entity_visible_set(pd->content, EINA_TRUE);
200 }
201 }
202 else
203 {
204 double pos = to;
205
206 pd->content = efl_pack_content_get(pd->container, to);
207 efl_gfx_entity_visible_set(pd->content, EINA_TRUE);
208 efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &pos);
209 }
210
211 _geom_sync(obj, pd);
212}
213
214EOLIAN static void
215_efl_ui_active_view_view_manager_stack_efl_ui_active_view_view_manager_view_size_set(Eo *obj, Efl_Ui_Active_View_View_Manager_Stack_Data *pd, Eina_Size2D size)
216{
217 pd->page_size = size;
218 _geom_sync(obj, pd);
219}
220
221EOLIAN static void
222_efl_ui_active_view_view_manager_stack_efl_object_destructor(Eo *obj, Efl_Ui_Active_View_View_Manager_Stack_Data *pd EINA_UNUSED)
223{
224 efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
225 efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
226
227 efl_destructor(efl_super(obj, MY_CLASS));
228
229 for (int i = 0; i < efl_content_count(pd->container); ++i)
230 {
231 Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
232 for (int d = 0; d < 4; d++)
233 {
234 efl_gfx_mapping_color_set(elem, d, 255, 255, 255, 255);
235 }
236 }
237}
238
239static void
240_reset_player(Efl_Animation_Player *player, Eina_Bool vis)
241{
242 Efl_Gfx_Entity *obj;
243
244 obj = efl_animation_player_target_get(player);
245 efl_player_stop(player);
246 efl_animation_player_target_set(player, NULL);
247 efl_gfx_entity_visible_set(obj, vis);
248}
249
250EOLIAN static void
251_efl_ui_active_view_view_manager_stack_efl_ui_active_view_view_manager_animation_enabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Stack_Data *pd, Eina_Bool animation)
252{
253 _reset_player(pd->hide, EINA_FALSE);
254 _reset_player(pd->show, EINA_TRUE);
255 pd->animation = animation;
256}
257
258EOLIAN static Eina_Bool
259_efl_ui_active_view_view_manager_stack_efl_ui_active_view_view_manager_animation_enabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Stack_Data *pd)
260{
261 return pd->animation;
262}
263
264
265#include "efl_ui_active_view_view_manager_stack.eo.c"
diff --git a/src/lib/elementary/efl_ui_active_view_view_manager_stack.eo b/src/lib/elementary/efl_ui_active_view_view_manager_stack.eo
new file mode 100644
index 0000000000..31c8e43cf8
--- /dev/null
+++ b/src/lib/elementary/efl_ui_active_view_view_manager_stack.eo
@@ -0,0 +1,12 @@
1class @beta Efl.Ui.Active_View.View_Manager_Stack extends Efl.Ui.Active_View.View_Manager
2{
3 implements {
4 Efl.Ui.Active_View.View_Manager.bind;
5 Efl.Ui.Active_View.View_Manager.content_add;
6 Efl.Ui.Active_View.View_Manager.content_del;
7 Efl.Ui.Active_View.View_Manager.switch_to;
8 Efl.Ui.Active_View.View_Manager.view_size {set;}
9 Efl.Ui.Active_View.View_Manager.animation_enabled {set; get;}
10 Efl.Object.destructor;
11 }
12}
diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build
index 3d5372b5dc..cb85beba17 100644
--- a/src/lib/elementary/meson.build
+++ b/src/lib/elementary/meson.build
@@ -154,6 +154,12 @@ pub_eo_files = [
154 'efl_ui_dnd_container.eo', 154 'efl_ui_dnd_container.eo',
155 'efl_ui_focus_manager_window_root.eo', 155 'efl_ui_focus_manager_window_root.eo',
156 'efl_ui_pager.eo', 156 'efl_ui_pager.eo',
157 'efl_ui_active_view_container.eo',
158 'efl_ui_active_view_view_manager.eo',
159 'efl_ui_active_view_view_manager_scroll.eo',
160 'efl_ui_active_view_view_manager_stack.eo',
161 'efl_ui_active_view_indicator.eo',
162 'efl_ui_active_view_indicator_icon.eo',
157 'efl_page_transition.eo', 163 'efl_page_transition.eo',
158 'efl_page_transition_scroll.eo', 164 'efl_page_transition_scroll.eo',
159 'efl_page_indicator.eo', 165 'efl_page_indicator.eo',
@@ -230,6 +236,7 @@ priv_eo_files = [
230 'efl_ui_homogeneous_model.eo', 236 'efl_ui_homogeneous_model.eo',
231 'efl_ui_exact_model.eo', 237 'efl_ui_exact_model.eo',
232 'efl_ui_average_model.eo', 238 'efl_ui_average_model.eo',
239 'efl_ui_active_view_view_manager_plain.eo',
233] 240]
234 241
235priv_eo_file_target = [] 242priv_eo_file_target = []
@@ -917,6 +924,13 @@ elementary_src = [
917 'efl_ui_dnd.c', 924 'efl_ui_dnd.c',
918 'elm_focus_legacy.c', 925 'elm_focus_legacy.c',
919 'efl_ui_pager.c', 926 'efl_ui_pager.c',
927 'efl_ui_active_view_container.c',
928 'efl_ui_active_view_view_manager.c',
929 'efl_ui_active_view_view_manager_plain.c',
930 'efl_ui_active_view_view_manager_scroll.c',
931 'efl_ui_active_view_view_manager_stack.c',
932 'efl_ui_active_view_indicator.c',
933 'efl_ui_active_view_indicator_icon.c',
920 'efl_page_transition.c', 934 'efl_page_transition.c',
921 'efl_page_transition_scroll.c', 935 'efl_page_transition_scroll.c',
922 'efl_page_indicator.c', 936 'efl_page_indicator.c',
diff --git a/src/tests/elementary/efl_ui_suite.c b/src/tests/elementary/efl_ui_suite.c
index a1ba34f1f4..8a8fc123d1 100644
--- a/src/tests/elementary/efl_ui_suite.c
+++ b/src/tests/elementary/efl_ui_suite.c
@@ -4,6 +4,7 @@
4 4
5#include "efl_ui_suite.h" 5#include "efl_ui_suite.h"
6#include "suite_helpers.h" 6#include "suite_helpers.h"
7#include "eo_internal.h"
7 8
8static const Efl_Test_Case etc[] = { 9static const Efl_Test_Case etc[] = {
9 //{ "elm_focus", elm_test_focus}, 10 //{ "elm_focus", elm_test_focus},
@@ -24,9 +25,12 @@ static const Efl_Test_Case etc[] = {
24 { "efl_ui_layout", efl_ui_test_layout}, 25 { "efl_ui_layout", efl_ui_test_layout},
25 { "Efl_Ui_Model", efl_ui_model }, 26 { "Efl_Ui_Model", efl_ui_model },
26 { "efl_ui_widget", efl_ui_test_widget }, 27 { "efl_ui_widget", efl_ui_test_widget },
28 { "efl_ui_active_view", efl_ui_test_active_view},
27 { NULL, NULL } 29 { NULL, NULL }
28}; 30};
29 31
32EFL_CLASS_SIMPLE_CLASS(efl_ui_widget, "efl_ui_widget", EFL_UI_WIDGET_CLASS);
33
30int 34int
31main(int argc, char **argv) 35main(int argc, char **argv)
32{ 36{
diff --git a/src/tests/elementary/efl_ui_suite.h b/src/tests/elementary/efl_ui_suite.h
index 5282949eb5..004a2a3a52 100644
--- a/src/tests/elementary/efl_ui_suite.h
+++ b/src/tests/elementary/efl_ui_suite.h
@@ -36,11 +36,15 @@ void efl_ui_test_focus_sub(TCase *tc);
36 36
37void efl_ui_model(TCase *tc); 37void efl_ui_model(TCase *tc);
38void efl_ui_test_widget(TCase *tc); 38void efl_ui_test_widget(TCase *tc);
39void efl_ui_test_active_view(TCase *tc);
39 40
40void loop_timer_interval_set(Eo *obj, double in); 41void loop_timer_interval_set(Eo *obj, double in);
41 42
42#define efl_loop_timer_interval_set loop_timer_interval_set 43#define efl_loop_timer_interval_set loop_timer_interval_set
43 44
45const Efl_Class* efl_ui_widget_realized_class_get(void);
46#define WIDGET_CLASS efl_ui_widget_realized_class_get()
47
44Eo *win_add(); 48Eo *win_add();
45Eo *win_add_focused(); 49Eo *win_add_focused();
46#endif 50#endif
diff --git a/src/tests/elementary/efl_ui_test_active_view.c b/src/tests/elementary/efl_ui_test_active_view.c
new file mode 100644
index 0000000000..0024b669e2
--- /dev/null
+++ b/src/tests/elementary/efl_ui_test_active_view.c
@@ -0,0 +1,571 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Efl_Ui.h>
6#include "efl_ui_suite.h"
7#include "eo_internal.h"
8
9EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_view_manager, "efl_ui_active_view_view_manager", EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_CLASS);
10EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_indicator, "efl_ui_active_view_indicator", EFL_UI_ACTIVE_VIEW_INDICATOR_CLASS);
11
12static Efl_Ui_Win *win;
13static Efl_Ui_Active_View_Container *container;
14static int tree_abort;
15static int tree_abort_level;
16
17static void
18_shutdown(void)
19{
20 eina_log_abort_on_critical_set(tree_abort);
21 eina_log_abort_on_critical_level_set(tree_abort_level);
22}
23
24static void
25_setup(void)
26{
27 tree_abort = eina_log_abort_on_critical_get();
28 tree_abort_level = eina_log_abort_on_critical_level_get();
29 eina_log_abort_on_critical_level_set(2);
30 eina_log_abort_on_critical_set(1);
31}
32static void
33active_view_setup()
34{
35 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
36 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC));
37
38 container = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, win,
39 efl_content_set(win, efl_added));
40
41 efl_gfx_entity_size_set(win, EINA_SIZE2D(200, 200));
42}
43
44static void
45active_view_teardown()
46{
47 if (win)
48 {
49 efl_del(win);
50 win = NULL;
51 }
52}
53
54typedef struct {
55 struct {
56 int called;
57 double position;
58 } position_update;
59 struct {
60 int called;
61 Efl_Gfx_Entity *subobj;
62 int index;
63 int current_page_at_call;
64 } content_del;
65 struct {
66 int called;
67 Efl_Gfx_Entity *subobj;
68 int index;
69 int current_page_at_call;
70 } content_add;
71 struct {
72 int called;
73 Efl_Ui_Active_View_Container *active_view;
74 } active_view;
75} Indicator_Calls;
76
77Indicator_Calls indicator_calls = { 0 };
78
79static void
80_indicator_content_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
81{
82 indicator_calls.content_del.called ++;
83 indicator_calls.content_del.subobj = subobj;
84 indicator_calls.content_del.index = index;
85 indicator_calls.content_del.current_page_at_call = efl_ui_active_view_active_index_get(container);
86}
87
88static void
89_indicator_content_add(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
90{
91 indicator_calls.content_add.called ++;
92 indicator_calls.content_add.subobj = subobj;
93 indicator_calls.content_add.index = index;
94 indicator_calls.content_add.current_page_at_call = efl_ui_active_view_active_index_get(container);
95}
96
97static void
98_indicator_position_update(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, double position)
99{
100 indicator_calls.position_update.called ++;
101 indicator_calls.position_update.position = position;
102}
103
104static void
105_indicator_bind(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Ui_Active_View_Container *active_view)
106{
107 indicator_calls.active_view.called++;
108 indicator_calls.active_view.active_view = active_view;
109}
110
111EFL_OPS_DEFINE(indicator_tracker,
112 EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_content_add, _indicator_content_add),
113 EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_content_del, _indicator_content_del),
114 EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_position_update, _indicator_position_update),
115 EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_bind, _indicator_bind),
116);
117
118static Efl_Ui_Active_View_View_Manager*
119_create_indicator(void)
120{
121 Eo *obj;
122
123 obj = efl_add(efl_ui_active_view_indicator_realized_class_get(), win);
124 efl_object_override(obj, &indicator_tracker);
125
126 return obj;
127}
128
129typedef struct {
130 struct {
131 int called;
132 Efl_Gfx_Entity *subobj;
133 int index;
134 int current_page_at_call;
135 } content_del;
136 struct {
137 int called;
138 Efl_Gfx_Entity *subobj;
139 int index;
140 int current_page_at_call;
141 } content_add;
142 struct {
143 int called;
144 int from;
145 int to;
146 } request_switch;
147 struct {
148 int called;
149 Eina_Size2D size;
150 } page_size;
151 struct {
152 int called;
153 Efl_Ui_Active_View_Container *active_view;
154 Efl_Canvas_Group *group;
155 } active_view;
156 struct {
157 int called;
158 } animation;
159 double last_position;
160} Transition_Calls;
161
162Transition_Calls transition_calls = { 0 };
163
164static void
165_emit_pos(Eo *obj, double d)
166{
167 if (d == transition_calls.last_position) return;
168 efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &d);
169 transition_calls.last_position = d;
170}
171
172static void
173_transition_content_add(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
174{
175 transition_calls.content_add.called ++;
176 transition_calls.content_add.subobj = subobj;
177 transition_calls.content_add.index = index;
178 transition_calls.content_add.current_page_at_call = efl_ui_active_view_active_index_get(container);
179
180 int i = efl_ui_active_view_active_index_get(container);
181 if (i != -1)
182 _emit_pos(obj, i);
183}
184
185static void
186_transition_content_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
187{
188 transition_calls.content_del.called ++;
189 transition_calls.content_del.subobj = subobj;
190 transition_calls.content_del.index = index;
191 transition_calls.content_del.current_page_at_call = efl_ui_active_view_active_index_get(container);
192
193 int i = efl_ui_active_view_active_index_get(container);
194 if (i != -1)
195 _emit_pos(obj, i);
196}
197
198static void
199_transition_request_switch(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, int from, int to)
200{
201 transition_calls.request_switch.called++;
202 transition_calls.request_switch.from = from;
203 transition_calls.request_switch.to = to;
204
205 _emit_pos(obj, to);
206}
207
208static void
209_transition_page_size_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Size2D size)
210{
211 transition_calls.page_size.called++;
212 transition_calls.page_size.size = size;
213}
214
215static void
216_transition_bind(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Ui_Active_View_Container *active_view, Efl_Canvas_Group *group)
217{
218 transition_calls.active_view.called++;
219 transition_calls.active_view.active_view = active_view;
220 transition_calls.active_view.group = group;
221}
222
223static void
224_transition_animation_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Bool animation)
225{
226 transition_calls.animation.called++;
227 ck_assert_int_eq(animation, EINA_TRUE);
228}
229
230static Eina_Bool
231_transition_animation_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED)
232{
233 return EINA_TRUE;
234}
235
236EFL_OPS_DEFINE(transition_tracker,
237 EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_animation_enabled_set, _transition_animation_set),
238 EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_animation_enabled_get, _transition_animation_get),
239 EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_content_add, _transition_content_add),
240 EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_content_del, _transition_content_del),
241 EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_switch_to, _transition_request_switch),
242 EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_view_size_set, _transition_page_size_set),
243 EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_bind, _transition_bind),
244);
245
246static Efl_Ui_Active_View_View_Manager*
247_create_transition(void)
248{
249 Eo *obj;
250
251 obj = efl_add(efl_ui_active_view_view_manager_realized_class_get(), win);
252 efl_object_override(obj, &transition_tracker);
253
254 return obj;
255}
256
257EFL_START_TEST (efl_ui_active_view_init)
258{
259 ck_assert_ptr_ne(container, NULL);
260 ck_assert_ptr_ne(win, NULL);
261 ck_assert_ptr_eq(efl_ui_active_view_indicator_get(container), NULL);
262 ck_assert_ptr_eq(efl_ui_active_view_manager_get(container), NULL);
263 Eina_Size2D s = efl_ui_active_view_size_get(container);
264 ck_assert_int_eq(s.w, 0); //FIXME
265 ck_assert_int_eq(s.h, 0); //FIXME
266 ck_assert_int_eq(efl_ui_active_view_active_index_get(container), -1);
267}
268EFL_END_TEST
269
270EFL_START_TEST (efl_ui_active_view_active_index)
271{
272 Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
273 efl_pack(container, w);
274 ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 0);
275
276 for (int i = -20; i < 20; ++i)
277 {
278 if (i == 0) continue;
279 EXPECT_ERROR_START;
280 efl_ui_active_view_active_index_set(container, i);
281 EXPECT_ERROR_END;
282 }
283 efl_del(w);
284 ck_assert_int_eq(efl_ui_active_view_active_index_get(container), -1);
285}
286EFL_END_TEST
287
288EFL_START_TEST (efl_ui_smart_transition_calls)
289{
290 Efl_Ui_Widget *w, *w1, *w2;
291 Efl_Ui_Active_View_View_Manager*t = _create_transition();
292
293 w = efl_add(WIDGET_CLASS, win);
294 w1 = efl_add(WIDGET_CLASS, win);
295 w2 = efl_add(WIDGET_CLASS, win);
296
297 efl_ui_active_view_manager_set(container, t);
298 transition_calls.last_position = -2.0;
299 ck_assert_int_eq(transition_calls.animation.called, 1);
300 ck_assert_int_eq(transition_calls.active_view.called, 1);
301 ck_assert_ptr_eq(transition_calls.active_view.active_view, container);
302 //We cannot verify group
303 ck_assert_int_eq(transition_calls.page_size.called, 1);
304 ck_assert_int_eq(transition_calls.page_size.size.w, 0); //FIXME
305 ck_assert_int_eq(transition_calls.page_size.size.h, 0); //FIXME
306 ck_assert_int_eq(transition_calls.request_switch.called, 0);
307 ck_assert_int_eq(transition_calls.content_add.called, 0);
308 ck_assert_int_eq(transition_calls.content_del.called, 0);
309 transition_calls.active_view.called = 0;
310 transition_calls.page_size.called = 0;
311
312 //must update content, and request a switch from -1 to 1
313 efl_pack(container, w);
314 ck_assert_int_eq(transition_calls.active_view.called, 0);
315 ck_assert_int_eq(transition_calls.page_size.called, 0);
316 ck_assert_int_eq(transition_calls.request_switch.called, 1);
317 ck_assert_int_eq(transition_calls.request_switch.from, -1);
318 ck_assert_int_eq(transition_calls.request_switch.to, 0);
319 ck_assert_int_eq(transition_calls.content_add.called, 1);
320 ck_assert_int_eq(transition_calls.content_add.index, 0);
321 ck_assert_ptr_eq(transition_calls.content_add.subobj, w);
322 ck_assert_int_eq(transition_calls.content_add.current_page_at_call, -1);
323 ck_assert_int_eq(transition_calls.content_del.called, 0);
324 transition_calls.content_add.called = 0;
325 transition_calls.request_switch.called = 0;
326
327 //this must update content and a updated current page, but no other call
328 efl_pack_begin(container, w1);
329 ck_assert_int_eq(transition_calls.active_view.called, 0);
330 ck_assert_int_eq(transition_calls.page_size.called, 0);
331 ck_assert_int_eq(transition_calls.request_switch.called, 0);
332 ck_assert_int_eq(transition_calls.content_add.called, 1);
333 ck_assert_int_eq(transition_calls.content_add.index, 0);
334 ck_assert_ptr_eq(transition_calls.content_add.subobj, w1);
335 ck_assert_int_eq(transition_calls.content_add.current_page_at_call, 1);
336 ck_assert_int_eq(transition_calls.content_del.called, 0);
337 transition_calls.content_add.called = 0;
338 transition_calls.request_switch.called = 0;
339 ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 1);
340
341 //new object, must update the content and a not update current page
342 efl_pack_end(container, w2);
343 ck_assert_int_eq(transition_calls.active_view.called, 0);
344 ck_assert_int_eq(transition_calls.page_size.called, 0);
345 ck_assert_int_eq(transition_calls.request_switch.called, 0);
346 ck_assert_int_eq(transition_calls.content_add.called, 1);
347 ck_assert_int_eq(transition_calls.content_add.index, 2);
348 ck_assert_ptr_eq(transition_calls.content_add.subobj, w2);
349 ck_assert_int_eq(transition_calls.content_add.current_page_at_call, 1);
350 ck_assert_int_eq(transition_calls.content_del.called, 0);
351 transition_calls.content_add.called = 0;
352 ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 1);
353
354 //page change must result in a call to request a switch
355 efl_ui_active_view_active_index_set(container, 2);
356 ck_assert_int_eq(transition_calls.active_view.called, 0);
357 ck_assert_int_eq(transition_calls.page_size.called, 0);
358 ck_assert_int_eq(transition_calls.request_switch.called, 1);
359 ck_assert_int_eq(transition_calls.request_switch.from, 1);
360 ck_assert_int_eq(transition_calls.request_switch.to, 2);
361 ck_assert_int_eq(transition_calls.content_add.called, 0);
362 ck_assert_int_eq(transition_calls.content_del.called, 0);
363 transition_calls.request_switch.called = 0;
364
365 //deletion of object must result in a content update
366 efl_del(w);
367 ck_assert_int_eq(transition_calls.active_view.called, 0);
368 ck_assert_int_eq(transition_calls.page_size.called, 0);
369 ck_assert_int_eq(transition_calls.request_switch.called, 0);
370 ck_assert_int_eq(transition_calls.content_add.called, 0);
371 ck_assert_int_eq(transition_calls.content_del.called, 1);
372 ck_assert_int_eq(transition_calls.content_del.index, 1);
373 ck_assert_ptr_eq(transition_calls.content_del.subobj, w);
374 ck_assert_int_eq(transition_calls.content_del.current_page_at_call, 1);
375 transition_calls.content_del.called = 0;
376}
377EFL_END_TEST
378
379
380EFL_START_TEST (efl_ui_smart_transition_lifetime)
381{
382 Efl_Ui_Active_View_View_Manager*t, *t1;
383
384 t = _create_transition();
385 efl_wref_add(t, &t);
386 t1 = _create_transition();
387 efl_wref_add(t1, &t1);
388
389 efl_ui_active_view_manager_set(container, t);
390 efl_ui_active_view_manager_set(container, t1);
391 ck_assert_ptr_eq(t, NULL);
392}
393EFL_END_TEST
394
395static void
396_verify_indicator_calls(void)