diff options
Diffstat (limited to 'src/lib/elementary/efl_ui_list.c')
-rw-r--r-- | src/lib/elementary/efl_ui_list.c | 1483 |
1 files changed, 806 insertions, 677 deletions
diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c index 68efe0a7ab..bb6abf3ef3 100644 --- a/src/lib/elementary/efl_ui_list.c +++ b/src/lib/elementary/efl_ui_list.c @@ -1,314 +1,95 @@ #ifdef HAVE_CONFIG_H # include "elementary_config.h" #endif -#define ELM_ACCESS_PROTECTED -#define ELM_ACCESS_WIDGET_ACTION_PROTECTED -#define EFL_ACCESS_SELECTION_PROTECTED + +#define ELM_LAYOUT_PROTECTED #define EFL_UI_SCROLL_MANAGER_PROTECTED #define EFL_UI_SCROLLBAR_PROTECTED #define EFL_UI_SCROLLBAR_BETA -#define EFL_GFX_SIZE_HINT_PROTECTED -#define EFL_UI_LIST_PROTECTED - #include <Elementary.h> +#include "elm_priv.h" +#include "efl_ui_list_item_private.h" +#include "efl_ui_item_private.h" #include "efl_ui_list_private.h" -#include "efl_ui_list_precise_layouter.eo.h" -#include <assert.h> +#define MY_CLASS EFL_UI_LIST_CLASS +#define MY_CLASS_PFX efl_ui_list -#define MY_CLASS EFL_UI_LIST_CLASS #define MY_CLASS_NAME "Efl.Ui.List" -#define MY_PAN_CLASS EFL_UI_LIST_PAN_CLASS - -#define SIG_CHILD_ADDED "child,added" -#define SIG_CHILD_REMOVED "child,removed" -#define SELECTED_PROP "selected" - -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHILD_ADDED, ""}, - {SIG_CHILD_REMOVED, ""}, - {NULL, NULL} -}; - -void _efl_ui_list_custom_layout(Efl_Ui_List *); -void _efl_ui_list_item_select_set(Efl_Ui_List_LayoutItem*, Eina_Bool); -static void _layout(Efl_Ui_List_Data* pd); - -static Eina_Bool _key_action_move(Evas_Object *obj, const char *params); -static Eina_Bool _key_action_select(Evas_Object *obj, const char *params); -static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params); - -static const Elm_Action key_actions[] = { - {"move", _key_action_move}, - {"select", _key_action_select}, - {"escape", _key_action_escape}, - {NULL, NULL} -}; - -EOLIAN static void -_efl_ui_list_pan_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd) -{ - evas_object_smart_changed(psd->wobj); -} - - -EOLIAN static void -_efl_ui_list_pan_efl_ui_pan_pan_position_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd, Eina_Position2D pos) -{ - if ((pos.x == psd->gmt.x) && (pos.y == psd->gmt.y)) return; - - psd->gmt.x = pos.x; - psd->gmt.y = pos.y; - - efl_event_callback_call(obj, EFL_UI_PAN_EVENT_POSITION_CHANGED, NULL); - evas_object_smart_changed(psd->wobj); -} - -EOLIAN static Eina_Position2D -_efl_ui_list_pan_efl_ui_pan_pan_position_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd) -{ - return psd->gmt.pos; -} - -EOLIAN static Eina_Position2D -_efl_ui_list_pan_efl_ui_pan_pan_position_max_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd) -{ - EFL_UI_LIST_DATA_GET(psd->wobj, pd); - Eina_Rect vgmt = {}; - Eina_Size2D min = {}; - - vgmt = efl_ui_scrollable_viewport_geometry_get(pd->scrl_mgr); - min = efl_ui_list_model_min_size_get(psd->wobj); - - min.w = min.w - vgmt.w; - if (min.w < 0) min.w = 0; - min.h = min.h - vgmt.h; - if (min.h < 0) min.h = 0; - - return EINA_POSITION2D(min.w, min.h); -} - -EOLIAN static Eina_Position2D -_efl_ui_list_pan_efl_ui_pan_pan_position_min_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd EINA_UNUSED) -{ - return EINA_POSITION2D(0, 0); -} - -EOLIAN static Eina_Size2D -_efl_ui_list_pan_efl_ui_pan_content_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *psd) -{ - Eina_Size2D min = {}; - min = efl_ui_list_model_min_size_get(psd->wobj); - - return min; -} - -EOLIAN static void -_efl_ui_list_pan_efl_object_destructor(Eo *obj, Efl_Ui_List_Pan_Data *psd EINA_UNUSED) -{ - efl_destructor(efl_super(obj, MY_PAN_CLASS)); -} - -#include "efl_ui_list_pan.eo.c" - -EOLIAN static void -_efl_ui_list_efl_ui_scrollable_interactive_content_pos_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *psd, Eina_Position2D pos) -{ - efl_ui_scrollable_content_pos_set(psd->scrl_mgr, pos); -} - -EOLIAN static Eina_Position2D -_efl_ui_list_efl_ui_scrollable_interactive_content_pos_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *psd) -{ - Eina_Position2D pos = efl_ui_scrollable_content_pos_get(psd->scrl_mgr); - return pos; -} - -EOLIAN static Eina_Size2D -_efl_ui_list_efl_ui_scrollable_interactive_content_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *psd) -{ - Eina_Size2D size = efl_ui_scrollable_content_size_get(psd->scrl_mgr); - return size; -} - -EOLIAN static Eina_Rect -_efl_ui_list_efl_ui_scrollable_interactive_viewport_geometry_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *psd) +static void +_item_scroll_internal(Eo *obj, + Efl_Ui_List_Item *item, + double align, + Eina_Bool anim) { - Eina_Rect gmt = efl_ui_scrollable_viewport_geometry_get(psd->scrl_mgr); - return gmt; -} + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + Eina_Rect ipos, view; + Eina_Position2D vpos; -static Eina_Bool -_efl_model_properties_has(Efl_Model *model, Eina_Stringshare *propfind) -{ - const Eina_Array *properties; - Eina_Array_Iterator iter_prop; - Eina_Stringshare *property; - Eina_Bool ret = EINA_FALSE; - unsigned i = 0; + if (!pd->smanager) return; - EINA_SAFETY_ON_NULL_RETURN_VAL(model, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(propfind, EINA_FALSE); + ipos = efl_gfx_entity_geometry_get(item); + view = efl_ui_scrollable_viewport_geometry_get(pd->smanager); + vpos = efl_ui_scrollable_content_pos_get(pd->smanager); - properties = efl_model_properties_get(model); + ipos.x = view.x; + ipos.w = ipos.w; - EINA_ARRAY_ITER_NEXT(properties, i, property, iter_prop) + // FIXME: align case will not correctly show in the position because of + // bar size calculation. there are no certain way to know the scroll calcuation finished. + if (EINA_DBL_EQ(align, -1.0)) { - if (property == propfind) - { - ret = EINA_TRUE; - break; - } + ipos.y = ipos.y + vpos.y - view.y; + ipos.h = ipos.h; } - return ret; -} - -static void -_on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info) -{ - Evas_Event_Mouse_Down *ev = event_info; - Efl_Ui_List_LayoutItem *item = data; - - if (ev->button != 1) return; - if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; - - _efl_ui_list_item_select_set(item, EINA_TRUE); -} - -static void -_count_then(void * data, Efl_Event const* event EINA_UNUSED) -{ - Efl_Ui_List_Data *pd = data; - EINA_SAFETY_ON_NULL_RETURN(pd); - - pd->count_future = NULL; - _layout(pd); -} - -static void -_count_error(void * data, Efl_Event const* event EINA_UNUSED) -{ - Efl_Ui_List_Data *pd = data; - EINA_SAFETY_ON_NULL_RETURN(pd); - pd->count_future = NULL; -} - -static void -_children_slice_error(void * data EINA_UNUSED, Efl_Event const* event EINA_UNUSED) -{ - Efl_Ui_List_Data *pd = data; - EINA_SAFETY_ON_NULL_RETURN(pd); - pd->slice_future = NULL; -} - -EOLIAN static void -_efl_ui_list_select_mode_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Elm_Object_Select_Mode mode) -{ - if (pd->select_mode == mode) - return; - - pd->select_mode = mode; -} - -EOLIAN static Elm_Object_Select_Mode -_efl_ui_list_select_mode_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) -{ - return pd->select_mode; -} - -EOLIAN static void -_efl_ui_list_default_style_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Eina_Stringshare *style) -{ - eina_stringshare_replace(&pd->style, style); -} - -EOLIAN static Eina_Stringshare * -_efl_ui_list_default_style_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) -{ - return pd->style; -} - -EOLIAN static void -_efl_ui_list_homogeneous_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Eina_Bool homogeneous) -{ - pd->homogeneous = homogeneous; -} - -EOLIAN static Eina_Bool -_efl_ui_list_homogeneous_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) -{ - return pd->homogeneous; -} - -EOLIAN static void -_efl_ui_list_efl_gfx_position_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Position2D pos) -{ - if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y)) - return; - - efl_gfx_position_set(efl_super(obj, MY_CLASS), pos); - evas_object_smart_changed(pd->obj); -} - -EOLIAN static void -_efl_ui_list_efl_gfx_size_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Size2D size) -{ - if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, size.w, size.h)) - return; - - efl_gfx_size_set(efl_super(obj, MY_CLASS), size); - - evas_object_smart_changed(pd->obj); -} - -EOLIAN static void -_efl_ui_list_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) -{ - _layout(pd); -} + else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) && + (align < 1.0 || EINA_DBL_EQ(align, 1.0))) + { + ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align); + ipos.h = view.h; + } + else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align); -EOLIAN static void -_efl_ui_list_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, Evas_Object *member) -{ - efl_canvas_group_member_add(efl_super(obj, MY_CLASS), member); + efl_ui_scrollable_scroll(pd->smanager, ipos, anim); } -//Scrollable Implement static void _efl_ui_list_bar_read_and_update(Eo *obj) { - EFL_UI_LIST_DATA_GET(obj, pd); + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - double vx, vy; + double vx = 0.0, vy = 0.0; edje_object_part_drag_value_get - (wd->resize_obj, "elm.dragable.vbar", NULL, &vy); - edje_object_part_drag_value_get - (wd->resize_obj, "elm.dragable.hbar", &vx, NULL); + (wd->resize_obj, "efl.dragable.vbar", NULL, &vy); - efl_ui_scrollbar_bar_position_set(pd->scrl_mgr, vx, vy); + /* FIXME: Horizontal Scroll is not yet supported in the list. + edje_object_part_drag_value_get + (wd->resize_obj, "efl.dragable.hbar", &vx, NULL); + */ - efl_canvas_group_change(pd->pan_obj); + efl_ui_scrollbar_bar_position_set(pd->smanager, vx, vy); } static void _efl_ui_list_reload_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) { - EFL_UI_LIST_DATA_GET(data, pd); + Eo *list = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd); - efl_ui_scrollbar_bar_visibility_update(pd->scrl_mgr); + efl_ui_scrollbar_bar_visibility_update(pd->smanager); } static void _efl_ui_list_vbar_drag_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) { _efl_ui_list_bar_read_and_update(data); @@ -318,9 +99,9 @@ _efl_ui_list_vbar_drag_cb(void *data, static void _efl_ui_list_vbar_press_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) { Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL; efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type); @@ -328,9 +109,9 @@ _efl_ui_list_vbar_press_cb(void *data, static void _efl_ui_list_vbar_unpress_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) { Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL; efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type); @@ -338,674 +119,1022 @@ _efl_ui_list_vbar_unpress_cb(void *data, static void _efl_ui_list_edje_drag_start_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) { - EFL_UI_LIST_DATA_GET(data, pd); + Eo *list = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd); - _efl_ui_list_bar_read_and_update(data); + _efl_ui_list_bar_read_and_update(list); - pd->scrl_freeze = efl_ui_scrollable_scroll_freeze_get(pd->scrl_mgr); - efl_ui_scrollable_scroll_freeze_set(pd->scrl_mgr, EINA_TRUE); - efl_event_callback_call(data, EFL_UI_EVENT_SCROLL_DRAG_START, NULL); + pd->freeze_want = efl_ui_scrollable_scroll_freeze_get(pd->smanager); + efl_ui_scrollable_scroll_freeze_set(pd->smanager, EINA_TRUE); + efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_START, NULL); } static void _efl_ui_list_edje_drag_stop_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) { - EFL_UI_LIST_DATA_GET(data, pd); + Eo *list = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd); - _efl_ui_list_bar_read_and_update(data); + _efl_ui_list_bar_read_and_update(list); - efl_ui_scrollable_scroll_freeze_set(pd->scrl_mgr, pd->scrl_freeze); - efl_event_callback_call(data, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL); + efl_ui_scrollable_scroll_freeze_set(pd->smanager, pd->freeze_want); + efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL); } static void _efl_ui_list_edje_drag_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) { _efl_ui_list_bar_read_and_update(data); } -static void -_efl_ui_list_hbar_drag_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) -{ +/* FIXME: Horizontal Scroll is not yet supported in the list. + static void + _efl_ui_list_hbar_drag_cb(void *data, + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) + { _efl_ui_list_bar_read_and_update(data); Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL; efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type); -} + } -static void -_efl_ui_list_hbar_press_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) -{ + static void + _efl_ui_list_hbar_press_cb(void *data, + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) + { Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL; efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type); -} - -static void -_efl_ui_list_hbar_unpress_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) -{ + } + + static void + _efl_ui_list_hbar_unpress_cb(void *data, + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) + { Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL; efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type); -} - -static void -_scroll_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED) -{ - //scroll cb -} + } + */ static void _efl_ui_list_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED) { Eo *obj = data; - EFL_UI_LIST_DATA_GET(obj, pd); + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); double width = 0.0, height = 0.0; - efl_ui_scrollbar_bar_size_get(pd->scrl_mgr, &width, &height); - - edje_object_part_drag_size_set(wd->resize_obj, "elm.dragable.hbar", width, 1.0); - edje_object_part_drag_size_set(wd->resize_obj, "elm.dragable.vbar", 1.0, height); + edje_object_calc_force(wd->resize_obj); + efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height); + edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0); + edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height); } static void _efl_ui_list_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED) { Eo *obj = data; - EFL_UI_LIST_DATA_GET(obj, pd); + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); double posx = 0.0, posy = 0.0; - efl_ui_scrollbar_bar_position_get(pd->scrl_mgr, &posx, &posy); - - edje_object_part_drag_value_set(wd->resize_obj, "elm.dragable.hbar", posx, 0.0); - edje_object_part_drag_value_set(wd->resize_obj, "elm.dragable.vbar", 0.0, posy); + efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy); + edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0); + edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy); } static void _efl_ui_list_bar_show_cb(void *data, const Efl_Event *event) { Eo *obj = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info); if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL) - edje_object_signal_emit(wd->resize_obj, "elm,action,show,hbar", "elm"); + edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl"); else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL) - edje_object_signal_emit(wd->resize_obj, "elm,action,show,vbar", "elm"); + edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl"); } static void _efl_ui_list_bar_hide_cb(void *data, const Efl_Event *event) { Eo *obj = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info); if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL) - edje_object_signal_emit(wd->resize_obj, "elm,action,hide,hbar", "elm"); + edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl"); else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL) - edje_object_signal_emit(wd->resize_obj, "elm,action,hide,vbar", "elm"); -} - -EOLIAN static Eina_Bool -_efl_ui_list_efl_layout_signal_signal_callback_add(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *sd EINA_UNUSED, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) -{ - Eina_Bool ok; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); - - ok = efl_layout_signal_callback_add(wd->resize_obj, emission, source, func_cb, data); - - return ok; -} - -EOLIAN static Eina_Bool -_efl_ui_list_efl_layout_signal_signal_callback_del(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *sd EINA_UNUSED, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) -{ - Eina_Bool ok; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); - - ok = efl_layout_signal_callback_del(wd->resize_obj, emission, source, func_cb, data); - - return ok; + edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl"); } static void -_efl_ui_list_edje_object_attach(Eo *obj) +_scroll_edje_object_attach(Eo *obj) { + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + efl_layout_signal_callback_add - (obj, "reload", "elm", _efl_ui_list_reload_cb, obj); - //Vertical bar + (obj, "reload", "efl", + _efl_ui_list_reload_cb, obj); efl_layout_signal_callback_add - (obj, "drag", "elm.dragable.vbar", _efl_ui_list_vbar_drag_cb, - obj); + (obj, "drag", "efl.dragable.vbar", + _efl_ui_list_vbar_drag_cb, obj); efl_layout_signal_callback_add - (obj, "drag,set", "elm.dragable.vbar", + (obj, "drag,set", "efl.dragable.vbar", _efl_ui_list_edje_drag_cb, obj); efl_layout_signal_callback_add - (obj, "drag,start", "elm.dragable.vbar", + (obj, "drag,start", "efl.dragable.vbar", _efl_ui_list_edje_drag_start_cb, obj); efl_layout_signal_callback_add - (obj, "drag,stop", "elm.dragable.vbar", + (obj, "drag,stop", "efl.dragable.vbar", _efl_ui_list_edje_drag_stop_cb, obj); efl_layout_signal_callback_add - (obj, "drag,step", "elm.dragable.vbar", + (obj, "drag,step", "efl.dragable.vbar", _efl_ui_list_edje_drag_cb, obj); efl_layout_signal_callback_add - (obj, "drag,page", "elm.dragable.vbar", + (obj, "drag,page", "efl.dragable.vbar", _efl_ui_list_edje_drag_cb, obj); efl_layout_signal_callback_add - (obj, "elm,vbar,press", "elm", + (obj, "efl,vbar,press", "efl", _efl_ui_list_vbar_press_cb, obj); efl_layout_signal_callback_add - (obj, "elm,vbar,unpress", "elm", + (obj, "efl,vbar,unpress", "efl", _efl_ui_list_vbar_unpress_cb, obj); - //Horizontal bar - efl_layout_signal_callback_add - (obj, "drag", "elm.dragable.hbar", _efl_ui_list_hbar_drag_cb, - obj); - efl_layout_signal_callback_add - (obj, "drag,set", "elm.dragable.hbar", - _efl_ui_list_edje_drag_cb, obj); - efl_layout_signal_callback_add - (obj, "drag,start", "elm.dragable.hbar", - _efl_ui_list_edje_drag_start_cb, obj); - efl_layout_signal_callback_add - (obj, "drag,stop", "elm.dragable.hbar", - _efl_ui_list_edje_drag_stop_cb, obj); - efl_layout_signal_callback_add - (obj, "drag,step", "elm.dragable.hbar", - _efl_ui_list_edje_drag_cb, obj); - efl_layout_signal_callback_add - (obj, "drag,page", "elm.dragable.hbar", - _efl_ui_list_edje_drag_cb, obj); - efl_layout_signal_callback_add - (obj, "elm,hbar,press", "elm", - _efl_ui_list_hbar_press_cb, obj); - efl_layout_signal_callback_add - (obj, "elm,hbar,unpress", "elm", - _efl_ui_list_hbar_unpress_cb, obj); + /* FIXME: Horizontal Scroll is not yet supported in the list. + efl_layout_signal_callback_add + (obj, "drag", "efl.dragable.hbar", + _efl_ui_list_hbar_drag_cb, obj); + efl_layout_signal_callback_add + (obj, "drag,set", "efl.dragable.hbar", + _efl_ui_list_edje_drag_cb, obj); + efl_layout_signal_callback_add + (obj, "drag,start", "efl.dragable.hbar", + _efl_ui_list_edje_drag_start_cb, obj); + efl_layout_signal_callback_add + (obj, "drag,stop", "efl.dragable.hbar", + _efl_ui_list_edje_drag_stop_cb, obj); + efl_layout_signal_callback_add + (obj, "drag,step", "efl.dragable.hbar", + _efl_ui_list_edje_drag_cb, obj); + efl_layout_signal_callback_add + (obj, "drag,page", "efl.dragable.hbar", + _efl_ui_list_edje_drag_cb, obj); + efl_layout_signal_callback_add + (obj, "efl,hbar,press", "efl", + _efl_ui_list_hbar_press_cb, obj); + efl_layout_signal_callback_add + (obj, "efl,hbar,unpress", "efl", + _efl_ui_list_hbar_unpress_cb, obj); + */ } static void -_efl_ui_list_edje_object_detach(Evas_Object *obj) +_scroll_edje_object_detach(Eo *obj) { + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + efl_layout_signal_callback_del - (obj, "reload", "elm", _efl_ui_list_reload_cb, obj); - //Vertical bar + (obj, "reload", "efl", + _efl_ui_list_reload_cb, obj); efl_layout_signal_callback_del - (obj, "drag", "elm.dragable.vbar", _efl_ui_list_vbar_drag_cb, - obj); + (obj, "drag", "efl.dragable.vbar", + _efl_ui_list_vbar_drag_cb, obj); efl_layout_signal_callback_del - (obj, "drag,set", "elm.dragable.vbar", + (obj, "drag,set", "efl.dragable.vbar", _efl_ui_list_edje_drag_cb, obj); efl_layout_signal_callback_del - (obj, "drag,start", "elm.dragable.vbar", + (obj, "drag,start", "efl.dragable.vbar", _efl_ui_list_edje_drag_start_cb, obj); efl_layout_signal_callback_del - (obj, "drag,stop", "elm.dragable.vbar", + (obj, "drag,stop", "efl.dragable.vbar", _efl_ui_list_edje_drag_stop_cb, obj); efl_layout_signal_callback_del - (obj, "drag,step", "elm.dragable.vbar", + (obj, "drag,step", "efl.dragable.vbar", _efl_ui_list_edje_drag_cb, obj); efl_layout_signal_callback_del - (obj, "drag,page", "elm.dragable.vbar", + (obj, "drag,page", "efl.dragable.vbar", _efl_ui_list_edje_drag_cb, obj); efl_layout_signal_callback_del - (obj, "elm,vbar,press", "elm", + (obj, "efl,vbar,press", "efl", _efl_ui_list_vbar_press_cb, obj); efl_layout_signal_callback_del - (obj, "elm,vbar,unpress", "elm", - _efl_ui_list_vbar_unpress_cb, obj); + (obj, "efl,vbar,unpress", "efl", + _efl_ui_list_vbar_unpress_cb, obj); - //Horizontal bar - efl_layout_signal_callback_del - (obj, "drag", "elm.dragable.hbar", _efl_ui_list_hbar_drag_cb, - obj); - efl_layout_signal_callback_del - (obj, "drag,set", "elm.dragable.hbar", - _efl_ui_list_edje_drag_cb, obj); - efl_layout_signal_callback_del - (obj, "drag,start", "elm.dragable.hbar", - _efl_ui_list_edje_drag_start_cb, obj); - efl_layout_signal_callback_del - (obj, "drag,stop", "elm.dragable.hbar", - _efl_ui_list_edje_drag_stop_cb, obj); - efl_layout_signal_callback_del - (obj, "drag,step", "elm.dragable.hbar", - _efl_ui_list_edje_drag_cb, obj); - efl_layout_signal_callback_del - (obj, "drag,page", "elm.dragable.hbar", - _efl_ui_list_edje_drag_cb, obj); - efl_layout_signal_callback_del - (obj, "elm,hbar,press", "elm", - _efl_ui_list_hbar_press_cb, obj); - efl_layout_signal_callback_del - (obj, "elm,hbar,unpress", "elm", - _efl_ui_list_hbar_unpress_cb, obj); + /* FIXME: Horizontal Scroll is not yet supported in the list. + efl_layout_signal_callback_del + (obj, "drag", "efl.dragable.hbar", + _efl_ui_list_hbar_drag_cb, obj); + efl_layout_signal_callback_del + (obj, "drag,set", "efl.dragable.hbar", + _efl_ui_list_edje_drag_cb, obj); + efl_layout_signal_callback_del + (obj, "drag,start", "efl.dragable.hbar", + _efl_ui_list_edje_drag_start_cb, obj); + efl_layout_signal_callback_del + (obj, "drag,stop", "efl.dragable.hbar", + _efl_ui_list_edje_drag_stop_cb, obj); + efl_layout_signal_callback_del + (obj, "drag,step", "efl.dragable.hbar", + _efl_ui_list_edje_drag_cb, obj); + efl_layout_signal_callback_del + (obj, "drag,page", "efl.dragable.hbar", + _efl_ui_list_edje_drag_cb, obj); + efl_layout_signal_callback_del + (obj, "efl,hbar,press", "efl", + _efl_ui_list_hbar_press_cb, obj); + efl_layout_signal_callback_del + (obj, "efl,hbar,unpress", "efl", + _efl_ui_list_hbar_unpress_cb, obj); + */ } -EOLIAN static void -_efl_ui_list_efl_canvas_group_group_add(Eo *obj, Efl_Ui_List_Data *pd) +static void +_efl_ui_list_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED) { - Efl_Ui_List_Pan_Data *pan_data; - Eina_Size2D min = {}; - Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable; + Eo *obj = data; + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + if (!pd->smanager) return; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); + elm_layout_sizing_eval(obj); + + if (!pd->pan_resized) + { + Eina_Rect view = efl_ui_scrollable_viewport_geometry_get(pd->smanager); + // FIXME: Below code is workaround size check + if (view.h > 1) + { + pd->pan_resized = EINA_TRUE; + if (pd->scroll.item) + { + _item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim); + + pd->scroll.item = NULL; + pd->scroll.align = 0.0; + pd->scroll.anim = EINA_FALSE; + return; + } + } + } +} - efl_canvas_group_add(efl_super(obj, MY_CLASS)); - elm_widget_sub_object_parent_add(obj); +static void +_efl_ui_list_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + elm_layout_sizing_eval(data); +} - elm_widget_can_focus_set(obj, EINA_TRUE); +static void +_efl_ui_list_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + elm_layout_sizing_eval(data); +} - if (!elm_layout_theme_set(obj, "list", "base", elm_widget_style_get(obj))) - CRI("Failed to set layout!"); +EOLIAN static Eo * +_efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); - pd->scrl_mgr = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj, - efl_ui_mirrored_set(efl_added, efl_ui_mirrored_get(obj))); - pd->pan_obj = efl_add(MY_PAN_CLASS, obj); - pan_data = efl_data_scope_get(pd->pan_obj, MY_PAN_CLASS); - pan_data->wobj = obj; + return obj; +} + +EOLIAN static Eo * +_efl_ui_list_efl_object_finalize(Eo *obj, + Efl_Ui_List_Data *pd) +{ + obj = efl_finalize(efl_super(obj, MY_CLASS)); - efl_ui_scroll_manager_pan_set(pd->scrl_mgr, pd->pan_obj); - efl_ui_scrollable_bounce_enabled_set(pd->scrl_mgr, bounce, bounce); + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); - edje_object_part_swallow(wd->resize_obj, "elm.swallow.content", pd->pan_obj); - efl_gfx_stack_raise((Eo *)edje_object_part_object_get(wd->resize_obj, "elm.dragable.vbar")); + efl_ui_layout_object_theme_set(obj, "list", "base", efl_ui_widget_style_get(obj)); - pd->mode = ELM_LIST_COMPRESS; + pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj); + efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj)); - efl_gfx_visible_set(pd->pan_obj, EINA_TRUE); + pd->pan = efl_add(EFL_UI_PAN_CLASS, obj); - efl_access_type_set(obj, EFL_ACCESS_TYPE_DISABLED); + efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan); + edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan); - edje_object_size_min_calc(wd->resize_obj, &min.w, &min.h); - efl_gfx_size_hint_restricted_min_set(obj, min); + pd->box = efl_add(EFL_UI_BOX_CLASS, obj, + efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL)); + efl_ui_mirrored_set(pd->box, efl_ui_mirrored_get(obj)); + efl_content_set(pd->pan, pd->box); + + pd->select_mode = EFL_UI_SELECT_SINGLE; + + _scroll_edje_object_attach(obj); - efl_event_callback_add(obj, EFL_UI_EVENT_SCROLL, _scroll_cb, obj); efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED, - _efl_ui_list_bar_size_changed_cb, obj); + _efl_ui_list_bar_size_changed_cb, obj); efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED, - _efl_ui_list_bar_pos_changed_cb, obj); + _efl_ui_list_bar_pos_changed_cb, obj); efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW, - _efl_ui_list_bar_show_cb, obj); + _efl_ui_list_bar_show_cb, obj); efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE, _efl_ui_list_bar_hide_cb, obj); - - _efl_ui_list_edje_object_attach(obj); + efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_RESIZE, + _efl_ui_list_resized_cb, obj); + efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS, + _efl_ui_list_size_hint_changed_cb, obj); + efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE, + _efl_ui_list_pan_resized_cb, obj); elm_layout_sizing_eval(obj); + + return obj; } EOLIAN static void -_efl_ui_list_efl_canvas_group_group_del(Eo *obj, Efl_Ui_List_Data *pd) +_efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd) { - ELM_SAFE_FREE(pd->pan_obj, evas_object_del); - efl_canvas_group_del(efl_super(obj, MY_CLASS)); + _scroll_edje_object_detach(obj); + + efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED, + _efl_ui_list_bar_size_changed_cb, obj); + efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED, + _efl_ui_list_bar_pos_changed_cb, obj); + efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW, + _efl_ui_list_bar_show_cb, obj); + efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE, + _efl_ui_list_bar_hide_cb, obj); + efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_RESIZE, + _efl_ui_list_resized_cb, obj); + efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS, + _efl_ui_list_size_hint_changed_cb, obj); + efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE, + _efl_ui_list_pan_resized_cb, obj); + + efl_del(pd->box); + pd->box = NULL; + efl_del(pd->pan); + pd->pan = NULL; + efl_del(pd->smanager); + pd->smanager = NULL; + + efl_destructor(efl_super(obj, MY_CLASS)); } -EOLIAN static Efl_Ui_Focus_Manager* -_efl_ui_list_elm_widget_focus_manager_create(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root) +EOLIAN static void +_efl_ui_list_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED) { - if (!pd->manager) - pd->manager = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, obj, - efl_ui_focus_manager_root_set(efl_added, root)); - - return pd->manager; + // Need to be implemented + efl_canvas_group_calculate(efl_super(obj, MY_CLASS)); } -EOLIAN static Eo * -_efl_ui_list_efl_object_finalize(Eo *obj, Efl_Ui_List_Data *pd) +EOLIAN static void +_efl_ui_list_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Data *pd) { + Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1}; + Eina_Rect view = {}; + Evas_Coord vmw = 0, vmh = 0; + double xw = 0.0, yw = 0.0; - if (!pd->factory) - pd->factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, NULL); + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - if(!pd->relayout) + if (pd->box) { - pd->relayout = efl_add(EFL_UI_LIST_PRECISE_LAYOUTER_CLASS, obj); - if (pd->model) - efl_ui_list_relayout_model_set(pd->relayout, pd->model); + min = efl_gfx_size_hint_combined_min_get(pd->box); + max = efl_gfx_size_hint_max_get(pd->box); + efl_gfx_size_hint_weight_get(pd->box, &xw, &yw); } - return obj; -} -EOLIAN static Eo * -_efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd) -{ - Efl_Ui_Focus_Manager *manager; + if (pd->smanager) + view = efl_ui_scrollable_viewport_geometry_get(pd->smanager); - obj = efl_constructor(efl_super(obj, MY_CLASS)); - pd->obj = obj; - efl_canvas_object_type_set(obj, MY_CLASS_NAME); - evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks); - efl_access_role_set(obj, EFL_ACCESS_ROLE_LIST); + if (xw > 0.0) + { + if ((min.w > 0) && (view.w < min.w)) + view.w = min.w; + else if ((max.w > 0) && (view.w > max.w)) + view.w = max.w; + } + else if (min.w > 0) + view.w = min.w; + + if (yw > 0.0) + { + if ((min.h > 0) && (view.h < min.h)) + view.h = min.h; + else if ((max.h > 0) && (view.h > max.h)) + view.h = max.h; + } + else if (min.h > 0) + view.h = min.h; - efl_ui_list_segarray_setup(&pd->segarray, 32); + if (pd->box) efl_gfx_entity_size_set(pd->box, EINA_SIZE2D(view.w, view.h)); - manager = efl_ui_widget_focus_manager_create(obj, obj); - efl_composite_attach(obj, manager); - _efl_ui_focus_manager_redirect_events_add(manager, obj); + edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh); - pd->style = eina_stringshare_add(elm_widget_style_get(obj)); + if (pd->match_content_w) size.w = vmw + min.w; + if (pd->match_content_h) size.h = vmh + min.h; - pd->factory = NULL; - pd->orient = EFL_ORIENT_DOWN; - pd->align.h = 0; - pd->align.v = 0; - pd->min.w = 0; - pd->min.h = 0; + max = efl_gfx_size_hint_max_get(obj); + if ((max.w > 0) && (size.w > max.w)) size.w = max.w; + if ((max.h > 0) && (size.h > max.h)) size.h = max.h; - return obj; + efl_gfx_size_hint_min_set(obj, size); } -EOLIAN static void -_efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd) +//FIXME: is this box related API could be improved more? +EOLIAN static int +_efl_ui_list_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + return pd->box ? efl_content_count(pd->box) : 0; +} + +EOLIAN static Eina_Iterator * +_efl_ui_list_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) { - efl_ui_list_relayout_model_set(pd->relayout, NULL); + return pd->box ? efl_content_iterate(pd->box) : NULL; +} - efl_unref(pd->model); - eina_stringshare_del(pd->style); +/* FIXME: Direction is not supported yet in the list + EOLIAN static void + _efl_ui_list_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_Dir dir) + { + switch (dir) + { + case EFL_UI_DIR_RTL: + // FIXME: Should be inverted! + case EFL_UI_DIR_HORIZONTAL: + case EFL_UI_DIR_LTR: + pd->dir = EFL_UI_DIR_HORIZONTAL; + break; + + case EFL_UI_DIR_UP: + // FIXME: Should be inverted! + case EFL_UI_DIR_DOWN: + case EFL_UI_DIR_VERTICAL: + case EFL_UI_DIR_DEFAULT: + default: + pd->dir = EFL_UI_DIR_VERTICAL; + break; + } - efl_event_callback_del(obj, EFL_UI_EVENT_SCROLL, _scroll_cb, obj); - _efl_ui_list_edje_object_detach(obj); + efl_pack_layout_request(obj); + } + */ - ELM_SAFE_FREE(pd->pan_obj, evas_object_del); - efl_canvas_group_del(efl_super(obj, MY_CLASS)); +EOLIAN static Efl_Ui_Theme_Apply +_efl_ui_list_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_List_Data *pd) +{ + Efl_Ui_Theme_Apply int_ret = EFL_UI_THEME_APPLY_FAILED; + int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS)); + if (!int_ret) return EFL_UI_THEME_APPLY_FAILED; - efl_ui_list_segarray_flush(&pd->segarray); + efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj)); - efl_destructor(efl_super(obj, MY_CLASS)); + elm_layout_sizing_eval(obj); + + return int_ret; } -EOLIAN static void -_efl_ui_list_layout_factory_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Efl_Ui_Factory *factory) +static void +_list_item_pressed(void *data, const Efl_Event *event) { - if (pd->factory) - efl_unref(pd->factory); + Eo *obj = data; + Efl_Ui_List_Item *item = event->object; + efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item); +} - pd->factory = factory; - efl_ref(pd->factory); +static void +_list_item_unpressed(void *data, const Efl_Event *event) +{ + Eo *obj = data; + Efl_Ui_List_Item *item = event->object; + efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item); } -EOLIAN static void -_efl_ui_list_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, Efl_Model *model) +static void +_list_item_longpressed(void *data, const Efl_Event *event) { - if (pd->model == model) - return; + Eo *obj = data; + Efl_Ui_List_Item *item = event->object; + efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item); +} - if (pd->count_future) - { - efl_future_cancel(pd->count_future); - pd->count_future = NULL; - } +static void +_list_item_selected(void *data, const Efl_Event *event) +{ + Eo *obj = data; + Efl_Ui_List_Item *item = event->object; + Efl_Ui_List_Item *selected; + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); - if (pd->model) + /* Single Select */ + if (pd->select_mode != EFL_UI_SELECT_MULTI) { - if (pd->relayout) - efl_ui_list_relayout_model_set(pd->relayout, NULL); - efl_ui_list_segarray_flush(&pd->segarray); - efl_unref(pd->model); - pd->model = NULL; + EINA_LIST_FREE(pd->selected, selected) + { + if (selected != item) + efl_ui_item_selected_set(selected, EINA_FALSE); + } } + pd->selected = eina_list_append(pd->selected, item); + pd->last_selected = item; - if (model) - { - pd->model = model; - efl_ref(pd->model); - if (pd->relayout) - efl_ui_list_relayout_model_set(pd->relayout, model); - pd->count_future = efl_model_children_count_get(pd->model); - efl_future_then(pd->count_future, &_count_then, &_count_error, NULL, pd); - } + efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, item); +} - evas_object_smart_changed(pd->obj); +static void +_list_item_unselected(void *data, const Efl_Event *event) +{ + Eo *obj = data; + Efl_Ui_List_Item *item = event->object; + EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd); + + pd->selected = eina_list_remove(pd->selected, item); + if (pd->last_selected == item) pd->last_selected = NULL; + + efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, item); } -EOLIAN static Efl_Model * -_efl_ui_list_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +static Eina_Bool +_list_item_process(Eo *obj, Efl_Ui_List_Data *pd, EINA_UNUSED Efl_Ui_List_Item *it) { - return pd->model; + EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE); + + //FIXME: This is tricky workaround for set select mode and parent value. + EFL_UI_LIST_ITEM_DATA_GET(it, ld); + EFL_UI_ITEM_DATA_GET(it, id); + id->select_mode = &(pd->select_mode); + id->parent = obj; + ld->parent = obj; + efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj)); + + efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj); + efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj); + efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj); + efl_event_callback_add(it, EFL_UI_EVENT_SELECTED, _list_item_selected, obj); + efl_event_callback_add(it, EFL_UI_EVENT_UNSELECTED, _list_item_unselected, obj); + + return EINA_TRUE; } -EOLIAN int -_efl_ui_list_efl_access_selection_selected_children_count_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +static void +_list_item_clear(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, EINA_UNUSED Efl_Ui_List_Item *it) { - return eina_list_count(pd->selected_items); + EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it); + EFL_UI_LIST_ITEM_DATA_GET(it, ld); + EFL_UI_ITEM_DATA_GET(it, id); + id->select_mode = NULL; + id->parent = NULL; + ld->parent = NULL; + + efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj); + efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj); + efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj); + efl_event_callback_del(it, EFL_UI_EVENT_SELECTED, _list_item_selected, obj); + efl_event_callback_del(it, EFL_UI_EVENT_UNSELECTED, _list_item_unselected, obj); } -EOLIAN Eo* -_efl_ui_list_efl_access_selection_selected_child_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int child_index) +/* Pack APIs */ +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_pack_clear(Eo *obj, Efl_Ui_List_Data *pd) { - if(child_index < (int) eina_list_count(pd->selected_items)) + Eina_Bool ret = efl_pack_clear(pd->box); + + if (ret) { - Efl_Ui_List_Item* items = eina_list_nth(pd->selected_items, child_index); - return items[child_index].item.layout; + eina_list_free(pd->items); + eina_list_free(pd->selected); + pd->items = NULL; + pd->selected = NULL; } - else - return NULL; + + elm_layout_sizing_eval(obj); + return ret; } -EOLIAN Eina_Bool -_efl_ui_list_efl_access_selection_child_select(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_unpack_all(Eo *obj, Efl_Ui_List_Data *pd) { - return EINA_FALSE; + Eina_Bool ret = efl_pack_unpack_all(pd->box); + + if (ret) + { + Efl_Ui_List_Item *it = NULL; + EINA_LIST_FREE(pd->items, it) + { + _list_item_clear(obj, pd, it); + } + eina_list_free(pd->selected); + pd->items = NULL; + pd->selected = NULL; + } + + elm_layout_sizing_eval(obj); + return ret; } -EOLIAN Eina_Bool -_efl_ui_list_efl_access_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_unpack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj) { - return EINA_FALSE; + Eina_Bool ret = efl_pack_unpack(pd->box, subobj); + Efl_Ui_List_Item *item = (Efl_Ui_List_Item *)subobj; + + if (ret) + { + pd->items = eina_list_remove(pd->items, item); + if (efl_ui_item_selected_get(item)) + { + pd->selected = eina_list_remove(pd->selected, item); + } + _list_item_clear(obj, pd, item); + } + + elm_layout_sizing_eval(obj); + return ret; } -EOLIAN Eina_Bool -_efl_ui_list_efl_access_selection_is_child_selected(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_pack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj) { - return EINA_FALSE; + if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE; + + Eina_Bool ret = efl_pack_end(pd->box, subobj); + pd->items = eina_list_append(pd->items, subobj); + return ret; } -EOLIAN Eina_Bool -_efl_ui_list_efl_access_selection_all_children_select(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj) { - return EINA_TRUE; + if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE; + + Eina_Bool ret = efl_pack_end(pd->box, subobj); + pd->items = eina_list_append(pd->items, subobj); + return ret; } -EOLIAN Eina_Bool -_efl_ui_list_efl_access_selection_clear(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj) { - return EINA_TRUE; + if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE; + + Eina_Bool ret = efl_pack_begin(pd->box, subobj); + pd->items = eina_list_prepend(pd->items, subobj); + return ret; } -EOLIAN Eina_Bool -_efl_ui_list_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_linear_pack_before(Eo *obj, + Efl_Ui_List_Data *pd, + Efl_Gfx_Entity *subobj, + const Efl_Gfx_Entity *existing) { - return EINA_FALSE; + if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE; + EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE); + + Eina_Bool ret = efl_pack_before(pd->box, subobj, existing); + pd->items = eina_list_prepend_relative(pd->items, subobj, existing); + return ret; } -static Eina_Bool -_key_action_move(Evas_Object *obj EINA_UNUSED, const char *params EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_linear_pack_after(Eo *obj, + Efl_Ui_List_Data *pd, + Efl_Gfx_Entity *subobj, + const Efl_Gfx_Entity *existing) { - return EINA_FALSE; + if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE; + EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE); + + Eina_Bool ret = efl_pack_after(pd->box, subobj, existing); + pd->items = eina_list_append_relative(pd->items, subobj, existing); + return ret; } -static Eina_Bool -_key_action_select(Evas_Object *obj EINA_UNUSED, const char *params EINA_UNUSED) +EOLIAN static Eina_Bool +_efl_ui_list_efl_pack_linear_pack_at(Eo *obj, + Efl_Ui_List_Data *pd, + Efl_Gfx_Entity *subobj, + int index) { - return EINA_FALSE; + if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE; + Efl_Ui_List_Item *existing = efl_pack_content_get(pd->box, index); + + Eina_Bool ret = efl_pack_at(pd->box, subobj, index); + pd->items = eina_list_append_relative(pd->items, subobj, existing); + return ret; } -static Eina_Bool -_key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED) +EOLIAN static Efl_Gfx_Entity * +_efl_ui_list_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index) { - efl_ui_focus_manager_reset_history(obj); - return EINA_TRUE; + return efl_pack_content_get(pd->box, index); } -ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_list, Efl_Ui_List_Data) +EOLIAN static Efl_Gfx_Entity * +_efl_ui_list_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index) +{ + return efl_pack_unpack_at(pd->box, index); +} -void -_efl_ui_list_item_select_set(Efl_Ui_List_LayoutItem *item, Eina_Bool selected) +EOLIAN static int +_efl_ui_list_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + const Efl_Gfx_Entity *subobj) { - Eina_Stringshare *sprop; - assert(item != NULL); - assert(item->children != NULL); + return efl_pack_index_get(pd->box, subobj); +} - selected = !!selected; +EOLIAN static void +_efl_ui_list_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_List_Data *pd) +{ + efl_pack_layout_update(pd->box); + elm_layout_sizing_eval(obj); - sprop = eina_stringshare_add(SELECTED_PROP); + efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL); +} - if (_efl_model_properties_has(item->children, sprop)) - { - Eina_Value v; - eina_value_setup(&v, EINA_VALUE_TYPE_UCHAR); - eina_value_set(&v, selected); - efl_model_property_set(item->children, sprop, &v); - eina_value_flush(&v); - } - eina_stringshare_del(sprop); +EOLIAN static void +_efl_ui_list_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_List_Data *pd) +{ + efl_pack_layout_request(pd->box); + elm_layout_sizing_eval(obj); } -static void -_efl_ui_list_relayout_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED, Efl_Ui_List_Relayout *object) +EOLIAN static void +_efl_ui_list_efl_pack_pack_padding_set(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + double h, + double v, + Eina_Bool scalable) { - if(pd->relayout) - efl_unref(pd->relayout); + efl_pack_padding_set(pd->box, h, v, scalable); +} - pd->relayout = object; - efl_ref(pd->relayout); +EOLIAN static void +_efl_ui_list_efl_pack_pack_padding_get(const Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + double *h, + double *v, + Eina_Bool *scalable) +{ + efl_pack_padding_get(pd->box, h, v, scalable); +} + +/* FIXME: align could not work properly on the list + EOLIAN static void + _efl_ui_list_efl_pack_pack_align_set(Eo *obj, Efl_Ui_List_Data *pd, double h, double v) + { + efl_pack_align_set(pd->box, h, v); + } + + EOLIAN static void + _efl_ui_list_efl_pack_pack_align_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, double *h, double *v) + { + efl_pack_align_get(pd->box, &h, &v); + } + */ + +/* Scroll APIs */ +EOLIAN static Eina_Size2D +_efl_ui_list_efl_ui_scrollable_interactive_content_size_get(const Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd) +{ + return efl_ui_scrollable_content_size_get(pd->smanager); } -static Efl_Ui_List_Relayout * -_efl_ui_list_relayout_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED) +EOLIAN static Eina_Rect +_efl_ui_list_efl_ui_scrollable_interactive_viewport_geometry_get(const Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd) { - return pd->relayout; + return efl_ui_scrollable_viewport_geometry_get(pd->smanager); } -static void -_layout(Efl_Ui_List_Data *pd) +EOLIAN static void +_efl_ui_list_efl_ui_scrollable_interactive_bounce_enabled_set(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Eina_Bool horiz, + Eina_Bool vert) { - if (!pd->model) - return; + efl_ui_scrollable_bounce_enabled_set(pd->smanager, horiz, vert); +} - efl_ui_list_relayout_layout_do(pd->relayout, pd->obj, pd->segarray_first, &pd->segarray); +EOLIAN static void +_efl_ui_list_efl_ui_scrollable_interactive_bounce_enabled_get(const Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Eina_Bool *horiz, + Eina_Bool *vert) +{ + efl_ui_scrollable_bounce_enabled_get(pd->smanager, horiz, vert); } -static void -_children_slice_then(void * data, Efl_Event const* event) +EOLIAN static Eina_Bool +_efl_ui_list_efl_ui_scrollable_interactive_scroll_hold_get(const Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd) { - Efl_Ui_List_Data *pd = data; - Eina_Accessor *acc = (Eina_Accessor*)((Efl_Future_Event_Success*)event->info)->value; + return efl_ui_scrollable_scroll_hold_get(pd->smanager); +} - efl_ui_list_segarray_insert_accessor(&pd->segarray, pd->outstanding_slice.slice_start, acc); +EOLIAN static void +_efl_ui_list_efl_ui_scrollable_interactive_scroll_hold_set(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Eina_Bool hold) +{ + efl_ui_scrollable_scroll_hold_set(pd->smanager, hold); +} - pd->segarray_first = pd->outstanding_slice.slice_start; - pd->outstanding_slice.slice_start = pd->outstanding_slice.slice_count = 0; - pd->slice_future = NULL; +EOLIAN static Eina_Bool +_efl_ui_list_efl_ui_scrollable_interactive_scroll_freeze_get(const Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd) +{ + return efl_ui_scrollable_scroll_freeze_get(pd->smanager); } -/* EFL UI LIST MODEL INTERFACE */ -EOLIAN static Eina_Size2D -_efl_ui_list_efl_ui_list_model_min_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +EOLIAN static void +_efl_ui_list_efl_ui_scrollable_interactive_scroll_freeze_set(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Eina_Bool freeze) { - return pd->min; + efl_ui_scrollable_scroll_freeze_set(pd->smanager, freeze); } EOLIAN static void -_efl_ui_list_efl_ui_list_model_min_size_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Size2D min) +_efl_ui_list_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Eina_Bool match_content_w, + Eina_Bool match_content_h) { - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); + pd->match_content_w = !!match_content_w; + pd->match_content_h = !!match_content_h; - pd->min.w = min.w; - pd->min.h = min.h; + efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h); - evas_object_size_hint_min_set(wd->resize_obj, pd->min.w, pd->min.h); - efl_event_callback_call(pd->pan_obj, EFL_UI_PAN_EVENT_CONTENT_CHANGED, NULL); + elm_layout_sizing_eval(obj); } -EOLIAN static Efl_Ui_List_LayoutItem * -_efl_ui_list_efl_ui_list_model_realize(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_List_LayoutItem *item) +EOLIAN static void +_efl_ui_list_efl_ui_scrollbar_bar_mode_set(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Efl_Ui_Scrollbar_Mode hmode, + Efl_Ui_Scrollbar_Mode vmode) { - Efl_Ui_List_Item_Event evt; - EINA_SAFETY_ON_NULL_RETURN_VAL(item->children, item); - - item->layout = efl_ui_factory_create(pd->factory, item->children, obj); - evas_object_smart_member_add(item->layout, pd->pan_obj); - evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item); + efl_ui_scrollbar_bar_mode_set(pd->smanager, hmode, vmode); +} - evt.child = item->children; - evt.layout = item->layout; - evt.index = efl_ui_list_item_index_get((Efl_Ui_List_Item *)item); - efl_event_callback_call(obj, EFL_UI_LIST_EVENT_ITEM_REALIZED, &evt); +EOLIAN static void +_efl_ui_list_efl_ui_scrollbar_bar_mode_get(const Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Efl_Ui_Scrollbar_Mode *hmode, + Efl_Ui_Scrollbar_Mode *vmode) +{ + efl_ui_scrollbar_bar_mode_get(pd->smanager, hmode, vmode); +} - evas_object_show(item->layout); - return item; +EOLIAN static void +_efl_ui_list_efl_ui_scrollable_interactive_scroll(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Eina_Rect rc, + Eina_Bool animation) +{ + efl_ui_scrollable_scroll(pd->smanager, rc, animation); } EOLIAN static void -_efl_ui_list_efl_ui_list_model_unrealize(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_List_LayoutItem *item) +_efl_ui_list_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED, + Efl_Ui_List_Data *pd, + Efl_Ui_Select_Mode mode) { - Efl_Ui_List_Item_Event evt; - EINA_SAFETY_ON_NULL_RETURN(item->layout); + Efl_Ui_List_Item *selected; - evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item); - evas_object_hide(item->layout); - evas_object_move(item->layout, -9999, -9999); + if ((pd->select_mode == EFL_UI_SELECT_MULTI && + mode != EFL_UI_SELECT_MULTI) || + mode == EFL_UI_SELECT_NONE) + { + Eina_List *clone = eina_list_clone(pd->selected); + EINA_LIST_FREE(clone, selected) + efl_ui_item_selected_set(selected, EINA_FALSE); + } - evt.child = item->children; - evt.layout = item->layout; - evt.index = efl_ui_list_item_index_get((Efl_Ui_List_Item *)item); - efl_event_callback_call(obj, EFL_UI_LIST_EVENT_ITEM_UNREALIZED, &evt); + pd->select_mode = mode; +} - evas_object_smart_member_del(item->layout); - efl_ui_factory_release(pd->factory, item->layout); - item->layout = NULL; +EOLIAN static Efl_Ui_Select_Mode +_efl_ui_list_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +{ + return pd->select_mode; } +/* List APIs */ EOLIAN static void -_efl_ui_list_efl_ui_list_model_load_range_set(Eo* obj EINA_UNUSED, Efl_Ui_List_Data* pd, int first, int count) +_efl_ui_list_item_scroll(Eo *obj, + Efl_Ui_List_Data *pd, + Efl_Ui_List_Item *item, + Eina_Bool animation) { - if(!pd->slice_future) + // Need to be implemented here. + if (pd->pan_resized) { - pd->slice_future = efl_model_children_slice_get(pd->model, first, count); - pd->outstanding_slice.slice_start = first; - pd->outstanding_slice.slice_count = count; - efl_future_then(pd->slice_future, &_children_slice_then, &_children_slice_error, NULL, pd); + _item_scroll_internal(obj, item, -1.0, animation); + } + else + { + pd->scroll.item = item; + pd->scroll.align = -1.0; + pd->scroll.anim = animation; } } -EOLIAN static int -_efl_ui_list_efl_ui_list_model_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) +EOLIAN static void +_efl_ui_list_item_scroll_align(Eo *obj, + Efl_Ui_List_Data *pd, + Efl_Ui_List_Item *item, + double align, + Eina_Bool animation) +{ + // Need to be implemented here. + if (pd->pan_resized) + { + _item_scroll_internal(obj, item, align, animation); + } + else + { + pd->scroll.item = item; + pd->scroll.align = align; + pd->scroll.anim = animation; + } +} + +EOLIAN static Efl_Ui_List_Item * +_efl_ui_list_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd) { - return pd->item_count; + return pd->last_selected; } -/* Internal EO APIs and hidden overrides */ +static Eina_Bool +_list_item_iterator_next(Item_Iterator *it, void **data) +{ + Efl_Ui_List_Item *item; + + if (!eina_iterator_next(it->real_iterator, (void **)&item)) + return EINA_FALSE; + + if (data) *data = item; + return EINA_TRUE; +} + +static Eo * +_list_item_iterator_get_container(Item_Iterator *it) +{ + return it->object; +} + +static void +_list_item_iterator_free(Item_Iterator *it) +{ + eina_iterator_free(it->real_iterator); + eina_list_free(it->list); + free(it); +} + +EOLIAN static Eina_Iterator * +_efl_ui_list_selected_items_get(Eo *obj, Efl_Ui_List_Data *pd) +{ + Item_Iterator *item; + + item = calloc(1, sizeof(*item)); + if (!item) return NULL; + + EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR); + + item->list = eina_list_clone(pd->selected); + item->real_iterator = eina_list_iterator_new(item->list); + item->iterator.version = EINA_ITERATOR_VERSION; + item->iterator.next = FUNC_ITERATOR_NEXT(_list_item_iterator_next); + item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_list_item_iterator_get_container); + item->iterator.free = FUNC_ITERATOR_FREE(_list_item_iterator_free); + item->object = obj; + return &item->iterator; +} + +/* Internal EO APIs and hidden overrides */ #define EFL_UI_LIST_EXTRA_OPS \ - EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_list) + ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_list) #include "efl_ui_list.eo.c" -#include "efl_ui_list_relayout.eo.c" -#include "efl_ui_list_model.eo.c" |