efl_ui_stack: remove!

this can now be done with active_view. This is done in order to reduce
the LOC in elementary that basically do the same.

Differential Revision: https://phab.enlightenment.org/D8920
This commit is contained in:
Marcel Hollerbach 2019-05-18 18:45:50 +02:00
parent e71c9ad00b
commit 0a4beb291d
14 changed files with 473 additions and 1238 deletions

View File

@ -1119,7 +1119,7 @@ add_tests:
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_EO(NULL, "Active View", "Navigation stack", test_ui_stack);
//------------------------------//
ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup);
ADD_TEST(NULL, "Popups", "Hover", test_hover);
@ -1184,7 +1184,6 @@ add_tests:
ADD_TEST(NULL, "Naviframe", "Naviframe 2", test_naviframe2);
ADD_TEST(NULL, "Naviframe", "Naviframe 3", test_naviframe3);
ADD_TEST(NULL, "Naviframe", "Naviframe: Complex", test_naviframe_complex);
ADD_TEST_EO(NULL, "Naviframe", "Efl.Ui.Stack", test_ui_stack);
//------------------------------//
ADD_TEST(NULL, "Geographic", "Map", test_map);

View File

@ -7,13 +7,15 @@
#include <Efl_Ui.h>
#include <Elementary.h>
typedef enum _Page_Type {
typedef enum _View_Type
{
LAYOUT,
LIST,
BUTTON
} Page_Type;
} View_Type;
typedef enum _Pack_Type {
typedef enum _Pack_Type
{
PACK_BEGIN,
PACK_END,
PACK_BEFORE,
@ -23,82 +25,90 @@ typedef enum _Pack_Type {
CLEAR
} Pack_Type;
typedef struct _Params {
typedef struct _Params
{
Evas_Object *navi;
Eo *active_view;
Eo *indicator;
int w, h;
Eina_Bool wfill, hfill;
Eo *active_view;
Eo *indicator;
int w, h;
Eina_Bool wfill, hfill;
} Params;
typedef struct _Page_Set_Params {
typedef struct _Page_Set_Params
{
Eo *active_view;
Eo *spinner;
} Page_Set_Params;
typedef struct _Pack_Params {
typedef struct _Pack_Params
{
Pack_Type type;
Eo *active_view;
Eo *pack_sp;
Eo *unpack_sp;
Eo *unpack_btn;
Eo *active_view;
Eo *pack_sp;
Eo *unpack_sp;
Eo *unpack_btn;
} Pack_Params;
typedef struct _Size_Params {
Eo *active_view;
Eo *slider;
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)
static Eo *
view_add(View_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;
}
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;
}
@ -110,7 +120,7 @@ prev_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
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);
efl_ui_active_view_active_index_set(active_view, active_index - 1);
}
static void
@ -120,7 +130,7 @@ next_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
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);
efl_ui_active_view_active_index_set(active_view, active_index + 1);
}
static void
@ -215,55 +225,67 @@ pack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
Eo *page = NULL, *curr_page;
int index, cnt;
if ((param->type != UNPACK_AT) && (param->type != CLEAR)) {
index = efl_content_count(active_view);
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 (index % 3)
{
case 0:
page = view_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;
}
case 1:
page = view_add(LIST, active_view);
break;
case 2:
page = view_add(BUTTON, active_view);
break;
default:
page = view_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);
@ -302,7 +324,7 @@ 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));
efl_ui_range_value_get(psp->spinner));
}
static void
@ -329,8 +351,8 @@ indicator_none_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
static void
active_view_size(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Params *params = data;
Size_Params *size_params;
@ -355,7 +377,7 @@ active_view_size(void *data,
efl_gfx_entity_visible_set(fr, 1);
inbox = efl_add(EFL_UI_BOX_CLASS, fr,
efl_content_set(fr, efl_added));
efl_content_set(fr, efl_added));
ck = elm_check_add(inbox);
elm_object_text_set(ck, "Fill");
@ -396,7 +418,7 @@ active_view_size(void *data,
efl_gfx_entity_visible_set(fr, 1);
inbox = efl_add(EFL_UI_BOX_CLASS, fr,
efl_content_set(fr, efl_added));
efl_content_set(fr, efl_added));
ck = elm_check_add(inbox);
elm_object_text_set(ck, "Fill");
@ -429,56 +451,6 @@ active_view_size(void *data,
}
}
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)
{
@ -489,8 +461,8 @@ _animation_cb(void *data, const Efl_Event *ev)
static void
view_animation_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Params *params = data;
Evas_Object *navi = params->navi;
@ -515,8 +487,8 @@ view_animation_cb(void *data,
static void
pack_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Params *params = (Params *)data;
Evas_Object *navi = params->navi;
@ -695,13 +667,12 @@ pack_cb(void *data,
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)
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Params *params = (Params *)data;
Evas_Object *navi = params->navi;
@ -717,7 +688,7 @@ active_index_cb(void *data,
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,
elm_naviframe_item_push(navi, "Active Index", btn, NULL,
efl_added, NULL));
btn = efl_add(EFL_UI_BUTTON_CLASS, box,
@ -750,8 +721,8 @@ active_index_cb(void *data,
static void
indicator_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Params *params = (Params *)data;
Evas_Object *navi = params->navi;
@ -780,11 +751,12 @@ indicator_cb(void *data,
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)
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;
Eo *win, *panes, *navi, *list, *layout, *active_view, *view;
Params *params = NULL;
char buf[PATH_MAX];
int i;
@ -818,8 +790,8 @@ void test_ui_active_view_stack(void *data EINA_UNUSED,
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_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));
@ -850,38 +822,43 @@ void test_ui_active_view_stack(void *data EINA_UNUSED,
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);
}
for (i = 0; i < PAGE_NUM; i++)
{
switch (i % 3)
{
case 0:
view = view_add(LAYOUT, active_view);
break;
case 1:
view = view_add(LIST, active_view);
break;
case 2:
view = view_add(BUTTON, active_view);
break;
default:
view = view_add(LAYOUT, active_view);
break;
}
efl_pack_end(active_view, view);
}
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)
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;
Eo *win, *panes, *navi, *list, *layout, *active_view, *view;
Params *params = NULL;
char buf[PATH_MAX];
int i;
@ -915,8 +892,8 @@ void test_ui_active_view_plain(void *data EINA_UNUSED,
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_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"),
@ -945,38 +922,42 @@ void test_ui_active_view_plain(void *data EINA_UNUSED,
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);
}
for (i = 0; i < PAGE_NUM; i++)
{
switch (i % 3)
{
case 0:
view = view_add(LAYOUT, active_view);
break;
case 1:
view = view_add(LIST, active_view);
break;
case 2:
view = view_add(BUTTON, active_view);
break;
default:
view = view_add(LAYOUT, active_view);
break;
}
efl_pack_end(active_view, view);
}
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)
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;
Eo *win, *panes, *navi, *list, *layout, *active_view, *view;
Params *params = NULL;
char buf[PATH_MAX];
int i;
@ -1010,8 +991,8 @@ void test_ui_active_view_scroll(void *data EINA_UNUSED,
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_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));
@ -1042,29 +1023,33 @@ void test_ui_active_view_scroll(void *data EINA_UNUSED,
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);
}
switch (i % 3)
{
case 0:
view = view_add(LAYOUT, active_view);
break;
case 1:
view = view_add(LIST, active_view);
break;
case 2:
view = view_add(BUTTON, active_view);
break;
default:
view = view_add(LAYOUT, active_view);
break;
}
efl_pack_end(active_view, view);
}
efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
}

