From 32cedce2bd383035ad5de952b180332b7413a7b3 Mon Sep 17 00:00:00 2001 From: Tae-Hwan Kim Date: Sun, 14 Apr 2013 22:07:32 +0900 Subject: [PATCH] [Genlist/list] Add focused UI implementation For key down/up/home/end Change-Id: I5f4b78a13f60128f8b608cff967efd5cf075456f --- src/lib/elm_genlist.c | 420 +++++++++++++++++++++++++++---------------- src/lib/elm_list.c | 133 ++++++++++++-- src/lib/elm_widget_genlist.h | 1 + src/lib/elm_widget_list.h | 1 + 4 files changed, 384 insertions(+), 171 deletions(-) diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c index 7306458..1688d85 100644 --- a/src/lib/elm_genlist.c +++ b/src/lib/elm_genlist.c @@ -78,6 +78,8 @@ static const char SIG_UNHIGHLIGHTED[] = "unhighlighted"; static const char SIG_LANG_CHANGED[] = "language,changed"; static const char SIG_PRESSED[] = "pressed"; static const char SIG_RELEASED[] = "released"; +static const char SIG_FOCUSED[] = "item,focused"; +static const char SIG_UNFOCUSED[] = "item,unfocused"; static const Evas_Smart_Cb_Description _smart_callbacks[] = { {SIG_CLICKED_DOUBLE, ""}, @@ -2363,7 +2365,7 @@ _item_single_select_down(Elm_Genlist_Smart_Data *sd) } else next = (Elm_Gen_Item *)elm_genlist_item_next_get - (sd->last_selected_item); + (sd->last_selected_item); if (!next) return EINA_FALSE; @@ -2376,6 +2378,214 @@ _item_single_select_down(Elm_Genlist_Smart_Data *sd) return EINA_TRUE; } +static void +_item_highlight(Elm_Gen_Item *it) +{ + const char *selectraise; + Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; + + if (elm_widget_item_disabled_get(it)) return; + if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || + (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) || + (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || + (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY )) + return; + + if (!sd->highlight || it->highlighted) return; +#if GENLIST_PINCH_ZOOM_SUPPORT + if (sd->pinch_zoom_mode) return; +#endif + + selectraise = edje_object_data_get(VIEW(it), "selectraise"); + if ((selectraise) && (!strcmp(selectraise, "on"))) + { + if (it->deco_all_view) evas_object_raise(it->deco_all_view); + else evas_object_raise(VIEW(it)); + if ((it->item->group_item) && (it->item->group_item->realized)) + evas_object_raise(it->item->VIEW(group_item)); + } + it->highlighted = EINA_TRUE; + + if (it->deco_all_view) + edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm"); + edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); + evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it); +} + +static void +_item_unhighlight(Elm_Gen_Item *it) +{ + if (!it->highlighted) return; + + if (!it->item->nostacking) + { + if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) + { + if (it->deco_all_view) evas_object_lower(it->deco_all_view); + else evas_object_lower(VIEW(it)); + } + else + { + if (it->deco_all_view) evas_object_raise(it->deco_all_view); + else evas_object_raise(VIEW(it)); + } + } + it->highlighted = EINA_FALSE; + + if (it->deco_all_view) + edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm"); + edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm"); + evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it); +} + +static void +_item_unselect(Elm_Gen_Item *it) +{ + Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; + _item_unhighlight(it); + if (!it->selected) return; + + it->selected = EINA_FALSE; + sd->selected = eina_list_remove(sd->selected, it); + evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it); +} + +static void +_item_select(Elm_Gen_Item *it) +{ + Evas_Object *obj = WIDGET(it); + Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; + if (elm_widget_item_disabled_get(it)) return; + if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || + (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) || + (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || + (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)) + return; + +#if GENLIST_PINCH_ZOOM_SUPPORT + if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)) + { + elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND); + elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP); + return; + } +#endif + +#if 0 + // FIXME: difference from upstream + if ((GL_IT(it)->wsd->last_selected_item) && + (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item)) + _item_unfocusable_set + ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE); +#endif + + // Do not check selected because always select mode can be used + _item_highlight(it); + it->selected = EINA_TRUE; + sd->selected = eina_list_append(sd->selected, it); + sd->last_selected_item = (Elm_Object_Item *)it; + + if (it->func.func) it->func.func((void *)it->func.data, obj, it); + if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC)) + return; + evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it); +} + +static void +_item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected) +{ + Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; + Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj; + if (elm_widget_item_disabled_get(it)) return; + + evas_object_ref(obj); + if (!sd->multi) + { + const Eina_List *l, *ll; + Elm_Gen_Item *it2; + EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2) + if (it2 != it) _item_unselect(it2); + } + if (selected) _item_select(it); + else _item_unselect(it); + evas_object_unref(obj); +} + +static void _item_focused(Elm_Gen_Item *it) +{ + if (!it) return; + Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; + Evas_Coord x, y, w, h, sx, sy, sw, sh; + + evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); + evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh); + if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh))) + { + elm_genlist_item_bring_in((Elm_Object_Item *)it, + ELM_GENLIST_ITEM_SCROLLTO_IN); + } + + edje_object_signal_emit + (VIEW(it), "elm,state,focused", "elm"); + if (it->deco_all_view) + edje_object_signal_emit + (it->deco_all_view, "elm,state,focused", "elm"); + + sd->focused = it; +} + +static void _item_unfocused(Elm_Gen_Item *it) +{ + if (!it) return; + Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; + edje_object_signal_emit + (VIEW(sd->focused), "elm,state,unfocused", "elm"); + if (sd->focused->deco_all_view) + edje_object_signal_emit + (sd->focused->deco_all_view, "elm,state,unfocused", "elm"); + if (it == sd->focused) + sd->focused = NULL; +} + +static Elm_Gen_Item *_item_focused_search(Elm_Gen_Item *it, int dir) +{ + if (!it) return NULL; + Elm_Gen_Item *tmp = it; + if (dir == 1) + { + tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next); + } + else + { + tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev); + } + if (!tmp) tmp = it; + return tmp; +} + +static void _item_focused_next(Elm_Genlist_Smart_Data *sd, int dir) +{ + Elm_Gen_Item *it; + if (elm_widget_focus_get(ELM_WIDGET_DATA(sd)->obj)) + edje_object_signal_emit + (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm"); + + if (!sd->focused) + { + if (dir == 1) + it = ELM_GEN_ITEM_FROM_INLIST(sd->items); + else + it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); + } + else + { + it = sd->focused; + _item_unfocused(sd->focused); + it = _item_focused_search(it, dir); + } + _item_focused(it); +} + static Eina_Bool _elm_genlist_smart_event(Evas_Object *obj, Evas_Object *src __UNUSED__, @@ -2390,7 +2600,6 @@ _elm_genlist_smart_event(Evas_Object *obj, Evas_Coord step_y = 0; Evas_Coord page_x = 0; Evas_Coord page_y = 0; - Elm_Object_Item *it; Evas_Event_Key_Down *ev = event_info; Evas_Coord pan_max_x = 0, pan_max_y = 0; @@ -2420,43 +2629,48 @@ _elm_genlist_smart_event(Evas_Object *obj, ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string))) { if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && - (_item_multi_select_up(sd))) - || (_item_single_select_up(sd))) + (_item_multi_select_up(sd)))) { ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else - y -= step_y; + { + _item_focused_next(sd, -1); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } } else if ((!strcmp(ev->keyname, "Down")) || ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string))) { if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && - (_item_multi_select_down(sd))) - || (_item_single_select_down(sd))) + (_item_multi_select_down(sd)))) { ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else - y += step_y; + { + _item_focused_next(sd, 1); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } } else if ((!strcmp(ev->keyname, "Home")) || ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string))) { - it = elm_genlist_first_item_get(obj); - elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN); - elm_genlist_item_selected_set(it, EINA_TRUE); + _item_unfocused(sd->focused); + _item_focused_next(sd, 1); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else if ((!strcmp(ev->keyname, "End")) || ((!strcmp(ev->keyname, "KP_End")) && (!ev->string))) { - it = elm_genlist_last_item_get(obj); - elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN); - elm_genlist_item_selected_set(it, EINA_TRUE); + _item_unfocused(sd->focused); + sd->focused = ELM_GEN_ITEM_FROM_INLIST(sd->items->last); + _item_focused_next(sd, -1); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } @@ -2482,14 +2696,16 @@ _elm_genlist_smart_event(Evas_Object *obj, ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } - else if (((!strcmp(ev->keyname, "Return")) || - (!strcmp(ev->keyname, "KP_Enter")) || - (!strcmp(ev->keyname, "space"))) - && (!sd->multi) && (sd->selected)) + else if (!strcmp(ev->keyname, "Return") || + !strcmp(ev->keyname, "KP_Enter") || + !strcmp(ev->keyname, "space")) { - it = elm_genlist_selected_item_get(obj); - elm_genlist_item_expanded_set(it, !elm_genlist_item_expanded_get(it)); - evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); + if (sd->focused) + { + Elm_Gen_Item *it = sd->focused; + _item_select_unselect(it, EINA_TRUE); + evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); + } } else return EINA_FALSE; @@ -2551,6 +2767,7 @@ _elm_genlist_smart_on_focus(Evas_Object *obj) { ELM_GENLIST_DATA_GET(obj, sd); + // Why does parent do first? if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->on_focus(obj)) return EINA_FALSE; @@ -2558,6 +2775,32 @@ _elm_genlist_smart_on_focus(Evas_Object *obj) (!sd->last_selected_item)) sd->last_selected_item = eina_list_data_get(sd->selected); + if (elm_widget_focus_get(obj)) + { + if (sd->focused) + { + edje_object_signal_emit + (VIEW(sd->focused), "elm,state,focused", "elm"); + if (sd->focused->deco_all_view) + edje_object_signal_emit + (sd->focused->deco_all_view, "elm,state,focused", "elm"); + } + else + edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,focused", "elm"); + } + else + { + if (sd->focused) + { + edje_object_signal_emit + (VIEW(sd->focused), "elm,state,unfocused", "elm"); + if (sd->focused->deco_all_view) + edje_object_signal_emit + (sd->focused->deco_all_view, "elm,state,unfocused", "elm"); + } + else + edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm"); + } return EINA_TRUE; } @@ -2692,139 +2935,6 @@ _elm_genlist_smart_translate(Evas_Object *obj) } static void -_item_highlight(Elm_Gen_Item *it) -{ - const char *selectraise; - Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; - - if (elm_widget_item_disabled_get(it)) return; - if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || - (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) || - (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || - (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY )) - return; - - if (!sd->highlight || it->highlighted) return; -#if GENLIST_PINCH_ZOOM_SUPPORT - if (sd->pinch_zoom_mode) return; -#endif - - selectraise = edje_object_data_get(VIEW(it), "selectraise"); - if ((selectraise) && (!strcmp(selectraise, "on"))) - { - if (it->deco_all_view) evas_object_raise(it->deco_all_view); - else evas_object_raise(VIEW(it)); - if ((it->item->group_item) && (it->item->group_item->realized)) - evas_object_raise(it->item->VIEW(group_item)); - } - it->highlighted = EINA_TRUE; - - if (it->deco_all_view) - edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm"); - edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); - evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it); -} - -static void -_item_unhighlight(Elm_Gen_Item *it) -{ - if (!it->highlighted) return; - - if (!it->item->nostacking) - { - if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) - { - if (it->deco_all_view) evas_object_lower(it->deco_all_view); - else evas_object_lower(VIEW(it)); - } - else - { - if (it->deco_all_view) evas_object_raise(it->deco_all_view); - else evas_object_raise(VIEW(it)); - } - } - it->highlighted = EINA_FALSE; - - if (it->deco_all_view) - edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm"); - edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm"); - evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it); -} - -static void -_item_unselect(Elm_Gen_Item *it) -{ - Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; - _item_unhighlight(it); - if (!it->selected) return; - - it->selected = EINA_FALSE; - sd->selected = eina_list_remove(sd->selected, it); - evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it); -} - -static void -_item_select(Elm_Gen_Item *it) -{ - Evas_Object *obj = WIDGET(it); - Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; - if (elm_widget_item_disabled_get(it)) return; - if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || - (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) || - (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || - (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)) - return; - -#if GENLIST_PINCH_ZOOM_SUPPORT - if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT)) - { - elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND); - elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP); - return; - } -#endif - -#if 0 - // FIXME: difference from upstream - if ((GL_IT(it)->wsd->last_selected_item) && - (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item)) - _item_unfocusable_set - ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE); -#endif - - // Do not check selected because always select mode can be used - _item_highlight(it); - it->selected = EINA_TRUE; - sd->selected = eina_list_append(sd->selected, it); - sd->last_selected_item = (Elm_Object_Item *)it; - - if (it->func.func) it->func.func((void *)it->func.data, obj, it); - if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC)) - return; - evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it); -} - -static void -_item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected) -{ - Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd; - Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj; - if (elm_widget_item_disabled_get(it)) return; - - evas_object_ref(obj); - if (!sd->multi) - { - const Eina_List *l, *ll; - Elm_Gen_Item *it2; - EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2) - if (it2 != it) _item_unselect(it2); - } - if (selected) _item_select(it); - else _item_unselect(it); - evas_object_unref(obj); -} - -static void _item_block_position_update(Eina_Inlist *list, int idx) { @@ -4898,7 +5008,7 @@ _elm_genlist_smart_set_user(Elm_Genlist_Smart_Class *sc) ELM_WIDGET_CLASS(sc)->translate = _elm_genlist_smart_translate; /* not a 'focus chain manager' */ - ELM_WIDGET_CLASS(sc)->focus_next = NULL; + ELM_WIDGET_CLASS(sc)->focus_next = NULL; //_elm_genlist_smart_focus_next; ELM_WIDGET_CLASS(sc)->focus_direction = NULL; ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_genlist_smart_sizing_eval; diff --git a/src/lib/elm_list.c b/src/lib/elm_list.c index 0f2fc58..1f7e131 100644 --- a/src/lib/elm_list.c +++ b/src/lib/elm_list.c @@ -44,6 +44,10 @@ static void _mouse_up_cb(void *, Evas *, Evas_Object *, void *); static void _mouse_down_cb(void *, Evas *, Evas_Object *, void *); static void _mouse_move_cb(void *, Evas *, Evas_Object *, void *); static void _items_fix(Evas_Object *); +static void _item_select(Elm_List_Item *it); +static void _item_unselect(Elm_List_Item *it); + + EVAS_SMART_SUBCLASS_IFACE_NEW (ELM_LIST_SMART_NAME, _elm_list, Elm_List_Smart_Class, @@ -192,6 +196,71 @@ _item_single_select_down(Elm_List_Smart_Data *sd) return EINA_TRUE; } +static void _item_focused(Elm_List_Item *it) +{ + if (!it) return; + Elm_List_Smart_Data *sd = it->sd; + Evas_Coord x, y, w, h, sx, sy, sw, sh; + + evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); + evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh); + if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh))) + { + elm_list_item_bring_in((Elm_Object_Item *)it); + } + + edje_object_signal_emit + (VIEW(it), "elm,state,focused", "elm"); + + sd->focused = (Elm_Object_Item *)it; +} + +static void _item_unfocused(Elm_List_Item *it) +{ + if (!it) return; + Elm_List_Smart_Data *sd = it->sd; + edje_object_signal_emit + (VIEW(sd->focused), "elm,state,unfocused", "elm"); + if (it == (Elm_List_Item *)sd->focused) + sd->focused = NULL; +} + +static Elm_List_Item *_item_focused_search(Elm_List_Item *it, int dir) +{ + if (!it) return NULL; + Eina_List *l = eina_list_data_find_list(it->sd->items, it); + Eina_List *tmp = l; + if (dir == 1) tmp = eina_list_next(tmp); + else tmp = eina_list_prev(tmp); + if (!tmp) tmp = l; + return (Elm_List_Item *)eina_list_data_get(tmp); +} + +static void _item_focused_next(Elm_List_Smart_Data *sd, int dir) +{ + Elm_List_Item *it = NULL; + + if (elm_widget_focus_get(ELM_WIDGET_DATA(sd)->obj)) + edje_object_signal_emit + (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm"); + + if (!sd->focused) + { + if (dir == 1) + it = (Elm_List_Item *)eina_list_data_get(sd->items); + else + it = (Elm_List_Item *)eina_list_data_get(eina_list_last(sd->items)); + } + else + { + it = (Elm_List_Item *)sd->focused; + _item_unfocused((Elm_List_Item *)sd->focused); + it = _item_focused_search(it, dir); + } + _item_focused(it); +} + + static Eina_Bool _elm_list_smart_event(Evas_Object *obj, Evas_Object *src __UNUSED__, @@ -254,43 +323,49 @@ _elm_list_smart_event(Evas_Object *obj, ((!strcmp(ev->keyname, "KP_Up")) && !ev->string)) { if ((!sd->h_mode) && - (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && - (_item_multi_select_up(sd))) - || (_item_single_select_up(sd)))) + (evas_key_modifier_is_set(ev->modifiers, "Shift")) && + (_item_multi_select_up(sd))) { ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else - y -= step_y; + { + _item_focused_next(sd, -1); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } } else if ((!strcmp(ev->keyname, "Down")) || ((!strcmp(ev->keyname, "KP_Down")) && !ev->string)) { if ((!sd->h_mode) && - (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && - (_item_multi_select_down(sd))) - || (_item_single_select_down(sd)))) + (evas_key_modifier_is_set(ev->modifiers, "Shift")) && + (_item_multi_select_down(sd))) { ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else - y += step_y; + { + _item_focused_next(sd, 1); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } } else if ((!strcmp(ev->keyname, "Home")) || ((!strcmp(ev->keyname, "KP_Home")) && !ev->string)) { - it = eina_list_data_get(sd->items); - elm_list_item_bring_in((Elm_Object_Item *)it); + _item_unfocused((Elm_List_Item *)sd->focused); + _item_focused_next(sd, 1); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else if ((!strcmp(ev->keyname, "End")) || ((!strcmp(ev->keyname, "KP_End")) && !ev->string)) { - it = eina_list_data_get(eina_list_last(sd->items)); - elm_list_item_bring_in((Elm_Object_Item *)it); + _item_unfocused((Elm_List_Item *)sd->focused); + _item_focused_next(sd, -1); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } @@ -332,11 +407,17 @@ _elm_list_smart_event(Evas_Object *obj, } else if (((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")) || - (!strcmp(ev->keyname, "space"))) - && (!sd->multi) && (sd->selected)) + (!strcmp(ev->keyname, "space"))) && + (!sd->multi)) { - it = (Elm_List_Item *)elm_list_selected_item_get(obj); - if (it) evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); + if (sd->focused) + { + it = (Elm_List_Item *)sd->focused; + _item_select(it); + evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); + it->selected = EINA_FALSE; + sd->selected = eina_list_remove(sd->selected, it); + } } else if (!strcmp(ev->keyname, "Escape")) { @@ -792,6 +873,26 @@ _elm_list_smart_on_focus(Evas_Object *obj) if (elm_widget_focus_get(obj) && sd->selected && !sd->last_selected_item) sd->last_selected_item = eina_list_data_get(sd->selected); + if (elm_widget_focus_get(obj)) + { + if (sd->focused) + { + edje_object_signal_emit + (VIEW(sd->focused), "elm,state,focused", "elm"); + } + else + edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,focused", "elm"); + } + else + { + if (sd->focused) + { + edje_object_signal_emit + (VIEW(sd->focused), "elm,state,unfocused", "elm"); + } + else + edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm"); + } return EINA_TRUE; } diff --git a/src/lib/elm_widget_genlist.h b/src/lib/elm_widget_genlist.h index 4895434..07967d8 100644 --- a/src/lib/elm_widget_genlist.h +++ b/src/lib/elm_widget_genlist.h @@ -139,6 +139,7 @@ struct _Elm_Genlist_Smart_Data Evas_Object *hit_rect; Evas_Object *pan_obj; + Elm_Gen_Item *focused; Eina_List *selected; /* a list of * selected * items */ diff --git a/src/lib/elm_widget_list.h b/src/lib/elm_widget_list.h index 8bd51c5..6b9fe38 100644 --- a/src/lib/elm_widget_list.h +++ b/src/lib/elm_widget_list.h @@ -131,6 +131,7 @@ struct _Elm_List_Smart_Data Evas_Object *box, *hit_rect; const Elm_Scrollable_Smart_Interface *s_iface; + Elm_Object_Item *focused; Eina_List *items, *selected, *to_delete; Elm_Object_Item *last_selected_item; Evas_Coord minw[2], minh[2]; -- 2.7.4