From: Daniel Juyung Seo Date: Mon, 8 Nov 2010 10:06:01 +0000 (+0900) Subject: [elm_genlist.c] Refactoring. X-Git-Tag: sbs-working-i386~37^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0dd3ea82627e0b12f15508c48f1d06e5fcccf48f;p=framework%2Fuifw%2Felementary.git [elm_genlist.c] Refactoring. + Synchronize with SVN code for indentation and some other stuffs. --- diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c index 9226c10..f440e90 100644 --- a/src/lib/elm_genlist.c +++ b/src/lib/elm_genlist.c @@ -2,11 +2,13 @@ #include "elm_priv.h" #include "els_scroller.h" +#define SWIPE_MOVES 12 + /** * @defgroup Genlist Genlist * @ingroup Elementary * - * The aim was to have more expansive list that the simple list in + * The Aim was to have more expansive list that the simple list in * Elementary that could have more flexible items and allow many more entries * while still being fast and low on memory usage. At the same time it was * also made to be able to do tree structures. But the price to pay is more @@ -52,6 +54,10 @@ * not use the object pointer from elm_genlist_item_object_get() in a way * where it may point to freed objects. * + * unrealized - This is called just before an item is unrealized. After + * this call icon objects provideed will be deleted and the item object + * itself delete or be put into a floating cache. + * * drag,start,up - This is called when the item in the list has been dragged * (not scrolled) up. * @@ -271,12 +277,12 @@ typedef enum _Elm_Genlist_Item_Pinchzoom_effect_Mode struct _Widget_Data { Evas_Object *obj, *scr, *pan_smart; - Eina_Inlist *items, *blocks, *group_items; + Eina_Inlist *items, *blocks; Pan *pan; Evas_Coord pan_x, pan_y, minw, minh; Ecore_Job *calc_job, *update_job; Ecore_Idler *queue_idler; - Eina_List *queue, *selected, *menuopened; + Eina_List *queue, *selected; Elm_Genlist_Item *show_item; Elm_List_Mode mode; Eina_Bool on_hold : 1; @@ -294,6 +300,8 @@ struct _Widget_Data int item_height; int max_items_per_block; double longpress_timeout; + Eina_Inlist *group_items; + Eina_List *menuopened; int edit_mode; int select_all_minh; Eina_Bool animate_edit_controls :1; @@ -365,22 +373,22 @@ struct _Elm_Genlist_Item const void *data; Elm_Genlist_Item *parent; Elm_Genlist_Item_Flags flags; - Elm_Genlist_GroupItem *group_item; - struct - { - Evas_Smart_Cb func; - const void *data; - } func; + struct { + Evas_Smart_Cb func; + const void *data; + } func; - Evas_Object *base, *spacer, *edit_obj; - Eina_List *labels, *icons, *states, *icon_objs, *edit_icon_objs; - Ecore_Timer *long_timer, *edit_long_timer; + Evas_Object *spacer, *base; + Eina_List *labels, *icons, *states, *icon_objs; + Ecore_Timer *long_timer; Evas_Coord dx, dy, scrl_x, scrl_y; Evas_Coord reoder_cavas_x, reoder_cavas_y; Elm_Genlist_Item *rel; int relcount; int walking; + int expanded_depth; + Eina_Bool before : 1; Eina_Bool want_unrealize : 1; @@ -388,18 +396,17 @@ struct _Elm_Genlist_Item Eina_Bool selected : 1; Eina_Bool hilighted : 1; Eina_Bool expanded : 1; - int expanded_depth; Eina_Bool disabled : 1; Eina_Bool display_only : 1; Eina_Bool mincalcd : 1; Eina_Bool queued : 1; Eina_Bool showme : 1; Eina_Bool delete_me : 1; - Eina_Bool delete_check : 1; - Eina_Bool del_confirm_state : 1; Eina_Bool down : 1; Eina_Bool dragging : 1; Eina_Bool updateme : 1; + Eina_Bool delete_check : 1; + Eina_Bool del_confirm_state : 1; Eina_Bool reordering : 1; Eina_Bool menuopened : 1; Eina_Bool select_all_item : 1; @@ -412,6 +419,10 @@ struct _Elm_Genlist_Item Evas_Coord old_pad_left; int list_expanded; Eina_Bool effect_done : 1; + Elm_Genlist_GroupItem *group_item; + Evas_Object *edit_obj; + Eina_List *edit_icon_objs; + Ecore_Timer *edit_long_timer; }; #define ELM_GENLIST_ITEM_FROM_INLIST(item) \ @@ -468,6 +479,12 @@ static Eina_Bool _item_moving_effect_timer_cb(void *data); static Eina_Bool _edit_mode_item_moving_effect_cb(void *data); static int _item_flip_effect_show(void *data); static void _elm_genlist_pinch_zoom_execute(Evas_Object *obj, Eina_Bool emode); +static void _delete_confirm_cb(void *data, Evas_Object *obj, void *event_info); +static void _select_all_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__); +static void _notify_item_position( Elm_Genlist_Item *it ); +static int _get_space_for_reorder_item( Elm_Genlist_Item *it ); +static void _notify_item_position( Elm_Genlist_Item *it ); +static int _get_space_for_reorder_item( Elm_Genlist_Item *it ); static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION; @@ -506,14 +523,14 @@ _theme_hook(Evas_Object *obj) } EINA_INLIST_FOREACH(wd->blocks, itb) { - Eina_List *l; - Elm_Genlist_Item *it; - - if (itb->realized) _item_block_unrealize(itb); - EINA_LIST_FOREACH(itb->items, l, it) - it->mincalcd = EINA_FALSE; + Eina_List *l; + Elm_Genlist_Item *it; - itb->changed = EINA_TRUE; + if (itb->realized) _item_block_unrealize(itb); + EINA_LIST_FOREACH(itb->items, l, it) + it->mincalcd = EINA_FALSE; + + itb->changed = EINA_TRUE; } if (wd->calc_job) ecore_job_del(wd->calc_job); wd->calc_job = ecore_job_add(_calc_job, wd); @@ -545,7 +562,7 @@ _sizing_eval(Evas_Object *obj) else { Evas_Coord vmw, vmh, vw, vh; - + minw = wd->minw; maxw = -1; elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh); @@ -591,54 +608,54 @@ _item_block_del(Elm_Genlist_Item *it) it->wd->calc_job = ecore_job_add(_calc_job, it->wd); if (itb->count < 1) { - il = EINA_INLIST_GET(itb); - Item_Block *itbn = (Item_Block *)(il->next); - if (it->parent) - it->parent->items = eina_list_remove(it->parent->items, it); - else - it->wd->blocks = eina_inlist_remove(it->wd->blocks, il); - free(itb); - if (itbn) itbn->changed = EINA_TRUE; + il = EINA_INLIST_GET(itb); + Item_Block *itbn = (Item_Block *)(il->next); + if (it->parent) + it->parent->items = eina_list_remove(it->parent->items, it); + else + it->wd->blocks = eina_inlist_remove(it->wd->blocks, il); + free(itb); + if (itbn) itbn->changed = EINA_TRUE; } else { - if (itb->count < 16) - { - il = EINA_INLIST_GET(itb); - Item_Block *itbp = (Item_Block *)(il->prev); - Item_Block *itbn = (Item_Block *)(il->next); - if ((itbp) && ((itbp->count + itb->count) < 48)) - { - Elm_Genlist_Item *it2; + if (itb->count < 16) + { + il = EINA_INLIST_GET(itb); + Item_Block *itbp = (Item_Block *)(il->prev); + Item_Block *itbn = (Item_Block *)(il->next); + if ((itbp) && ((itbp->count + itb->count) < 48)) + { + Elm_Genlist_Item *it2; - EINA_LIST_FREE(itb->items, it2) - { - it2->block = itbp; - itbp->items = eina_list_append(itbp->items, it2); - itbp->count++; - itbp->changed = EINA_TRUE; - } - it->wd->blocks = eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb)); - free(itb); - } - else if ((itbn) && ((itbn->count + itb->count) < 48)) - { - while (itb->items) - { - Eina_List *last = eina_list_last(itb->items); - Elm_Genlist_Item *it2 = last->data; - - it2->block = itbn; - itb->items = eina_list_remove_list(itb->items, last); - itbn->items = eina_list_prepend(itbn->items, it2); - itbn->count++; - itbn->changed = EINA_TRUE; - } - it->wd->blocks = - eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb)); - free(itb); - } - } + EINA_LIST_FREE(itb->items, it2) + { + it2->block = itbp; + itbp->items = eina_list_append(itbp->items, it2); + itbp->count++; + itbp->changed = EINA_TRUE; + } + it->wd->blocks = eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb)); + free(itb); + } + else if ((itbn) && ((itbn->count + itb->count) < 48)) + { + while (itb->items) + { + Eina_List *last = eina_list_last(itb->items); + Elm_Genlist_Item *it2 = last->data; + + it2->block = itbn; + itb->items = eina_list_remove_list(itb->items, last); + itbn->items = eina_list_prepend(itbn->items, it2); + itbn->count++; + itbn->changed = EINA_TRUE; + } + it->wd->blocks = + eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb)); + free(itb); + } + } } } @@ -673,8 +690,8 @@ _item_select(Elm_Genlist_Item *it) if ((it->wd->no_select) || (it->delete_me) || (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)) return; if (it->selected) { - if (it->wd->always_select) goto call; - return; + if (it->wd->always_select) goto call; + return; } it->selected = EINA_TRUE; it->wd->selected = eina_list_append(it->wd->selected, it); @@ -771,12 +788,12 @@ _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_inf if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) { - if (!it->wd->on_hold) - { - it->wd->on_hold = EINA_TRUE; + if (!it->wd->on_hold) + { + it->wd->on_hold = EINA_TRUE; if (!it->wd->wasselected) - _item_unselect(it); - } + _item_unselect(it); + } } if ((it->dragging) && (it->down)) { @@ -1221,15 +1238,15 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void * } if (it->dragging) { - it->dragging = 0; + it->dragging = 0; evas_object_smart_callback_call(it->wd->obj, "drag,stop", it); - dragged = 1; + dragged = 1; } if (it->wd->on_hold) { it->wd->longpressed = EINA_FALSE; - it->wd->on_hold = EINA_FALSE; - return; + it->wd->on_hold = EINA_FALSE; + return; } if (it->wd->longpressed) { @@ -1252,32 +1269,32 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void * if (it->wd->multi) { if (!it->selected && !it->menuopened) - { - _item_hilight(it); - _item_select(it); - } - else _item_unselect(it); + { + _item_hilight(it); + _item_select(it); + } + else _item_unselect(it); } else { - if (!it->selected) - { - Widget_Data *wd = it->wd; + if (!it->selected) + { + Widget_Data *wd = it->wd; if (wd) { while (wd->selected) _item_unselect(wd->selected->data); } - } - else - { - const Eina_List *l, *l_next; - Elm_Genlist_Item *it2; + } + else + { + const Eina_List *l, *l_next; + Elm_Genlist_Item *it2; - EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2) - if (it2 != it) _item_unselect(it2); -// _item_hilight(it); -// _item_select(it); - } + EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2) + if (it2 != it) _item_unselect(it2); + //_item_hilight(it); + //_item_select(it); + } if (!it->menuopened) { _item_hilight(it); @@ -1563,19 +1580,20 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc) edje_object_signal_emit(it->base, "elm,state,expanded", "elm"); } - if (calc && it->wd->homogeneous && it->wd->item_width) + if ((calc) && (it->wd->homogeneous) && (it->wd->item_width)) { - /* homogenous genlist shortcut */ - if (!it->mincalcd) - { - it->w = it->minw = it->wd->item_width; - it->h = it->minh = it->wd->item_height; - it->mincalcd = EINA_TRUE; - } + /* homogenous genlist shortcut */ + if (!it->mincalcd) + { + it->w = it->minw = it->wd->item_width; + it->h = it->minh = it->wd->item_height; + it->mincalcd = EINA_TRUE; + } } else { - if(!strcmp(it->itc->item_style, "select_all")) { + if(!strcmp(it->itc->item_style, "select_all")) + { const Eina_List *l; const char *key; @@ -1585,80 +1603,91 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc) } } - if (it->itc->func.label_get) - { - const Eina_List *l; - const char *key; + if (it->itc->func.label_get) + { + const Eina_List *l; + const char *key; - it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels")); - EINA_LIST_FOREACH(it->labels, l, key) - { - char *s = it->itc->func.label_get(it->data, it->wd->obj, l->data); + it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels")); + EINA_LIST_FOREACH(it->labels, l, key) + { + char *s = it->itc->func.label_get + ((void *)it->data, it->wd->obj, l->data); - if (s) - { - edje_object_part_text_set(it->base, l->data, s); - free(s); - } - } - } - if (it->itc->func.icon_get) - { - const Eina_List *l; - const char *key; + if (s) + { + edje_object_part_text_set(it->base, l->data, s); + free(s); + } +/* else if (itc) + edje_object_part_text_set(it->base, l->data, "");*/ + } + } + if (it->itc->func.icon_get) + { + const Eina_List *l; + const char *key; - it->icons = _elm_stringlist_get(edje_object_data_get(it->base, "icons")); - EINA_LIST_FOREACH(it->icons, l, key) - { - Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data); + it->icons = _elm_stringlist_get(edje_object_data_get(it->base, "icons")); + EINA_LIST_FOREACH(it->icons, l, key) + { + Evas_Object *ic = it->itc->func.icon_get + ((void *)it->data, it->wd->obj, l->data); - if (ic) - { - it->icon_objs = eina_list_append(it->icon_objs, ic); - edje_object_part_swallow(it->base, key, ic); - evas_object_show(ic); - elm_widget_sub_object_add(it->wd->obj, ic); - } - } - } - if (it->itc->func.state_get) - { - const Eina_List *l; - const char *key; + if (ic) + { + it->icon_objs = eina_list_append(it->icon_objs, ic); + edje_object_part_swallow(it->base, key, ic); + evas_object_show(ic); + elm_widget_sub_object_add(it->wd->obj, ic); + } + } + } + if (it->itc->func.state_get) + { + const Eina_List *l; + const char *key; it->states = _elm_stringlist_get(edje_object_data_get(it->base, "states")); - EINA_LIST_FOREACH(it->states, l, key) - { - Eina_Bool on = it->itc->func.state_get(it->data, it->wd->obj, l->data); + EINA_LIST_FOREACH(it->states, l, key) + { + Eina_Bool on = it->itc->func.state_get + (it->data, it->wd->obj, l->data); + + if (on) + { + snprintf(buf, sizeof(buf), "elm,state,%s,active", key); + edje_object_signal_emit(it->base, buf, "elm"); + } +/* else if (itc) + { + snprintf(buf, sizeof(buf), "elm,state,%s,passive", key); + edje_object_signal_emit(it->base, buf, "elm"); + }*/ + } + } + if (!it->mincalcd) + { + Evas_Coord mw = -1, mh = -1; - if (on) - { - snprintf(buf, sizeof(buf), "elm,state,%s,active", key); - edje_object_signal_emit(it->base, buf, "elm"); - } - } - } - if (!it->mincalcd) - { - Evas_Coord mw = -1, mh = -1; - if (!it->display_only) - elm_coords_finger_size_adjust(1, &mw, 1, &mh); - edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh); + elm_coords_finger_size_adjust(1, &mw, 1, &mh); + edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh); if (!it->display_only) - elm_coords_finger_size_adjust(1, &mw, 1, &mh); - it->w = it->minw = mw; - it->h = it->minh = mh; - it->mincalcd = EINA_TRUE; + elm_coords_finger_size_adjust(1, &mw, 1, &mh); + it->w = it->minw = mw; + it->h = it->minh = mh; + it->mincalcd = EINA_TRUE; - if (!in && it->wd->homogeneous) - { - it->wd->item_width = mw; - it->wd->item_height = mh; - } - } - if (!calc) evas_object_show(it->base); + if ((!in) && (it->wd->homogeneous)) + { + it->wd->item_width = mw; + it->wd->item_height = mh; + } + } + if (!calc) evas_object_show(it->base); } + it->realized = EINA_TRUE; it->want_unrealize = EINA_FALSE; if(it->group_item) @@ -1698,8 +1727,8 @@ _item_unrealize(Elm_Genlist_Item *it) it->icons = NULL; _elm_stringlist_free(it->states); - EINA_LIST_FREE(it->icon_objs, icon) - evas_object_del(icon); + EINA_LIST_FREE(it->icon_objs, icon) + evas_object_del(icon); EINA_LIST_FREE(it->edit_icon_objs, icon) evas_object_del(icon); @@ -1714,18 +1743,18 @@ _item_block_recalc(Item_Block *itb, int in, int qadd, int norender) { const Eina_List *l; Elm_Genlist_Item *it; - Elm_Genlist_GroupItem *git = NULL; Evas_Coord minw = 0, minh = 0; int showme = 0, changed = 0; Evas_Coord y = 0; - + Elm_Genlist_GroupItem *git = NULL; + itb->num = in; EINA_LIST_FOREACH(itb->items, l, it) { - if (it->delete_me) continue; - showme |= it->showme; - if (!itb->realized) - { + if (it->delete_me) continue; + showme |= it->showme; + if (!itb->realized) + { if (qadd) { if (!it->mincalcd) changed = 1; @@ -1749,12 +1778,12 @@ _item_block_recalc(Item_Block *itb, int in, int qadd, int norender) if (!was_realized) evas_object_smart_callback_call(it->wd->obj, "realized", it); } - minh += it->minh; - if (minw < it->minw) minw = it->minw; - in++; - it->x = 0; - it->y = y; - y += it->h; + minh += it->minh; + if (minw < it->minw) minw = it->minw; + in++; + it->x = 0; + it->y = y; + y += it->h; if( git != it->group_item ) { git = it->group_item; @@ -1784,7 +1813,7 @@ _item_block_realize(Item_Block *itb, int in, int full) if (itb->realized) return; EINA_LIST_FOREACH(itb->items, l, it) { - if (it->delete_me) continue; + if (it->delete_me) continue; if (full) { Eina_Bool was_realized = it->realized; @@ -1793,7 +1822,7 @@ _item_block_realize(Item_Block *itb, int in, int full) if (!was_realized) evas_object_smart_callback_call(it->wd->obj, "realized", it); } - in++; + in++; } itb->realized = EINA_TRUE; itb->want_unrealize = EINA_FALSE; @@ -1827,2442 +1856,2091 @@ _item_block_unrealize(Item_Block *itb) } static void -_delete_confirm_cb(void *data, Evas_Object *obj, void *event_info) +_item_block_position(Item_Block *itb, int in) { - Widget_Data *wd = data; - evas_object_hide( wd->ed->del_confirm ); - if( wd->ed->ec && wd->ed->ec->remove ) - wd->ed->ec->remove(wd->obj, wd->ed->del_item); - wd->ed->del_item = NULL; -} + const Eina_List *l; + Elm_Genlist_Item *it; + Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh; + int vis=0; + int is_reorder = 0; + Elm_Genlist_GroupItem *git = NULL; + Elm_Genlist_Item *select_all_item; -static void -_hide_delete_confirm_object (void *data, Evas_Object *obj, const char *emission, const char *source) -{ - const char *del_icon_part; - Elm_Genlist_Item *it = data; - del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm"); - if (del_icon_part) - edje_object_part_unswallow( it->edit_obj, it->wd->ed->del_confirm ); + evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh); + evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy, &cvw, &cvh); - evas_object_hide( it->wd->ed->del_confirm ); -} + if (itb->wd->select_all_item && + (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) ) + { -static void -_remove_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source) -{ - const char *del_conf_style; - Elm_Genlist_Item *it = data; - if(_edit_mode_reset( it->wd )) - return; + select_all_item = itb->wd->select_all_item; - if (it->edit_long_timer) - { - ecore_timer_del(it->edit_long_timer); - it->edit_long_timer = NULL; - } - - if( it->del_confirm_state ) - { - it->del_confirm_state = 0; - it->delete_check = 0; - edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm"); - it->wd->selct_all = 0; - if(it->wd->select_all_item) - edje_object_signal_emit(it->wd->select_all_item->base, "elm,state,del,animated,enable", "elm"); + evas_object_resize(select_all_item->base, itb->w, select_all_item->h); + evas_object_move(select_all_item->base, ox, oy); + evas_object_raise(select_all_item->base); - if (!it->wd->selct_all && it->wd->ed->ec->item_selected) - { - it->wd->ed->ec->item_selected(it->data, it, it->delete_check); + if ( itb->wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE ) + evas_object_show(select_all_item->base); + else + evas_object_hide(select_all_item->base); + y = select_all_item->h; } - return; - } - - it->del_confirm_state = 1; - it->delete_check = 1; - - it->wd->ed->del_item = it; - if (!it->wd->selct_all && it->wd->ed->ec->item_selected) - { - it->wd->ed->ec->item_selected(it->data, it, it->delete_check); - } + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->delete_me) continue; + it->x = 0; + it->y = y; + it->w = itb->w; + vis = (ELM_RECTS_INTERSECT(itb->x - it->wd->pan_x + ox, + itb->y - it->wd->pan_y + oy, + itb->w, itb->h, + cvx, cvy, cvw, cvh)); + if ((itb->realized) && (!it->realized)) + { + if (vis) + { + Eina_Bool was_realized = it->realized; - del_conf_style = edje_object_data_get(it->edit_obj, "del_button_style"); - if(del_conf_style ) - elm_object_style_set( it->wd->ed->del_confirm, del_conf_style); + _item_realize(it, in, 0); + if (!was_realized) + evas_object_smart_callback_call(it->wd->obj, + "realized", it); + } + } + if (it->realized) + { + _notify_item_position( it ); + if (vis) + { + it->scrl_x = ox + itb->x + it->x - itb->wd->pan_x; + it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y;; + if( git != it->group_item ) + { + git = it->group_item; + if (git) + { + git->visible = EINA_TRUE; //Mark Group Item to make it visible + if (git->items->data == it) + git->y = it->scrl_y; + if (GROUP_ALIGN_NORTH == git->align) + { + git->w = itb->w; + if (git->items->data == it) + { + it->scrl_y += git->minh; + y += git->minh; + } + } + } + } + if (git) + { + git->x = ox + itb->x - itb->wd->pan_x; -/* - del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm"); - if (del_icon_part) - edje_object_part_swallow(it->edit_obj, del_icon_part, it->wd->ed->del_confirm); - evas_object_show( it->wd->ed->del_confirm ); -*/ - edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm"); -} + if (git->y < oy) + git->y = oy; -static void -_insert_new_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source) -{ - Elm_Genlist_Item *it = data; + if (git->align == GROUP_ALIGN_WEST) + { + it->w -= git->w; + it->scrl_x += git->x + git->w; + git->h = (it->scrl_y + it->h) - git->y ; + if( git->h < it->h ) + { + git->y = it->scrl_y; + git->h = it->h; + } + } + if (git->align == GROUP_ALIGN_NORTH) + { + git->h = git->minh; + if ((git->y + git->h) > (it->scrl_y + it->h)) + git->y = (it->scrl_y + it->h) - git->minh; + } + if(git->update_finish_y) + { + git->finish_y += oy; + git->update_finish_y = EINA_FALSE; + } - if(_edit_mode_reset( it->wd )) - return; + } - if( it->wd->ed->ec && it->wd->ed->ec->insert_new ) - it->wd->ed->ec->insert_new(it->wd->obj, it); -} + is_reorder = _get_space_for_reorder_item( it ); -static Eina_Bool -_edit_mode_reset(Widget_Data *wd) -{ - /* - if(wd->ed->del_confirm_state) - { - //edje_object_signal_emit(wd->ed->del_item->edit_obj, "elm,state,delete", "elm"); - //wd->ed->del_confirm_state = 0; - //wd->ed->del_item = NULL; - return EINA_TRUE; - } - */ - return EINA_FALSE; -} + if (is_reorder) + it->reorder_check = 1; + else + it->reorder_check = 0; -static void -_reorder_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info) -{ - Elm_Genlist_Item *it = data; - Evas_Event_Mouse_Down *ev = event_info; - Evas_Coord x, y; + if (it->wd->ed) + { + if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && !itb->reoder_y) + { + itb->reoder_y -= it->h; + it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y; + } + else if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && itb->reoder_y) + { + itb->reoder_y = 0; + } + } + y += is_reorder; - if(!elm_genlist_item_next_get(it)) - return; - - if(it->wd->edit_field && !it->renamed) - elm_genlist_item_rename_mode_set(it, 0); + if (!it->reordering ) + { + if ((!it->wd->effect_mode || + (it->wd->effect_mode && it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_NONE)) && !it->wd->pinch_zoom_reserve) + { + _move_edit_controls( it,it->scrl_x, it->scrl_y ); + evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h); - if(!(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER)) - return; + evas_object_move(it->base, it->scrl_x+it->pad_left, it->scrl_y); - if(_edit_mode_reset( it->wd ) ) - return; + if (it->delete_check) + { + edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm"); + edje_object_signal_emit(it->base, "elm,state,del_confirm", "elm"); + } + evas_object_show(it->base); + it->old_pad_left = it->pad_left; + it->old_scrl_y = it->scrl_y; + } - it->dragging = 0; - it->down = 1; - - it->reoder_cavas_x = ev->canvas.x; - it->reoder_cavas_y = ev->canvas.y; + } + } + else + { + if (!it->dragging) + _item_unrealize(it); + } + } + if (!it->reordering ) + y += it->h; - evas_object_geometry_get(obj, &x, &y, NULL, NULL); - it->dx = ev->canvas.x - x; - it->dy = ev->canvas.y - y; + in++; + } - if (it->edit_long_timer) + if (itb->wd->select_all_item && + (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) ) + evas_object_raise(select_all_item->base); + + if (vis) { - ecore_timer_del(it->edit_long_timer); - it->edit_long_timer = NULL; + itb->wd->animate_edit_controls = 0; + if (git) + git->visible = EINA_TRUE; } - - if (it->realized) { - it->edit_long_timer = ecore_timer_add(0.3,_edit_long_press, it); - } - else - it->edit_long_timer = NULL; - } static void -_reorder_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info) +_calc_job(void *data) { - Elm_Genlist_Item *it = data; - - Item_Block *itb; - EINA_INLIST_FOREACH(it->wd->blocks, itb) - { - itb->reoder_y = 0; - } + Widget_Data *wd = data; + Item_Block *itb; + Evas_Coord minw = -1, minh = 0, y = 0, ow; + Item_Block *chb = NULL; + int in = 0, minw_change = 0; + Evas_Coord oh; - if (it->edit_long_timer) - { - ecore_timer_del(it->edit_long_timer); - it->edit_long_timer = NULL; - } - - it->down = 0; + if (!wd) return; + EINA_INLIST_FOREACH(wd->blocks, itb) + { + int showme = 0; - if (it->wd->ed->ec->selected) - { - it->wd->ed->ec->selected(NULL, it, 1); - } + itb->num = in; + showme = itb->showme; + itb->showme = 0; + if (chb) + { + if (itb->realized) _item_block_unrealize(itb); + } + if (itb->changed) + { + if (itb->realized) _item_block_unrealize(itb); + showme = _item_block_recalc(itb, in, 0, 1); + chb = itb; + } + itb->y = y; + itb->x = 0; + minh += itb->minh; + if (minw == -1) minw = itb->minw; + else if (minw < itb->minw) + { + minw = itb->minw; + minw_change = 1; + } + itb->w = minw; + itb->h = itb->minh; + y += itb->h; + in += itb->count; + if (showme) + { + if(wd->show_item) + { + wd->show_item->showme = 0; + if (wd->bring_in) + elm_smart_scroller_region_bring_in(wd->scr, + wd->show_item->x + wd->show_item->block->x, + wd->show_item->y + wd->show_item->block->y, + wd->show_item->block->w, + wd->show_item->h); + else + elm_smart_scroller_child_region_show(wd->scr, + wd->show_item->x + wd->show_item->block->x, + wd->show_item->y + wd->show_item->block->y, + wd->show_item->block->w, + wd->show_item->h); + wd->show_item = NULL; + } + } + } - if( it->reordering && it->wd->ed->reorder_item ) + if (minw_change) + { + EINA_INLIST_FOREACH(wd->blocks, itb) + { + itb->minw = minw; + itb->w = itb->minw; + } + } + if ((chb) && (EINA_INLIST_GET(chb)->next)) + { + EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb) + if (itb->realized) _item_block_unrealize(itb); + } + evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh); + if (minw < ow) minw = ow; + if ((minw != wd->minw) || (minh != wd->minh) || wd->select_all_item) { - it->wd->ed->reorder_item->reordering = 0; - edje_object_signal_emit(it->wd->ed->reorder_item->edit_obj, "elm,action,item,reorder_end", "elm"); - elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE); - - if( (!it->wd->ed->reorder_rel) || (!it->wd->ed->ec->move) || - (!it->wd->ed->ec->move(it->wd->obj, it->wd->ed->reorder_item, it->wd->ed->reorder_rel, EINA_TRUE ) ) ) - { - evas_object_move(it->wd->ed->reorder_item->base, it->wd->ed->reorder_item->scrl_x+it->pad_left, it->wd->ed->reorder_item->scrl_y); - _move_edit_controls( it,it->wd->ed->reorder_item->scrl_x, it->wd->ed->reorder_item->scrl_y ); - } - it->wd->ed->reorder_item = NULL; - it->wd->ed->reorder_rel = NULL; - return; + wd->minw = minw; + wd->minh = minh; + if(wd->select_all_item) + wd->minh += wd->select_all_item->h; + evas_object_smart_callback_call(wd->pan_smart, "changed", NULL); + _sizing_eval(wd->obj); } + wd->calc_job = NULL; + evas_object_smart_changed(wd->pan_smart); } static void -_reorder_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info) +_update_job(void *data) { - Elm_Genlist_Item *it = data; - Evas_Event_Mouse_Move *ev = event_info; - - if ((it->dragging) && (it->down)) + Widget_Data *wd = data; + Eina_List *l2; + Item_Block *itb; + int num, num0, position = 0, recalc = 0; + if (!wd) return; + wd->update_job = NULL; + num = 0; + EINA_INLIST_FOREACH(wd->blocks, itb) { - if (it->edit_long_timer) + Evas_Coord itminw, itminh; + Elm_Genlist_Item *it; + + if (!itb->updateme) { - ecore_timer_del(it->edit_long_timer); - it->edit_long_timer = NULL; - } - - evas_object_smart_callback_call(it->wd->obj, "drag", it); -// return; - } - - - Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady; + num += itb->count; + if (position) + _item_block_position(itb, num); + continue; + } + num0 = num; + recalc = 0; + EINA_LIST_FOREACH(itb->items, l2, it) + { + if (it->updateme) + { + itminw = it->w; + itminh = it->h; - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - evas_object_geometry_get(obj, &x, &y, NULL, NULL); - x = ev->cur.canvas.x - x; - y = ev->cur.canvas.y - y; - dx = x - it->dx; - adx = dx; - if (adx < 0) adx = -dx; - dy = y - it->dy; - ady = dy; - if (ady < 0) ady = -dy; - minw /= 2; - minh /= 2; - if ((adx > minw) || (ady > minh)) - { - it->dragging = 1; - if (it->edit_long_timer) + it->updateme = 0; + if (it->realized) + { + _item_unrealize(it); + _item_realize(it, num, 0); + evas_object_smart_callback_call(it->wd->obj, + "realized", it); + } + else + { + _item_realize(it, num, 1); + _item_unrealize(it); + } + if ((it->minw != itminw) || (it->minh != itminh)) + recalc = 1; + } + num++; + } + itb->updateme = 0; + if (recalc) { - ecore_timer_del(it->edit_long_timer); - it->edit_long_timer = NULL; + position = 1; + itb->changed = EINA_TRUE; + _item_block_recalc(itb, num0, 0, 1); + _item_block_position(itb, num0); } - } + } + if (position) + { + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); + } +} - if( it->reordering && it->wd->ed->reorder_item ) - { - int y = ev->cur.canvas.y - it->wd->ed->reorder_item->dy; - evas_object_raise(it->wd->ed->reorder_item->base); - evas_object_move(it->wd->ed->reorder_item->base, it->wd->ed->reorder_item->scrl_x+it->pad_left, y); - evas_object_show(it->wd->ed->reorder_item->base); - _move_edit_controls( it,it->wd->ed->reorder_item->scrl_x, y ); +static void +_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + Pan *sd = evas_object_smart_data_get(obj); +// Evas_Coord ow, oh; +// evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); +// ow = sd->wd->minw - ow; +// if (ow < 0) ow = 0; +// oh = sd->wd->minh - oh; +// if (oh < 0) oh = 0; +// if (x < 0) x = 0; +// if (y < 0) y = 0; +// if (x > ow) x = ow; +// if (y > oh) y = oh; + if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return; + sd->wd->pan_x = x; + sd->wd->pan_y = y; + evas_object_smart_changed(obj); +} - it->block->updateme = EINA_TRUE; +static void +_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) +{ + Pan *sd = evas_object_smart_data_get(obj); - if (it->wd->calc_job) ecore_job_del(it->wd->calc_job); - it->wd->calc_job = ecore_job_add(_calc_job, it->wd); + if (x) *x = sd->wd->pan_x; + if (y) *y = sd->wd->pan_y; + + if( sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH ) + { + int git_cnt = 0, git_h = 0; + Elm_Genlist_GroupItem *git; + + EINA_INLIST_FOREACH(sd->wd->group_items, git) + { + git_cnt++; + git_h = git->h; + } + + if( sd->wd->minh != (git_h+1) * git_cnt) + { + sd->wd->minh = (git_h+1) * git_cnt; + } + } - return; - } } static void -_select_all_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) +_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) { - Item_Block *itb; - Elm_Genlist_Item *select_all_it = data, *it; - Eina_List *l; - Widget_Data *wd = select_all_it->wd; - if (!wd) return; + Pan *sd = evas_object_smart_data_get(obj); + Evas_Coord ow, oh; - if(!wd->selct_all) - edje_object_signal_emit(select_all_it->base, "elm,state,del_confirm", "elm"); - else - edje_object_signal_emit(select_all_it->base, "elm,state,del,animated,enable", "elm"); - + evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); + ow = sd->wd->minw - ow; + if (ow < 0) ow = 0; + oh = sd->wd->minh - oh; + if (oh < 0) oh = 0; + if (x) *x = ow; + if (y) *y = oh; +} - EINA_INLIST_FOREACH(wd->blocks, itb) - { +static void +_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) +{ + Pan *sd = evas_object_smart_data_get(obj); - EINA_LIST_FOREACH(itb->items, l, it) - { + if (w) *w = sd->wd->minw; + if (h) *h = sd->wd->minh; +} - if(!wd->selct_all) - { - it->delete_check = 1; - it->del_confirm_state = 1; - edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm"); - } - else - { - it->delete_check = 0; - it->del_confirm_state = 0; - edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm"); - } - } - } +static void +_pan_add(Evas_Object *obj) +{ + Pan *sd; + Evas_Object_Smart_Clipped_Data *cd; - wd->selct_all ^= 0xFF; + _pan_sc.add(obj); + cd = evas_object_smart_data_get(obj); + sd = ELM_NEW(Pan); + if (!sd) return; + sd->__clipped_data = *cd; + free(cd); + evas_object_smart_data_set(obj, sd); +} - if (wd->ed->ec->item_selected) - { - wd->ed->ec->item_selected(select_all_it->data, select_all_it, wd->selct_all); - } +static void +_pan_del(Evas_Object *obj) +{ + Pan *sd = evas_object_smart_data_get(obj); - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); + if (!sd) return; + _pan_sc.del(obj); } static void -_move_edit_controls( Elm_Genlist_Item *it, int itx, int ity ) +_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { - if(it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE ) - return; + Pan *sd = evas_object_smart_data_get(obj); + Evas_Coord ow, oh; - evas_object_resize(it->edit_obj,it->w, it->h ); - evas_object_move(it->edit_obj, itx, ity ); - evas_object_raise( it->edit_obj ); + evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); + if ((ow == w) && (oh == h)) return; +/* don't do this... use wd->compress mode + if (sd->wd->mode == ELM_LIST_COMPRESS) + { + Item_Block *itb; + // this is nasty - but no choice. have to mark all as not mincalced. + EINA_INLIST_FOREACH(sd->wd->blocks, itb) + { + Eina_List *l; + Elm_Genlist_Item *it; + + EINA_LIST_FOREACH(itb->items, l, it) + it->mincalcd = EINA_FALSE; + + itb->changed = EINA_TRUE; + } + } + */ + if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job); + sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd); } static void -_edit_controls_eval(Elm_Genlist_Item *it) +_pan_calculate(Evas_Object *obj) { - int itmode = 0; - const char *pad_str; - int pad = 0; - it->pad_left = 0; - it->pad_right = 0; - Evas_Object *icon; - char buf[1024]; + Pan *sd = evas_object_smart_data_get(obj); + Item_Block *itb; + Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; + int in = 0; + Elm_Genlist_GroupItem *git; - if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE && !it->edit_obj) - return; + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND) return; - if (it->itc->func.editmode_get) - itmode = it->itc->func.editmode_get(it->data, it->wd->obj, it->wd->edit_mode); - itmode &= it->wd->edit_mode; + if( sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH ) + { + sd->wd->contract_pan_y = sd->wd->pan_y; + EINA_INLIST_FOREACH(sd->wd->group_items, git) + { + git->visible = EINA_TRUE; + evas_object_raise(git->base); + evas_object_resize(git->base, sd->wd->minw, git->h); + evas_object_move(git->base, git->x, git->y + sd->wd->pan_y * -1); + evas_object_show(git->base); + } + } - if (itmode & ELM_GENLIST_EDIT_MODE_SELECTALL) - itmode |= ELM_GENLIST_EDIT_MODE_SELECT; + if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return; - if (!it->edit_obj) + if (sd->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE) + (void)_edit_mode_reset(sd->wd); + EINA_INLIST_FOREACH(sd->wd->group_items, git) { - it->edit_obj = edje_object_add(evas_object_evas_get(it->wd->obj)); - edje_object_scale_set(it->edit_obj, elm_widget_scale_get(it->wd->obj) * - _elm_config->scale); - evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart); - elm_widget_sub_object_add(it->wd->obj, it->edit_obj); - if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf)); - else strncpy(buf, "item", sizeof(buf)); - if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf)); - // if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf)); - strncat(buf, "/", sizeof(buf) - strlen(buf)); - - if (it->wd->ed->ec->item_style && strcmp(it->wd->ed->ec->item_style, "default")) - { - strncat(buf, it->wd->ed->ec->item_style, sizeof(buf) - strlen(buf)); - _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", buf, elm_widget_style_get(it->wd->obj)); - } - else - { - _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", "item/edit_control", elm_widget_style_get(it->wd->obj)); - } - - // edje_object_signal_callback_add(it->edit_obj, "elm,action,edit,reset", - // "elm", _edit_mode_reset, it); - } - - pad_str = edje_object_data_get(it->edit_obj, "icon_width"); - if (pad_str) pad = atoi(pad_str); - - if ((itmode & ELM_GENLIST_EDIT_MODE_INSERT)) - { - if (it->wd->animate_edit_controls) - edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,enable", "elm"); - else - edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm"); - - edje_object_signal_callback_add(it->edit_obj, "elm,action,item,insert", - "elm", _insert_new_item_cb, it); - it->pad_left += pad * _elm_config->scale; - } - else - { - if (it->wd->animate_edit_controls) - edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,disable", "elm"); - else - edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm"); - - edje_object_signal_callback_del(it->edit_obj, "elm,action,item,insert", - "elm", _insert_new_item_cb ); + git->visible = EINA_FALSE; } - if ((itmode & ELM_GENLIST_EDIT_MODE_DELETE) || (itmode & ELM_GENLIST_EDIT_MODE_SELECT)) - { - if (it->wd->animate_edit_controls) - edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm"); - else - edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm"); - - edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete", - "elm", _remove_item_cb ); - edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm", - "elm", _hide_delete_confirm_object ); - - edje_object_signal_callback_add(it->edit_obj, "elm,action,item,delete", - "elm", _remove_item_cb, it); + evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh); + EINA_INLIST_FOREACH(sd->wd->blocks, itb) + { + itb->w = sd->wd->minw; + if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox, + itb->y - sd->wd->pan_y + oy, + itb->w, itb->h, + cvx, cvy, cvw, cvh)) + { + if ((!itb->realized) || (itb->changed)) + _item_block_realize(itb, in, 0); + _item_block_position(itb, in); + } + else + { + if (itb->realized) _item_block_unrealize(itb); + } + in += itb->count; + } - edje_object_signal_callback_add(it->edit_obj, "elm,action,hide,del_confirm", - "elm", _hide_delete_confirm_object, it ); - it->pad_left += pad * _elm_config->scale; - evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, - _reorder_mouse_down, it); - } - else + if (sd->wd->effect_mode && + (sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND || sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)) { - if (it->wd->animate_edit_controls) - edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,disable", "elm"); - else - edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm"); - - edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete", - "elm", _remove_item_cb ); - edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm", - "elm", _hide_delete_confirm_object ); - evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, - _reorder_mouse_down); + _item_flip_effect_show(sd->wd); + sd->wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, sd->wd); } - if ((itmode & ELM_GENLIST_EDIT_MODE_REORDER)) - { - const char* reorder_part; - - reorder_part = edje_object_data_get(it->edit_obj, "reorder"); - if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part)) - { - edje_object_part_object_get(it->edit_obj, reorder_part); - - evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, - _reorder_mouse_down); - evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP, - _reorder_mouse_up); - evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE, - _reorder_mouse_move); + if (sd->wd->effect_mode && sd->wd->edit_mode_effect_mode) + sd->wd->item_moving_effect_timer = ecore_animator_add(_edit_mode_item_moving_effect_cb, sd->wd); - evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, - _reorder_mouse_down, it); - evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_UP, - _reorder_mouse_up, it); - evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE, - _reorder_mouse_move, it); - } - // it->pad_right += pad * _elm_config->scale; - } - else + EINA_INLIST_FOREACH(sd->wd->group_items, git) { - const char* reorder_part; - - reorder_part = edje_object_data_get(it->edit_obj, "reorder"); - if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part)) + if (git->visible) { - - if (itmode == ELM_GENLIST_EDIT_MODE_NONE) - { - evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, - _reorder_mouse_down); - evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP, - _reorder_mouse_up); - evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE, - _reorder_mouse_move); - } + evas_object_raise(git->base); + evas_object_resize(git->base, git->w, git->h - 1); + evas_object_move(git->base, git->x, git->y); + if(!sd->wd->pinch_zoom_reserve) + evas_object_show(git->base); + else + evas_object_hide(git->base); } + else + evas_object_hide(git->base); } - - if (it->wd->edit_mode != 0xF0) { - if (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE) - { - if (it->itc->func.icon_get) - { - edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,enable", "elm"); - - const Eina_List *l; - const char *key; - - it->icons = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "icons")); - EINA_LIST_FOREACH(it->icons, l, key) - { - Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data); - - if (ic) - { - it->edit_icon_objs = eina_list_append(it->edit_icon_objs, ic); - edje_object_part_swallow(it->edit_obj, key, ic); - evas_object_show(ic); - // elm_widget_sub_object_add(it->wd->obj, ic); - } - } - } - } - else - { - edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm"); - EINA_LIST_FREE(it->edit_icon_objs, icon) - evas_object_del(icon); - - Evas_Object *editfield; - EINA_LIST_FREE(it->wd->edit_field, editfield) - evas_object_del(editfield); - } - } - - if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)//Unrealize + if ((sd->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER) && (sd->wd->ed->reorder_item)) { - evas_object_del(it->edit_obj); - it->edit_obj = NULL; - return; + evas_object_raise(sd->wd->ed->reorder_item->base); + evas_object_raise(sd->wd->ed->reorder_item->edit_obj); } - _move_edit_controls(it,it->scrl_x, it->scrl_y ); - evas_object_show( it->edit_obj ); + if(sd->wd->select_all_item) + evas_object_raise(sd->wd->select_all_item->base); } static void -_notify_item_position( Elm_Genlist_Item *it ) +_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__) { - const Eina_List *l; - if( it->parent ) - { - l = eina_list_last(it->parent->items); + Pan *sd = evas_object_smart_data_get(obj); - //Check if the Item is First Node or Last node of its Parent & raise signal. - if( it->parent->items->data != it && l->data != it ) - { - edje_object_signal_emit(it->base, "normal_item", "elm"); - } - else - { - if(it->parent->items->data == it ) - edje_object_signal_emit(it->base, "first_item", "elm"); + if (sd->wd->effect_mode && sd->wd->multi_down) return; + if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return; - if(l->data == it ) - edje_object_signal_emit(it->base, "last_item", "elm"); - } - } + if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job); + sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd); } - -static int -_get_space_for_reorder_item( Elm_Genlist_Item *it ) +static void +_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - int top=0; - Evas_Coord rox, roy, row, roh; - if(!it->wd->ed) - return 0; - - if( !(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER ) || !it->wd->ed->reorder_item ) - return 0; - - evas_object_geometry_get(it->wd->ed->reorder_item->base, &rox, &roy, &row, &roh); - - top = (ELM_RECTS_INTERSECT(it->scrl_x, it->scrl_y, it->w, it->h, - rox, roy+roh/2, row, 1)); - - if( top ) - { - it->wd->ed->reorder_rel = it; - it->scrl_y+=it->wd->ed->reorder_item->h; - return it->wd->ed->reorder_item->h; - } - - return 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_hold_set(wd->scr, 1); } static void -_item_block_position(Item_Block *itb, int in) +_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - const Eina_List *l; - Elm_Genlist_Item *it, *select_all_item; - Elm_Genlist_GroupItem *git = NULL; - Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh; - int vis=0; - int is_reorder = 0; - - evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh); - evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy, &cvw, &cvh); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_hold_set(wd->scr, 0); +} - if (itb->wd->select_all_item && - (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) ) - { - - select_all_item = itb->wd->select_all_item; - - evas_object_resize(select_all_item->base, itb->w, select_all_item->h); - evas_object_move(select_all_item->base, ox, oy); - evas_object_raise(select_all_item->base); - - if ( itb->wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE ) - evas_object_show(select_all_item->base); - else - evas_object_hide(select_all_item->base); - y = select_all_item->h; - } - - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->delete_me) continue; - it->x = 0; - it->y = y; - it->w = itb->w; - vis = (ELM_RECTS_INTERSECT(itb->x - it->wd->pan_x + ox, - itb->y - it->wd->pan_y + oy, - itb->w, itb->h, - cvx, cvy, cvw, cvh)); - if ((itb->realized) && (!it->realized)) - { - if (vis) - { - Eina_Bool was_realized = it->realized; - - _item_realize(it, in, 0); - if (!was_realized) - evas_object_smart_callback_call(it->wd->obj, - "realized", it); - } - } - if (it->realized) - { - _notify_item_position( it ); - if (vis) - { - it->scrl_x = ox + itb->x + it->x - itb->wd->pan_x; - it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y;; - if( git != it->group_item ) - { - git = it->group_item; - if (git) - { - git->visible = EINA_TRUE; //Mark Group Item to make it visible - if (git->items->data == it) - git->y = it->scrl_y; - if (GROUP_ALIGN_NORTH == git->align) - { - git->w = itb->w; - if (git->items->data == it) - { - it->scrl_y += git->minh; - y += git->minh; - } - } - } - } - if (git) - { - git->x = ox + itb->x - itb->wd->pan_x; +static void +_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_freeze_set(wd->scr, 1); +} - if (git->y < oy) - git->y = oy; +static void +_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_freeze_set(wd->scr, 0); +} - if (git->align == GROUP_ALIGN_WEST) - { - it->w -= git->w; - it->scrl_x += git->x + git->w; - git->h = (it->scrl_y + it->h) - git->y ; - if( git->h < it->h ) - { - git->y = it->scrl_y; - git->h = it->h; - } - } - if (git->align == GROUP_ALIGN_NORTH) - { - git->h = git->minh; - if ((git->y + git->h) > (it->scrl_y + it->h)) - git->y = (it->scrl_y + it->h) - git->minh; - } - if(git->update_finish_y) - { - git->finish_y += oy; - git->update_finish_y = EINA_FALSE; - } +/** + * Add a new Genlist object + * + * @param parent The parent object + * @return The new object or NULL if it cannot be created + * + * @ingroup Genlist + */ +EAPI Evas_Object * +elm_genlist_add(Evas_Object *parent) +{ + Evas_Object *obj; + Evas *e; + Widget_Data *wd; + Evas_Coord minw, minh; + static Evas_Smart *smart = NULL; - } + if (!parent) return NULL; + if (!smart) + { + static Evas_Smart_Class sc; + + evas_object_smart_clipped_smart_set(&_pan_sc); + sc = _pan_sc; + sc.name = "elm_genlist_pan"; + sc.version = EVAS_SMART_CLASS_VERSION; + sc.add = _pan_add; + sc.del = _pan_del; + sc.resize = _pan_resize; + sc.move = _pan_move; + sc.calculate = _pan_calculate; + if (!(smart = evas_smart_class_new(&sc))) return NULL; + } + wd = ELM_NEW(Widget_Data); + e = evas_object_evas_get(parent); + obj = elm_widget_add(e); + ELM_SET_WIDTYPE(widtype, "genlist"); + elm_widget_type_set(obj, "genlist"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_theme_hook_set(obj, _theme_hook); - is_reorder = _get_space_for_reorder_item( it ); + wd->scr = elm_smart_scroller_add(e); + elm_smart_scroller_widget_set(wd->scr, obj); + elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj)); + elm_widget_resize_object_set(obj, wd->scr); - if (is_reorder) - it->reorder_check = 1; - else - it->reorder_check = 0; + elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); - if (it->wd->ed) - { - if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && !itb->reoder_y) - { - itb->reoder_y -= it->h; - it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y; - } - else if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && itb->reoder_y) - { - itb->reoder_y = 0; - } - } - y += is_reorder; + wd->obj = obj; + wd->mode = ELM_LIST_SCROLL; + wd->max_items_per_block = 32; + wd->longpress_timeout = 1.0; + wd->max_git_num = 0; - if (!it->reordering ) - { - if ((!it->wd->effect_mode || - (it->wd->effect_mode && it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_NONE)) && !it->wd->pinch_zoom_reserve) - { - _move_edit_controls( it,it->scrl_x, it->scrl_y ); - evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h); + evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj); + evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj); + evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj); + evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj); - evas_object_move(it->base, it->scrl_x+it->pad_left, it->scrl_y); + wd->pan_smart = evas_object_smart_add(e, smart); + wd->pan = evas_object_smart_data_get(wd->pan_smart); + wd->pan->wd = wd; - if (it->delete_check) - { - edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm"); - edje_object_signal_emit(it->base, "elm,state,del_confirm", "elm"); - } - evas_object_show(it->base); - it->old_pad_left = it->pad_left; - it->old_scrl_y = it->scrl_y; - } + elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart, + _pan_set, _pan_get, + _pan_max_get, _pan_child_size_get); - } - } - else - { - if (!it->dragging) - _item_unrealize(it); - } - } - if (!it->reordering ) - y += it->h; + edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), + &minw, &minh); + evas_object_size_hint_min_set(obj, minw, minh); - in++; - } + _sizing_eval(obj); + return obj; +} - if (itb->wd->select_all_item && - (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) ) - evas_object_raise(select_all_item->base); +static Elm_Genlist_Item * +_item_new(Widget_Data *wd, const Elm_Genlist_Item_Class *itc, + const void *data, Elm_Genlist_Item *parent, + Elm_Genlist_Item_Flags flags, + Evas_Smart_Cb func, + const void *func_data) +{ + Elm_Genlist_Item *it; - if (vis) - { - itb->wd->animate_edit_controls = 0; - if (git) - git->visible = EINA_TRUE; - } + it = calloc(1, sizeof(Elm_Genlist_Item)); + if (!it) return NULL; + it->wd = wd; + it->itc = itc; + it->data = data; + it->parent = parent; + it->flags = flags; + it->func.func = func; + it->func.data = func_data; + it->expanded_depth = 0; + return it; } static void -_calc_job(void *data) +_item_block_add(Widget_Data *wd, Elm_Genlist_Item *it) { - Widget_Data *wd = data; - Item_Block *itb; - Evas_Coord minw = -1, minh = 0, y = 0, ow, oh; - Item_Block *chb = NULL; - int in = 0, minw_change = 0; - if (!wd) return; - EINA_INLIST_FOREACH(wd->blocks, itb) - { - int showme = 0; + Item_Block *itb = NULL; - itb->num = in; - showme = itb->showme; - itb->showme = 0; - if (chb) - { - if (itb->realized) _item_block_unrealize(itb); - } - if (itb->changed) - { - if (itb->realized) _item_block_unrealize(itb); - showme = _item_block_recalc(itb, in, 0, 1); - chb = itb; - } - itb->y = y; - itb->x = 0; - minh += itb->minh; - if (minw == -1) minw = itb->minw; - else if (minw < itb->minw) - { - minw = itb->minw; - minw_change = 1; - } - itb->w = minw; - itb->h = itb->minh; - y += itb->h; - in += itb->count; - if (showme) - { - if(wd->show_item) - { - wd->show_item->showme = 0; - if (wd->bring_in) - elm_smart_scroller_region_bring_in(wd->scr, - wd->show_item->x + wd->show_item->block->x, - wd->show_item->y + wd->show_item->block->y, - wd->show_item->block->w, - wd->show_item->h); - else - elm_smart_scroller_child_region_show(wd->scr, - wd->show_item->x + wd->show_item->block->x, - wd->show_item->y + wd->show_item->block->y, - wd->show_item->block->w, - wd->show_item->h); - wd->show_item = NULL; - } - } - } - - if (minw_change) - { - EINA_INLIST_FOREACH(wd->blocks, itb) - { - itb->minw = minw; - itb->w = itb->minw; - } - } - if ((chb) && (EINA_INLIST_GET(chb)->next)) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb) - if (itb->realized) _item_block_unrealize(itb); - } - evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh); - if (minw < ow) minw = ow; - if ((minw != wd->minw) || (minh != wd->minh) || wd->select_all_item) - { - wd->minw = minw; - wd->minh = minh; - if(wd->select_all_item) - wd->minh += wd->select_all_item->h; - evas_object_smart_callback_call(wd->pan_smart, "changed", NULL); - _sizing_eval(wd->obj); - } - wd->calc_job = NULL; - evas_object_smart_changed(wd->pan_smart); - -} - -static void -_update_job(void *data) -{ - Widget_Data *wd = data; - Eina_List *l2; - Item_Block *itb; - int num, num0, position = 0, recalc = 0; - if (!wd) return; - wd->update_job = NULL; - num = 0; - EINA_INLIST_FOREACH(wd->blocks, itb) + if (!it->rel) { - Evas_Coord itminw, itminh; - Elm_Genlist_Item *it; - - if (!itb->updateme) - { - num += itb->count; - if (position) - _item_block_position(itb, num); - continue; - } - num0 = num; - recalc = 0; - EINA_LIST_FOREACH(itb->items, l2, it) +newblock: + if (it->rel) { - if (it->updateme) + itb = calloc(1, sizeof(Item_Block)); + if (!itb) return; + itb->wd = wd; + if (!it->rel->block) { - itminw = it->w; - itminh = it->h; - - it->updateme = 0; - if (it->realized) + it->rel->block = itb; + wd->blocks = + eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb)); + itb->items = eina_list_append(itb->items, it); + } + else + { + if (it->before) { - _item_unrealize(it); - _item_realize(it, num, 0); - evas_object_smart_callback_call(it->wd->obj, - "realized", it); + wd->blocks = + eina_inlist_prepend_relative(wd->blocks, + EINA_INLIST_GET(itb), + EINA_INLIST_GET(it->rel->block)); + itb->items = + eina_list_prepend_relative(itb->items, it, it->rel); } else { - _item_realize(it, num, 1); - _item_unrealize(it); + wd->blocks = + eina_inlist_append_relative(wd->blocks, + EINA_INLIST_GET(itb), + EINA_INLIST_GET(it->rel->block)); + itb->items = + eina_list_append_relative(itb->items, it, it->rel); } - if ((it->minw != itminw) || (it->minh != itminh)) - recalc = 1; } - num++; } - itb->updateme = 0; - if (recalc) + else { - position = 1; - itb->changed = EINA_TRUE; - _item_block_recalc(itb, num0, 0, 1); - _item_block_position(itb, num0); + if (it->before) + { + if (wd->blocks) + { + itb = (Item_Block *)(wd->blocks); + if (itb->count >= wd->max_items_per_block) + { + itb = calloc(1, sizeof(Item_Block)); + if (!itb) return; + itb->wd = wd; + wd->blocks = + eina_inlist_prepend(wd->blocks, + EINA_INLIST_GET(itb)); + } + } + else + { + itb = calloc(1, sizeof(Item_Block)); + if (!itb) return; + itb->wd = wd; + wd->blocks = + eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb)); + } + itb->items = eina_list_prepend(itb->items, it); + } + else + { + if (wd->blocks) + { + itb = (Item_Block *)(wd->blocks->last); + if (itb->count >= wd->max_items_per_block) + { + itb = calloc(1, sizeof(Item_Block)); + if (!itb) return; + itb->wd = wd; + wd->blocks = + eina_inlist_append(wd->blocks, + EINA_INLIST_GET(itb)); + } + } + else + { + itb = calloc(1, sizeof(Item_Block)); + if (!itb) return; + itb->wd = wd; + wd->blocks = + eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb)); + } + itb->items = eina_list_append(itb->items, it); + } } } - if (position) + else { - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); + itb = it->rel->block; + if (!itb) goto newblock; + if (it->before) + itb->items = eina_list_prepend_relative(itb->items, it, it->rel); + else + itb->items = eina_list_append_relative(itb->items, it, it->rel); } -} - -static void -_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) -{ - Pan *sd = evas_object_smart_data_get(obj); -// Evas_Coord ow, oh; -// evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); -// ow = sd->wd->minw - ow; -// if (ow < 0) ow = 0; -// oh = sd->wd->minh - oh; -// if (oh < 0) oh = 0; -// if (x < 0) x = 0; -// if (y < 0) y = 0; -// if (x > ow) x = ow; -// if (y > oh) y = oh; - if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return; - sd->wd->pan_x = x; - sd->wd->pan_y = y; - evas_object_smart_changed(obj); -} + itb->count++; + itb->changed = EINA_TRUE; + it->block = itb; -static void -_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) -{ - Pan *sd = evas_object_smart_data_get(obj); + if(!itb->wd) + itb->wd = wd; - if (x) *x = sd->wd->pan_x; - if (y) *y = sd->wd->pan_y; + if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job); + itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd); + if (it->rel) + { + it->rel->relcount--; + if ((it->rel->delete_me) && (!it->rel->relcount)) + _item_del(it->rel); + it->rel = NULL; + } + if (itb->count > itb->wd->max_items_per_block) + { + int newc; + Item_Block *itb2; + Elm_Genlist_Item *it2; - if( sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH ) - { - int git_cnt = 0, git_h = 0; - Elm_Genlist_GroupItem *git; - - EINA_INLIST_FOREACH(sd->wd->group_items, git) - { - git_cnt++; - git_h = git->h; - } + newc = itb->count / 2; + itb2 = calloc(1, sizeof(Item_Block)); + if (!itb2) return; + itb2->wd = wd; + wd->blocks = + eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2), + EINA_INLIST_GET(itb)); + itb2->changed = EINA_TRUE; + while ((itb->count > newc) && (itb->items)) + { + Eina_List *l; - if( sd->wd->minh != (git_h+1) * git_cnt) - { - sd->wd->minh = (git_h+1) * git_cnt; - } - } + l = eina_list_last(itb->items); + it2 = l->data; + itb->items = eina_list_remove_list(itb->items, l); + itb->count--; + itb2->items = eina_list_prepend(itb2->items, it2); + it2->block = itb2; + itb2->count++; + } + } } -static void -_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) +static int +_queue_proecess(Widget_Data *wd, int norender) { - Pan *sd = evas_object_smart_data_get(obj); - Evas_Coord ow, oh; - - evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); - ow = sd->wd->minw - ow; - if (ow < 0) ow = 0; - oh = sd->wd->minh - oh; - if (oh < 0) oh = 0; - if (x) *x = ow; - if (y) *y = oh; -} + int n, showme = 0; + double t0, t; -static void -_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) -{ - Pan *sd = evas_object_smart_data_get(obj); + t0 = ecore_time_get(); + for (n = 0; (wd->queue) && (n < 128); n++) + { + Elm_Genlist_Item *it; - if (w) *w = sd->wd->minw; - if (h) *h = sd->wd->minh; + it = wd->queue->data; + wd->queue = eina_list_remove_list(wd->queue, wd->queue); + it->queued = EINA_FALSE; + _item_block_add(wd, it); + t = ecore_time_get(); + if (it->block->changed) + { + showme = _item_block_recalc(it->block, it->block->num, 1, norender); + it->block->changed = 0; + } + if (showme) it->block->showme = 1; + if (eina_inlist_count(wd->blocks) > 1) + { + if ((t - t0) > (ecore_animator_frametime_get())) break; + } + } + return n; } -static void -_pan_add(Evas_Object *obj) +static Eina_Bool +_item_idler(void *data) { - Pan *sd; - Evas_Object_Smart_Clipped_Data *cd; + Widget_Data *wd = data; - _pan_sc.add(obj); - cd = evas_object_smart_data_get(obj); - sd = ELM_NEW(Pan); - if (!sd) return; - sd->__clipped_data = *cd; - free(cd); - evas_object_smart_data_set(obj, sd); + //xxx + //static double q_start = 0.0; + //if (q_start == 0.0) q_start = ecore_time_get(); + //xxx + + if (_queue_proecess(wd, 1) > 0) + { + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); + } + if (!wd->queue) + { + //xxx + //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start); + //xxx + wd->queue_idler = NULL; + if(wd->pinch_zoom_reserve) + _elm_genlist_pinch_zoom_execute(wd->obj, 1); + return ECORE_CALLBACK_CANCEL; + } + return ECORE_CALLBACK_RENEW; } static void -_pan_del(Evas_Object *obj) +_item_queue(Widget_Data *wd, Elm_Genlist_Item *it) { - Pan *sd = evas_object_smart_data_get(obj); - - if (!sd) return; - _pan_sc.del(obj); -} - -static void -_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) -{ - Pan *sd = evas_object_smart_data_get(obj); - Evas_Coord ow, oh; - - evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); - if ((ow == w) && (oh == h)) return; - if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job); - sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd); -} - -static void -_pan_calculate(Evas_Object *obj) -{ - Pan *sd = evas_object_smart_data_get(obj); - Item_Block *itb; - Elm_Genlist_GroupItem *git; - Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - int in = 0; - - evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); - if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND) return; - - - if( sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH ) - { - sd->wd->contract_pan_y = sd->wd->pan_y; - EINA_INLIST_FOREACH(sd->wd->group_items, git) - { - git->visible = EINA_TRUE; - evas_object_raise(git->base); - evas_object_resize(git->base, sd->wd->minw, git->h); - evas_object_move(git->base, git->x, git->y + sd->wd->pan_y * -1); - evas_object_show(git->base); - } - } - - if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return; - - if (sd->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE) - (void)_edit_mode_reset(sd->wd); - EINA_INLIST_FOREACH(sd->wd->group_items, git) - { - git->visible = EINA_FALSE; - } - - evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh); - EINA_INLIST_FOREACH(sd->wd->blocks, itb) - { - itb->w = sd->wd->minw; - if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox, - itb->y - sd->wd->pan_y + oy, - itb->w, itb->h, - cvx, cvy, cvw, cvh)) - { - if ((!itb->realized) || (itb->changed)) - _item_block_realize(itb, in, 0); - _item_block_position(itb, in); - } - else - { - if (itb->realized) _item_block_unrealize(itb); - } - in += itb->count; - } - - if (sd->wd->effect_mode && - (sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND || sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)) - { - _item_flip_effect_show(sd->wd); - sd->wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, sd->wd); - } - - if (sd->wd->effect_mode && sd->wd->edit_mode_effect_mode) - sd->wd->item_moving_effect_timer = ecore_animator_add(_edit_mode_item_moving_effect_cb, sd->wd); - - EINA_INLIST_FOREACH(sd->wd->group_items, git) - { - if (git->visible) - { - evas_object_raise(git->base); - evas_object_resize(git->base, git->w, git->h - 1); - evas_object_move(git->base, git->x, git->y); - if(!sd->wd->pinch_zoom_reserve) - evas_object_show(git->base); - else - evas_object_hide(git->base); - } - else - evas_object_hide(git->base); - } - if ((sd->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER) && (sd->wd->ed->reorder_item)) - { - evas_object_raise(sd->wd->ed->reorder_item->base); - evas_object_raise(sd->wd->ed->reorder_item->edit_obj); - } - if(sd->wd->select_all_item) - evas_object_raise(sd->wd->select_all_item->base); -} - -static void -_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__) -{ - Pan *sd = evas_object_smart_data_get(obj); - - if (sd->wd->effect_mode && sd->wd->multi_down) return; - if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return; - - if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job); - sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd); -} - -static void -_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_smart_scroller_hold_set(wd->scr, 1); + if(!wd->queue_exception) + { + if (it->queued) return; + wd->queue = eina_list_append(wd->queue, it); + it->queued = EINA_TRUE; + wd->item_count++; + } + while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next))) + { + if (wd->queue_idler) + { + ecore_idler_del(wd->queue_idler); + wd->queue_idler = NULL; + } + _queue_proecess(wd, 0); + } + if (!wd->queue_idler) wd->queue_idler = ecore_idler_add(_item_idler, wd); + if(wd->queue_exception) + { + wd->queue = eina_list_append(wd->queue, it); + it->queued = EINA_TRUE; + } } -static void -_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +/** + * Append item to the end of the genlist + * + * This appends the given item to the end of the list or the end of the + * children if the parent is given. + * + * @param obj The genlist object + * @param itc The item class for the item + * @param data The item data + * @param parent The parent item, or NULL if none + * @param flags Item flags + * @param func Convenience function called when item selected + * @param func_data Data passed to @p func above. + * @return A handle to the item added or NULL if not possible + * + * @ingroup Genlist + */ +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, + Evas_Smart_Cb func, const void *func_data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_smart_scroller_hold_set(wd->scr, 0); + Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data); + if (!wd) return NULL; + if (!it) return NULL; + if (!it->parent) + { + wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it)); + it->rel = NULL; + it->before = 0; + } + else + { + Elm_Genlist_Item *it2 = NULL; + Eina_List *ll = eina_list_last(it->parent->items); + if (ll) it2 = ll->data; + it->parent->items = eina_list_append(it->parent->items, it); + if (!it2) it2 = it->parent; + wd->items = + eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), + EINA_INLIST_GET(it2)); + it->rel = it2; + it->rel->relcount++; + it->before = 0; + } + _item_queue(wd, it); + return it; } -static void -_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +/** + * Prepend item at start of the genlist + * + * This adds an item to the beginning of the list or beginning of the children + * of the parent if given. + * + * @param obj The genlist object + * @param itc The item class for the item + * @param data The item data + * @param parent The parent item, or NULL if none + * @param flags Item flags + * @param func Convenience function called when item selected + * @param func_data Data passed to @p func above. + * @return A handle to the item added or NULL if not possible + * + * @ingroup Genlist + */ +EAPI Elm_Genlist_Item * +elm_genlist_item_prepend(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, + const void *data, Elm_Genlist_Item *parent, + Elm_Genlist_Item_Flags flags, + Evas_Smart_Cb func, const void *func_data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_smart_scroller_freeze_set(wd->scr, 1); + Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data); + if (!wd) return NULL; + if (!it) return NULL; + if (!it->parent) + wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it)); + else + { + printf("FIXME: 12 tree not handled yet\n"); + } + it->rel = NULL; + it->before = 1; + _item_queue(wd, it); + return it; } -static void -_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +/** + * Insert item before another in the genlist + * + * This inserts an item before another in the list. It will be in the same tree + * level as the item it is inseted before. + * + * @param obj The genlist object + * @param itc The item class for the item + * @param data The item data + * @param before The item to insert before + * @param flags Item flags + * @param func Convenience function called when item selected + * @param func_data Data passed to @p func above. + * @return A handle to the item added or NULL if not possible + * + * @ingroup Genlist + */ +EAPI Elm_Genlist_Item * +elm_genlist_item_insert_before(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, + const void *data, Elm_Genlist_Item *before, + Elm_Genlist_Item_Flags flags, + Evas_Smart_Cb func, const void *func_data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_smart_scroller_freeze_set(wd->scr, 0); + Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data); + if (!wd) return NULL; + if (!it) return NULL; + if (!it->parent) + wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), + EINA_INLIST_GET(before)); + else + { + printf("FIXME: 13 tree not handled yet\n"); + } + it->rel = before; + it->rel->relcount++; + it->before = 1; + _item_queue(wd, it); + return it; } /** - * Add a new Genlist object + * Insert and item after another in the genlst * - * @param parent The parent object - * @return The new object or NULL if it cannot be created + * This inserts an item after another in the list. It will be in the same tree + * level as the item it is inseted after. + * + * @param obj The genlist object + * @param itc The item class for the item + * @param data The item data + * @param after The item to insert after + * @param flags Item flags + * @param func Convenience function called when item selected + * @param func_data Data passed to @p func above. + * @return A handle to the item added or NULL if not possible * * @ingroup Genlist */ -EAPI Evas_Object * -elm_genlist_add(Evas_Object *parent) +EAPI Elm_Genlist_Item * +elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, + const void *data, Elm_Genlist_Item *after, + Elm_Genlist_Item_Flags flags, + Evas_Smart_Cb func, const void *func_data) { - Evas_Object *obj; - Evas *e; - Widget_Data *wd; - Evas_Coord minw, minh; - static Evas_Smart *smart = NULL; - - if (!parent) return NULL; - wd = ELM_NEW(Widget_Data); - e = evas_object_evas_get(parent); - obj = elm_widget_add(e); - ELM_SET_WIDTYPE(widtype, "genlist"); - elm_widget_type_set(obj, "genlist"); - elm_widget_sub_object_add(parent, obj); - elm_widget_data_set(obj, wd); - elm_widget_del_hook_set(obj, _del_hook); - elm_widget_del_pre_hook_set(obj, _del_pre_hook); - elm_widget_theme_hook_set(obj, _theme_hook); - - wd->scr = elm_smart_scroller_add(e); - elm_smart_scroller_widget_set(wd->scr, obj); - elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj)); - elm_widget_resize_object_set(obj, wd->scr); - - elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); - - wd->obj = obj; - wd->mode = ELM_LIST_SCROLL; - wd->max_items_per_block = 32; - wd->longpress_timeout = 1.0; - wd->max_git_num = 0; - - evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj); - evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj); - evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj); - evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj); - - if (!smart) - { - static Evas_Smart_Class sc; - - evas_object_smart_clipped_smart_set(&_pan_sc); - sc = _pan_sc; - sc.name = "elm_genlist_pan"; - sc.version = EVAS_SMART_CLASS_VERSION; - sc.add = _pan_add; - sc.del = _pan_del; - sc.resize = _pan_resize; - sc.move = _pan_move; - sc.calculate = _pan_calculate; - smart = evas_smart_class_new(&sc); - } - if (smart) + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL); + Widget_Data *wd = elm_widget_data_get(obj); + Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data); + if (!wd) return NULL; + if (!it) return NULL; + if (!it->parent) + wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), + EINA_INLIST_GET(after)); + else { - wd->pan_smart = evas_object_smart_add(e, smart); - wd->pan = evas_object_smart_data_get(wd->pan_smart); - wd->pan->wd = wd; + printf("FIXME: 14 tree not handled yet\n"); } - - elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart, - _pan_set, _pan_get, - _pan_max_get, _pan_child_size_get); - - edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), - &minw, &minh); - evas_object_size_hint_min_set(obj, minw, minh); - _sizing_eval(obj); - return obj; + it->rel = after; + it->rel->relcount++; + it->before = 0; + _item_queue(wd, it); + return it; } -static Elm_Genlist_Item * -_item_new(Widget_Data *wd, const Elm_Genlist_Item_Class *itc, - const void *data, Elm_Genlist_Item *parent, - Elm_Genlist_Item_Flags flags, - Evas_Smart_Cb func, - const void *func_data) +/** + * Clear the genlist + * + * This clears all items in the list, leaving it empty. + * + * @param obj The genlist object + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_clear(Evas_Object *obj) { - Elm_Genlist_Item *it; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - it = calloc(1, sizeof(Elm_Genlist_Item)); - if (!it) return NULL; - it->wd = wd; - it->itc = itc; - it->data = data; - it->parent = parent; - it->flags = flags; - it->func.func = func; - it->func.data = func_data; - it->expanded_depth = 0; - return it; -} + wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; + wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE; + elm_smart_scroller_hold_set(wd->scr, 0); + elm_smart_scroller_freeze_set(wd->scr, 0); + elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0); + elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); + wd->max_git_num = 0; + wd->pinch_zoom_reserve = EINA_FALSE; -static void -_item_block_add(Widget_Data *wd, Elm_Genlist_Item *it) -{ - Item_Block *itb = NULL; + if(wd->item_moving_effect_timer) + { + // ecore_timer_del(wd->item_moving_effect_timer); + wd->item_moving_effect_timer = NULL; + } - if (!it->rel) + while (wd->group_items) { - newblock: - if (it->rel) - { - itb = calloc(1, sizeof(Item_Block)); - if (!itb) return; - itb->wd = wd; - if (!it->rel->block) - { - it->rel->block = itb; - wd->blocks = - eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb)); - itb->items = eina_list_append(itb->items, it); - } - else - { - if (it->before) - { - wd->blocks = - eina_inlist_prepend_relative(wd->blocks, - EINA_INLIST_GET(itb), - EINA_INLIST_GET(it->rel->block)); - itb->items = - eina_list_prepend_relative(itb->items, it, it->rel); - } - else - { - wd->blocks = - eina_inlist_append_relative(wd->blocks, - EINA_INLIST_GET(itb), - EINA_INLIST_GET(it->rel->block)); - itb->items = - eina_list_append_relative(itb->items, it, it->rel); - } - } - } - else - { - if (it->before) - { - if (wd->blocks) - { - itb = (Item_Block *)(wd->blocks); - if (itb->count >= wd->max_items_per_block) - { - itb = calloc(1, sizeof(Item_Block)); - if (!itb) return; - itb->wd = wd; - wd->blocks = - eina_inlist_prepend(wd->blocks, - EINA_INLIST_GET(itb)); - } - } - else - { - itb = calloc(1, sizeof(Item_Block)); - if (!itb) return; - itb->wd = wd; - wd->blocks = - eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb)); - } - itb->items = eina_list_prepend(itb->items, it); - } - else - { - if (wd->blocks) - { - itb = (Item_Block *)(wd->blocks->last); - if (itb->count >= wd->max_items_per_block) - { - itb = calloc(1, sizeof(Item_Block)); - if (!itb) return; - itb->wd = wd; - wd->blocks = - eina_inlist_append(wd->blocks, - EINA_INLIST_GET(itb)); - } - } - else - { - itb = calloc(1, sizeof(Item_Block)); - if (!itb) return; - itb->wd = wd; - wd->blocks = - eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb)); - } - itb->items = eina_list_append(itb->items, it); - } - } + _groupitem_remove((Elm_Genlist_GroupItem *)wd->group_items, EINA_FALSE); } - else + + if (wd->walking > 0) { - itb = it->rel->block; - if (!itb) goto newblock; - if (it->before) - itb->items = eina_list_prepend_relative(itb->items, it, it->rel); - else - itb->items = eina_list_append_relative(itb->items, it, it->rel); + Elm_Genlist_Item *it; + + wd->clear_me = 1; + EINA_INLIST_FOREACH(wd->items, it) + { + it->delete_me = 1; + } + return; } - itb->count++; - itb->changed = EINA_TRUE; - it->block = itb; + wd->clear_me = 0; + while (wd->items) + { + Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items); - if(!itb->wd) - itb->wd = wd; + wd->items = eina_inlist_remove(wd->items, wd->items); + if (it->realized) _item_unrealize(it); + if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj); + if (it->long_timer) ecore_timer_del(it->long_timer); + free(it); + } + while (wd->blocks) + { + Item_Block *itb = (Item_Block *)(wd->blocks); - if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job); - itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd); - if (it->rel) + wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks); + if (itb->items) eina_list_free(itb->items); + free(itb); + } + if (wd->calc_job) { - it->rel->relcount--; - if ((it->rel->delete_me) && (!it->rel->relcount)) - _item_del(it->rel); - it->rel = NULL; + ecore_job_del(wd->calc_job); + wd->calc_job = NULL; } - if (itb->count > itb->wd->max_items_per_block) + if (wd->queue_idler) { - int newc; - Item_Block *itb2; - Elm_Genlist_Item *it2; - - newc = itb->count / 2; - itb2 = calloc(1, sizeof(Item_Block)); - if (!itb2) return; - itb2->wd = wd; - wd->blocks = - eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2), - EINA_INLIST_GET(itb)); - itb2->changed = EINA_TRUE; - while ((itb->count > newc) && (itb->items)) - { - Eina_List *l; - - l = eina_list_last(itb->items); - it2 = l->data; - itb->items = eina_list_remove_list(itb->items, l); - itb->count--; - - itb2->items = eina_list_prepend(itb2->items, it2); - it2->block = itb2; - itb2->count++; - } + ecore_idler_del(wd->queue_idler); + wd->queue_idler = NULL; } -} + if (wd->queue) + { + eina_list_free(wd->queue); + wd->queue = NULL; + } + if (wd->selected) + { + eina_list_free(wd->selected); + wd->selected = NULL; + } + wd->show_item = NULL; + wd->pan_x = 0; + wd->pan_y = 0; + wd->minw = 0; + wd->minh = 0; -static int -_queue_proecess(Widget_Data *wd, int norender) -{ - int n, showme = 0; - double t0, t; + if(wd->alpha_bg) + evas_object_del(wd->alpha_bg); + wd->alpha_bg = NULL; - t0 = ecore_time_get(); - for (n = 0; (wd->queue) && (n < 128); n++) + if (wd->pan_smart) { - Elm_Genlist_Item *it; - - it = wd->queue->data; - wd->queue = eina_list_remove_list(wd->queue, wd->queue); - it->queued = EINA_FALSE; - _item_block_add(wd, it); - t = ecore_time_get(); - if (it->block->changed) - { - showme = _item_block_recalc(it->block, it->block->num, 1, norender); - it->block->changed = 0; - } - if (showme) it->block->showme = 1; - if (eina_inlist_count(wd->blocks) > 1) - { - if ((t - t0) > (ecore_animator_frametime_get())) break; - } + evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh); + evas_object_smart_callback_call(wd->pan_smart, "changed", NULL); } - return n; -} - -static Eina_Bool -_item_idler(void *data) -{ - Widget_Data *wd = data; - - if (_queue_proecess(wd, 1) > 0) - { - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); - } - if (!wd->queue) - { - wd->queue_idler = NULL; - if(wd->pinch_zoom_reserve) - _elm_genlist_pinch_zoom_execute(wd->obj, 1); - return ECORE_CALLBACK_CANCEL; - } - return ECORE_CALLBACK_RENEW; -} - -static void -_item_queue(Widget_Data *wd, Elm_Genlist_Item *it) -{ - if(!wd->queue_exception) - { - if (it->queued) return; - wd->queue = eina_list_append(wd->queue, it); - it->queued = EINA_TRUE; - wd->item_count++; - } - - while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next))) - { - if (wd->queue_idler) - { - ecore_idler_del(wd->queue_idler); - wd->queue_idler = NULL; - } - _queue_proecess(wd, 0); - } - - if (!wd->queue_idler) wd->queue_idler = ecore_idler_add(_item_idler, wd); - - if(wd->queue_exception) - { - wd->queue = eina_list_append(wd->queue, it); - it->queued = EINA_TRUE; - } + _sizing_eval(obj); } /** - * Add Group Item to the genlist + * Enable or disable multi-select in the genlist + * + * This enables (EINA_TRUE) or disableds (EINA_FALSE) multi-select in the list. This allows + * more than 1 item to be selected. * * @param obj The genlist object - * @param itc The item class for the item - * @param data The group item data + * @param multi Multi-select enable/disable + * + * @ingroup Genlist */ -EAPI Elm_Genlist_GroupItem * -elm_genlist_groupitem_add(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, - const void *data) +EAPI void +elm_genlist_multi_select_set(Evas_Object *obj, Eina_Bool multi) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Elm_Genlist_GroupItem *git; + ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - - git = calloc(1, sizeof(Elm_Genlist_GroupItem)); - if (!git) return NULL; - git->wd = wd; - git->itc = itc; - git->data = data; - - wd->group_items = eina_inlist_append(wd->group_items, EINA_INLIST_GET(git) ); - return git; + if (!wd) return; + wd->multi = multi; } /** - * Delete a given groupitem - * - * This deletes the group item from genlist and calls the genlist group item del class - * callback defined in the item class, if it is set. + * Gets if multi-select in genlist is enable or disable * - * @param git The group item + * @param obj The genlist object + * @return Multi-select enable/disable + * (EINA_TRUE = enabled/EINA_FALSE = disabled) * * @ingroup Genlist */ -EAPI void -elm_genlist_groupitem_del(Elm_Genlist_GroupItem *git) +EAPI Eina_Bool +elm_genlist_multi_select_get(const Evas_Object *obj) { - _groupitem_remove( git, EINA_TRUE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->multi; } + /** - * Append item to the end of the genlist + * Get the selectd item in the genlist * - * This appends the given item to the end of the list or the end of the - * children if the parent is given. + * This gets the selected item in the list (if multi-select is enabled only + * the first item in the list is selected - which is not very useful, so see + * elm_genlist_selected_items_get()for when multi-select is used). + * + * If no item is selected, NULL is returned. * * @param obj The genlist object - * @param itc The item class for the item - * @param data The item data - * @param parent The parent item, or NULL if none - * @param flags Item flags - * @param func Convenience function called when item selected - * @param func_data Data passed to @p func above. - * @return A handle to the item added or NULL if not possible + * @return The selected item, or NULL if none. * * @ingroup Genlist */ 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, - Evas_Smart_Cb func, const void *func_data) +elm_genlist_selected_item_get(const Evas_Object *obj) { ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); - Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data); if (!wd) return NULL; - if (!it) return NULL; - if (!it->parent) - { - wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it)); - it->rel = NULL; - it->before = 0; - } - else - { - Elm_Genlist_Item *it2 = NULL; - Eina_List *ll = eina_list_last(it->parent->items); - if (ll) it2 = ll->data; - it->parent->items = eina_list_append(it->parent->items, it); - if (!it2) it2 = it->parent; - wd->items = - eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), - EINA_INLIST_GET(it2)); - it->rel = it2; - it->rel->relcount++; - it->before = 0; - } - _item_queue(wd, it); - return it; + if (wd->selected) return wd->selected->data; + return NULL; } /** - * Append item to the end of the genlist with Group Item + * Get a list of selected items in the genlist * - * This appends the given item to the end of the list or the end of the - * children if the parent is given. + * This retgurns a list of the selected items. This list pointer is only valid + * so long as no items are selected or unselected (or unselected implicitly + * by deletion). The list contains Elm_Genlist_Item pointers. * * @param obj The genlist object - * @param itc The item class for the item - * @param data The item data - * @param parent The parent item, or NULL if none - * @param flags Item flags - * @param git Group Item - * @param func Convenience function called when item selected - * @param func_data Data passed to @p func above. - * @return A handle to the item added or NULL if not possible + * @return The list of selected items, nor NULL if none are selected. * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_item_append_with_group(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, - const void *data, Elm_Genlist_Item *parent, - Elm_Genlist_Item_Flags flags, Elm_Genlist_GroupItem *git, - Evas_Smart_Cb func, const void *func_data) +EAPI const Eina_List * +elm_genlist_selected_items_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - parent = NULL; - Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data); - Elm_Genlist_GroupItem *pgit = NULL; - Elm_Genlist_Item *it2 = NULL; - Eina_List *ll = NULL; - if (!wd) return NULL; - if (!it) return NULL; - if (!git) return NULL; - - pgit = git; - while (pgit) - { - ll = eina_list_last(pgit->items); - if (ll) - { - it2 = ll->data; - break; - } - if (!(EINA_INLIST_GET(pgit)->prev)) break; - pgit = (Elm_Genlist_GroupItem *)(EINA_INLIST_GET(pgit)->prev); - } - if (it2) - { - wd->items = - eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), - EINA_INLIST_GET(it2)); - it->rel = it2; - it->rel->relcount++; - } - else - { - wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it)); - it->rel = NULL; - } - git->items = eina_list_append(git->items, it); - it->before = 0; - it->group_item = git; - _item_queue(wd, it); - return it; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->selected; } /** - * Prepend item at start of the genlist + * Get a list of realized items in genlist * - * This adds an item to the beginning of the list or beginning of the children - * of the parent if given. + * This returns a list of the realized items in the genlist. The list + * contains Elm_Genlist_Item pointers. The list must be freed by the + * caller when done with eina_list_free(). The item pointers in the list + * are only vallid so long as those items are not deleted or the genlist is + * not deleted. * * @param obj The genlist object - * @param itc The item class for the item - * @param data The item data - * @param parent The parent item, or NULL if none - * @param flags Item flags - * @param func Convenience function called when item selected - * @param func_data Data passed to @p func above. - * @return A handle to the item added or NULL if not possible + * @return The list of realized items, nor NULL if none are realized. * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_item_prepend(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, - const void *data, Elm_Genlist_Item *parent, - Elm_Genlist_Item_Flags flags, - Evas_Smart_Cb func, const void *func_data) +EAPI Eina_List * +elm_genlist_realized_items_get(const Evas_Object *obj) { ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); - Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data); + Eina_List *list = NULL; + Item_Block *itb; + Eina_Bool done = EINA_FALSE; if (!wd) return NULL; - if (!it) return NULL; - if (!it->parent) - wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it)); - else + EINA_INLIST_FOREACH(wd->blocks, itb) { - printf("FIXME: 12 tree not handled yet\n"); + if (itb->realized) + { + Eina_List *l; + Elm_Genlist_Item *it; + + done = 1; + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->realized) list = eina_list_append(list, it); + } + } + else + { + if (done) break; + } } - it->rel = NULL; - it->before = 1; - _item_queue(wd, it); - return it; + return list; } /** - * Insert item before another in the genlist + * Get the item that is at the x, y canvas coords * - * This inserts an item before another in the list. It will be in the same tree - * level as the item it is inseted before. + * This returns the item at the given coordinates (which are canvas relative + * not object-relative). If an item is at that coordinate, that item handle + * is returned, and if @p posret is not NULL, the integer pointed to is set + * to a value of -1, 0 or 1, depending if the coordinate is on the upper + * portion of that item (-1), on the middle section (0) or on the lower part + * (1). If NULL is returned as an item (no item found there), then posret + * may indicate -1 or 1 based if the coordinate is above or below all items + * respectively in the genlist. * - * @param obj The genlist object - * @param itc The item class for the item - * @param data The item data - * @param before The item to insert before - * @param flags Item flags - * @param func Convenience function called when item selected - * @param func_data Data passed to @p func above. - * @return A handle to the item added or NULL if not possible + * @param it The item + * @param x The input x coordinate + * @param y The input y coordinate + * @param posret The position relative to the item returned here + * @return The item at the coordinates or NULL if none * * @ingroup Genlist */ EAPI Elm_Genlist_Item * -elm_genlist_item_insert_before(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, - const void *data, Elm_Genlist_Item *before, - Elm_Genlist_Item_Flags flags, - Evas_Smart_Cb func, const void *func_data) +elm_genlist_at_xy_item_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *posret) { ELM_CHECK_WIDTYPE(obj, widtype) NULL; - EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL); Widget_Data *wd = elm_widget_data_get(obj); - Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data); + Evas_Coord ox, oy, ow, oh; + Item_Block *itb; + Evas_Coord lasty; if (!wd) return NULL; - if (!it) return NULL; - if (!it->parent) - wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), - EINA_INLIST_GET(before)); - else + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + lasty = oy; + EINA_INLIST_FOREACH(wd->blocks, itb) { - printf("FIXME: 13 tree not handled yet\n"); + Eina_List *l; + Elm_Genlist_Item *it; + + if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x, + oy + itb->y - itb->wd->pan_y, + itb->w, itb->h, x, y, 1, 1)) + continue; + EINA_LIST_FOREACH(itb->items, l, it) + { + Evas_Coord itx, ity; + + itx = ox + itb->x + it->x - itb->wd->pan_x; + ity = oy + itb->y + it->y - itb->wd->pan_y; + if (ELM_RECTS_INTERSECT(itx, ity, it->w, it->h, x, y, 1, 1)) + { + if (posret) + { + if (y <= (ity + (it->h / 4))) *posret = -1; + else if (y >= (ity + it->h - (it->h / 4))) *posret = 1; + else *posret = 0; + } + return it; + } + lasty = ity + it->h; + } } - it->rel = before; - it->rel->relcount++; - it->before = 1; - _item_queue(wd, it); - return it; + if (posret) + { + if (y > lasty) *posret = 1; + else *posret = -1; + } + return NULL; } /** - * Insert and item after another in the genlst + * Get the first item in the genlist * - * This inserts an item after another in the list. It will be in the same tree - * level as the item it is inseted after. + * This returns the first item in the list. * * @param obj The genlist object - * @param itc The item class for the item - * @param data The item data - * @param after The item to insert after - * @param flags Item flags - * @param func Convenience function called when item selected - * @param func_data Data passed to @p func above. - * @return A handle to the item added or NULL if not possible + * @return The first item, or NULL if none * * @ingroup Genlist */ EAPI Elm_Genlist_Item * -elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, - const void *data, Elm_Genlist_Item *after, - Elm_Genlist_Item_Flags flags, - Evas_Smart_Cb func, const void *func_data) +elm_genlist_first_item_get(const Evas_Object *obj) { ELM_CHECK_WIDTYPE(obj, widtype) NULL; - EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL); Widget_Data *wd = elm_widget_data_get(obj); - Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data); if (!wd) return NULL; - if (!it) return NULL; - if (!it->parent) - wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), - EINA_INLIST_GET(after)); - else - { - printf("FIXME: 14 tree not handled yet\n"); - } - it->rel = after; - it->rel->relcount++; - it->before = 0; - _item_queue(wd, it); + if (!wd->items) return NULL; + Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items); + while ((it) && (it->delete_me)) + it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next); return it; } /** - * Moves the Genlist Item + * Get the last item in the genlist + * + * This returns the last item in the list. + * + * @return The last item, or NULL if none + * + * @ingroup Genlist */ -EAPI void -elm_genlist_item_move_after(Elm_Genlist_Item *it, Elm_Genlist_Item *after ) +EAPI Elm_Genlist_Item * +elm_genlist_last_item_get(const Evas_Object *obj) { - if (!it) return; - - Elm_Genlist_Item *next_item = elm_genlist_item_next_get(after); - - if(it->y == after->y && after->reorder_check && it->reorder_check) { - if (it->wd->calc_job) ecore_job_del(it->wd->calc_job); - it->wd->calc_job = ecore_job_add(_calc_job, it->wd); - return; - } - - it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it)); - _item_block_del(it); - - if((!next_item && !after->reorder_check) || (next_item && !after->reorder_check) ) - { - - if(next_item && !after->reorder_check && it == after) { - it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), - EINA_INLIST_GET(next_item)); - it->rel = next_item; - } - else { - it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), - EINA_INLIST_GET(after)); - it->rel = after; - } - - it->rel->relcount++; - it->before = 0; - } - else - { - if( after) - { - it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), - EINA_INLIST_GET(after)); - it->rel = after; - it->rel->relcount++; - } - else - { - it->wd->items = eina_inlist_prepend(it->wd->items, EINA_INLIST_GET(it)); - } - - it->before = 1; - } - - _item_queue(it->wd, it); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd->items) return NULL; + Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items->last); + if (!wd) return NULL; + while ((it) && (it->delete_me)) + it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev); + return it; } /** - * Clear the genlist + * Get the next item in the genlist * - * This clears all items in the list, leaving it empty. + * This returns the item after the item @p it. * - * @param obj The genlist object + * @param it The item + * @return The item after @p it, or NULL if none * * @ingroup Genlist */ -EAPI void -elm_genlist_clear(Evas_Object *obj) +EAPI Elm_Genlist_Item * +elm_genlist_item_next_get(const Elm_Genlist_Item *it) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - - wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; - wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE; - elm_smart_scroller_hold_set(wd->scr, 0); - elm_smart_scroller_freeze_set(wd->scr, 0); - elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0); - elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); - wd->max_git_num = 0; - wd->pinch_zoom_reserve = EINA_FALSE; - - if(wd->item_moving_effect_timer) - { - // ecore_timer_del(wd->item_moving_effect_timer); - wd->item_moving_effect_timer = NULL; - } - - while (wd->group_items) + while (it) { - _groupitem_remove((Elm_Genlist_GroupItem *)wd->group_items, EINA_FALSE); + it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next); + if ((it) && (!it->delete_me)) break; } + return (Elm_Genlist_Item *)it; +} - if (wd->walking > 0) +/** + * Get the previous item in the genlist + * + * This returns the item before the item @p it. + * + * @param it The item + * @return The item before @p it, or NULL if none + * + * @ingroup Genlist + */ +EAPI Elm_Genlist_Item * +elm_genlist_item_prev_get(const Elm_Genlist_Item *it) +{ + while (it) { - Elm_Genlist_Item *it; - - wd->clear_me = 1; - EINA_INLIST_FOREACH(wd->items, it) - { - it->delete_me = 1; - } - return; + it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev); + if ((it) && (!it->delete_me)) break; } - wd->clear_me = 0; + return (Elm_Genlist_Item *)it; +} - while (wd->items) - { - Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items); +/** + * Get the genlist object from an item + * + * This returns the genlist object itself that an item belongs to. + * + * @param it The item + * @return The genlist object + * + * @ingroup Genlist + */ +EAPI Evas_Object * +elm_genlist_item_genlist_get(const Elm_Genlist_Item *it) +{ + if (!it) return NULL; + return it->wd->obj; +} - wd->items = eina_inlist_remove(wd->items, wd->items); - if (it->realized) _item_unrealize(it); - if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj); - if (it->long_timer) ecore_timer_del(it->long_timer); - free(it); - } - while (wd->blocks) - { - Item_Block *itb = (Item_Block *)(wd->blocks); - - wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks); - if (itb->items) eina_list_free(itb->items); - free(itb); - } - if (wd->calc_job) - { - ecore_job_del(wd->calc_job); - wd->calc_job = NULL; - } - if (wd->queue_idler) - { - ecore_idler_del(wd->queue_idler); - wd->queue_idler = NULL; - } - if (wd->queue) - { - eina_list_free(wd->queue); - wd->queue = NULL; - } - if (wd->selected) - { - eina_list_free(wd->selected); - wd->selected = NULL; - } - wd->show_item = NULL; - wd->pan_x = 0; - wd->pan_y = 0; - wd->minw = 0; - wd->minh = 0; +/** + * Get the parent item of the given item + * + * This returns the prent item of the item @p it given. + * + * @param it The item + * @return The parent of the item or NULL if none + * + * @ingroup Genlist + */ +EAPI Elm_Genlist_Item * +elm_genlist_item_parent_get(const Elm_Genlist_Item *it) +{ + if (!it) return NULL; + return it->parent; +} - if(wd->alpha_bg) - evas_object_del(wd->alpha_bg); - wd->alpha_bg = NULL; +/** + * Clear all sub-items (children) of the given item + * + * This clears all items that are children (or their descendants) of the + * given item @p it. + * + * @param it The item + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_item_subitems_clear(Elm_Genlist_Item *it) +{ + if (!it) return; + Eina_List *tl = NULL, *l; + Elm_Genlist_Item *it2; - if (wd->pan_smart) - { - evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh); - evas_object_smart_callback_call(wd->pan_smart, "changed", NULL); - } - _sizing_eval(obj); + EINA_LIST_FOREACH(it->items, l, it2) + tl = eina_list_append(tl, it2); + EINA_LIST_FREE(tl, it2) + elm_genlist_item_del(it2); } /** - * Enable or disable multi-select in the genlist + * Set the selected state of an item * - * This enables (EINA_TRUE) or disableds (EINA_FALSE) multi-select in the list. This allows - * more than 1 item to be selected. + * This sets the selected state (1 selected, 0 not selected) of the given + * item @p it. * - * @param obj The genlist object - * @param multi Multi-select enable/disable + * @param it The item + * @param selected The slected state * * @ingroup Genlist */ EAPI void -elm_genlist_multi_select_set(Evas_Object *obj, Eina_Bool multi) +elm_genlist_item_selected_set(Elm_Genlist_Item *it, Eina_Bool selected) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); + if (!it) return; + ELM_CHECK_WIDTYPE(it->wd->obj, widtype); + Widget_Data *wd = elm_widget_data_get(it->wd->obj); if (!wd) return; - wd->multi = multi; + if (it->delete_me) return; + selected = !!selected; + if (it->selected == selected) return; + + if (selected) + { + if (!wd->multi) + { + while (wd->selected) + _item_unselect(wd->selected->data); + } + _item_hilight(it); + _item_select(it); + } + else + _item_unselect(it); } /** - * Gets if multi-select in genlist is enable or disable + * Get the selected state of an item * - * @param obj The genlist object - * @return Multi-select enable/disable - * (EINA_TRUE = enabled/EINA_FALSE = disabled) + * This gets the selected state of an item (1 selected, 0 not selected). + * + * @param it The item + * @return The selected state * * @ingroup Genlist */ EAPI Eina_Bool -elm_genlist_multi_select_get(const Evas_Object *obj) +elm_genlist_item_selected_get(const Elm_Genlist_Item *it) { - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - return wd->multi; + if (!it) return EINA_FALSE; + return it->selected; } - /** - * Get the selectd item in the genlist - * - * This gets the selected item in the list (if multi-select is enabled only - * the first item in the list is selected - which is not very useful, so see - * elm_genlist_selected_items_get()for when multi-select is used). + * Sets the expanded state of an item (if it's a parent) * - * If no item is selected, NULL is returned. + * This expands or contracts a parent iterm (thus showing or hiding the + * children). * - * @param obj The genlist object - * @return The selected item, or NULL if none. + * @param it The item + * @param expanded The expanded state (1 expanded, 0 not expanded). * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_selected_item_get(const Evas_Object *obj) +EAPI void +elm_genlist_item_expanded_set(Elm_Genlist_Item *it, Eina_Bool expanded) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - if (wd->selected) return wd->selected->data; - return NULL; + if (!it) return; + if (it->expanded == expanded || it->disabled ) return; + it->expanded = expanded; + it->wd->expand_item = it; + it->effect_done = EINA_FALSE; + if (it->expanded) + { + it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND; + if (it->realized) + edje_object_signal_emit(it->base, "elm,state,expanded", "elm"); + evas_object_smart_callback_call(it->wd->obj, "expanded", it); + + } + else + { + it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT; + if (it->realized) + edje_object_signal_emit(it->base, "elm,state,contracted", "elm"); + evas_object_smart_callback_call(it->wd->obj, "contracted", it); + } } /** - * Get a list of selected items in the genlist + * Get the expanded state of an item * - * This retgurns a list of the selected items. This list pointer is only valid - * so long as no items are selected or unselected (or unselected implicitly - * by deletion). The list contains Elm_Genlist_Item pointers. + * This gets the expanded state of an item * - * @param obj The genlist object - * @return The list of selected items, nor NULL if none are selected. + * @param it The item + * @return Thre expanded state * * @ingroup Genlist */ -EAPI const Eina_List * -elm_genlist_selected_items_get(const Evas_Object *obj) +EAPI Eina_Bool +elm_genlist_item_expanded_get(const Elm_Genlist_Item *it) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - return wd->selected; + if (!it) return EINA_FALSE; + return it->expanded; } /** - * Get a list of realized items in genlist + * Get the depth of expanded item * - * This returns a list of the realized items in the genlist. The list - * contains Elm_Genlist_Item pointers. The list must be freed by the - * caller when done with eina_list_free(). The item pointers in the list - * are only vallid so long as those items are not deleted or the genlist is - * not deleted. + * @param it The genlist item object + * @return The depth of expanded item * - * @param obj The genlist object - * @return The list of realized items, nor NULL if none are realized. + * @ingroup Genlist + */ +EAPI int +elm_genlist_item_expanded_depth_get(const Elm_Genlist_Item *it) +{ + if (!it) return 0; + return it->expanded_depth; +} + +/** + * Sets the disabled state of an item. + * + * A disabled item cannot be selected or unselected. It will also change + * appearance to appear disabled. This sets the disabled state (1 disabled, 0 + * not disabled). + * + * @param it The item + * @param disabled The disabled state * * @ingroup Genlist */ -EAPI Eina_List * -elm_genlist_realized_items_get(const Evas_Object *obj) +EAPI void +elm_genlist_item_disabled_set(Elm_Genlist_Item *it, Eina_Bool disabled) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - Eina_List *list = NULL; - Item_Block *itb; - Eina_Bool done = EINA_FALSE; - if (!wd) return NULL; - EINA_INLIST_FOREACH(wd->blocks, itb) + if (!it) return; + if (it->disabled == disabled) return; + if (it->delete_me) return; + it->disabled = disabled; + if (it->realized) { - if (itb->realized) - { - Eina_List *l; - Elm_Genlist_Item *it; - - done = 1; - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->realized) list = eina_list_append(list, it); - } - } + if (it->disabled) + edje_object_signal_emit(it->base, "elm,state,disabled", "elm"); else - { - if (done) break; - } + edje_object_signal_emit(it->base, "elm,state,enabled", "elm"); } - return list; } /** - * Get the item that is at the x, y canvas coords + * Get the disabled state of an item * - * This returns the item at the given coordinates (which are canvas relative - * not object-relative). If an item is at that coordinate, that item handle - * is returned, and if @p posret is not NULL, the integer pointed to is set - * to a value of -1, 0 or 1, depending if the coordinate is on the upper - * portion of that item (-1), on the middle section (0) or on the lower part - * (1). If NULL is returned as an item (no item found there), then posret - * may indicate -1 or 1 based if the coordinate is above or below all items - * respectively in the genlist. + * This gets the disabld state of the given item. * * @param it The item - * @param x The input x coordinate - * @param y The input y coordinate - * @param posret The position relative to the item returned here - * @return The item at the coordinates or NULL if none + * @return The disabled state * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_at_xy_item_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *posret) +EAPI Eina_Bool +elm_genlist_item_disabled_get(const Elm_Genlist_Item *it) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - Evas_Coord ox, oy, ow, oh; - Item_Block *itb; - Evas_Coord lasty; - if (!wd) return NULL; - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); - lasty = oy; - EINA_INLIST_FOREACH(wd->blocks, itb) - { - Eina_List *l; - Elm_Genlist_Item *it; - - if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x, - oy + itb->y - itb->wd->pan_y, - itb->w, itb->h, x, y, 1, 1)) - continue; - EINA_LIST_FOREACH(itb->items, l, it) - { - Evas_Coord itx, ity; - - itx = ox + itb->x + it->x - itb->wd->pan_x; - ity = oy + itb->y + it->y - itb->wd->pan_y; - if (ELM_RECTS_INTERSECT(itx, ity, it->w, it->h, x, y, 1, 1)) - { - if (posret) - { - if (y <= (ity + (it->h / 4))) *posret = -1; - else if (y >= (ity + it->h - (it->h / 4))) *posret = 1; - else *posret = 0; - } - return it; - } - lasty = ity + it->h; - } - } - if (posret) - { - if (y > lasty) *posret = 1; - else *posret = -1; - } - return NULL; + if (!it) return EINA_FALSE; + if (it->delete_me) return EINA_FALSE; + return it->disabled; } /** - * Get the first item in the genlist + * Sets the display only state of an item. * - * This returns the first item in the list. + * A display only item cannot be selected or unselected. It is for display + * only and not selecting or otherwise clicking, dragging etc. by the user, + * thus finger size rules will not be applied to this item. * - * @param obj The genlist object - * @return The first item, or NULL if none + * @param it The item + * @param display_only The display only state * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_first_item_get(const Evas_Object *obj) +EAPI void +elm_genlist_item_display_only_set(Elm_Genlist_Item *it, Eina_Bool display_only) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - if (!wd->items) return NULL; - Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items); - while ((it) && (it->delete_me)) - it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next); - return it; + if (!it) return; + if (!it->block) return; + if (it->display_only == display_only) return; + if (it->delete_me) return; + it->display_only = display_only; + it->mincalcd = EINA_FALSE; + it->updateme = EINA_TRUE; + it->block->updateme = EINA_TRUE; + if (it->wd->update_job) ecore_job_del(it->wd->update_job); + it->wd->update_job = ecore_job_add(_update_job, it->wd); } /** - * Get the last item in the genlist + * Get the display only state of an item * - * This returns the last item in the list. + * This gets the display only state of the given item. * - * @return The last item, or NULL if none + * @param it The item + * @return The display only state * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_last_item_get(const Evas_Object *obj) +EAPI Eina_Bool +elm_genlist_item_display_only_get(const Elm_Genlist_Item *it) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd->items) return NULL; - Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items->last); - if (!wd) return NULL; - while ((it) && (it->delete_me)) - it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev); - return it; + if (!it) return EINA_FALSE; + if (it->delete_me) return EINA_FALSE; + return it->display_only; } /** - * Get the next item in the genlist + * Show the given item * - * This returns the item after the item @p it. + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. * * @param it The item - * @return The item after @p it, or NULL if none * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_item_next_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_item_show(Elm_Genlist_Item *it) { - while (it) + if (!it) return; + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) { - it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next); - if ((it) && (!it->delete_me)) break; + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; } - return (Elm_Genlist_Item *)it; + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + elm_smart_scroller_child_region_show(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y, + it->block->w, it->h); } /** - * Get the previous item in the genlist + * Bring in the given item * - * This returns the item before the item @p it. + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. This may use animation to do so and take a + * period of time * * @param it The item - * @return The item before @p it, or NULL if none * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_item_prev_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_item_bring_in(Elm_Genlist_Item *it) { - while (it) + if (!it) return; + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) { - it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev); - if ((it) && (!it->delete_me)) break; + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; } - return (Elm_Genlist_Item *)it; + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + elm_smart_scroller_region_bring_in(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y, + it->block->w, it->h); } /** - * Get the genlist object from an item + * Show the given item at the top * - * This returns the genlist object itself that an item belongs to. + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. * * @param it The item - * @return The genlist object * * @ingroup Genlist */ -EAPI Evas_Object * -elm_genlist_item_genlist_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_item_top_show(Elm_Genlist_Item *it) { - if (!it) return NULL; - return it->wd->obj; + if (!it) return; + Evas_Coord ow, oh; + + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) + { + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; + } + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); + elm_smart_scroller_child_region_show(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y, + it->block->w, oh); } /** - * Get the parent item of the given item + * Bring in the given item at the top * - * This returns the prent item of the item @p it given. + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. This may use animation to do so and take a + * period of time * * @param it The item - * @return The parent of the item or NULL if none * * @ingroup Genlist */ -EAPI Elm_Genlist_Item * -elm_genlist_item_parent_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_item_top_bring_in(Elm_Genlist_Item *it) { - if (!it) return NULL; - return it->parent; + if (!it) return; + Evas_Coord ow, oh; + + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) + { + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; + } + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); + elm_smart_scroller_region_bring_in(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y, + it->block->w, oh); } /** - * Clear all sub-items (children) of the given item + * Show the given item at the middle * - * This clears all items that are children (or their descendants) of the - * given item @p it. + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. * * @param it The item * * @ingroup Genlist */ EAPI void -elm_genlist_item_subitems_clear(Elm_Genlist_Item *it) +elm_genlist_item_middle_show(Elm_Genlist_Item *it) { - Eina_List *tl = NULL, *l; - Elm_Genlist_Item *it2; - if (!it) return; - EINA_LIST_FOREACH(it->items, l, it2) - tl = eina_list_append(tl, it2); - EINA_LIST_FREE(tl, it2) - elm_genlist_item_del(it2); + Evas_Coord ow, oh; + + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) + { + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; + } + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); + elm_smart_scroller_child_region_show(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y - oh/2 + it->h/2, + it->block->w, oh); } + /** - * Set the selected state of an item + * Bring in the given item at the middle * - * This sets the selected state (1 selected, 0 not selected) of the given - * item @p it. + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. This may use animation to do so and take a + * period of time * * @param it The item - * @param selected The slected state * * @ingroup Genlist */ EAPI void -elm_genlist_item_selected_set(Elm_Genlist_Item *it, Eina_Bool selected) +elm_genlist_item_middle_bring_in(Elm_Genlist_Item *it) { if (!it) return; - ELM_CHECK_WIDTYPE(it->wd->obj, widtype); - Widget_Data *wd = elm_widget_data_get(it->wd->obj); - if (!wd) return; - if (it->delete_me) return; - selected = !!selected; - if (it->selected == selected) return; + Evas_Coord ow, oh; - if (selected) + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) { - if (!wd->multi) - { - while (wd->selected) - _item_unselect(wd->selected->data); - } - _item_hilight(it); - _item_select(it); + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; } - else - _item_unselect(it); -} - -/** - * Get the selected state of an item - * - * This gets the selected state of an item (1 selected, 0 not selected). - * - * @param it The item - * @return The selected state - * - * @ingroup Genlist - */ -EAPI Eina_Bool -elm_genlist_item_selected_get(const Elm_Genlist_Item *it) -{ - if (!it) return EINA_FALSE; - return it->selected; + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); + elm_smart_scroller_region_bring_in(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y - oh/2 + it->h/2, + it->block->w, oh); } /** - * Sets the expanded state of an item (if it's a parent) + * Delete a given item * - * This expands or contracts a parent iterm (thus showing or hiding the - * children). + * This deletes the item from genlist and calls the genlist item del class + * callback defined in the item class, if it is set. * * @param it The item - * @param expanded The expanded state (1 expanded, 0 not expanded). * * @ingroup Genlist */ EAPI void -elm_genlist_item_expanded_set(Elm_Genlist_Item *it, Eina_Bool expanded) +elm_genlist_item_del(Elm_Genlist_Item *it) { if (!it) return; - if (it->expanded == expanded || it->disabled ) return; - it->expanded = expanded; - it->wd->expand_item = it; - it->effect_done = EINA_FALSE; - if (it->expanded) - { - it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND; - if (it->realized) - edje_object_signal_emit(it->base, "elm,state,expanded", "elm"); - evas_object_smart_callback_call(it->wd->obj, "expanded", it); - - } - else + if ((it->relcount > 0) || (it->walking > 0)) { - it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT; - if (it->realized) - edje_object_signal_emit(it->base, "elm,state,contracted", "elm"); - evas_object_smart_callback_call(it->wd->obj, "contracted", it); - + elm_genlist_item_subitems_clear(it); + it->delete_me = EINA_TRUE; + if (it->wd->show_item == it) it->wd->show_item = NULL; + if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); + if (it->block) + { + if (it->realized) _item_unrealize(it); + it->block->changed = EINA_TRUE; + 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->itc->func.del) + it->itc->func.del((void *)it->data, it->wd->obj); + return; } - } + _item_del(it); +} /** - * Get the expanded state of an item + * Set the data item from the genlist item * - * This gets the expanded state of an item + * This set the data value passed on the elm_genlist_item_append() and + * related item addition calls. This function will also call + * elm_genlist_item_update() so the item will be updated to reflect the + * new data. * * @param it The item - * @return Thre expanded state - * - * @ingroup Genlist - */ -EAPI Eina_Bool -elm_genlist_item_expanded_get(const Elm_Genlist_Item *it) -{ - if (!it) return EINA_FALSE; - return it->expanded; -} - -/** - * Get the depth of expanded item - * - * @param it The genlist item object - * @return The depth of expanded item + * @param data The new data pointer to set * * @ingroup Genlist */ -EAPI int -elm_genlist_item_expanded_depth_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_item_data_set(Elm_Genlist_Item *it, const void *data) { - if (!it) return 0; - return it->expanded_depth; + if (!it) return; + it->data = data; + elm_genlist_item_update(it); } /** - * Sets the disabled state of an item. + * Get the data item from the genlist item * - * A disabled item cannot be selected or unselected. It will also change - * appearance to appear disabled. This sets the disabled state (1 disabled, 0 - * not disabled). + * This returns the data value passed on the elm_genlist_item_append() and + * related item addition calls. * * @param it The item - * @param disabled The disabled state + * @return The data pointer provided when created * * @ingroup Genlist */ -EAPI void -elm_genlist_item_disabled_set(Elm_Genlist_Item *it, Eina_Bool disabled) +EAPI const void * +elm_genlist_item_data_get(const Elm_Genlist_Item *it) { - if (!it) return; - if (it->disabled == disabled) return; - if (it->delete_me) return; - it->disabled = disabled; - if (it->realized) - { - if (it->disabled) - edje_object_signal_emit(it->base, "elm,state,disabled", "elm"); - else - edje_object_signal_emit(it->base, "elm,state,enabled", "elm"); - } + if (!it) return NULL; + return it->data; } /** - * Get the disabled state of an item + * Get the real evas object of the genlist item * - * This gets the disabld state of the given item. + * This returns the actual evas object used for the specified genlist item. + * This may be NULL as it may not be created, and ma be deleted at any time + * by genlist. Do not modify this object (move, resize, show, hide etc.) as + * genlist is controlling it. This function is for querying, emitting + * custom signals or hooking lower level callbacks for events. Do not + * delete this object under any circumstances. * * @param it The item - * @return The disabled state + * @return The objct pointer * * @ingroup Genlist */ -EAPI Eina_Bool -elm_genlist_item_disabled_get(const Elm_Genlist_Item *it) +EAPI const Evas_Object * +elm_genlist_item_object_get(const Elm_Genlist_Item *it) { - if (!it) return EINA_FALSE; - if (it->delete_me) return EINA_FALSE; - return it->disabled; + if (!it) return NULL; + return it->base; } /** - * Sets the display only state of an item. + * Update the contents of an item * - * A display only item cannot be selected or unselected. It is for display - * only and not selecting or otherwise clicking, dragging etc. by the user, - * thus finger size rules will not be applied to this item. + * This updates an item by calling all the item class functions again to get + * the icons, labels and states. Use this when the original item data has + * changed and the changes are desired to be reflected. * * @param it The item - * @param display_only The display only state * * @ingroup Genlist */ EAPI void -elm_genlist_item_display_only_set(Elm_Genlist_Item *it, Eina_Bool display_only) +elm_genlist_item_update(Elm_Genlist_Item *it) { if (!it) return; if (!it->block) return; - if (it->display_only == display_only) return; if (it->delete_me) return; - it->display_only = display_only; it->mincalcd = EINA_FALSE; it->updateme = EINA_TRUE; it->block->updateme = EINA_TRUE; @@ -4271,2044 +3949,2416 @@ elm_genlist_item_display_only_set(Elm_Genlist_Item *it, Eina_Bool display_only) } /** - * Get the display only state of an item + * This sets the horizontal stretching mode * - * This gets the display only state of the given item. + * This sets the mode used for sizing items horizontally. Valid modes are + * ELM_LIST_LIMIT and ELM_LIST_SCROLL. The default is ELM_LIST_SCROLL. This + * mode means that if items are too wide to fit, the scroller will scroll + * horizontally. Otherwise items are expanded to fill the width of the + * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded + * to the viewport width and limited to that size. * - * @param it The item - * @return The display only state + * @param obj The genlist object + * @param mode The mode to use * * @ingroup Genlist */ -EAPI Eina_Bool -elm_genlist_item_display_only_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode) { - if (!it) return EINA_FALSE; - if (it->delete_me) return EINA_FALSE; - return it->display_only; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->mode == mode) return; + wd->mode = mode; + _sizing_eval(obj); } /** - * Show the given item - * - * This causes genlist to jump to the given item @p it and show it (by scrolling), - * if it is not fully visible. + * Gets the horizontal stretching mode * - * @param it The item + * @param obj The genlist object + * @return The mode to use + * (ELM_LIST_LIMIT, ELM_LIST_SCROLL, ELM_LIST_LIMIT) * * @ingroup Genlist */ -EAPI void -elm_genlist_item_show(Elm_Genlist_Item *it) +EAPI Elm_List_Mode +elm_genlist_horizontal_mode_get(const Evas_Object *obj) { - if (!it) return; - if (it->delete_me) return; - if ((it->queued) || (!it->mincalcd)) - { - it->wd->show_item = it; - it->wd->bring_in = 1; - it->showme = EINA_TRUE; - return; - } - if (it->wd->show_item) - { - it->wd->show_item->showme = EINA_FALSE; - it->wd->show_item = NULL; - } - elm_smart_scroller_child_region_show(it->wd->scr, - it->x + it->block->x, - it->y + it->block->y, - it->block->w, it->h); + ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_LIST_LAST; + return wd->mode; } /** - * Bring in the given item + * Set the always select mode. * - * This causes genlist to jump to the given item @p it and show it (by scrolling), - * if it is not fully visible. This may use animation to do so and take a - * period of time + * Items will only call their selection func and callback when first becoming + * selected. Any further clicks will do nothing, unless you enable always + * select with elm_genlist_always_select_mode_set(). This means even if + * selected, every click will make the selected callbacks be called. * - * @param it The item + * @param obj The genlist object + * @param always_select The always select mode + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ EAPI void -elm_genlist_item_bring_in(Elm_Genlist_Item *it) +elm_genlist_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select) { - if (!it) return; - if (it->delete_me) return; - if ((it->queued) || (!it->mincalcd)) - { - it->wd->show_item = it; - it->wd->bring_in = 1; - it->showme = EINA_TRUE; - return; - } - if (it->wd->show_item) - { - it->wd->show_item->showme = EINA_FALSE; - it->wd->show_item = NULL; - } - elm_smart_scroller_region_bring_in(it->wd->scr, - it->x + it->block->x, - it->y + it->block->y, - it->block->w, it->h); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->always_select = always_select; } /** - * Show the given item at the top - * - * This causes genlist to jump to the given item @p it and show it (by scrolling), - * if it is not fully visible. + * Get the always select mode. * - * @param it The item + * @param obj The genlist object + * @return The always select mode + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ -EAPI void -elm_genlist_item_top_show(Elm_Genlist_Item *it) +EAPI Eina_Bool +elm_genlist_always_select_mode_get(const Evas_Object *obj) { - Evas_Coord ow, oh; - - if (!it) return; - if (it->delete_me) return; - if ((it->queued) || (!it->mincalcd)) - { - it->wd->show_item = it; - it->wd->bring_in = 1; - it->showme = EINA_TRUE; - return; - } - if (it->wd->show_item) - { - it->wd->show_item->showme = EINA_FALSE; - it->wd->show_item = NULL; - } - evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); - elm_smart_scroller_child_region_show(it->wd->scr, - it->x + it->block->x, - it->y + it->block->y, - it->block->w, oh); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->always_select; } /** - * Bring in the given item at the top + * Set no select mode * - * This causes genlist to jump to the given item @p it and show it (by scrolling), - * if it is not fully visible. This may use animation to do so and take a - * period of time + * This will turn off the ability to select items entirely and they will + * neither appear selected nor call selected callback functions. * - * @param it The item + * @param obj The genlist object + * @param no_select The no select mode + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ EAPI void -elm_genlist_item_top_bring_in(Elm_Genlist_Item *it) +elm_genlist_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select) { - Evas_Coord ow, oh; - - if (!it) return; - if (it->delete_me) return; - if ((it->queued) || (!it->mincalcd)) - { - it->wd->show_item = it; - it->wd->bring_in = 1; - it->showme = EINA_TRUE; - return; - } - if (it->wd->show_item) - { - it->wd->show_item->showme = EINA_FALSE; - it->wd->show_item = NULL; - } - evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); - elm_smart_scroller_region_bring_in(it->wd->scr, - it->x + it->block->x, - it->y + it->block->y, - it->block->w, oh); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->no_select = no_select; } /** - * Show the given item at the middle - * - * This causes genlist to jump to the given item @p it and show it (by scrolling), - * if it is not fully visible. + * Gets no select mode * - * @param it The item + * @param obj The genlist object + * @return The no select mode + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ -EAPI void -elm_genlist_item_middle_show(Elm_Genlist_Item *it) +EAPI Eina_Bool +elm_genlist_no_select_mode_get(const Evas_Object *obj) { - Evas_Coord ow, oh; - - if (!it) return; - if (it->delete_me) return; - if ((it->queued) || (!it->mincalcd)) - { - it->wd->show_item = it; - it->wd->bring_in = 1; - it->showme = EINA_TRUE; - return; - } - if (it->wd->show_item) - { - it->wd->show_item->showme = EINA_FALSE; - it->wd->show_item = NULL; - } - evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); - elm_smart_scroller_child_region_show(it->wd->scr, - it->x + it->block->x, - it->y + it->block->y - oh/2 + it->h/2, - it->block->w, oh); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->no_select; } - /** - * Bring in the given item at the middle + * Set compress mode * - * This causes genlist to jump to the given item @p it and show it (by scrolling), - * if it is not fully visible. This may use animation to do so and take a - * period of time + * This will enable the compress mode where items are "compressed" horizontally + * to fit the genlist scrollable viewport width. this is special for gnelist. + * do not rely on elm_genlist_horizontal_mode_set() being set to + * ELM_LIST_COMPRESS to work as genlist needs to handle it specially. * - * @param it The item + * @param obj The genlist object + * @param compress The compress mode + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ EAPI void -elm_genlist_item_middle_bring_in(Elm_Genlist_Item *it) +elm_genlist_compress_mode_set(Evas_Object *obj, Eina_Bool compress) { - Evas_Coord ow, oh; - - if (!it) return; - if (it->delete_me) return; - if ((it->queued) || (!it->mincalcd)) - { - it->wd->show_item = it; - it->wd->bring_in = 1; - it->showme = EINA_TRUE; - return; - } - if (it->wd->show_item) - { - it->wd->show_item->showme = EINA_FALSE; - it->wd->show_item = NULL; - } - evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); - elm_smart_scroller_region_bring_in(it->wd->scr, - it->x + it->block->x, - it->y + it->block->y - oh/2 + it->h/2, - it->block->w, oh); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->compress = compress; } /** - * Delete a given item - * - * This deletes the item from genlist and calls the genlist item del class - * callback defined in the item class, if it is set. + * Get the compress mode * - * @param it The item + * @param obj The genlist object + * @return The compress mode + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ -EAPI void -elm_genlist_item_del(Elm_Genlist_Item *it) +EAPI Eina_Bool +elm_genlist_compress_mode_get(const Evas_Object *obj) { - if (!it) return; - if ((it->relcount > 0) || (it->walking > 0)) - { - elm_genlist_item_subitems_clear(it); - it->delete_me = EINA_TRUE; - if (it->wd->show_item == it) it->wd->show_item = NULL; - if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); - if (it->block) - { - if (it->realized) _item_unrealize(it); - it->block->changed = EINA_TRUE; - 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->itc->func.del) - it->itc->func.del((void *)it->data, it->wd->obj); - return; - } - _item_del(it); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->compress; } /** - * Set the data item from the genlist item + * Set bounce mode * - * This set the data value passed on the elm_genlist_item_append() and - * related item addition calls. This function will also call - * elm_genlist_item_update() so the item will be updated to reflect the - * new data. + * This will enable or disable the scroller bounce mode for the genlist. See + * elm_scroller_bounce_set() for details * - * @param it The item - * @param data The new data pointer to set + * @param obj The genlist object + * @param h_bounce Allow bounce horizontally + * @param v_bounce Allow bounce vertically * * @ingroup Genlist */ EAPI void -elm_genlist_item_data_set(Elm_Genlist_Item *it, const void *data) +elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce) { - if (!it) return; - it->data = data; - elm_genlist_item_update(it); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce); } /** - * Get the data item from the genlist item - * - * This returns the data value passed on the elm_genlist_item_append() and - * related item addition calls. + * Get the bounce mode * - * @param it The item - * @return The data pointer provided when created + * @param obj The genlist object + * @param h_bounce Allow bounce horizontally + * @param v_bounce Allow bounce vertically * * @ingroup Genlist */ -EAPI const void * -elm_genlist_item_data_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce) { - if (!it) return NULL; - return it->data; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_bounce_allow_get(obj, h_bounce, v_bounce); } /** - * Get the real evas object of the genlist item + * Set homogenous mode * - * This returns the actual evas object used for the specified genlist item. - * This may be NULL as it may not be created, and ma be deleted at any time - * by genlist. Do not modify this object (move, resize, show, hide etc.) as - * genlist is controlling it. This function is for querying, emitting - * custom signals or hooking lower level callbacks for events. Do not - * delete this object under any circumstances. + * This will enable the homogeneous mode where items are of the same height and width + * so that genlist may do the lazy-loading at its maximum. This implies 'compressed' mode * - * @param it The item - * @return The objct pointer + * @param obj The genlist object + * @param homogeneous Assume the items within the genlist are of the same height and width + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ -EAPI const Evas_Object * -elm_genlist_item_object_get(const Elm_Genlist_Item *it) +EAPI void +elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous) { - if (!it) return NULL; - return it->base; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE); + wd->homogeneous = homogeneous; } /** - * Update the contents of an item - * - * This updates an item by calling all the item class functions again to get - * the icons, labels and states. Use this when he original item data has - * changed and the changes are desired to be reflected. + * Get the homogenous mode * - * @param it The item + * @param obj The genlist object + * @return Assume the items within the genlist are of the same height and width + * (EINA_TRUE = on, EINA_FALSE = off) * * @ingroup Genlist */ -EAPI void -elm_genlist_item_update(Elm_Genlist_Item *it) +EAPI Eina_Bool +elm_genlist_homogeneous_get(const Evas_Object *obj) { - if (!it) return; - if (!it->block) return; - if (it->delete_me) return; - it->mincalcd = EINA_FALSE; - it->updateme = EINA_TRUE; - it->block->updateme = EINA_TRUE; - if (it->wd->update_job) ecore_job_del(it->wd->update_job); - it->wd->update_job = ecore_job_add(_update_job, it->wd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->homogeneous; } /** - * This sets the horizontal stretching mode + * Set the maximum number of items within an item block * - * This sets the mode used for sizing items horizontally. Valid modes are - * ELM_LIST_LIMIT and ELM_LIST_SCROLL. The default is ELM_LIST_SCROLL. This - * mode means that if items are too wide to fit, the scroller will scroll - * horizontally. Otherwise items are expanded to fill the width of the - * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded - * to the viewport width and limited to that size. + * This will configure the block count to tune to the target with particular performance matrix. * * @param obj The genlist object - * @param mode The mode to use + * @param n Maximum number of items within an item block * * @ingroup Genlist */ EAPI void -elm_genlist_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode) +elm_genlist_block_count_set(Evas_Object *obj, int n) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - if (wd->mode == mode) return; - wd->mode = mode; - _sizing_eval(obj); + wd->max_items_per_block = n; } /** - * Gets the horizontal stretching mode + * Get the maximum number of items within an item block * * @param obj The genlist object - * @return The mode to use - * (ELM_LIST_LIMIT, ELM_LIST_SCROLL, ELM_LIST_LIMIT) + * @return Maximum number of items within an item block * * @ingroup Genlist */ -EAPI Elm_List_Mode -elm_genlist_horizontal_mode_get(const Evas_Object *obj) +EAPI int +elm_genlist_block_count_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST; + ELM_CHECK_WIDTYPE(obj, widtype) 0; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return ELM_LIST_LAST; - return wd->mode; + if (!wd) return 0; + return wd->max_items_per_block; } /** - * Set the always select mode. - * - * Items will only call their selection func and callback when first becoming - * selected. Any further clicks will do nothing, unless you enable always - * select with elm_genlist_always_select_mode_set(). This means even if - * selected, every click will make the selected callbacks be called. - * + * Set the timeout in seconds for the longpress event + * * @param obj The genlist object - * @param always_select The always select mode - * (EINA_TRUE = on, EINA_FALSE = off) - * + * @param timeout timeout in seconds + * * @ingroup Genlist */ EAPI void -elm_genlist_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select) +elm_genlist_longpress_timeout_set(Evas_Object *obj, double timeout) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - wd->always_select = always_select; + wd->longpress_timeout = timeout; } /** - * Get the always select mode. - * + * Get the timeout in seconds for the longpress event + * * @param obj The genlist object - * @return The always select mode - * (EINA_TRUE = on, EINA_FALSE = off) - * + * @return timeout in seconds + * * @ingroup Genlist */ -EAPI Eina_Bool -elm_genlist_always_select_mode_get(const Evas_Object *obj) +EAPI double +elm_genlist_longpress_timeout_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) 0; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - return wd->always_select; + if (!wd) return 0; + return wd->longpress_timeout; } -/** - * Set no select mode - * - * This will turn off the ability to select items entirely and they will - * neither appear selected nor call selected callback functions. - * - * @param obj The genlist object - * @param no_select The no select mode - * (EINA_TRUE = on, EINA_FALSE = off) - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select) +// added for item moving animation. + static Eina_Bool +_group_item_contract_moving_effect_timer_cb(void *data) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->no_select = no_select; -} + Evas_Object *obj = (Evas_Object *)data; + Widget_Data *wd = elm_widget_data_get(obj); -/** - * Gets no select mode - * - * @param obj The genlist object - * @return The no select mode - * (EINA_TRUE = on, EINA_FALSE = off) - * - * @ingroup Genlist - */ -EAPI Eina_Bool -elm_genlist_no_select_mode_get(const Evas_Object *obj) -{ - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - return wd->no_select; -} + Item_Block *itb = NULL; + Elm_Genlist_GroupItem *git; + Elm_Genlist_Item *it; + const Eina_List *l; + int cnt = 0, git_count = 0; + double added_gy = 1; -/** - * Set compress mode - * - * This will enable the compress mode where items are "compressed" horizontally - * to fit the genlist scrollable viewport width. - * - * @param obj The genlist object - * @param no_select The compress mode - * (EINA_TRUE = on, EINA_FALSE = off) - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_compress_mode_set(Evas_Object *obj, Eina_Bool compress) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->compress = compress; -} + int hide_git = 0, git_cnt = 0, list_start_y = 0; -/** - * Get the compress mode - * - * @param obj The genlist object - * @return The compress mode - * (EINA_TRUE = on, EINA_FALSE = off) - * - * @ingroup Genlist - */ -EAPI Eina_Bool -elm_genlist_compress_mode_get(const Evas_Object *obj) -{ - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - return wd->compress; + int *git_array = NULL; + int base_git = 0, base_git_num = 0; + int tmp_y = 0, devide_size = 1; + double t; + + Eina_Bool finish = EINA_FALSE; + + Evas_Coord ox, oy, ow, oh; + if(!wd) + return ECORE_CALLBACK_CANCEL; + + if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) + return ECORE_CALLBACK_CANCEL; + + git_array = (int*)malloc(sizeof(int) * wd->max_git_num); + t = ecore_loop_time_get(); + + if (t - wd->effect_start >= 5.0) + finish = EINA_TRUE; + + if(wd->item_count < 100) + devide_size = 8 * _elm_config->scale; + else if(wd->item_count < 500) + devide_size = (8 - (devide_size / 100 )) * _elm_config->scale; + else + devide_size = 2 * _elm_config->scale; + + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + + list_start_y = oy; + + EINA_INLIST_FOREACH(wd->group_items, git) + { + git_array[git_cnt++] = git->y; + if(git->y < list_start_y) + hide_git++; + edje_object_signal_emit(git->base, "elm,state,alpha,disable", "elm"); + } + base_git_num = hide_git; + + EINA_INLIST_FOREACH(wd->group_items, git) + { + base_git = oy + git->h * (git->num-1) + git->num; + git->old_y = git->y; + added_gy = abs(base_git - git->y) / devide_size; + if(added_gy < 1.0) + added_gy = 1.0; + + if (!git->down && git->old_y < list_start_y) + { + git->finish_y = base_git; + git->down = 1; + git->y = list_start_y - (git->h+1) * hide_git--; + + git->old_y = 0; + } + else if (!git->down && git->y < base_git ) + git->down = 1; + + if(wd->pinch_zoom_reserve) + git->y = base_git; + else + { + + if (git->down) + { + if (git->y < base_git) + { + git->y +=added_gy; + if (git->y > base_git) + git->y = base_git; + } + } + else + { + if (git->y > base_git) + git->y -= added_gy; + + if (git->y < base_git) + git->y = base_git; + } + } + if (git->num - 1 == cnt && git->y == base_git) + git_count++; + + evas_object_resize(git->base, wd->minw, git->h ); + evas_object_move(git->base, git->x, git->y); + evas_object_raise(git->base); + evas_object_show(git->base); + + EINA_INLIST_FOREACH(wd->blocks, itb) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->group_item == git) + { + if (it->group_item->old_y) + it->old_scrl_y -= (it->group_item->old_y - it->group_item->y); + + if(git_array[it->group_item->num+1] <= it->old_scrl_y || added_gy == 1.0) + evas_object_color_set(it->base, 0,0,0,0); + + _move_edit_controls(it,it->scrl_x, it->scrl_y); + evas_object_resize(it->base, itb->wd->minw-(it->pad_left+it->pad_right), it->h); + evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); + evas_object_raise(it->group_item->base); + evas_object_show(it->base); + } + } + } + if (git_count == git_cnt ) + { + finish = EINA_TRUE; + break; + } + + cnt++; + } + free(git_array); + + if(finish) // finish animation + { + added_gy = 1; + EINA_INLIST_FOREACH(wd->group_items, git) + git->down = 0; + + wd->pan_y = 0; + wd->contract_pan_y = 0; + wd->pinch_zoom_reserve = EINA_FALSE; + wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH; + elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0); + elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); + +// fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT FINISH \n"); + + tmp_y =0 ; + // added for event + EINA_INLIST_FOREACH(wd->blocks, itb) + { + if(itb->realized) { + EINA_LIST_FOREACH(itb->items, l, it) + { + if(it->realized) { + it->scrl_y = oy + tmp_y; + tmp_y += it->h; + // need to handle edit mode + evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); + evas_object_color_set(it->base, 0,0,0,0); + evas_object_show(it->base); + } + } + } + + } + evas_object_lower(wd->alpha_bg); + evas_object_hide(wd->alpha_bg); + + return ECORE_CALLBACK_CANCEL; + } + + return ECORE_CALLBACK_RENEW; +} + +// added for item moving animation. + static Eina_Bool +_group_item_expand_moving_effect_timer_cb(void *data) +{ + Evas_Object *obj = (Evas_Object *)data; + Widget_Data *wd = elm_widget_data_get(obj); + Elm_Genlist_GroupItem *git, *tmp_git; + Item_Block *itb = NULL; + Elm_Genlist_Item *it; + const Eina_List *l; + int cnt = 0, git_count = 0, git_cnt = 0, git_tmp_y = 0, in = 0, start_in = 0; + int tmp = 0, show_git_cnt = 0, scroll_y = 0, top_git = 0 , git_h = 0, scroll_pan_y = 0, down = 0; + int up_cnt = 1, down_cnt = 1, it_h = 0, devide_size = 1; + static int last_git_y = 0; + + double t; + + Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; + + static double added_gy = 0; // temp value for animation speed + static double added_gy2 = 0; + Eina_Bool finish = EINA_FALSE; + if (!wd) + return ECORE_CALLBACK_CANCEL; + + if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) + return ECORE_CALLBACK_CANCEL; + + t = ecore_loop_time_get(); + + top_git = wd->pinch_it; + + if (top_git< 1) + top_git = 1; + else if (top_git >= wd->max_git_num) + top_git = wd->max_git_num - 1; + + if(wd->item_count < 100) + devide_size = 8 * _elm_config->scale; + else if(wd->item_count < 500) + devide_size = (8 - (devide_size / 100 )) * _elm_config->scale; + else + devide_size = 2 * _elm_config->scale; + + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); + + // calculate git count and srcroll move position + EINA_INLIST_FOREACH(wd->group_items, git) + { + if (git_cnt == top_git - 1) + scroll_y = tmp; + + if (!scroll_y) + { + EINA_INLIST_FOREACH(wd->blocks, itb) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->group_item == git ) + tmp += it->h; + it_h = it->h; + } + } + } + git_h = git->h; + git_cnt++; + + } + scroll_pan_y = scroll_y + git_h * (top_git-1) ; + + if (t - wd->effect_start >= 5.0) + finish = EINA_TRUE; + + // items realize + EINA_INLIST_FOREACH(wd->blocks, itb) + { + if((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh) + || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh)) + { + if (!itb->realized) + { + start_in = in; + EINA_LIST_FOREACH(itb->items, l, it) + { + _item_realize(it, start_in, 0); + it->realized = EINA_TRUE; + start_in++; + } + itb->realized = EINA_TRUE; + itb->want_unrealize = EINA_FALSE; + + } + } + else + { + if (itb->realized) _item_block_unrealize(itb); + } + in += itb->count; + } + + // set group item finish y and items y position of group item and items. + tmp = 0; + git_tmp_y = oy; + EINA_INLIST_FOREACH(wd->group_items, git) + { + if (git->num >= top_git) + { + git->finish_y = git_tmp_y; + git_tmp_y += git->h; + tmp = git->y + git->h; + + } + else + git->finish_y = -1 * oh; + + EINA_INLIST_FOREACH(wd->blocks, itb) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->group_item == git ) + { + if(git->finish_y != -1 * oh) + { + it->old_scrl_y = tmp; + git_tmp_y += it->h; + added_gy2 = abs(git->finish_y - git->y) / devide_size; + tmp += it->h - added_gy2; + } + else + it->old_scrl_y = -1 * oh; + } + } + } + + if (git->finish_y >= oy && git->finish_y < oy+oh) + show_git_cnt++; + } + + EINA_INLIST_FOREACH(wd->group_items, git) + { + down = 0; + + evas_object_move(git->base, git->x, git->y); + evas_object_raise(git->base); + evas_object_show(git->base); + + added_gy = abs(git->finish_y - git->y) / devide_size; + if(added_gy < 1.0) + added_gy = 1.0; + if(git->y > git->finish_y) { + if (git->y > oy) + git->y -= added_gy; + + + if(git->num >= top_git) + up_cnt++; + down = 0; + + } + else if(git->y < git->finish_y) { + git->y += added_gy; + down_cnt++; + down = 1; + } + + if( (!down && git->y < git->finish_y) || (down && git->y > git->finish_y) ) + git->y = git->finish_y; + + if (git_cnt-1 == cnt) + last_git_y = git->y; + + if (git->num == top_git && git->y == oy) + { + evas_object_move(git->base, git->x, git->y); + evas_object_show(git->base); + git_count = 0; + EINA_INLIST_FOREACH(wd->group_items, tmp_git) + { + if (tmp_git->y == tmp_git->finish_y && tmp_git->y > oy && tmp_git->y < oy+oh ) + { + git_count++; + } + } + } + + EINA_INLIST_FOREACH(wd->blocks, itb) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->group_item == git) + { + + if((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh) + || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh)) + + { + evas_object_resize(it->base, wd->minw-(it->pad_left+it->pad_right), it->h); + evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); + evas_object_color_set(it->base, 255,255,255,255); + evas_object_raise(it->base); + evas_object_raise(it->group_item->base); + + } + } + } + } + + cnt++; + + if(git_count + 1 == show_git_cnt ) + { + finish = EINA_TRUE; + } + + } + if(finish) + { + added_gy = 0; + added_gy2 = 0; + last_git_y = 0; + + wd->pan_y = scroll_y + (git_h) * (top_git-1) ; + + EINA_INLIST_FOREACH(wd->group_items, git) + { + edje_object_signal_emit(git->base, "elm,state,alpha,enable", "elm"); + } + EINA_INLIST_FOREACH(wd->blocks, itb) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + _item_unselect(it); + } + } + + + wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE; + fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND FINISH \n"); + elm_smart_scroller_hold_set(wd->scr, 0); + elm_smart_scroller_freeze_set(wd->scr, 0); + elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0); + elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); +// printf("_group_item_expand_moving_effect_timer_cb FINISH \n"); + evas_object_lower(wd->alpha_bg); + evas_object_hide(wd->alpha_bg); + // evas_object_smart_changed(wd->pan_smart); + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); + + return ECORE_CALLBACK_CANCEL; + } + + return ECORE_CALLBACK_RENEW; +} + + static int +_item_pinch_recalc(Evas_Object *obj, int emode) +{ + Item_Block *itb = NULL; + + Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; + Widget_Data *wd = elm_widget_data_get(obj); + + if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND) + return EINA_FALSE; + + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); + + if (emode) + { + if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) + { + wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT; + + elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1); + elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_FALSE); + evas_object_raise(wd->alpha_bg); + evas_object_show(wd->alpha_bg); + + wd->effect_start = ecore_loop_time_get(); + wd->item_moving_effect_timer = ecore_animator_add(_group_item_contract_moving_effect_timer_cb, obj); + } + } + else if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH) + { + elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1); + + evas_object_raise(wd->alpha_bg); + evas_object_show(wd->alpha_bg); + + wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND; + EINA_INLIST_FOREACH(wd->blocks, itb) + { + if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, + itb->y - wd->pan_y + oy, + itb->w, itb->h, + cvx, cvy, cvw, cvh)) + { + if (itb->realized) _item_block_unrealize(itb); + itb->realized = EINA_FALSE; + } + } + + wd->effect_start = ecore_loop_time_get(); + wd->item_moving_effect_timer = ecore_animator_add(_group_item_expand_moving_effect_timer_cb, obj); + } + + return EINA_TRUE; } -/** - * Set bounce mode - * - * This will enable or disable the scroller bounce mode for the genlist. See - * elm_scroller_bounce_set() for details - * - * @param obj The genlist object - * @param h_bounce Allow bounce horizontally - * @param v_bounce Allow bounce vertically - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce) +static Evas_Object* +create_tray_alpha_bg(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; - elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce); + if (!wd) return NULL; + + Evas_Object *bg = NULL; + Evas_Coord ox, oy, ow, oh; + + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj)); + evas_object_color_set(bg , 0,0,0,0); + evas_object_resize(bg , ow, oh); + evas_object_move(bg , ox, oy); + evas_object_show(bg ); + evas_object_hide(bg ); + return bg ; } -/** - * Get the bounce mode - * - * @param obj The genlist object - * @param h_bounce Allow bounce horizontally - * @param v_bounce Allow bounce vertically - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce) +static void +_elm_genlist_pinch_zoom_execute(Evas_Object *obj, Eina_Bool emode) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_smart_scroller_bounce_allow_get(obj, h_bounce, v_bounce); + + if (!wd || !wd->pinch_zoom) return; + + if(!wd->queue_idler) + { + + if(!wd->alpha_bg) + wd->alpha_bg = create_tray_alpha_bg(obj); + + _item_pinch_recalc(obj, emode); + } } /** - * Set homogenous mode - * - * This will enable the homogeneous mode where items are of the same height and width - * so that genlist may do the lazy-loading at its maximum. This implies 'compressed' mode - * + * Set pinch zoom mode + * * @param obj The genlist object - * @param homogeneous Assume the items within the genlist are of the same height and width - * (EINA_TRUE = on, EINA_FALSE = off) - * + * @param emode + * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out) + * * @ingroup Genlist */ EAPI void -elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous) +elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Eina_Bool emode) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE); - wd->homogeneous = homogeneous; + if (!wd || !wd->pinch_zoom) return; + wd->pinch_zoom_reserve = emode; } /** - * Get the homogenous mode - * + * Get pinch zoom mode + * * @param obj The genlist object - * @return Assume the items within the genlist are of the same height and width - * (EINA_TRUE = on, EINA_FALSE = off) - * + * @return The pinch mode + * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out) + * * @ingroup Genlist */ EAPI Eina_Bool -elm_genlist_homogeneous_get(const Evas_Object *obj) +elm_genlist_pinch_zoom_mode_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return EINA_FALSE; - return wd->homogeneous; + if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH) + return EINA_TRUE; + else return EINA_FALSE; } -/** - * Set the maximum number of items within an item block - * - * This will configure the block count to tune to the target with particular performance matrix. - * - * @param obj The genlist object - * @param n Maximum number of items within an item block - * - * @ingroup Genlist - */ EAPI void -elm_genlist_block_count_set(Evas_Object *obj, int n) +elm_genlist_pinch_zoom_set(Evas_Object *obj, Eina_Bool emode) { - ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - wd->max_items_per_block = n; + wd->pinch_zoom = emode; } -/** - * Get the maximum number of items within an item block - * - * @param obj The genlist object - * @return Maximum number of items within an item block - * - * @ingroup Genlist - */ -EAPI int -elm_genlist_block_count_get(const Evas_Object *obj) -{ - ELM_CHECK_WIDTYPE(obj, widtype) 0; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return 0; - return wd->max_items_per_block; -} -/** - * Set the Genlist Internal scroller scrollbar policy - * - * This sets the Genlist Internal scrollbar visibility policy. - * ELM_SMART_SCROLLER_POLICY_AUTO means the scrollbar is made visible if it - * is needed, and otherwise kept hidden. ELM_SMART_SCROLLER_POLICY_ON turns - * it on all the time, and ELM_SMART_SCROLLER_POLICY_OFF always keeps it off. - * This applies respectively for the horizontal and vertical scrollbars. - * - * @param obj The Genlist object - * @param policy_h Horizontal scrollbar policy - * @param policy_v Vertical scrollbar policy - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v) +// added for item moving animation. +static Eina_Bool +_item_moving_effect_timer_cb(void *data) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; + Widget_Data *wd = data; + Item_Block *itb; + Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - const Elm_Scroller_Policy map[3] = - { - ELM_SMART_SCROLLER_POLICY_AUTO, - ELM_SMART_SCROLLER_POLICY_ON, - ELM_SMART_SCROLLER_POLICY_OFF - }; - if ((policy_h < 0) || (policy_h >= 3) || (policy_v < 0) || (policy_v >= 3)) - return; + if (!wd) return EINA_FALSE; - elm_smart_scroller_policy_set(wd->scr, map[policy_h], map[policy_v]); + Elm_Genlist_Item *it; + const Eina_List *l; + int expanded_cnt = 0; + int cnt = 0; + static double added_gy =25; + static int count = 0; + + if(added_gy < 1) + added_gy = 1; + + count++; + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); + + EINA_INLIST_FOREACH(wd->blocks, itb) + { + itb->w = wd->minw; + if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, + itb->y - wd->pan_y + oy, + itb->w, itb->h, + cvx, cvy, cvw, cvh)) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + if (!it->old_scrl_y) + it->old_scrl_y = it->scrl_y; + if(it->parent && it->parent->expanded && !it->showme) + { + evas_object_hide(it->base); + } + else evas_object_show(it->base); + + evas_object_show(it->base); + + if(itb && itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND) + { + + if(it->old_scrl_y && it->old_scrl_y < it->scrl_y) { + + it->old_scrl_y += added_gy; + + } + + if(it->old_scrl_y >= it->scrl_y) { + it->list_expanded = 1; + it->old_scrl_y = it->scrl_y; + } + + } + + else if(itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT) + { + if(it->old_scrl_y && it->old_scrl_y > it->scrl_y) + { + + it->old_scrl_y -= added_gy; + } + + if(it->old_scrl_y <= it->scrl_y) { + it->list_expanded = 1; + it->old_scrl_y = it->scrl_y; + } + + } + expanded_cnt += it->list_expanded; + cnt++; + + _move_edit_controls( it,it->scrl_x, it->scrl_y ); + evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h); + + evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); + + evas_object_raise(it->base); + } + } + } + if(expanded_cnt == cnt) { + + if(wd->item_moving_effect_timer) { + added_gy = 25; + count = 0; + wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; + EINA_INLIST_FOREACH(wd->blocks, itb) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + it->list_expanded = 0; + } + } + + } + return ECORE_CALLBACK_CANCEL; + } + return ECORE_CALLBACK_RENEW; } -EAPI void -elm_genlist_set_edit_mode(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class) +// added for edit mode item moving animation. +static Eina_Bool +_edit_mode_item_moving_effect_cb(void *data) { - fprintf(stderr, "=================> Caution!!! <========================\n"); - fprintf(stderr, "==> elm_genlist_set_edit_mode() is deprecated. <=======\n"); - fprintf(stderr, "==> Please use elm_genlist_edit_mode_set() instead. <==\n"); - fprintf(stderr, "=======================================================\n"); + Widget_Data *wd = data; + Item_Block *itb; + Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - elm_genlist_edit_mode_set(obj, emode, edit_class); -} + if (!wd) return EINA_FALSE; -/** - * Set Genlist edit mode - * - * This sets Genlist edit mode. - * - * @param obj The Genlist object - * @param emode ELM_GENLIST_EDIT_MODE_{NONE & REORDER & INSERT & DELETE & SELECT & SELECT_ALL} - * @param edit_class Genlist edit class (Elm_Genlist_Edit_Class structure) - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_edit_mode_set(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class) -{ - Elm_Genlist_Item *it; - Eina_List *l; - Item_Block *itb; + Elm_Genlist_Item *it, *select_all_item; + const Eina_List *l; + int expanded_cnt = 0; + static double added_gy = 9; + static float count = 0; + int finish = 0; - static Elm_Genlist_Item_Class itc; + static float select_all_y = 0; - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if (wd->edit_mode == emode) return; + count++; - wd->edit_mode = emode; + if(!wd->select_all_item) + return ECORE_CALLBACK_CANCEL; - wd->animate_edit_controls = 1; - if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) - wd->edit_mode |= ELM_GENLIST_EDIT_MODE_SELECT; + static float dy = 9; + dy -= 0.5; + if(dy < 1.0) + dy = 1.0f; - if(wd->edit_mode_effect_mode) { - wd->effect_mode = EINA_TRUE; - wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE; - } - if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) - { - if (wd->ed) free (wd->ed); - wd->ed = NULL; - } - else - { - if (!wd->ed) - wd->ed = calloc(1, sizeof(Edit_Data)); + select_all_y += (dy); - wd->ed->ec = edit_class; + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); - if (((wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT)) && !wd->ed->del_confirm) - { - wd->ed->del_confirm = elm_button_add(wd->obj); - elm_button_label_set(wd->ed->del_confirm, "Delete"); - evas_object_smart_member_add(wd->ed->del_confirm, wd->pan_smart); - edje_object_scale_set( wd->ed->del_confirm, elm_widget_scale_get(wd->ed->del_confirm) * - _elm_config->scale); - evas_object_smart_callback_add(wd->ed->del_confirm, "clicked", _delete_confirm_cb, wd ); - } - } EINA_INLIST_FOREACH(wd->blocks, itb) { - EINA_LIST_FOREACH(itb->items, l, it) - { - it->delete_check = 0; - it->del_confirm_state = 0; - _item_unselect(it); - _edit_controls_eval(it); - } - } - - if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) - { - if(edit_class->select_all_item_style && strcmp(edit_class->select_all_item_style, "default")) - itc.item_style = edit_class->select_all_item_style; - else - itc.item_style = "select_all"; - itc.func.label_get = NULL; - itc.func.icon_get = NULL; - itc.func.del = NULL; - itc.func.editmode_get = NULL; + itb->w = wd->minw; + if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, + itb->y - wd->pan_y + oy, + itb->w, itb->h, + cvx, cvy, cvw, cvh)) - wd->select_all_item = _item_new(wd, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + { + EINA_LIST_FOREACH(itb->items, l, it) + { - if (!wd) return; - if (!wd->select_all_item) return; + evas_object_show(it->base); + if(it->old_pad_left < it->pad_left) { - _item_realize(wd->select_all_item, 0, 0); - edje_object_signal_callback_add(wd->select_all_item->base, "elm,action,select,press", "elm", _select_all_down, wd->select_all_item); + it->old_pad_left += dy; - wd->select_all_item->rel = NULL; - wd->select_all_item->selected = 0; - wd->select_all_item->before = 1; - wd->select_all_item->block = NULL; - wd->select_all_minh = wd->minh + wd->select_all_item->h; - } - else if(wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE) - { - if (wd->select_all_item) - { - if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item); - free(wd->select_all_item); - } - wd->select_all_item = NULL; + if(it->old_pad_left >= it->pad_left) { + it->list_expanded = 1; + it->old_pad_left = it->pad_left; + } - } - edje_object_signal_emit(wd->scr, "elm,state,edit,animated,enable", "elm"); + } - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); -} + if(it->old_pad_left > it->pad_left) + { + it->old_pad_left -= dy; + if(it->old_pad_left <= it->pad_left) { + it->list_expanded = 1; + it->old_pad_left = it->pad_left; + } -/** - * Delete selected items in genlist edit mode. - * - * @param obj The genlist object - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_edit_selected_items_del(Evas_Object *obj) -{ - Elm_Genlist_Item *it; - Eina_List *l; - Item_Block *itb = NULL; - Evas_Object *icon; - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if(!wd->blocks) return; + } - - EINA_INLIST_FOREACH(wd->blocks, itb) - { - if(!wd->blocks) break; - - if (itb ) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->delete_check) - { - it->wd->effect_mode = EINA_TRUE; - - if(!wd->selct_all) - { - itb->wd->minh -= it->h; - itb->wd->select_all_minh -= it->h; - } - if ((it->relcount > 0) || (it->walking > 0)) - { - elm_genlist_item_subitems_clear(it); - it->delete_me = EINA_TRUE; - if (it->wd->show_item == it) it->wd->show_item = NULL; - if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); - if (it->block) - { - if (it->realized) _item_unrealize(it); - it->block->changed = EINA_TRUE; - } - if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj); - return; - } + if(it->old_scrl_y < it->scrl_y) { - it->wd->walking -= it->walking; - if (it->wd->show_item == it) it->wd->show_item = NULL; - if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); - if (it->realized) _item_unrealize(it); + it->old_scrl_y += (dy) ; + if(it->old_scrl_y >= it->scrl_y) { + it->list_expanded = 1; + it->old_scrl_y = it->scrl_y; + } - EINA_LIST_FREE(it->edit_icon_objs, icon) - evas_object_del(icon); + } - Evas_Object *editfield; - EINA_LIST_FREE(it->wd->edit_field, editfield) - evas_object_del(editfield); + if(it->old_scrl_y > it->scrl_y) + { + it->old_scrl_y -= (dy); - evas_object_del(it->edit_obj); - it->edit_obj = NULL; + if(it->old_scrl_y <= it->scrl_y) { + it->list_expanded = 1; + it->old_scrl_y = it->scrl_y; + } - itb->items = eina_list_remove(itb->items, it); - itb->count--; - itb->changed = EINA_TRUE; - if ((!it->delete_me) && (it->itc->func.del)) - it->itc->func.del(it->data, it->wd->obj); - it->delete_me = EINA_TRUE; - if (it->queued) - it->wd->queue = eina_list_remove(it->wd->queue, it); - it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it)); - if (it->parent) - it->parent->items = eina_list_remove(it->parent->items, it); - if (it->long_timer) ecore_timer_del(it->long_timer); - if( it->group_item ) - it->group_item->items = eina_list_remove(it->group_item->items,it); + } - free(it); - } - } - } - } + select_all_item = itb->wd->select_all_item; + evas_object_resize(select_all_item->base, itb->w, select_all_item->h); + if(wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) + evas_object_move(select_all_item->base, ox, oy - select_all_y); + else if( select_all_y <= select_all_item->h) + evas_object_move(select_all_item->base, ox, oy - select_all_item->h + select_all_y); + evas_object_raise(select_all_item->base); - evas_render(evas_object_evas_get(wd->obj)); - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); -} + evas_object_show(select_all_item->base); -EAPI void -elm_genlist_selected_items_del(Evas_Object *obj) -{ - fprintf(stderr, "=================> Caution!!! <========================\n"); - fprintf(stderr, "==> elm_genlist_selected_items_del() is deprecated. <=======\n"); - fprintf(stderr, "==> Please use elm_genlist_edit_selected_items_del() instead. <==\n"); - fprintf(stderr, "=======================================================\n"); - elm_genlist_edit_selected_items_del(obj); -} + expanded_cnt += it->list_expanded; -/** - * Get a list of selected items in genlist - * - * This returns a list of the selected items in the genlist. The list - * contains Elm_Genlist_Item pointers. The list must be freed by the - * caller when done with eina_list_free(). The item pointers in the list - * are only vallid so long as those items are not deleted or the genlist is - * not deleted. - * - * @param obj The genlist object - * @return The list of selected items, nor NULL if none are selected. - * - * @ingroup Genlist - */ -EAPI Eina_List * -elm_genlist_edit_selected_items_get(const Evas_Object *obj) -{ - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - Eina_List *list = NULL; - Item_Block *itb; - if (!wd) return NULL; - - EINA_INLIST_FOREACH(wd->blocks, itb) - { - Eina_List *l; - Elm_Genlist_Item *it; + evas_object_move(it->base, it->scrl_x+it->old_pad_left, it->old_scrl_y); + evas_object_move(it->edit_obj, it->scrl_x, it->old_scrl_y); + evas_object_raise(it->edit_obj); + evas_object_raise(it->base); - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->delete_check) list = eina_list_append(list, it); - } + evas_object_show(it->edit_obj); + evas_object_show(it->base); - } - return list; -} + if(select_all_y >= wd->select_all_item->h && it->list_expanded == 1) + { + finish = 1; + evas_object_raise(it->edit_obj); + break; + } -/** - * Set a given item's rename mode - * - * This renames the item's label from genlist - * - * @param it The item - * @param emode set if emode is EINA_TRUE, unset if emode is EINA_FALSE - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_item_rename_mode_set(Elm_Genlist_Item *it, int emode) -{ - if (!it) return; + } + } + } - const Eina_List *l, *list, *l2; - const char *label, *rename_swallow_part; - char *s; - Eina_Bool done = EINA_FALSE; - int label_cnt = 0 , swallow_part_cnt = 0; + if(finish) { - Item_Block *itb; - Evas_Object *editfield; - Evas_Object *entry; - int edit_field_cnt = 0; - Evas_Object *icon; + if(wd->item_moving_effect_timer) { + added_gy = 9; + count = 0; + select_all_y = 0; + dy = 9; + wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; + EINA_INLIST_FOREACH(wd->blocks, itb) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + it->list_expanded = 0; + } + } + if(wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) + { + if (wd->select_all_item) + { + if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item); + free(wd->select_all_item); + } + wd->select_all_item = NULL; + } - if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) - { - it->wd->edit_mode = 0xF0; - _edit_controls_eval(it); - } + } + wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; + wd->effect_mode = 0; - EINA_INLIST_FOREACH(it->wd->blocks, itb) - { - if (itb->realized) - { - Eina_List *l; - Elm_Genlist_Item *it; + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); + return ECORE_CALLBACK_CANCEL; + } - done = EINA_TRUE; - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->renamed) - { - it->renamed = EINA_FALSE; + return ECORE_CALLBACK_RENEW; +} - EINA_LIST_FOREACH(it->wd->edit_field, l2, editfield) - { - entry = elm_editfield_entry_get(editfield); - const char *text = elm_entry_entry_get(entry); +// added for item moving animation. +static int +_item_flip_effect_show(void *data) +{ + Widget_Data *wd = data; + Item_Block *itb; + Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - if (it->itc->func.label_changed) - it->itc->func.label_changed( it->data, it, text, edit_field_cnt++); - } - Ecore_IMF_Context *imf = elm_entry_imf_context_get(entry); - ecore_imf_context_input_panel_hide(imf); + if (!wd) return EINA_FALSE; - Evas_Object *editfield; - EINA_LIST_FREE(it->wd->edit_field, editfield) - evas_object_del(editfield); + Elm_Genlist_Item *it; + Evas_Object *base ; + const Eina_List *l; + int start = 0, end = 0; + + evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); - if (it->wd->edit_mode) + + EINA_INLIST_FOREACH(wd->blocks, itb) + { + itb->w = wd->minw; + if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, + itb->y - wd->pan_y + oy, + itb->w, itb->h, + cvx, cvy, cvw, cvh)) { - if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_INSERT)) - edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm"); + EINA_LIST_FOREACH(itb->items, l, it) + { + if(it->parent && it->wd->expand_item == it->parent && !it->effect_done) + { + if(!start) + start = it->scrl_y; + base = (Evas_Object *) it->base; + edje_object_signal_emit(it->base, "flip_item", ""); + end = it->scrl_y + it->h; + it->effect_done = EINA_TRUE; - if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT)) - edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm"); - if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER)) - edje_object_signal_emit(it->edit_obj, "elm,state,rename,disable", "elm"); - } - if (it->edit_obj) - { - evas_object_del(it->edit_obj); - it->edit_obj = NULL; + } + } } - EINA_LIST_FREE(it->edit_icon_objs, icon) - evas_object_del(icon); - } - } - } - else - { - if (done) break; } - } - // if (emode != ELM_GENLIST_RENAME_MODE_NONE) - if (emode != 0) - { - it->renamed = EINA_TRUE; + wd->expand_item_cnt = end - start; + return ECORE_CALLBACK_CANCEL; +} + +EAPI void +elm_genlist_effect_set(const Evas_Object *obj, Eina_Bool emode) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->effect_mode = emode; + wd->point_rect = evas_object_rectangle_add(evas_object_evas_get(wd->obj)); + evas_object_resize(wd->point_rect, 10, 25); + evas_object_color_set(wd->point_rect, 255, 0, 0, 130); + evas_object_show(wd->point_rect); + evas_object_hide(wd->point_rect); +} + +/* +EAPI void +elm_genlist_edit_mode_effect_set(const Evas_Object *obj, Eina_Bool emode) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->edit_mode_effect_mode = emode; +} +*/ + +EAPI void +elm_genlist_queue_exception_set(const Evas_Object *obj, Eina_Bool emode) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->queue_exception = emode; + + fprintf(stderr, "=================> Caution!!! <========================\n"); + fprintf(stderr, "==> elm_genlist_queue_exception_set() is for demo. <===\n"); + fprintf(stderr, "==> Do not use this API <==\n"); + fprintf(stderr, "=======================================================\n"); +} + +static void +_delete_confirm_cb(void *data, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = data; + evas_object_hide( wd->ed->del_confirm ); + if( wd->ed->ec && wd->ed->ec->remove ) + wd->ed->ec->remove(wd->obj, wd->ed->del_item); + wd->ed->del_item = NULL; +} - it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels")); - EINA_LIST_FOREACH(it->labels, list, label) - { - edje_object_signal_emit(it->edit_obj, "elm,state,rename,enable", "elm"); - edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm"); - edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm"); - edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm"); +static void +_hide_delete_confirm_object (void *data, Evas_Object *obj, const char *emission, const char *source) +{ + const char *del_icon_part; + Elm_Genlist_Item *it = data; + del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm"); + if (del_icon_part) + edje_object_part_unswallow( it->edit_obj, it->wd->ed->del_confirm ); - if (it->itc->func.label_get) - { - it->renamed = EINA_TRUE; - swallow_part_cnt = 0; + evas_object_hide( it->wd->ed->del_confirm ); +} - EINA_LIST_FREE(it->edit_icon_objs, icon) - evas_object_del(icon); - Eina_List *rename = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "rename")); - EINA_LIST_FOREACH(rename, l, rename_swallow_part) - { - if (label_cnt == swallow_part_cnt) - { - editfield = elm_editfield_add(it->wd->obj); - it->wd->edit_field = eina_list_append(it->wd->edit_field, editfield); +static void +_remove_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + const char *del_conf_style; + Elm_Genlist_Item *it = data; + if(_edit_mode_reset( it->wd )) + return; + if (it->edit_long_timer) + { + ecore_timer_del(it->edit_long_timer); + it->edit_long_timer = NULL; + } + + if( it->del_confirm_state ) + { + it->del_confirm_state = 0; + it->delete_check = 0; + edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm"); + it->wd->selct_all = 0; + if(it->wd->select_all_item) + edje_object_signal_emit(it->wd->select_all_item->base, "elm,state,del,animated,enable", "elm"); - elm_editfield_entry_single_line_set(editfield, EINA_TRUE); - elm_editfield_eraser_set(editfield, EINA_TRUE); - edje_object_part_swallow(it->edit_obj, rename_swallow_part, editfield); + if (!it->wd->selct_all && it->wd->ed->ec->item_selected) + { + it->wd->ed->ec->item_selected(it->data, it, it->delete_check); + } + return; + } - evas_object_show(editfield); + it->del_confirm_state = 1; + it->delete_check = 1; - s = it->itc->func.label_get(it->data, it->wd->obj, list->data); + it->wd->ed->del_item = it; - if (s) - { - Evas_Object *entry = elm_editfield_entry_get(editfield); - elm_entry_entry_set(entry,s); + if (!it->wd->selct_all && it->wd->ed->ec->item_selected) + { + it->wd->ed->ec->item_selected(it->data, it, it->delete_check); + } - free(s); - } - else - elm_editfield_guide_text_set(editfield, "Text Input"); - } - swallow_part_cnt++; - } - label_cnt++; - } - } - } + del_conf_style = edje_object_data_get(it->edit_obj, "del_button_style"); + if(del_conf_style ) + elm_object_style_set( it->wd->ed->del_confirm, del_conf_style); - if (it->wd->edit_mode == 0xF0) - { - it->wd->edit_mode = 0; - } +/* + del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm"); + if (del_icon_part) + edje_object_part_swallow(it->edit_obj, del_icon_part, it->wd->ed->del_confirm); + evas_object_show( it->wd->ed->del_confirm ); +*/ + edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm"); } -/** - * Set the timeout in seconds for the longpress event - * - * @param obj The genlist object - * @param timeout timeout in seconds - * - * @ingroup Genlist - */ -EAPI void -elm_genlist_longpress_timeout_set(Evas_Object *obj, double timeout) +static void +_insert_new_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->longpress_timeout = timeout; + Elm_Genlist_Item *it = data; + + if(_edit_mode_reset( it->wd )) + return; + + if( it->wd->ed->ec && it->wd->ed->ec->insert_new ) + it->wd->ed->ec->insert_new(it->wd->obj, it); } -/** - * Get the timeout in seconds for the longpress event - * - * @param obj The genlist object - * @return timeout in seconds - * - * @ingroup Genlist - */ -EAPI double -elm_genlist_longpress_timeout_get(const Evas_Object *obj) +static Eina_Bool +_edit_mode_reset(Widget_Data *wd) { - ELM_CHECK_WIDTYPE(obj, widtype) 0; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return 0; - return wd->longpress_timeout; + /* + if(wd->ed->del_confirm_state) + { + //edje_object_signal_emit(wd->ed->del_item->edit_obj, "elm,state,delete", "elm"); + //wd->ed->del_confirm_state = 0; + //wd->ed->del_item = NULL; + return EINA_TRUE; + } + */ + return EINA_FALSE; } -// added for item moving animation. - static Eina_Bool -_group_item_contract_moving_effect_timer_cb(void *data) +static void +_reorder_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info) { - Evas_Object *obj = (Evas_Object *)data; - Widget_Data *wd = elm_widget_data_get(obj); - - Item_Block *itb = NULL; - Elm_Genlist_GroupItem *git; - Elm_Genlist_Item *it; - const Eina_List *l; - int cnt = 0, git_count = 0; - double added_gy = 1; + Elm_Genlist_Item *it = data; + Evas_Event_Mouse_Down *ev = event_info; + Evas_Coord x, y; - int hide_git = 0, git_cnt = 0, list_start_y = 0; + if(!elm_genlist_item_next_get(it)) + return; + + if(it->wd->edit_field && !it->renamed) + elm_genlist_item_rename_mode_set(it, 0); - int *git_array = NULL; - int base_git = 0, base_git_num = 0; - int tmp_y = 0, devide_size = 1; - double t; + if(!(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER)) + return; - Eina_Bool finish = EINA_FALSE; + if(_edit_mode_reset( it->wd ) ) + return; - Evas_Coord ox, oy, ow, oh; - if(!wd) - return ECORE_CALLBACK_CANCEL; + it->dragging = 0; + it->down = 1; + + it->reoder_cavas_x = ev->canvas.x; + it->reoder_cavas_y = ev->canvas.y; - if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) - return ECORE_CALLBACK_CANCEL; + evas_object_geometry_get(obj, &x, &y, NULL, NULL); + it->dx = ev->canvas.x - x; + it->dy = ev->canvas.y - y; - git_array = (int*)malloc(sizeof(int) * wd->max_git_num); - t = ecore_loop_time_get(); + if (it->edit_long_timer) + { + ecore_timer_del(it->edit_long_timer); + it->edit_long_timer = NULL; + } - if (t - wd->effect_start >= 5.0) - finish = EINA_TRUE; + if (it->realized) { + it->edit_long_timer = ecore_timer_add(0.3,_edit_long_press, it); + } + else + it->edit_long_timer = NULL; + +} - if(wd->item_count < 100) - devide_size = 8 * _elm_config->scale; - else if(wd->item_count < 500) - devide_size = (8 - (devide_size / 100 )) * _elm_config->scale; - else - devide_size = 2 * _elm_config->scale; +static void +_reorder_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info) +{ + Elm_Genlist_Item *it = data; + + Item_Block *itb; + EINA_INLIST_FOREACH(it->wd->blocks, itb) + { + itb->reoder_y = 0; + } - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); + if (it->edit_long_timer) + { + ecore_timer_del(it->edit_long_timer); + it->edit_long_timer = NULL; + } + + it->down = 0; - list_start_y = oy; + if (it->wd->ed->ec->selected) + { + it->wd->ed->ec->selected(NULL, it, 1); + } - EINA_INLIST_FOREACH(wd->group_items, git) - { - git_array[git_cnt++] = git->y; - if(git->y < list_start_y) - hide_git++; - edje_object_signal_emit(git->base, "elm,state,alpha,disable", "elm"); - } - base_git_num = hide_git; + if( it->reordering && it->wd->ed->reorder_item ) + { + it->wd->ed->reorder_item->reordering = 0; + edje_object_signal_emit(it->wd->ed->reorder_item->edit_obj, "elm,action,item,reorder_end", "elm"); + elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE); - EINA_INLIST_FOREACH(wd->group_items, git) - { - base_git = oy + git->h * (git->num-1) + git->num; - git->old_y = git->y; - added_gy = abs(base_git - git->y) / devide_size; - if(added_gy < 1.0) - added_gy = 1.0; + if( (!it->wd->ed->reorder_rel) || (!it->wd->ed->ec->move) || + (!it->wd->ed->ec->move(it->wd->obj, it->wd->ed->reorder_item, it->wd->ed->reorder_rel, EINA_TRUE ) ) ) + { + evas_object_move(it->wd->ed->reorder_item->base, it->wd->ed->reorder_item->scrl_x+it->pad_left, it->wd->ed->reorder_item->scrl_y); + _move_edit_controls( it,it->wd->ed->reorder_item->scrl_x, it->wd->ed->reorder_item->scrl_y ); + } + it->wd->ed->reorder_item = NULL; + it->wd->ed->reorder_rel = NULL; + return; + } +} - if (!git->down && git->old_y < list_start_y) - { - git->finish_y = base_git; - git->down = 1; - git->y = list_start_y - (git->h+1) * hide_git--; +static void +_reorder_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info) +{ + Elm_Genlist_Item *it = data; + Evas_Event_Mouse_Move *ev = event_info; - git->old_y = 0; - } - else if (!git->down && git->y < base_git ) - git->down = 1; + if ((it->dragging) && (it->down)) + { + if (it->edit_long_timer) + { + ecore_timer_del(it->edit_long_timer); + it->edit_long_timer = NULL; + } + + evas_object_smart_callback_call(it->wd->obj, "drag", it); +// return; + } - if(wd->pinch_zoom_reserve) - git->y = base_git; - else - { - if (git->down) - { - if (git->y < base_git) - { - git->y +=added_gy; - if (git->y > base_git) - git->y = base_git; - } - } - else - { - if (git->y > base_git) - git->y -= added_gy; + Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady; - if (git->y < base_git) - git->y = base_git; - } - } - if (git->num - 1 == cnt && git->y == base_git) - git_count++; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + evas_object_geometry_get(obj, &x, &y, NULL, NULL); + x = ev->cur.canvas.x - x; + y = ev->cur.canvas.y - y; + dx = x - it->dx; + adx = dx; + if (adx < 0) adx = -dx; + dy = y - it->dy; + ady = dy; + if (ady < 0) ady = -dy; + minw /= 2; + minh /= 2; + if ((adx > minw) || (ady > minh)) + { + it->dragging = 1; + if (it->edit_long_timer) + { + ecore_timer_del(it->edit_long_timer); + it->edit_long_timer = NULL; + } + } - evas_object_resize(git->base, wd->minw, git->h ); - evas_object_move(git->base, git->x, git->y); - evas_object_raise(git->base); - evas_object_show(git->base); + if( it->reordering && it->wd->ed->reorder_item ) + { + int y = ev->cur.canvas.y - it->wd->ed->reorder_item->dy; + evas_object_raise(it->wd->ed->reorder_item->base); + evas_object_move(it->wd->ed->reorder_item->base, it->wd->ed->reorder_item->scrl_x+it->pad_left, y); + evas_object_show(it->wd->ed->reorder_item->base); + _move_edit_controls( it,it->wd->ed->reorder_item->scrl_x, y ); - EINA_INLIST_FOREACH(wd->blocks, itb) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->group_item == git) - { - if (it->group_item->old_y) - it->old_scrl_y -= (it->group_item->old_y - it->group_item->y); + it->block->updateme = EINA_TRUE; - if(git_array[it->group_item->num+1] <= it->old_scrl_y || added_gy == 1.0) - evas_object_color_set(it->base, 0,0,0,0); + if (it->wd->calc_job) ecore_job_del(it->wd->calc_job); + it->wd->calc_job = ecore_job_add(_calc_job, it->wd); - _move_edit_controls(it,it->scrl_x, it->scrl_y); - evas_object_resize(it->base, itb->wd->minw-(it->pad_left+it->pad_right), it->h); - evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); - evas_object_raise(it->group_item->base); - evas_object_show(it->base); - } - } - } - if (git_count == git_cnt ) - { - finish = EINA_TRUE; - break; - } + return; + } +} - cnt++; - } - free(git_array); +static void +_select_all_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) +{ + Item_Block *itb; + Elm_Genlist_Item *select_all_it = data, *it; + Eina_List *l; + Widget_Data *wd = select_all_it->wd; + if (!wd) return; - if(finish) // finish animation - { - added_gy = 1; - EINA_INLIST_FOREACH(wd->group_items, git) - git->down = 0; + if(!wd->selct_all) + edje_object_signal_emit(select_all_it->base, "elm,state,del_confirm", "elm"); + else + edje_object_signal_emit(select_all_it->base, "elm,state,del,animated,enable", "elm"); + - wd->pan_y = 0; - wd->contract_pan_y = 0; - wd->pinch_zoom_reserve = EINA_FALSE; - wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH; - elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0); - elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); + EINA_INLIST_FOREACH(wd->blocks, itb) + { -// fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT FINISH \n"); + EINA_LIST_FOREACH(itb->items, l, it) + { - tmp_y =0 ; - // added for event - EINA_INLIST_FOREACH(wd->blocks, itb) - { - if(itb->realized) { - EINA_LIST_FOREACH(itb->items, l, it) - { - if(it->realized) { - it->scrl_y = oy + tmp_y; - tmp_y += it->h; - // need to handle edit mode - evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); - evas_object_color_set(it->base, 0,0,0,0); - evas_object_show(it->base); - } - } - } + if(!wd->selct_all) + { + it->delete_check = 1; + it->del_confirm_state = 1; + edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm"); + } + else + { + it->delete_check = 0; + it->del_confirm_state = 0; + edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm"); + } + } + } - } - evas_object_lower(wd->alpha_bg); - evas_object_hide(wd->alpha_bg); + wd->selct_all ^= 0xFF; - return ECORE_CALLBACK_CANCEL; - } + if (wd->ed->ec->item_selected) + { + wd->ed->ec->item_selected(select_all_it->data, select_all_it, wd->selct_all); + } - return ECORE_CALLBACK_RENEW; + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); } -// added for item moving animation. - static Eina_Bool -_group_item_expand_moving_effect_timer_cb(void *data) +static void +_move_edit_controls( Elm_Genlist_Item *it, int itx, int ity ) { - Evas_Object *obj = (Evas_Object *)data; - Widget_Data *wd = elm_widget_data_get(obj); - Elm_Genlist_GroupItem *git, *tmp_git; - Item_Block *itb = NULL; - Elm_Genlist_Item *it; - const Eina_List *l; - int cnt = 0, git_count = 0, git_cnt = 0, git_tmp_y = 0, in = 0, start_in = 0; - int tmp = 0, show_git_cnt = 0, scroll_y = 0, top_git = 0 , git_h = 0, scroll_pan_y = 0, down = 0; - int up_cnt = 1, down_cnt = 1, it_h = 0, devide_size = 1; - static int last_git_y = 0; - - double t; - - Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - - static double added_gy = 0; // temp value for animation speed - static double added_gy2 = 0; - Eina_Bool finish = EINA_FALSE; - if (!wd) - return ECORE_CALLBACK_CANCEL; - - if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) - return ECORE_CALLBACK_CANCEL; + if(it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE ) + return; - t = ecore_loop_time_get(); + evas_object_resize(it->edit_obj,it->w, it->h ); + evas_object_move(it->edit_obj, itx, ity ); + evas_object_raise( it->edit_obj ); +} - top_git = wd->pinch_it; +static void +_edit_controls_eval(Elm_Genlist_Item *it) +{ + int itmode = 0; + const char *pad_str; + int pad = 0; + it->pad_left = 0; + it->pad_right = 0; + Evas_Object *icon; + char buf[1024]; - if (top_git< 1) - top_git = 1; - else if (top_git >= wd->max_git_num) - top_git = wd->max_git_num - 1; + if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE && !it->edit_obj) + return; - if(wd->item_count < 100) - devide_size = 8 * _elm_config->scale; - else if(wd->item_count < 500) - devide_size = (8 - (devide_size / 100 )) * _elm_config->scale; - else - devide_size = 2 * _elm_config->scale; - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); - evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); + if (it->itc->func.editmode_get) + itmode = it->itc->func.editmode_get(it->data, it->wd->obj, it->wd->edit_mode); + itmode &= it->wd->edit_mode; - // calculate git count and srcroll move position - EINA_INLIST_FOREACH(wd->group_items, git) + if (itmode & ELM_GENLIST_EDIT_MODE_SELECTALL) + itmode |= ELM_GENLIST_EDIT_MODE_SELECT; + + if (!it->edit_obj) { - if (git_cnt == top_git - 1) - scroll_y = tmp; + it->edit_obj = edje_object_add(evas_object_evas_get(it->wd->obj)); + edje_object_scale_set(it->edit_obj, elm_widget_scale_get(it->wd->obj) * + _elm_config->scale); + evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart); + elm_widget_sub_object_add(it->wd->obj, it->edit_obj); + if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf)); + else strncpy(buf, "item", sizeof(buf)); + if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf)); + // if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf)); + strncat(buf, "/", sizeof(buf) - strlen(buf)); - if (!scroll_y) + if (it->wd->ed->ec->item_style && strcmp(it->wd->ed->ec->item_style, "default")) { - EINA_INLIST_FOREACH(wd->blocks, itb) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->group_item == git ) - tmp += it->h; - it_h = it->h; - } - } + strncat(buf, it->wd->ed->ec->item_style, sizeof(buf) - strlen(buf)); + _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", buf, elm_widget_style_get(it->wd->obj)); + } + else + { + _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", "item/edit_control", elm_widget_style_get(it->wd->obj)); } - git_h = git->h; - git_cnt++; + // edje_object_signal_callback_add(it->edit_obj, "elm,action,edit,reset", + // "elm", _edit_mode_reset, it); } - scroll_pan_y = scroll_y + git_h * (top_git-1) ; - if (t - wd->effect_start >= 5.0) - finish = EINA_TRUE; + pad_str = edje_object_data_get(it->edit_obj, "icon_width"); + if (pad_str) pad = atoi(pad_str); - // items realize - EINA_INLIST_FOREACH(wd->blocks, itb) + if ((itmode & ELM_GENLIST_EDIT_MODE_INSERT)) { - if((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh) - || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh)) - { - if (!itb->realized) - { - start_in = in; - EINA_LIST_FOREACH(itb->items, l, it) - { - _item_realize(it, start_in, 0); - it->realized = EINA_TRUE; - start_in++; - } - itb->realized = EINA_TRUE; - itb->want_unrealize = EINA_FALSE; + if (it->wd->animate_edit_controls) + edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,enable", "elm"); + else + edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm"); - } - } + edje_object_signal_callback_add(it->edit_obj, "elm,action,item,insert", + "elm", _insert_new_item_cb, it); + it->pad_left += pad * _elm_config->scale; + } + else + { + if (it->wd->animate_edit_controls) + edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,disable", "elm"); else - { - if (itb->realized) _item_block_unrealize(itb); - } - in += itb->count; + edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm"); + + edje_object_signal_callback_del(it->edit_obj, "elm,action,item,insert", + "elm", _insert_new_item_cb ); } - // set group item finish y and items y position of group item and items. - tmp = 0; - git_tmp_y = oy; - EINA_INLIST_FOREACH(wd->group_items, git) + if ((itmode & ELM_GENLIST_EDIT_MODE_DELETE) || (itmode & ELM_GENLIST_EDIT_MODE_SELECT)) { - if (git->num >= top_git) - { - git->finish_y = git_tmp_y; - git_tmp_y += git->h; - tmp = git->y + git->h; + if (it->wd->animate_edit_controls) + edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm"); + else + edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm"); - } - else - git->finish_y = -1 * oh; + edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete", + "elm", _remove_item_cb ); + edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm", + "elm", _hide_delete_confirm_object ); - EINA_INLIST_FOREACH(wd->blocks, itb) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - if (it->group_item == git ) - { - if(git->finish_y != -1 * oh) - { - it->old_scrl_y = tmp; - git_tmp_y += it->h; - added_gy2 = abs(git->finish_y - git->y) / devide_size; - tmp += it->h - added_gy2; - } - else - it->old_scrl_y = -1 * oh; - } - } - } + edje_object_signal_callback_add(it->edit_obj, "elm,action,item,delete", + "elm", _remove_item_cb, it); - if (git->finish_y >= oy && git->finish_y < oy+oh) - show_git_cnt++; + edje_object_signal_callback_add(it->edit_obj, "elm,action,hide,del_confirm", + "elm", _hide_delete_confirm_object, it ); + it->pad_left += pad * _elm_config->scale; + evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, + _reorder_mouse_down, it); } - - EINA_INLIST_FOREACH(wd->group_items, git) + else { - down = 0; - - evas_object_move(git->base, git->x, git->y); - evas_object_raise(git->base); - evas_object_show(git->base); - - added_gy = abs(git->finish_y - git->y) / devide_size; - if(added_gy < 1.0) - added_gy = 1.0; - if(git->y > git->finish_y) { - if (git->y > oy) - git->y -= added_gy; + if (it->wd->animate_edit_controls) + edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,disable", "elm"); + else + edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm"); + edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete", + "elm", _remove_item_cb ); + edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm", + "elm", _hide_delete_confirm_object ); + evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, + _reorder_mouse_down); + } - if(git->num >= top_git) - up_cnt++; - down = 0; + if ((itmode & ELM_GENLIST_EDIT_MODE_REORDER)) + { + const char* reorder_part; - } - else if(git->y < git->finish_y) { - git->y += added_gy; - down_cnt++; - down = 1; - } + reorder_part = edje_object_data_get(it->edit_obj, "reorder"); + if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part)) + { + edje_object_part_object_get(it->edit_obj, reorder_part); - if( (!down && git->y < git->finish_y) || (down && git->y > git->finish_y) ) - git->y = git->finish_y; + evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, + _reorder_mouse_down); + evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP, + _reorder_mouse_up); + evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE, + _reorder_mouse_move); - if (git_cnt-1 == cnt) - last_git_y = git->y; + evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, + _reorder_mouse_down, it); + evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_UP, + _reorder_mouse_up, it); + evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE, + _reorder_mouse_move, it); + } + // it->pad_right += pad * _elm_config->scale; + } + else + { + const char* reorder_part; - if (git->num == top_git && git->y == oy) + reorder_part = edje_object_data_get(it->edit_obj, "reorder"); + if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part)) { - evas_object_move(git->base, git->x, git->y); - evas_object_show(git->base); - git_count = 0; - EINA_INLIST_FOREACH(wd->group_items, tmp_git) + + if (itmode == ELM_GENLIST_EDIT_MODE_NONE) { - if (tmp_git->y == tmp_git->finish_y && tmp_git->y > oy && tmp_git->y < oy+oh ) - { - git_count++; - } + evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN, + _reorder_mouse_down); + evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP, + _reorder_mouse_up); + evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE, + _reorder_mouse_move); } } + } - EINA_INLIST_FOREACH(wd->blocks, itb) - { - EINA_LIST_FOREACH(itb->items, l, it) + if (it->wd->edit_mode != 0xF0) { + if (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE) + { + if (it->itc->func.icon_get) { - if (it->group_item == git) - { + edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,enable", "elm"); - if((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh) - || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh)) + const Eina_List *l; + const char *key; - { - evas_object_resize(it->base, wd->minw-(it->pad_left+it->pad_right), it->h); - evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); - evas_object_color_set(it->base, 255,255,255,255); - evas_object_raise(it->base); - evas_object_raise(it->group_item->base); + it->icons = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "icons")); + EINA_LIST_FOREACH(it->icons, l, key) + { + Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data); + if (ic) + { + it->edit_icon_objs = eina_list_append(it->edit_icon_objs, ic); + edje_object_part_swallow(it->edit_obj, key, ic); + evas_object_show(ic); + // elm_widget_sub_object_add(it->wd->obj, ic); } } - } + } } - - cnt++; - - if(git_count + 1 == show_git_cnt ) + else { - finish = EINA_TRUE; - } - - } - if(finish) - { - added_gy = 0; - added_gy2 = 0; - last_git_y = 0; - - wd->pan_y = scroll_y + (git_h) * (top_git-1) ; + edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm"); + EINA_LIST_FREE(it->edit_icon_objs, icon) + evas_object_del(icon); - EINA_INLIST_FOREACH(wd->group_items, git) - { - edje_object_signal_emit(git->base, "elm,state,alpha,enable", "elm"); - } - EINA_INLIST_FOREACH(wd->blocks, itb) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - _item_unselect(it); - } + Evas_Object *editfield; + EINA_LIST_FREE(it->wd->edit_field, editfield) + evas_object_del(editfield); } + } + if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)//Unrealize + { + evas_object_del(it->edit_obj); + it->edit_obj = NULL; + return; + } + _move_edit_controls(it,it->scrl_x, it->scrl_y ); + evas_object_show( it->edit_obj ); +} - wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE; - fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND FINISH \n"); - elm_smart_scroller_hold_set(wd->scr, 0); - elm_smart_scroller_freeze_set(wd->scr, 0); - elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0); - elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE); -// printf("_group_item_expand_moving_effect_timer_cb FINISH \n"); - evas_object_lower(wd->alpha_bg); - evas_object_hide(wd->alpha_bg); - // evas_object_smart_changed(wd->pan_smart); - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); +static void +_notify_item_position( Elm_Genlist_Item *it ) +{ + const Eina_List *l; + if( it->parent ) + { + l = eina_list_last(it->parent->items); - return ECORE_CALLBACK_CANCEL; - } + //Check if the Item is First Node or Last node of its Parent & raise signal. + if( it->parent->items->data != it && l->data != it ) + { + edje_object_signal_emit(it->base, "normal_item", "elm"); + } + else + { + if(it->parent->items->data == it ) + edje_object_signal_emit(it->base, "first_item", "elm"); - return ECORE_CALLBACK_RENEW; + if(l->data == it ) + edje_object_signal_emit(it->base, "last_item", "elm"); + } + } } - static int -_item_pinch_recalc(Evas_Object *obj, int emode) +static int +_get_space_for_reorder_item( Elm_Genlist_Item *it ) { - Item_Block *itb = NULL; - - Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - Widget_Data *wd = elm_widget_data_get(obj); + int top=0; + Evas_Coord rox, roy, row, roh; + if(!it->wd->ed) + return 0; - if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND) - return EINA_FALSE; + if( !(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER ) || !it->wd->ed->reorder_item ) + return 0; - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); - evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); + evas_object_geometry_get(it->wd->ed->reorder_item->base, &rox, &roy, &row, &roh); - if (emode) - { - if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) - { - wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT; + top = (ELM_RECTS_INTERSECT(it->scrl_x, it->scrl_y, it->w, it->h, + rox, roy+roh/2, row, 1)); - elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1); - elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_FALSE); - evas_object_raise(wd->alpha_bg); - evas_object_show(wd->alpha_bg); + if( top ) + { + it->wd->ed->reorder_rel = it; + it->scrl_y+=it->wd->ed->reorder_item->h; + return it->wd->ed->reorder_item->h; + } - wd->effect_start = ecore_loop_time_get(); - wd->item_moving_effect_timer = ecore_animator_add(_group_item_contract_moving_effect_timer_cb, obj); - } - } - else if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH) - { - elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1); + return 0; +} - evas_object_raise(wd->alpha_bg); - evas_object_show(wd->alpha_bg); +/** + * Add Group Item to the genlist + * + * @param obj The genlist object + * @param itc The item class for the item + * @param data The group item data + */ +EAPI Elm_Genlist_GroupItem * +elm_genlist_groupitem_add(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, + const void *data) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Elm_Genlist_GroupItem *git; + Widget_Data *wd = elm_widget_data_get(obj); - wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND; - EINA_INLIST_FOREACH(wd->blocks, itb) - { - if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, - itb->y - wd->pan_y + oy, - itb->w, itb->h, - cvx, cvy, cvw, cvh)) - { - if (itb->realized) _item_block_unrealize(itb); - itb->realized = EINA_FALSE; - } - } + git = calloc(1, sizeof(Elm_Genlist_GroupItem)); + if (!git) return NULL; + git->wd = wd; + git->itc = itc; + git->data = data; - wd->effect_start = ecore_loop_time_get(); - wd->item_moving_effect_timer = ecore_animator_add(_group_item_expand_moving_effect_timer_cb, obj); - } + wd->group_items = eina_inlist_append(wd->group_items, EINA_INLIST_GET(git) ); + return git; +} - return EINA_TRUE; +/** + * Delete a given groupitem + * + * This deletes the group item from genlist and calls the genlist group item del class + * callback defined in the item class, if it is set. + * + * @param git The group item + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_groupitem_del(Elm_Genlist_GroupItem *git) +{ + _groupitem_remove( git, EINA_TRUE); } -static Evas_Object* -create_tray_alpha_bg(const Evas_Object *obj) +/** + * Append item to the end of the genlist with Group Item + * + * This appends the given item to the end of the list or the end of the + * children if the parent is given. + * + * @param obj The genlist object + * @param itc The item class for the item + * @param data The item data + * @param parent The parent item, or NULL if none + * @param flags Item flags + * @param git Group Item + * @param func Convenience function called when item selected + * @param func_data Data passed to @p func above. + * @return A handle to the item added or NULL if not possible + * + * @ingroup Genlist + */ +EAPI Elm_Genlist_Item * +elm_genlist_item_append_with_group(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, + const void *data, Elm_Genlist_Item *parent, + Elm_Genlist_Item_Flags flags, Elm_Genlist_GroupItem *git, + Evas_Smart_Cb func, const void *func_data) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + parent = NULL; + Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data); + Elm_Genlist_GroupItem *pgit = NULL; + Elm_Genlist_Item *it2 = NULL; + Eina_List *ll = NULL; + if (!wd) return NULL; + if (!it) return NULL; + if (!git) return NULL; - Evas_Object *bg = NULL; - Evas_Coord ox, oy, ow, oh; - - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); - bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj)); - evas_object_color_set(bg , 0,0,0,0); - evas_object_resize(bg , ow, oh); - evas_object_move(bg , ox, oy); - evas_object_show(bg ); - evas_object_hide(bg ); - return bg ; + pgit = git; + while (pgit) + { + ll = eina_list_last(pgit->items); + if (ll) + { + it2 = ll->data; + break; + } + if (!(EINA_INLIST_GET(pgit)->prev)) break; + pgit = (Elm_Genlist_GroupItem *)(EINA_INLIST_GET(pgit)->prev); + } + if (it2) + { + wd->items = + eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), + EINA_INLIST_GET(it2)); + it->rel = it2; + it->rel->relcount++; + } + else + { + wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it)); + it->rel = NULL; + } + git->items = eina_list_append(git->items, it); + it->before = 0; + it->group_item = git; + _item_queue(wd, it); + return it; } -static void -_elm_genlist_pinch_zoom_execute(Evas_Object *obj, Eina_Bool emode) +/** + * Moves the Genlist Item + */ +EAPI void +elm_genlist_item_move_after(Elm_Genlist_Item *it, Elm_Genlist_Item *after ) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); + if (!it) return; - if (!wd || !wd->pinch_zoom) return; + Elm_Genlist_Item *next_item = elm_genlist_item_next_get(after); - if(!wd->queue_idler) - { + if(it->y == after->y && after->reorder_check && it->reorder_check) { + if (it->wd->calc_job) ecore_job_del(it->wd->calc_job); + it->wd->calc_job = ecore_job_add(_calc_job, it->wd); + return; + } - if(!wd->alpha_bg) - wd->alpha_bg = create_tray_alpha_bg(obj); + it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it)); + _item_block_del(it); - _item_pinch_recalc(obj, emode); + if((!next_item && !after->reorder_check) || (next_item && !after->reorder_check) ) + { + + if(next_item && !after->reorder_check && it == after) { + it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), + EINA_INLIST_GET(next_item)); + it->rel = next_item; + } + else { + it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), + EINA_INLIST_GET(after)); + it->rel = after; + } + + it->rel->relcount++; + it->before = 0; + } + else + { + if( after) + { + it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), + EINA_INLIST_GET(after)); + it->rel = after; + it->rel->relcount++; + } + else + { + it->wd->items = eina_inlist_prepend(it->wd->items, EINA_INLIST_GET(it)); + } + + it->before = 1; } + + _item_queue(it->wd, it); } /** - * Set pinch zoom mode - * - * @param obj The genlist object - * @param emode - * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out) - * + * Set the Genlist Internal scroller scrollbar policy + * + * This sets the Genlist Internal scrollbar visibility policy. + * ELM_SMART_SCROLLER_POLICY_AUTO means the scrollbar is made visible if it + * is needed, and otherwise kept hidden. ELM_SMART_SCROLLER_POLICY_ON turns + * it on all the time, and ELM_SMART_SCROLLER_POLICY_OFF always keeps it off. + * This applies respectively for the horizontal and vertical scrollbars. + * + * @param obj The Genlist object + * @param policy_h Horizontal scrollbar policy + * @param policy_v Vertical scrollbar policy + * * @ingroup Genlist */ EAPI void -elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Eina_Bool emode) +elm_genlist_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd || !wd->pinch_zoom) return; - wd->pinch_zoom_reserve = emode; -} + if (!wd) return; -/** - * Get pinch zoom mode - * - * @param obj The genlist object - * @return The pinch mode - * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out) - * - * @ingroup Genlist - */ -EAPI Eina_Bool -elm_genlist_pinch_zoom_mode_get(const Evas_Object *obj) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - if(wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH) - return EINA_TRUE; - else return EINA_FALSE; -} + const Elm_Scroller_Policy map[3] = + { + ELM_SMART_SCROLLER_POLICY_AUTO, + ELM_SMART_SCROLLER_POLICY_ON, + ELM_SMART_SCROLLER_POLICY_OFF + }; + if ((policy_h < 0) || (policy_h >= 3) || (policy_v < 0) || (policy_v >= 3)) + return; -EAPI void -elm_genlist_pinch_zoom_set(Evas_Object *obj, Eina_Bool emode) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->pinch_zoom = emode; + elm_smart_scroller_policy_set(wd->scr, map[policy_h], map[policy_v]); } - -// added for item moving animation. -static Eina_Bool -_item_moving_effect_timer_cb(void *data) +EAPI void +elm_genlist_set_edit_mode(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class) { - Widget_Data *wd = data; - Item_Block *itb; - Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - - if (!wd) return EINA_FALSE; - - Elm_Genlist_Item *it; - const Eina_List *l; - int expanded_cnt = 0; - int cnt = 0; - static double added_gy =25; - static int count = 0; - - if(added_gy < 1) - added_gy = 1; - - count++; - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); - evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); - - EINA_INLIST_FOREACH(wd->blocks, itb) - { - itb->w = wd->minw; - if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, - itb->y - wd->pan_y + oy, - itb->w, itb->h, - cvx, cvy, cvw, cvh)) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - if (!it->old_scrl_y) - it->old_scrl_y = it->scrl_y; - if(it->parent && it->parent->expanded && !it->showme) - { - evas_object_hide(it->base); - } - else evas_object_show(it->base); - - evas_object_show(it->base); - - if(itb && itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND) - { - - if(it->old_scrl_y && it->old_scrl_y < it->scrl_y) { - - it->old_scrl_y += added_gy; - - } - - if(it->old_scrl_y >= it->scrl_y) { - it->list_expanded = 1; - it->old_scrl_y = it->scrl_y; - } - - } - - else if(itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT) - { - if(it->old_scrl_y && it->old_scrl_y > it->scrl_y) - { - - it->old_scrl_y -= added_gy; - } - - if(it->old_scrl_y <= it->scrl_y) { - it->list_expanded = 1; - it->old_scrl_y = it->scrl_y; - } - - } - expanded_cnt += it->list_expanded; - cnt++; - - _move_edit_controls( it,it->scrl_x, it->scrl_y ); - evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h); - - evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y); - - evas_object_raise(it->base); - } - } - } - if(expanded_cnt == cnt) { + fprintf(stderr, "=================> Caution!!! <========================\n"); + fprintf(stderr, "==> elm_genlist_set_edit_mode() is deprecated. <=======\n"); + fprintf(stderr, "==> Please use elm_genlist_edit_mode_set() instead. <==\n"); + fprintf(stderr, "=======================================================\n"); - if(wd->item_moving_effect_timer) { - added_gy = 25; - count = 0; - wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; - EINA_INLIST_FOREACH(wd->blocks, itb) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - it->list_expanded = 0; - } - } - - } - return ECORE_CALLBACK_CANCEL; - } - return ECORE_CALLBACK_RENEW; + elm_genlist_edit_mode_set(obj, emode, edit_class); } -// added for edit mode item moving animation. -static Eina_Bool -_edit_mode_item_moving_effect_cb(void *data) -{ - Widget_Data *wd = data; - Item_Block *itb; - Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; - - if (!wd) return EINA_FALSE; - - Elm_Genlist_Item *it, *select_all_item; - const Eina_List *l; - int expanded_cnt = 0; - static double added_gy = 9; - static float count = 0; - int finish = 0; +/** + * Set Genlist edit mode + * + * This sets Genlist edit mode. + * + * @param obj The Genlist object + * @param emode ELM_GENLIST_EDIT_MODE_{NONE & REORDER & INSERT & DELETE & SELECT & SELECT_ALL} + * @param edit_class Genlist edit class (Elm_Genlist_Edit_Class structure) + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_edit_mode_set(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class) +{ + Elm_Genlist_Item *it; + Eina_List *l; + Item_Block *itb; - static float select_all_y = 0; + static Elm_Genlist_Item_Class itc; - count++; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->edit_mode == emode) return; - if(!wd->select_all_item) - return ECORE_CALLBACK_CANCEL; + wd->edit_mode = emode; + wd->animate_edit_controls = 1; - static float dy = 9; - dy -= 0.5; - if(dy < 1.0) - dy = 1.0f; + if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) + wd->edit_mode |= ELM_GENLIST_EDIT_MODE_SELECT; + if(wd->edit_mode_effect_mode) { + wd->effect_mode = EINA_TRUE; + wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE; + } - select_all_y += (dy); + if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) + { + if (wd->ed) free (wd->ed); + wd->ed = NULL; + } + else + { + if (!wd->ed) + wd->ed = calloc(1, sizeof(Edit_Data)); - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); - evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); + wd->ed->ec = edit_class; + if (((wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT)) && !wd->ed->del_confirm) + { + wd->ed->del_confirm = elm_button_add(wd->obj); + elm_button_label_set(wd->ed->del_confirm, "Delete"); + evas_object_smart_member_add(wd->ed->del_confirm, wd->pan_smart); + edje_object_scale_set( wd->ed->del_confirm, elm_widget_scale_get(wd->ed->del_confirm) * + _elm_config->scale); + evas_object_smart_callback_add(wd->ed->del_confirm, "clicked", _delete_confirm_cb, wd ); + } + } EINA_INLIST_FOREACH(wd->blocks, itb) { - itb->w = wd->minw; - if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, - itb->y - wd->pan_y + oy, - itb->w, itb->h, - cvx, cvy, cvw, cvh)) + EINA_LIST_FOREACH(itb->items, l, it) + { + it->delete_check = 0; + it->del_confirm_state = 0; + _item_unselect(it); + _edit_controls_eval(it); + } + } + + if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL) + { + if(edit_class->select_all_item_style && strcmp(edit_class->select_all_item_style, "default")) + itc.item_style = edit_class->select_all_item_style; + else + itc.item_style = "select_all"; + itc.func.label_get = NULL; + itc.func.icon_get = NULL; + itc.func.del = NULL; + itc.func.editmode_get = NULL; + + wd->select_all_item = _item_new(wd, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + + if (!wd) return; + if (!wd->select_all_item) return; + + _item_realize(wd->select_all_item, 0, 0); + edje_object_signal_callback_add(wd->select_all_item->base, "elm,action,select,press", "elm", _select_all_down, wd->select_all_item); + wd->select_all_item->rel = NULL; + wd->select_all_item->selected = 0; + wd->select_all_item->before = 1; + wd->select_all_item->block = NULL; + wd->select_all_minh = wd->minh + wd->select_all_item->h; + } + else if(wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE) + { + if (wd->select_all_item) { - EINA_LIST_FOREACH(itb->items, l, it) - { + if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item); + free(wd->select_all_item); + } + wd->select_all_item = NULL; - evas_object_show(it->base); - if(it->old_pad_left < it->pad_left) { + } + edje_object_signal_emit(wd->scr, "elm,state,edit,animated,enable", "elm"); - it->old_pad_left += dy; + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); +} - if(it->old_pad_left >= it->pad_left) { - it->list_expanded = 1; - it->old_pad_left = it->pad_left; - } +/** + * Delete selected items in genlist edit mode. + * + * @param obj The genlist object + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_edit_selected_items_del(Evas_Object *obj) +{ + Elm_Genlist_Item *it; + Eina_List *l; + Item_Block *itb = NULL; + Evas_Object *icon; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if(!wd->blocks) return; - } + + EINA_INLIST_FOREACH(wd->blocks, itb) + { + if(!wd->blocks) break; + + if (itb ) + { + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->delete_check) + { + it->wd->effect_mode = EINA_TRUE; + + if(!wd->selct_all) + { + itb->wd->minh -= it->h; + itb->wd->select_all_minh -= it->h; + } - if(it->old_pad_left > it->pad_left) - { - it->old_pad_left -= dy; - if(it->old_pad_left <= it->pad_left) { - it->list_expanded = 1; - it->old_pad_left = it->pad_left; - } + if ((it->relcount > 0) || (it->walking > 0)) + { + elm_genlist_item_subitems_clear(it); + it->delete_me = EINA_TRUE; + if (it->wd->show_item == it) it->wd->show_item = NULL; + if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); + if (it->block) + { + if (it->realized) _item_unrealize(it); + it->block->changed = EINA_TRUE; + } + if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj); + return; + } - } + it->wd->walking -= it->walking; + if (it->wd->show_item == it) it->wd->show_item = NULL; + if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); + if (it->realized) _item_unrealize(it); + EINA_LIST_FREE(it->edit_icon_objs, icon) + evas_object_del(icon); - if(it->old_scrl_y < it->scrl_y) { + Evas_Object *editfield; + EINA_LIST_FREE(it->wd->edit_field, editfield) + evas_object_del(editfield); - it->old_scrl_y += (dy) ; - if(it->old_scrl_y >= it->scrl_y) { - it->list_expanded = 1; - it->old_scrl_y = it->scrl_y; - } + evas_object_del(it->edit_obj); + it->edit_obj = NULL; - } + itb->items = eina_list_remove(itb->items, it); + itb->count--; + itb->changed = EINA_TRUE; + if ((!it->delete_me) && (it->itc->func.del)) + it->itc->func.del(it->data, it->wd->obj); + it->delete_me = EINA_TRUE; + if (it->queued) + it->wd->queue = eina_list_remove(it->wd->queue, it); + it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it)); + if (it->parent) + it->parent->items = eina_list_remove(it->parent->items, it); + if (it->long_timer) ecore_timer_del(it->long_timer); + if( it->group_item ) + it->group_item->items = eina_list_remove(it->group_item->items,it); - if(it->old_scrl_y > it->scrl_y) - { - it->old_scrl_y -= (dy); + free(it); + } + } + } + } - if(it->old_scrl_y <= it->scrl_y) { - it->list_expanded = 1; - it->old_scrl_y = it->scrl_y; - } + evas_render(evas_object_evas_get(wd->obj)); + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); +} - } - select_all_item = itb->wd->select_all_item; - evas_object_resize(select_all_item->base, itb->w, select_all_item->h); - if(wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) - evas_object_move(select_all_item->base, ox, oy - select_all_y); - else if( select_all_y <= select_all_item->h) - evas_object_move(select_all_item->base, ox, oy - select_all_item->h + select_all_y); - evas_object_raise(select_all_item->base); +EAPI void +elm_genlist_selected_items_del(Evas_Object *obj) +{ + fprintf(stderr, "=================> Caution!!! <========================\n"); + fprintf(stderr, "==> elm_genlist_selected_items_del() is deprecated. <=======\n"); + fprintf(stderr, "==> Please use elm_genlist_edit_selected_items_del() instead. <==\n"); + fprintf(stderr, "=======================================================\n"); + elm_genlist_edit_selected_items_del(obj); +} - evas_object_show(select_all_item->base); +/** + * Get a list of selected items in genlist + * + * This returns a list of the selected items in the genlist. The list + * contains Elm_Genlist_Item pointers. The list must be freed by the + * caller when done with eina_list_free(). The item pointers in the list + * are only vallid so long as those items are not deleted or the genlist is + * not deleted. + * + * @param obj The genlist object + * @return The list of selected items, nor NULL if none are selected. + * + * @ingroup Genlist + */ +EAPI Eina_List * +elm_genlist_edit_selected_items_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *list = NULL; + Item_Block *itb; + if (!wd) return NULL; + + EINA_INLIST_FOREACH(wd->blocks, itb) + { + Eina_List *l; + Elm_Genlist_Item *it; + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->delete_check) list = eina_list_append(list, it); + } - expanded_cnt += it->list_expanded; + } + return list; +} - evas_object_move(it->base, it->scrl_x+it->old_pad_left, it->old_scrl_y); - evas_object_move(it->edit_obj, it->scrl_x, it->old_scrl_y); - evas_object_raise(it->edit_obj); - evas_object_raise(it->base); +/** + * Set a given item's rename mode + * + * This renames the item's label from genlist + * + * @param it The item + * @param emode set if emode is EINA_TRUE, unset if emode is EINA_FALSE + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_item_rename_mode_set(Elm_Genlist_Item *it, int emode) +{ + if (!it) return; - evas_object_show(it->edit_obj); - evas_object_show(it->base); + const Eina_List *l, *list, *l2; + const char *label, *rename_swallow_part; + char *s; + Eina_Bool done = EINA_FALSE; + int label_cnt = 0 , swallow_part_cnt = 0; - if(select_all_y >= wd->select_all_item->h && it->list_expanded == 1) - { - finish = 1; - evas_object_raise(it->edit_obj); - break; - } + Item_Block *itb; + Evas_Object *editfield; + Evas_Object *entry; + int edit_field_cnt = 0; + Evas_Object *icon; - } - } - } + if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) + { + it->wd->edit_mode = 0xF0; + _edit_controls_eval(it); + } - if(finish) { + EINA_INLIST_FOREACH(it->wd->blocks, itb) + { + if (itb->realized) + { + Eina_List *l; + Elm_Genlist_Item *it; - if(wd->item_moving_effect_timer) { - added_gy = 9; - count = 0; - select_all_y = 0; - dy = 9; - wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; - EINA_INLIST_FOREACH(wd->blocks, itb) - { - EINA_LIST_FOREACH(itb->items, l, it) - { - it->list_expanded = 0; - } - } - if(wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE) - { - if (wd->select_all_item) - { - if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item); - free(wd->select_all_item); - } - wd->select_all_item = NULL; - } + done = EINA_TRUE; + EINA_LIST_FOREACH(itb->items, l, it) + { + if (it->renamed) + { + it->renamed = EINA_FALSE; - } - wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE; - wd->effect_mode = 0; - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); - return ECORE_CALLBACK_CANCEL; - } + EINA_LIST_FOREACH(it->wd->edit_field, l2, editfield) + { + entry = elm_editfield_entry_get(editfield); + const char *text = elm_entry_entry_get(entry); - return ECORE_CALLBACK_RENEW; -} + if (it->itc->func.label_changed) + it->itc->func.label_changed( it->data, it, text, edit_field_cnt++); + } + Ecore_IMF_Context *imf = elm_entry_imf_context_get(entry); + ecore_imf_context_input_panel_hide(imf); + Evas_Object *editfield; + EINA_LIST_FREE(it->wd->edit_field, editfield) + evas_object_del(editfield); -// added for item moving animation. -static int -_item_flip_effect_show(void *data) -{ - Widget_Data *wd = data; - Item_Block *itb; - Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; + if (it->wd->edit_mode) + { + if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_INSERT)) + edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm"); - if (!wd) return EINA_FALSE; + if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT)) + edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm"); - Elm_Genlist_Item *it; - Evas_Object *base ; - const Eina_List *l; - int start = 0, end = 0; - - evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh); - evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh); + if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER)) + edje_object_signal_emit(it->edit_obj, "elm,state,rename,disable", "elm"); + } + if (it->edit_obj) + { + evas_object_del(it->edit_obj); + it->edit_obj = NULL; + } + EINA_LIST_FREE(it->edit_icon_objs, icon) + evas_object_del(icon); + } + } + } + else + { + if (done) break; + } + } + // if (emode != ELM_GENLIST_RENAME_MODE_NONE) + if (emode != 0) + { + it->renamed = EINA_TRUE; - EINA_INLIST_FOREACH(wd->blocks, itb) + it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels")); + EINA_LIST_FOREACH(it->labels, list, label) { - itb->w = wd->minw; - if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox, - itb->y - wd->pan_y + oy, - itb->w, itb->h, - cvx, cvy, cvw, cvh)) + edje_object_signal_emit(it->edit_obj, "elm,state,rename,enable", "elm"); + edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm"); + edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm"); + edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm"); + + if (it->itc->func.label_get) + { + it->renamed = EINA_TRUE; + swallow_part_cnt = 0; + + EINA_LIST_FREE(it->edit_icon_objs, icon) + evas_object_del(icon); + Eina_List *rename = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "rename")); + EINA_LIST_FOREACH(rename, l, rename_swallow_part) + { + if (label_cnt == swallow_part_cnt) { - EINA_LIST_FOREACH(itb->items, l, it) - { - if(it->parent && it->wd->expand_item == it->parent && !it->effect_done) - { - if(!start) - start = it->scrl_y; - base = (Evas_Object *) it->base; - edje_object_signal_emit(it->base, "flip_item", ""); - end = it->scrl_y + it->h; - it->effect_done = EINA_TRUE; + editfield = elm_editfield_add(it->wd->obj); + it->wd->edit_field = eina_list_append(it->wd->edit_field, editfield); - } - } - } - } + elm_editfield_entry_single_line_set(editfield, EINA_TRUE); + elm_editfield_eraser_set(editfield, EINA_TRUE); + edje_object_part_swallow(it->edit_obj, rename_swallow_part, editfield); - wd->expand_item_cnt = end - start; - return ECORE_CALLBACK_CANCEL; -} + evas_object_show(editfield); -EAPI void -elm_genlist_effect_set(const Evas_Object *obj, Eina_Bool emode) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->effect_mode = emode; - wd->point_rect = evas_object_rectangle_add(evas_object_evas_get(wd->obj)); - evas_object_resize(wd->point_rect, 10, 25); - evas_object_color_set(wd->point_rect, 255, 0, 0, 130); - evas_object_show(wd->point_rect); - evas_object_hide(wd->point_rect); -} + s = it->itc->func.label_get(it->data, it->wd->obj, list->data); -/* -EAPI void -elm_genlist_edit_mode_effect_set(const Evas_Object *obj, Eina_Bool emode) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->edit_mode_effect_mode = emode; -} -*/ + if (s) + { + Evas_Object *entry = elm_editfield_entry_get(editfield); + elm_entry_entry_set(entry,s); -EAPI void -elm_genlist_queue_exception_set(const Evas_Object *obj, Eina_Bool emode) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->queue_exception = emode; + free(s); + } + else + elm_editfield_guide_text_set(editfield, "Text Input"); + } + swallow_part_cnt++; + } + label_cnt++; + } + } + } - fprintf(stderr, "=================> Caution!!! <========================\n"); - fprintf(stderr, "==> elm_genlist_queue_exception_set() is for demo. <===\n"); - fprintf(stderr, "==> Do not use this API <==\n"); - fprintf(stderr, "=======================================================\n"); -} + if (it->wd->edit_mode == 0xF0) + { + it->wd->edit_mode = 0; + } +} \ No newline at end of file