forked from enlightenment/efl
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
This commit is contained in:
parent
cdfcd02886
commit
79fe0121ee
|
@ -119,6 +119,13 @@ elm_public_eolian_files = \
|
||||||
lib/elementary/efl_ui_dnd_container.eo \
|
lib/elementary/efl_ui_dnd_container.eo \
|
||||||
lib/elementary/efl_ui_focus_manager_window_root.eo \
|
lib/elementary/efl_ui_focus_manager_window_root.eo \
|
||||||
lib/elementary/efl_ui_pager.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.eo \
|
||||||
lib/elementary/efl_page_transition_scroll.eo \
|
lib/elementary/efl_page_transition_scroll.eo \
|
||||||
lib/elementary/efl_page_indicator.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.h \
|
||||||
static_libs/buildsystem/buildsystem_autotools.c \
|
static_libs/buildsystem/buildsystem_autotools.c \
|
||||||
lib/elementary/efl_ui_pager.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.c \
|
||||||
lib/elementary/efl_page_transition_scroll.c \
|
lib/elementary/efl_page_transition_scroll.c \
|
||||||
lib/elementary/efl_page_indicator.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_tab_pager.c \
|
||||||
bin/elementary/test_ui_pager.c \
|
bin/elementary/test_ui_pager.c \
|
||||||
bin/elementary/test_ui_pager_scroll.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_ui_relative_layout.c \
|
||||||
bin/elementary/test.h
|
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_image_zoomable.c \
|
||||||
tests/elementary/efl_ui_test_layout.c \
|
tests/elementary/efl_ui_test_layout.c \
|
||||||
tests/elementary/efl_ui_test_widget.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_suite.h \
|
||||||
tests/elementary/efl_ui_model.c
|
tests/elementary/efl_ui_model.c
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ elementary_test_src = [
|
||||||
'test_ui_panel.c',
|
'test_ui_panel.c',
|
||||||
'test_ui_pager.c',
|
'test_ui_pager.c',
|
||||||
'test_ui_pager_scroll.c',
|
'test_ui_pager_scroll.c',
|
||||||
|
'test_ui_active_view.c',
|
||||||
'test_part_bg.c',
|
'test_part_bg.c',
|
||||||
'test_part_shadow.c',
|
'test_part_shadow.c',
|
||||||
'test_photo.c',
|
'test_photo.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_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(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_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);
|
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, "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, "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, "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);
|
ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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();
|
|
@ -116,7 +116,8 @@ examples = [
|
||||||
'efl_ui_list_view_example_3',
|
'efl_ui_list_view_example_3',
|
||||||
'efl_canvas_layout_text',
|
'efl_canvas_layout_text',
|
||||||
'efl_ui_theme_example_01',
|
'efl_ui_theme_example_01',
|
||||||
'efl_ui_theme_example_02'
|
'efl_ui_theme_example_02',
|
||||||
|
'efl_ui_slideshow_example'
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach example : examples
|
foreach example : examples
|
||||||
|
|
|
@ -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_eo.h>
|
||||||
# include <efl_ui_panes_part.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.eo.h>
|
||||||
# include <efl_ui_navigation_bar_part.eo.h>
|
# include <efl_ui_navigation_bar_part.eo.h>
|
||||||
# include <efl_ui_navigation_bar_part_back_button.eo.h>
|
# include <efl_ui_navigation_bar_part_back_button.eo.h>
|
||||||
|
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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.]]
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -154,6 +154,12 @@ pub_eo_files = [
|
||||||
'efl_ui_dnd_container.eo',
|
'efl_ui_dnd_container.eo',
|
||||||
'efl_ui_focus_manager_window_root.eo',
|
'efl_ui_focus_manager_window_root.eo',
|
||||||
'efl_ui_pager.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.eo',
|
||||||
'efl_page_transition_scroll.eo',
|
'efl_page_transition_scroll.eo',
|
||||||
'efl_page_indicator.eo',
|
'efl_page_indicator.eo',
|
||||||
|
@ -230,6 +236,7 @@ priv_eo_files = [
|
||||||
'efl_ui_homogeneous_model.eo',
|
'efl_ui_homogeneous_model.eo',
|
||||||
'efl_ui_exact_model.eo',
|
'efl_ui_exact_model.eo',
|
||||||
'efl_ui_average_model.eo',
|
'efl_ui_average_model.eo',
|
||||||
|
'efl_ui_active_view_view_manager_plain.eo',
|
||||||
]
|
]
|
||||||
|
|
||||||
priv_eo_file_target = []
|
priv_eo_file_target = []
|
||||||
|
@ -917,6 +924,13 @@ elementary_src = [
|
||||||
'efl_ui_dnd.c',
|
'efl_ui_dnd.c',
|
||||||
'elm_focus_legacy.c',
|
'elm_focus_legacy.c',
|
||||||
'efl_ui_pager.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.c',
|
||||||
'efl_page_transition_scroll.c',
|
'efl_page_transition_scroll.c',
|
||||||
'efl_page_indicator.c',
|
'efl_page_indicator.c',
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "efl_ui_suite.h"
|
#include "efl_ui_suite.h"
|
||||||
#include "suite_helpers.h"
|
#include "suite_helpers.h"
|
||||||
|
#include "eo_internal.h"
|
||||||
|
|
||||||
static const Efl_Test_Case etc[] = {
|
static const Efl_Test_Case etc[] = {
|
||||||
//{ "elm_focus", elm_test_focus},
|
//{ "elm_focus", elm_test_focus},
|
||||||
|
@ -24,9 +25,12 @@ static const Efl_Test_Case etc[] = {
|
||||||
{ "efl_ui_layout", efl_ui_test_layout},
|
{ "efl_ui_layout", efl_ui_test_layout},
|
||||||
{ "Efl_Ui_Model", efl_ui_model },
|
{ "Efl_Ui_Model", efl_ui_model },
|
||||||
{ "efl_ui_widget", efl_ui_test_widget },
|
{ "efl_ui_widget", efl_ui_test_widget },
|
||||||
|
{ "efl_ui_active_view", efl_ui_test_active_view},
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EFL_CLASS_SIMPLE_CLASS(efl_ui_widget, "efl_ui_widget", EFL_UI_WIDGET_CLASS);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,11 +36,15 @@ void efl_ui_test_focus_sub(TCase *tc);
|
||||||
|
|
||||||
void efl_ui_model(TCase *tc);
|
void efl_ui_model(TCase *tc);
|
||||||
void efl_ui_test_widget(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);
|
void loop_timer_interval_set(Eo *obj, double in);
|
||||||
|
|
||||||
#define efl_loop_timer_interval_set loop_timer_interval_set
|
#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();
|
||||||
Eo *win_add_focused();
|
Eo *win_add_focused();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -9,8 +9,6 @@
|
||||||
#include "eo_internal.h"
|
#include "eo_internal.h"
|
||||||
#include "suite_helpers.h"
|
#include "suite_helpers.h"
|
||||||
|
|
||||||
EFL_CLASS_SIMPLE_CLASS(efl_ui_widget, "efl_ui_widget", EFL_UI_WIDGET_CLASS)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Efl_Ui_Widget *btn1, *btn2;
|
Efl_Ui_Widget *btn1, *btn2;
|
||||||
Efl_Ui_Widget *box;
|
Efl_Ui_Widget *box;
|
||||||
|
|
|
@ -138,6 +138,7 @@ efl_ui_suite_src = [
|
||||||
'efl_ui_suite.h',
|
'efl_ui_suite.h',
|
||||||
'efl_ui_model.c',
|
'efl_ui_model.c',
|
||||||
'efl_ui_test_widget.c',
|
'efl_ui_test_widget.c',
|
||||||
|
'efl_ui_test_active_view.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
efl_ui_suite = executable('efl_ui_suite',
|
efl_ui_suite = executable('efl_ui_suite',
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
/* spec-meta-start
|
/* spec-meta-start
|
||||||
{"test-interface":"Efl.Pack_Linear",
|
{"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" : {
|
"custom-mapping" : {
|
||||||
"Efl.Ui.Grid" : "EFL_UI_GRID_DEFAULT_ITEM_CLASS"
|
"Efl.Ui.Grid" : "EFL_UI_GRID_DEFAULT_ITEM_CLASS"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue