From 897a0e35a23bed636217e1d2c571614dc6f53a03 Mon Sep 17 00:00:00 2001 From: SangHyeon Lee Date: Thu, 29 Sep 2016 21:02:40 +0900 Subject: [PATCH] genlist: add item focused feature in mobile genlist for focus UI Change-Id: Ifdf09de56651308a0be2e3f5b23e02379a01be82 Signed-off-by: SangHyeon Lee --- src/mobile_lib/elm_genlist.c | 169 +++++++++++++++++++++++------------- src/mobile_lib/elm_genlist.eo | 1 + src/mobile_lib/elm_genlist_item.eo | 5 +- src/mobile_lib/elm_widget_genlist.h | 1 + 4 files changed, 115 insertions(+), 61 deletions(-) diff --git a/src/mobile_lib/elm_genlist.c b/src/mobile_lib/elm_genlist.c index ea09100..b7736a5 100644 --- a/src/mobile_lib/elm_genlist.c +++ b/src/mobile_lib/elm_genlist.c @@ -147,8 +147,8 @@ static const char SIGNAL_REORDER_MODE_SET[] = "elm,state,reorder,mode_set"; static const char SIGNAL_REORDER_MODE_UNSET[] = "elm,state,reorder,mode_unset"; //TIZEN ONLY static const char SIGNAL_DEFAULT[] = "elm,state,default"; -static const char SIGNAL_FOCUSED[] = "elm,action,focus_highlight,show"; -static const char SIGNAL_UNFOCUSED[] = "elm,action,focus_highlight,hide"; +static const char SIGNAL_FOCUSED[] = "elm,state,focused"; +static const char SIGNAL_UNFOCUSED[] = "elm,state,unfocused"; static const char SIGNAL_BG_CHANGE[] = "bg_color_change"; static const char SIGNAL_ITEM_HIGHLIGHTED[] = "elm,state,highlighted"; static const char SIGNAL_ITEM_UNHIGHLIGHTED[] = "elm,state,unhighlighted"; @@ -667,22 +667,6 @@ _changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSE _changed(GL_IT(it)->wsd->pan_obj); } -// FIXME: There are applications which do not use elm_win as top widget. -// This is workaround! Those could not use focus! -static Eina_Bool _focus_enabled(Evas_Object *obj) -{ - if (!elm_widget_focus_get(obj)) return EINA_FALSE; - - const Evas_Object *win = elm_widget_top_get(obj); - const char *type = evas_object_type_get(win); - - if (type && !strcmp(type, "elm_win")) - { - return elm_win_focus_highlight_enabled_get(win); - } - return EINA_FALSE; -} - static Eina_List * _item_content_realize(Elm_Gen_Item *it, Evas_Object *target, @@ -1590,7 +1574,7 @@ _item_realize(Elm_Gen_Item *it, edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm"); } - if (_focus_enabled(WIDGET(it)) && (it == sd->focused_item)) + if (elm_widget_focus_highlight_enabled_get(WIDGET(it)) && (it == sd->focused_item)) { edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm"); } @@ -2555,21 +2539,19 @@ static void _item_unfocused(Elm_Gen_Item *it) static void _item_focused(Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type) { + Evas_Coord x, y, w, h, sx, sy, sw, sh; if (!it) return; Elm_Genlist_Data *sd = GL_IT(it)->wsd; - if (sd->focused_item != it) _item_unfocused(sd->focused_item); - - if (_focus_enabled(sd->obj)) + evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); + evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh); + if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh))) { - Evas_Coord x, y, w, h, sx, sy, sw, sh; - evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); - evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh); - if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh))) - { - elm_genlist_item_bring_in(EO_OBJ(it), type); - } + elm_genlist_item_bring_in(EO_OBJ(it), type); + } + if (elm_widget_focus_highlight_enabled_get(sd->obj)) + { if (it->deco_all_view) edje_object_signal_emit (it->deco_all_view, SIGNAL_FOCUSED, "elm"); @@ -2577,6 +2559,7 @@ static void _item_focused(Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type) edje_object_signal_emit (VIEW(it), SIGNAL_FOCUSED, "elm"); } + sd->focused_item = it; evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, EO_OBJ(it)); if (_elm_atspi_enabled()) @@ -2772,7 +2755,8 @@ _item_select(Elm_Gen_Item *it) } sd->last_selected_item = EO_OBJ(it); _item_highlight(it); - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_IN); + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN) // can be called again eventhough already received it. @@ -2943,7 +2927,7 @@ static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir) { it = ELM_GEN_ITEM_FROM_INLIST (EINA_INLIST_GET(sd->focused_item)->next); - _item_unfocused(sd->focused_item); + elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE); } else it = ELM_GEN_ITEM_FROM_INLIST(sd->items); find_item = _item_focusable_search(&it, 1); @@ -2954,7 +2938,7 @@ static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir) { it = ELM_GEN_ITEM_FROM_INLIST (EINA_INLIST_GET(sd->focused_item)->prev); - _item_unfocused(sd->focused_item); + elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE); } else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); find_item = _item_focusable_search(&it, -1); @@ -2964,21 +2948,24 @@ static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir) { if (old_focused) { - sd->focused_item = old_focused; if (old_content) { sd->focused_content = old_content; elm_object_focus_set(old_content, EINA_TRUE); } else - _item_focused(old_focused, ELM_GENLIST_ITEM_SCROLLTO_IN); + { + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; + elm_object_item_focus_set(EO_OBJ(old_focused), EINA_TRUE); + } } return EINA_FALSE; } else if (!find_item) return EINA_TRUE; - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_IN); + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); } else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT) { @@ -3091,7 +3078,6 @@ _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EI if (!sd->items) return EINA_FALSE; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; if (elm_widget_disabled_get(obj)) return EINA_FALSE; - if (!_focus_enabled(obj)) return EINA_FALSE; eo_do(obj, elm_interface_scrollable_content_pos_get(&x, &y), @@ -3194,7 +3180,7 @@ _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EI } else { - _item_unfocused(sd->focused_item); + elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE); _item_focus_next(sd, FOCUS_DIR_DOWN); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; } @@ -3212,7 +3198,7 @@ _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EI } else { - _item_unfocused(sd->focused_item); + elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE); sd->focused_item = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); _item_focus_next(sd, FOCUS_DIR_UP); } @@ -3237,11 +3223,15 @@ _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EI page_y += GL_IT(it)->minh; } if (_item_focusable_search(&it, -1)) - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_TOP); + { + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); + } else if (!it) { _item_focusable_search(&it, 1); - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_TOP); + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); } ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; @@ -3267,14 +3257,19 @@ _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EI page_y += GL_IT(it)->minh; } if (_item_focusable_search(&it, 1)) - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_TOP); + { + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); + } else if(!it) { _item_focusable_search(&it, -1); - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_TOP); + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); } - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_TOP); + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; @@ -3415,7 +3410,10 @@ _elm_genlist_focus_highlight_show(void *data EINA_UNUSED, Elm_Gen_Item *it = sd->focused_item; found = _item_focusable_search(&it, 1); if (found) - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_IN); + { + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); + } } else elm_object_focus_set(sd->focused_content, EINA_TRUE); } @@ -3479,7 +3477,7 @@ _elm_genlist_elm_widget_focus_highlight_geometry_get(const Eo *obj EINA_UNUSED, } EOLIAN static Eina_Bool -_elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item) +_elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED) { ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); Eina_Bool int_ret = EINA_FALSE; @@ -3517,22 +3515,22 @@ _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item if (sd->select_on_focus_enabled) return EINA_TRUE; if (elm_widget_focus_get(obj)) { - if (_focus_enabled(obj)) + if (sd->focused_item) { - if (sd->focused_item) + if (!sd->focused_content) { - if (!sd->focused_content) + Eina_Bool found = EINA_FALSE; + Elm_Gen_Item *it = sd->focused_item; + found = _item_focusable_search(&it, 1); + if (found) { - Eina_Bool found = EINA_FALSE; - Elm_Gen_Item *it = sd->focused_item; - found = _item_focusable_search(&it, 1); - if (found) - _item_focused(it, ELM_GENLIST_ITEM_SCROLLTO_IN); + sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; + elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); } } - else - _item_focus_next(sd, FOCUS_DIR_DOWN); } + else + _item_focus_next(sd, FOCUS_DIR_DOWN); } else { @@ -3565,6 +3563,61 @@ _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item return EINA_TRUE; } +EOLIAN static void +_elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool focused) +{ + Evas_Object *obj = WIDGET(it); + ELM_GENLIST_DATA_GET(obj, sd); + + if (focused) + { + if (!elm_object_focus_get(obj)) + elm_object_focus_set(obj, EINA_TRUE); + + if (!elm_widget_focus_get(obj)) + return; + + if (it != sd->focused_item) + { + if (sd->focused_item) + _item_unfocused(sd->focused_item); + _item_focused(it, sd->focus_scrollto_type); + + /* If item is not realized state, widget couldn't get focus_highlight data. */ + if (it->realized) + { + _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it)); + _elm_widget_highlight_in_theme_update(obj); + _elm_widget_focus_highlight_start(obj); + } + } + } + else + { + if (!elm_widget_focus_get(obj)) + return; + _item_unfocused(it); + } +} + +EOLIAN static Eina_Bool +_elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it, Elm_Gen_Item *it) +{ + Evas_Object *obj = WIDGET(it); + ELM_GENLIST_DATA_GET(obj, sd); + + if (it == sd->focused_item) + return EINA_TRUE; + + return EINA_FALSE; +} + +EOLIAN static Elm_Object_Item* +_elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd) +{ + return EO_OBJ(sd->focused_item); +} + static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE; EOLIAN static Eina_Bool @@ -5679,7 +5732,7 @@ _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it) Eina_Bool ret; _item_unselect(it); - if (it == GL_IT(it)->wsd->focused_item) _item_unfocused(it); + if (it == GL_IT(it)->wsd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE); if (GL_IT(it)->highlight_timer) { ecore_timer_del(GL_IT(it)->highlight_timer); @@ -5804,7 +5857,7 @@ _item_free(Elm_Gen_Item *it) if (sd->mode_item) sd->mode_item = NULL; if (it->selected) _item_unselect(it); - if (it == sd->focused_item) _item_unfocused(it); + if (it == sd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE); if (it == sd->key_down_item) sd->key_down_item = NULL; if (it == sd->highlighted_item) sd->highlighted_item = NULL; #ifndef TIZEN_PROFILE_WEARABLE @@ -6370,7 +6423,7 @@ elm_genlist_clear(Evas_Object *obj) ELM_GENLIST_DATA_GET(obj, sd); eina_hash_free_buckets(sd->size_caches); - _item_unfocused(sd->focused_item); + elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE); if (sd->key_down_item) sd->key_down_item = NULL; if (sd->mode_item) sd->mode_item = NULL; diff --git a/src/mobile_lib/elm_genlist.eo b/src/mobile_lib/elm_genlist.eo index 61c560a..12a6363 100644 --- a/src/mobile_lib/elm_genlist.eo +++ b/src/mobile_lib/elm_genlist.eo @@ -23,6 +23,7 @@ class Elm.Genlist (Elm.Layout, Elm_Interface_Scrollable, Evas.Clickable_Interfac Elm.Widget.focus_direction_manager_is; Elm.Widget.sub_object_del; Elm.Widget.event; + Elm.Widget.focused_item.get; Elm.Widget.translate; Elm.Layout.sub_object_add_enable; Elm.Layout.sizing_eval; diff --git a/src/mobile_lib/elm_genlist_item.eo b/src/mobile_lib/elm_genlist_item.eo index 94464a7..27c11b4 100644 --- a/src/mobile_lib/elm_genlist_item.eo +++ b/src/mobile_lib/elm_genlist_item.eo @@ -580,9 +580,8 @@ class Elm.Genlist_Item(Elm.Widget_Item) Elm.Widget_Item.del_pre; Elm.Widget_Item.disable; Elm.Widget_Item.signal_emit; - // TIZEN_ONLY(20150402): FIXME: It should be implemented. - //Elm.Widget_Item.focus.set; - //Elm.Widget_Item.focus.get; + Elm.Widget_Item.focus.set; + Elm.Widget_Item.focus.get; Elm.Widget_Item.part_text.get; Elm.Widget_Item.part_content.get; Elm.Widget_Item.tooltip_text_set; diff --git a/src/mobile_lib/elm_widget_genlist.h b/src/mobile_lib/elm_widget_genlist.h index f3035c4..53e2270 100644 --- a/src/mobile_lib/elm_widget_genlist.h +++ b/src/mobile_lib/elm_widget_genlist.h @@ -217,6 +217,7 @@ struct _Elm_Genlist_Data unsigned int filtered_count; Ecore_Idle_Enterer *queue_filter_enterer; Eina_Bool filter; + Elm_Genlist_Item_Scrollto_Type focus_scrollto_type; }; typedef struct _Item_Block Item_Block; -- 2.7.4