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)
downloadefl-79fe0121eec5772fca8771d19d3265ad6a7d3117.tar.gz
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 = \
lib/elementary/efl_ui_dnd_container.eo \
lib/elementary/efl_ui_focus_manager_window_root.eo \
lib/elementary/efl_ui_pager.eo \
+ lib/elementary/efl_ui_active_view_container.eo \
+ lib/elementary/efl_ui_active_view_view_manager.eo \
+ lib/elementary/efl_ui_active_view_view_manager_plain.eo \
+ lib/elementary/efl_ui_active_view_view_manager_scroll.eo \
+ lib/elementary/efl_ui_active_view_view_manager_stack.eo \
+ lib/elementary/efl_ui_active_view_indicator.eo \
+ lib/elementary/efl_ui_active_view_indicator_icon.eo \
lib/elementary/efl_page_transition.eo \
lib/elementary/efl_page_transition_scroll.eo \
lib/elementary/efl_page_indicator.eo \
@@ -1197,6 +1204,13 @@ lib_elementary_libelementary_la_SOURCES = \
static_libs/buildsystem/buildsystem.h \
static_libs/buildsystem/buildsystem_autotools.c \
lib/elementary/efl_ui_pager.c \
+ lib/elementary/efl_ui_active_view_container.c \
+ lib/elementary/efl_ui_active_view_view_manager.c \
+ lib/elementary/efl_ui_active_view_view_manager_plain.c \
+ lib/elementary/efl_ui_active_view_view_manager_scroll.c \
+ lib/elementary/efl_ui_active_view_view_manager_stack.c \
+ lib/elementary/efl_ui_active_view_indicator.c \
+ lib/elementary/efl_ui_active_view_indicator_icon.c \
lib/elementary/efl_page_transition.c \
lib/elementary/efl_page_transition_scroll.c \
lib/elementary/efl_page_indicator.c \
@@ -1435,6 +1449,7 @@ bin/elementary/test_gesture_framework.c \
bin/elementary/test_ui_tab_pager.c \
bin/elementary/test_ui_pager.c \
bin/elementary/test_ui_pager_scroll.c \
+bin/elementary/test_ui_active_view.c \
bin/elementary/test_ui_relative_layout.c \
bin/elementary/test.h
@@ -1963,6 +1978,7 @@ tests_elementary_efl_ui_suite_SOURCES = \
tests/elementary/efl_ui_test_image_zoomable.c \
tests/elementary/efl_ui_test_layout.c \
tests/elementary/efl_ui_test_widget.c \
+ tests/elementary/efl_ui_test_active_view.c \
tests/elementary/efl_ui_suite.h \
tests/elementary/efl_ui_model.c
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 = [
'test_ui_panel.c',
'test_ui_pager.c',
'test_ui_pager_scroll.c',
+ 'test_ui_active_view.c',
'test_part_bg.c',
'test_part_shadow.c',
'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);
void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info);
void test_ui_pager(void *data, Evas_Object *obj, void *event_info);
+void test_ui_pager_stack(void *data, Evas_Object *obj, void *event_info);
void test_ui_pager_scroll(void *data, Evas_Object *obj, void *event_info);
+void test_ui_active_view_stack(void *data, Evas_Object *obj, void *event_info);
+void test_ui_active_view_plain(void *data, Evas_Object *obj, void *event_info);
+void test_ui_active_view_scroll(void *data, Evas_Object *obj, void *event_info);
void test_ui_relative_layout(void *data, Evas_Object *obj, void *event_info);
@@ -1117,6 +1121,9 @@ add_tests:
ADD_TEST_EO(NULL, "Tab Pager", "Efl.Ui.Tab_Pager", test_ui_tab_pager);
ADD_TEST_EO(NULL, "Pager", "Efl.Ui.Pager", test_ui_pager);
ADD_TEST_EO(NULL, "Scroll Pager", "Efl.Ui.Pager (Scroll)", test_ui_pager_scroll);
+ ADD_TEST_EO(NULL, "Active View", "Efl.Ui.Active_View Plain", test_ui_active_view_plain);
+ ADD_TEST_EO(NULL, "Active View", "Efl.Ui.Active_View Scroll", test_ui_active_view_scroll);
+ ADD_TEST_EO(NULL, "Active View", "Efl.Ui.Active_View Stack", test_ui_active_view_stack);
//------------------------------//
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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#define EO_BETA_API
+#define EFL_UI_WIDGET_PROTECTED
+
+#include <Efl_Ui.h>
+#include <Elementary.h>
+
+typedef enum _Page_Type {
+ LAYOUT,
+ LIST,
+ BUTTON
+} Page_Type;
+
+typedef enum _Pack_Type {
+ PACK_BEGIN,
+ PACK_END,
+ PACK_BEFORE,
+ PACK_AFTER,
+ PACK_AT,
+ UNPACK_AT,
+ CLEAR
+} Pack_Type;
+
+typedef struct _Params {
+ Evas_Object *navi;
+ Eo *active_view;
+ Eo *indicator;
+ int w, h;
+ Eina_Bool wfill, hfill;
+} Params;
+
+typedef struct _Page_Set_Params {
+ Eo *active_view;
+ Eo *spinner;
+} Page_Set_Params;
+
+typedef struct _Pack_Params {
+ Pack_Type type;
+ Eo *active_view;
+ Eo *pack_sp;
+ Eo *unpack_sp;
+ Eo *unpack_btn;
+} Pack_Params;
+
+typedef struct _Size_Params {
+ Eo *active_view;
+ Eo *slider;
+ Params *params;
+} Size_Params;
+
+#define PAGE_NUM 3
+
+static Eo*
+page_add(Page_Type p, Eo *parent)
+{
+ Eo *page;
+ char buf[PATH_MAX];
+ int i;
+
+ switch (p) {
+ case LAYOUT:
+ snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
+ elm_app_data_dir_get());
+ page = efl_add(EFL_UI_LAYOUT_CLASS, parent,
+ efl_file_set(efl_added, buf),
+ efl_file_key_set(efl_added, "page"),
+ efl_file_load(efl_added),
+ efl_text_set(efl_part(efl_added, "text"), "Layout Page"));
+ efl_gfx_hint_fill_set(page, EINA_TRUE, EINA_TRUE);
+ break;
+ case LIST:
+ page = elm_list_add(parent);
+ elm_list_select_mode_set(page, ELM_OBJECT_SELECT_MODE_ALWAYS);
+ evas_object_show(page);
+ for (i = 0; i < 20; i++) {
+ snprintf(buf, sizeof(buf), "List Page - Item #%d", i);
+ elm_list_item_append(page, buf, NULL, NULL, NULL, NULL);
+ }
+ evas_object_size_hint_weight_set(page, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(page, EVAS_HINT_FILL,
+ EVAS_HINT_FILL);
+ break;
+ case BUTTON:
+ page = efl_add(EFL_UI_BUTTON_CLASS, parent,
+ efl_text_set(efl_added, "Button Page"));
+ efl_gfx_hint_fill_set(page, EINA_TRUE, EINA_TRUE);
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
+ elm_app_data_dir_get());
+ page = efl_add(EFL_UI_LAYOUT_CLASS, parent,
+ efl_file_set(efl_added, buf),
+ efl_file_key_set(efl_added, "page"),
+ efl_file_load(efl_added),
+ efl_text_set(efl_part(efl_added, "text"), "Layout Page"));
+ efl_gfx_hint_fill_set(page, EINA_TRUE, EINA_TRUE);
+ break;
+ }
+
+ return page;
+}
+
+static void
+prev_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Eo *active_view = data;
+ int active_index = efl_ui_active_view_active_index_get(active_view);
+
+ if (active_index - 1 > -1)
+ efl_ui_active_view_active_index_set(active_view, active_index -1);
+}
+
+static void
+next_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Eo *active_view = data;
+ int active_index = efl_ui_active_view_active_index_get(active_view);
+
+ if (active_index + 1 < efl_content_count(active_view))
+ efl_ui_active_view_active_index_set(active_view, active_index +1);
+}
+
+static void
+back_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ elm_naviframe_item_pop(data);
+}
+
+static void
+list_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ free(data);
+}
+
+static void
+width_slider_cb(void *data, const Efl_Event *ev)
+{
+ Params *params = data;
+ int h;
+
+ if (params->hfill) h = -1;
+ else h = params->h;
+
+ params->w = efl_ui_range_value_get(ev->object);
+ efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(params->w, h));
+}
+
+static void
+height_slider_cb(void *data, const Efl_Event *ev)
+{
+ Params *params = data;
+ int w;
+
+ if (params->wfill) w = -1;
+ else w = params->w;
+
+ params->h = efl_ui_range_value_get(ev->object);
+ efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(w, params->h));
+}
+
+static void
+width_check_cb(void *data, const Efl_Event *ev)
+{
+ Size_Params *params = data;
+ Eina_Bool ck = elm_check_selected_get(ev->object);
+ int w, h;
+
+ elm_object_disabled_set(params->slider, ck);
+
+ params->params->wfill = ck;
+
+ if (params->params->wfill) w = -1;
+ else w = params->params->w;
+
+ if (params->params->hfill) h = -1;
+ else h = params->params->h;
+
+ efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(w, h));
+}
+
+static void
+height_check_cb(void *data, const Efl_Event *ev)
+{
+ Size_Params *params = data;
+ Eina_Bool ck = elm_check_selected_get(ev->object);
+ int w, h;
+
+ elm_object_disabled_set(params->slider, ck);
+
+ params->params->hfill = ck;
+
+ if (params->params->wfill) w = -1;
+ else w = params->params->w;
+
+ if (params->params->hfill) h = -1;
+ else h = params->params->h;
+
+ efl_ui_active_view_size_set(params->active_view, EINA_SIZE2D(w, h));
+}
+
+static void
+check_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ free(data);
+}
+
+static void
+pack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Pack_Params *param = data;
+ Eo *active_view = param->active_view;
+ Eo *page = NULL, *curr_page;
+ int index, cnt;
+
+ if ((param->type != UNPACK_AT) && (param->type != CLEAR)) {
+ index = efl_content_count(active_view);
+
+ switch (index % 3) {
+ case 0:
+ page = page_add(LAYOUT, active_view);
+ break;
+ case 1:
+ page = page_add(LIST, active_view);
+ break;
+ case 2:
+ page = page_add(BUTTON, active_view);
+ break;
+ default:
+ page = page_add(LAYOUT, active_view);
+ break;
+ }
+ }
+
+ switch (param->type) {
+ case PACK_BEGIN:
+ efl_pack_begin(active_view, page);
+ break;
+ case PACK_END:
+ efl_pack_end(active_view, page);
+ break;
+ case PACK_BEFORE:
+ index = efl_ui_active_view_active_index_get(active_view);
+ curr_page = efl_pack_content_get(active_view, index);
+ efl_pack_before(active_view, page, curr_page);
+ break;
+ case PACK_AFTER:
+ index = efl_ui_active_view_active_index_get(active_view);
+ curr_page = efl_pack_content_get(active_view, index);
+ efl_pack_after(active_view, page, curr_page);
+ break;
+ case PACK_AT:
+ index = efl_ui_range_value_get(param->pack_sp);
+ efl_pack_at(active_view, page, index);
+ break;
+ case UNPACK_AT:
+ index = efl_ui_range_value_get(param->unpack_sp);
+ page = efl_pack_unpack_at(active_view, index);
+ efl_del(page);
+ break;
+ case CLEAR:
+ efl_pack_clear(active_view);
+ break;
+ }
+
+ cnt = efl_content_count(active_view);
+
+ index = efl_ui_range_value_get(param->pack_sp);
+ if (index > cnt)
+ efl_ui_range_value_set(param->pack_sp, cnt);
+ efl_ui_range_min_max_set(param->pack_sp, 0, cnt);
+
+ if (cnt > 0)
+ {
+ elm_object_disabled_set(param->unpack_btn, EINA_FALSE);
+ elm_object_disabled_set(param->unpack_sp, EINA_FALSE);
+
+ cnt -= 1;
+ index = efl_ui_range_value_get(param->unpack_sp);
+ if (index > cnt)
+ efl_ui_range_value_set(param->unpack_sp, cnt);
+ efl_ui_range_min_max_set(param->unpack_sp, 0, cnt);
+ }
+ else
+ {
+ elm_object_disabled_set(param->unpack_btn, EINA_TRUE);
+ elm_object_disabled_set(param->unpack_sp, EINA_TRUE);
+ }
+}
+
+static void
+pack_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ free(data);
+}
+
+static void
+page_set_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Page_Set_Params *psp = data;
+
+ efl_ui_active_view_active_index_set(psp->active_view,
+ efl_ui_range_value_get(psp->spinner));
+}
+
+static void
+page_set_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ free(data);
+}
+
+static void
+indicator_icon_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Params *params = data;
+
+ params->indicator = efl_add(EFL_UI_ACTIVE_VIEW_INDICATOR_ICON_CLASS, params->active_view);
+ efl_ui_active_view_indicator_set(params->active_view, params->indicator);
+}
+
+static void
+indicator_none_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Params *params = data;
+ efl_ui_active_view_indicator_set(params->active_view, NULL);
+}
+
+static void
+active_view_size(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Params *params = data;
+ Size_Params *size_params;
+ Evas_Object *navi = params->navi;
+ Eo *btn, *box, *fr, *inbox, *ck, *sl;
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
+ efl_text_set(efl_added, "Back"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ back_btn_cb, navi));
+
+ box = efl_add(EFL_UI_BOX_CLASS, navi,
+ elm_naviframe_item_push(navi, "View Size", btn, NULL,
+ efl_added, NULL));
+
+ // Width
+ fr = elm_frame_add(box);
+ elm_object_text_set(fr, "Width");
+ efl_gfx_hint_align_set(fr, -1, -1);
+ efl_gfx_hint_weight_set(fr, 1, 1);
+ efl_pack(box, fr);
+ efl_gfx_entity_visible_set(fr, 1);
+
+ inbox = efl_add(EFL_UI_BOX_CLASS, fr,
+ efl_content_set(fr, efl_added));
+
+ ck = elm_check_add(inbox);
+ elm_object_text_set(ck, "Fill");
+ efl_pack_end(inbox, ck);
+ efl_gfx_entity_visible_set(ck, 1);
+
+ sl = efl_add(EFL_UI_SLIDER_CLASS, inbox,
+ efl_ui_range_min_max_set(efl_added, 100, 200),
+ efl_ui_range_value_set(efl_added, params->w),
+ efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(100, 0)),
+ efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED,
+ width_slider_cb, params),
+ efl_pack_end(inbox, efl_added));
+
+ size_params = calloc(1, sizeof(Size_Params));
+ if (!size_params) return;
+
+ size_params->slider = sl;
+ size_params->active_view = params->active_view;
+ size_params->params = params;
+
+ efl_event_callback_add(ck, EFL_UI_CHECK_EVENT_CHANGED, width_check_cb,
+ size_params);
+ efl_event_callback_add(ck, EFL_EVENT_DEL, check_del_cb, size_params);
+
+ if (params->wfill)
+ {
+ elm_check_state_set(ck, EINA_TRUE);
+ elm_object_disabled_set(sl, EINA_TRUE);
+ }
+
+ // Height
+ fr = elm_frame_add(box);
+ elm_object_text_set(fr, "Height");
+ efl_gfx_hint_align_set(fr, -1, -1);
+ efl_gfx_hint_weight_set(fr, 1, 1);
+ efl_pack(box, fr);
+ efl_gfx_entity_visible_set(fr, 1);
+
+ inbox = efl_add(EFL_UI_BOX_CLASS, fr,
+ efl_content_set(fr, efl_added));
+
+ ck = elm_check_add(inbox);
+ elm_object_text_set(ck, "Fill");
+ efl_pack_end(inbox, ck);
+ efl_gfx_entity_visible_set(ck, 1);
+
+ sl = efl_add(EFL_UI_SLIDER_CLASS, inbox,
+ efl_ui_range_min_max_set(efl_added, 100, 300),
+ efl_ui_range_value_set(efl_added, params->h),
+ efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(100, 0)),
+ efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED,
+ height_slider_cb, params),
+ efl_pack_end(inbox, efl_added));
+
+ size_params = calloc(1, sizeof(Size_Params));
+ if (!size_params) return;
+
+ size_params->slider = sl;
+ size_params->active_view = params->active_view;
+ size_params->params = params;
+
+ efl_event_callback_add(ck, EFL_UI_CHECK_EVENT_CHANGED, height_check_cb,
+ size_params);
+ efl_event_callback_add(ck, EFL_EVENT_DEL, check_del_cb, size_params);
+
+ if (params->hfill)
+ {
+ elm_check_state_set(ck, EINA_TRUE);
+ elm_object_disabled_set(sl, EINA_TRUE);
+ }
+}
+
+static void
+_gravity_changed_cb(void *data, const Efl_Event *ev)
+{
+ Params *params = data;
+
+ if (efl_ui_nstate_value_get(ev->object) == 0)
+ {
+ efl_ui_active_view_gravity_set(params->active_view, EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_INDEX);
+ }
+ else
+ {
+ efl_ui_active_view_gravity_set(params->active_view, EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT);
+ }
+}
+
+static void
+view_index_gravity_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Params *params = data;
+ Evas_Object *navi = params->navi;
+ Eo *btn, *box, *ck;
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
+ efl_text_set(efl_added, "Back"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ back_btn_cb, navi));
+
+ box = efl_add(EFL_UI_BOX_CLASS, navi,
+ elm_naviframe_item_push(navi, "View Index Gravity", btn, NULL,
+ efl_added, NULL));
+
+ // Width
+
+ ck = efl_add(EFL_UI_CHECK_CLASS, box);
+ efl_event_callback_add(ck, EFL_UI_NSTATE_EVENT_CHANGED, _gravity_changed_cb, params);
+ efl_text_set(ck, "Content Index Gravity");
+ efl_pack_end(box, ck);
+ efl_gfx_entity_visible_set(ck, 1);
+ if (efl_ui_active_view_gravity_get(params->active_view) == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT)
+ {
+ efl_ui_nstate_value_set(ck, 1);
+ }
+ else
+ {
+ efl_ui_nstate_value_set(ck, 0);
+ }
+}
+
+static void
+_animation_cb(void *data, const Efl_Event *ev)
+{
+ Params *params = data;
+
+ 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));
+}
+
+static void
+view_animation_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Params *params = data;
+ Evas_Object *navi = params->navi;
+ Eo *btn, *box, *ck;
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
+ efl_text_set(efl_added, "Back"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ back_btn_cb, navi));
+
+ box = efl_add(EFL_UI_BOX_CLASS, navi,
+ elm_naviframe_item_push(navi, "View Manager animation", btn, NULL,
+ efl_added, NULL));
+
+ ck = efl_add(EFL_UI_CHECK_CLASS, box);
+ efl_event_callback_add(ck, EFL_UI_NSTATE_EVENT_CHANGED, _animation_cb, params);
+ efl_ui_nstate_value_set(ck, efl_ui_active_view_view_manager_animation_enabled_get(efl_ui_active_view_manager_get(params->active_view)));
+ efl_text_set(ck, "Animation");
+ efl_pack_end(box, ck);
+ efl_gfx_entity_visible_set(ck, 1);
+}
+
+static void
+pack_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Params *params = (Params *)data;
+ Evas_Object *navi = params->navi;
+ Eo *active_view = params->active_view;
+ Eo *btn, *box, *in_box1, *in_box2, *sp1, *sp2;
+ Pack_Params *pack_param;
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
+ efl_text_set(efl_added, "Back"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ back_btn_cb, navi));
+
+ box = efl_add(EFL_UI_BOX_CLASS, navi,
+ efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
+ elm_naviframe_item_push(navi, "Pack", btn, NULL,
+ efl_added, NULL));
+
+ in_box1 = efl_add(EFL_UI_BOX_CLASS, box,
+ efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
+ efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL));
+
+ sp1 = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box1,
+ efl_ui_range_min_max_set(efl_added, 0,
+ efl_content_count(active_view)),
+ efl_ui_range_value_set(efl_added,
+ efl_ui_active_view_active_index_get(active_view)));
+
+ in_box2 = efl_add(EFL_UI_BOX_CLASS, box,
+ efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
+ efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL));
+
+ sp2 = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box2);
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, in_box2,
+ efl_text_set(efl_added, "Unpack At"));
+
+ // Pack Begin
+ pack_param = calloc(1, sizeof(Pack_Params));
+ if (!pack_param) return;
+
+ pack_param->active_view = active_view;
+ pack_param->pack_sp = sp1;
+ pack_param->unpack_sp = sp2;
+ pack_param->unpack_btn = btn;
+ pack_param->type = PACK_BEGIN;
+
+ efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "Pack Begin"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ pack_btn_cb, pack_param),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL,
+ pack_btn_del_cb, pack_param),
+ efl_pack_end(box, efl_added));
+
+ // Pack End
+ pack_param = calloc(1, sizeof(Pack_Params));
+ if (!pack_param) return;
+
+ pack_param->active_view = active_view;
+ pack_param->pack_sp = sp1;
+ pack_param->unpack_sp = sp2;
+ pack_param->unpack_btn = btn;
+ pack_param->type = PACK_END;
+
+ efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "Pack End"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ pack_btn_cb, pack_param),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL,
+ pack_btn_del_cb, pack_param),
+ efl_pack_end(box, efl_added));
+
+ // Pack Before
+ pack_param = calloc(1, sizeof(Pack_Params));
+ if (!pack_param) return;
+
+ pack_param->active_view = active_view;
+ pack_param->pack_sp = sp1;
+ pack_param->unpack_sp = sp2;
+ pack_param->unpack_btn = btn;
+ pack_param->type = PACK_BEFORE;
+
+ efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "Pack Before Current Page"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ pack_btn_cb, pack_param),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL,
+ pack_btn_del_cb, pack_param),
+ efl_pack_end(box, efl_added));
+
+ // Pack After
+ pack_param = calloc(1, sizeof(Pack_Params));
+ if (!pack_param) return;
+
+ pack_param->active_view = active_view;
+ pack_param->pack_sp = sp1;
+ pack_param->unpack_sp = sp2;
+ pack_param->unpack_btn = btn;
+ pack_param->type = PACK_AFTER;
+
+ efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "Pack After Current Page"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ pack_btn_cb, pack_param),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL,
+ pack_btn_del_cb, pack_param),
+ efl_pack_end(box, efl_added));
+
+ // Pack At
+ pack_param = calloc(1, sizeof(Pack_Params));
+ if (!pack_param) return;
+
+ pack_param->active_view = active_view;
+ pack_param->pack_sp = sp1;
+ pack_param->unpack_sp = sp2;
+ pack_param->unpack_btn = btn;
+ pack_param->type = PACK_AT;
+
+ efl_add(EFL_UI_BUTTON_CLASS, in_box1,
+ efl_text_set(efl_added, "Pack At"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ pack_btn_cb, pack_param),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL,
+ pack_btn_del_cb, pack_param),
+ efl_pack_end(in_box1, efl_added));
+
+ efl_pack_end(box, in_box1);
+ efl_pack_end(in_box1, sp1);
+
+ // Unpack At
+ pack_param = calloc(1, sizeof(Pack_Params));
+ if (!pack_param) return;
+
+ pack_param->active_view = active_view;
+ pack_param->pack_sp = sp1;
+ pack_param->unpack_sp = sp2;
+ pack_param->unpack_btn = btn;
+ pack_param->type = UNPACK_AT;
+
+ efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED,
+ pack_btn_cb, pack_param);
+ efl_event_callback_add(btn, EFL_EVENT_DEL,
+ pack_btn_del_cb, pack_param);
+
+ if (efl_content_count(active_view) > 0)
+ {
+ efl_ui_range_min_max_set(sp2, 0,
+ (efl_content_count(active_view) - 1));
+ efl_ui_range_value_set(sp2,
+ efl_ui_active_view_active_index_get(active_view));
+ }
+ else
+ {
+ elm_object_disabled_set(btn, EINA_TRUE);
+ elm_object_disabled_set(sp2, EINA_TRUE);
+ }
+
+ efl_pack_end(box, in_box2);
+ efl_pack_end(in_box2, btn);
+ efl_pack_end(in_box2, sp2);
+
+ // Clear
+ pack_param = calloc(1, sizeof(Pack_Params));
+ if (!pack_param) return;
+
+ pack_param->active_view = active_view;
+ pack_param->pack_sp = sp1;
+ pack_param->unpack_sp = sp2;
+ pack_param->unpack_btn = btn;
+ pack_param->type = CLEAR;
+
+ efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "Clear"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ pack_btn_cb, pack_param),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL,
+ pack_btn_del_cb, pack_param),
+ efl_pack_end(box, efl_added));
+
+}
+
+static void
+active_index_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Params *params = (Params *)data;
+ Evas_Object *navi = params->navi;
+ Eo *active_view = params->active_view;
+ Eo *btn, *box, *sp;
+ Page_Set_Params *psp = calloc(1, sizeof(Page_Set_Params));
+ if (!psp) return;
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
+ efl_text_set(efl_added, "Back"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ back_btn_cb, navi));
+
+ box = efl_add(EFL_UI_BOX_CLASS, navi,
+ efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
+ elm_naviframe_item_push(navi, "Active Index", btn, NULL,
+ efl_added, NULL));
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "Set Active Index"),
+ efl_pack_end(box, efl_added));
+
+ sp = efl_add(EFL_UI_SPIN_BUTTON_CLASS, box,
+ efl_gfx_hint_align_set(efl_added, -1, -1),
+ efl_pack_end(box, efl_added));
+
+ if (efl_content_count(active_view) > 0)
+ {
+ efl_ui_range_min_max_set(sp, 0,
+ (efl_content_count(active_view) - 1));
+ efl_ui_range_value_set(sp,
+ efl_ui_active_view_active_index_get(active_view));
+ }
+ else
+ {
+ elm_object_disabled_set(btn, EINA_TRUE);
+ elm_object_disabled_set(sp, EINA_TRUE);
+ }
+
+ psp->active_view = active_view;
+ psp->spinner = sp;
+
+ efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, page_set_btn_cb, psp);
+ efl_event_callback_add(btn, EFL_EVENT_DEL, page_set_btn_del_cb, psp);
+}
+
+static void
+indicator_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Params *params = (Params *)data;
+ Evas_Object *navi = params->navi;
+ Eo *btn, *box;
+
+ btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
+ efl_text_set(efl_added, "Back"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ back_btn_cb, navi));
+
+ box = efl_add(EFL_UI_BOX_CLASS, navi,
+ efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
+ elm_naviframe_item_push(navi, "Indicator", btn, NULL,
+ efl_added, NULL));
+
+ efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "Icon Type"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ indicator_icon_btn_cb, params),
+ efl_pack_end(box, efl_added));
+
+ efl_add(EFL_UI_BUTTON_CLASS, box,
+ efl_text_set(efl_added, "None"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
+ indicator_none_btn_cb, params),
+ efl_pack_end(box, efl_added));
+}
+
+void test_ui_active_view_stack(void *data EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Eo *win, *panes, *navi, *list, *layout, *active_view, *page;
+ Params *params = NULL;
+ char buf[PATH_MAX];
+ int i;
+
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
+ efl_text_set(efl_added, "Efl.Ui.Active_View Stack"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+ panes = efl_add(EFL_UI_PANES_CLASS, win,
+ efl_gfx_hint_weight_set(efl_added, 1, 1),
+ efl_ui_panes_split_ratio_set(efl_added, 0.3),
+ efl_content_set(win, efl_added));
+
+ navi = elm_naviframe_add(panes);
+ evas_object_show(navi);
+ efl_content_set(efl_part(panes, "first"), navi);
+
+ list = elm_list_add(navi);
+ elm_list_horizontal_set(list, EINA_FALSE);
+ elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
+ elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
+ evas_object_show(list);
+
+ snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
+ elm_app_data_dir_get());
+ layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
+ efl_file_set(efl_added, buf),
+ efl_file_key_set(efl_added, "pager"),
+ efl_file_load(efl_added),
+ efl_content_set(efl_part(panes, "second"), efl_added));
+
+ active_view = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, layout,
+ efl_content_set(efl_part(layout, "pager"), efl_added),
+ efl_ui_active_view_size_set(efl_added, EINA_SIZE2D(200, 300)));
+
+ efl_ui_active_view_manager_set(active_view, efl_new(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_STACK_CLASS));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Prev"),
+ efl_event_callback_add(efl_added,
+ EFL_UI_EVENT_CLICKED, prev_btn_cb, active_view),
+ efl_content_set(efl_part(layout, "prev_btn"), efl_added));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Next"),
+ efl_event_callback_add(efl_added,
+ EFL_UI_EVENT_CLICKED, next_btn_cb, active_view),
+ efl_content_set(efl_part(layout, "next_btn"), efl_added));
+
+ params = calloc(1, sizeof(Params));
+ if (!params) return;
+
+ params->navi = navi;
+ params->active_view = active_view;
+ params->indicator = NULL;
+ params->w = 200;
+ params->h = 300;
+ params->wfill = EINA_FALSE;
+ params->hfill = EINA_FALSE;
+
+ elm_list_item_append(list, "View Size", NULL, NULL, active_view_size, params);
+ elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
+ elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
+ elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
+ elm_list_item_append(list, "View Index Gravity", NULL, NULL, view_index_gravity_cb, params);
+ elm_list_item_append(list, "Animation", NULL, NULL, view_animation_cb, params);
+ elm_list_go(list);
+
+ efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
+
+ for (i = 0; i < PAGE_NUM; i++) {
+ switch (i % 3) {
+ case 0:
+ page = page_add(LAYOUT, active_view);
+ break;
+ case 1:
+ page = page_add(LIST, active_view);
+ break;
+ case 2:
+ page = page_add(BUTTON, active_view);
+ break;
+ default:
+ page = page_add(LAYOUT, active_view);
+ break;
+ }
+ efl_pack_end(active_view, page);
+ }
+
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
+}
+
+void test_ui_active_view_plain(void *data EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Eo *win, *panes, *navi, *list, *layout, *active_view, *page;
+ Params *params = NULL;
+ char buf[PATH_MAX];
+ int i;
+
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
+ efl_text_set(efl_added, "Efl.Ui.Active_View Plain"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+ panes = efl_add(EFL_UI_PANES_CLASS, win,
+ efl_gfx_hint_weight_set(efl_added, 1, 1),
+ efl_ui_panes_split_ratio_set(efl_added, 0.3),
+ efl_content_set(win, efl_added));
+
+ navi = elm_naviframe_add(panes);
+ evas_object_show(navi);
+ efl_content_set(efl_part(panes, "first"), navi);
+
+ list = elm_list_add(navi);
+ elm_list_horizontal_set(list, EINA_FALSE);
+ elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
+ elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
+ evas_object_show(list);
+
+ snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
+ elm_app_data_dir_get());
+ layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
+ efl_file_set(efl_added, buf),
+ efl_file_key_set(efl_added, "pager"),
+ efl_file_load(efl_added),
+ efl_content_set(efl_part(panes, "second"), efl_added));
+
+ active_view = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, layout,
+ efl_content_set(efl_part(layout, "pager"), efl_added),
+ efl_ui_active_view_size_set(efl_added, EINA_SIZE2D(200, 300)));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Prev"),
+ efl_event_callback_add(efl_added,
+ EFL_UI_EVENT_CLICKED, prev_btn_cb, active_view),
+ efl_content_set(efl_part(layout, "prev_btn"), efl_added));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Next"),
+ efl_event_callback_add(efl_added,
+ EFL_UI_EVENT_CLICKED, next_btn_cb, active_view),
+ efl_content_set(efl_part(layout, "next_btn"), efl_added));
+
+ params = calloc(1, sizeof(Params));
+ if (!params) return;
+
+ params->navi = navi;
+ params->active_view = active_view;
+ params->indicator = NULL;
+ params->w = 200;
+ params->h = 300;
+ params->wfill = EINA_FALSE;
+ params->hfill = EINA_FALSE;
+
+ elm_list_item_append(list, "View Size", NULL, NULL, active_view_size, params);
+ elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
+ elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
+ elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
+ elm_list_item_append(list, "View Index Gravity", NULL, NULL, view_index_gravity_cb, params);
+ elm_list_go(list);
+
+ efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
+
+ for (i = 0; i < PAGE_NUM; i++) {
+ switch (i % 3) {
+ case 0:
+ page = page_add(LAYOUT, active_view);
+ break;
+ case 1:
+ page = page_add(LIST, active_view);
+ break;
+ case 2:
+ page = page_add(BUTTON, active_view);
+ break;
+ default:
+ page = page_add(LAYOUT, active_view);
+ break;
+ }
+ efl_pack_end(active_view, page);
+ }
+
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
+}
+
+
+void test_ui_active_view_scroll(void *data EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Eo *win, *panes, *navi, *list, *layout, *active_view, *page;
+ Params *params = NULL;
+ char buf[PATH_MAX];
+ int i;
+
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
+ efl_text_set(efl_added, "Efl.Ui.Active_View Scroll"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+ panes = efl_add(EFL_UI_PANES_CLASS, win,
+ efl_gfx_hint_weight_set(efl_added, 1, 1),
+ efl_ui_panes_split_ratio_set(efl_added, 0.3),
+ efl_content_set(win, efl_added));
+
+ navi = elm_naviframe_add(panes);
+ evas_object_show(navi);
+ efl_content_set(efl_part(panes, "first"), navi);
+
+ list = elm_list_add(navi);
+ elm_list_horizontal_set(list, EINA_FALSE);
+ elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
+ elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
+ evas_object_show(list);
+
+ snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
+ elm_app_data_dir_get());
+ layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
+ efl_file_set(efl_added, buf),
+ efl_file_key_set(efl_added, "pager"),
+ efl_file_load(efl_added),
+ efl_content_set(efl_part(panes, "second"), efl_added));
+
+ active_view = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, layout,
+ efl_content_set(efl_part(layout, "pager"), efl_added),
+ efl_ui_active_view_size_set(efl_added, EINA_SIZE2D(200, 300)));
+
+ efl_ui_active_view_manager_set(active_view, efl_new(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Prev"),
+ efl_event_callback_add(efl_added,
+ EFL_UI_EVENT_CLICKED, prev_btn_cb, active_view),
+ efl_content_set(efl_part(layout, "prev_btn"), efl_added));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Next"),
+ efl_event_callback_add(efl_added,
+ EFL_UI_EVENT_CLICKED, next_btn_cb, active_view),
+ efl_content_set(efl_part(layout, "next_btn"), efl_added));
+
+ params = calloc(1, sizeof(Params));
+ if (!params) return;
+
+ params->navi = navi;
+ params->active_view = active_view;
+ params->indicator = NULL;
+ params->w = 200;
+ params->h = 300;
+ params->wfill = EINA_FALSE;
+ params->hfill = EINA_FALSE;
+
+ elm_list_item_append(list, "View Size", NULL, NULL, active_view_size, params);
+ elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
+ elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
+ elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
+ elm_list_item_append(list, "View Index Gravity", NULL, NULL, view_index_gravity_cb, params);
+ elm_list_item_append(list, "Animation", NULL, NULL, view_animation_cb, params);
+ elm_list_go(list);
+
+ efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
+
+ for (i = 0; i < PAGE_NUM; i++) {
+ switch (i % 3) {
+ case 0:
+ page = page_add(LAYOUT, active_view);
+ break;
+ case 1:
+ page = page_add(LIST, active_view);
+ break;
+ case 2:
+ page = page_add(BUTTON, active_view);
+ break;
+ default:
+ page = page_add(LAYOUT, active_view);
+ break;
+ }
+ efl_pack_end(active_view, page);
+ }
+
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
+}
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 @@
+#include <Efl_Ui.h>
+
+#include <Elementary.h>
+
+static Efl_Ui_Active_View_Container *container;
+static Eina_Bool play_state = EINA_FALSE;
+static Efl_Loop_Timer *show_timer = NULL;
+
+char *img_files[] = {
+ "logo.png",
+ "plant_01.jpg",
+ "rock_01.jpg",
+ "rock_02.jpg",
+ "sky_01.jpg",
+ "wood_01.jpg",
+ "mystrale.jpg",
+ "mystrale_2.jpg"
+};
+#define IMG_NUM 8
+
+static void
+_show_next(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
+{
+ if (!show_timer) return;
+ efl_del(show_timer);
+ show_timer = NULL;
+
+ int current_index = efl_ui_active_view_active_index_get(container);
+ int new_index = (current_index + 1) % efl_content_count(container);
+ efl_ui_active_view_active_index_set(container, new_index);
+}
+
+static void
+put_play(void)
+{
+ play_state = EINA_TRUE;
+ show_timer = efl_add(EFL_LOOP_TIMER_CLASS, container,
+ efl_loop_timer_interval_set(efl_added, 2.0),
+ efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _show_next, NULL));
+}
+
+static void
+put_pause(void)
+{
+ play_state = EINA_FALSE;
+ if (show_timer)
+ efl_del(show_timer);
+ show_timer = NULL;
+
+}
+
+static void
+_container_end(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
+{
+ if (play_state)
+ {
+ show_timer = efl_add(EFL_LOOP_TIMER_CLASS, efl_app_main_get(),
+ efl_loop_timer_interval_set(efl_added, 2.0),
+ efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _show_next, NULL));
+ }
+}
+
+static void
+_play_toggle(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ if (play_state)
+ {
+ put_pause();
+ efl_text_set(ev->object, "Play");
+ }
+ else
+ {
+ put_play();
+ efl_text_set(ev->object, "Pause");
+ }
+}
+
+static void
+efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
+{
+ Efl_Ui_Win *win;
+ Efl_Ui_Table *table;
+
+ elm_app_info_set(efl_main, "elementary", "images");
+
+ win = efl_new(EFL_UI_WIN_CLASS,
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE),
+ efl_text_set(efl_added, "Slideshow Example")
+ );
+ table = efl_add(EFL_UI_TABLE_CLASS, win);
+ efl_content_set(win, table);
+
+ container = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, win,
+ efl_event_callback_add(efl_added, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_END, _container_end, NULL),
+ efl_pack_table(table, efl_added, 0, 0, 1, 1));
+ efl_ui_active_view_indicator_set(container, efl_new(EFL_UI_ACTIVE_VIEW_INDICATOR_ICON_CLASS));
+ efl_ui_active_view_manager_set(container, efl_new(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_STACK_CLASS));
+
+ for (int i = 0; i < IMG_NUM; i++)
+ {
+ char path[PATH_MAX];
+ snprintf(path, PATH_MAX, "%s/images/%s", elm_app_data_dir_get(), img_files[i]);
+ efl_add(EFL_UI_IMAGE_CLASS, container,
+ efl_file_set(efl_added, path),
+ efl_file_load(efl_added),
+ efl_pack_end(container, efl_added));
+ }
+
+ efl_add(EFL_UI_BUTTON_CLASS, table,
+ efl_gfx_hint_weight_set(efl_added, 1.0, 0.0),
+ efl_pack_table(table, efl_added, 0, 1, 1, 1),
+ efl_text_set(efl_added, "Play"),
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _play_toggle, NULL));
+
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(200, 200));
+}
+
+EFL_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 = [
'efl_ui_list_view_example_3',
'efl_canvas_layout_text',
'efl_ui_theme_example_01',
- 'efl_ui_theme_example_02'
+ 'efl_ui_theme_example_02',
+ 'efl_ui_slideshow_example'
]
foreach 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);
# include <efl_ui_panes_eo.h>
# include <efl_ui_panes_part.eo.h>
+#define _EFL_UI_ACTIVE_VIEW_VIEW_MANAGEREO_CLASS_TYPE
+typedef Eo Efl_Ui_Active_View_View_Manager;
+#define _EFL_UI_ACTIVE_VIEW_INDICATOR_EO_CLASS_TYPE
+typedef Eo Efl_Ui_Active_View_Indicator;
+
+# include <efl_ui_active_view_container.eo.h>
+# include <efl_ui_active_view_view_manager.eo.h>
+# include <efl_ui_active_view_indicator.eo.h>
+# include <efl_ui_active_view_indicator_icon.eo.h>
+# include <efl_ui_active_view_view_manager_scroll.eo.h>
+# include <efl_ui_active_view_view_manager_stack.eo.h>
+
# include <efl_ui_navigation_bar.eo.h>
# include <efl_ui_navigation_bar_part.eo.h>
# 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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Efl_Ui.h>
+#include "elm_priv.h"
+#include "efl_ui_active_view_view_manager_plain.eo.h"
+
+typedef struct _Efl_Ui_Active_View_Container_Data
+{
+ Eina_List *content_list;
+ Eo *page_root, *event;
+ struct {
+ Eina_Size2D sz;
+ } page_spec;
+ struct {
+ int page;
+ double pos;
+ } curr;
+ struct {
+ int from;
+ int to;
+ double last_pos;
+ Eina_Bool active;
+ } show_request;
+ Efl_Ui_Active_View_View_Manager *transition;
+ Efl_Ui_Active_View_Indicator *indicator;
+ double position;
+ Eina_Bool fill_width: 1;
+ Eina_Bool fill_height: 1;
+ Eina_Bool prevent_transition_interaction : 1;
+ Efl_Ui_Active_View_Container_Gravity gravity;
+} Efl_Ui_Active_View_Container_Data;
+
+#define MY_CLASS EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS
+
+static void _unpack(Eo *obj, Efl_Ui_Active_View_Container_Data *pd, Efl_Gfx_Entity *subobj, int index);
+static void _unpack_all(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Eina_Bool clear);
+
+static int
+clamp_index(Efl_Ui_Active_View_Container_Data *pd, int index)
+{
+ if (index < ((int)eina_list_count(pd->content_list)) * -1)
+ return -1;
+ else if (index > (int)eina_list_count(pd->content_list) - 1)
+ return 1;
+ return 0;
+}
+
+static int
+index_rollover(Efl_Ui_Active_View_Container_Data *pd, int index)
+{
+ int c = eina_list_count(pd->content_list);
+ if (index < c * -1)
+ return 0;
+ else if (index > c - 1)
+ return c - 1;
+ else if (index < 0)
+ return index + c;
+ return index;
+}
+
+static void
+_transition_end(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
+{
+ Efl_Ui_Active_View_Transition_Event ev;
+
+ if (pd->prevent_transition_interaction) return;
+
+ ev.from = pd->show_request.from;
+ ev.to = pd->show_request.to;
+ efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_END, &ev);
+ pd->show_request.active = EINA_FALSE;
+ pd->show_request.from = -1;
+ pd->show_request.to = -1;
+}
+
+static void
+_transition_start(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, int from, int to, double progress)
+{
+ Efl_Ui_Active_View_Transition_Event ev;
+
+ if (pd->prevent_transition_interaction) return;
+
+ if (pd->show_request.active)
+ _transition_end(obj, pd);
+
+ pd->show_request.active = EINA_TRUE;
+ pd->show_request.from = from;
+ pd->show_request.to = to;
+ pd->show_request.last_pos = progress;
+ ev.from = pd->show_request.from;
+ ev.to = pd->show_request.to;
+ efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_START, &ev);
+}
+
+static void
+_position_set(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, double progress)
+{
+ if (progress < -1.0) progress = -1.0;
+ if (progress > eina_list_count(pd->content_list)) progress = eina_list_count(pd->content_list);
+ if (pd->indicator)
+ {
+ efl_ui_active_view_indicator_position_update(pd->indicator, progress);
+ }
+ pd->position = progress;
+}
+
+static void
+_transition_event_emission(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
+{
+ if (pd->show_request.active)
+ {
+ if ((pd->show_request.to != -1 || pd->show_request.from != -1) &&
+ fabs(pd->show_request.last_pos - pd->show_request.to) < fabs(pd->position - pd->show_request.to))
+ {
+ //abort event here, movement is not in the direction we request
+ pd->show_request.to = -1;
+ _transition_end(obj, pd);
+ }
+ if (pd->position == pd->show_request.to)
+ {
+ //successfully there
+ _transition_end(obj, pd);
+ }
+ }
+ else
+ {
+ //the progress changed without a show_request beeing active. instaciate a new one
+ _transition_start(obj, pd, -1, -1, pd->position);
+ }
+}
+
+static void
+_resize_cb(void *data, const Efl_Event *ev)
+{
+ Efl_Ui_Active_View_Container_Data *pd = data;
+ Eina_Size2D sz;
+
+ sz = efl_gfx_entity_size_get(ev->object);
+
+ if (pd->fill_width) pd->page_spec.sz.w = sz.w;
+ if (pd->fill_height) pd->page_spec.sz.h = sz.h;
+
+ if (pd->transition)
+ efl_ui_active_view_view_manager_view_size_set(pd->transition, pd->page_spec.sz);
+}
+
+EOLIAN static Eo *
+_efl_ui_active_view_container_efl_object_constructor(Eo *obj,
+ Efl_Ui_Active_View_Container_Data *pd)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+
+ if (!elm_widget_theme_klass_get(obj))
+ elm_widget_theme_klass_set(obj, "pager");
+
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+ if (elm_widget_theme_object_set(obj, wd->resize_obj,
+ elm_widget_theme_klass_get(obj),
+ elm_widget_theme_element_get(obj),
+ elm_widget_theme_style_get(obj)) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
+ CRI("Failed to set layout!");
+
+ pd->position = -1;
+ pd->curr.page = -1;
+ pd->curr.pos = 0.0;
+
+ pd->transition = NULL;
+ pd->indicator = NULL;
+
+ pd->fill_width = EINA_TRUE;
+ pd->fill_height = EINA_TRUE;
+
+ efl_ui_active_view_size_set(obj, EINA_SIZE2D(-1, -1));
+ efl_ui_active_view_gravity_set(obj, EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT);
+
+ elm_widget_can_focus_set(obj, EINA_FALSE);
+
+ pd->page_root = efl_add(EFL_CANVAS_GROUP_CLASS, evas_object_evas_get(obj));
+ efl_content_set(efl_part(obj, "efl.page_root"), pd->page_root);
+
+ efl_event_callback_add(pd->page_root, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, pd);
+
+ pd->event = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
+ evas_object_evas_get(obj));
+ evas_object_color_set(pd->event, 0, 0, 0, 0);
+ evas_object_repeat_events_set(pd->event, EINA_TRUE);
+ efl_content_set(efl_part(obj, "efl.event"), pd->event);
+
+ return obj;
+}
+
+EOLIAN static Efl_Object*
+_efl_ui_active_view_container_efl_object_finalize(Eo *obj, Efl_Ui_Active_View_Container_Data *pd EINA_UNUSED)
+{
+ Efl_Ui_Active_View_View_Manager *manager;
+
+ obj = efl_finalize(efl_super(obj, MY_CLASS));
+
+ manager = efl_ui_active_view_manager_get(obj);
+ //set a view manager in case nothing is here
+ if (!manager)
+ {
+ Eo *plain;
+ plain = efl_add(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS, obj);
+ efl_ui_active_view_manager_set(obj, plain);
+ }
+ else
+ {
+ efl_ui_active_view_view_manager_animation_enabled_set(manager, EINA_TRUE);
+ }
+
+ return obj;
+}
+
+EOLIAN static void
+_efl_ui_active_view_container_efl_object_invalidate(Eo *obj,
+ Efl_Ui_Active_View_Container_Data *pd)
+{
+ _unpack_all(obj, pd, EINA_TRUE);
+ efl_invalidate(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static int
+_efl_ui_active_view_container_efl_container_content_count(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd)
+{
+ return eina_list_count(pd->content_list);
+}
+
+static void
+_child_inv(void *data, const Efl_Event *ev)
+{
+ Efl_Ui_Active_View_Container_Data *pd = efl_data_scope_get(data, MY_CLASS);
+ int index = eina_list_data_idx(pd->content_list, ev->object);
+ _unpack(data, pd, ev->object, index);
+}
+
+static Eina_Bool
+_register_child(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE);
+ if (eina_list_data_find(pd->content_list, subobj))
+ {
+ ERR("Object %p is already part of this!", subobj);
+ return EINA_FALSE;
+ }
+ if (!efl_ui_widget_sub_object_add(obj, subobj))
+ return EINA_FALSE;
+
+ efl_event_callback_add(subobj, EFL_EVENT_INVALIDATE, _child_inv, obj);
+
+ return EINA_TRUE;
+}
+
+
+EOLIAN static void
+_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)
+{
+ pd->gravity = gravity;
+}
+
+EOLIAN static Efl_Ui_Active_View_Container_Gravity
+_efl_ui_active_view_container_active_view_gravity_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
+{
+ return pd->gravity;
+}
+
+static void
+_update_internals(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index)
+{
+ Eina_Bool curr_page_update = EINA_FALSE;
+
+ if (pd->gravity == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT && pd->curr.page >= index)
+ {
+ pd->curr.page++;
+ curr_page_update = EINA_TRUE;
+ }
+
+ pd->prevent_transition_interaction = EINA_TRUE;
+ if (pd->transition)
+ efl_ui_active_view_view_manager_content_add(pd->transition, subobj, index);
+ if (pd->indicator)
+ efl_ui_active_view_indicator_content_add(pd->indicator, subobj, index);
+ if (curr_page_update && !pd->transition && eina_list_count(pd->content_list) != 1)
+ _position_set(obj, pd, pd->curr.page);
+ pd->prevent_transition_interaction = EINA_FALSE;
+ if (eina_list_count(pd->content_list) == 1)
+ efl_ui_active_view_active_index_set(obj, 0);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_linear_pack_begin(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Efl_Gfx_Entity *subobj)
+{
+ if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
+ pd->content_list = eina_list_prepend(pd->content_list, subobj);
+ _update_internals(obj, pd, subobj, 0);
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_linear_pack_end(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Efl_Gfx_Entity *subobj)
+{
+ if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
+ pd->content_list = eina_list_append(pd->content_list, subobj);
+ _update_internals(obj, pd, subobj, eina_list_count(pd->content_list) - 1);
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_linear_pack_before(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Efl_Gfx_Entity *subobj,
+ const Efl_Gfx_Entity *existing)
+{
+ if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
+ int index = eina_list_data_idx(pd->content_list, (void *)existing);
+ if (index == -1) return EINA_FALSE;
+ pd->content_list = eina_list_prepend_relative(pd->content_list, subobj, existing);
+ _update_internals(obj, pd, subobj, index);
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_linear_pack_after(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Efl_Gfx_Entity *subobj,
+ const Efl_Gfx_Entity *existing)
+{
+ if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
+ int index = eina_list_data_idx(pd->content_list, (void *)existing);
+ if (index == -1) return EINA_FALSE;
+ pd->content_list = eina_list_append_relative(pd->content_list, subobj, existing);
+ _update_internals(obj, pd, subobj, index + 1);
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_linear_pack_at(Eo *obj,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Efl_Gfx_Entity *subobj,
+ int index)
+{
+ Efl_Gfx_Entity *existing = NULL;
+
+ if (!_register_child(obj, pd, subobj)) return EINA_FALSE;
+ int clamp = clamp_index(pd, index);
+ int pass_index = -1;
+ if (clamp == 0)
+ {
+ existing = eina_list_nth(pd->content_list, index_rollover(pd, index));
+ pd->content_list = eina_list_prepend_relative(
+ pd->content_list, subobj, existing);
+ }
+ else if (clamp == 1)
+ {
+ pd->content_list = eina_list_append(pd->content_list, subobj);
+ pass_index = eina_list_count(pd->content_list);
+ }
+ else
+ {
+ pd->content_list = eina_list_prepend(pd->content_list, subobj);
+ pass_index = 0;
+ }
+ _update_internals(obj, pd, subobj, pass_index);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Efl_Gfx_Entity *
+_efl_ui_active_view_container_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ int index)
+{
+ return eina_list_nth(pd->content_list, index_rollover(pd, index));
+}
+
+EOLIAN static int
+_efl_ui_active_view_container_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ const Efl_Gfx_Entity *subobj)
+{
+ return eina_list_data_idx(pd->content_list, (void *)subobj);
+}
+
+EOLIAN static void
+_efl_ui_active_view_container_active_index_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ int index)
+{
+ int before;
+
+ if ((index < 0) || (index > ((int)eina_list_count(pd->content_list) - 1)))
+ {
+ ERR("index %d out of range", index);
+ return;
+ }
+
+ before = pd->curr.page;
+ pd->show_request.last_pos = pd->curr.page;
+ pd->show_request.from = pd->curr.page;
+ pd->show_request.to = index;
+
+ if (pd->show_request.active && pd->show_request.from == -1 && pd->show_request.to)
+ pd->show_request.to = index; //we just edit this here, a user animation will end when the progress is at the goal.
+ else
+ {
+ _transition_start(obj, pd, before, index, before);
+ }
+
+ int old_curr_page = pd->curr.page;
+ pd->curr.page = index;
+ efl_ui_active_view_view_manager_switch_to(pd->transition, old_curr_page, pd->curr.page);
+}
+
+EOLIAN static int
+_efl_ui_active_view_container_active_index_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd)
+{
+ return pd->curr.page;
+}
+
+EOLIAN Eina_Size2D
+_efl_ui_active_view_container_active_view_size_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd)
+{
+ return pd->page_spec.sz;
+}
+
+EOLIAN static void
+_efl_ui_active_view_container_active_view_size_set(Eo *obj,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Eina_Size2D sz)
+{
+ Eina_Size2D size;
+ if (sz.w < -1 || sz.h < -1) return;
+
+ pd->page_spec.sz = sz;
+ pd->fill_width = sz.w == -1 ? EINA_TRUE : EINA_FALSE;
+ pd->fill_height = sz.h == -1 ? EINA_TRUE : EINA_FALSE;
+
+ size = efl_gfx_entity_size_get(obj);
+ if (pd->fill_height)
+ pd->page_spec.sz.h = size.h;
+ if (pd->fill_width)
+ pd->page_spec.sz.w = size.w;
+
+ if (pd->transition)
+ efl_ui_active_view_view_manager_view_size_set(pd->transition, pd->page_spec.sz);
+}
+
+static void
+_unpack_all(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Eina_Bool clear)
+{
+ pd->curr.page = -1;
+
+ while(pd->content_list)
+ {
+ Eo *content = eina_list_data_get(pd->content_list);
+
+ _unpack(obj, pd, content, 0);
+
+ if (clear)
+ efl_del(content);
+
+ pd->content_list = eina_list_remove(pd->content_list, content);
+ }
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_pack_clear(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd)
+{
+ _unpack_all(obj, pd, EINA_TRUE);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_unpack_all(Eo *obj EINA_UNUSED,
+ Efl_Ui_Active_View_Container_Data *pd)
+{
+ _unpack_all(obj, pd, EINA_FALSE);
+
+ return EINA_TRUE;
+}
+
+static void
+_unpack(Eo *obj,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Efl_Gfx_Entity *subobj,
+ int index)
+{
+ int early_curr_page = pd->curr.page;
+
+ pd->content_list = eina_list_remove(pd->content_list, subobj);
+ _elm_widget_sub_object_redirect_to_top(obj, subobj);
+
+ if (pd->gravity == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT && index < pd->curr.page)
+ pd->curr.page--;
+
+ if (pd->transition)
+ efl_ui_active_view_view_manager_content_del(pd->transition, subobj, index);
+ if (pd->indicator)
+ efl_ui_active_view_indicator_content_del(pd->indicator, subobj, index);
+
+ //we deleted the current index
+ if (pd->gravity == EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_CONTENT && early_curr_page == index)
+ {
+ int new_curr_page = MIN(MAX(early_curr_page, 0), (int)eina_list_count(pd->content_list) - 1);
+ pd->curr.page = -1;
+ if (eina_list_count(pd->content_list) > 0 && efl_alive_get(obj))
+ efl_ui_active_view_active_index_set(obj, new_curr_page);
+ }
+ //position has updated
+ if (early_curr_page != pd->curr.page && early_curr_page != index &&
+ pd->indicator && !pd->transition)
+ efl_ui_active_view_indicator_position_update(pd->indicator, pd->curr.page);
+
+ efl_event_callback_del(subobj, EFL_EVENT_INVALIDATE, _child_inv, obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_unpack(Eo *obj,
+ Efl_Ui_Active_View_Container_Data *pd,
+ Efl_Gfx_Entity *subobj)
+{
+ if (!subobj) return EINA_FALSE;
+
+ int index = eina_list_data_idx(pd->content_list, subobj);
+ if (index == -1)
+ {
+ ERR("Item %p is not part of this container", subobj);
+ return EINA_FALSE;
+ }
+
+ _unpack(obj, pd, subobj, index);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Efl_Gfx_Entity *
+_efl_ui_active_view_container_efl_pack_linear_pack_unpack_at(Eo *obj,
+ Efl_Ui_Active_View_Container_Data *pd,
+ int index)
+{
+ Efl_Gfx_Entity *subobj = eina_list_nth(pd->content_list, index_rollover(pd, index_rollover(pd, index)));
+
+ _unpack(obj, pd, subobj, index);
+
+ return subobj;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_active_view_container_efl_pack_pack(Eo *obj, Efl_Ui_Active_View_Container_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
+{
+ return efl_pack_begin(obj, subobj);
+}
+
+EOLIAN static Eina_Iterator*
+_efl_ui_active_view_container_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
+{
+ return eina_list_iterator_new(pd->content_list);
+}
+
+static void
+_pos_updated(void *data, const Efl_Event *event)
+{
+ Efl_Ui_Active_View_Container_Data *pd = efl_data_scope_get(data, MY_CLASS);
+ double progress = *((double*)event->info);
+ //ignore this here, this could result in unintendet transition,start / end calls
+ if (EINA_DBL_EQ(progress, pd->position))
+ return;
+ _position_set(data, pd, progress);
+ _transition_event_emission(data, pd);
+}
+
+EOLIAN static void
+_efl_ui_active_view_container_view_manager_set(Eo *obj, Efl_Ui_Active_View_Container_Data *pd, Efl_Ui_Active_View_View_Manager *transition)
+{
+ if (!transition)
+ pd->transition = efl_add(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS, obj);
+ else
+ EINA_SAFETY_ON_FALSE_RETURN(efl_isa(transition, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_CLASS));
+
+ if (pd->transition)
+ {
+ efl_ui_active_view_view_manager_bind(pd->transition, NULL, NULL);
+ efl_del(pd->transition);
+ }
+
+ pd->transition = transition;
+
+ if (pd->transition)
+ {
+ efl_parent_set(pd->transition, obj);
+ //disable animation when not finalized yet, this help reducing the overhead of scheduling a animation that will not be displayed
+ efl_ui_active_view_view_manager_animation_enabled_set(pd->transition, efl_finalized_get(obj));
+ efl_ui_active_view_view_manager_bind(pd->transition, obj,
+ pd->page_root);
+ efl_ui_active_view_view_manager_view_size_set(pd->transition, pd->page_spec.sz);
+ efl_event_callback_add(pd->transition, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, _pos_updated, obj);
+ }
+
+}
+
+EOLIAN static Efl_Ui_Active_View_View_Manager*
+_efl_ui_active_view_container_view_manager_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
+{
+ if (efl_isa(pd->transition, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS))
+ return NULL;
+ else
+ return pd->transition;
+}
+
+EOLIAN static void
+_efl_ui_active_view_container_indicator_set(Eo *obj, Efl_Ui_Active_View_Container_Data *pd, Efl_Ui_Active_View_Indicator *indicator)
+{
+ if (pd->indicator)
+ {
+ efl_ui_active_view_indicator_bind(pd->indicator, obj);
+ efl_del(pd->indicator);
+ }
+ pd->indicator = indicator;
+ if (pd->indicator)
+ {
+ efl_ui_active_view_indicator_bind(pd->indicator, obj);
+ if (pd->position != -1)
+ efl_ui_active_view_indicator_position_update(pd->indicator, pd->position);
+ }
+}
+
+EOLIAN static Efl_Ui_Active_View_Indicator*
+_efl_ui_active_view_container_indicator_get(const Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
+{
+ return pd->indicator;
+}
+
+#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 @@
+struct @beta Efl.Ui.Active_View.Transition_Event {
+ from : int; [[The id from where the transition started, -1 if not known]]
+ to : int; [[The id from where the transition started, -1 if not known]]
+}
+
+enum Efl.Ui.Active_View.Container_Gravity {
+ content = 0, [[In case the internal list of content is changed, then the $active_index will always point to the same content]]
+ index = 1, [[In case the internal list of content is changed, then the $active_index will keep its value]]
+}
+
+class @beta Efl.Ui.Active_View.Container extends Efl.Ui.Layout_Base implements Efl.Pack_Linear
+{
+ [[ 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.
+ 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.
+
+ Without a transition object this widget will just display the content with the id set with $active_index. On page changes,
+ ]]
+ c_prefix: efl_ui_active_view;
+ methods {
+ @property view_manager {
+ [[The transition object which defines the animation and exact position of the content]]
+ values {
+ transition : Efl.Ui.Active_View.View_Manager @owned;
+ }
+ }
+ @property indicator {
+ [[A indicator object which can be used to display the state and position of the content in this widget
+ When this object here is set, the position of the indicator object is immidiatly called to the current position of the widget
+ ]]
+ values {
+ indicator : Efl.Ui.Active_View.Indicator @owned;
+ }
+ }
+ @property active_index {
+ [[Selects which is the maincontent to display by this widget. The exact positioning depends on the $transition object]]
+ values {
+ index: int;
+ }
+ }
+ @property active_view_gravity {
+ [[active_view can be used to set the currently active viewed content.
+
+ 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.
+ ]]
+ values {
+ gravity : Efl.Ui.Active_View.Container_Gravity;
+ }
+ }
+ @property active_view_size {
+ [[The size that is give to each content when displayed]]
+ values {
+ size: Eina.Size2D;
+ }
+ }
+ }
+ events {
+ transition,start : Efl.Ui.Active_View.Transition_Event;
+ transition,end : Efl.Ui.Active_View.Transition_Event;
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.finalize;
+ Efl.Object.invalidate;
+ Efl.Container.content_count;
+ Efl.Container.content_iterate;
+ Efl.Pack.pack_clear;
+ Efl.Pack.unpack_all;
+ Efl.Pack.unpack;
+ Efl.Pack.pack;
+ Efl.Pack_Linear.pack_begin;
+ Efl.Pack_Linear.pack_end;
+ Efl.Pack_Linear.pack_before;
+ Efl.Pack_Linear.pack_after;
+ Efl.Pack_Linear.pack_at;
+ Efl.Pack_Linear.pack_content_get;
+ Efl.Pack_Linear.pack_index_get;
+ Efl.Pack_Linear.pack_unpack_at;
+ }
+}
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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_PACK_LAYOUT_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct {
+
+} Efl_Ui_Active_View_Indicator_Data;
+
+
+#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 @@
+abstract @beta Efl.Ui.Active_View.Indicator extends Efl.Object {
+ [[Indicator object that is used by @Efl.Ui.Active_View.Container]]
+ methods {
+ bind @pure_virtual {
+ [[Initial call to flush the required objects of the active view to the transition object
+
+ This call can be used to setup the indicator part of $active_view.
+
+ if there is a position of the widget, then after this call, $position_update will be called.
+ ]]
+ params {
+ active_view : Efl.Ui.Active_View.Container;
+ }
+ }
+ content_add @pure_virtual {
+ [[Content has been added to the container passed in .bind. The $subobj is at position $index.
+
+ While in the call, the $current_page property of the active_view might change.
+ If such a change is happening. No animation should be displayed, and the new state should be applied.
+ ]]
+ params {
+ subobj : Efl.Gfx.Entity;
+ index : int;
+ }
+ }
+ content_del @pure_virtual {
+ [[Content has been removed from the container passed in .bind. The $subobj at position $index is now removed.
+
+ While in the call, the $current_page property of the active_view might change.
+ If such a change is happening. No animation should be displayed, and the new state should be applied.
+ ]]
+ params {
+ subobj : Efl.Gfx.Entity;
+ index : int;
+ }
+ }
+ position_update @pure_virtual {
+ [[The position between the content has been changed.
+
+ The position is absolut and ranges from [-1,x + 1] where x is the number of contents in the active_view.
+
+ Values between two actaul positions must be expected as this is the way the animation of the transition object populates to the indicator
+ ]]
+ params {
+ position : double; [[The position the transition object is currently in]]
+ }
+ }
+ }
+}
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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_PACK_LAYOUT_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct {
+ Efl_Ui_Box *indicator;
+ Efl_Ui_Active_View_Container *container;
+ double last_position;
+} Efl_Ui_Active_View_Indicator_Icon_Data;
+
+static void
+_flush_state(Eo *item, double val)
+{
+ Eina_Value v = eina_value_double_init(val);
+
+ efl_layout_signal_message_send(item, 1, v);
+}
+
+static void
+_add_item(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Indicator_Icon_Data *pd)
+{
+ Efl_Canvas_Layout *item;
+
+ item = efl_add(EFL_CANVAS_LAYOUT_CLASS, pd->indicator);
+ elm_widget_theme_object_set(pd->indicator, item,
+ "pager", "indicator", "default");
+ efl_gfx_hint_align_set(item, 0.5, 0.5);
+ efl_gfx_hint_weight_set(item, 0, 0);
+ efl_gfx_hint_fill_set(item, 0, 0);
+ efl_pack_end(pd->indicator, item);
+ _flush_state(item, 0.0);
+}
+
+static void
+_flush_position(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Indicator_Icon_Data *pd)
+{
+ int next = -1, closer;
+ double closer_val;
+
+ for (int i = 0; i < efl_content_count(pd->indicator); ++i)
+ {
+ _flush_state(efl_pack_content_get(pd->indicator, i), 0.0f);
+ }
+
+ closer = MIN(MAX(round(pd->last_position), 0), efl_content_count(pd->container) - 1);
+ closer_val = fabs(1.0f - fabs(closer - pd->last_position));
+
+ _flush_state(efl_pack_content_get(pd->indicator, closer), closer_val);
+
+ if (pd->last_position > closer)
+ next = closer + 1;
+ else if (pd->last_position < closer)
+ next = closer - 1;
+ else
+ {
+ next = closer + 1;
+ if (next < efl_content_count(pd->container))
+ _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
+ next = closer - 1;
+ if (next >= 0)
+ _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
+ }
+
+ if (next >= 0 && next < efl_content_count(pd->container))
+ _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
+}
+
+EOLIAN static void
+_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)
+{
+ if (active_view)
+ {
+ pd->container = active_view;
+ pd->indicator = efl_add(EFL_UI_BOX_CLASS, active_view);
+ efl_ui_widget_internal_set(pd->indicator, EINA_TRUE);
+ efl_content_set(efl_part(pd->container, "efl.indicator"), pd->indicator);
+ efl_gfx_entity_visible_set(pd->indicator, EINA_TRUE);
+ efl_ui_layout_orientation_set(pd->indicator, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL);
+ efl_gfx_arrangement_content_padding_set(pd->indicator, 15, 15, EINA_TRUE);
+
+ for (int i = 0; i < efl_content_count(pd->container); ++i)
+ {
+ _add_item(obj, pd);
+ }
+ }
+}
+
+EOLIAN static void
+_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)
+{
+ _add_item(obj, pd);
+ _flush_position(obj, pd);
+}
+
+EOLIAN static void
+_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)
+{
+ efl_del(efl_pack_content_get(pd->indicator, 0));
+ _flush_position(obj, pd);
+}
+
+EOLIAN static void
+_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)
+{
+ pd->last_position = position;
+ _flush_position(obj, pd);
+}
+
+#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 @@
+class @beta Efl.Ui.Active_View.Indicator_Icon extends Efl.Ui.Active_View.Indicator {
+ implements {
+ Efl.Ui.Active_View.Indicator.bind;
+ Efl.Ui.Active_View.Indicator.content_del;
+ Efl.Ui.Active_View.Indicator.content_add;
+ Efl.Ui.Active_View.Indicator.position_update;
+ }
+}
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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_PACK_LAYOUT_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct {
+
+} Efl_Ui_Active_View_View_Manager_Data;
+
+
+#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 @@
+abstract @beta Efl.Ui.Active_View.View_Manager extends Efl.Object {
+ [[Transition object which is used by active_view.
+
+ The transition object can display changes to the active view with animations.
+ 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.
+ ]]
+ methods {
+ bind @pure_virtual {
+ [[Initial call to flush the required objects of the active view to the transition object]]
+ params {
+ active_view : Efl.Ui.Active_View.Container;
+ group : Efl.Canvas.Group;
+ }
+ }
+ content_add @pure_virtual {
+ [[Content has been added to the container passed in .bind. The $subobj is at position $index.
+
+ While in the call, the $current_page property of the active_view might change.
+ If such a change is happening. No animation should be displayed, and the new state should be applied.
+ ]]
+ params {
+ subobj : Efl.Gfx.Entity;
+ index : int;
+ }
+ }
+ content_del @pure_virtual {
+ [[Content has been removed from the container passed in .bind. The $subobj at position $index is now removed.
+
+ While in the call, the $current_page property of the active_view might change.
+ If such a change is happening. No animation should be displayed, and the new state should be applied.
+ ]]
+ params {
+ subobj : Efl.Gfx.Entity;
+ index : int;
+ }
+ }
+ switch_to @pure_virtual {
+ [[Switch from one side to another, if there has been no side before, from is -1.
+ This function should, if the transition object supports this, display a animation.
+ ]]
+ params {
+ from : int;
+ to : int;
+ }
+ }
+ @property view_size @pure_virtual {
+ [[Will be called whenever the page size changes]]
+ set {
+
+ }
+ values {
+ size : Eina.Size2D; [[The size of the page, real coordiates at any time]]
+ }
+ }
+ @property animation_enabled @pure_virtual {
+ [[This flag can be used to indicate that no animations should be done]]
+ values {
+ enable : bool; [[$true if you want animations to happen, $false if otherwise]]
+ }
+ }
+ }
+ events {
+ 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.]]
+ }
+}
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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Efl_Ui.h>
+#include "elm_priv.h"
+#include "efl_ui_active_view_view_manager_plain.eo.h"
+
+typedef struct {
+ Efl_Ui_Active_View_Container * container;
+ Efl_Gfx_Entity *group;
+ Eina_Size2D page_size;
+ int current_content;
+ Eina_Bool animation;
+} Efl_Ui_Active_View_View_Manager_Plain_Data;
+
+#define MY_CLASS EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_PLAIN_CLASS
+
+static void
+_emit_position(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Plain_Data *pd)
+{
+ double absolut_position = pd->current_content;
+ efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &absolut_position);
+}
+
+static void
+_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Plain_Data *pd)
+{
+ Efl_Gfx_Entity *entity = efl_pack_content_get(pd->container, pd->current_content);
+ Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->group);
+ Eina_Rect goal = EINA_RECT_EMPTY();
+
+ goal.size = pd->page_size;
+ goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
+ goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
+ efl_gfx_entity_geometry_set(entity, goal);
+}
+
+static void
+_resize_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
+}
+
+static void
+_move_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(group_callback,
+ {EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb},
+ {EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb},
+)
+
+EOLIAN static void
+_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)
+{
+ if (active_view && group)
+ {
+ int index;
+
+ pd->container = active_view;
+ pd->group = group;
+
+ efl_event_callback_array_add(pd->group, group_callback(), obj);
+
+ for (int i = 0; i < efl_content_count(active_view) ; ++i) {
+ Efl_Gfx_Entity *elem = efl_pack_content_get(active_view, i);
+ efl_canvas_group_member_add(pd->group, elem);
+ efl_gfx_entity_visible_set(elem, EINA_FALSE);
+ }
+ index = efl_ui_active_view_active_index_get(active_view);
+ if (index != -1)
+ {
+ pd->current_content = index;
+ efl_gfx_entity_visible_set(efl_pack_content_get(pd->container, pd->current_content), EINA_TRUE);
+ _geom_sync(obj, pd);
+ _emit_position(obj, pd);
+ }
+ }
+}
+
+static void
+_content_changed(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd)
+{
+ if (efl_ui_active_view_active_index_get(pd->container) != pd->current_content)
+ {
+ pd->current_content = efl_ui_active_view_active_index_get(pd->container);
+ efl_gfx_entity_visible_set(efl_pack_content_get(pd->container, pd->current_content), EINA_FALSE);
+ _geom_sync(obj, pd);
+ _emit_position(obj, pd);
+ }
+}
+
+EOLIAN static void
+_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)
+{
+ efl_canvas_group_member_add(pd->group, subobj);
+ efl_gfx_entity_visible_set(subobj, EINA_FALSE);
+ _content_changed(obj, pd);
+}
+
+EOLIAN static void
+_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)
+{
+ efl_canvas_group_member_remove(pd->group, subobj);
+ _content_changed(obj, pd);
+}
+EOLIAN static void
+_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)
+{
+ Efl_Gfx_Entity *to_obj, *from_obj;
+ to_obj = efl_pack_content_get(pd->container, to);
+ from_obj = efl_pack_content_get(pd->container, from);
+ if (from_obj)
+ {
+ efl_gfx_entity_visible_set(from_obj, EINA_FALSE);
+ pd->current_content = -1;
+ }
+
+ if (to_obj)
+ {
+ efl_gfx_entity_visible_set(to_obj, EINA_TRUE);
+ pd->current_content = to;
+ }
+
+ _emit_position(obj, pd);
+ _geom_sync(obj, pd);
+}
+
+EOLIAN static void
+_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)
+{
+ pd->page_size = size;
+ _geom_sync(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_active_view_view_manager_plain_efl_object_destructor(Eo *obj, Efl_Ui_Active_View_View_Manager_Plain_Data *pd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+
+ efl_event_callback_array_del(pd->group, group_callback(), obj);
+
+ for (int i = 0; i < efl_content_count(pd->container); ++i)
+ {
+ Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
+ efl_gfx_entity_visible_set(elem, EINA_TRUE);
+ }
+}
+
+EOLIAN static void
+_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)
+{
+ pd->animation = animation;
+}
+
+EOLIAN static Eina_Bool
+_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)
+{
+ return pd->animation;
+}
+
+
+#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 @@
+class @beta Efl.Ui.Active_View.View_Manager_Plain extends Efl.Ui.Active_View.View_Manager
+{
+ implements {
+ Efl.Ui.Active_View.View_Manager.bind;
+ Efl.Ui.Active_View.View_Manager.content_add;
+ Efl.Ui.Active_View.View_Manager.content_del;
+ Efl.Ui.Active_View.View_Manager.switch_to;
+ Efl.Ui.Active_View.View_Manager.view_size {set;}
+ Efl.Ui.Active_View.View_Manager.animation_enabled {set; get;}
+ Efl.Object.destructor;
+ }
+}
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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Efl_Ui.h>
+#include "elm_priv.h"
+
+typedef struct {
+ Efl_Ui_Active_View_Container * container;
+ Efl_Gfx_Entity *group, *foreclip, *backclip;
+ Eina_Size2D page_size;
+ struct {
+ Eina_Bool active;
+ int to;
+ double from, progress;
+ double start_time;
+ double max_time;
+ } transition;
+ struct {
+ Eina_Bool active;
+ int from;
+ Eina_Position2D mouse_start;
+ } mouse_move;
+ Eina_Bool animation;
+} Efl_Ui_Active_View_View_Manager_Scroll_Data;
+
+#define MY_CLASS EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS
+
+static void _page_set_animation(void *data, const Efl_Event *event);
+
+static void
+_propagate_progress(Eo *obj, double pos)
+{
+ efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &pos);
+}
+
+static void
+_apply_box_properties(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd)
+{
+ Eina_Rect geometry = EINA_RECT_EMPTY();
+ Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->group);
+ double current_pos;
+
+ if (pd->transition.active)
+ current_pos = pd->transition.from + ((double)pd->transition.to - pd->transition.from)*pd->transition.progress;
+ else
+ current_pos = efl_ui_active_view_active_index_get(pd->container);
+
+ efl_gfx_entity_geometry_set(pd->foreclip, group_pos);
+ //first calculate the size
+ geometry.h = pd->page_size.h;
+ geometry.w = (pd->page_size.w);
+
+ //calculate the position
+ geometry.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
+
+ for (int i = 0; i < efl_content_count(pd->container) ; ++i)
+ {
+ double diff = i - current_pos;
+ Efl_Gfx_Entity *elem = efl_pack_content_get(pd->container, i);
+
+ geometry.x = (group_pos.x + group_pos.w/2)-(pd->page_size.w/2 - diff*pd->page_size.w);
+ if (!eina_rectangles_intersect(&geometry.rect, &group_pos.rect))
+ {
+ efl_canvas_object_clipper_set(elem, pd->backclip);
+ }
+ else
+ {
+ efl_gfx_entity_geometry_set(elem, geometry);
+ efl_canvas_object_clipper_set(elem, pd->foreclip);
+ }
+ }
+
+ //Propagate progress
+ _propagate_progress(obj, current_pos);
+}
+
+static void
+_resize_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _apply_box_properties(data, efl_data_scope_get(data, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS));
+}
+
+static void
+_move_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _apply_box_properties(data, efl_data_scope_get(data, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_SCROLL_CLASS));
+}
+
+static void
+_mouse_down_cb(void *data,
+ const Efl_Event *event)
+{
+ Efl_Input_Pointer *ev = event->info;
+ Eo *obj = data;
+ Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+
+ if (efl_input_pointer_button_get(ev) != 1) return;
+ if (efl_input_event_flags_get(ev) & EFL_INPUT_FLAGS_PROCESSED) return;
+
+ if (efl_content_count(pd->container) == 0) return;
+
+ efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
+
+ pd->mouse_move.active = EINA_TRUE;
+ pd->mouse_move.from = efl_ui_active_view_active_index_get(pd->container);
+ pd->mouse_move.mouse_start = efl_input_pointer_position_get(ev);
+}
+
+static void
+_mouse_move_cb(void *data,
+ const Efl_Event *event)
+{
+ Efl_Input_Pointer *ev = event->info;
+ Eo *obj = data;
+ Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+ Eina_Position2D pos;
+ int pos_y_diff;
+
+ if (efl_input_event_flags_get(ev) & EFL_INPUT_FLAGS_PROCESSED) return;
+ if (!pd->mouse_move.active) return;
+
+ pos = efl_input_pointer_position_get(ev);
+ pos_y_diff = pd->mouse_move.mouse_start.x - pos.x;
+
+ pd->transition.active = EINA_TRUE;
+ pd->transition.from = pd->mouse_move.from;
+ pd->transition.progress = (double)pos_y_diff / (double)pd->page_size.w;
+ pd->transition.to = pd->transition.from + 1;
+
+ _propagate_progress(data, pd->transition.from + pd->transition.progress);
+
+ _apply_box_properties(obj, pd);
+}
+
+static void
+_mouse_up_cb(void *data,
+ const Efl_Event *event)
+{
+ Efl_Input_Pointer *ev = event->info;
+ Eo *obj = data;
+ Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+
+ if (efl_input_event_flags_get(ev) & EFL_INPUT_FLAGS_PROCESSED) return;
+ if (!pd->mouse_move.active) return;
+
+ double absolut_current_position = (double)pd->transition.from + pd->transition.progress;
+ int result = round(absolut_current_position);
+
+ efl_ui_active_view_active_index_set(pd->container, MIN(MAX(result, 0), efl_content_count(pd->container) - 1));
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(mouse_listeners,
+ {EFL_EVENT_POINTER_DOWN, _mouse_down_cb},
+ {EFL_EVENT_POINTER_UP, _mouse_up_cb},
+ {EFL_EVENT_POINTER_MOVE, _mouse_move_cb},
+);
+
+EOLIAN static void
+_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)
+{
+ if (active_view && group)
+ {
+ pd->container = active_view;
+ pd->group = group;
+ efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
+ efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
+
+ pd->foreclip = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
+ evas_object_evas_get(group));
+ evas_object_static_clip_set(pd->foreclip, EINA_TRUE);
+
+ pd->backclip = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
+ evas_object_evas_get(group));
+ evas_object_static_clip_set(pd->backclip, EINA_TRUE);
+ efl_gfx_entity_visible_set(pd->backclip, EINA_FALSE);
+
+ for (int i = 0; i < efl_content_count(active_view) ; ++i) {
+ Efl_Gfx_Entity *elem = efl_pack_content_get(active_view, i);
+ efl_canvas_object_clipper_set(elem, pd->backclip);
+ efl_canvas_group_member_add(pd->group, elem);
+ efl_gfx_entity_visible_set(elem, EINA_TRUE);
+ }
+ _apply_box_properties(obj, pd);
+
+ efl_event_callback_array_add(efl_content_get(efl_part(pd->container, "efl.event")), mouse_listeners(), obj);
+ }
+
+}
+
+EOLIAN static void
+_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)
+{
+ efl_gfx_entity_visible_set(subobj, EINA_TRUE);
+ efl_canvas_object_clipper_set(subobj, pd->backclip);
+ efl_canvas_group_member_add(pd->group, subobj);
+
+ if (!pd->transition.active)
+ _apply_box_properties(obj, pd);
+}
+
+
+EOLIAN static void
+_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)
+{
+ efl_canvas_object_clipper_set(subobj, NULL);
+ efl_canvas_group_member_remove(pd->group, subobj);
+
+ if (!pd->transition.active)
+ _apply_box_properties(obj, pd);
+}
+
+static void
+_page_set_animation(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Efl_Ui_Active_View_View_Manager_Scroll_Data *pd = efl_data_scope_get(data, MY_CLASS);
+ double p = (ecore_loop_time_get() - pd->transition.start_time) / pd->transition.max_time;
+
+ if (p >= 1.0) p = 1.0;
+ p = ecore_animator_pos_map(p, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
+
+ pd->transition.progress = p;
+
+ if (EINA_DBL_EQ(p, 1.0))
+ {
+ efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK,
+ _page_set_animation, data);
+ pd->transition.active = EINA_FALSE;
+ }
+ _apply_box_properties(data, pd);
+}
+
+static void
+_animation_request_switch(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd, int from, int to)
+{
+ efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
+ //if there is a ongoing transition, try to guess a better time, and try copy over the position where we are right now
+ if (pd->transition.active || pd->mouse_move.active)
+ {
+ pd->transition.from = MIN(pd->transition.from, pd->transition.to) + pd->transition.progress;
+ pd->transition.max_time = MIN(MAX(fabs(pd->transition.progress), 0.2), 0.5f);
+ pd->mouse_move.active = EINA_FALSE;
+ pd->transition.progress = 0.0f;
+ }
+ else
+ {
+ pd->transition.from = from;
+ pd->transition.max_time = 0.5;
+ }
+ pd->transition.start_time = ecore_loop_time_get();
+ pd->transition.active = EINA_TRUE;
+ pd->transition.to = to;
+ efl_event_callback_add(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
+}
+
+EOLIAN static void
+_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)
+{
+ if (pd->animation)
+ {
+ _animation_request_switch(obj, pd, from, to);
+ }
+ else
+ {
+ pd->mouse_move.active = EINA_FALSE;
+ pd->transition.active = EINA_FALSE;
+ _apply_box_properties(obj, pd);
+ }
+}
+
+EOLIAN static void
+_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)
+{
+ pd->page_size = size;
+ if (!pd->transition.active)
+ _apply_box_properties(obj, pd);
+}
+
+EOLIAN static void
+_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)
+{
+ pd->animation = animation;
+ if (pd->transition.active && !animation)
+ {
+ efl_event_callback_del(pd->container, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _page_set_animation, obj);
+ _apply_box_properties(obj, pd);
+ pd->transition.active = EINA_FALSE;
+ }
+}
+
+EOLIAN static Eina_Bool
+_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)
+{
+ return pd->animation;
+}
+
+
+EOLIAN static void
+_efl_ui_active_view_view_manager_scroll_efl_object_destructor(Eo *obj, Efl_Ui_Active_View_View_Manager_Scroll_Data *pd EINA_UNUSED)
+{
+ efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
+ efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
+ efl_event_callback_array_del(efl_content_get(efl_part(pd->container, "efl.event")), mouse_listeners(), obj);
+ efl_del(pd->backclip);
+ efl_del(pd->foreclip);
+
+ for (int i = 0; i < efl_content_count(pd->container); ++i)
+ {
+ efl_canvas_object_clipper_set(efl_pack_content_get(pd->container, i), NULL);
+ }
+
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+
+#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 @@
+class @beta Efl.Ui.Active_View.View_Manager_Scroll extends Efl.Ui.Active_View.View_Manager
+{
+ implements {
+ Efl.Ui.Active_View.View_Manager.bind;
+ Efl.Ui.Active_View.View_Manager.content_add;
+ Efl.Ui.Active_View.View_Manager.content_del;
+ Efl.Ui.Active_View.View_Manager.switch_to;
+ Efl.Ui.Active_View.View_Manager.view_size {set;}
+ Efl.Ui.Active_View.View_Manager.animation_enabled {set; get;}
+ Efl.Object.destructor;
+ }
+}
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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Efl_Ui.h>
+#include "elm_priv.h"
+
+
+typedef struct {
+ Efl_Ui_Active_View_Container * container;
+ Efl_Gfx_Entity *group;
+ Efl_Canvas_Animation_Player *hide, *show;
+ int from, to;
+ Efl_Gfx_Entity *content;
+ Eina_Size2D page_size;
+ Eina_Bool animation;
+} Efl_Ui_Active_View_View_Manager_Stack_Data;
+
+#define MY_CLASS EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_STACK_CLASS
+
+static void
+_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_View_Manager_Stack_Data *pd)
+{
+ Eina_Array *array = eina_array_new(2);
+ Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->group);
+ if (efl_player_play_get(pd->hide))
+ {
+ //we are currently in animation, sync the geometry of the targets
+ eina_array_push(array, efl_animation_player_target_get(pd->hide));
+ eina_array_push(array, efl_animation_player_target_get(pd->show));
+ }
+ else
+ {
+ //we only have our content right now, or nothing
+ eina_array_push(array, pd->content);
+ }
+ Eina_Rect goal = EINA_RECT_EMPTY();
+ goal.size = pd->page_size;
+ goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
+ goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
+ while (eina_array_count(array) > 0)
+ {
+ Efl_Gfx_Entity *subobj = eina_array_pop(array);
+ efl_gfx_entity_geometry_set(subobj, goal);
+ }
+ eina_array_free(array);
+}
+
+static void
+_resize_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
+}
+
+static void
+_move_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _geom_sync(data, efl_data_scope_get(data, MY_CLASS));
+}
+
+static void
+_running_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Efl_Ui_Active_View_View_Manager_Stack_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
+
+ //calculate absolut position, multiply pos with 2.0 because duration is only 0.5)
+ double absolut_position = pd->from + (pd->to - pd->from)*(efl_player_pos_get(pd->show)*2.0);
+ efl_event_callback_call(data, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &absolut_position);
+}
+
+static void
+_anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Efl_Canvas_Object *content;
+
+ content = efl_animation_player_target_get(event->object);
+ efl_gfx_entity_visible_set(content, EINA_TRUE);
+}
+
+static void
+_hide_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Efl_Ui_Active_View_View_Manager_Stack_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
+ Efl_Canvas_Object *content;
+
+ EINA_SAFETY_ON_NULL_RETURN(pd);
+ content = efl_animation_player_target_get(pd->hide);
+ efl_gfx_entity_visible_set(content, EINA_FALSE);
+}
+
+static void
+_show_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Efl_Ui_Active_View_View_Manager_Stack_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
+ Efl_Canvas_Object *content;
+
+ EINA_SAFETY_ON_NULL_RETURN(pd);
+ content = efl_animation_player_target_get(pd->show);
+ efl_gfx_entity_visible_set(content, EINA_TRUE);
+ pd->content = content;
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(_anim_show_event_cb,
+ {EFL_ANIMATION_PLAYER_EVENT_RUNNING, _running_cb},
+ {EFL_ANIMATION_PLAYER_EVENT_STARTED, _anim_started_cb},
+ {EFL_ANIMATION_PLAYER_EVENT_ENDED, _show_anim_ended_cb},
+)
+
+EFL_CALLBACKS_ARRAY_DEFINE(_anim_hide_event_cb,
+ {EFL_ANIMATION_PLAYER_EVENT_STARTED, _anim_started_cb},
+ {EFL_ANIMATION_PLAYER_EVENT_ENDED, _hide_anim_ended_cb},
+)
+
+EOLIAN static void
+_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)
+{
+ if (active_view && group)
+ {
+ Efl_Canvas_Animation_Alpha *show_anim, *hide_anim;
+ pd->container = active_view;
+ pd->group = group;
+
+ efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
+ efl_event_callback_add(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
+
+ show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj);
+ efl_animation_alpha_set(show_anim, 0.0, 1.0);
+ efl_animation_duration_set(show_anim, 0.5);
+ efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
+
+ pd->show = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj);
+ efl_animation_player_animation_set(pd->show, show_anim);
+ efl_player_play_set(pd->show, EINA_FALSE);
+ efl_event_callback_array_add(pd->show, _anim_show_event_cb(), obj);
+
+ //Default Hide Animation
+ hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj);
+ efl_animation_alpha_set(hide_anim, 1.0, 0.0);
+ efl_animation_duration_set(hide_anim, 0.5);
+ efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
+
+ pd->hide = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj);
+ efl_animation_player_animation_set(pd->hide, hide_anim);
+ efl_player_play_set(pd->hide, EINA_FALSE);
+ efl_event_callback_array_add(pd->hide, _anim_hide_event_cb(), obj);
+
+ for (int i = 0; i < efl_content_count(active_view) ; ++i) {
+ Efl_Gfx_Entity *elem = efl_pack_content_get(active_view, i);
+ efl_canvas_group_member_add(pd->group, elem);
+ efl_gfx_entity_visible_set(elem, EINA_FALSE);
+ }
+ if (efl_ui_active_view_active_index_get(active_view) != -1)
+ {
+ pd->content = efl_pack_content_get(pd->container, efl_ui_active_view_active_index_get(active_view));
+ efl_gfx_entity_visible_set(pd->content, EINA_TRUE);
+ _geom_sync(obj, pd);
+ }
+ }
+}
+
+EOLIAN static void
+_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)
+{
+ efl_canvas_group_member_add(pd->group, subobj);
+ efl_gfx_entity_visible_set(subobj, EINA_FALSE);
+}
+
+EOLIAN static void
+_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)
+{
+ efl_canvas_group_member_remove(pd->group, subobj);
+}
+
+static void
+_setup_anim(Efl_Animation_Player *player, Efl_Gfx_Entity *entity)
+{
+ efl_player_stop(player);
+ efl_animation_player_target_set(player, entity);
+ efl_player_start(player);
+}
+
+EOLIAN static void
+_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)
+{
+ if (from != -1)
+ {
+ if (pd->animation)
+ {
+ pd->from = from;
+ pd->to = to;
+ pd->content = NULL;
+ _setup_anim(pd->hide, efl_pack_content_get(pd->container, from));
+ _setup_anim(pd->show, efl_pack_content_get(pd->container, to));
+ }
+ else
+ {
+ efl_gfx_entity_visible_set(efl_pack_content_get(pd->container, from), EINA_FALSE);
+ pd->content = efl_pack_content_get(pd->container, to);
+ efl_gfx_entity_visible_set(pd->content, EINA_TRUE);
+ }
+ }
+ else
+ {
+ double pos = to;
+
+ pd->content = efl_pack_content_get(pd->container, to);
+ efl_gfx_entity_visible_set(pd->content, EINA_TRUE);
+ efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &pos);
+ }
+
+ _geom_sync(obj, pd);
+}
+
+EOLIAN static void
+_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)
+{
+ pd->page_size = size;
+ _geom_sync(obj, pd);
+}
+
+EOLIAN static void
+_efl_ui_active_view_view_manager_stack_efl_object_destructor(Eo *obj, Efl_Ui_Active_View_View_Manager_Stack_Data *pd EINA_UNUSED)
+{
+ efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb, obj);
+ efl_event_callback_del(pd->group, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _move_cb, obj);
+
+ efl_destructor(efl_super(obj, MY_CLASS));
+
+ for (int i = 0; i < efl_content_count(pd->container); ++i)
+ {
+ Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
+ for (int d = 0; d < 4; d++)
+ {
+ efl_gfx_mapping_color_set(elem, d, 255, 255, 255, 255);
+ }
+ }
+}
+
+static void
+_reset_player(Efl_Animation_Player *player, Eina_Bool vis)
+{
+ Efl_Gfx_Entity *obj;
+
+ obj = efl_animation_player_target_get(player);
+ efl_player_stop(player);
+ efl_animation_player_target_set(player, NULL);
+ efl_gfx_entity_visible_set(obj, vis);
+}
+
+EOLIAN static void
+_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)
+{
+ _reset_player(pd->hide, EINA_FALSE);
+ _reset_player(pd->show, EINA_TRUE);
+ pd->animation = animation;
+}
+
+EOLIAN static Eina_Bool
+_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)
+{
+ return pd->animation;
+}
+
+
+#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 @@
+class @beta Efl.Ui.Active_View.View_Manager_Stack extends Efl.Ui.Active_View.View_Manager
+{
+ implements {
+ Efl.Ui.Active_View.View_Manager.bind;
+ Efl.Ui.Active_View.View_Manager.content_add;
+ Efl.Ui.Active_View.View_Manager.content_del;
+ Efl.Ui.Active_View.View_Manager.switch_to;
+ Efl.Ui.Active_View.View_Manager.view_size {set;}
+ Efl.Ui.Active_View.View_Manager.animation_enabled {set; get;}
+ Efl.Object.destructor;
+ }
+}
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 = [
'efl_ui_dnd_container.eo',
'efl_ui_focus_manager_window_root.eo',
'efl_ui_pager.eo',
+ 'efl_ui_active_view_container.eo',
+ 'efl_ui_active_view_view_manager.eo',
+ 'efl_ui_active_view_view_manager_scroll.eo',
+ 'efl_ui_active_view_view_manager_stack.eo',
+ 'efl_ui_active_view_indicator.eo',
+ 'efl_ui_active_view_indicator_icon.eo',
'efl_page_transition.eo',
'efl_page_transition_scroll.eo',
'efl_page_indicator.eo',
@@ -230,6 +236,7 @@ priv_eo_files = [
'efl_ui_homogeneous_model.eo',
'efl_ui_exact_model.eo',
'efl_ui_average_model.eo',
+ 'efl_ui_active_view_view_manager_plain.eo',
]
priv_eo_file_target = []
@@ -917,6 +924,13 @@ elementary_src = [
'efl_ui_dnd.c',
'elm_focus_legacy.c',
'efl_ui_pager.c',
+ 'efl_ui_active_view_container.c',
+ 'efl_ui_active_view_view_manager.c',
+ 'efl_ui_active_view_view_manager_plain.c',
+ 'efl_ui_active_view_view_manager_scroll.c',
+ 'efl_ui_active_view_view_manager_stack.c',
+ 'efl_ui_active_view_indicator.c',
+ 'efl_ui_active_view_indicator_icon.c',
'efl_page_transition.c',
'efl_page_transition_scroll.c',
'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 @@
#include "efl_ui_suite.h"
#include "suite_helpers.h"
+#include "eo_internal.h"
static const Efl_Test_Case etc[] = {
//{ "elm_focus", elm_test_focus},
@@ -24,9 +25,12 @@ static const Efl_Test_Case etc[] = {
{ "efl_ui_layout", efl_ui_test_layout},
{ "Efl_Ui_Model", efl_ui_model },
{ "efl_ui_widget", efl_ui_test_widget },
+ { "efl_ui_active_view", efl_ui_test_active_view},
{ NULL, NULL }
};
+EFL_CLASS_SIMPLE_CLASS(efl_ui_widget, "efl_ui_widget", EFL_UI_WIDGET_CLASS);
+
int
main(int argc, char **argv)
{
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);
void efl_ui_model(TCase *tc);
void efl_ui_test_widget(TCase *tc);
+void efl_ui_test_active_view(TCase *tc);
void loop_timer_interval_set(Eo *obj, double in);
#define efl_loop_timer_interval_set loop_timer_interval_set
+const Efl_Class* efl_ui_widget_realized_class_get(void);
+#define WIDGET_CLASS efl_ui_widget_realized_class_get()
+
Eo *win_add();
Eo *win_add_focused();
#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 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Efl_Ui.h>
+#include "efl_ui_suite.h"
+#include "eo_internal.h"
+
+EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_view_manager, "efl_ui_active_view_view_manager", EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_CLASS);
+EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_indicator, "efl_ui_active_view_indicator", EFL_UI_ACTIVE_VIEW_INDICATOR_CLASS);
+
+static Efl_Ui_Win *win;
+static Efl_Ui_Active_View_Container *container;
+static int tree_abort;
+static int tree_abort_level;
+
+static void
+_shutdown(void)
+{
+ eina_log_abort_on_critical_set(tree_abort);
+ eina_log_abort_on_critical_level_set(tree_abort_level);
+}
+
+static void
+_setup(void)
+{
+ tree_abort = eina_log_abort_on_critical_get();
+ tree_abort_level = eina_log_abort_on_critical_level_get();
+ eina_log_abort_on_critical_level_set(2);
+ eina_log_abort_on_critical_set(1);
+}
+static void
+active_view_setup()
+{
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC));
+
+ container = efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, win,
+ efl_content_set(win, efl_added));
+
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(200, 200));
+}
+
+static void
+active_view_teardown()
+{
+ if (win)
+ {
+ efl_del(win);
+ win = NULL;
+ }
+}
+
+typedef struct {
+ struct {
+ int called;
+ double position;
+ } position_update;
+ struct {
+ int called;
+ Efl_Gfx_Entity *subobj;
+ int index;
+ int current_page_at_call;
+ } content_del;
+ struct {
+ int called;
+ Efl_Gfx_Entity *subobj;
+ int index;
+ int current_page_at_call;
+ } content_add;
+ struct {
+ int called;
+ Efl_Ui_Active_View_Container *active_view;
+ } active_view;
+} Indicator_Calls;
+
+Indicator_Calls indicator_calls = { 0 };
+
+static void
+_indicator_content_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
+{
+ indicator_calls.content_del.called ++;
+ indicator_calls.content_del.subobj = subobj;
+ indicator_calls.content_del.index = index;
+ indicator_calls.content_del.current_page_at_call = efl_ui_active_view_active_index_get(container);
+}
+
+static void
+_indicator_content_add(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
+{
+ indicator_calls.content_add.called ++;
+ indicator_calls.content_add.subobj = subobj;
+ indicator_calls.content_add.index = index;
+ indicator_calls.content_add.current_page_at_call = efl_ui_active_view_active_index_get(container);
+}
+
+static void
+_indicator_position_update(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, double position)
+{
+ indicator_calls.position_update.called ++;
+ indicator_calls.position_update.position = position;
+}
+
+static void
+_indicator_bind(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Ui_Active_View_Container *active_view)
+{
+ indicator_calls.active_view.called++;
+ indicator_calls.active_view.active_view = active_view;
+}
+
+EFL_OPS_DEFINE(indicator_tracker,
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_content_add, _indicator_content_add),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_content_del, _indicator_content_del),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_position_update, _indicator_position_update),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_indicator_bind, _indicator_bind),
+);
+
+static Efl_Ui_Active_View_View_Manager*
+_create_indicator(void)
+{
+ Eo *obj;
+
+ obj = efl_add(efl_ui_active_view_indicator_realized_class_get(), win);
+ efl_object_override(obj, &indicator_tracker);
+
+ return obj;
+}
+
+typedef struct {
+ struct {
+ int called;
+ Efl_Gfx_Entity *subobj;
+ int index;
+ int current_page_at_call;
+ } content_del;
+ struct {
+ int called;
+ Efl_Gfx_Entity *subobj;
+ int index;
+ int current_page_at_call;
+ } content_add;
+ struct {
+ int called;
+ int from;
+ int to;
+ } request_switch;
+ struct {
+ int called;
+ Eina_Size2D size;
+ } page_size;
+ struct {
+ int called;
+ Efl_Ui_Active_View_Container *active_view;
+ Efl_Canvas_Group *group;
+ } active_view;
+ struct {
+ int called;
+ } animation;
+ double last_position;
+} Transition_Calls;
+
+Transition_Calls transition_calls = { 0 };
+
+static void
+_emit_pos(Eo *obj, double d)
+{
+ if (d == transition_calls.last_position) return;
+ efl_event_callback_call(obj, EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_EVENT_POS_UPDATE, &d);
+ transition_calls.last_position = d;
+}
+
+static void
+_transition_content_add(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
+{
+ transition_calls.content_add.called ++;
+ transition_calls.content_add.subobj = subobj;
+ transition_calls.content_add.index = index;
+ transition_calls.content_add.current_page_at_call = efl_ui_active_view_active_index_get(container);
+
+ int i = efl_ui_active_view_active_index_get(container);
+ if (i != -1)
+ _emit_pos(obj, i);
+}
+
+static void
+_transition_content_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
+{
+ transition_calls.content_del.called ++;
+ transition_calls.content_del.subobj = subobj;
+ transition_calls.content_del.index = index;
+ transition_calls.content_del.current_page_at_call = efl_ui_active_view_active_index_get(container);
+
+ int i = efl_ui_active_view_active_index_get(container);
+ if (i != -1)
+ _emit_pos(obj, i);
+}
+
+static void
+_transition_request_switch(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, int from, int to)
+{
+ transition_calls.request_switch.called++;
+ transition_calls.request_switch.from = from;
+ transition_calls.request_switch.to = to;
+
+ _emit_pos(obj, to);
+}
+
+static void
+_transition_page_size_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Size2D size)
+{
+ transition_calls.page_size.called++;
+ transition_calls.page_size.size = size;
+}
+
+static void
+_transition_bind(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Ui_Active_View_Container *active_view, Efl_Canvas_Group *group)
+{
+ transition_calls.active_view.called++;
+ transition_calls.active_view.active_view = active_view;
+ transition_calls.active_view.group = group;
+}
+
+static void
+_transition_animation_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Bool animation)
+{
+ transition_calls.animation.called++;
+ ck_assert_int_eq(animation, EINA_TRUE);
+}
+
+static Eina_Bool
+_transition_animation_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED)
+{
+ return EINA_TRUE;
+}
+
+EFL_OPS_DEFINE(transition_tracker,
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_animation_enabled_set, _transition_animation_set),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_animation_enabled_get, _transition_animation_get),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_content_add, _transition_content_add),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_content_del, _transition_content_del),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_switch_to, _transition_request_switch),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_view_size_set, _transition_page_size_set),
+ EFL_OBJECT_OP_FUNC(efl_ui_active_view_view_manager_bind, _transition_bind),
+);
+
+static Efl_Ui_Active_View_View_Manager*
+_create_transition(void)
+{
+ Eo *obj;
+
+ obj = efl_add(efl_ui_active_view_view_manager_realized_class_get(), win);
+ efl_object_override(obj, &transition_tracker);
+
+ return obj;
+}
+
+EFL_START_TEST (efl_ui_active_view_init)
+{
+ ck_assert_ptr_ne(container, NULL);
+ ck_assert_ptr_ne(win, NULL);
+ ck_assert_ptr_eq(efl_ui_active_view_indicator_get(container), NULL);
+ ck_assert_ptr_eq(efl_ui_active_view_manager_get(container), NULL);
+ Eina_Size2D s = efl_ui_active_view_size_get(container);
+ ck_assert_int_eq(s.w, 0); //FIXME
+ ck_assert_int_eq(s.h, 0); //FIXME
+ ck_assert_int_eq(efl_ui_active_view_active_index_get(container), -1);
+}
+EFL_END_TEST
+
+EFL_START_TEST (efl_ui_active_view_active_index)
+{
+ Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
+ efl_pack(container, w);
+ ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 0);
+
+ for (int i = -20; i < 20; ++i)
+ {
+ if (i == 0) continue;
+ EXPECT_ERROR_START;
+ efl_ui_active_view_active_index_set(container, i);
+ EXPECT_ERROR_END;
+ }
+ efl_del(w);
+ ck_assert_int_eq(efl_ui_active_view_active_index_get(container), -1);
+}
+EFL_END_TEST
+
+EFL_START_TEST (efl_ui_smart_transition_calls)
+{
+ Efl_Ui_Widget *w, *w1, *w2;
+ Efl_Ui_Active_View_View_Manager*t = _create_transition();
+
+ w = efl_add(WIDGET_CLASS, win);
+ w1 = efl_add(WIDGET_CLASS, win);
+ w2 = efl_add(WIDGET_CLASS, win);
+
+ efl_ui_active_view_manager_set(container, t);
+ transition_calls.last_position = -2.0;
+ ck_assert_int_eq(transition_calls.animation.called, 1);
+ ck_assert_int_eq(transition_calls.active_view.called, 1);
+ ck_assert_ptr_eq(transition_calls.active_view.active_view, container);
+ //We cannot verify group
+ ck_assert_int_eq(transition_calls.page_size.called, 1);
+ ck_assert_int_eq(transition_calls.page_size.size.w, 0); //FIXME
+ ck_assert_int_eq(transition_calls.page_size.size.h, 0); //FIXME
+ ck_assert_int_eq(transition_calls.request_switch.called, 0);
+ ck_assert_int_eq(transition_calls.content_add.called, 0);
+ ck_assert_int_eq(transition_calls.content_del.called, 0);
+ transition_calls.active_view.called = 0;
+ transition_calls.page_size.called = 0;
+
+ //must update content, and request a switch from -1 to 1
+ efl_pack(container, w);
+ ck_assert_int_eq(transition_calls.active_view.called, 0);
+ ck_assert_int_eq(transition_calls.page_size.called, 0);
+ ck_assert_int_eq(transition_calls.request_switch.called, 1);
+ ck_assert_int_eq(transition_calls.request_switch.from, -1);
+ ck_assert_int_eq(transition_calls.request_switch.to, 0);
+ ck_assert_int_eq(transition_calls.content_add.called, 1);
+ ck_assert_int_eq(transition_calls.content_add.index, 0);
+ ck_assert_ptr_eq(transition_calls.content_add.subobj, w);
+ ck_assert_int_eq(transition_calls.content_add.current_page_at_call, -1);
+ ck_assert_int_eq(transition_calls.content_del.called, 0);
+ transition_calls.content_add.called = 0;
+ transition_calls.request_switch.called = 0;
+
+ //this must update content and a updated current page, but no other call
+ efl_pack_begin(container, w1);
+ ck_assert_int_eq(transition_calls.active_view.called, 0);
+ ck_assert_int_eq(transition_calls.page_size.called, 0);
+ ck_assert_int_eq(transition_calls.request_switch.called, 0);
+ ck_assert_int_eq(transition_calls.content_add.called, 1);
+ ck_assert_int_eq(transition_calls.content_add.index, 0);
+ ck_assert_ptr_eq(transition_calls.content_add.subobj, w1);
+ ck_assert_int_eq(transition_calls.content_add.current_page_at_call, 1);
+ ck_assert_int_eq(transition_calls.content_del.called, 0);
+ transition_calls.content_add.called = 0;
+ transition_calls.request_switch.called = 0;
+ ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 1);
+
+ //new object, must update the content and a not update current page
+ efl_pack_end(container, w2);
+ ck_assert_int_eq(transition_calls.active_view.called, 0);
+ ck_assert_int_eq(transition_calls.page_size.called, 0);
+ ck_assert_int_eq(transition_calls.request_switch.called, 0);
+ ck_assert_int_eq(transition_calls.content_add.called, 1);
+ ck_assert_int_eq(transition_calls.content_add.index, 2);
+ ck_assert_ptr_eq(transition_calls.content_add.subobj, w2);
+ ck_assert_int_eq(transition_calls.content_add.current_page_at_call, 1);
+ ck_assert_int_eq(transition_calls.content_del.called, 0);
+ transition_calls.content_add.called = 0;
+ ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 1);
+
+ //page change must result in a call to request a switch
+ efl_ui_active_view_active_index_set(container, 2);
+ ck_assert_int_eq(transition_calls.active_view.called, 0);
+ ck_assert_int_eq(transition_calls.page_size.called, 0);
+ ck_assert_int_eq(transition_calls.request_switch.called, 1);
+ ck_assert_int_eq(transition_calls.request_switch.from, 1);
+ ck_assert_int_eq(transition_calls.request_switch.to, 2);
+ ck_assert_int_eq(transition_calls.content_add.called, 0);
+ ck_assert_int_eq(transition_calls.content_del.called, 0);
+ transition_calls.request_switch.called = 0;
+
+ //deletion of object must result in a content update
+ efl_del(w);
+ ck_assert_int_eq(transition_calls.active_view.called, 0);
+ ck_assert_int_eq(transition_calls.page_size.called, 0);
+ ck_assert_int_eq(transition_calls.request_switch.called, 0);
+ ck_assert_int_eq(transition_calls.content_add.called, 0);
+ ck_assert_int_eq(transition_calls.content_del.called, 1);
+ ck_assert_int_eq(transition_calls.content_del.index, 1);
+ ck_assert_ptr_eq(transition_calls.content_del.subobj, w);
+ ck_assert_int_eq(transition_calls.content_del.current_page_at_call, 1);
+ transition_calls.content_del.called = 0;
+}
+EFL_END_TEST
+
+
+EFL_START_TEST (efl_ui_smart_transition_lifetime)
+{
+ Efl_Ui_Active_View_View_Manager*t, *t1;
+
+ t = _create_transition();
+ efl_wref_add(t, &t);
+ t1 = _create_transition();
+ efl_wref_add(t1, &t1);
+
+ efl_ui_active_view_manager_set(container, t);
+ efl_ui_active_view_manager_set(container, t1);
+ ck_assert_ptr_eq(t, NULL);
+}
+EFL_END_TEST
+
+static void
+_verify_indicator_calls(void)
+{
+ Efl_Ui_Widget *w, *w1, *w2;
+
+ w = efl_add(WIDGET_CLASS, win);
+ w1 = efl_add(WIDGET_CLASS, win);
+ w2 = efl_add(WIDGET_CLASS, win);
+
+ ck_assert_int_eq(indicator_calls.active_view.called, 1);
+ ck_assert_ptr_eq(indicator_calls.active_view.active_view, container);
+ ck_assert_int_eq(indicator_calls.content_add.called, 0);
+ ck_assert_int_eq(indicator_calls.content_del.called, 0);
+ ck_assert_int_eq(indicator_calls.position_update.called, 0);
+ indicator_calls.active_view.called = 0;
+
+ efl_pack(container, w);
+ ck_assert_int_eq(indicator_calls.active_view.called, 0);
+ ck_assert_int_eq(indicator_calls.content_add.called, 1);
+ ck_assert_int_eq(indicator_calls.content_add.index, 0);
+ ck_assert_ptr_eq(indicator_calls.content_add.subobj, w);
+ ck_assert_int_eq(indicator_calls.content_del.called, 0);
+ ck_assert_int_eq(indicator_calls.position_update.called, 1);
+ ck_assert(indicator_calls.position_update.position == 0.0);
+ indicator_calls.content_add.called = 0;
+ indicator_calls.position_update.called = 0;
+
+ efl_pack_begin(container, w1);
+ ck_assert_int_eq(indicator_calls.active_view.called, 0);
+ ck_assert_int_eq(indicator_calls.content_add.called, 1);
+ ck_assert_int_eq(indicator_calls.content_add.index, 0);
+ ck_assert_ptr_eq(indicator_calls.content_add.subobj, w1);
+ ck_assert_int_eq(indicator_calls.content_del.called, 0);
+ ck_assert_int_eq(indicator_calls.position_update.called, 1);
+ ck_assert(indicator_calls.position_update.position == 1.0);
+ indicator_calls.content_add.called = 0;
+ indicator_calls.position_update.called = 0;
+
+ efl_pack_end(container, w2);
+ ck_assert_int_eq(indicator_calls.active_view.called, 0);
+ ck_assert_int_eq(indicator_calls.content_add.called, 1);
+ ck_assert_int_eq(indicator_calls.content_add.index, 2);
+ ck_assert_ptr_eq(indicator_calls.content_add.subobj, w2);
+ ck_assert_int_eq(indicator_calls.content_del.called, 0);
+ ck_assert_int_eq(indicator_calls.position_update.called, 0);
+ indicator_calls.content_add.called = 0;
+ indicator_calls.position_update.called = 0;
+
+ efl_del(w1);
+ ck_assert_int_eq(indicator_calls.active_view.called, 0);
+ ck_assert_int_eq(indicator_calls.content_add.called, 0);
+ ck_assert_int_eq(indicator_calls.content_del.called, 1);
+ ck_assert_int_eq(indicator_calls.content_del.index, 0);
+ ck_assert_ptr_eq(indicator_calls.content_del.subobj, w1);
+ ck_assert_int_eq(indicator_calls.position_update.called, 1);
+ ck_assert(indicator_calls.position_update.position == 0.0);
+ indicator_calls.content_del.called = 0;
+ indicator_calls.position_update.called = 0;
+}
+
+EFL_START_TEST (efl_ui_smart_indicator_calls)
+{
+ Efl_Ui_Active_View_View_Manager*i = _create_indicator();
+ efl_ui_active_view_indicator_set(container, i);
+ _verify_indicator_calls();
+}
+EFL_END_TEST
+
+EFL_START_TEST (efl_ui_smart_indicator_transition_calls)
+{
+ Efl_Ui_Active_View_View_Manager *i = _create_indicator();
+ Efl_Ui_Active_View_View_Manager *t = _create_transition();
+
+ transition_calls.last_position = -2.0;
+ efl_ui_active_view_indicator_set(container, i);
+ efl_ui_active_view_manager_set(container, t);
+ _verify_indicator_calls();
+}
+EFL_END_TEST
+
+Efl_Ui_Active_View_Transition_Event start;
+Efl_Ui_Active_View_Transition_Event end;
+
+static void
+_start(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ Efl_Ui_Active_View_Transition_Event *e = ev->info;
+
+ memcpy(&start, e, sizeof(Efl_Ui_Active_View_Transition_Event));
+}
+
+static void
+_end(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ Efl_Ui_Active_View_Transition_Event *e = ev->info;
+
+ memcpy(&end, e, sizeof(Efl_Ui_Active_View_Transition_Event));
+}
+
+#define EV_RESET \
+ start.from = -8; \
+ start.to = -8; \
+ end.from = -8; \
+ end.to = -8;
+
+static void
+_verify_transition_start_end_events(void)
+{
+ Efl_Ui_Widget *w, *w1, *w2;
+
+ w = efl_add(WIDGET_CLASS, win);
+ w1 = efl_add(WIDGET_CLASS, win);
+ w2 = efl_add(WIDGET_CLASS, win);
+
+ efl_event_callback_add(container, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_START, _start, NULL);
+ efl_event_callback_add(container, EFL_UI_ACTIVE_VIEW_EVENT_TRANSITION_END, _end, NULL);
+
+ EV_RESET
+ efl_pack_end(container, w);
+ ck_assert_int_eq(start.to, 0);
+ ck_assert_int_eq(end.to, 0);
+ ck_assert_int_eq(start.from, -1);
+ ck_assert_int_eq(end.from, -1);
+
+ EV_RESET
+ efl_pack_begin(container, w1);
+ efl_pack_end(container, w2);
+ ck_assert_int_eq(start.to, -8);
+ ck_assert_int_eq(end.to, -8);
+ ck_assert_int_eq(start.from, -8);
+ ck_assert_int_eq(end.from, -8);
+
+ EV_RESET
+ efl_ui_active_view_active_index_set(container, 2);
+ ck_assert_int_eq(start.to, 2);
+ ck_assert_int_eq(end.to, 2);
+ ck_assert_int_eq(start.from, 1);
+ ck_assert_int_eq(end.from, 1);
+}
+
+EFL_START_TEST (efl_ui_active_view_view_manager_start_end)
+{
+ transition_calls.last_position = -2.0;
+
+ _verify_transition_start_end_events();
+}
+EFL_END_TEST
+
+EFL_START_TEST (efl_ui_active_view_active_index_not_update)
+{
+ efl_ui_active_view_gravity_set(container, EFL_UI_ACTIVE_VIEW_CONTAINER_GRAVITY_INDEX);
+
+ for (int i = 0; i < 5; ++i)
+ {
+ Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
+ efl_pack(container, w);
+ ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 0);
+ }
+
+ efl_del(efl_pack_content_get(container, 0));
+ ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 0);
+}
+EFL_END_TEST
+
+void efl_ui_test_active_view(TCase *tc)
+{
+ tcase_add_checked_fixture(tc, _setup, _shutdown);
+ tcase_add_checked_fixture(tc, active_view_setup, active_view_teardown);
+ tcase_add_test(tc, efl_ui_active_view_init);
+ tcase_add_test(tc, efl_ui_active_view_active_index);
+ tcase_add_test(tc, efl_ui_smart_transition_calls);
+ tcase_add_test(tc, efl_ui_smart_transition_lifetime);
+ tcase_add_test(tc, efl_ui_smart_indicator_calls);
+ tcase_add_test(tc, efl_ui_smart_indicator_transition_calls);
+ tcase_add_test(tc, efl_ui_active_view_view_manager_start_end);
+ tcase_add_test(tc, efl_ui_active_view_active_index_not_update);
+}
diff --git a/src/tests/elementary/efl_ui_test_widget.c b/src/tests/elementary/efl_ui_test_widget.c
index 79d172fa14..3390a81a73 100644
--- a/src/tests/elementary/efl_ui_test_widget.c
+++ b/src/tests/elementary/efl_ui_test_widget.c
@@ -9,8 +9,6 @@
#include "eo_internal.h"
#include "suite_helpers.h"
-EFL_CLASS_SIMPLE_CLASS(efl_ui_widget, "efl_ui_widget", EFL_UI_WIDGET_CLASS)
-
typedef struct {
Efl_Ui_Widget *btn1, *btn2;
Efl_Ui_Widget *box;
diff --git a/src/tests/elementary/meson.build b/src/tests/elementary/meson.build
index 9eb1b50fdb..31ce270f4b 100644
--- a/src/tests/elementary/meson.build
+++ b/src/tests/elementary/meson.build
@@ -138,6 +138,7 @@ efl_ui_suite_src = [
'efl_ui_suite.h',
'efl_ui_model.c',
'efl_ui_test_widget.c',
+ 'efl_ui_test_active_view.c',
]
efl_ui_suite = executable('efl_ui_suite',
diff --git a/src/tests/elementary/spec/efl_test_pack_linear.c b/src/tests/elementary/spec/efl_test_pack_linear.c
index 41ec13e731..148f8a0995 100644
--- a/src/tests/elementary/spec/efl_test_pack_linear.c
+++ b/src/tests/elementary/spec/efl_test_pack_linear.c
@@ -9,7 +9,7 @@
/* spec-meta-start
{"test-interface":"Efl.Pack_Linear",
- "test-widgets": ["Efl.Ui.Box", "Efl.Ui.Grid", "Efl.Ui.Pager"],
+ "test-widgets": ["Efl.Ui.Box", "Efl.Ui.Grid", "Efl.Ui.Pager", "Efl.Ui.Active_View.Container"],
"custom-mapping" : {
"Efl.Ui.Grid" : "EFL_UI_GRID_DEFAULT_ITEM_CLASS"
}