From 65feeb1b0bf64dc07413df0043d0aa5a43b1d6c4 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 28 Jun 2017 15:10:14 +0200 Subject: [PATCH 1/6] elm_gengrid: refactor reorder mode Its breaking the logic down into 3 little functions that could be reused later. Overall this reduces the code duplication --- src/lib/elementary/elm_gengrid.c | 122 ++++++++++++++++--------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index edcc031128..7886e8c80f 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -3339,6 +3339,64 @@ _item_horizontal_loop(Evas_Object *obj, Elm_Focus_Direction dir) return EINA_FALSE; } +/* + * transform the focus direction so it can be used for deciding in which direction to go on the internal data structure + * This is respecting the horizontal + */ + +static Elm_Focus_Direction +_direction_transform_horizontal(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) +{ + if (!sd->horizontal) return dir; + + switch(dir){ + case ELM_FOCUS_DOWN: return ELM_FOCUS_RIGHT; + case ELM_FOCUS_UP: return ELM_FOCUS_LEFT; + case ELM_FOCUS_RIGHT: return ELM_FOCUS_DOWN; + case ELM_FOCUS_LEFT: return ELM_FOCUS_UP; + default: break; + } + ERR("unhandled transform case"); + return dir; +} + +static Elm_Object_Item* +_get_neighbor(Elm_Gengrid_Data *sd, Elm_Object_Item *item, Elm_Focus_Direction dir) +{ + Elm_Focus_Direction access_dir = _direction_transform_horizontal(sd, dir); + + switch(access_dir){ + case ELM_FOCUS_DOWN: return get_down_item(sd, item); + case ELM_FOCUS_UP: return get_up_item(sd, item); + case ELM_FOCUS_RIGHT: return elm_gengrid_item_next_get(item); + case ELM_FOCUS_LEFT: return elm_gengrid_item_prev_get(item); + default: break; + } + + return NULL; +} + +static Eina_Bool +_reorder_helper(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) +{ + Elm_Object_Item *neighbor; + + if (_elm_gengrid_item_edge_check(sd->focused_item, dir)) + { + if ((dir == ELM_FOCUS_LEFT || dir == ELM_FOCUS_RIGHT) && sd->item_loop_enable) + return EINA_TRUE; + return EINA_FALSE; + } + + neighbor = _get_neighbor(sd, sd->focused_item, dir); + + if (!neighbor) return EINA_FALSE; + + _swap_items(sd->focused_item, neighbor, dir); + + return EINA_TRUE; +} + static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { @@ -3369,23 +3427,7 @@ _key_action_move(Evas_Object *obj, const char *params) { if (sd->reorder_mode) { - Elm_Object_Item *eo_left; - - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_LEFT)) - { - if (sd->item_loop_enable) - return EINA_TRUE; - return EINA_FALSE; - } - if (!sd->horizontal) - eo_left = elm_gengrid_item_prev_get(sd->focused_item); - else - eo_left = get_up_item(sd, sd->focused_item); - if (!eo_left) - return EINA_TRUE; - _swap_items(sd->focused_item, eo_left, ELM_FOCUS_LEFT); - - return EINA_TRUE; + return _reorder_helper(sd, ELM_FOCUS_LEFT); } else { @@ -3467,23 +3509,7 @@ _key_action_move(Evas_Object *obj, const char *params) { if (sd->reorder_mode) { - Elm_Object_Item *eo_right; - - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_RIGHT)) - { - if (sd->item_loop_enable) - return EINA_TRUE; - return EINA_FALSE; - } - if (!sd->horizontal) - eo_right = elm_gengrid_item_next_get(sd->focused_item); - else - eo_right = get_down_item(sd, sd->focused_item); - if (!eo_right) - return EINA_TRUE; - _swap_items(sd->focused_item, eo_right, ELM_FOCUS_RIGHT); - - return EINA_TRUE; + return _reorder_helper(sd, ELM_FOCUS_RIGHT); } else { @@ -3563,19 +3589,7 @@ _key_action_move(Evas_Object *obj, const char *params) { if (sd->reorder_mode) { - Elm_Object_Item *eo_up; - - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_UP)) - return EINA_FALSE; - if (!sd->horizontal) - eo_up = get_up_item(sd, sd->focused_item); - else - eo_up = elm_gengrid_item_prev_get(sd->focused_item); - if (!eo_up) - return EINA_TRUE; - _swap_items(sd->focused_item, eo_up, ELM_FOCUS_UP); - - return EINA_TRUE; + return _reorder_helper(sd, ELM_FOCUS_UP); } else { @@ -3639,19 +3653,7 @@ _key_action_move(Evas_Object *obj, const char *params) { if (sd->reorder_mode) { - Elm_Object_Item *eo_down; - - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_DOWN)) - return EINA_FALSE; - if (!sd->horizontal) - eo_down = get_down_item(sd, sd->focused_item); - else - eo_down = elm_gengrid_item_next_get(sd->focused_item); - if (!eo_down) - return EINA_TRUE; - _swap_items(sd->focused_item, eo_down, ELM_FOCUS_DOWN); - - return EINA_TRUE; + return _reorder_helper(sd, ELM_FOCUS_DOWN); } else { From 377311cd6608e4c9e7dc65356f2f90246fffe300 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 28 Jun 2017 16:06:10 +0200 Subject: [PATCH 2/6] elm_gengrid: gengrid never sets the focus objects this is always NULL --- src/lib/elementary/elm_gengrid.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index 7886e8c80f..f4d920ee02 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -3432,14 +3432,6 @@ _key_action_move(Evas_Object *obj, const char *params) else { Evas_Object *next = NULL; - Elm_Object_Item *next_item = NULL; - next_item = elm_object_item_focus_next_item_get(sd->focused_item, - ELM_FOCUS_LEFT); - if (next_item) - { - elm_object_item_focus_set(next_item, EINA_TRUE); - return EINA_TRUE; - } next = elm_object_item_focus_next_object_get(sd->focused_item, ELM_FOCUS_LEFT); if (next) @@ -3514,14 +3506,6 @@ _key_action_move(Evas_Object *obj, const char *params) else { Evas_Object *next = NULL; - Elm_Object_Item *next_item = NULL; - next_item = elm_object_item_focus_next_item_get(sd->focused_item, - ELM_FOCUS_RIGHT); - if (next_item) - { - elm_object_item_focus_set(next_item, EINA_TRUE); - return EINA_TRUE; - } next = elm_object_item_focus_next_object_get(sd->focused_item, ELM_FOCUS_RIGHT); if (next) @@ -3594,14 +3578,6 @@ _key_action_move(Evas_Object *obj, const char *params) else { Evas_Object *next = NULL; - Elm_Object_Item *next_item = NULL; - next_item = elm_object_item_focus_next_item_get(sd->focused_item, - ELM_FOCUS_UP); - if (next_item) - { - elm_object_item_focus_set(next_item, EINA_TRUE); - return EINA_TRUE; - } next = elm_object_item_focus_next_object_get(sd->focused_item, ELM_FOCUS_UP); if (next) @@ -3658,14 +3634,6 @@ _key_action_move(Evas_Object *obj, const char *params) else { Evas_Object *next = NULL; - Elm_Object_Item *next_item = NULL; - next_item = elm_object_item_focus_next_item_get(sd->focused_item, - ELM_FOCUS_DOWN); - if (next_item) - { - elm_object_item_focus_set(next_item, EINA_TRUE); - return EINA_TRUE; - } next = elm_object_item_focus_next_object_get(sd->focused_item, ELM_FOCUS_DOWN); if (next) From a7ca960025c9aa6b25b181e4dc3d75c2b7125cd4 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Thu, 29 Jun 2017 13:13:40 +0200 Subject: [PATCH 3/6] elm_gengrid: refactor focus movement This removes duplicated code and brings it into a smaller way more readable function --- src/lib/elementary/elm_gengrid.c | 358 +++++++------------------------ 1 file changed, 81 insertions(+), 277 deletions(-) diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index f4d920ee02..efdfedcb94 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -2330,168 +2330,6 @@ _elm_gengrid_item_unfocused(Elm_Object_Item *eo_it) elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE); } -static Eina_Bool -_item_focus_up(Elm_Gengrid_Data *sd) -{ - unsigned int i; - Elm_Gen_Item *prev = NULL; - - if (!sd->focused_item) - { - prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); - while (prev && - (prev->generation < sd->generation || - elm_object_item_disabled_get(EO_OBJ(prev)))) - prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev); - } - else - { - Elm_Object_Item *eo_prev = elm_gengrid_item_prev_get(sd->focused_item); - if (!eo_prev) return EINA_FALSE; - if (eo_prev == sd->focused_item) return EINA_FALSE; - - eo_prev = sd->focused_item; - while (eo_prev) - { - for (i = 0; i < sd->nmax; i++) - { - eo_prev = elm_gengrid_item_prev_get(eo_prev); - if (!eo_prev) return EINA_FALSE; - } - if (!elm_object_item_disabled_get(eo_prev)) break; - } - - prev = efl_data_scope_get(eo_prev, ELM_GENGRID_ITEM_CLASS); - } - - if (!prev) return EINA_FALSE; - - elm_object_item_focus_set(EO_OBJ(prev), EINA_TRUE); - - return EINA_TRUE; -} - -static Eina_Bool -_item_focus_down(Elm_Gengrid_Data *sd) -{ - unsigned int i, idx; - Elm_Gen_Item *next = NULL; - Elm_Object_Item *eo_next = NULL; - - if (!sd->focused_item) - { - next = ELM_GEN_ITEM_FROM_INLIST(sd->items); - while (next && - (next->generation < sd->generation - || elm_object_item_disabled_get(EO_OBJ(next)))) - next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); - } - else - { - - idx = elm_gengrid_item_index_get(sd->focused_item); - - if (idx > sd->item_count - - ((sd->item_count % sd->nmax) == 0 ? - sd->nmax : (sd->item_count % sd->nmax))) - return EINA_FALSE; - if (idx > sd->item_count - sd->nmax) - { - eo_next = elm_gengrid_last_item_get(sd->obj); - if (elm_object_item_disabled_get(eo_next)) return EINA_FALSE; - } - else - { - eo_next = sd->focused_item; - while (eo_next) - { - for (i = 0; i < sd->nmax; i++) - { - eo_next = elm_gengrid_item_next_get(eo_next); - if (!eo_next) return EINA_FALSE; - } - if (!elm_object_item_disabled_get(eo_next)) break; - } - } - - next = efl_data_scope_get(eo_next, ELM_GENGRID_ITEM_CLASS); - } - - if (!next) return EINA_FALSE; - - elm_object_item_focus_set(EO_OBJ(next), EINA_TRUE); - - return EINA_TRUE; -} - -static Eina_Bool -_item_focus_left(Elm_Gengrid_Data *sd) -{ - Elm_Gen_Item *prev; - - if (!sd->focused_item) - { - prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); - while (((prev) && (prev->generation < sd->generation)) - || elm_object_item_disabled_get(EO_OBJ(prev))) - prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev); - } - else - { - Elm_Object_Item *eo_prev = elm_gengrid_item_prev_get(sd->focused_item); - if (!eo_prev) return EINA_FALSE; - if (eo_prev == sd->focused_item) return EINA_FALSE; - - while (eo_prev) - { - if (!elm_object_item_disabled_get(eo_prev)) break; - eo_prev = elm_gengrid_item_prev_get(eo_prev); - } - - prev = efl_data_scope_get(eo_prev, ELM_GENGRID_ITEM_CLASS); - } - - if (!prev) return EINA_FALSE; - - elm_object_item_focus_set(EO_OBJ(prev), EINA_TRUE); - - return EINA_TRUE; -} - -static Eina_Bool -_item_focus_right(Elm_Gengrid_Data *sd) -{ - Elm_Gen_Item *next; - - if (!sd->focused_item) - { - next = ELM_GEN_ITEM_FROM_INLIST(sd->items); - while (((next) && (next->generation < sd->generation)) - || elm_object_item_disabled_get(EO_OBJ(next))) - next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); - } - else - { - Elm_Object_Item *eo_next = elm_gengrid_item_next_get(sd->focused_item); - if (!eo_next) return EINA_FALSE; - if (eo_next == sd->focused_item) return EINA_FALSE; - - while (eo_next) - { - if (!elm_object_item_disabled_get(eo_next)) break; - eo_next = elm_gengrid_item_next_get(eo_next); - } - - next = efl_data_scope_get(eo_next, ELM_GENGRID_ITEM_CLASS); - } - - if (!next) return EINA_FALSE; - - elm_object_item_focus_set(EO_OBJ(next), EINA_TRUE); - - return EINA_TRUE; -} - static Eina_Bool _item_multi_select_left(Elm_Gengrid_Data *sd) { @@ -3359,7 +3197,19 @@ _direction_transform_horizontal(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) ERR("unhandled transform case"); return dir; } - +static Elm_Focus_Direction +_direction_mirror(Elm_Focus_Direction dir) +{ + switch(dir){ + case ELM_FOCUS_DOWN: return ELM_FOCUS_UP; + case ELM_FOCUS_UP: return ELM_FOCUS_DOWN; + case ELM_FOCUS_RIGHT: return ELM_FOCUS_LEFT; + case ELM_FOCUS_LEFT: return ELM_FOCUS_RIGHT; + default: break; + } + ERR("unhandled transform case"); + return dir; +} static Elm_Object_Item* _get_neighbor(Elm_Gengrid_Data *sd, Elm_Object_Item *item, Elm_Focus_Direction dir) { @@ -3397,6 +3247,70 @@ _reorder_helper(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) return EINA_TRUE; } +static Eina_Bool +_item_focus(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) +{ + Elm_Object_Item *candidate; + + if (!sd->focused_item) + { + Elm_Gen_Item *next; + + if (dir == ELM_FOCUS_RIGHT || dir == ELM_FOCUS_DOWN) + next = ELM_GEN_ITEM_FROM_INLIST(sd->items); + else + next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); + + while (((next) && (next->generation < sd->generation)) + || elm_object_item_disabled_get(EO_OBJ(next))) + { + if (dir == ELM_FOCUS_RIGHT || dir == ELM_FOCUS_DOWN) + next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); + else + next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->prev); + } + candidate = EO_OBJ(next); + } + else + { + candidate = sd->focused_item; + do { + candidate = _get_neighbor(sd, candidate, dir); + if (!candidate) return EINA_FALSE; + if (candidate == sd->focused_item) return EINA_FALSE; + + } while(elm_object_item_disabled_get(candidate)); + } + + elm_object_item_focus_set(candidate, EINA_TRUE); + + return EINA_TRUE; +} + +static Eina_Bool +_focus_move(Evas_Object *obj, Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) +{ + Elm_Focus_Direction access_dir = _direction_transform_horizontal(sd, dir); + if (_elm_gengrid_item_edge_check(sd->focused_item, dir)) + { + if (sd->item_loop_enable && (access_dir == ELM_FOCUS_RIGHT || access_dir == ELM_FOCUS_LEFT)) + { + if (_item_horizontal_loop(obj, _direction_mirror(access_dir))) + return EINA_TRUE; + } + } + + if (!_elm_config->item_select_on_focus_disable) + { + if (access_dir == ELM_FOCUS_UP) _item_single_select_up(sd); + if (access_dir == ELM_FOCUS_DOWN) _item_single_select_down(sd); + if (access_dir == ELM_FOCUS_RIGHT) _item_single_select_right(sd); + if (access_dir == ELM_FOCUS_LEFT) _item_single_select_left(sd); + } + + return _item_focus(sd, dir); +} + static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { @@ -3440,43 +3354,7 @@ _key_action_move(Evas_Object *obj, const char *params) return EINA_TRUE; } } - if (sd->horizontal) - { - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_LEFT)) - { - if (sd->item_loop_enable) - { - if (_item_horizontal_loop(obj, ELM_FOCUS_RIGHT)) - return EINA_TRUE; - } - return EINA_FALSE; - } - if (!_elm_config->item_select_on_focus_disable) - { - return _item_single_select_up(sd); - } - else - return _item_focus_up(sd); - } - else - { - if (sd->focused_item && (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_LEFT) || - !elm_gengrid_item_prev_get(sd->focused_item))) - { - if (sd->item_loop_enable) - { - if (_item_horizontal_loop(obj, ELM_FOCUS_RIGHT)) - return EINA_TRUE; - } - return EINA_FALSE; - } - if (!_elm_config->item_select_on_focus_disable) - { - return _item_single_select_left(sd); - } - else - return _item_focus_left(sd); - } + return _focus_move(obj, sd, ELM_FOCUS_LEFT); } else if ((!strcmp(dir, "left_multi") && !mirrored) || (!strcmp(dir, "right_multi") && mirrored)) @@ -3514,42 +3392,7 @@ _key_action_move(Evas_Object *obj, const char *params) return EINA_TRUE; } } - if (sd->horizontal) - { - if (sd->focused_item && _elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_RIGHT)) - { - if (sd->item_loop_enable) - { - if (_item_horizontal_loop(obj, ELM_FOCUS_UP)) - return EINA_TRUE; - } - } - if (!_elm_config->item_select_on_focus_disable) - { - return _item_single_select_down(sd); - } - else - return _item_focus_down(sd); - } - else - { - if (sd->focused_item && (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_RIGHT) || - !elm_gengrid_item_next_get(sd->focused_item))) - { - if (sd->item_loop_enable) - { - if (_item_horizontal_loop(obj, ELM_FOCUS_LEFT)) - return EINA_TRUE; - } - return EINA_FALSE; - } - if (!_elm_config->item_select_on_focus_disable) - { - return _item_single_select_right(sd); - } - else - return _item_focus_right(sd); - } + return _focus_move(obj, sd, ELM_FOCUS_RIGHT); } else if ((!strcmp(dir, "right_multi") && !mirrored) || (!strcmp(dir, "left_multi") && mirrored)) @@ -3586,27 +3429,7 @@ _key_action_move(Evas_Object *obj, const char *params) return EINA_TRUE; } } - if (sd->horizontal) - { - if (sd->focused_item && _elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_UP)) - return EINA_FALSE; - if (!_elm_config->item_select_on_focus_disable) - { - if (_item_single_select_left(sd)) return EINA_TRUE; - else return EINA_FALSE; - } - else - return _item_focus_left(sd); - } - else - { - if (!_elm_config->item_select_on_focus_disable) - { - return _item_single_select_up(sd); - } - else - return _item_focus_up(sd); - } + return _focus_move(obj, sd, ELM_FOCUS_UP); } else if (!strcmp(dir, "up_multi")) { @@ -3642,26 +3465,7 @@ _key_action_move(Evas_Object *obj, const char *params) return EINA_TRUE; } } - if (sd->horizontal) - { - if (sd->focused_item && _elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_DOWN)) - return EINA_FALSE; - if (!_elm_config->item_select_on_focus_disable) - { - return _item_single_select_right(sd); - } - else - return _item_focus_right(sd); - } - else - { - if (!_elm_config->item_select_on_focus_disable) - { - return _item_single_select_down(sd); - } - else - return _item_focus_down(sd); - } + return _focus_move(obj, sd, ELM_FOCUS_DOWN); } else if (!strcmp(dir, "down_multi")) { From 31c11925eb5c4a7f79739a1521e222df95abda24 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Thu, 29 Jun 2017 15:37:34 +0200 Subject: [PATCH 4/6] elm_gengrid: refactor single selection move --- src/lib/elementary/elm_gengrid.c | 219 ++++++++----------------------- 1 file changed, 52 insertions(+), 167 deletions(-) diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index efdfedcb94..a4f60752c2 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -2424,145 +2424,6 @@ _all_items_deselect(Elm_Gengrid_Data *sd) return EINA_TRUE; } -static Eina_Bool -_item_single_select_up(Elm_Gengrid_Data *sd) -{ - unsigned int i; - Elm_Object_Item *eo_prev; - - if (!sd->selected) - eo_prev = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items->last)); - else - eo_prev = sd->last_selected_item; - - while (eo_prev) - { - for (i = 0; i < sd->nmax; i++) - { - eo_prev = elm_gengrid_item_prev_get(eo_prev); - if (!eo_prev) return EINA_FALSE; - } - - if (!elm_object_item_disabled_get(eo_prev)) break; - } - - if (!eo_prev) return EINA_FALSE; - - _all_items_deselect(sd); - elm_gengrid_item_selected_set(eo_prev, EINA_TRUE); - - return EINA_TRUE; -} - -static Eina_Bool -_item_single_select_down(Elm_Gengrid_Data *sd) -{ - unsigned int i; - unsigned int idx; - Elm_Object_Item *eo_next, *eo_orig; - - if (!sd->selected) - eo_next = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items)); - else - eo_next = sd->last_selected_item; - eo_orig = eo_next; - - while (eo_next) - { - for (i = 0; i < sd->nmax; i++) - { - eo_next = elm_gengrid_item_next_get(eo_next); - if (!eo_next) break; - } - - if (eo_next && !elm_object_item_disabled_get(eo_next)) break; - } - - if (!eo_next) - { - idx = elm_gengrid_item_index_get(eo_orig); - if (idx > sd->item_count - - ((sd->item_count % sd->nmax) == 0 ? - sd->nmax : (sd->item_count % sd->nmax))) - return EINA_FALSE; - else - eo_next = elm_gengrid_last_item_get(sd->obj); - } - - _all_items_deselect(sd); - elm_gengrid_item_selected_set(eo_next, EINA_TRUE); - - return EINA_TRUE; -} - -static Eina_Bool -_item_single_select_left(Elm_Gengrid_Data *sd) -{ - Elm_Gen_Item *prev; - - if (!sd->selected) - { - prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); - while (((prev) && (prev->generation < sd->generation)) - || elm_object_item_disabled_get(EO_OBJ(prev))) - prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev); - } - else - { - Elm_Object_Item *eo_prev = - elm_gengrid_item_prev_get(sd->last_selected_item); - while (eo_prev) - { - if (!elm_object_item_disabled_get(eo_prev)) - break; - eo_prev = elm_gengrid_item_prev_get(eo_prev); - } - prev = efl_data_scope_get(eo_prev, ELM_GENGRID_ITEM_CLASS); - } - - if (!prev) return EINA_FALSE; - - _all_items_deselect(sd); - - elm_gengrid_item_selected_set(EO_OBJ(prev), EINA_TRUE); - - return EINA_TRUE; -} - -static Eina_Bool -_item_single_select_right(Elm_Gengrid_Data *sd) -{ - Elm_Gen_Item *next; - - if (!sd->selected) - { - next = ELM_GEN_ITEM_FROM_INLIST(sd->items); - while (((next) && (next->generation < sd->generation)) - || elm_object_item_disabled_get(EO_OBJ(next))) - next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); - } - else - { - Elm_Object_Item *eo_next = - elm_gengrid_item_next_get(sd->last_selected_item); - while (eo_next) - { - if (!elm_object_item_disabled_get(eo_next)) - break; - eo_next = elm_gengrid_item_next_get(eo_next); - } - next = efl_data_scope_get(eo_next, ELM_GENGRID_ITEM_CLASS); - } - - if (!next) return EINA_FALSE; - - _all_items_deselect(sd); - - elm_gengrid_item_selected_set(EO_OBJ(next), EINA_TRUE); - - return EINA_TRUE; -} - static Eina_Bool _elm_gengrid_item_edge_check(Elm_Object_Item *eo_it, Elm_Focus_Direction dir) @@ -3247,6 +3108,28 @@ _reorder_helper(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) return EINA_TRUE; } +static Elm_Object_Item* +_pick_item(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) +{ + Elm_Gen_Item *next; + + if (dir == ELM_FOCUS_RIGHT || dir == ELM_FOCUS_DOWN) + next = ELM_GEN_ITEM_FROM_INLIST(sd->items); + else + next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); + + while (((next) && (next->generation < sd->generation)) + || elm_object_item_disabled_get(EO_OBJ(next))) + { + if (dir == ELM_FOCUS_RIGHT || dir == ELM_FOCUS_DOWN) + next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); + else + next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->prev); + } + + return EO_OBJ(next); +} + static Eina_Bool _item_focus(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) { @@ -3254,22 +3137,7 @@ _item_focus(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) if (!sd->focused_item) { - Elm_Gen_Item *next; - - if (dir == ELM_FOCUS_RIGHT || dir == ELM_FOCUS_DOWN) - next = ELM_GEN_ITEM_FROM_INLIST(sd->items); - else - next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); - - while (((next) && (next->generation < sd->generation)) - || elm_object_item_disabled_get(EO_OBJ(next))) - { - if (dir == ELM_FOCUS_RIGHT || dir == ELM_FOCUS_DOWN) - next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); - else - next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->prev); - } - candidate = EO_OBJ(next); + candidate = _pick_item(sd, dir); } else { @@ -3287,6 +3155,26 @@ _item_focus(Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) return EINA_TRUE; } +static Eina_Bool +_selection_single_move(Evas_Object *obj EINA_UNUSED, Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) +{ + Elm_Object_Item *candidate; + + if (!sd->selected) + candidate = _pick_item(sd, dir); + else + candidate = sd->last_selected_item; + + if (!candidate) return EINA_FALSE; + + candidate = _get_neighbor(sd, candidate, dir); + + _all_items_deselect(sd); + elm_gengrid_item_selected_set(candidate, EINA_TRUE); + + return EINA_TRUE; +} + static Eina_Bool _focus_move(Evas_Object *obj, Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) { @@ -3302,10 +3190,7 @@ _focus_move(Evas_Object *obj, Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) if (!_elm_config->item_select_on_focus_disable) { - if (access_dir == ELM_FOCUS_UP) _item_single_select_up(sd); - if (access_dir == ELM_FOCUS_DOWN) _item_single_select_down(sd); - if (access_dir == ELM_FOCUS_RIGHT) _item_single_select_right(sd); - if (access_dir == ELM_FOCUS_LEFT) _item_single_select_left(sd); + _selection_single_move(obj, sd, access_dir); } return _item_focus(sd, dir); @@ -3362,7 +3247,7 @@ _key_action_move(Evas_Object *obj, const char *params) if (sd->horizontal) { if (_item_multi_select_up(sd)) return EINA_TRUE; - else if (_item_single_select_up(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_UP)) return EINA_TRUE; else return EINA_FALSE; } else @@ -3370,7 +3255,7 @@ _key_action_move(Evas_Object *obj, const char *params) if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_LEFT)) return EINA_FALSE; if (_item_multi_select_left(sd)) return EINA_TRUE; - else if (_item_single_select_left(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_LEFT)) return EINA_TRUE; else return EINA_FALSE; } } @@ -3400,7 +3285,7 @@ _key_action_move(Evas_Object *obj, const char *params) if (sd->horizontal) { if (_item_multi_select_down(sd)) return EINA_TRUE; - else if (_item_single_select_down(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_DOWN)) return EINA_TRUE; else return EINA_FALSE; } else @@ -3408,7 +3293,7 @@ _key_action_move(Evas_Object *obj, const char *params) if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_RIGHT)) return EINA_FALSE; if (_item_multi_select_right(sd)) return EINA_TRUE; - else if (_item_single_select_right(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_RIGHT)) return EINA_TRUE; else return EINA_FALSE; } } @@ -3438,13 +3323,13 @@ _key_action_move(Evas_Object *obj, const char *params) if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_UP)) return EINA_FALSE; if (_item_multi_select_left(sd)) return EINA_TRUE; - else if (_item_single_select_left(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_LEFT)) return EINA_TRUE; else return EINA_FALSE; } else { if (_item_multi_select_up(sd)) return EINA_TRUE; - else if (_item_single_select_up(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_UP)) return EINA_TRUE; else return EINA_FALSE; } } @@ -3474,13 +3359,13 @@ _key_action_move(Evas_Object *obj, const char *params) if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_DOWN)) return EINA_FALSE; if (_item_multi_select_right(sd)) return EINA_TRUE; - else if (_item_single_select_right(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_RIGHT)) return EINA_TRUE; else return EINA_FALSE; } else { if (_item_multi_select_down(sd)) return EINA_TRUE; - else if (_item_single_select_down(sd)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, ELM_FOCUS_DOWN)) return EINA_TRUE; else return EINA_FALSE; } } From f046394d0fdc747db4c1f657bb193cfd2cd5c9e5 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Thu, 29 Jun 2017 18:29:24 +0200 Subject: [PATCH 5/6] elm_gengrid: refactor duplicated code this brings the simple selection move into a single spot --- src/lib/elementary/elm_gengrid.c | 84 +++++++++----------------------- 1 file changed, 22 insertions(+), 62 deletions(-) diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index a4f60752c2..bf728291a3 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -3196,6 +3196,17 @@ _focus_move(Evas_Object *obj, Elm_Gengrid_Data *sd, Elm_Focus_Direction dir) return _item_focus(sd, dir); } +static Eina_Bool +_get_direction(const char *str, Elm_Focus_Direction *dir) +{ + if (!strcmp(str, "left")) *dir = ELM_FOCUS_LEFT; + else if (!strcmp(str, "right")) *dir = ELM_FOCUS_RIGHT; + else if (!strcmp(str, "up")) *dir = ELM_FOCUS_UP; + else if (!strcmp(str, "down")) *dir = ELM_FOCUS_DOWN; + else return EINA_FALSE; + return EINA_TRUE; +} + static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { @@ -3212,6 +3223,7 @@ _key_action_move(Evas_Object *obj, const char *params) Evas_Coord page_y = 0; Elm_Object_Item *it = NULL; Eina_Bool mirrored = efl_ui_mirrored_get(obj); + Elm_Focus_Direction direction; elm_interface_scrollable_content_pos_get(obj, &x, &y); elm_interface_scrollable_step_size_get(obj, &step_x, &step_y); @@ -3221,12 +3233,17 @@ _key_action_move(Evas_Object *obj, const char *params) if (sd->reorder_mode && sd->reorder.running) return EINA_TRUE; _elm_widget_focus_auto_show(obj); - if ((!strcmp(dir, "left") && !mirrored) || - (!strcmp(dir, "right") && mirrored)) + + if (_get_direction(dir, &direction)) { + if (mirrored) + { + if (direction == ELM_FOCUS_RIGHT || direction == ELM_FOCUS_LEFT) + direction = _direction_mirror(direction); + } if (sd->reorder_mode) { - return _reorder_helper(sd, ELM_FOCUS_LEFT); + return _reorder_helper(sd, direction); } else { @@ -3239,7 +3256,8 @@ _key_action_move(Evas_Object *obj, const char *params) return EINA_TRUE; } } - return _focus_move(obj, sd, ELM_FOCUS_LEFT); + return _focus_move(obj, sd, direction); + } else if ((!strcmp(dir, "left_multi") && !mirrored) || (!strcmp(dir, "right_multi") && mirrored)) @@ -3259,26 +3277,6 @@ _key_action_move(Evas_Object *obj, const char *params) else return EINA_FALSE; } } - else if ((!strcmp(dir, "right") && !mirrored) || - (!strcmp(dir, "left") && mirrored)) - { - if (sd->reorder_mode) - { - return _reorder_helper(sd, ELM_FOCUS_RIGHT); - } - else - { - Evas_Object *next = NULL; - next = elm_object_item_focus_next_object_get(sd->focused_item, - ELM_FOCUS_RIGHT); - if (next) - { - elm_object_focus_set(next, EINA_TRUE); - return EINA_TRUE; - } - } - return _focus_move(obj, sd, ELM_FOCUS_RIGHT); - } else if ((!strcmp(dir, "right_multi") && !mirrored) || (!strcmp(dir, "left_multi") && mirrored)) { @@ -3297,25 +3295,6 @@ _key_action_move(Evas_Object *obj, const char *params) else return EINA_FALSE; } } - else if (!strcmp(dir, "up")) - { - if (sd->reorder_mode) - { - return _reorder_helper(sd, ELM_FOCUS_UP); - } - else - { - Evas_Object *next = NULL; - next = elm_object_item_focus_next_object_get(sd->focused_item, - ELM_FOCUS_UP); - if (next) - { - elm_object_focus_set(next, EINA_TRUE); - return EINA_TRUE; - } - } - return _focus_move(obj, sd, ELM_FOCUS_UP); - } else if (!strcmp(dir, "up_multi")) { if (sd->horizontal) @@ -3333,25 +3312,6 @@ _key_action_move(Evas_Object *obj, const char *params) else return EINA_FALSE; } } - else if (!strcmp(dir, "down")) - { - if (sd->reorder_mode) - { - return _reorder_helper(sd, ELM_FOCUS_DOWN); - } - else - { - Evas_Object *next = NULL; - next = elm_object_item_focus_next_object_get(sd->focused_item, - ELM_FOCUS_DOWN); - if (next) - { - elm_object_focus_set(next, EINA_TRUE); - return EINA_TRUE; - } - } - return _focus_move(obj, sd, ELM_FOCUS_DOWN); - } else if (!strcmp(dir, "down_multi")) { if (sd->horizontal) From 9600542547cf9f650a146a1da324fb2235202e69 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Thu, 29 Jun 2017 18:41:06 +0200 Subject: [PATCH 6/6] elm_gengrid: remove duplicated code --- src/lib/elementary/elm_gengrid.c | 93 +++++++++++--------------------- 1 file changed, 30 insertions(+), 63 deletions(-) diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index bf728291a3..53237a19a2 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -3207,6 +3207,27 @@ _get_direction(const char *str, Elm_Focus_Direction *dir) return EINA_TRUE; } +static Eina_Bool +_get_multi_direction(const char *str, Elm_Focus_Direction *dir) +{ + if (!strcmp(str, "left_multi")) *dir = ELM_FOCUS_LEFT; + else if (!strcmp(str, "right_multi")) *dir = ELM_FOCUS_RIGHT; + else if (!strcmp(str, "up_multi")) *dir = ELM_FOCUS_UP; + else if (!strcmp(str, "down_multi")) *dir = ELM_FOCUS_DOWN; + else return EINA_FALSE; + return EINA_TRUE; +} + +static Eina_Bool +_item_multi_select(Elm_Gengrid_Data *sd, Elm_Focus_Direction direction) +{ + if (direction == ELM_FOCUS_UP) return _item_multi_select_up(sd); + else if (direction == ELM_FOCUS_DOWN) return _item_multi_select_down(sd); + else if (direction == ELM_FOCUS_RIGHT) return _item_multi_select_right(sd); + else if (direction == ELM_FOCUS_LEFT) return _item_multi_select_left(sd); + return EINA_FALSE; +} + static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { @@ -3259,75 +3280,21 @@ _key_action_move(Evas_Object *obj, const char *params) return _focus_move(obj, sd, direction); } - else if ((!strcmp(dir, "left_multi") && !mirrored) || - (!strcmp(dir, "right_multi") && mirrored)) + else if (_get_multi_direction(dir, &direction)) { - if (sd->horizontal) + if (mirrored) { - if (_item_multi_select_up(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_UP)) return EINA_TRUE; - else return EINA_FALSE; + if (direction == ELM_FOCUS_RIGHT || direction == ELM_FOCUS_LEFT) + direction = _direction_mirror(direction); } - else + if (direction == ELM_FOCUS_LEFT || direction == ELM_FOCUS_RIGHT) { - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_LEFT)) + if (_elm_gengrid_item_edge_check(sd->focused_item, direction)) return EINA_FALSE; - if (_item_multi_select_left(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_LEFT)) return EINA_TRUE; - else return EINA_FALSE; - } - } - else if ((!strcmp(dir, "right_multi") && !mirrored) || - (!strcmp(dir, "left_multi") && mirrored)) - { - if (sd->horizontal) - { - if (_item_multi_select_down(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_DOWN)) return EINA_TRUE; - else return EINA_FALSE; - } - else - { - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_RIGHT)) - return EINA_FALSE; - if (_item_multi_select_right(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_RIGHT)) return EINA_TRUE; - else return EINA_FALSE; - } - } - else if (!strcmp(dir, "up_multi")) - { - if (sd->horizontal) - { - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_UP)) - return EINA_FALSE; - if (_item_multi_select_left(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_LEFT)) return EINA_TRUE; - else return EINA_FALSE; - } - else - { - if (_item_multi_select_up(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_UP)) return EINA_TRUE; - else return EINA_FALSE; - } - } - else if (!strcmp(dir, "down_multi")) - { - if (sd->horizontal) - { - if (_elm_gengrid_item_edge_check(sd->focused_item, ELM_FOCUS_DOWN)) - return EINA_FALSE; - if (_item_multi_select_right(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_RIGHT)) return EINA_TRUE; - else return EINA_FALSE; - } - else - { - if (_item_multi_select_down(sd)) return EINA_TRUE; - else if (_selection_single_move(obj, sd, ELM_FOCUS_DOWN)) return EINA_TRUE; - else return EINA_FALSE; } + if (_item_multi_select(sd, direction)) return EINA_TRUE; + else if (_selection_single_move(obj, sd, direction)) return EINA_TRUE; + else return EINA_FALSE; } else if (!strcmp(dir, "first")) {