View File

@ -6,29 +6,20 @@
#include <Elementary.h>
static void _third_layout_push(void *data, const Efl_Event *ev EINA_UNUSED);
static void _fourth_layout_push(void *data, const Efl_Event *ev EINA_UNUSED);
static void
_stack_remove(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *stack = data;
Eo *top_layout = efl_ui_stack_top(stack);
efl_ui_stack_remove(stack, top_layout);
}
static void
_stack_double_pop(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *stack = data;
efl_ui_stack_pop(stack);
efl_ui_stack_pop(stack);
Eo *top_layout = efl_pack_content_get(stack, 0);
efl_del(top_layout);
}
static void
_stack_pop(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *stack = data;
efl_ui_stack_pop(stack);
efl_ui_active_view_pop(stack, EINA_TRUE);
}
static void
@ -36,14 +27,13 @@ _stack_double_push(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *stack = data;
_third_layout_push(stack, NULL);
_fourth_layout_push(stack, NULL);
}
static void
_stack_del(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *stack = data;
Eo *top_layout = efl_ui_stack_top(stack);
Eo *top_layout = efl_pack_content_get(stack, 0);
efl_del(top_layout);
}
@ -103,31 +93,13 @@ _fifth_layout_insert(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *stack = data;
Eo *top_layout = efl_ui_stack_top(stack);
Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, stack);
efl_text_set(btn, "Press to remove top layout");
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _stack_remove, stack);
Eo *nl = _navigation_layout_create(stack, "5th layout", btn);
efl_ui_stack_insert_after(stack, top_layout, nl);
}
static void
_fourth_layout_push(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *stack = data;
Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, stack);
efl_text_set(btn, "Press to double pop");
efl_event_callback_add(btn, EFL_UI_EVENT_CLICKED, _stack_double_pop, stack);
Eo *nl = _navigation_layout_create(stack, "4th layout", btn);
_bar_right_btn_set(nl, _fifth_layout_insert, stack);
efl_ui_stack_push(stack, nl);
efl_ui_active_view_push(stack, nl);
}
static void
@ -141,9 +113,9 @@ _third_layout_push(void *data, const Efl_Event *ev EINA_UNUSED)
Eo *nl = _navigation_layout_create(stack, "3rd layout", btn);
_bar_right_btn_set(nl, _fourth_layout_push, stack);
_bar_right_btn_set(nl, _fifth_layout_insert, stack);
efl_ui_stack_push(stack, nl);
efl_ui_active_view_push(stack, nl);
}
static void
@ -159,7 +131,7 @@ _second_layout_push(void *data, const Efl_Event *ev EINA_UNUSED)
_bar_right_btn_set(nl, _third_layout_push, stack);
efl_ui_stack_push(stack, nl);
efl_ui_active_view_push(stack, nl);
}
static void
@ -174,35 +146,7 @@ _first_layout_push(Eo *win, Eo *stack)
_bar_left_btn_set(nl, _win_del, win);
_bar_right_btn_set(nl, _second_layout_push, stack);
efl_ui_stack_push(stack, nl);
}
static void
_stack_loaded_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_Stack_Event_Loaded *loaded_info = event->info;
printf("Content(%p) is loaded to the stack.\n\n", loaded_info->content);
}
static void
_stack_unloaded_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_Stack_Event_Unloaded *unloaded_info = event->info;
printf("Content(%p) is unloaded from the stack.\n\n", unloaded_info->content);
}
static void
_stack_activated_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_Stack_Event_Activated *activated_info = event->info;
printf("Content(%p) is activated in the stack.\n\n", activated_info->content);
}
static void
_stack_deactivated_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_Stack_Event_Deactivated *deactivated_info = event->info;
printf("Content(%p) is deactivated in the stack.\n\n", deactivated_info->content);
efl_ui_active_view_push(stack, nl);
}
void
@ -214,15 +158,8 @@ test_ui_stack(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_
efl_gfx_entity_size_set(win, EINA_SIZE2D(500, 500));
Eo *stack = efl_add(EFL_UI_STACK_CLASS, win);
efl_event_callback_add(stack, EFL_UI_STACK_EVENT_LOADED,
_stack_loaded_cb, NULL);
efl_event_callback_add(stack, EFL_UI_STACK_EVENT_UNLOADED,
_stack_unloaded_cb, NULL);
efl_event_callback_add(stack, EFL_UI_STACK_EVENT_ACTIVATED,
_stack_activated_cb, NULL);
efl_event_callback_add(stack, EFL_UI_STACK_EVENT_DEACTIVATED,
_stack_deactivated_cb, NULL);
Eo *stack = efl_ui_active_view_util_stack_gen(win);
efl_content_set(win, stack);
_first_layout_push(win, stack);

View File

@ -242,12 +242,12 @@ typedef Eo Efl_Ui_Active_View_Indicator;
# 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_active_view_util.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>
# include <efl_ui_navigation_layout.eo.h>
# include <efl_ui_stack.eo.h>
# include <efl_ui_clickable.eo.h>
# include <efl_ui_clickable_util.eo.h>

View File

@ -23,13 +23,16 @@ typedef struct _Efl_Ui_Active_View_Container_Data
double last_pos;
Eina_Bool active;
} show_request;
struct {
Eina_Promise *transition_done;
Efl_Gfx_Entity *content;
} transition_done;
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
@ -67,6 +70,15 @@ _transition_end(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd)
if (pd->prevent_transition_interaction) return;
if (pd->transition_done.content)
{
Eina_Value v = eina_value_object_init(pd->transition_done.content);
efl_pack_unpack(obj, pd->transition_done.content);
eina_promise_resolve(pd->transition_done.transition_done, v);
pd->transition_done.transition_done = NULL;
pd->transition_done.content = NULL;
}
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);
@ -174,7 +186,6 @@ _efl_ui_active_view_container_efl_object_constructor(Eo *obj,
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);
@ -255,25 +266,12 @@ _register_child(Eo *obj EINA_UNUSED, Efl_Ui_Active_View_Container_Data *pd, Efl_
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)
if (pd->curr.page >= index)
{
pd->curr.page++;
curr_page_update = EINA_TRUE;
@ -505,7 +503,7 @@ _unpack(Eo *obj,
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)
if (index < pd->curr.page)
pd->curr.page--;
if (pd->transition)
@ -514,7 +512,7 @@ _unpack(Eo *obj,
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)
if (early_curr_page == index)
{
int new_curr_page = MIN(MAX(early_curr_page, 0), (int)eina_list_count(pd->content_list) - 1);
//when we delete the active index and we are not updating the index,
@ -651,4 +649,50 @@ _efl_ui_active_view_container_indicator_get(const Eo *obj EINA_UNUSED, Efl_Ui_Ac
return pd->indicator;
}
EOLIAN static void
_efl_ui_active_view_container_push(Eo *obj, Efl_Ui_Active_View_Container_Data *pd EINA_UNUSED, Efl_Gfx_Entity *view)
{
int old_active_index = efl_ui_active_view_active_index_get(obj);
if (old_active_index == -1)
old_active_index = 0;
efl_pack_at(obj, view, old_active_index);
efl_ui_active_view_active_index_set(obj, old_active_index);
}
static Eina_Value
_delete_obj(void *data EINA_UNUSED, const Eina_Value value, const Eina_Future *dead_future EINA_UNUSED)
{
efl_del(eina_value_object_get(&value));
return EINA_VALUE_EMPTY;
}
EOLIAN static Eina_Future*
_efl_ui_active_view_container_pop(Eo *obj, Efl_Ui_Active_View_Container_Data *pd, Eina_Bool del)
{
Eina_Future *transition_done;
int new_index;
if (eina_list_count(pd->content_list) < 2)
new_index = -1;
new_index = efl_ui_active_view_active_index_get(obj) + 1;
if (new_index >= (int)eina_list_count(pd->content_list))
new_index -= 2;
pd->transition_done.content = efl_pack_content_get(obj, efl_ui_active_view_active_index_get(obj));
pd->transition_done.transition_done = efl_loop_promise_new(obj);
transition_done = eina_future_new(pd->transition_done.transition_done);
if (del)
transition_done = eina_future_then(transition_done, _delete_obj, NULL);
efl_ui_active_view_active_index_set(obj, new_index);
return transition_done;
}
#include "efl_ui_active_view_container.eo.c"

View File

@ -4,15 +4,6 @@ struct @beta Efl.Ui.Active_View.Transition_Event {
to : int; [[The view index to where the transition is headed, -1 if not known.]]
}
enum Efl.Ui.Active_View.Container_Gravity {
[[This enum controls the behavior of @Efl.Ui.Active_View.Container.active_index when indices are
shifted due to object addition or removal.]]
content = 0, [[When a view is added or removed from the container, the @Efl.Ui.Active_View.Container.active_index will
be adjusted as necessary so it points to the same view as before.]]
index = 1, [[When a view is added or removed from the container, the @Efl.Ui.Active_View.Container.active_index will
remain the same, possibly pointing to a different view.]]
}
class @beta Efl.Ui.Active_View.Container extends Efl.Ui.Layout_Base implements Efl.Pack_Linear
{
[[The Active View widget is a container for other sub-widgets (views), where only one sub-widget is active at any given time.
@ -51,27 +42,13 @@ class @beta Efl.Ui.Active_View.Container extends Efl.Ui.Layout_Base implements E
}
@property active_index {
[[Currently active view among all the views added to this widget.
Changing this value might trigger an animation.
]]
values {
index: int; [[Index of the active view, from 0 to the number of views - 1 (@Efl.Container.content_count - 1).]]
}
}
@property active_view_gravity {
[[When a new view is added to this widget, the indices for the previous views might change (for example,
when adding a view at the beginning of the list with @Efl.Pack_Linear.pack_begin all previous view's indices are increased by one).
This property controls whether the Active View should remain the same view as before (@Efl.Ui.Active_View.Container_Gravity.content)
or if the Active View should be moved to the one with the same index as before (@Efl.Ui.Active_View.Container_Gravity.index).
For example, @Efl.Ui.Active_View.Container_Gravity.index can be used to build a Stack, where @.active_index is always 0 and new
views are pushed onto the stack with @Efl.Pack_Linear.pack_begin and popped from the stack with @Efl.Pack_Linear.pack_unpack_at 0.
]]
values {
gravity : Efl.Ui.Active_View.Container_Gravity; [[Active View behavior when adding new views. Default is @Efl.Ui.Active_View.Container_Gravity.content.]]
}
}
@property active_view_size {
[[The size to use when displaying the Active View. This is used by the @.view_manager to perform the rendering.
Views other than the Active one may or may not use this size.]]
@ -79,6 +56,34 @@ class @beta Efl.Ui.Active_View.Container extends Efl.Ui.Layout_Base implements E
size: Eina.Size2D; [[Render size for the Active View. (-1, -1) means that all available space inside the container is used.]]
}
}
push @beta {
[[Packs a new view at the position indicated by @.active_index (0 by default).
This is the same behavior as a push operation on a stack.
An animation might be triggered to make the new active view come into position.
]]
params {
view : Efl.Gfx.Entity; [[View to add and set to be the active view.]]
}
}
pop @beta {
[[Removes the active view from the widget.
The views behind it naturally flow down so the next one becomes the active view. This is the same behavior as a pop operation on a stack.
When combined with @.push you don't have to worry about @.active_index since only the first view is manipulated.
An animation might be triggered to make the new active view come into position and the old one disappear.
The removed view can be returned to the caller or deleted (depending on $delete_on_transition_end).
]]
params {
deletion_on_transition_end : bool; [[ if $true, then the object will be deleted before resolving the future, and a NULL pointer is the value of the future. $false if no operation should be applied to it]]
}
return : future<Efl.Gfx.Entity>; [[ This Future gets resolved when any transition animation finishes and the popped view is ready for collection.
If there is no animation, the Future resolves immediately.
If $deletion_on_transition_end is $true then this widget will destroy the popped view and the Future will contain no Value. Otherwise, the caller becomes the owner of the view contained in the Future and must dispose of it appropriately. ]]
}
}
events {
transition,start : Efl.Ui.Active_View.Transition_Event; [[A transition animation has started.]]

View File

@ -0,0 +1,21 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Efl_Ui.h>
#include "elm_priv.h"
typedef struct {
} Efl_Ui_Active_View_Util_Data;
EOLIAN static Efl_Ui_Active_View_Container*
_efl_ui_active_view_util_stack_gen(Efl_Ui_Widget *parent)
{
Efl_Ui_Active_View_View_Manager *manager = efl_add(EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_STACK_CLASS, parent);
return efl_add(EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS, parent,
efl_ui_active_view_manager_set(efl_added, manager));
}
#include "efl_ui_active_view_util.eo.c"

View File

@ -0,0 +1,11 @@
class @beta Efl.Ui.Active_View.Util {
methods {
stack_gen @class {
[[Get a preconfigured stack obejct]]
params {
parent : Efl.Ui.Widget;
}
return : Efl.Ui.Active_View.Container;
}
}
}

View File

@ -19,14 +19,14 @@ _back_button_clicked_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *navigation_bar = data;
Eo *stack = efl_provider_find(navigation_bar, EFL_UI_STACK_CLASS);
if (!stack)
Eo *active_view = efl_provider_find(navigation_bar, EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS);
if (!active_view)
{
ERR("Cannot find EFL_UI_STACK_CLASS instance!");
ERR("Cannot find EFL_UI_ACTIVE_VIEW_CONTAINER_CLASS instance!");
return;
}
efl_ui_stack_pop(stack);
efl_ui_active_view_pop(active_view, EINA_TRUE);
}
EOLIAN static Eo *

View File

@ -1,697 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_stack_private.h"
#define MY_CLASS EFL_UI_STACK_CLASS
#define MY_CLASS_NAME "Efl.Ui.Stack"
static Efl_Canvas_Animation *show_anim = NULL;
static Efl_Canvas_Animation *hide_anim = NULL;
static void
_announce_hiding(Efl_Ui_Stack *obj, Evas_Object *content)
{
//Deactivated Event
Efl_Ui_Stack_Event_Deactivated deactivated_info;
deactivated_info.content = content;
efl_event_callback_call(obj,
EFL_UI_STACK_EVENT_DEACTIVATED,
&deactivated_info);
//Unloaded Event
Efl_Ui_Stack_Event_Unloaded unloaded_info;
unloaded_info.content = content;
efl_event_callback_call(obj,
EFL_UI_STACK_EVENT_UNLOADED,
&unloaded_info);
}
static void
_show_content_without_anim(Efl_Ui_Stack *obj, Evas_Object *content)
{
//Loaded Event
Efl_Ui_Stack_Event_Loaded loaded_info;
loaded_info.content = content;
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
&loaded_info);
evas_object_raise(content);
/* efl_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set()
* internally.
* Therefore, efl_ui_widget_resize_object_set() is called after
* setting animation and efl_gfx_entity_visible_set() is not called. */
efl_ui_widget_resize_object_set(obj, content);
//Activated Event
Efl_Ui_Stack_Event_Activated activated_info;
activated_info.content = content;
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_ACTIVATED,
&activated_info);
}
static void
_hide_content_without_anim(Efl_Ui_Stack *obj EINA_UNUSED, Evas_Object *content)
{
efl_gfx_entity_visible_set(content, EINA_FALSE);
}
static void
_content_del_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
Content_Data *cd = data;
//Popped content has already called deactivated event and unloaded event.
if (cd->popped_hidden) return;
_announce_hiding(NULL, cd->content);
}
static Content_Data *
_content_data_new(Eo *obj EINA_UNUSED, Eo *content)
{
Content_Data *cd = calloc(1, sizeof(Content_Data));
if (!cd)
{
ERR("Memory allocation error!");
return NULL;
}
cd->content = content;
efl_event_callback_add(cd->content, EFL_EVENT_DEL, _content_del_cb, cd);
return cd;
}
static void
_content_data_del(Content_Data *cd)
{
if (!cd) return;
if (cd->content)
efl_del(cd->content);
free(cd);
}
static void
_anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
efl_event_freeze(efl_animation_player_target_get(event->object));
}
static Evas_Object*
_end_anim(Transit_Data *td)
{
Efl_Canvas_Object *content = td->cd->content;
efl_event_thaw(content);
td->cd->on_pushing = EINA_FALSE;
td->cd->on_popping = EINA_FALSE;
free(td);
return content;
}
static void
_hide_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
Efl_Ui_Stack_Data *pd = efl_data_scope_safe_get(data, EFL_UI_STACK_CLASS);
Efl_Canvas_Object *content;
EINA_SAFETY_ON_NULL_RETURN(pd);
content = _end_anim(pd->hide_td);
pd->hide_td = NULL;
efl_gfx_entity_visible_set(content, EINA_FALSE);
_announce_hiding(data, content);
}
static void
_show_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
Efl_Ui_Stack_Data *pd = efl_data_scope_safe_get(data, EFL_UI_STACK_CLASS);
Efl_Canvas_Object *content;
EINA_SAFETY_ON_NULL_RETURN(pd);
content = _end_anim(pd->show_td);
pd->show_td = NULL;
//Activated Event
Efl_Ui_Stack_Event_Activated activated_info;
activated_info.content = content;
efl_event_callback_call(data,
EFL_UI_STACK_EVENT_ACTIVATED,
&activated_info);
}
static void
_show_content_with_anim(Efl_Ui_Stack *obj, Efl_Ui_Stack_Data *pd, Content_Data *cd)
{
//immidiatly stop hiding animation
efl_player_stop(pd->show);
if (pd->show_td)
EINA_SAFETY_ERROR("td is set but it should not");
//attach new content target
efl_animation_player_target_set(pd->show, cd->content);
Transit_Data *td = calloc(1, sizeof(Transit_Data));
if (!td)
{
ERR("Memory allocation error!");
//show content without animation
_show_content_without_anim(obj, cd->content);
return;
}
td->cd = cd;
pd->show_td = td;
/* efl_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set()
* internally.
* Therefore, efl_ui_widget_resize_object_set() is called after
* setting animation and efl_gfx_entity_visible_set() is not called. */
efl_ui_widget_resize_object_set(obj, cd->content);
efl_player_start(pd->show);
}
static void
_hide_content_with_anim(Efl_Ui_Stack *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd, Content_Data *cd)
{
//immidiatly stop hiding animation
efl_player_stop(pd->hide);
if (pd->hide_td)
EINA_SAFETY_ERROR("td is set but it should not");
//attach new content target
efl_animation_player_target_set(pd->hide, cd->content);
Transit_Data *td = calloc(1, sizeof(Transit_Data));
if (!td)
{
ERR("Memory allocation error!");
//hide content without animation
_hide_content_without_anim(obj, cd->content);
return;
}
td->cd = cd;
pd->hide_td = td;
efl_player_start(pd->hide);
}
EOLIAN static void
_efl_ui_stack_push(Eo *obj, Efl_Ui_Stack_Data *pd, Eo *content)
{
if (!content) return;
//If the given content exists in the stack, promote the given content to the top.
Content_Data *cd = NULL;
EINA_INLIST_FOREACH(pd->stack, cd)
if (cd->content == content)
break;
Content_Data *top_cd = NULL;
if (pd->stack)
top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
if (cd)
{
//If given content is already the top content, then do nothing.
if (cd == top_cd)
return;
//Remove the given content(existing content) to promote it to the top.
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(cd));
}
else
{
cd = _content_data_new(obj, content);
if (!cd) return;
evas_object_smart_member_add(content, obj);
}
pd->stack = eina_inlist_append(pd->stack, EINA_INLIST_GET(cd));
//Loaded Event
Efl_Ui_Stack_Event_Loaded loaded_info;
loaded_info.content = content;
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED, &loaded_info);
/* Apply transition to top content.
* Hide top content with animation. */
if (top_cd)
{
Eo *top_content = top_cd->content;
/* If content is being pushed now, then finish current animation and hide
* the content without animation. */
if (top_cd->on_pushing)
{
_hide_content_without_anim(obj, top_content);
_announce_hiding(obj, top_content);
}
else
{
top_cd->on_pushing = EINA_TRUE;
_hide_content_with_anim(obj, pd, top_cd);
}
}
/* Prepare transition for new content.
* Hide new content without animation. */
cd->on_pushing = EINA_TRUE;
_hide_content_without_anim(obj, content);
/* Apply transition to new content.
* Show new content with animation. */
_show_content_with_anim(obj, pd, cd);
}
static void
_pop_content_hide_cb(void *data, const Efl_Event *event)
{
Content_Data *cd = data;
Eina_Bool *visible = event->info;
/* object is being shown */
if (*visible) return;
cd->popped_hidden = EINA_TRUE;
_content_data_del(cd);
}
EOLIAN static Eo *
_efl_ui_stack_pop(Eo *obj, Efl_Ui_Stack_Data *pd)
{
if (!pd->stack)
{
ERR("There is no content in the stack!");
return NULL;
}
Content_Data *top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(top_cd));
/* Apply transition to top content.
* Hide top content with animation. */
{
Eo *top_content = top_cd->content;
/* If content is being popped now, then finish current animation and show
* the content without animation. */
if (top_cd->on_popping)
{
_hide_content_without_anim(obj, top_content);
_announce_hiding(obj, top_content);
}
else
{
top_cd->on_popping = EINA_TRUE;
//Deallocate content data when hide animation is finished.
efl_event_callback_add(top_content, EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED,
_pop_content_hide_cb, top_cd);
_hide_content_with_anim(obj, pd, top_cd);
}
}
if (pd->stack)
{
Content_Data *prev_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last,
Content_Data);
Eo *prev_content = prev_cd->content;
prev_cd->on_popping = EINA_TRUE;
//Loaded Event
Efl_Ui_Stack_Event_Loaded loaded_info;
loaded_info.content = prev_content;
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
&loaded_info);
/* Apply transition to previous content.
* Show previous content with animation. */
_show_content_with_anim(obj, pd, prev_cd);
}
return NULL;
}
EOLIAN static void
_efl_ui_stack_insert_before(Eo *obj, Efl_Ui_Stack_Data *pd,
Eo *base_content, Eo *content)
{
if (!content) return;
Content_Data *base_cd = NULL;
EINA_INLIST_FOREACH(pd->stack, base_cd)
if (base_cd->content == base_content)
break;
if (!base_cd)
{
ERR("The given base content is not found in the stack!");
return;
}
Content_Data *cd = _content_data_new(obj, content);
if (!cd) return;
pd->stack = eina_inlist_prepend_relative(pd->stack,
EINA_INLIST_GET(cd),
EINA_INLIST_GET(base_cd));
evas_object_smart_member_add(content, obj);
}
EOLIAN static void
_efl_ui_stack_insert_after(Eo *obj, Efl_Ui_Stack_Data *pd,
Eo *base_content, Eo *content)
{
if (!content) return;
Content_Data *base_cd = NULL;
EINA_INLIST_FOREACH(pd->stack, base_cd)
if (base_cd->content == base_content)
break;
if (!base_cd)
{
ERR("The given base content is not found in the stack!");
return;
}
Content_Data *cd = _content_data_new(obj, content);
if (!cd) return;
pd->stack = eina_inlist_append_relative(pd->stack,
EINA_INLIST_GET(cd),
EINA_INLIST_GET(base_cd));
evas_object_smart_member_add(content, obj);
if (pd->stack->last == EINA_INLIST_GET(cd))
{
/* Do not apply transition for insert.
* Hide top content without animation. */
_hide_content_without_anim(obj, base_cd->content);
_announce_hiding(obj, base_cd->content);
/* Do not apply transition for insert.
* Show new content without animation. */
_show_content_without_anim(obj, content);
}
}
EOLIAN static void
_efl_ui_stack_insert_at(Eo *obj, Efl_Ui_Stack_Data *pd,
int index, Eo *content)
{
if (!content)
{
ERR("The given content is NULL!");
return;
}
int count = eina_inlist_count(pd->stack);
if ((index < 0) || (index > count))
{
ERR("The index(%d) should be from 0 to #contents in the stack(%d)!",
index, count);
return;
}
Content_Data *base_cd = NULL;
if (index == count)
{
base_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
}
else
{
int i = 0;
EINA_INLIST_FOREACH(pd->stack, base_cd)
{
if (i == index)
break;
i++;
}
}
Content_Data *cd = _content_data_new(obj, content);
if (!cd) return;
if (index == count)
pd->stack = eina_inlist_append_relative(pd->stack,
EINA_INLIST_GET(cd),
EINA_INLIST_GET(base_cd));
else
pd->stack = eina_inlist_prepend_relative(pd->stack,
EINA_INLIST_GET(cd),
EINA_INLIST_GET(base_cd));
evas_object_smart_member_add(content, obj);
if (pd->stack->last == EINA_INLIST_GET(cd))
{
/* Do not apply transition for insert.
* Hide top content without animation. */
_hide_content_without_anim(obj, base_cd->content);
_announce_hiding(obj, base_cd->content);
/* Do not apply transition for insert.
* Show new content without animation. */
_show_content_without_anim(obj, content);
}
}
EOLIAN static void
_efl_ui_stack_remove(Eo *obj, Efl_Ui_Stack_Data *pd, Eo *content)
{
if (!pd->stack)
{
ERR("There is no content in the stack!");
return;
}
if (!content)
{
ERR("The given content is NULL!");
return;
}
Content_Data *cd = NULL;
EINA_INLIST_FOREACH(pd->stack, cd)
{
if (cd->content == content)
break;
}
if (!cd)
{
ERR("The given content does not exist in the stack!");
return;
}
Eina_Bool remove_top = EINA_FALSE;
if (pd->stack->last == EINA_INLIST_GET(cd))
remove_top = EINA_TRUE;
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(cd));
_announce_hiding(obj, cd->content);
_content_data_del(cd);
if (remove_top)
{
if (pd->stack)
{
Content_Data *new_top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last,
Content_Data);
/* Do not apply transition for insert.
* Show new content without animation. */
_show_content_without_anim(obj, new_top_cd->content);
}
}
}
EOLIAN static void
_efl_ui_stack_remove_at(Eo *obj, Efl_Ui_Stack_Data *pd,
int index)
{
if (!pd->stack)
{
ERR("There is no content in the stack!");
return;
}
int count = eina_inlist_count(pd->stack);
if ((index < 0) || (index >= count))
{
ERR("The index(%d) should be from 0 to (#contents - 1) in the stack(%d)!",
index, count);
return;
}
Content_Data *cd = NULL;
int i = 0;
EINA_INLIST_FOREACH(pd->stack, cd)
{
if (i == index)
break;
i++;
}
Eina_Bool remove_top = EINA_FALSE;
if (pd->stack->last == EINA_INLIST_GET(cd))
remove_top = EINA_TRUE;
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(cd));
_announce_hiding(NULL, cd->content);
_content_data_del(cd);
//FIXME: Apply transition here.
if (remove_top)
{
if (pd->stack)
{
Content_Data *new_top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last,
Content_Data);
/* Do not apply transition for insert.
* Show new content without animation. */
_show_content_without_anim(obj, new_top_cd->content);
}
}
}
EOLIAN static int
_efl_ui_stack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd, Efl_Canvas_Object *content)
{
if (!pd->stack)
{
ERR("There is no content in the stack!");
return -1;
}
if (!content)
{
ERR("The given content is NULL!");
return -1;
}
Content_Data *cd = NULL;
int index = 0;
int count = eina_inlist_count(pd->stack);
EINA_INLIST_FOREACH(pd->stack, cd)
{
if (cd->content == content)
break;
index++;
}
//The given content is not found.
if (index == count) return -1;
return index;
}
EOLIAN static Eo *
_efl_ui_stack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd, int index)
{
if (!pd->stack)
{
ERR("There is no content in the stack!");
return NULL;
}
int count = eina_inlist_count(pd->stack);
if ((index < 0) || (index >= count))
{
ERR("The index(%d) should be from 0 to (#contents - 1) in the stack(%d)!",
index, count);
return NULL;
}
Content_Data *cd = NULL;
int i = 0;
EINA_INLIST_FOREACH(pd->stack, cd)
{
if (i == index)
break;
i++;
}
if (cd)
return cd->content;
return NULL;
}
EOLIAN static Eo *
_efl_ui_stack_top(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd)
{
if (!pd->stack) return NULL;
Content_Data *cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
return cd->content;
}
EFL_CALLBACKS_ARRAY_DEFINE(_anim_show_event_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 Eo *
_efl_ui_stack_efl_object_constructor(Eo *obj, Efl_Ui_Stack_Data *pd EINA_UNUSED)
{
Efl_Canvas_Animation *sh, *hi;
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
//Default Show Animation
sh = 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);
pd->show = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj);
efl_animation_player_animation_set(pd->show, sh);
efl_player_play_set(pd->show, EINA_FALSE);
efl_event_callback_array_add(pd->show, _anim_show_event_cb(), obj);
//Default Hide Animation
hi = 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);
pd->hide = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj);
efl_animation_player_animation_set(pd->hide, hi);
efl_player_play_set(pd->hide, EINA_FALSE);
efl_event_callback_array_add(pd->hide, _anim_hide_event_cb(), obj);
return obj;
}
#include "efl_ui_stack.eo.c"

