X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flib%2Felm_list.c;h=d370baac54d95726acdc5e79543f8ec58e857943;hb=7fe2818cc3815724be0e6957d4c862688505fd6d;hp=f80bd639171b9db07f61bbf28f796d58396aac10;hpb=ff69fb49d9efa148c47f0e6a34c838e961134942;p=framework%2Fuifw%2Felementary.git diff --git a/src/lib/elm_list.c b/src/lib/elm_list.c index f80bd63..d370baa 100644 --- a/src/lib/elm_list.c +++ b/src/lib/elm_list.c @@ -1,37 +1,40 @@ #include #include "elm_priv.h" +#include "els_scroller.h" #define SWIPE_MOVES 12 typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_List_Item Elm_List_Item; struct _Widget_Data { Evas_Object *scr, *box, *self; Eina_List *items, *selected, *to_delete; - Elm_List_Item *last_selected_item; + Elm_Object_Item *last_selected_item; Elm_List_Mode mode; Elm_List_Mode h_mode; Evas_Coord minw[2], minh[2]; - Eina_Bool scr_minw : 1; - Eina_Bool scr_minh : 1; + Elm_Object_Select_Mode select_mode; int walking; int movements; - struct { + struct + { Evas_Coord x, y; - } history[SWIPE_MOVES]; + } history[SWIPE_MOVES]; + Eina_Bool scr_minw : 1; + Eina_Bool scr_minh : 1; Eina_Bool swipe : 1; Eina_Bool fix_pending : 1; Eina_Bool on_hold : 1; Eina_Bool multi : 1; - Eina_Bool always_select : 1; Eina_Bool longpressed : 1; Eina_Bool wasselected : 1; }; struct _Elm_List_Item { - Elm_Widget_Item base; + ELM_WIDGET_ITEM; Widget_Data *wd; Eina_List *node; const char *label; @@ -40,13 +43,12 @@ struct _Elm_List_Item Ecore_Timer *long_timer; Ecore_Timer *swipe_timer; Eina_Bool deleted : 1; - Eina_Bool disabled : 1; Eina_Bool even : 1; Eina_Bool is_even : 1; Eina_Bool is_separator : 1; Eina_Bool fixed : 1; Eina_Bool selected : 1; - Eina_Bool hilighted : 1; + Eina_Bool highlighted : 1; Eina_Bool dummy_icon : 1; Eina_Bool dummy_end : 1; }; @@ -65,10 +67,10 @@ static void _fix_items(Evas_Object *obj); static void _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info); static void _mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info); static void _mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info); -static void _scroll_edge_left(void *data, Evas_Object *scr, void *event_info); -static void _scroll_edge_right(void *data, Evas_Object *scr, void *event_info); -static void _scroll_edge_top(void *data, Evas_Object *scr, void *event_info); -static void _scroll_edge_bottom(void *data, Evas_Object *scr, void *event_info); +static void _edge_left(void *data, Evas_Object *scr, void *event_info); +static void _edge_right(void *data, Evas_Object *scr, void *event_info); +static void _edge_top(void *data, Evas_Object *scr, void *event_info); +static void _edge_bottom(void *data, Evas_Object *scr, void *event_info); static Eina_Bool _item_multi_select_up(Widget_Data *wd); static Eina_Bool _item_multi_select_down(Widget_Data *wd); static Eina_Bool _item_single_select_up(Widget_Data *wd); @@ -82,10 +84,10 @@ static const char SIG_CLICKED_DOUBLE[] = "clicked,double"; static const char SIG_SELECTED[] = "selected"; static const char SIG_UNSELECTED[] = "unselected"; static const char SIG_LONGPRESSED[] = "longpressed"; -static const char SIG_SCROLL_EDGE_TOP[] = "scroll,edge,top"; -static const char SIG_SCROLL_EDGE_BOTTOM[] = "scroll,edge,bottom"; -static const char SIG_SCROLL_EDGE_LEFT[] = "scroll,edge,left"; -static const char SIG_SCROLL_EDGE_RIGHT[] = "scroll,edge,right"; +static const char SIG_EDGE_TOP[] = "edge,top"; +static const char SIG_EDGE_BOTTOM[] = "edge,bottom"; +static const char SIG_EDGE_LEFT[] = "edge,left"; +static const char SIG_EDGE_RIGHT[] = "edge,right"; static const Evas_Smart_Cb_Description _signals[] = { {SIG_ACTIVATED, ""}, @@ -93,16 +95,16 @@ static const Evas_Smart_Cb_Description _signals[] = { {SIG_SELECTED, ""}, {SIG_UNSELECTED, ""}, {SIG_LONGPRESSED, ""}, - {SIG_SCROLL_EDGE_TOP, ""}, - {SIG_SCROLL_EDGE_BOTTOM, ""}, - {SIG_SCROLL_EDGE_LEFT, ""}, - {SIG_SCROLL_EDGE_RIGHT, ""}, + {SIG_EDGE_TOP, ""}, + {SIG_EDGE_BOTTOM, ""}, + {SIG_EDGE_LEFT, ""}, + {SIG_EDGE_RIGHT, ""}, {NULL, NULL} }; #define ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, ...) \ - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, __VA_ARGS__); \ -if (it->deleted) \ + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, __VA_ARGS__); \ +if (((Elm_List_Item *)it)->deleted) \ { \ ERR("ERROR: "#it" has been DELETED.\n"); \ return __VA_ARGS__; \ @@ -112,30 +114,30 @@ static inline void _elm_list_item_free(Elm_List_Item *it) { evas_object_event_callback_del_full - (it->base.view, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it); + (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it); evas_object_event_callback_del_full - (it->base.view, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it); + (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _mouse_up, it); evas_object_event_callback_del_full - (it->base.view, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, it); + (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, it); if (it->icon) evas_object_event_callback_del_full (it->icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _changed_size_hints, it->base.widget); + _changed_size_hints, WIDGET(it)); if (it->end) evas_object_event_callback_del_full (it->end, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _changed_size_hints, it->base.widget); + _changed_size_hints, WIDGET(it)); eina_stringshare_del(it->label); if (it->swipe_timer) ecore_timer_del(it->swipe_timer); + it->swipe_timer = NULL; if (it->long_timer) ecore_timer_del(it->long_timer); + it->long_timer = NULL; if (it->icon) evas_object_del(it->icon); if (it->end) evas_object_del(it->end); - - elm_widget_item_del(it); } static Eina_Bool @@ -166,7 +168,7 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty /* TODO: fix logic for horizontal mode */ if ((!strcmp(ev->keyname, "Left")) || - (!strcmp(ev->keyname, "KP_Left"))) + ((!strcmp(ev->keyname, "KP_Left")) && !ev->string)) { if ((wd->h_mode) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -180,7 +182,7 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty x -= step_x; } else if ((!strcmp(ev->keyname, "Right")) || - (!strcmp(ev->keyname, "KP_Right"))) + ((!strcmp(ev->keyname, "KP_Right")) && !ev->string)) { if ((wd->h_mode) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -194,7 +196,7 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty x += step_x; } else if ((!strcmp(ev->keyname, "Up")) || - (!strcmp(ev->keyname, "KP_Up"))) + ((!strcmp(ev->keyname, "KP_Up")) && !ev->string)) { if ((!wd->h_mode) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -208,7 +210,7 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty y -= step_y; } else if ((!strcmp(ev->keyname, "Down")) || - (!strcmp(ev->keyname, "KP_Down"))) + ((!strcmp(ev->keyname, "KP_Down")) && !ev->string)) { if ((!wd->h_mode) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -222,23 +224,23 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty y += step_y; } else if ((!strcmp(ev->keyname, "Home")) || - (!strcmp(ev->keyname, "KP_Home"))) + ((!strcmp(ev->keyname, "KP_Home")) && !ev->string)) { it = eina_list_data_get(wd->items); - elm_list_item_bring_in(it); + elm_list_item_bring_in((Elm_Object_Item *)it); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else if ((!strcmp(ev->keyname, "End")) || - (!strcmp(ev->keyname, "KP_End"))) + ((!strcmp(ev->keyname, "KP_End")) && !ev->string)) { it = eina_list_data_get(eina_list_last(wd->items)); - elm_list_item_bring_in(it); + elm_list_item_bring_in((Elm_Object_Item *)it); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else if ((!strcmp(ev->keyname, "Prior")) || - (!strcmp(ev->keyname, "KP_Prior"))) + ((!strcmp(ev->keyname, "KP_Prior")) && !ev->string)) { if (wd->h_mode) { @@ -256,7 +258,7 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty } } else if ((!strcmp(ev->keyname, "Next")) || - (!strcmp(ev->keyname, "KP_Next"))) + ((!strcmp(ev->keyname, "KP_Next")) && !ev->string)) { if (wd->h_mode) { @@ -278,8 +280,8 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty (!strcmp(ev->keyname, "space"))) && (!wd->multi) && (wd->selected)) { - it = elm_list_selected_item_get(obj); - evas_object_smart_callback_call(it->base.widget, SIG_ACTIVATED, it); + it = (Elm_List_Item *) elm_list_selected_item_get(obj); + evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); } else if (!strcmp(ev->keyname, "Escape")) { @@ -294,12 +296,19 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty return EINA_TRUE; } +static void +_translate_hook(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, "language,changed", NULL); +} + static Eina_Bool _deselect_all_items(Widget_Data *wd) { if (!wd->selected) return EINA_FALSE; while (wd->selected) - elm_list_item_selected_set(wd->selected->data, EINA_FALSE); + elm_list_item_selected_set((Elm_Object_Item *) wd->selected->data, + EINA_FALSE); return EINA_TRUE; } @@ -310,7 +319,7 @@ _item_multi_select_up(Widget_Data *wd) if (!wd->selected) return EINA_FALSE; if (!wd->multi) return EINA_FALSE; - Elm_List_Item *prev = elm_list_item_prev(wd->last_selected_item); + Elm_Object_Item *prev = elm_list_item_prev(wd->last_selected_item); if (!prev) return EINA_TRUE; if (elm_list_item_selected_get(prev)) @@ -333,7 +342,7 @@ _item_multi_select_down(Widget_Data *wd) if (!wd->selected) return EINA_FALSE; if (!wd->multi) return EINA_FALSE; - Elm_List_Item *next = elm_list_item_next(wd->last_selected_item); + Elm_Object_Item *next = elm_list_item_next(wd->last_selected_item); if (!next) return EINA_TRUE; if (elm_list_item_selected_get(next)) @@ -353,11 +362,10 @@ _item_multi_select_down(Widget_Data *wd) static Eina_Bool _item_single_select_up(Widget_Data *wd) { - Elm_List_Item *prev; + Elm_Object_Item *prev; if (!wd->selected) prev = eina_list_data_get(eina_list_last(wd->items)); else prev = elm_list_item_prev(wd->last_selected_item); - if (!prev) return EINA_FALSE; _deselect_all_items(wd); @@ -370,11 +378,10 @@ _item_single_select_up(Widget_Data *wd) static Eina_Bool _item_single_select_down(Widget_Data *wd) { - Elm_List_Item *next; + Elm_Object_Item *next; if (!wd->selected) next = eina_list_data_get(wd->items); else next = elm_list_item_next(wd->last_selected_item); - if (!next) return EINA_FALSE; _deselect_all_items(wd); @@ -393,10 +400,9 @@ _elm_list_process_deletions(Widget_Data *wd) EINA_LIST_FREE(wd->to_delete, it) { - elm_widget_item_pre_notify_del(it); - wd->items = eina_list_remove_list(wd->items, it->node); _elm_list_item_free(it); + elm_widget_item_free(it); } wd->walking--; @@ -441,8 +447,25 @@ static void _del_pre_hook(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); + const Eina_List *l; + Elm_List_Item *it; + + evas_object_smart_callback_del(obj, "sub-object-del", _sub_del); + if (!wd) return; + EINA_LIST_FOREACH(wd->items, l, it) + { + if (it->icon) + evas_object_event_callback_del(it->icon, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints); + if (it->end) + evas_object_event_callback_del(it->end, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints); + } + evas_object_event_callback_del(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints); @@ -468,7 +491,11 @@ _del_hook(Evas_Object *obj) if (wd->to_delete) ERR("ERROR: leaking nodes!\n"); - EINA_LIST_FREE(wd->items, it) _elm_list_item_free(it); + EINA_LIST_FREE(wd->items, it) + { + _elm_list_item_free(it); + elm_widget_item_free(it); + } eina_list_free(wd->selected); free(wd); } @@ -493,7 +520,7 @@ _disable_hook(Evas_Object *obj) _signal_emit_hook(obj, "elm,state,disabled", "elm"); elm_widget_scroll_freeze_push(obj); elm_widget_scroll_hold_push(obj); - /* FIXME: if we get to have a way to only un-hilight items + /* FIXME: if we get to have a way to only un-highlight items * in the future, keeping them selected... */ _deselect_all_items(wd); } @@ -585,7 +612,7 @@ _mirrored_set(Evas_Object *obj, Eina_Bool rtl) elm_smart_scroller_mirrored_set(wd->scr, rtl); EINA_LIST_FOREACH(wd->items, n, it) - edje_object_mirrored_set(it->base.view, rtl); + edje_object_mirrored_set(VIEW(it), rtl); } static void @@ -617,7 +644,7 @@ _theme_hook(Evas_Object *obj) } EINA_LIST_FOREACH(wd->items, n, it) { - edje_object_scale_set(it->base.view, elm_widget_scale_get(obj) * _elm_config->scale); + edje_object_scale_set(VIEW(it), elm_widget_scale_get(obj) * _elm_config->scale); it->fixed = 0; } _fix_items(obj); @@ -687,24 +714,25 @@ _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) } static void -_item_hilight(Elm_List_Item *it) +_item_highlight(Elm_List_Item *it) { - Evas_Object *obj = it->base.widget; + Evas_Object *obj = WIDGET(it); Widget_Data *wd = elm_widget_data_get(obj); const char *selectraise; if (!wd) return; ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - if (it->hilighted) return; + if ((it->highlighted) || (it->base.disabled) || + (wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE)) return; evas_object_ref(obj); _elm_list_walk(wd); - edje_object_signal_emit(it->base.view, "elm,state,selected", "elm"); - selectraise = edje_object_data_get(it->base.view, "selectraise"); + edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); + selectraise = edje_object_data_get(VIEW(it), "selectraise"); if ((selectraise) && (!strcmp(selectraise, "on"))) - evas_object_raise(it->base.view); - it->hilighted = EINA_TRUE; + evas_object_raise(VIEW(it)); + it->highlighted = EINA_TRUE; _elm_list_unwalk(wd); evas_object_unref(obj); @@ -713,14 +741,15 @@ _item_hilight(Elm_List_Item *it) static void _item_select(Elm_List_Item *it) { - Evas_Object *obj = it->base.widget; + Evas_Object *obj = WIDGET(it); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); + if (it->base.disabled || (wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE)) return; if (it->selected) { - if (wd->always_select) goto call; + if (wd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) goto call; return; } it->selected = EINA_TRUE; @@ -730,9 +759,9 @@ call: evas_object_ref(obj); _elm_list_walk(wd); - if (it->func) it->func((void *)it->base.data, it->base.widget, it); + if (it->func) it->func((void *)it->base.data, WIDGET(it), it); evas_object_smart_callback_call(obj, SIG_SELECTED, it); - it->wd->last_selected_item = it; + it->wd->last_selected_item = (Elm_Object_Item *)it; _elm_list_unwalk(wd); evas_object_unref(obj); @@ -741,31 +770,31 @@ call: static void _item_unselect(Elm_List_Item *it) { - Evas_Object *obj = it->base.widget; + Evas_Object *obj = WIDGET(it); Widget_Data *wd = elm_widget_data_get(obj); const char *stacking, *selectraise; if (!wd) return; ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - if (!it->hilighted) return; + if (!it->highlighted) return; evas_object_ref(obj); _elm_list_walk(wd); - edje_object_signal_emit(it->base.view, "elm,state,unselected", "elm"); - stacking = edje_object_data_get(it->base.view, "stacking"); - selectraise = edje_object_data_get(it->base.view, "selectraise"); + edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm"); + stacking = edje_object_data_get(VIEW(it), "stacking"); + selectraise = edje_object_data_get(VIEW(it), "selectraise"); if ((selectraise) && (!strcmp(selectraise, "on"))) { if ((stacking) && (!strcmp(stacking, "below"))) - evas_object_lower(it->base.view); + evas_object_lower(VIEW(it)); } - it->hilighted = EINA_FALSE; + it->highlighted = EINA_FALSE; if (it->selected) { it->selected = EINA_FALSE; wd->selected = eina_list_remove(wd->selected, it); - evas_object_smart_callback_call(it->base.widget, SIG_UNSELECTED, it); + evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it); } _elm_list_unwalk(wd); @@ -776,7 +805,7 @@ static Eina_Bool _swipe_cancel(void *data) { Elm_List_Item *it = data; - Widget_Data *wd = elm_widget_data_get(it->base.widget); + Widget_Data *wd = elm_widget_data_get(WIDGET(it)); if (!wd) return ECORE_CALLBACK_CANCEL; ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, ECORE_CALLBACK_CANCEL); @@ -789,7 +818,7 @@ static void _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { Elm_List_Item *it = data; - Evas_Object *obj2 = it->base.widget; + Evas_Object *obj2 = WIDGET(it); Widget_Data *wd = elm_widget_data_get(obj2); Evas_Event_Mouse_Move *ev = event_info; @@ -829,48 +858,48 @@ _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void } static void -_scroll_edge_left(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) +_edge_left(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) { Evas_Object *obj = data; - evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_LEFT, NULL); + evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL); } static void -_scroll_edge_right(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) +_edge_right(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) { Evas_Object *obj = data; - evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_RIGHT, NULL); + evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL); } static void -_scroll_edge_top(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) +_edge_top(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) { Evas_Object *obj = data; - evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_TOP, NULL); + evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL); } static void -_scroll_edge_bottom(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) +_edge_bottom(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__) { Evas_Object *obj = data; - evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_BOTTOM, NULL); + evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL); } static Eina_Bool _long_press(void *data) { Elm_List_Item *it = data; - Evas_Object *obj = it->base.widget; + Evas_Object *obj = WIDGET(it); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) goto end; ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, ECORE_CALLBACK_CANCEL); it->long_timer = NULL; - if (it->disabled) goto end; + if (it->base.disabled) goto end; wd->longpressed = EINA_TRUE; - evas_object_smart_callback_call(it->base.widget, SIG_LONGPRESSED, it); + evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it); end: return ECORE_CALLBACK_CANCEL; @@ -880,7 +909,7 @@ static void _swipe(Elm_List_Item *it) { int i, sum = 0; - Widget_Data *wd = elm_widget_data_get(it->base.widget); + Widget_Data *wd = elm_widget_data_get(WIDGET(it)); ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); if (!wd) return; @@ -893,14 +922,14 @@ _swipe(Elm_List_Item *it) sum /= wd->movements; if (abs(sum - wd->history[0].x) <= 10) return; - evas_object_smart_callback_call(it->base.widget, "swipe", it); + evas_object_smart_callback_call(WIDGET(it), "swipe", it); } static void _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { Elm_List_Item *it = data; - Evas_Object *obj2 = it->base.widget; + Evas_Object *obj2 = WIDGET(it); Widget_Data *wd = elm_widget_data_get(obj2); Evas_Event_Mouse_Down *ev = event_info; @@ -915,7 +944,7 @@ _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void evas_object_ref(obj2); _elm_list_walk(wd); - _item_hilight(it); + _item_highlight(it); wd->longpressed = EINA_FALSE; if (it->long_timer) ecore_timer_del(it->long_timer); it->long_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, it); @@ -924,8 +953,8 @@ _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void /* Always call the callbacks last - the user may delete our context! */ if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) { - evas_object_smart_callback_call(it->base.widget, SIG_CLICKED_DOUBLE, it); - evas_object_smart_callback_call(it->base.widget, SIG_ACTIVATED, it); + evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it); + evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); } wd->swipe = EINA_FALSE; wd->movements = 0; @@ -938,7 +967,7 @@ static void _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { Elm_List_Item *it = data; - Evas_Object *obj2 = it->base.widget; + Evas_Object *obj2 = WIDGET(it); Widget_Data *wd = elm_widget_data_get(obj2); Evas_Event_Mouse_Up *ev = event_info; @@ -971,7 +1000,7 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void * return; } - if (it->disabled) + if (it->base.disabled) return; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; @@ -982,7 +1011,7 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void * { if (!it->selected) { - _item_hilight(it); + _item_highlight(it); _item_select(it); } else _item_unselect(it); @@ -993,7 +1022,7 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void * { while (wd->selected) _item_unselect(wd->selected->data); - _item_hilight(it); + _item_highlight(it); _item_select(it); } else @@ -1003,7 +1032,7 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void * EINA_LIST_FOREACH_SAFE(wd->selected, l, l_next, it2) if (it2 != it) _item_unselect(it2); - _item_hilight(it); + _item_highlight(it); _item_select(it); } } @@ -1012,6 +1041,144 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void * evas_object_unref(obj2); } +static void +_item_disable(Elm_Object_Item *it) +{ + Elm_List_Item *item = (Elm_List_Item *)it; + if (item->base.disabled) + edje_object_signal_emit(VIEW(item), "elm,state,disabled", "elm"); + else + edje_object_signal_emit(VIEW(item), "elm,state,enabled", "elm"); +} + +static void +_item_content_set_hook(Elm_Object_Item *it, const char *part, Evas_Object *content) +{ + Elm_List_Item *item = (Elm_List_Item *)it; + Evas_Object **icon_p = NULL; + Eina_Bool dummy = EINA_FALSE; + + if ((!part) || (!strcmp(part, "start"))) + { + icon_p = &(item->icon); + dummy = item->dummy_icon; + if (!content) item->dummy_icon = EINA_TRUE; + else item->dummy_icon = EINA_FALSE; + } + else if (!strcmp(part, "end")) + { + icon_p = &(item->end); + dummy = item->dummy_end; + if (!content) item->dummy_end = EINA_TRUE; + else item->dummy_end = EINA_FALSE; + } + else + return; + + if (content == *icon_p) return; + if ((dummy) && (!content)) return; + if (dummy) evas_object_del(*icon_p); + if (!content) + { + content = evas_object_rectangle_add(evas_object_evas_get(WIDGET(item))); + evas_object_color_set(content, 0, 0, 0, 0); + } + if (*icon_p) + { + evas_object_del(*icon_p); + *icon_p = NULL; + } + *icon_p = content; + if (VIEW(item)) + edje_object_part_swallow(VIEW(item), "elm.swallow.icon", content); +} + +static Evas_Object * +_item_content_get_hook(const Elm_Object_Item *it, const char *part) +{ + Elm_List_Item *item = (Elm_List_Item *)it; + + if ((!part) || (!strcmp(part, "start"))) + { + if (item->dummy_icon) return NULL; + return item->icon; + } + else if (!strcmp(part, "end")) + { + if (item->dummy_end) return NULL; + return item->end; + } + return NULL; +} + +static Evas_Object * +_item_content_unset_hook(const Elm_Object_Item *it, const char *part) +{ + Elm_List_Item *item = (Elm_List_Item *)it; + + if ((!part) || (!strcmp(part, "start"))) + { + Evas_Object *obj = item->icon; + _item_content_set_hook((Elm_Object_Item *)it, part, NULL); + return obj; + } + else if (!strcmp(part, "end")) + { + Evas_Object *obj = item->end; + _item_content_set_hook((Elm_Object_Item *)it, part, NULL); + return obj; + } + return NULL; +} + +static void +_item_text_set_hook(Elm_Object_Item *it, const char *part, const char *text) +{ + Elm_List_Item *list_it = (Elm_List_Item *)it; + if (part && strcmp(part, "default")) return; + if (!eina_stringshare_replace(&list_it->label, text)) return; + if (VIEW(list_it)) + edje_object_part_text_escaped_set(VIEW(list_it), "elm.text", text); +} + +static const char * +_item_text_get_hook(const Elm_Object_Item *it, const char *part) +{ + if (part && strcmp(part, "default")) return NULL; + return ((Elm_List_Item *)it)->label; +} + +static Eina_Bool +_item_del_pre_hook(Elm_Object_Item *it) +{ + Evas_Object *obj = WIDGET(it); + Elm_List_Item *item = (Elm_List_Item *)it; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + + if (item->selected) _item_unselect(item); + + if (wd->walking > 0) + { + if (item->deleted) return EINA_FALSE; + item->deleted = EINA_TRUE; + wd->to_delete = eina_list_append(wd->to_delete, item); + return EINA_FALSE; + } + + wd->items = eina_list_remove_list(wd->items, item->node); + + evas_object_ref(obj); + _elm_list_walk(wd); + + _elm_list_item_free(item); + + _elm_list_unwalk(wd); + evas_object_unref(obj); + + return EINA_TRUE; +} + static Elm_List_Item * _item_new(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) { @@ -1026,16 +1193,16 @@ _item_new(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *e it->end = end; it->func = func; it->base.data = data; - it->base.view = edje_object_add(evas_object_evas_get(obj)); - edje_object_mirrored_set(it->base.view, elm_widget_mirrored_get(obj)); - evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_DOWN, + VIEW(it) = edje_object_add(evas_object_evas_get(obj)); + edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj)); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it); - evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_UP, + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP, _mouse_up, it); - evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_MOVE, + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, it); - evas_object_size_hint_weight_set(it->base.view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(it->base.view, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(VIEW(it), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL); if (it->icon) { elm_widget_sub_object_add(obj, it->icon); @@ -1048,6 +1215,13 @@ _item_new(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *e evas_object_event_callback_add(it->end, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); } + elm_widget_item_disable_hook_set(it, _item_disable); + elm_widget_item_content_set_hook_set(it, _item_content_set_hook); + elm_widget_item_content_get_hook_set(it, _item_content_get_hook); + elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook); + elm_widget_item_text_set_hook_set(it, _item_text_set_hook); + elm_widget_item_text_get_hook_set(it, _item_text_get_hook); + elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); return it; } @@ -1148,46 +1322,46 @@ _fix_items(Evas_Object *obj) /* FIXME: separators' themes seem to be b0rked */ if (it->is_separator) - _elm_theme_object_set(obj, it->base.view, "separator", + _elm_theme_object_set(obj, VIEW(it), "separator", wd->h_mode ? "horizontal" : "vertical", style); else if (wd->mode == ELM_LIST_COMPRESS) { if (it->even) - _elm_theme_object_set(obj, it->base.view, "list", + _elm_theme_object_set(obj, VIEW(it), "list", it_compress, style); else - _elm_theme_object_set(obj, it->base.view, "list", + _elm_theme_object_set(obj, VIEW(it), "list", it_compress_odd, style); } else { if (it->even) - _elm_theme_object_set(obj, it->base.view, "list", it_plain, + _elm_theme_object_set(obj, VIEW(it), "list", it_plain, style); else - _elm_theme_object_set(obj, it->base.view, "list", it_odd, + _elm_theme_object_set(obj, VIEW(it), "list", it_odd, style); } - stacking = edje_object_data_get(it->base.view, "stacking"); + stacking = edje_object_data_get(VIEW(it), "stacking"); if (stacking) { if (!strcmp(stacking, "below")) - evas_object_lower(it->base.view); + evas_object_lower(VIEW(it)); else if (!strcmp(stacking, "above")) - evas_object_raise(it->base.view); + evas_object_raise(VIEW(it)); } - edje_object_part_text_set(it->base.view, "elm.text", it->label); + edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label); if ((!it->icon) && (minh[0] > 0)) { - it->icon = evas_object_rectangle_add(evas_object_evas_get(it->base.view)); + it->icon = evas_object_rectangle_add(evas_object_evas_get(VIEW(it))); evas_object_color_set(it->icon, 0, 0, 0, 0); it->dummy_icon = EINA_TRUE; } if ((!it->end) && (minh[1] > 0)) { - it->end = evas_object_rectangle_add(evas_object_evas_get(it->base.view)); + it->end = evas_object_rectangle_add(evas_object_evas_get(VIEW(it))); evas_object_color_set(it->end, 0, 0, 0, 0); it->dummy_end = EINA_TRUE; } @@ -1195,46 +1369,46 @@ _fix_items(Evas_Object *obj) { evas_object_size_hint_min_set(it->icon, minw[0], minh[0]); evas_object_size_hint_max_set(it->icon, 99999, 99999); - edje_object_part_swallow(it->base.view, "elm.swallow.icon", it->icon); + edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon); } if (it->end) { evas_object_size_hint_min_set(it->end, minw[1], minh[1]); evas_object_size_hint_max_set(it->end, 99999, 99999); - edje_object_part_swallow(it->base.view, "elm.swallow.end", it->end); + edje_object_part_swallow(VIEW(it), "elm.swallow.end", it->end); } if (!it->fixed) { // this may call up user and it may modify the list item // but we're safe as we're flagged as walking. // just don't process further - edje_object_message_signal_process(it->base.view); + edje_object_message_signal_process(VIEW(it)); if (it->deleted) continue; mw = mh = -1; elm_coords_finger_size_adjust(1, &mw, 1, &mh); - edje_object_size_min_restricted_calc(it->base.view, &mw, &mh, mw, mh); + edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh); elm_coords_finger_size_adjust(1, &mw, 1, &mh); - evas_object_size_hint_min_set(it->base.view, mw, mh); - evas_object_show(it->base.view); + evas_object_size_hint_min_set(VIEW(it), mw, mh); + evas_object_show(VIEW(it)); } - if ((it->selected) || (it->hilighted)) + if ((it->selected) || (it->highlighted)) { const char *selectraise; // this may call up user and it may modify the list item // but we're safe as we're flagged as walking. // just don't process further - edje_object_signal_emit(it->base.view, "elm,state,selected", "elm"); + edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); if (it->deleted) continue; - selectraise = edje_object_data_get(it->base.view, "selectraise"); + selectraise = edje_object_data_get(VIEW(it), "selectraise"); if ((selectraise) && (!strcmp(selectraise, "on"))) - evas_object_raise(it->base.view); + evas_object_raise(VIEW(it)); } - if (it->disabled) - edje_object_signal_emit(it->base.view, "elm,state,disabled", + if (it->base.disabled) + edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); it->fixed = EINA_TRUE; @@ -1318,6 +1492,7 @@ elm_list_add(Evas_Object *parent) elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); elm_widget_event_hook_set(obj, _event_hook); + elm_widget_translate_hook_set(obj, _translate_hook); wd->self = obj; wd->scr = elm_smart_scroller_add(e); @@ -1348,10 +1523,10 @@ elm_list_add(Evas_Object *parent) wd->mode = ELM_LIST_SCROLL; - evas_object_smart_callback_add(wd->scr, "edge,left", _scroll_edge_left, obj); - evas_object_smart_callback_add(wd->scr, "edge,right", _scroll_edge_right, obj); - evas_object_smart_callback_add(wd->scr, "edge,top", _scroll_edge_top, obj); - evas_object_smart_callback_add(wd->scr, "edge,bottom", _scroll_edge_bottom, obj); + evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj); + evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj); + evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj); + evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj); evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj); @@ -1366,139 +1541,6 @@ elm_list_add(Evas_Object *parent) return obj; } -EAPI Elm_List_Item * -elm_list_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) -{ - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - Elm_List_Item *it = _item_new(obj, label, icon, end, func, data); - - wd->items = eina_list_append(wd->items, it); - it->node = eina_list_last(wd->items); - elm_box_pack_end(wd->box, it->base.view); - return it; -} - -EAPI Elm_List_Item * -elm_list_item_prepend(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) -{ - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - Elm_List_Item *it = _item_new(obj, label, icon, end, func, data); - - wd->items = eina_list_prepend(wd->items, it); - it->node = wd->items; - elm_box_pack_start(wd->box, it->base.view); - return it; -} - -EAPI Elm_List_Item * -elm_list_item_insert_before(Evas_Object *obj, Elm_List_Item *before, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) -{ - Widget_Data *wd; - Elm_List_Item *it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL); - if (!before->node) return NULL; - ELM_LIST_ITEM_CHECK_DELETED_RETURN(before, NULL); - - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - wd = elm_widget_data_get(obj); - if (!wd) return NULL; - it = _item_new(obj, label, icon, end, func, data); - wd->items = eina_list_prepend_relative_list(wd->items, it, before->node); - it->node = before->node->prev; - elm_box_pack_before(wd->box, it->base.view, before->base.view); - return it; -} - -EAPI Elm_List_Item * -elm_list_item_insert_after(Evas_Object *obj, Elm_List_Item *after, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) -{ - Widget_Data *wd; - Elm_List_Item *it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL); - if (!after->node) return NULL; - ELM_LIST_ITEM_CHECK_DELETED_RETURN(after, NULL); - - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - wd = elm_widget_data_get(obj); - if (!wd) return NULL; - it = _item_new(obj, label, icon, end, func, data); - wd->items = eina_list_append_relative_list(wd->items, it, after->node); - it->node = after->node->next; - elm_box_pack_after(wd->box, it->base.view, after->base.view); - return it; -} - -EAPI Elm_List_Item * -elm_list_item_sorted_insert(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data, Eina_Compare_Cb cmp_func) -{ - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - Elm_List_Item *it = _item_new(obj, label, icon, end, func, data); - Eina_List *l; - - wd->items = eina_list_sorted_insert(wd->items, cmp_func, it); - l = eina_list_data_find_list(wd->items, it); - l = eina_list_next(l); - if (!l) - { - it->node = eina_list_last(wd->items); - elm_box_pack_end(wd->box, it->base.view); - } - else - { - Elm_List_Item *before = eina_list_data_get(l); - it->node = before->node->prev; - elm_box_pack_before(wd->box, it->base.view, before->base.view); - } - return it; -} - -EAPI void -elm_list_clear(Evas_Object *obj) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - Elm_List_Item *it; - - if (!wd) return; - if (!wd->items) return; - - eina_list_free(wd->selected); - wd->selected = NULL; - - if (wd->walking > 0) - { - Eina_List *n; - - EINA_LIST_FOREACH(wd->items, n, it) - { - if (it->deleted) continue; - it->deleted = EINA_TRUE; - wd->to_delete = eina_list_append(wd->to_delete, it); - } - return; - } - - evas_object_ref(obj); - _elm_list_walk(wd); - - EINA_LIST_FREE(wd->items, it) - { - elm_widget_item_pre_notify_del(it); - _elm_list_item_free(it); - } - - _elm_list_unwalk(wd); - - _fix_items(obj); - _sizing_eval(obj); - evas_object_unref(obj); -} - EAPI void elm_list_go(Evas_Object *obj) { @@ -1601,456 +1643,362 @@ elm_list_horizontal_get(const Evas_Object *obj) } EAPI void -elm_list_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select) +elm_list_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - wd->always_select = always_select; + if (mode >= ELM_OBJECT_SELECT_MODE_MAX) + return; + if (wd->select_mode != mode) + wd->select_mode = mode; } -EAPI Eina_Bool -elm_list_always_select_mode_get(const Evas_Object *obj) +EAPI Elm_Object_Select_Mode +elm_list_select_mode_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - return wd->always_select; + if (!wd) return ELM_OBJECT_SELECT_MODE_MAX; + return wd->select_mode; } -EAPI const Eina_List * -elm_list_items_get(const Evas_Object *obj) +EAPI void +elm_list_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; + ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - return wd->items; + if (!wd) return; + if (wd->scr) + elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce); } -EAPI Elm_List_Item * -elm_list_selected_item_get(const Evas_Object *obj) +EAPI void +elm_list_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; + ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - if (wd->selected) return wd->selected->data; - return NULL; + if (!wd) return; + elm_smart_scroller_bounce_allow_get(wd->scr, h_bounce, v_bounce); } -EAPI const Eina_List * -elm_list_selected_items_get(const Evas_Object *obj) +EAPI void +elm_list_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; + ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - return wd->selected; + if ((!wd) || (!wd->scr)) return; + if ((policy_h >= ELM_SCROLLER_POLICY_LAST) || + (policy_v >= ELM_SCROLLER_POLICY_LAST)) + return; + elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v); } EAPI void -elm_list_item_separator_set(Elm_List_Item *it, Eina_Bool setting) +elm_list_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - it->is_separator = !!setting; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + Elm_Smart_Scroller_Policy s_policy_h, s_policy_v; + if ((!wd) || (!wd->scr)) return; + elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v); + if (policy_h) *policy_h = (Elm_Scroller_Policy) s_policy_h; + if (policy_v) *policy_v = (Elm_Scroller_Policy) s_policy_v; } -EAPI Eina_Bool -elm_list_item_separator_get(const Elm_List_Item *it) +EAPI void +elm_list_clear(Evas_Object *obj) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, EINA_FALSE); - return it->is_separator; -} - - -EAPI void -elm_list_item_selected_set(Elm_List_Item *it, Eina_Bool selected) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - Evas_Object *obj = it->base.widget; + ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); + Elm_List_Item *it; + if (!wd) return; + if (!wd->items) return; - selected = !!selected; - if (it->selected == selected) return; + eina_list_free(wd->selected); + wd->selected = NULL; + + if (wd->walking > 0) + { + Eina_List *n; + + EINA_LIST_FOREACH(wd->items, n, it) + { + if (it->deleted) continue; + it->deleted = EINA_TRUE; + wd->to_delete = eina_list_append(wd->to_delete, it); + } + return; + } evas_object_ref(obj); _elm_list_walk(wd); - if (selected) + EINA_LIST_FREE(wd->items, it) { - if (!wd->multi) - { - while (wd->selected) - _item_unselect(wd->selected->data); - } - _item_hilight(it); - _item_select(it); + _elm_list_item_free(it); + elm_widget_item_free(it); } - else - _item_unselect(it); _elm_list_unwalk(wd); + + _fix_items(obj); + _sizing_eval(obj); evas_object_unref(obj); } -EAPI Eina_Bool -elm_list_item_selected_get(const Elm_List_Item *it) +EAPI const Eina_List * +elm_list_items_get(const Evas_Object *obj) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, EINA_FALSE); - return it->selected; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->items; } -EAPI void -elm_list_item_show(Elm_List_Item *it) +EAPI Elm_Object_Item * +elm_list_selected_item_get(const Evas_Object *obj) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - Widget_Data *wd = elm_widget_data_get(it->base.widget); - Evas_Coord bx, by, bw, bh; - Evas_Coord x, y, w, h; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (wd->selected) return (Elm_Object_Item *) wd->selected->data; + return NULL; +} - evas_object_geometry_get(wd->box, &bx, &by, &bw, &bh); - evas_object_geometry_get(it->base.view, &x, &y, &w, &h); - x -= bx; - y -= by; - if (wd->scr) - elm_smart_scroller_child_region_show(wd->scr, x, y, w, h); +EAPI const Eina_List * +elm_list_selected_items_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->selected; } -EAPI void -elm_list_item_bring_in(Elm_List_Item *it) +EAPI Elm_Object_Item * +elm_list_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - Widget_Data *wd = elm_widget_data_get(it->base.widget); - Evas_Coord bx, by, bw, bh; - Evas_Coord x, y, w, h; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + Elm_List_Item *it = _item_new(obj, label, icon, end, func, data); - evas_object_geometry_get(wd->box, &bx, &by, &bw, &bh); - evas_object_geometry_get(it->base.view, &x, &y, &w, &h); - x -= bx; - y -= by; - if (wd->scr) - elm_smart_scroller_region_bring_in(wd->scr, x, y, w, h); + wd->items = eina_list_append(wd->items, it); + it->node = eina_list_last(wd->items); + elm_box_pack_end(wd->box, VIEW(it)); + return (Elm_Object_Item *)it; } -EAPI void -elm_list_item_del(Elm_List_Item *it) +EAPI Elm_Object_Item * +elm_list_item_prepend(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - Evas_Object *obj = it->base.widget; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; + Elm_List_Item *it = _item_new(obj, label, icon, end, func, data); - if (it->selected) _item_unselect(it); + wd->items = eina_list_prepend(wd->items, it); + it->node = wd->items; + elm_box_pack_start(wd->box, VIEW(it)); + return (Elm_Object_Item *)it; +} - if (wd->walking > 0) - { - if (it->deleted) return; - it->deleted = EINA_TRUE; - wd->to_delete = eina_list_append(wd->to_delete, it); - return; - } +EAPI Elm_Object_Item * +elm_list_item_insert_before(Evas_Object *obj, Elm_Object_Item *before, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + ELM_LIST_ITEM_CHECK_DELETED_RETURN(before, NULL); - wd->items = eina_list_remove_list(wd->items, it->node); + Widget_Data *wd; + Elm_List_Item *it, *before_it; - evas_object_ref(obj); - _elm_list_walk(wd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; - elm_widget_item_pre_notify_del(it); - _elm_list_item_free(it); + before_it = (Elm_List_Item *) before; + if (!before_it->node) return NULL; - _elm_list_unwalk(wd); - evas_object_unref(obj); + it = _item_new(obj, label, icon, end, func, data); + wd->items = eina_list_prepend_relative_list(wd->items, it, before_it->node); + it->node = before_it->node->prev; + elm_box_pack_before(wd->box, VIEW(it), VIEW(before_it)); + return (Elm_Object_Item *)it; } -EAPI void -elm_list_item_del_cb_set(Elm_List_Item *it, Evas_Smart_Cb func) +EAPI Elm_Object_Item * +elm_list_item_insert_after(Evas_Object *obj, Elm_Object_Item *after, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - elm_widget_item_del_cb_set(it, func); -} + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + ELM_LIST_ITEM_CHECK_DELETED_RETURN(after, NULL); -EAPI void * -elm_list_item_data_get(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); - return elm_widget_item_data_get(it); -} + Widget_Data *wd; + Elm_List_Item *it, *after_it; -EAPI Evas_Object * -elm_list_item_icon_get(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); - if (it->dummy_icon) return NULL; - return it->icon; -} + wd = elm_widget_data_get(obj); + if (!wd) return NULL; -EAPI void -elm_list_item_icon_set(Elm_List_Item *it, Evas_Object *icon) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - if (it->icon == icon) return; - if ((it->dummy_icon) && (!icon)) return; - if (it->dummy_icon) - { - evas_object_del(it->icon); - it->dummy_icon = EINA_FALSE; - } - if (!icon) - { - icon = evas_object_rectangle_add(evas_object_evas_get(it->base.widget)); - evas_object_color_set(icon, 0, 0, 0, 0); - it->dummy_icon = EINA_TRUE; - } - if (it->icon) - { - evas_object_del(it->icon); - it->icon = NULL; - } - it->icon = icon; - if (it->base.view) - edje_object_part_swallow(it->base.view, "elm.swallow.icon", icon); -} + after_it = (Elm_List_Item *) after; + if (!after_it->node) return NULL; -EAPI Evas_Object * -elm_list_item_end_get(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); - if (it->dummy_end) return NULL; - return it->end; + it = _item_new(obj, label, icon, end, func, data); + wd->items = eina_list_append_relative_list(wd->items, it, after_it->node); + it->node = after_it->node->next; + elm_box_pack_after(wd->box, VIEW(it), VIEW(after_it)); + return (Elm_Object_Item *)it; } -EAPI void -elm_list_item_end_set(Elm_List_Item *it, Evas_Object *end) +EAPI Elm_Object_Item * +elm_list_item_sorted_insert(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data, Eina_Compare_Cb cmp_func) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - if (it->end == end) return; - if ((it->dummy_end) && (!end)) return; - if (it->dummy_end) - { - evas_object_del(it->end); - it->dummy_icon = EINA_FALSE; - } - if (!end) + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + Elm_List_Item *it = _item_new(obj, label, icon, end, func, data); + Eina_List *l; + + wd->items = eina_list_sorted_insert(wd->items, cmp_func, it); + l = eina_list_data_find_list(wd->items, it); + l = eina_list_next(l); + if (!l) { - end = evas_object_rectangle_add(evas_object_evas_get(it->base.widget)); - evas_object_color_set(end, 0, 0, 0, 0); - it->dummy_end = EINA_TRUE; + it->node = eina_list_last(wd->items); + elm_box_pack_end(wd->box, VIEW(it)); } - if (it->end) + else { - evas_object_del(it->end); - it->end = NULL; + Elm_List_Item *before = eina_list_data_get(l); + it->node = before->node->prev; + elm_box_pack_before(wd->box, VIEW(it), VIEW(before)); } - it->end = end; - if (it->base.view) - edje_object_part_swallow(it->base.view, "elm.swallow.end", end); -} - -EAPI Evas_Object * -elm_list_item_base_get(const Elm_List_Item *it) -{ - return elm_list_item_object_get(it); -} - -EAPI Evas_Object * -elm_list_item_object_get(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); - return it->base.view; -} - -EAPI const char * -elm_list_item_label_get(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); - return it->label; + return (Elm_Object_Item *)it; } EAPI void -elm_list_item_label_set(Elm_List_Item *it, const char *text) +elm_list_item_separator_set(Elm_Object_Item *it, Eina_Bool setting) { ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - if (!eina_stringshare_replace(&it->label, text)) return; - if (it->base.view) - edje_object_part_text_set(it->base.view, "elm.text", it->label); -} - -EAPI Elm_List_Item * -elm_list_item_prev(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); - if (it->node->prev) return it->node->prev->data; - else return NULL; -} - -EAPI Elm_List_Item * -elm_list_item_next(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); - if (it->node->next) return it->node->next->data; - else return NULL; + ((Elm_List_Item *)it)->is_separator = !!setting; } -EAPI void -elm_list_item_tooltip_text_set(Elm_List_Item *item, const char *text) +EAPI Eina_Bool +elm_list_item_separator_get(const Elm_Object_Item *it) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_tooltip_text_set(item, text); + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, EINA_FALSE); + return ((Elm_List_Item *)it)->is_separator; } EAPI void -elm_list_item_tooltip_content_cb_set(Elm_List_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb) +elm_list_item_selected_set(Elm_Object_Item *it, Eina_Bool selected) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_tooltip_content_cb_set(item, func, data, del_cb); -} + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); + Evas_Object *obj = WIDGET(it); + Widget_Data *wd = elm_widget_data_get(obj); + Elm_List_Item *item = (Elm_List_Item *)it; + if (!wd) return; -EAPI void -elm_list_item_tooltip_unset(Elm_List_Item *item) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_tooltip_unset(item); -} + selected = !!selected; + if (item->selected == selected) return; -EAPI Eina_Bool -elm_list_item_tooltip_size_restrict_disable(Elm_List_Item *item, Eina_Bool disable) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item, EINA_FALSE); - return elm_widget_item_tooltip_size_restrict_disable(item, disable); -} + evas_object_ref(obj); + _elm_list_walk(wd); -EAPI Eina_Bool -elm_list_item_tooltip_size_restrict_disabled_get(const Elm_List_Item *item) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item, EINA_FALSE); - return elm_widget_item_tooltip_size_restrict_disabled_get(item); -} + if (selected) + { + if (!wd->multi) + { + while (wd->selected) + _item_unselect(wd->selected->data); + } + _item_highlight(item); + _item_select(item); + } + else + _item_unselect(item); -EAPI void -elm_list_item_tooltip_style_set(Elm_List_Item *item, const char *style) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_tooltip_style_set(item, style); + _elm_list_unwalk(wd); + evas_object_unref(obj); } -EAPI const char * -elm_list_item_tooltip_style_get(const Elm_List_Item *item) +EAPI Eina_Bool +elm_list_item_selected_get(const Elm_Object_Item *it) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item, NULL); - return elm_widget_item_tooltip_style_get(item); + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, EINA_FALSE); + return ((Elm_List_Item *)it)->selected; } EAPI void -elm_list_item_cursor_set(Elm_List_Item *item, const char *cursor) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_cursor_set(item, cursor); -} - -EAPI const char * -elm_list_item_cursor_get(const Elm_List_Item *item) +elm_list_item_show(Elm_Object_Item *it) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item, NULL); - return elm_widget_item_cursor_get(item); -} + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); + Widget_Data *wd = elm_widget_data_get(WIDGET(it)); + if (!wd) return; + Evas_Coord bx, by, bw, bh; + Evas_Coord x, y, w, h; -EAPI void -elm_list_item_cursor_unset(Elm_List_Item *item) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_cursor_unset(item); + evas_smart_objects_calculate(evas_object_evas_get(wd->box)); + evas_object_geometry_get(wd->box, &bx, &by, &bw, &bh); + evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); + x -= bx; + y -= by; + if (wd->scr) elm_smart_scroller_child_region_show(wd->scr, x, y, w, h); } EAPI void -elm_list_item_cursor_style_set(Elm_List_Item *item, const char *style) +elm_list_item_bring_in(Elm_Object_Item *it) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_cursor_style_set(item, style); -} - -EAPI const char * -elm_list_item_cursor_style_get(const Elm_List_Item *item) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item, NULL); - return elm_widget_item_cursor_style_get(item); -} + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); + Widget_Data *wd = elm_widget_data_get(WIDGET(it)); + if (!wd) return; + Evas_Coord bx, by, bw, bh; + Evas_Coord x, y, w, h; -EAPI void -elm_list_item_cursor_engine_only_set(Elm_List_Item *item, Eina_Bool engine_only) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item); - elm_widget_item_cursor_engine_only_set(item, engine_only); + evas_smart_objects_calculate(evas_object_evas_get(wd->box)); + evas_object_geometry_get(wd->box, &bx, &by, &bw, &bh); + evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); + x -= bx; + y -= by; + if (wd->scr) elm_smart_scroller_region_bring_in(wd->scr, x, y, w, h); } -EAPI Eina_Bool -elm_list_item_cursor_engine_only_get(const Elm_List_Item *item) +EAPI Evas_Object * +elm_list_item_object_get(const Elm_Object_Item *it) { - ELM_LIST_ITEM_CHECK_DELETED_RETURN(item, EINA_FALSE); - return elm_widget_item_cursor_engine_only_get(item); + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); + return VIEW(it); } -EAPI void -elm_list_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce) +EAPI Elm_Object_Item * +elm_list_item_prev(const Elm_Object_Item *it) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if (wd->scr) - elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce); + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); + Elm_List_Item *item = (Elm_List_Item *)it; + if (item->node->prev) return item->node->prev->data; + else return NULL; } -EAPI void -elm_list_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce) +EAPI Elm_Object_Item * +elm_list_item_next(const Elm_Object_Item *it) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_smart_scroller_bounce_allow_get(wd->scr, h_bounce, v_bounce); + ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL); + Elm_List_Item *item = (Elm_List_Item *)it; + if (item->node->next) return item->node->next->data; + else return NULL; } -EAPI void -elm_list_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v) +EAPI Elm_Object_Item * +elm_list_first_item_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if ((policy_h >= ELM_SCROLLER_POLICY_LAST) || - (policy_v >= ELM_SCROLLER_POLICY_LAST)) - if (wd->scr) - elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v); + if (!wd) return NULL; + if (!wd->items) return NULL; + return eina_list_data_get(wd->items); } -EAPI void -elm_list_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v) +EAPI Elm_Object_Item * +elm_list_last_item_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); - Elm_Smart_Scroller_Policy s_policy_h, s_policy_v; - if ((!wd) || (!wd->scr)) return; - elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v); - if (policy_h) *policy_h = (Elm_Scroller_Policy) s_policy_h; - if (policy_v) *policy_v = (Elm_Scroller_Policy) s_policy_v; -} - -EAPI void -elm_list_item_disabled_set(Elm_List_Item *it, Eina_Bool disabled) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it); - - if (it->disabled == disabled) - return; - - it->disabled = !!disabled; - - if (it->disabled) - edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm"); - else - edje_object_signal_emit(it->base.view, "elm,state,enabled", "elm"); -} - -EAPI Eina_Bool -elm_list_item_disabled_get(const Elm_List_Item *it) -{ - ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, EINA_FALSE); - - return it->disabled; + if (!wd) return NULL; + if (!wd->items) return NULL; + return eina_list_data_get(eina_list_last(wd->items)); }