From 0f636e890a7de818be338b3bebd10134779c37d4 Mon Sep 17 00:00:00 2001 From: Hosang Kim Date: Thu, 24 Apr 2014 14:12:52 +0900 Subject: [PATCH] genlist: Add item loop feature Summary: If item loop feature is enabled, item is moved infinitely. 1. Refactor direction key event handling routine - added internal function _elm_genlist_elm_widget_event_direction. 2. Add looping feature for genlist - added Eolian function _elm_genlist_elm_widget_item_loop_enabled_set/get. 3. Add demo - test_genlist.c / genlist focus Reviewers: seoz, woohyun, jaehwan, Hermet, raster Reviewed By: Hermet Differential Revision: https://phab.enlightenment.org/D778 Conflicts: src/lib/elm_widget_genlist.h --- legacy/elementary/src/bin/test_genlist.c | 18 ++- legacy/elementary/src/lib/elm_genlist.c | 111 +++++++++++++++++- legacy/elementary/src/lib/elm_genlist.eo | 2 + .../elementary/src/lib/elm_widget_genlist.h | 2 + 4 files changed, 126 insertions(+), 7 deletions(-) diff --git a/legacy/elementary/src/bin/test_genlist.c b/legacy/elementary/src/bin/test_genlist.c index 14186a74de..4557804fb3 100644 --- a/legacy/elementary/src/bin/test_genlist.c +++ b/legacy/elementary/src/bin/test_genlist.c @@ -3615,7 +3615,7 @@ test_genlist_del(void *data EINA_UNUSED, } /*************/ -static unsigned _gl_focus_objects = 5; +static unsigned _gl_focus_objects = 3; static const char *_gl_focus_object_names[] = {"None", "Square", "Button", "Check", "Box"}; static char * @@ -3674,6 +3674,14 @@ gl_focus_content_get(void *data, Evas_Object *obj, const char *part) return cnt; } +static void +test_genlist_focus_item_loop_enable_check_changed(void *data, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + Evas_Object *gl = data; + elm_object_scroll_item_loop_enabled_set(gl, elm_check_state_get(obj)); +} + static void test_genlist_focus_focus_on_selection_set(Evas_Object *gl, Evas_Object *chk, Eina_Bool focus) @@ -3947,6 +3955,14 @@ test_genlist_focus(void *data EINA_UNUSED, elm_box_pack_end(bx_opt, chk); evas_object_show(chk); + chk = elm_check_add(bx_opt); + elm_object_text_set(chk, "Item Looping Enalbe"); + evas_object_size_hint_weight_set(chk, EVAS_HINT_EXPAND, 0.0); + evas_object_smart_callback_add(chk, "changed", + test_genlist_focus_item_loop_enable_check_changed, gl); + elm_box_pack_end(bx_opt, chk); + evas_object_show(chk); + // Focus Movement Policy fr = elm_frame_add(bx); elm_object_text_set(fr, "Focus Movement Policy"); diff --git a/legacy/elementary/src/lib/elm_genlist.c b/legacy/elementary/src/lib/elm_genlist.c index db317d4854..28cd2f1324 100644 --- a/legacy/elementary/src/lib/elm_genlist.c +++ b/legacy/elementary/src/lib/elm_genlist.c @@ -2576,6 +2576,64 @@ _elm_genlist_item_content_focus_set(Elm_Gen_Item *it, Elm_Focus_Direction dir) elm_object_focus_set(eina_list_data_get(l), EINA_TRUE); } +static Eina_Bool +_elm_genlist_elm_widget_event_direction(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool multi) +{ + ELM_GENLIST_DATA_GET(obj, sd); + Elm_Object_Item *it = NULL; + Eina_Bool ret = EINA_FALSE; + Evas_Coord v = 0; + Evas_Coord min = 0; + + // get content size and viewport size + eo_do(obj, + elm_interface_scrollable_content_viewport_geometry_get + (NULL, NULL, NULL, &v), + elm_interface_scrollable_content_size_get(NULL, &min)); + + if (multi) + { + if (dir == ELM_FOCUS_UP) + ret = _item_multi_select_up(sd); + else if (dir == ELM_FOCUS_DOWN) + ret = _item_multi_select_down(sd); + } + else + { + if (dir == ELM_FOCUS_UP) + ret = _item_single_select_up(sd); + else if (dir == ELM_FOCUS_DOWN) + ret = _item_single_select_down(sd); + } + if (ret) + return EINA_TRUE; + + // handle item loop feature + if (sd->item_loop_enable) + { + if (min > v) + { + if (dir == ELM_FOCUS_UP) + elm_layout_signal_emit(obj, "elm,action,looping,up", "elm"); + else if (dir == ELM_FOCUS_DOWN) + elm_layout_signal_emit(obj, "elm,action,looping,down", "elm"); + } + else + { + if (dir == ELM_FOCUS_UP) + it = elm_genlist_last_item_get(obj); + else if(dir == ELM_FOCUS_DOWN) + it = elm_genlist_first_item_get(obj); + + if (it) + elm_genlist_item_selected_set(it, EINA_TRUE); + } + return EINA_TRUE; + } + + return EINA_FALSE; +} + static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { @@ -2620,24 +2678,24 @@ _key_action_move(Evas_Object *obj, const char *params) } else if (!strcmp(dir, "up")) { - if (_item_single_select_up(sd)) return EINA_TRUE; + if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE; else return EINA_FALSE; } else if (!strcmp(dir, "up_multi")) { - if (_item_multi_select_up(sd)) return EINA_TRUE; - else if (_item_single_select_up(sd)) return EINA_TRUE; + if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_UP, EINA_TRUE)) return EINA_TRUE; + else if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE; else return EINA_FALSE; } else if (!strcmp(dir, "down")) { - if (_item_single_select_down(sd)) return EINA_TRUE; + if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE; else return EINA_FALSE; } else if (!strcmp(dir, "down_multi")) { - if (_item_multi_select_down(sd)) return EINA_TRUE; - else if (_item_single_select_down(sd)) return EINA_TRUE; + if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_DOWN, EINA_TRUE)) return EINA_TRUE; + else if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE; else return EINA_FALSE; } else if (!strcmp(dir, "first")) @@ -5092,6 +5150,31 @@ _decorate_item_unset(Elm_Genlist_Data *sd) sd->mode_item = NULL; } +static void +_elm_genlist_looping_up_cb(void *data, + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + Evas_Object *genlist = data; + Elm_Object_Item *it = elm_genlist_last_item_get(genlist); + elm_genlist_item_selected_set(it, EINA_TRUE); + elm_layout_signal_emit(genlist, "elm,action,looping,up,end", "elm"); +} + +static void +_elm_genlist_looping_down_cb(void *data, + Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + Evas_Object *genlist = data; + Elm_Object_Item *it = elm_genlist_first_item_get(genlist); + elm_genlist_item_selected_set(it, EINA_TRUE); + elm_layout_signal_emit(genlist, "elm,action,looping,down,end", "elm"); +} + + EOLIAN static void _elm_genlist_evas_smart_add(Eo *obj, Elm_Genlist_Data *priv) { @@ -5169,6 +5252,9 @@ _elm_genlist_evas_smart_add(Eo *obj, Elm_Genlist_Data *priv) _mirrored_set(obj, elm_widget_mirrored_get(obj)); elm_layout_sizing_eval(obj); + + edje_object_signal_callback_add(wd->resize_obj, "elm,looping,up,done", "elm", _elm_genlist_looping_up_cb, obj); + edje_object_signal_callback_add(wd->resize_obj, "elm,looping,down,done", "elm", _elm_genlist_looping_down_cb, obj); } EOLIAN static void @@ -7373,6 +7459,19 @@ _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data * return sd->focused_item; } +EOLIAN static void +_elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enable) +{ + if (sd->item_loop_enable == enable) return; + sd->item_loop_enable = !!enable; +} + +EOLIAN static Eina_Bool +_elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd) +{ + return sd->item_loop_enable; +} + EOLIAN static void _elm_genlist_class_constructor(Eo_Class *klass) { diff --git a/legacy/elementary/src/lib/elm_genlist.eo b/legacy/elementary/src/lib/elm_genlist.eo index 0e9fc8dbfa..0a2d74af31 100644 --- a/legacy/elementary/src/lib/elm_genlist.eo +++ b/legacy/elementary/src/lib/elm_genlist.eo @@ -701,6 +701,8 @@ class Elm_Genlist (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interfac Elm_Widget::sub_object_del; Elm_Widget::event; Elm_Widget::focused_item::get; + Elm_Widget::item_loop_enabled::set; + Elm_Widget::item_loop_enabled::get; Elm_Layout::sub_object_add_enable; Elm_Layout::sizing_eval; Elm_Interface_Scrollable::bounce_allow; diff --git a/legacy/elementary/src/lib/elm_widget_genlist.h b/legacy/elementary/src/lib/elm_widget_genlist.h index 19991c412b..af187b28af 100644 --- a/legacy/elementary/src/lib/elm_widget_genlist.h +++ b/legacy/elementary/src/lib/elm_widget_genlist.h @@ -184,6 +184,8 @@ struct _Elm_Genlist_Data * selection */ Eina_Bool swipe : 1; + /**< value whether item loop feature is enabled or not. */ + Eina_Bool item_loop_enable : 1; }; typedef struct _Item_Block Item_Block;