View File

@ -1,131 +0,0 @@
struct @beta Efl.Ui.Stack_Event_Loaded {
[[Information of loaded event.]]
content: Efl.Canvas.Object; [[Loaded content.]]
}
struct @beta Efl.Ui.Stack_Event_Unloaded {
[[Information of unloaded event.]]
content: Efl.Canvas.Object; [[Unloaded content.]]
}
struct @beta Efl.Ui.Stack_Event_Activated {
[[Information of activated event.]]
content: Efl.Canvas.Object; [[Activated content.]]
}
struct @beta Efl.Ui.Stack_Event_Deactivated {
[[Information of deactivated event.]]
content: Efl.Canvas.Object; [[Deactivated content.]]
}
class @beta Efl.Ui.Stack extends Efl.Ui.Layout_Base
{
[[Stack widget.
Stack widget arranges objects in stack structure by pushing and poping them.
]]
methods {
push {
[[Pushes a new object to the top of the stack and shows it.
]]
params {
@in content: Efl.Canvas.Object;
[[The pushed object which becomes the top content of the stack.]]
}
}
pop {
[[Pops the top content from the stack and deletes it.
]]
return: Efl.Canvas.Object;
[[The top content which is removed from the stack.]]
}
insert_before {
[[Inserts an object before the given base content in the stack.
]]
params {
@in base_content: Efl.Canvas.Object;
[[$content is inserted before this $base_content.]]
@in content: Efl.Canvas.Object;
[[The inserted object in the stack.]]
}
}
insert_after {
[[Inserts an object after the given base content in the stack.
]]
params {
@in base_content: Efl.Canvas.Object;
[[$content is inserted after this $base_content.]]
@in content: Efl.Canvas.Object;
[[The inserted object in the stack.]]
}
}
insert_at {
[[Inserts an object at the given place in the stack.
]]
params {
@in index: int;
[[The index of the inserted object in the stack.
$index begins from bottom to top of the stack.
$index of the bottom content is 0.
]]
@in content: Efl.Canvas.Object;
[[The inserted object in the stack.]]
}
}
remove {
[[Removes the given content in the stack.
]]
params {
@in content: Efl.Canvas.Object;
[[The removed content from the stack.]]
}
}
remove_at {
[[Removes a content matched to the given index in the stack.
]]
params {
@in index: int;
[[The index of the removed object in the stack.
$index begins from bottom to top of the stack.
$index of the bottom content is 0.
]]
}
}
index_get {
[[Gets the index of the given content in the stack.
The index begins from bottom to top of the stack.
The index of the bottom content is 0.
]]
return: int;
[[The index of $content in the stack.]]
params {
@in content: Efl.Canvas.Object;
[[The content matched to the index to be returned in the stack.]]
}
}
content_get {
[[Gets the content matched to the given index in the stack.
]]
return: Efl.Canvas.Object;
[[The content matched to $index in the stack.]]
params {
@in index: int;
[[The index of the content to be returned in the stack.]]
}
}
top {
[[Gets the top content in the stack.
]]
return: Efl.Canvas.Object; [[The top content in the stack.]]
}
}
implements {
Efl.Object.constructor;
}
events {
loaded: Efl.Ui.Stack_Event_Loaded; [[Called when content is loaded right before transition.]]
unloaded: Efl.Ui.Stack_Event_Unloaded; [[Called when content is unloaded right after being deactivated.]]
activated: Efl.Ui.Stack_Event_Activated; [[Called when content is activated right after transition.]]
deactivated: Efl.Ui.Stack_Event_Deactivated; [[Called when content is deactivated right after transition.]]
}
}

