From 00f0b4c9cc4c5ff92c4c3e7189e4864fd7a24f4e Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Tue, 17 Feb 2009 07:50:35 +0000 Subject: [PATCH] more genlist testing - deletign items works. not perfect - but working... in small tests. SVN revision: 39056 --- legacy/elementary/src/bin/test.c | 108 ++++++++++- legacy/elementary/src/lib/Elementary.h.in | 22 ++- legacy/elementary/src/lib/elm_genlist.c | 219 ++++++++++++++++++---- legacy/elementary/src/lib/elm_list.c | 11 +- 4 files changed, 316 insertions(+), 44 deletions(-) diff --git a/legacy/elementary/src/bin/test.c b/legacy/elementary/src/bin/test.c index 9bdd2c2649..3269619a4c 100644 --- a/legacy/elementary/src/bin/test.c +++ b/legacy/elementary/src/bin/test.c @@ -2076,6 +2076,12 @@ void gl_del(const void *data, Evas_Object *obj) { } +static void +gl_sel(void *data, Evas_Object *obj, void *event_info) +{ + printf("sel item data [%p] on genlist obj [%p], item pointer [%p]\n", data, obj, event_info); +} + static void my_bt_29(void *data, Evas_Object *obj, void *event_info) { @@ -2105,14 +2111,109 @@ my_bt_29(void *data, Evas_Object *obj, void *event_info) for (i = 0; i < 10000; i++) { - gli = elm_genlist_item_append(gl, &itc1, (void *)i/* item data */, - NULL/* parent */, ELM_GENLIST_ITEM_NONE, - NULL/* func */, NULL/* func data */); + gli = elm_genlist_item_append(gl, &itc1, + (void *)i/* item data */, + NULL/* parent */, + ELM_GENLIST_ITEM_NONE, + gl_sel/* func */, + (void *)(i * 10)/* func data */); } evas_object_resize(win, 320, 320); evas_object_show(win); } +static void +my_gl_add(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *gl = data; + Elm_Genlist_Item *gli; + static int i = 0; + + itc1.style = "default"; + itc1.func.label_get = gl_label_get; + itc1.func.icon_get = gl_icon_get; + itc1.func.state_get = gl_state_get; + itc1.func.del = gl_del; + + gli = elm_genlist_item_append(gl, &itc1, + (void *)i/* item data */, + NULL/* parent */, + ELM_GENLIST_ITEM_NONE, + gl_sel/* func */, + (void *)(i * 10)/* func data */); + i++; +} + +static void +my_gl_del(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *gl = data; + Elm_Genlist_Item *gli = elm_genlist_selected_item_get(gl); + if (!gli) + { + printf("no item selected\n"); + return; + } + elm_genlist_item_del(gli); +} + +static void +my_bt_30(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *win, *bg, *gl, *bx, *bx2, *bt; + int i; + + win = elm_win_add(NULL, "genlist-2", ELM_WIN_BASIC); + elm_win_title_set(win, "Genlist 2"); + elm_win_autodel_set(win, 1); + + bg = elm_bg_add(win); + elm_win_resize_object_add(win, bg); + evas_object_size_hint_weight_set(bg, 1.0, 1.0); + evas_object_show(bg); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, 1.0, 1.0); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + gl = elm_genlist_add(win); + evas_object_size_hint_align_set(gl, -1.0, -1.0); + evas_object_size_hint_weight_set(gl, 1.0, 1.0); + evas_object_show(gl); + + elm_box_pack_end(bx, gl); + evas_object_show(bx2); + + bx2 = elm_box_add(win); + elm_box_horizontal_set(bx2, 1); + elm_box_homogenous_set(bx2, 1); + evas_object_size_hint_weight_set(bx2, 1.0, 0.0); + evas_object_size_hint_align_set(bx2, -1.0, -1.0); + + bt = elm_button_add(win); + elm_button_label_set(bt, "[+]"); + evas_object_smart_callback_add(bt, "clicked", my_gl_add, gl); + evas_object_size_hint_align_set(bt, -1.0, -1.0); + evas_object_size_hint_weight_set(bt, 1.0, 0.0); + elm_box_pack_end(bx2, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_button_label_set(bt, "[-]"); + evas_object_smart_callback_add(bt, "clicked", my_gl_del, gl); + evas_object_size_hint_align_set(bt, -1.0, -1.0); + evas_object_size_hint_weight_set(bt, 1.0, 0.0); + elm_box_pack_end(bx2, bt); + evas_object_show(bt); + + elm_box_pack_end(bx, bx2); + evas_object_show(bx2); + + evas_object_resize(win, 320, 320); + evas_object_show(win); +} + static void my_win_main(void) { @@ -2217,6 +2318,7 @@ my_win_main(void) elm_list_item_append(li, "Scaling 2", NULL, NULL, my_bt_27, NULL); elm_list_item_append(li, "Slider", NULL, NULL, my_bt_28, NULL); elm_list_item_append(li, "Genlist", NULL, NULL, my_bt_29, NULL); + elm_list_item_append(li, "Genlist 2", NULL, NULL, my_bt_30, NULL); elm_list_go(li); diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index 52ef3749c0..949c6f777e 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -515,11 +515,23 @@ extern "C" { }; EAPI Evas_Object *elm_genlist_add(Evas_Object *parent); - EAPI Elm_Genlist_Item * - elm_genlist_item_append(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, - const void *data, Elm_Genlist_Item *parent, - Elm_Genlist_Item_Flags flags, - void (*func) (void *data, Evas_Object *obj, void *event_info), const void *func_data); + EAPI Elm_Genlist_Item *elm_genlist_item_append(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item_Flags flags, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *func_data); + EAPI const Elm_Genlist_Item *elm_genlist_selected_item_get(Evas_Object *obj); + EAPI const Eina_List *elm_genlist_selected_items_get(Evas_Object *obj); + EAPI const Elm_Genlist_Item *elm_genlist_first_item_get(Evas_Object *obj); + EAPI const Elm_Genlist_Item *elm_genlist_last_item_get(Evas_Object *obj); + EAPI const Elm_Genlist_Item *elm_genlist_item_next_get(Elm_Genlist_Item *item); + EAPI const Elm_Genlist_Item *elm_genlist_item_prev_get(Elm_Genlist_Item *item); + EAPI void elm_genlist_item_selected_set(Elm_Genlist_Item *item, Evas_Bool selected); + EAPI void elm_genlist_item_del(Elm_Genlist_Item *item); + EAPI const void *elm_genlist_item_data_get(Elm_Genlist_Item *item); + + /* smart callbacks called: + * "clicked" - the user clicked the hoversel button and popped up the sel + * "selected" - an item in the hoversel list is selected + * "dismissed" - the hover is dismissed + */ + /* smart callbacks called: */ diff --git a/legacy/elementary/src/lib/elm_genlist.c b/legacy/elementary/src/lib/elm_genlist.c index c6dc2dc718..f81cc76611 100644 --- a/legacy/elementary/src/lib/elm_genlist.c +++ b/legacy/elementary/src/lib/elm_genlist.c @@ -18,6 +18,9 @@ struct _Widget_Data Ecore_Job *calc_job; Ecore_Idler *queue_idler; Eina_List *queue; + Eina_List *selected; + Evas_Bool on_hold : 1; + Evas_Bool multi : 1; Evas_Bool min_w : 1; Evas_Bool min_h : 1; }; @@ -60,7 +63,6 @@ struct _Item Evas_Bool disabled : 1; Evas_Bool mincalcd : 1; Evas_Bool queued : 1; - }; struct _Pan { @@ -92,6 +94,11 @@ _del_hook(Evas_Object *obj) free(itb); } */ + // free wd->items + // free wd->blocks + if (wd->selected) eina_list_free(wd->selected); + if (wd->queue) eina_list_free(wd->queue); + if (wd->calc_job) ecore_job_del(wd->calc_job); evas_object_del(wd->pan_smart); wd->pan_smart = NULL; free(wd); @@ -103,6 +110,7 @@ _theme_hook(Evas_Object *obj) Widget_Data *wd = elm_widget_data_get(obj); elm_smart_scroller_theme_set(wd->scr, "scroller", "base", "default"); edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale); + // FIXME: redo items _sizing_eval(obj); } @@ -154,22 +162,7 @@ _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info) { _sizing_eval(data); } -/* -static void -_sub_del(void *data, Evas_Object *obj, void *event_info) -{ - Widget_Data *wd = elm_widget_data_get(obj); - Evas_Object *sub = event_info; - if (sub == wd->content) - { - elm_widget_on_show_region_hook_set(wd->content, NULL, NULL); - evas_object_event_callback_del - (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints); - wd->content = NULL; - _sizing_eval(obj); - } -} -*/ + static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info) { @@ -211,6 +204,80 @@ _stringlist_free(Eina_List *list) } } +static void +_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + Item *it = data; + Evas_Event_Mouse_Down *ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = 1; + else it->wd->on_hold = 0; + if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) + evas_object_smart_callback_call(it->wd->obj, "clicked", it); +} + +static void +_item_select(Item *it) +{ + const char *selectraise; + if (it->selected) return; + edje_object_signal_emit(it->base, "elm,state,selected", "elm"); + selectraise = edje_object_data_get(it->base, "selectraise"); + if ((selectraise) && (!strcmp(selectraise, "on"))) + evas_object_raise(it->base); + it->selected = 1; + it->wd->selected = eina_list_append(it->wd->selected, it); + if (it->func.func) it->func.func((void *)it->func.data, it->wd->obj, it); + evas_object_smart_callback_call(it->wd->obj, "selected", it); +} + +static void +_item_unselect(Item *it) +{ + const char *stacking, *selectraise; + if (!it->selected) return; + edje_object_signal_emit(it->base, "elm,state,unselected", "elm"); + stacking = edje_object_data_get(it->base, "stacking"); + selectraise = edje_object_data_get(it->base, "selectraise"); + if ((selectraise) && (!strcmp(selectraise, "on"))) + { + if ((stacking) && (!strcmp(stacking, "below"))) + evas_object_lower(it->base); + } + it->selected = 0; + it->wd->selected = eina_list_remove(it->wd->selected, it); + evas_object_smart_callback_call(it->wd->obj, "unselected", it); +} + +static void +_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + Item *it = data; + Evas_Event_Mouse_Up *ev = event_info; + Eina_List *l; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = 1; + else it->wd->on_hold = 0; + if (it->wd->on_hold) + { + it->wd->on_hold = 0; + return; + } + if (it->wd->multi) + { + if (!it->selected) _item_select(it); + else _item_unselect(it); + } + else + { + for (l = it->wd->selected; l;) + { + Item *it2 = l->data; + l = l->next; + if ((it2 != it) && (it2->selected)) _item_unselect(it2); + } + if (!it->selected) _item_select(it); + } +} + static void _item_realize(Item *it, int in, int calc) { @@ -234,11 +301,12 @@ _item_realize(Item *it, int in, int calc) if (!strcmp(stacking, "below")) evas_object_lower(it->base); else if (!strcmp(stacking, "above")) evas_object_raise(it->base); } -// FIXME: hook callbacks -// evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, -// _mouse_down, it); -// evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, -// _mouse_up, it); + evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, + _mouse_down, it); + evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, + _mouse_up, it); + if (it->selected) + edje_object_signal_emit(it->base, "elm,state,selected", "elm"); } if (it->itc->func.label_get) @@ -606,9 +674,7 @@ elm_genlist_add(Evas_Object *parent) edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &minw, &minh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj); -/* - evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); - */ + _sizing_eval(obj); return obj; } @@ -633,6 +699,44 @@ _item_new(Widget_Data *wd, const Elm_Genlist_Item_Class *itc, return it; } +static void +_item_block_del(Item *it) +{ + Eina_Inlist *il; + + it->block->items = eina_list_remove(it->block->items, it); + it->block->count--; + it->block->changed = 1; + if (it->wd->calc_job) ecore_job_del(it->wd->calc_job); + it->wd->calc_job = ecore_job_add(_calc_job, it->wd); + if (it->block->count < 1) + { + // FIXME: free block + } + for (il = (Eina_Inlist *)(it->block); il; il = il->next) + { + Item_Block *itb = (Item_Block *)il; + _item_block_unrealize(itb); + } +} + +static void +_item_del(Item *it) +{ + if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); + if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj); + if (it->realized) _item_unrealize(it); + if (it->block) _item_block_del(it); + // FIXME: del it->subblocks + // FIXME: del it->subitems + if (it->queued) + { + it->wd->queue = eina_list_remove(it->wd->queue, it); + } + it->wd->items = eina_inlist_remove(it->wd->items, (Eina_Inlist *)it); + free(it); +} + static void _item_block_add(Widget_Data *wd, Item *it, Item *itpar, Item *itrel, int before) { @@ -780,6 +884,8 @@ elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *it EAPI void elm_genlist_multi_select_set(Evas_Object *obj, Evas_Bool multi) { + Widget_Data *wd = elm_widget_data_get(obj); + wd->multi = multi; } EAPI const Eina_List * @@ -790,21 +896,66 @@ elm_genlist_items_get(Evas_Object *obj) EAPI const Elm_Genlist_Item * elm_genlist_selected_item_get(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); + if (wd->selected) return wd->selected->data; + return NULL; } EAPI const Eina_List * elm_genlist_selected_items_get(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); + return wd->selected; } -EAPI const Eina_List * -elm_genlist_item_items_get(Elm_Genlist_Item *item) +EAPI const Elm_Genlist_Item * +elm_genlist_first_item_get(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); + return (Elm_Genlist_Item *)(wd->items); +} + +EAPI const Elm_Genlist_Item * +elm_genlist_last_item_get(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd->items) return NULL; + return (Elm_Genlist_Item*)(wd->items->last); +} + +EAPI const Elm_Genlist_Item * +elm_genlist_item_next_get(Elm_Genlist_Item *item) +{ + return ((Eina_Inlist *)item)->next; +} + +EAPI const Elm_Genlist_Item * +elm_genlist_item_prev_get(Elm_Genlist_Item *item) +{ + return ((Eina_Inlist *)item)->prev; } EAPI void elm_genlist_item_selected_set(Elm_Genlist_Item *item, Evas_Bool selected) { + Item *it = (Item *)item; + Widget_Data *wd = elm_widget_data_get(it->wd->obj); + Eina_List *l; + if (selected) + { + if (!wd->multi) + { + for (l = it->wd->selected; l;) + { + Item *it2 = l->data; + l = l->next; + if ((it2 != it) && (it2->selected)) _item_unselect(it2); + } + } + if (!it->selected) _item_select(it); + } + else if (it->selected) + _item_unselect(it); } EAPI void @@ -814,28 +965,30 @@ elm_genlist_item_expanded_set(Elm_Genlist_Item *item, Evas_Bool expanded) } EAPI void -elm_genlist_item_disabld_set(Elm_Genlist_Item *item, Evas_Bool disabld) +elm_genlist_item_disabled_set(Elm_Genlist_Item *item, Evas_Bool disabled) { + // call this to set the disabled flag and update } EAPI void elm_genlist_item_show(Elm_Genlist_Item *item) { + // call this to jump to item in scroll } EAPI void elm_genlist_item_del(Elm_Genlist_Item *item) { + Item *it = (Item *)item; + if (!it) return; + _item_del(it); } EAPI const void * elm_genlist_item_data_get(Elm_Genlist_Item *item) { -} - -EAPI const Evas_Object * -elm_genlist_item_icon_get(Elm_Genlist_Item *item) -{ + Item *it = (Item *)item; + return it->data; } EAPI void diff --git a/legacy/elementary/src/lib/elm_list.c b/legacy/elementary/src/lib/elm_list.c index ecd0da4716..5cd7de2426 100644 --- a/legacy/elementary/src/lib/elm_list.c +++ b/legacy/elementary/src/lib/elm_list.c @@ -180,9 +180,10 @@ _mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info) } else { - for (l = wd->items; l; l = l->next) + for (l = wd->selected; l;) { Item *it2 = l->data; + l = l->next; if ((it2 != it) && (it2->selected)) _item_unselect(it2); } if (!it->selected) _item_select(it); @@ -468,8 +469,12 @@ elm_list_item_selected_set(Elm_List_Item *item, Evas_Bool selected) { if (!wd->multi) { - Item *it2 = l->data; - if ((it2 != it) && (it2->selected)) _item_unselect(it2); + for (l = it->selected; l;) + { + Item *it2 = l->data; + l = l->next; + if ((it2 != it) && (it2->selected)) _item_unselect(it2); + } } if (!it->selected) _item_select(it); }