View File

@ -1,31 +0,0 @@
#ifndef EFL_UI_WIDGET_STACK_H
#define EFL_UI_WIDGET_STACK_H
typedef struct _Content_Data Content_Data;
struct _Content_Data
{
EINA_INLIST;
Eo *content;
Eina_Bool on_pushing : 1;
Eina_Bool on_popping : 1;
Eina_Bool popped_hidden : 1;
};
typedef struct _Transit_Data Transit_Data;
struct _Transit_Data
{
Content_Data *cd;
};
typedef struct _Efl_Ui_Stack_Data Efl_Ui_Stack_Data;
struct _Efl_Ui_Stack_Data
{
Eina_Inlist *stack; /* the last item is the top item */
Efl_Canvas_Animation_Player *hide, *show;
Transit_Data *show_td, *hide_td;
};
#endif

View File

@ -45,7 +45,6 @@ pub_eo_files = [
'efl_ui_check.eo',
'efl_ui_flip.eo',
'efl_ui_frame.eo',
'efl_ui_stack.eo',
'efl_ui_image.eo',
'efl_ui_image_zoomable.eo',
'efl_ui_layout.eo',
@ -159,6 +158,7 @@ pub_eo_files = [
'efl_ui_active_view_view_manager_stack.eo',
'efl_ui_active_view_indicator.eo',
'efl_ui_active_view_indicator_icon.eo',
'efl_ui_active_view_util.eo',
'efl_ui_tab_pager.eo',
'efl_ui_tab_bar.eo',
'efl_ui_tab_page.eo',
@ -291,7 +291,6 @@ elementary_headers_unstable = [
'efl_ui_widget_flip.h',
'elm_widget_flipselector.h',
'efl_ui_widget_frame.h',
'efl_ui_stack_private.h',
'elm_widget_gengrid.h',
'elm_widget_genlist.h',
'elm_widget_glview.h',
@ -772,7 +771,6 @@ elementary_src = [
'elm_flipselector.c',
'elm_font.c',
'efl_ui_frame.c',
'efl_ui_stack.c',
'elm_gengrid.c',
'elm_genlist.c',
'elm_gesture_layer.c',
@ -920,6 +918,7 @@ elementary_src = [
'efl_ui_active_view_view_manager_stack.c',
'efl_ui_active_view_indicator.c',
'efl_ui_active_view_indicator_icon.c',
'efl_ui_active_view_util.c',
'efl_ui_focus_graph.h',
'efl_ui_focus_graph.c',
'efl_ui_tab_pager.c',

View File

@ -503,19 +503,108 @@ EFL_START_TEST (efl_ui_active_view_view_manager_start_end)
}
EFL_END_TEST
EFL_START_TEST (efl_ui_active_view_active_index_not_update)
EFL_START_TEST (efl_ui_active_view_test_push1)
{
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_pack_end(container, w);
}
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_ui_active_view_push(container, w);
ck_assert_int_eq(efl_pack_index_get(container, w), 0);
ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 0);
}
EFL_END_TEST
efl_del(efl_pack_content_get(container, 0));
ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 0);
EFL_START_TEST (efl_ui_active_view_test_push2)
{
for (int i = 0; i < 5; ++i)
{
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_pack_end(container, w);
}
efl_ui_active_view_active_index_set(container, 3);
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_ui_active_view_push(container, w);
ck_assert_int_eq(efl_pack_index_get(container, w), 3);
ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 3);
}
EFL_END_TEST
static Eina_Value
_then_cb(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
{
Eo **value = data;
*value = eina_value_object_get(&v);
return EINA_VALUE_EMPTY;
}
EFL_START_TEST (efl_ui_active_view_test_pop1)
{
Eo *called;
for (int i = 0; i < 5; ++i)
{
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_pack_end(container, w);
}
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_ui_active_view_push(container, w);
Eina_Future *f = efl_ui_active_view_pop(container, EINA_FALSE);
eina_future_then(f, _then_cb, &called);
for (int i = 0; i < 10; ++i)
{
efl_loop_iterate(efl_provider_find(container, EFL_LOOP_CLASS));
}
ck_assert_ptr_eq(efl_ui_widget_parent_get(w), win);
ck_assert_int_eq(efl_content_count(container), 5);
ck_assert_ptr_eq(called, w);
ck_assert_ptr_ne(f, NULL);
}
EFL_END_TEST
EFL_START_TEST (efl_ui_active_view_test_pop2)
{
for (int i = 0; i < 5; ++i)
{
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_pack_end(container, w);
}
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_ui_active_view_push(container, w);
Eina_Future *f = efl_ui_active_view_pop(container, EINA_TRUE);
for (int i = 0; i < 10; ++i)
{
efl_loop_iterate(efl_provider_find(container, EFL_LOOP_CLASS));
}
ck_assert_int_eq(efl_ref_count(w), 0);
ck_assert_int_eq(efl_content_count(container), 5);
ck_assert_ptr_ne(f, NULL);
}
EFL_END_TEST
EFL_START_TEST (efl_ui_active_view_test_pop3)
{
for (int i = 0; i < 5; ++i)
{
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_pack_end(container, w);
}
Efl_Ui_Widget *w = efl_add(WIDGET_CLASS, win);
efl_ui_active_view_active_index_set(container, 3);
efl_ui_active_view_push(container, w);
Eina_Future *f = efl_ui_active_view_pop(container, EINA_TRUE);
for (int i = 0; i < 10; ++i)
{
efl_loop_iterate(efl_provider_find(container, EFL_LOOP_CLASS));
}
ck_assert_int_eq(efl_ui_active_view_active_index_get(container), 3);
ck_assert_int_eq(efl_ref_count(w), 0);
ck_assert_int_eq(efl_content_count(container), 5);
ck_assert_ptr_ne(f, NULL);
}
EFL_END_TEST
@ -565,5 +654,9 @@ void efl_ui_test_active_view(TCase *tc)
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);
tcase_add_test(tc, efl_ui_active_view_test_push1);
tcase_add_test(tc, efl_ui_active_view_test_push2);
tcase_add_test(tc, efl_ui_active_view_test_pop1);
tcase_add_test(tc, efl_ui_active_view_test_pop2);
tcase_add_test(tc, efl_ui_active_view_test_pop3);
}