[src/lib/elm_genlist.c] Added parameter verification code to
[framework/uifw/elementary.git] / src / lib / elm_genlist.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "els_scroller.h"
4
5 #define SWIPE_MOVES 12
6 #define MAX_ITEMS_PER_BLOCK 32
7 #define LONGPRESS_TIMEOUT 1.0
8
9 /**
10  * @defgroup Genlist Genlist
11  * @ingroup Elementary
12  *
13  * The Aim was to have  more expansive list that the simple list in
14  * Elementary that could have more flexible items and allow many more entries
15  * while still being fast and low on memory usage. At the same time it was
16  * also made to be able to do tree structures. But the price to pay is more
17  * complexity when it comes to usage. If all you want is a simple list with
18  * icons and a single label, use the normal List object.
19  *
20  * Signals that you can add callbacks for are:
21  *
22  * clicked - This is called when a user has double-clicked an item. The
23  * event_info parameter is the genlist item that was double-clicked.
24  *
25  * selected - This is called when a user has made an item selected. The
26  * event_info parameter is the genlist item that was selected.
27  *
28  * unselected - This is called when a user has made an item unselected. The
29  * event_info parameter is the genlist item that was unselected.
30  *
31  * expanded -  This is called when elm_genlist_item_expanded_set() is called
32  * and the item is now meant to be expanded. The event_info parameter is the
33  * genlist item that was indicated to expand. It is the job of this callback
34  * to then fill in the child items.
35  *
36  * contracted - This is called when elm_genlist_item_expanded_set() is called
37  * and the item is now meant to be contracted. The event_info parameter is
38  * the genlist item that was indicated to contract. It is the job of this
39  * callback to then delete the child items
40  *
41  * expand,request - This is called when a user has indicated they want to
42  * expand a tree branch item. The callback should decide if the item can
43  * expand (has any children) and then call elm_genlist_item_expanded_set()
44  * appropriately to set the state. The event_info parameter is the genlist
45  * item that was indicated to expand.
46  *
47  * contract,request - This is called when a user has indicated they want to
48  * contract a tree branch item. The callback should decide if the item can
49  * contract (has any children) and then call elm_genlist_item_expanded_set()
50  * appropriately to set the state. The event_info parameter is the genlist
51  * item that was indicated to contract.
52  *
53  * realized - This is called when the item in the list is created as a real
54  * evas object. event_info parameter is the genlist item that was created.
55  * The object may be deleted at any time, so it is up to the caller to
56  * not use the object pointer from elm_genlist_item_object_get() in a way
57  * where it may point to freed objects.
58  *
59  * unrealized - This is called just before an item is unrealized. After
60  * this call icon objects provideed will be deleted and the item object
61  * itself delete or be put into a floating cache.
62  *
63  * drag,start,up - This is called when the item in the list has been dragged
64  * (not scrolled) up.
65  *
66  * drag,start,down - This is called when the item in the list has been dragged
67  * (not scrolled) down.
68  *
69  * drag,start,left - This is called when the item in the list has been dragged
70  * (not scrolled) left.
71  *
72  * drag,start,right - This is called when the item in the list has been dragged
73  * (not scrolled) right.
74  *
75  * drag,stop - This is called when the item in the list has stopped being
76  * dragged.
77  *
78  * drag - This is called when the item in the list is being dragged.
79  *
80  * longpressed - This is called when the item is pressed for a certain amount
81  * of time. By default it's 1 second.
82  *
83  * scroll,edge,top - This is called when the genlist is scrolled until the top
84  * edge.
85  *
86  * scroll,edge,bottom - This is called when the genlist is scrolled until the
87  * bottom edge.
88  *
89  * scroll,edge,left - This is called when the genlist is scrolled until the
90  * left edge.
91  *
92  * scroll,edge,right - This is called when the genlist is scrolled until the
93  * right edge.
94  *
95  * Genlist has a fairly large API, mostly because it's relatively complex,
96  * trying to be both expansive, powerful and efficient. First we will begin
97  * an overview o the theory behind genlist.
98  *
99  * Evas tracks every object you create. Every time it processes an event
100  * (mouse move, down, up etc.) it needs to walk through objects and find out
101  * what event that affects. Even worse every time it renders display updates,
102  * in order to just calculate what to re-draw, it needs to walk through many
103  * many many objects. Thus, the more objects you keep active, the more
104  * overhead Evas has in just doing its work. It is advisable to keep your
105  * active objects to the minimum working set you need. Also remember that
106  * object creation and deletion carries an overhead, so there is a
107  * middle-ground, which is not easily determined. But don't keep massive lists
108  * of objects you can't see or use. Genlist does this with list objects. It
109  * creates and destroys them dynamically as you scroll around. It groups them
110  * into blocks so it can determine the visibility etc. of a whole block at
111  * once as opposed to having to walk the whole list. This 2-level list allows
112  * for very large numbers of items to be in the list (tests have used up to
113  * 2,000,000 items). Also genlist employs a queue for adding items. As items
114  * may be different sizes, every item added needs to be calculated as to its
115  * size and thus this presents a lot of overhead on populating the list, this
116  * genlist employs a queue. Any item added is queued and spooled off over
117  * time, actually appearing some time later, so if your list has many members
118  * you may find it takes a while for them to all appear, with your process
119  * consuming a lot of CPU while it is busy spooling.
120  *
121  * Genlist also implements a tree structure, but it does so with callbacks to
122  * the application, with the application filling in tree structures when
123  * requested (allowing for efficient building of a very deep tree that could
124  * even be used for file-management). See the above smart signal callbacks for
125  * details.
126  *
127  * An item in the genlist world can have 0 or more text labels (they can be
128  * regular text or textblock ??that's up to the style to determine), 0 or
129  * more icons (which are simply objects swallowed into the genlist item) and
130  * 0 or more boolean states that can be used for check, radio or other
131  * indicators by the edje theme style. An item may be one of several styles
132  * (Elementary provides 2 by default - ?\9cdefault??and ?\9cdouble_label?? but this
133  * can be extended by system or application custom themes/overlays/extensions).
134  *
135  * In order to implement the ability to add and delete items on the fly,
136  * Genlist implements a class/callback system where the application provides
137  * a structure with information about that type of item (genlist may contain
138  * multiple different items with different classes, states and styles).
139  * Genlist will call the functions in this struct (methods) when an item is
140  * ?\9crealized??(that is created dynamically while scrolling). All objects will
141  * simply be deleted  when no longer needed with evas_object_del(). The
142  * Elm_Genlist_Item_Class structure contains the following members:
143  *
144  * item_style - This is a constant string and simply defines the name of the
145  * item style. It must be specified and the default should be ?\9cdefault??
146  *
147  * func.label_get - This function is called when an actual item object is
148  * created. The data parameter is the data parameter passed to
149  * elm_genlist_item_append() and related item creation functions. The obj
150  * parameter is the genlist object and the part parameter is the string name
151  * of the text part in the edje design that is listed as one of the possible
152  * labels that can be set. This function must return a strudup()'ed string as
153  * the caller will free() it when done.
154  *
155  * func.icon_get - This function is called when an actual item object is
156  * created. The data parameter is the data parameter passed to
157  * elm_genlist_item_append() and related item creation functions. The obj
158  * parameter is the genlist object and the part parameter is the string name
159  * of the icon part in the edje design that is listed as one of the possible
160  * icons that can be set. This must return NULL for no object or a valid
161  * object. The object will be deleted by genlist on shutdown or when the item
162  * its unrealized.
163  *
164  * func.state_get - This function is called when an actual item object is
165  * created. The data parameter is the data parameter passed to
166  * elm_genlist_item_append() and related item creation functions. The obj
167  * parameter is the genlist object and the part parameter is the string name
168  * of the state part in the edje design that is listed as one of the possible
169  * states that can be set. Return 0 for false or 1 for true. Genlist will
170  * emit a signal to the edje object with ?\9celm,state,XXX,active???\9celm??when
171  * true (the default is false), where XXX is the name of the part.
172  *
173  * func.del - This is called when elm_genlist_item_del() is called on an
174  * item, elm_genlist_clear() is called on the genlist, or
175  * elm_genlist_item_subitems_clear() is called to clear sub-items. This is
176  * intended for use when actual genlist items are deleted, so any backing
177  * data attached to the item (e.g. its data parameter on creation) can be
178  * deleted.
179  *
180  * Items can be added by several calls. All of them return a Elm_Genlist_Item
181  * handle that is an internal member inside the genlist. They all take a data
182  * parameter that is meant to be used for a handle to the applications
183  * internal data (eg the struct with the original item data). The parent
184  * parameter is the parent genlist item this belongs to if it is a tree, and
185  * NULL if there is no parent. The flags can be a bitmask of
186  * ELM_GENLIST_ITEM_NONE and ELM_GENLIST_ITEM_SUBITEMS. If
187  * ELM_GENLIST_ITEM_SUBITEMS is set then this item is displayed as a item
188  * that is able to expand and have child items. The func parameter is a
189  * convenience callback that is called when the item is selected and the data
190  * parameter will be the func_data parameter, obj be the genlist object and
191  * vent_info will be the genlist item.
192  *
193  * elm_genlist_item_append() appends an item to the end of the list, or if
194  * there is a parent, to the end of all the child items of the parent.
195  * elm_genlist_item_prepend() is the same but prepends to the beginning of
196  * the list or children list. elm_genlist_item_insert_before() inserts at
197  * item before another item and elm_genlist_item_insert_after() inserts after
198  * the indicated item.
199  *
200  * The application can clear the list with elm_genlist_clear() which deletes
201  * all the items in the list and elm_genlist_item_del() will delete a specific
202  * item. elm_genlist_item_subitems_clear() will clear all items that are
203  * children of the indicated parent item.
204  *
205  * If the application wants multiple items to be able to be selected,
206  * elm_genlist_multi_select_set() can enable this. If the list is
207  * single-selection only (the default), then elm_genlist_selected_item_get()
208  * will return the selected item, if any, or NULL I none is selected. If the
209  * list is multi-select then elm_genlist_selected_items_get() will return a
210  * list (that is only valid as long as no items are modified (added, deleted,
211  * selected or unselected).
212  *
213  * To help inspect list items you can jump to the item at the top of the list
214  * with elm_genlist_first_item_get() which will return the item pointer, and
215  * similarly elm_genlist_last_item_get() gets the item at the end of the list.
216  * elm_genlist_item_next_get() and elm_genlist_item_prev_get() get the next
217  * and previous items respectively relative to the indicated item. Using
218  * these calls you can walk the entire item list/tree. Note that as a tree
219  * the items are flattened in the list, so elm_genlist_item_parent_get() will
220  * let you know which item is the parent (and thus know how to skip them if
221  * wanted).
222  *
223  * There are also convenience functions. elm_genlist_item_genlist_get() will
224  * return the genlist object the item belongs to.  elm_genlist_item_show()
225  * will make the scroller scroll to show that specific item so its visible.
226  * elm_genlist_item_data_get() returns the data pointer set by the item
227  * creation functions.
228  *
229  * If an item changes (state of boolean changes, label or icons change),
230  * then use elm_genlist_item_update() to have genlist update the item with
231  * the new state. Genlist will re-realize the item thus call the functions
232  * in the _Elm_Genlist_Item_Class for that item.
233  *
234  * To programmatically (un)select an item use elm_genlist_item_selected_set().
235  * To get its selected state use elm_genlist_item_selected_get(). Similarly
236  * to expand/contract and item and get its expanded state, use
237  * elm_genlist_item_expanded_set() and elm_genlist_item_expanded_get(). And
238  * again to make an item disabled (unable to be selected and appear
239  * differently) use elm_genlist_item_disabled_set() to set this and
240  * elm_genlist_item_disabled_get() to get the disabled state.
241  *
242  * In general to indicate how the genlist should expand items horizontally to
243  * fill the list area, use elm_genlist_horizontal_mode_set(). Valid modes are
244  * ELM_LIST_LIMIT and ELM_LIST_SCROLL . The default is ELM_LIST_SCROLL. This
245  * mode means that if items are too wide to fit, the scroller will scroll
246  * horizontally. Otherwise items are expanded to fill the width of the
247  * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded
248  * to the viewport width and limited to that size. This can be combined with
249  * a different style that uses edjes' ellipsis feature (cutting text off like
250  * this: ?\9ctex...??.
251  *
252  * Items will only call their selection func and callback when first becoming
253  * selected. Any further clicks will do nothing, unless you enable always
254  * select with elm_genlist_always_select_mode_set(). This means even if
255  * selected, every click will make the selected callbacks be called.
256  * elm_genlist_no_select_mode_set() will turn off the ability to select
257  * items entirely and they will neither appear selected nor call selected
258  * callback functions.
259  *
260  * Remember that you can create new styles and add you own theme augmentation
261  * per application with elm_theme_extension_add(). If you absolutely must
262  * have a specific style that overrides any theme the user or system sets up
263  * you can use elm_theme_overlay_add() to add such a file.
264  */
265
266 typedef struct _Widget_Data Widget_Data;
267 typedef struct _Item_Block Item_Block;
268 typedef struct _Pan Pan;
269 typedef struct _Edit_Data Edit_Data;
270
271 typedef enum _Elm_Genlist_Item_Move_effect_Mode
272 {
273    ELM_GENLIST_ITEM_MOVE_EFFECT_NONE         = 0,
274    ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND       = (1 << 0),
275    ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT     = (1 << 1),
276    ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE    = (1 << 2),
277 } Elm_Genlist_Item_Move_effect_Mode;
278
279 typedef enum _Elm_Genlist_Item_Pinchzoom_effect_Mode
280 {
281    ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE             = 0,
282    ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND           = (1 << 0),
283    ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT         = (1 << 1),
284    ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH  = (1 << 2),
285    ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND_FINISH    = (1 << 3),
286 } Elm_Genlist_Item_Pinchzoom_effect_Mode;
287
288 #define GROUP_ALIGN_NORTH 1
289 #define GROUP_ALIGN_WEST 2
290
291 struct _Widget_Data
292 {
293    Evas_Object *obj, *scr, *pan_smart;
294    Eina_Inlist *items, *blocks;
295    Pan *pan;
296    Evas_Coord pan_x, pan_y, minw, minh;
297    Ecore_Job *calc_job, *update_job;
298    Ecore_Idler *queue_idler;
299    Eina_List *queue, *selected;
300    Elm_Genlist_Item *show_item;
301    Elm_List_Mode mode;
302    Eina_Bool on_hold : 1;
303    Eina_Bool multi : 1;
304    Eina_Bool always_select : 1;
305    Eina_Bool longpressed : 1;
306    Eina_Bool wasselected : 1;
307    Eina_Bool no_select : 1;
308    Eina_Bool bring_in : 1;
309    Eina_Bool compress : 1;
310    Eina_Bool homogeneous : 1;
311    Eina_Bool clear_me : 1;
312    int walking;
313    int item_width;
314    int item_height;
315    int max_items_per_block;
316    double longpress_timeout;
317    Eina_Inlist *group_items;
318    Eina_List *menuopened;
319    int edit_mode;
320    int select_all_minh;
321    Eina_Bool animate_edit_controls :1;
322    Edit_Data *ed;
323
324    Evas_Coord td1_x, td1_y, tu1_x, tu1_y;
325    Evas_Coord td2_x, td2_y, tu2_x, tu2_y;
326    Evas_Coord d1_x, d1_y, d2_x, d2_y;
327    Evas_Coord acc_x1, acc_y1, acc_x2, acc_y2;
328    Evas_Coord prev_multi_x, prev_multi_y;
329    Eina_Bool multi_down : 1;
330    Eina_Bool multi_touch : 1;
331    Eina_List *edit_field;
332    Eina_Bool selct_all : 1;
333    Elm_Genlist_Item *select_all_item;
334
335    Eina_Bool effect_mode : 1;
336    Eina_Bool edit_mode_effect_mode : 1;   
337    Eina_Bool pinch_zoom : 1;
338    Eina_Bool pinch_zoom_reserve : 1;   
339    int move_effect_mode;
340    int pinchzoom_effect_mode;
341    int pinch_it;
342    int max_git_num;     
343    Ecore_Animator *item_moving_effect_timer;
344    Evas_Object *alpha_bg;
345    Evas_Object *point_rect;
346    Elm_Genlist_Item *expand_item;
347    int expand_item_cnt;
348    int contract_pan_y;
349    Evas_Coord start_y_pos;
350    double effect_start;
351    Eina_Bool queue_exception : 1;
352    int item_count;
353    Eina_Bool reoder_moved : 1;
354    int reoder_pan_y;   
355    Eina_Bool group_items_moved : 1;
356 };
357
358 struct _Edit_Data
359 {
360   Elm_Genlist_Edit_Class  *ec;
361   Elm_Genlist_Item *del_item;
362   Elm_Genlist_Item *reorder_item;
363   Elm_Genlist_Item *reorder_rel;
364   Evas_Object *del_confirm;
365 };
366
367 struct _Item_Block
368 {
369    EINA_INLIST;
370    int count;
371    int num;
372    Widget_Data *wd;
373    Eina_List *items;
374    Evas_Coord x, y, w, h, minw, minh;
375    Eina_Bool want_unrealize : 1;
376    Eina_Bool realized : 1;
377    Eina_Bool changed : 1;
378    Eina_Bool updateme : 1;
379    Eina_Bool showme : 1;
380    Evas_Coord reoder_y;
381 };
382
383 struct _Elm_Genlist_Item
384 {
385    EINA_INLIST;
386    Widget_Data *wd;
387    Item_Block *block;
388    Eina_List *items;
389    Evas_Coord x, y, w, h, minw, minh;
390    const Elm_Genlist_Item_Class *itc;
391    const void *data;
392    Elm_Genlist_Item *parent;
393    Elm_Genlist_Item_Flags flags;
394    struct {
395      Evas_Smart_Cb func;
396      const void *data;
397    } func;
398
399    Evas_Object *spacer, *base;
400    Eina_List *labels, *icons, *states, *icon_objs;
401    Ecore_Timer *long_timer;
402    Evas_Coord dx, dy, scrl_x, scrl_y;
403    Evas_Coord reoder_cavas_x, reoder_cavas_y;
404
405    Elm_Genlist_Item *rel;
406    int relcount;
407    int walking;
408    int expanded_depth;
409    
410    Eina_Bool before : 1;
411
412    Eina_Bool want_unrealize : 1;
413    Eina_Bool realized : 1;
414    Eina_Bool selected : 1;
415    Eina_Bool hilighted : 1;
416    Eina_Bool expanded : 1;
417    Eina_Bool disabled : 1;
418    Eina_Bool display_only : 1;
419    Eina_Bool mincalcd : 1;
420    Eina_Bool queued : 1;
421    Eina_Bool showme : 1;
422    Eina_Bool delete_me : 1;
423    Eina_Bool down : 1;
424    Eina_Bool dragging : 1;
425    Eina_Bool updateme : 1;
426    Eina_Bool delete_check : 1;
427    Eina_Bool del_confirm_state : 1;
428    Eina_Bool reordering : 1;
429    Eina_Bool menuopened : 1;
430    Eina_Bool select_all_item : 1;
431    Eina_Bool reorder_check: 1;
432    Eina_Bool renamed : 1;
433
434    int pad_left, pad_right;
435
436    Evas_Coord old_scrl_y;
437    Evas_Coord old_pad_left;
438    int list_expanded;
439    Eina_Bool effect_done : 1;   
440    Elm_Genlist_GroupItem *group_item;
441    Evas_Object *edit_obj;
442    Eina_List *edit_icon_objs;
443    Ecore_Timer *edit_long_timer;
444 };
445
446 #define ELM_GENLIST_ITEM_FROM_INLIST(item)      \
447   ((item) ? EINA_INLIST_CONTAINER_GET(item, Elm_Genlist_Item) : NULL)
448
449 struct _Pan
450 {
451    Evas_Object_Smart_Clipped_Data __clipped_data;
452    Widget_Data *wd;
453 };
454
455 struct _Elm_Genlist_GroupItem
456 {
457    EINA_INLIST;
458    Widget_Data *wd;
459    Eina_List *items;
460    Evas_Coord x, y, w, h, minw, minh;
461    const Elm_Genlist_Item_Class *itc;
462    const void *data;
463    struct {
464         Evas_Smart_Cb func;
465         const void *data;
466      } func;
467
468    Evas_Object *base;
469    Eina_List *labels, *icons, *states, *icon_objs;
470    int align;
471    Eina_Bool realized : 1;
472    Eina_Bool delete_me : 1;
473    Eina_Bool visible : 1;
474    Eina_Bool mincalcd : 1;
475
476    Evas_Coord old_y, finish_y;
477    int num;
478    Eina_Bool down : 1;
479    Eina_Bool update_finish_y : 1;
480 };
481
482 static const char *widtype = NULL;
483 static void _del_hook(Evas_Object *obj);
484 static void _theme_hook(Evas_Object *obj);
485 static void _show_region_hook(void *data, Evas_Object *obj);
486 static void _sizing_eval(Evas_Object *obj);
487 static void _item_unrealize(Elm_Genlist_Item *it);
488 static void _item_block_unrealize(Item_Block *itb);
489 static void _calc_job(void *data);
490 static void _groupitem_remove(Elm_Genlist_GroupItem *git, Eina_Bool update_items);
491 static void _groupitem_unrealize(Elm_Genlist_GroupItem *git);
492 static Eina_Bool _edit_mode_reset(Widget_Data *wd);
493 static void _edit_controls_eval(Elm_Genlist_Item *it);
494 static void _move_edit_controls(Elm_Genlist_Item *it, int itx, int ity);
495 static Eina_Bool _item_moving_effect_timer_cb(void *data);
496 static Eina_Bool _edit_mode_item_moving_effect_cb(void *data);
497 static int _item_flip_effect_show(void *data);
498 static void _elm_genlist_pinch_zoom_execute(Evas_Object *obj, Eina_Bool emode);
499 static void _delete_confirm_cb(void *data, Evas_Object *obj, void *event_info);
500 static void _select_all_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
501 static void _notify_item_position(Elm_Genlist_Item *it);
502 static void _notify_item_position(Elm_Genlist_Item *it);
503 static int _get_space_for_reorder_item(Elm_Genlist_Item *it);
504
505 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
506
507 static void
508 _del_hook(Evas_Object *obj)
509 {
510    Widget_Data *wd = elm_widget_data_get(obj);
511    if (!wd) return;
512    if (wd->calc_job) ecore_job_del(wd->calc_job);
513    if (wd->update_job) ecore_job_del(wd->update_job);
514    free(wd);
515 }
516
517 static void
518 _del_pre_hook(Evas_Object *obj)
519 {
520    Widget_Data *wd = elm_widget_data_get(obj);
521    if (!wd) return;
522    evas_object_del(wd->pan_smart);
523    wd->pan_smart = NULL;
524    elm_genlist_clear(obj);
525 }
526
527 static void
528 _theme_hook(Evas_Object *obj)
529 {
530    Widget_Data *wd = elm_widget_data_get(obj);
531    Item_Block *itb;
532    Elm_Genlist_GroupItem *git;
533    if (!wd) return;
534    elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
535    //   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
536    EINA_INLIST_FOREACH(wd->group_items, git)
537      {
538         _groupitem_unrealize(git);
539      }
540    EINA_INLIST_FOREACH(wd->blocks, itb)
541      {
542         Eina_List *l;
543         Elm_Genlist_Item *it;
544
545         if (itb->realized) _item_block_unrealize(itb);
546         EINA_LIST_FOREACH(itb->items, l, it)
547            it->mincalcd = EINA_FALSE;
548
549         itb->changed = EINA_TRUE;
550      }
551    if (wd->calc_job) ecore_job_del(wd->calc_job);
552    wd->calc_job = ecore_job_add(_calc_job, wd);
553    _sizing_eval(obj);
554 }
555
556 static void
557 _show_region_hook(void *data, Evas_Object *obj)
558 {
559    Widget_Data *wd = elm_widget_data_get(data);
560    Evas_Coord x, y, w, h;
561    if (!wd) return;
562    elm_widget_show_region_get(obj, &x, &y, &w, &h);
563    //x & y are screen coordinates, Add with pan coordinates
564    x += wd->pan_x;
565    y += wd->pan_y;
566    elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
567 }
568
569 static void
570 _sizing_eval(Evas_Object *obj)
571 {
572    Widget_Data *wd = elm_widget_data_get(obj);
573    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
574    if (!wd) return;
575    evas_object_size_hint_min_get(wd->scr, &minw, &minh);
576    evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
577    minh = -1;
578    if (wd->mode != ELM_LIST_LIMIT) minw = -1;
579    else
580      {
581         Evas_Coord  vmw, vmh, vw, vh;
582
583         minw = wd->minw;
584         maxw = -1;
585         elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
586         if ((minw > 0) && (vw < minw)) vw = minw;
587         else if ((maxw > 0) && (vw > maxw)) vw = maxw;
588         minw = -1;
589         edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
590         minw = vmw + minw;
591      }
592    evas_object_size_hint_min_set(obj, minw, minh);
593    evas_object_size_hint_max_set(obj, maxw, maxh);
594 }
595
596 static void
597 _item_hilight(Elm_Genlist_Item *it)
598 {
599    const char *selectraise;
600
601    if ((it->wd->no_select) || (it->delete_me) || (it->hilighted) || (it->disabled) ||
602        (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)) return;
603    if (!it->menuopened)
604       edje_object_signal_emit(it->base, "elm,state,selected", "elm");
605    selectraise = edje_object_data_get(it->base, "selectraise");
606    if ((selectraise) && (!strcmp(selectraise, "on")))
607      {
608         evas_object_raise(it->base);
609         if (it->group_item && it->group_item->realized)
610            evas_object_raise(it->group_item->base);
611      }
612    it->hilighted = EINA_TRUE;
613 }
614
615 static void
616 _item_block_del(Elm_Genlist_Item *it)
617 {
618    Eina_Inlist *il;
619    Item_Block *itb = it->block;
620
621    itb->items = eina_list_remove(itb->items, it);
622    itb->count--;
623    itb->changed = EINA_TRUE;
624    if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
625    it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
626    if (itb->count < 1)
627      {
628         il = EINA_INLIST_GET(itb);
629         Item_Block *itbn = (Item_Block *)(il->next);
630         if (it->parent)
631            it->parent->items = eina_list_remove(it->parent->items, it);
632         else
633            it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
634         free(itb);
635         if (itbn) itbn->changed = EINA_TRUE;
636      }
637    else
638      {
639         if (itb->count < itb->wd->max_items_per_block/2)
640           {
641              il = EINA_INLIST_GET(itb);
642              Item_Block *itbp = (Item_Block *)(il->prev);
643              Item_Block *itbn = (Item_Block *)(il->next);
644              if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
645                {
646                   Elm_Genlist_Item *it2;
647
648                   EINA_LIST_FREE(itb->items, it2)
649                     {
650                        it2->block = itbp;
651                        itbp->items = eina_list_append(itbp->items, it2);
652                        itbp->count++;
653                        itbp->changed = EINA_TRUE;
654                     }
655                   it->wd->blocks = eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
656                   free(itb);
657                }
658              else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
659                {
660                   while (itb->items)
661                     {
662                        Eina_List *last = eina_list_last(itb->items);
663                        Elm_Genlist_Item *it2 = last->data;
664
665                        it2->block = itbn;
666                        itb->items = eina_list_remove_list(itb->items, last);
667                        itbn->items = eina_list_prepend(itbn->items, it2);
668                        itbn->count++;
669                        itbn->changed = EINA_TRUE;
670                     }
671                   it->wd->blocks =
672                      eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
673                   free(itb);
674                }
675           }
676      }
677 }
678
679 static void
680 _item_del(Elm_Genlist_Item *it)
681 {
682    elm_genlist_item_subitems_clear(it);
683    it->wd->walking -= it->walking;
684    if (it->wd->show_item == it) it->wd->show_item = NULL;
685    if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
686    if (it->realized) _item_unrealize(it);
687    if (it->block) _item_block_del(it);
688    if ((!it->delete_me) && (it->itc->func.del))
689       it->itc->func.del(it->data, it->wd->obj);
690    it->delete_me = EINA_TRUE;
691    if (it->queued)
692       it->wd->queue = eina_list_remove(it->wd->queue, it);
693    it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
694    if (it->parent)
695       it->parent->items = eina_list_remove(it->parent->items, it);
696    if (it->long_timer) ecore_timer_del(it->long_timer);
697    if (it->group_item)
698      {
699         it->group_item->items = eina_list_remove(it->group_item->items,it);
700      }
701    free(it);
702 }
703
704 static void
705 _item_select(Elm_Genlist_Item *it)
706 {
707    if ((it->wd->no_select) || (it->delete_me) || (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)) return;
708    if (it->selected)
709      {
710         if (it->wd->always_select) goto call;
711         return;
712      }
713    it->selected = EINA_TRUE;
714    it->wd->selected = eina_list_append(it->wd->selected, it);
715 call:
716    it->walking++;
717    it->wd->walking++;
718    if (it->func.func) it->func.func((void *)it->func.data, it->wd->obj, it);
719    if (!it->delete_me)
720       evas_object_smart_callback_call(it->wd->obj, "selected", it);
721    it->walking--;
722    it->wd->walking--;
723    if ((it->wd->clear_me) && (!it->wd->walking))
724       elm_genlist_clear(it->wd->obj);
725    else
726      {
727         if ((!it->walking) && (it->delete_me))
728           {
729              if (!it->relcount) _item_del(it);
730           }
731      }
732 }
733
734 static void
735 _item_unselect(Elm_Genlist_Item *it)
736 {
737    const char *stacking, *selectraise;
738
739    if ((it->delete_me) || (!it->hilighted)) return;
740    if (!it->menuopened)
741         edje_object_signal_emit(it->base, "elm,state,unselected", "elm");
742    stacking = edje_object_data_get(it->base, "stacking");
743    selectraise = edje_object_data_get(it->base, "selectraise");
744    if ((selectraise) && (!strcmp(selectraise, "on")))
745      {
746         if ((stacking) && (!strcmp(stacking, "below")))
747           evas_object_lower(it->base);
748      }
749    it->hilighted = EINA_FALSE;
750    if (it->selected)
751      {
752         it->selected = EINA_FALSE;
753         it->wd->selected = eina_list_remove(it->wd->selected, it);
754         evas_object_smart_callback_call(it->wd->obj, "unselected", it);
755      }
756 }
757
758 static void
759 _item_slide(Elm_Genlist_Item *it, Eina_Bool slide_to_right)
760 {
761    const Eina_List *l;
762    Elm_Genlist_Item *it2;
763    const char *allow_slide;
764
765    allow_slide = edje_object_data_get(it->base, "allow_slide");
766    if (!allow_slide)
767      return;
768
769    if (atoi(allow_slide) != 1)
770      return;
771
772    if (slide_to_right)
773      {
774         if (!it->menuopened)
775           edje_object_signal_emit(it->base, "elm,state,slide,right", "elm");
776         it->wd->menuopened = eina_list_append(it->wd->menuopened, it);
777
778         EINA_LIST_FOREACH(it->wd->menuopened, l, it2)
779           {
780              if (it2 != it)
781                {
782                   it2->menuopened = EINA_FALSE;
783                   edje_object_signal_emit(it2->base, "elm,state,slide,left", "elm");
784                   it2->wd->menuopened = eina_list_remove(it2->wd->menuopened, it2);
785                }
786           }
787      }
788    else
789      {
790         if (it->menuopened)
791           edje_object_signal_emit(it->base, "elm,state,slide,left", "elm");
792         it->wd->menuopened = eina_list_remove(it->wd->menuopened, it);
793      }
794
795    it->menuopened = slide_to_right;
796 }
797
798 static void
799 _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
800 {
801    Elm_Genlist_Item *it = data;
802    Evas_Event_Mouse_Move *ev = event_info;
803    Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
804    Evas_Coord acc_x, acc_y;
805
806    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
807      {
808         if (!it->wd->on_hold)
809           {
810              it->wd->on_hold = EINA_TRUE;
811              if (!it->wd->wasselected)
812                 _item_unselect(it);
813           }
814      }
815    if ((it->dragging) && (it->down))
816      {
817         if (it->long_timer)
818           {
819              ecore_timer_del(it->long_timer);
820              it->long_timer = NULL;
821           }
822         evas_object_smart_callback_call(it->wd->obj, "drag", it);
823         return;
824      }
825    if ((!it->down)/* || (it->wd->on_hold)*/ || (it->wd->longpressed))
826      {
827         if (it->long_timer)
828           {
829              ecore_timer_del(it->long_timer);
830              it->long_timer = NULL;
831           }
832         return;
833      }
834
835    if (it->wd->multi_down)
836      {
837         acc_x = ev->prev.canvas.x - ev->cur.canvas.x;
838         if (acc_x < 0)
839           it->wd->acc_x1 = it->wd->acc_x1 - acc_x;
840         else
841           it->wd->acc_x1 = it->wd->acc_x1 + acc_x;
842
843         acc_y = ev->prev.canvas.y - ev->cur.canvas.y;
844         if (acc_y < 0)
845           it->wd->acc_y1 = it->wd->acc_y1 - acc_y;
846         else
847           it->wd->acc_y1 = it->wd->acc_y1 + acc_y;
848
849         return;
850      }
851
852    if (!it->display_only)
853      elm_coords_finger_size_adjust(1, &minw, 1, &minh);
854    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
855    x = ev->cur.canvas.x - x;
856    y = ev->cur.canvas.y - y;
857    dx = x - it->dx;
858    adx = dx;
859    if (adx < 0) adx = -dx;
860    dy = y - it->dy;
861    ady = dy;
862    if (ady < 0) ady = -dy;
863    minw /= 2;
864    minh /= 2;
865    if ((adx > minw) || (ady > minh))
866      {
867         it->dragging = 1;
868         if (it->long_timer)
869           {
870              ecore_timer_del(it->long_timer);
871              it->long_timer = NULL;
872           }
873         if (!it->wd->wasselected)
874           _item_unselect(it);
875         if (dy < 0)
876           {
877              if (ady > adx)
878                evas_object_smart_callback_call(it->wd->obj, "drag,start,up", it);
879              else
880                {
881                   if (dx < 0)
882                     {
883                        evas_object_smart_callback_call(it->wd->obj,
884                              "drag,start,left", it);
885                        _item_slide(it, 0);
886                     }
887                   else
888                     {
889                        evas_object_smart_callback_call(it->wd->obj,
890                              "drag,start,right", it);
891                        _item_slide(it, 1);
892                     }
893                }
894           }
895         else
896           {
897              if (ady > adx)
898                evas_object_smart_callback_call(it->wd->obj,
899                      "drag,start,down", it);
900              else
901                {
902                   if (dx < 0)
903                     {
904                        evas_object_smart_callback_call(it->wd->obj,
905                              "drag,start,left", it);
906                        _item_slide(it, 0);
907                     }
908                   else
909                     {
910                        evas_object_smart_callback_call(it->wd->obj,
911                              "drag,start,right", it);
912                        _item_slide(it, 1);
913                     }
914                }
915           }
916      }
917 }
918
919 static Eina_Bool
920 _long_press(void *data)
921 {
922    Elm_Genlist_Item *it = data;
923
924    it->long_timer = NULL;
925    if ((it->disabled) || (it->dragging)) return ECORE_CALLBACK_CANCEL;
926    it->wd->longpressed = EINA_TRUE;
927    evas_object_smart_callback_call(it->wd->obj, "longpressed", it);
928    return ECORE_CALLBACK_CANCEL;
929 }
930
931 static Eina_Bool
932 _edit_long_press(void *data)
933 {
934   Elm_Genlist_Item *it = data, *it_tmp; 
935   Evas_Coord x, y;
936   static Eina_Bool contracted = EINA_FALSE;
937   Eina_List *l;
938   Item_Block *itb;
939    
940   it->edit_long_timer = NULL;
941   if ((it->disabled) || (it->dragging)) return 0;
942
943   EINA_INLIST_FOREACH(it->wd->blocks, itb)
944    {
945      EINA_LIST_FOREACH(itb->items, l, it_tmp)
946       {
947        if(!it_tmp->parent && elm_genlist_item_expanded_get(it_tmp)) 
948          {
949            elm_genlist_item_expanded_set(it_tmp, EINA_FALSE);
950            contracted = EINA_TRUE;
951            return 1;
952            
953          }
954       }
955    }
956   if(contracted) {
957    contracted = EINA_FALSE;
958    return 0;
959   }
960
961   edje_object_signal_emit(it->edit_obj, "elm,action,item,reorder_start", "elm");
962
963   evas_object_geometry_get(it->base, &x, &y, NULL, NULL);
964
965   it->dx = it->reoder_cavas_x - x;
966   it->dy = it->reoder_cavas_y - y;  
967
968   evas_object_raise(it->base);
969   evas_object_raise(it->edit_obj);
970
971   it->wd->ed->reorder_item = it;
972   it->wd->ed->reorder_item->reordering = 1;
973   it->wd->ed->reorder_rel = NULL;
974   elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
975   it->wd->reoder_pan_y = it->wd->pan_y;
976   it->wd->reoder_moved = EINA_TRUE;
977
978   return 0;
979 }
980  
981 static void
982 _multi_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
983 {
984    Elm_Genlist_Item *it = data;
985    Evas_Event_Multi_Down *ev = event_info;
986    Evas_Coord dx, dy, adx, ady;
987
988    if (it->long_timer)
989      {
990         ecore_timer_del(it->long_timer);
991         it->long_timer = NULL;
992      }
993
994    dx = it->wd->td1_x - ev->canvas.x;
995    adx = dx;
996    if (adx < 0) adx = -dx;
997    dy = it->wd->td1_y - ev->canvas.y;
998    ady = dy;
999    if (ady < 0) ady = -dy;
1000
1001    if (adx < 60 && ady < 60)
1002      return;
1003
1004    it->wd->multi_down = 1;
1005    it->wd->td2_x = ev->canvas.x;
1006    it->wd->td2_y = ev->canvas.y;
1007 /*
1008         if (it->wd->effect_mode && it->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH) 
1009           {
1010                   evas_object_move(it->wd->point_rect, 2, (it->wd->td1_y + it->wd->td2_y) / 2);
1011                   evas_object_raise(it->wd->point_rect);
1012                   evas_object_show(it->wd->point_rect);
1013           }
1014    fprintf(stderr, "\n MULTI_DOWN - BUTTON ID = %d, x= %d, y= %d\n", ev->device, it->wd->td2_x, it->wd->td2_y);
1015 */
1016 }
1017
1018 static void
1019 _multi_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
1020 {
1021    Elm_Genlist_Item *it = data;
1022    Evas_Event_Multi_Up *ev = event_info;
1023    Evas_Coord dy, uy, ady, auy;
1024    int multi_y_avg = 0;
1025
1026    fprintf(stderr, "\n MULTI_UP - x= %d, y= %d down= %d multi_down= %d\n", ev->canvas.x, ev->canvas.y, it->down, it->wd->multi_down);
1027
1028    if (!it->wd->multi_down)
1029       return;
1030
1031    it->wd->multi_down = 0;
1032    it->wd->tu2_x = ev->canvas.x;
1033    it->wd->tu2_y = ev->canvas.y;
1034    it->wd->d2_x = ev->canvas.x - it->wd->td2_x;
1035    it->wd->d2_y = ev->canvas.y - it->wd->td2_y;
1036
1037    evas_object_lower(it->wd->point_rect);
1038    evas_object_hide(it->wd->point_rect);
1039
1040    if (it->down)
1041      {
1042         it->wd->multi_touch = EINA_TRUE;
1043      }
1044    else
1045      {
1046         fprintf(stderr, "CHECK d1_x= %d, d2_x= %d, d1_y= %d, d2_y= %d\n", it->wd->d1_x, it->wd->d2_x, it->wd->d1_y, it->wd->d2_y);
1047
1048         if ((it->wd->d1_x > 180) && (it->wd->d2_x > 180))
1049           {
1050              // Two finger : Left -> Right
1051              fprintf(stderr, "L->R acc_y1= %d, acc_y2= %d\n", it->wd->acc_y1, it->wd->acc_y2);
1052              if (it->wd->acc_y1 < 200 && it->wd->acc_y2 < 200)
1053                 evas_object_smart_callback_call(it->wd->obj, "multi_touch,left,right", it);
1054           }
1055         else if ((it->wd->d1_y > 180) && (it->wd->d2_y > 180))
1056           {
1057              // Two finger : Top -> Bottom
1058              fprintf(stderr, "T->B acc_x1= %d, acc_x2= %d\n", it->wd->acc_x1, it->wd->acc_x2);
1059              if (it->wd->acc_x1 < 200 && it->wd->acc_x2 < 200)
1060                 evas_object_smart_callback_call(it->wd->obj, "multi_touch,top,bottom", it);
1061           }
1062         else
1063           {
1064              dy = it->wd->td1_y - it->wd->td2_y;
1065              if (dy < 0)
1066                 ady = -dy;
1067              else
1068                 ady = dy;
1069
1070              uy = it->wd->tu1_y - it->wd->tu2_y;
1071              if (uy < 0)
1072                 auy = -uy;
1073              else
1074                 auy = uy;
1075
1076              if (auy < ady)
1077                {
1078                   if (auy < ady*0.8)
1079                     {
1080                        // Two finger : Pinch Out
1081                        evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,out", it);
1082
1083                        if (it->wd->effect_mode == EINA_TRUE)
1084                           _elm_genlist_pinch_zoom_execute(it->wd->obj, 1);
1085                     }
1086                }
1087              else
1088                {
1089                   if (ady < auy*0.9)
1090                     {
1091                        // Two finger : Pinch In
1092                        evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,in", it);
1093
1094                        if (it->wd->effect_mode == EINA_TRUE && it->wd->pinch_zoom == EINA_TRUE)
1095                          {
1096                             multi_y_avg= (it->wd->td1_y + it->wd->td2_y) / 2;
1097                             if(it->group_item)
1098                                it->wd->pinch_it = (multi_y_avg / it->group_item->h + it->wd->contract_pan_y / it->group_item->h) - 2;
1099                             fprintf(stderr," pinch,in!! it ================ it->y = %d it->old_y = %d it = %d it->wd->td1_y = %d it->wd->td2_y = %d pinch_it = %d  it->wd->contract_pan_y = %d\n", it->y, it->old_scrl_y, it->old_scrl_y / 30,  it->wd->td1_y, it->wd->td2_y, it->wd->pinch_it, it->wd->contract_pan_y);
1100                             _elm_genlist_pinch_zoom_execute(it->wd->obj, 0);
1101                          }
1102                     }
1103                }
1104           }
1105
1106         it->wd->acc_x1 = 0;
1107         it->wd->acc_y1 = 0;
1108         it->wd->acc_x2 = 0;
1109         it->wd->acc_y2 = 0;
1110         it->wd->prev_multi_x = 0;
1111         it->wd->prev_multi_y = 0;
1112      }
1113 }
1114
1115 static void
1116 _multi_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
1117 {
1118    Elm_Genlist_Item *it = data;
1119    Evas_Event_Multi_Move *ev = event_info;
1120    Evas_Coord acc_x, acc_y;
1121
1122    if (!it->wd->prev_multi_x)
1123      {
1124         it->wd->prev_multi_x = ev->cur.canvas.x;
1125         it->wd->prev_multi_y = ev->cur.canvas.y;
1126         return;
1127      }
1128
1129    acc_x = it->wd->prev_multi_x - ev->cur.canvas.x;
1130    if (acc_x < 0)
1131       it->wd->acc_x2 = it->wd->acc_x2 - acc_x;
1132    else
1133       it->wd->acc_x2 = it->wd->acc_x2 + acc_x;
1134
1135    acc_y = it->wd->prev_multi_y - ev->cur.canvas.y;
1136    if (acc_y < 0)
1137       it->wd->acc_y2 = it->wd->acc_y2 - acc_y;
1138    else
1139       it->wd->acc_y2 = it->wd->acc_y2 + acc_y;
1140
1141    it->wd->prev_multi_x = ev->cur.canvas.x;
1142    it->wd->prev_multi_y = ev->cur.canvas.y;
1143 }
1144
1145 static void
1146 _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
1147 {
1148    Elm_Genlist_Item *it = data;
1149    Evas_Event_Mouse_Down *ev = event_info;
1150    Evas_Coord x, y;
1151
1152    it->wd->group_items_moved = EINA_FALSE;
1153    it->wd->td1_x = ev->canvas.x;
1154    it->wd->td1_y = ev->canvas.y;
1155    if (it->wd->effect_mode && it->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH) 
1156      {
1157         elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_TRUE);
1158         return;
1159      }
1160
1161    if (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)
1162       (void)_edit_mode_reset(it->wd);
1163    if (ev->button != 1) return;
1164    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)  
1165      {  
1166         it->wd->on_hold = EINA_TRUE;  
1167      }  
1168
1169    if (it->wd->edit_field && !it->renamed)
1170       elm_genlist_item_rename_mode_set(it, 0);
1171
1172    it->down = 1;
1173    it->dragging  = 0;
1174    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1175    it->dx = ev->canvas.x - x;
1176    it->dy = ev->canvas.y - y;
1177    it->wd->longpressed = EINA_FALSE;
1178    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1179    else it->wd->on_hold = EINA_FALSE;
1180    if (it->wd->on_hold) return; 
1181    it->wd->wasselected = it->selected;
1182    _item_hilight(it);
1183    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1184       evas_object_smart_callback_call(it->wd->obj, "clicked", it);
1185    if (it->long_timer) ecore_timer_del(it->long_timer);
1186    if (it->realized)
1187       it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press, it);
1188    else
1189       it->long_timer = NULL;
1190 }
1191
1192 static void
1193 _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1194 {
1195    Elm_Genlist_Item *it = data;
1196    Evas_Event_Mouse_Up *ev = event_info;
1197    Eina_Bool dragged = EINA_FALSE;
1198    Evas_Coord dy, uy, ady, auy;
1199    int multi_y_avg;
1200
1201    if (ev->button != 1) return;
1202    it->down = 0;
1203    it->wd->acc_x1 = 0;
1204    it->wd->acc_y1 = 0;
1205
1206    it->wd->tu1_x = ev->canvas.x;
1207    it->wd->tu1_y = ev->canvas.y;
1208    it->wd->d1_x = ev->canvas.x - it->wd->td1_x;
1209    it->wd->d1_y = ev->canvas.y - it->wd->td1_y;
1210
1211    //   evas_object_lower(it->wd->point_rect);
1212    //   evas_object_hide(it->wd->point_rect);
1213    if (it->wd->effect_mode && it->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE)  return;
1214
1215    if (!it->wd->multi_down && it->wd->multi_touch == EINA_TRUE)
1216      {
1217         if ((it->wd->d1_x > 180) && (it->wd->d2_x > 180))
1218           {
1219              // Two finger : Left -> Right
1220              fprintf(stderr, "L->R acc_y1= %d, acc_y2= %d\n", it->wd->acc_y1, it->wd->acc_y2);
1221              if (it->wd->acc_y1 < 200 && it->wd->acc_y2 < 200)
1222                 evas_object_smart_callback_call(it->wd->obj, "multi_touch,left,right", it);
1223           }
1224         else if ((it->wd->d1_y > 180) && (it->wd->d2_y > 180))
1225           {
1226              // Two finger : Top -> Bottom
1227              fprintf(stderr, "T->B acc_x1= %d, acc_x2= %d\n", it->wd->acc_x1, it->wd->acc_x2);
1228              if (it->wd->acc_x1 < 200 && it->wd->acc_x2 < 200)
1229                 evas_object_smart_callback_call(it->wd->obj, "multi_touch,top,bottom", it);
1230           }
1231         else
1232           {
1233              dy = it->wd->td1_y - it->wd->td2_y;
1234              if (dy < 0) ady = -dy;
1235              else ady = dy;
1236
1237              uy = it->wd->tu1_y - it->wd->tu2_y;
1238              if (uy < 0) auy = -uy;
1239              else auy = uy;
1240
1241              if (auy < ady)
1242                {
1243                   if (auy < ady*0.8)
1244                     {
1245                        // Two finger : Pinch Out
1246                        evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,out", it);
1247                        if (it->wd->effect_mode == EINA_TRUE)
1248                           _elm_genlist_pinch_zoom_execute(it->wd->obj, 1);
1249                     }
1250                }
1251              else
1252                {
1253                   if (ady < auy*0.9)
1254                     {
1255                        // Two finger : Pinch In
1256                        evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,in", it);
1257                        if (it->wd->effect_mode == EINA_TRUE && it->wd->pinch_zoom == EINA_TRUE)
1258                          {
1259                             multi_y_avg= (it->wd->td1_y + it->wd->td2_y) / 2;
1260                             if(it->group_item)
1261                                it->wd->pinch_it = (multi_y_avg / it->group_item->h + it->wd->contract_pan_y / it->group_item->h) - 2;
1262                             fprintf(stderr,"mouse up pinch,in!! it ================ it->y = %d it->old_y = %d it = %d it->wd->td1_y = %d it->wd->td2_y = %d pinch_it = %d  it->wd->contract_pan_y = %d \n", it->y, it->old_scrl_y, it->old_scrl_y / 30,  it->wd->td1_y, it->wd->td2_y, it->wd->pinch_it, it->wd->contract_pan_y);
1263                             _elm_genlist_pinch_zoom_execute(it->wd->obj, 0);
1264                          }
1265                     }
1266                }
1267
1268           }
1269
1270         it->wd->acc_x1 = 0;
1271         it->wd->acc_y1 = 0;
1272         it->wd->acc_x2 = 0;
1273         it->wd->acc_y2 = 0;
1274         it->wd->prev_multi_x = 0;
1275         it->wd->prev_multi_y = 0;
1276         it->wd->multi_down = 0;
1277      }
1278
1279    it->wd->multi_touch = EINA_FALSE;
1280
1281    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1282    else it->wd->on_hold = EINA_FALSE;
1283    if (it->long_timer)
1284      {
1285         ecore_timer_del(it->long_timer);
1286         it->long_timer = NULL;
1287      }
1288    if (it->dragging)
1289      {
1290         it->dragging = 0;
1291         evas_object_smart_callback_call(it->wd->obj, "drag,stop", it);
1292         dragged = 1;
1293      }
1294    if (it->wd->on_hold)
1295      {
1296         it->wd->longpressed = EINA_FALSE;
1297         it->wd->on_hold = EINA_FALSE;
1298         return;
1299      }
1300    if (it->wd->longpressed)
1301      {
1302         it->wd->longpressed = EINA_FALSE;
1303         if (!it->wd->wasselected)
1304            _item_unselect(it);
1305         it->wd->wasselected = 0;
1306         return;
1307      }
1308    if (dragged)
1309      {
1310         if (it->want_unrealize)
1311           {
1312              _item_unrealize(it);
1313              if (it->block->want_unrealize)
1314                 _item_block_unrealize(it->block);
1315           }
1316      }
1317    if ((it->disabled) || (dragged)) return;
1318    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;    
1319    if (it->wd->multi)
1320      {
1321         if (!it->selected && !it->menuopened)
1322           {
1323              _item_hilight(it);
1324              _item_select(it);
1325           }
1326         else _item_unselect(it);
1327      }
1328    else
1329      {
1330         if (!it->selected)
1331           {
1332              Widget_Data *wd = it->wd;
1333              if (wd)
1334                {
1335                   while (wd->selected) _item_unselect(wd->selected->data);
1336                }
1337           }
1338         else
1339           {
1340              const Eina_List *l, *l_next;
1341              Elm_Genlist_Item *it2;
1342
1343              EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1344                 if (it2 != it) _item_unselect(it2);
1345              //_item_hilight(it);
1346              //_item_select(it);
1347           }
1348         if (!it->menuopened)
1349           {
1350              _item_hilight(it);
1351              _item_select(it);
1352           }
1353      }
1354 }
1355
1356 static void
1357 _signal_expand_toggle(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1358 {
1359    Elm_Genlist_Item *it = data;
1360
1361    if (it->expanded)
1362      evas_object_smart_callback_call(it->wd->obj, "contract,request", it);
1363    else
1364      evas_object_smart_callback_call(it->wd->obj, "expand,request", it);
1365 }
1366
1367 static void
1368 _signal_expand(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1369 {
1370    Elm_Genlist_Item *it = data;
1371
1372    if (!it->expanded)
1373      evas_object_smart_callback_call(it->wd->obj, "expand,request", it);
1374 }
1375
1376 static void
1377 _signal_contract(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1378 {
1379    Elm_Genlist_Item *it = data;
1380
1381    if (it->expanded)
1382      evas_object_smart_callback_call(it->wd->obj, "contract,request", it);
1383 }
1384
1385 static void
1386 _group_item_click_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1387 {
1388    Elm_Genlist_GroupItem *git = data;
1389    elm_smart_scroller_bounce_allow_set(git->wd->scr, EINA_FALSE, EINA_TRUE);
1390    if (git->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
1391      {
1392       if(!git->wd->group_items_moved) 
1393       {
1394         git->wd->pinch_it = git->num;
1395         _elm_genlist_pinch_zoom_execute(git->wd->obj, 0);   
1396       }
1397       git->wd->group_items_moved = EINA_FALSE;
1398      }
1399    return;
1400 }
1401
1402 static void
1403 _groupitem_realize(Elm_Genlist_Item *it, int calc)
1404 {
1405    char buf[1024];
1406    const char *align;
1407    Elm_Genlist_GroupItem *git = it->group_item;
1408    Evas_Coord ox, oy, ow, oh;
1409
1410    if (calc && git->realized)
1411      {
1412         git->wd->start_y_pos += it->h;
1413      }
1414
1415    if ((git->realized) || (git->delete_me)) return;
1416    git->base = edje_object_add(evas_object_evas_get(git->wd->obj));
1417    edje_object_scale_set(git->base, elm_widget_scale_get(git->wd->obj) *
1418                          _elm_config->scale);
1419    evas_object_smart_member_add(git->base, git->wd->pan_smart);
1420    elm_widget_sub_object_add(git->wd->obj, git->base);
1421
1422    strncpy(buf, "item/", sizeof(buf));
1423    strncat(buf, git->itc->item_style, sizeof(buf) - strlen(buf));
1424    _elm_theme_object_set(git->wd->obj, git->base, "genlist", buf, elm_widget_style_get(git->wd->obj));
1425
1426    align = edje_object_data_get(git->base, "orientation");
1427    git->align = GROUP_ALIGN_NORTH;
1428    if (align)
1429      {
1430         if (!strcmp(align, "top"))
1431            git->align = GROUP_ALIGN_NORTH;
1432         else if (!strcmp(align, "left"))
1433            git->align = GROUP_ALIGN_WEST;
1434         else git->align = GROUP_ALIGN_NORTH;
1435      }
1436
1437    if (git->itc->func.label_get)
1438      {
1439         const Eina_List *l;
1440         const char *key;
1441
1442         git->labels = _elm_stringlist_get(edje_object_data_get(git->base, "labels"));
1443         EINA_LIST_FOREACH(git->labels, l, key)
1444           {
1445              char *s = git->itc->func.label_get(git->data, git->wd->obj, l->data);
1446
1447              if (s)
1448                {
1449                   edje_object_part_text_set(git->base, l->data, s);
1450                   free(s);
1451                }
1452           }
1453      }
1454
1455    if (git->itc->func.icon_get)
1456      {
1457         const Eina_List *l;
1458         const char *key;
1459
1460         git->icons = _elm_stringlist_get(edje_object_data_get(git->base, "icons"));
1461         EINA_LIST_FOREACH(git->icons, l, key)
1462           {
1463              Evas_Object *ic = git->itc->func.icon_get(git->data, git->wd->obj, l->data);
1464
1465              if (ic)
1466                {
1467                   git->icon_objs = eina_list_append(git->icon_objs, ic);
1468                   edje_object_part_swallow(git->base, key, ic);
1469                   evas_object_show(ic);
1470                   elm_widget_sub_object_add(git->wd->obj, ic);
1471                }
1472           }
1473
1474      }
1475    if (git->itc->func.state_get)
1476      {
1477         const Eina_List *l;
1478         const char *key;
1479
1480         git->states = _elm_stringlist_get(edje_object_data_get(git->base, "states"));
1481         EINA_LIST_FOREACH(git->states, l, key)
1482           {
1483              Eina_Bool on = git->itc->func.state_get(git->data, git->wd->obj, l->data);
1484
1485              if (on)
1486                {
1487                   snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1488                   edje_object_signal_emit(git->base, buf, "elm");
1489                }
1490           }
1491      }
1492    if (!git->mincalcd)
1493      {
1494         Evas_Coord mw = -1, mh = -1;
1495
1496         edje_object_size_min_restricted_calc(git->base, &mw, &mh, mw, mh);
1497
1498         git->w = git->minw = mw;
1499         git->h = git->minh = mh;
1500         git->mincalcd = EINA_TRUE;
1501      }
1502    evas_object_geometry_get(git->wd->pan_smart, &ox, &oy, &ow, &oh);      
1503
1504    if (!oy)
1505       git->update_finish_y = EINA_TRUE;
1506
1507    git->y = git->finish_y = oy + git->wd->start_y_pos;
1508    git->wd->start_y_pos += it->h + git->h;
1509
1510    git->num = ++git->wd->max_git_num;
1511
1512    edje_object_signal_callback_add(git->base, "elm,title_action,item,click",
1513                                    "elm", _group_item_click_cb, git);
1514    evas_object_show(git->base);
1515
1516    git->realized = EINA_TRUE;
1517 }
1518
1519 static void
1520 _groupitem_unrealize(Elm_Genlist_GroupItem *git)
1521 {
1522    Evas_Object *icon;
1523
1524    if (!git->realized) return;
1525    evas_object_del(git->base);
1526    git->base = NULL;
1527    _elm_stringlist_free(git->labels);
1528    git->labels = NULL;
1529    _elm_stringlist_free(git->icons);
1530    git->icons = NULL;
1531    _elm_stringlist_free(git->states);
1532
1533    EINA_LIST_FREE(git->icon_objs, icon)
1534       evas_object_del(icon);
1535
1536    if (git->wd->max_git_num)
1537       git->wd->max_git_num--;
1538    git->states = NULL;
1539    git->realized = EINA_FALSE;
1540 }
1541
1542 static void
1543 _groupitem_remove(Elm_Genlist_GroupItem *git, Eina_Bool update_items)
1544 {
1545    Elm_Genlist_Item *it;
1546    const Eina_List *l;
1547
1548    if (!git) return;
1549
1550    if (git->realized)
1551       _groupitem_unrealize(git);
1552
1553    git->wd->group_items = eina_inlist_remove(git->wd->group_items,EINA_INLIST_GET(git));
1554
1555    if (update_items)
1556      {
1557         EINA_LIST_FOREACH(git->items,l, it)
1558           {
1559              it->group_item = NULL;
1560              elm_genlist_item_update(it);
1561           }
1562      }
1563
1564    if (git->itc->func.del) git->itc->func.del(git->data, git->wd->obj);
1565    free(git);
1566 }
1567
1568 static void
1569 _item_realize(Elm_Genlist_Item *it, int in, int calc)
1570 {
1571    Elm_Genlist_Item *it2;
1572    const char *stacking;
1573    const char *treesize;
1574    char buf[1024];
1575    int depth, tsize = 20;
1576
1577    if ((it->realized) || (it->delete_me)) return;
1578    it->base = edje_object_add(evas_object_evas_get(it->wd->obj));
1579    edje_object_scale_set(it->base, elm_widget_scale_get(it->wd->obj) *
1580                          _elm_config->scale);
1581    evas_object_smart_member_add(it->base, it->wd->pan_smart);
1582    elm_widget_sub_object_add(it->wd->obj, it->base);
1583
1584    if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf));
1585    else strncpy(buf, "item", sizeof(buf));
1586    if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1587
1588    if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
1589    strncat(buf, "/", sizeof(buf) - strlen(buf));
1590    strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1591
1592    _elm_theme_object_set(it->wd->obj, it->base, "genlist", buf, elm_widget_style_get(it->wd->obj));
1593    it->spacer = evas_object_rectangle_add(evas_object_evas_get(it->wd->obj));
1594    evas_object_color_set(it->spacer, 0, 0, 0, 0);
1595    elm_widget_sub_object_add(it->wd->obj, it->spacer);
1596    for (it2 = it, depth = 0; it2->parent; it2 = it2->parent) depth += 1;
1597    it->expanded_depth = depth;
1598    treesize = edje_object_data_get(it->base, "treesize");
1599    if (treesize) tsize = atoi(treesize);
1600    evas_object_size_hint_min_set(it->spacer,
1601                                  (depth * tsize) * _elm_config->scale, 1);
1602    edje_object_part_swallow(it->base, "elm.swallow.pad", it->spacer);
1603    if (!calc)
1604      {
1605         edje_object_signal_callback_add(it->base, "elm,action,expand,toggle",
1606                                         "elm", _signal_expand_toggle, it);
1607         edje_object_signal_callback_add(it->base, "elm,action,expand", "elm",
1608                                         _signal_expand, it);
1609         edje_object_signal_callback_add(it->base, "elm,action,contract",
1610                                         "elm", _signal_contract, it);
1611         stacking = edje_object_data_get(it->base, "stacking");
1612         if (stacking)
1613           {
1614              if (!strcmp(stacking, "below")) evas_object_lower(it->base);
1615              else if (!strcmp(stacking, "above")) evas_object_raise(it->base);
1616           }
1617         evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN,
1618                                        _mouse_down, it);
1619         evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP,
1620                                        _mouse_up, it);
1621         evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_MOVE,
1622                                        _mouse_move, it);
1623         evas_object_event_callback_add(it->base, EVAS_CALLBACK_MULTI_DOWN,
1624                                        _multi_down, it);
1625         evas_object_event_callback_add(it->base, EVAS_CALLBACK_MULTI_UP,
1626                                        _multi_up, it);
1627         evas_object_event_callback_add(it->base, EVAS_CALLBACK_MULTI_MOVE,
1628                                        _multi_move, it);
1629         if (it->selected && !it->menuopened)
1630            edje_object_signal_emit(it->base, "elm,state,selected", "elm");
1631         if (it->disabled)
1632            edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
1633         if (it->expanded)
1634            edje_object_signal_emit(it->base, "elm,state,expanded", "elm");
1635      }
1636
1637    if ((calc) && (it->wd->homogeneous) && (it->wd->item_width))
1638      {
1639         /* homogenous genlist shortcut */
1640         if (!it->mincalcd)
1641           {
1642              it->w = it->minw = it->wd->item_width;
1643              it->h = it->minh = it->wd->item_height;
1644              it->mincalcd = EINA_TRUE;
1645           }
1646      }
1647    else
1648      {
1649         if (!strcmp(it->itc->item_style, "select_all"))
1650           {
1651              const Eina_List *l;
1652              const char *key;
1653
1654              it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
1655              EINA_LIST_FOREACH(it->labels, l, key) {
1656                   edje_object_part_text_set(it->base, l->data, "Select all");
1657              }
1658           }
1659
1660         if (it->itc->func.label_get)
1661           {
1662              const Eina_List *l;
1663              const char *key;
1664
1665              it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
1666              EINA_LIST_FOREACH(it->labels, l, key)
1667                {
1668                   char *s = it->itc->func.label_get
1669                      ((void *)it->data, it->wd->obj, l->data);
1670
1671                   if (s)
1672                     {
1673                        edje_object_part_text_set(it->base, l->data, s);
1674                        free(s);
1675                     }
1676                   /*                  else if (itc)
1677                                       edje_object_part_text_set(it->base, l->data, "");*/
1678                }
1679           }
1680         if (it->itc->func.icon_get)
1681           {
1682              const Eina_List *l;
1683              const char *key;
1684
1685              it->icons = _elm_stringlist_get(edje_object_data_get(it->base, "icons"));
1686              EINA_LIST_FOREACH(it->icons, l, key)
1687                {
1688                   Evas_Object *ic = it->itc->func.icon_get
1689                      ((void *)it->data, it->wd->obj, l->data);
1690
1691                   if (ic)
1692                     {
1693                        it->icon_objs = eina_list_append(it->icon_objs, ic);
1694                        edje_object_part_swallow(it->base, key, ic);
1695                        evas_object_show(ic);
1696                        elm_widget_sub_object_add(it->wd->obj, ic);
1697                     }
1698                }
1699           }
1700         if (it->itc->func.state_get)
1701           {
1702              const Eina_List *l;
1703              const char *key;
1704
1705              it->states = _elm_stringlist_get(edje_object_data_get(it->base, "states"));
1706              EINA_LIST_FOREACH(it->states, l, key)
1707                {
1708                   Eina_Bool on = it->itc->func.state_get
1709                      (it->data, it->wd->obj, l->data);
1710
1711                   if (on)
1712                     {
1713                        snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1714                        edje_object_signal_emit(it->base, buf, "elm");
1715                     }
1716                   /*                  else if (itc)
1717                                       {
1718                                       snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1719                                       edje_object_signal_emit(it->base, buf, "elm");
1720                                       }*/
1721                }
1722           }
1723         if (!it->mincalcd)
1724           {
1725              Evas_Coord mw = -1, mh = -1;
1726
1727              if (!it->display_only)
1728                 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1729              edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
1730              if (!it->display_only)
1731                 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1732              it->w = it->minw = mw;
1733              it->h = it->minh = mh;
1734              it->mincalcd = EINA_TRUE;
1735
1736              if ((!in) && (it->wd->homogeneous))
1737                {
1738                   it->wd->item_width = mw;
1739                   it->wd->item_height = mh;
1740                }
1741           }
1742         if (!calc) evas_object_show(it->base);
1743      }
1744
1745    it->realized = EINA_TRUE;
1746    it->want_unrealize = EINA_FALSE;
1747    if (it->group_item)
1748       _groupitem_realize(it, calc);
1749    if (ELM_GENLIST_EDIT_MODE_NONE != it->wd->edit_mode) 
1750      {
1751         Evas_Object *icon;
1752         EINA_LIST_FREE(it->edit_icon_objs, icon)
1753            evas_object_del(icon);
1754         _edit_controls_eval(it);
1755      }
1756 }
1757
1758 static void
1759 _item_unrealize(Elm_Genlist_Item *it)
1760 {
1761    Evas_Object *icon;
1762
1763    if (!it->realized) return;
1764    it->menuopened = EINA_FALSE;
1765    it->wd->menuopened = eina_list_remove(it->wd->menuopened, it);
1766    if (it->long_timer)
1767      {
1768         ecore_timer_del(it->long_timer);
1769         it->long_timer = NULL;
1770      }
1771    evas_object_del(it->base);
1772    it->base = NULL;
1773    evas_object_del(it->spacer);
1774    it->spacer = NULL;
1775    if (it->edit_obj)
1776       evas_object_del(it->edit_obj);
1777    it->edit_obj = NULL;
1778    _elm_stringlist_free(it->labels);
1779    it->labels = NULL;
1780    _elm_stringlist_free(it->icons);
1781    it->icons = NULL;
1782    _elm_stringlist_free(it->states);
1783
1784    EINA_LIST_FREE(it->icon_objs, icon) 
1785       evas_object_del(icon);
1786
1787    EINA_LIST_FREE(it->edit_icon_objs, icon)
1788       evas_object_del(icon);
1789
1790    it->states = NULL;
1791    it->realized = EINA_FALSE;
1792    it->want_unrealize = EINA_FALSE;
1793 }
1794
1795 static int
1796 _item_block_recalc(Item_Block *itb, int in, int qadd, int norender)
1797 {
1798    const Eina_List *l;
1799    Elm_Genlist_Item *it;
1800    Evas_Coord minw = 0, minh = 0;
1801    int showme = 0, changed = 0;
1802    Evas_Coord y = 0;
1803    Elm_Genlist_GroupItem *git = NULL;
1804
1805    itb->num = in;
1806    EINA_LIST_FOREACH(itb->items, l, it)
1807      {
1808         if (it->delete_me) continue;
1809         showme |= it->showme;
1810         if (!itb->realized)
1811           {
1812              if (qadd)
1813                {
1814                   if (!it->mincalcd) changed = 1;
1815                   if (changed)
1816                     {
1817                        _item_realize(it, in, 1);
1818                        _item_unrealize(it);
1819                     }
1820                }
1821              else
1822                {
1823                   _item_realize(it, in, 1);
1824                   _item_unrealize(it);
1825                }
1826           }
1827         else
1828           {
1829              Eina_Bool was_realized = it->realized;
1830
1831              _item_realize(it, in, 0);
1832              if (!was_realized)
1833                 evas_object_smart_callback_call(it->wd->obj, "realized", it);
1834           }
1835         minh += it->minh;
1836         if (minw < it->minw) minw = it->minw;
1837         in++;
1838         it->x = 0;
1839         it->y = y;
1840         y += it->h;
1841         if (git != it->group_item)
1842           {
1843              git = it->group_item;
1844
1845              if (git && git->align == GROUP_ALIGN_NORTH && git->items->data == it) //Add Place holder for Group title
1846                {
1847                   minh += git->minh;
1848                   it->y += git->minh;
1849                   y += git->minh;
1850                }
1851           }
1852      }
1853    itb->minw = minw;
1854    itb->minh = minh;
1855    itb->changed = EINA_FALSE;
1856    /* force an evas norender to garbage collect deleted objects */
1857    if (norender) evas_norender(evas_object_evas_get(itb->wd->obj));
1858    return showme;
1859 }
1860
1861 static void
1862 _item_block_realize(Item_Block *itb, int in, int full)
1863 {
1864    const Eina_List *l;
1865    Elm_Genlist_Item *it;
1866
1867    if (itb->realized) return;
1868    EINA_LIST_FOREACH(itb->items, l, it)
1869      {
1870         if (it->delete_me) continue;
1871         if (full)
1872           {
1873              Eina_Bool was_realized = it->realized;
1874
1875              _item_realize(it, in, 0);
1876              if (!was_realized)
1877                 evas_object_smart_callback_call(it->wd->obj, "realized", it);
1878           }
1879         in++;
1880      }
1881    itb->realized = EINA_TRUE;
1882    itb->want_unrealize = EINA_FALSE;
1883 }
1884
1885 static void
1886 _item_block_unrealize(Item_Block *itb)
1887 {
1888    const Eina_List *l;
1889    Elm_Genlist_Item *it;
1890    int dragging = 0;
1891
1892    if (!itb->realized) return;
1893    EINA_LIST_FOREACH(itb->items, l, it)
1894      {
1895         if (it->dragging || it->reordering)
1896           {
1897              dragging = 1;
1898              it->want_unrealize = EINA_TRUE;
1899           }
1900         else
1901            _item_unrealize(it);
1902      }
1903    if (!dragging)
1904      {
1905         itb->realized = EINA_FALSE;
1906         itb->want_unrealize = EINA_TRUE;
1907      }
1908    else
1909       itb->want_unrealize = EINA_FALSE;
1910 }
1911
1912 static void
1913 _item_block_position(Item_Block *itb, int in)
1914 {
1915    const Eina_List *l;
1916    Elm_Genlist_Item *it;
1917    Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1918    int vis=0;
1919    int is_reorder = 0;
1920    Elm_Genlist_GroupItem *git = NULL;
1921    Elm_Genlist_Item *select_all_item = NULL;
1922
1923    evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
1924    evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy, &cvw, &cvh);
1925
1926    if (itb->wd->select_all_item && 
1927        (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)) 
1928      {
1929
1930         select_all_item = itb->wd->select_all_item;
1931
1932         evas_object_resize(select_all_item->base, itb->w, select_all_item->h);  
1933         evas_object_move(select_all_item->base, ox, oy);
1934         evas_object_raise(select_all_item->base);
1935
1936         if (itb->wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE)         
1937            evas_object_show(select_all_item->base);
1938         else
1939            evas_object_hide(select_all_item->base);
1940         y = select_all_item->h;
1941      }
1942
1943    EINA_LIST_FOREACH(itb->items, l, it)
1944      {
1945         if (it->delete_me) continue;
1946         it->x = 0;
1947         it->y = y;
1948         it->w = itb->w;
1949         vis = (ELM_RECTS_INTERSECT(itb->x - it->wd->pan_x + ox,
1950                                    itb->y - it->wd->pan_y + oy,
1951                                    itb->w, itb->h,
1952                                    cvx, cvy, cvw, cvh));
1953         if ((itb->realized) && (!it->realized))
1954           {
1955              if (vis)
1956                {
1957                   Eina_Bool was_realized = it->realized;
1958
1959                   _item_realize(it, in, 0);
1960                   if (!was_realized)
1961                      evas_object_smart_callback_call(it->wd->obj,
1962                                                      "realized", it);
1963                }
1964           }
1965         if (it->realized)
1966           {
1967              _notify_item_position(it);
1968              if (vis)
1969                {
1970                   it->scrl_x = ox + itb->x + it->x - itb->wd->pan_x;
1971                   it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y;;
1972                   if (git != it->group_item)
1973                     {
1974                        git = it->group_item;
1975                        if (git)
1976                          {
1977                             git->visible = EINA_TRUE; //Mark Group Item to make it visible
1978                             if (git->items->data == it)
1979                                git->y = it->scrl_y;
1980                             if (GROUP_ALIGN_NORTH == git->align)
1981                               {
1982                                  git->w = itb->w;
1983                                  if (git->items->data == it)
1984                                    {
1985                                       it->scrl_y += git->minh;
1986                                       y += git->minh;
1987                                    }
1988                               }
1989                          }
1990                     }
1991                   if (git)
1992                     {
1993                        git->x = ox + itb->x - itb->wd->pan_x;
1994
1995                        if (git->y < oy)
1996                           git->y = oy;
1997
1998                        if (git->align == GROUP_ALIGN_WEST)
1999                          {
2000                             it->w -= git->w;
2001                             it->scrl_x += git->x + git->w;
2002                             git->h = (it->scrl_y + it->h)  -  git->y ;
2003                             if (git->h < it->h)
2004                               {
2005                                  git->y = it->scrl_y;
2006                                  git->h = it->h;
2007                               }
2008                          }
2009                        if (git->align == GROUP_ALIGN_NORTH)
2010                          {
2011                             git->h = git->minh;
2012                             if ((git->y + git->h) > (it->scrl_y + it->h))
2013                                git->y = (it->scrl_y + it->h) - git->minh;
2014                          }
2015                        if (git->update_finish_y) 
2016                          {
2017                             git->finish_y += oy;
2018                             git->update_finish_y = EINA_FALSE;
2019                          }
2020
2021                     }
2022
2023                   is_reorder = _get_space_for_reorder_item(it);
2024
2025                   if (it->wd->ed)
2026                     {
2027                        if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && !itb->reoder_y) 
2028                          {
2029                             itb->reoder_y -= it->h;
2030                             it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y;
2031                          }
2032                        else if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && itb->reoder_y) 
2033                          {
2034                             itb->reoder_y = 0;
2035                          }
2036                     }
2037                   y += is_reorder;
2038
2039                   if (!it->reordering)
2040                     {
2041                        if ((!it->wd->effect_mode || 
2042                             (it->wd->effect_mode && it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_NONE)) && !it->wd->pinch_zoom_reserve)
2043                          {
2044                             _move_edit_controls(it,it->scrl_x, it->scrl_y);
2045                             evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h);
2046
2047                             evas_object_move(it->base, it->scrl_x+it->pad_left, it->scrl_y);
2048
2049                             if (it->delete_check)
2050                               {
2051                                  edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm");
2052                                  edje_object_signal_emit(it->base, "elm,state,del_confirm", "elm");
2053                               }
2054                             evas_object_show(it->base);
2055                             it->old_pad_left = it->pad_left;
2056                             it->old_scrl_y = it->scrl_y;
2057                          }
2058
2059                     }
2060                }
2061              else
2062                {
2063                   if (!it->dragging)
2064                      _item_unrealize(it);
2065                }
2066           }
2067         if (!it->reordering)
2068            y += it->h;
2069
2070         in++;
2071      }
2072
2073    if (itb->wd->select_all_item && 
2074        (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)) 
2075       evas_object_raise(select_all_item->base);
2076
2077    if (vis)
2078      {
2079         itb->wd->animate_edit_controls = 0;
2080         if (git)
2081            git->visible = EINA_TRUE;
2082      }
2083 }
2084
2085 static void
2086 _calc_job(void *data)
2087 {
2088    Widget_Data *wd = data;
2089    Item_Block *itb;
2090    Evas_Coord minw = -1, minh = 0, y = 0, ow;
2091    Item_Block *chb = NULL;
2092    int in = 0, minw_change = 0;
2093    Evas_Coord oh;
2094
2095    if (!wd) return;
2096    EINA_INLIST_FOREACH(wd->blocks, itb)
2097      {
2098         int showme = 0;
2099
2100         itb->num = in;
2101         showme = itb->showme;
2102         itb->showme = 0;
2103         if (chb)
2104           {
2105              if (itb->realized) _item_block_unrealize(itb);
2106           }
2107         if (itb->changed)
2108           {
2109              if (itb->realized) _item_block_unrealize(itb);
2110              showme = _item_block_recalc(itb, in, 0, 1);
2111              chb = itb;
2112           }
2113         itb->y = y;
2114         itb->x = 0;
2115         minh += itb->minh;
2116         if (minw == -1) minw = itb->minw;
2117         else if (minw < itb->minw)
2118           {
2119              minw = itb->minw;
2120              minw_change = 1;
2121           }
2122         itb->w = minw;
2123         itb->h = itb->minh;
2124         y += itb->h;
2125         in += itb->count;
2126         if ((showme) && (wd->show_item) && (wd->show_item->mincalcd))
2127           {
2128              wd->show_item->showme = 0;
2129              if (wd->bring_in)
2130                 elm_smart_scroller_region_bring_in(wd->scr,
2131                                                    wd->show_item->x + wd->show_item->block->x,
2132                                                    wd->show_item->y + wd->show_item->block->y,
2133                                                    wd->show_item->block->w,
2134                                                    wd->show_item->h);
2135              else
2136                 elm_smart_scroller_child_region_show(wd->scr,
2137                                                      wd->show_item->x + wd->show_item->block->x,
2138                                                      wd->show_item->y + wd->show_item->block->y,
2139                                                      wd->show_item->block->w,
2140                                                      wd->show_item->h);
2141              wd->show_item = NULL;
2142           }
2143      }
2144    if (minw_change)
2145      {
2146         EINA_INLIST_FOREACH(wd->blocks, itb)
2147           {
2148              itb->minw = minw;
2149              itb->w = itb->minw;
2150           }
2151      }
2152    if ((chb) && (EINA_INLIST_GET(chb)->next))
2153      {
2154         EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2155           {
2156              if (itb->realized) _item_block_unrealize(itb);
2157           }
2158      }
2159    evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2160    if (minw < ow) minw = ow;
2161    if ((minw != wd->minw) || (minh != wd->minh) || wd->select_all_item)
2162      {
2163         wd->minw = minw;
2164         wd->minh = minh;
2165         if (wd->select_all_item)
2166            wd->minh += wd->select_all_item->h;
2167         evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2168         _sizing_eval(wd->obj);
2169      }
2170    wd->calc_job = NULL;
2171    evas_object_smart_changed(wd->pan_smart);
2172 }
2173
2174 static void
2175 _update_job(void *data)
2176 {
2177    Widget_Data *wd = data;
2178    Eina_List *l2;
2179    Item_Block *itb;
2180    int num, num0, position = 0, recalc = 0;
2181    if (!wd) return;
2182    wd->update_job = NULL;
2183    num = 0;
2184    EINA_INLIST_FOREACH(wd->blocks, itb)
2185      {
2186         Evas_Coord itminw, itminh;
2187         Elm_Genlist_Item *it;
2188
2189         if (!itb->updateme)
2190           {
2191              num += itb->count;
2192              if (position)
2193                 _item_block_position(itb, num);
2194              continue;
2195           }
2196         num0 = num;
2197         recalc = 0;
2198         EINA_LIST_FOREACH(itb->items, l2, it)
2199           {
2200              if (it->updateme)
2201                {
2202                   itminw = it->w;
2203                   itminh = it->h;
2204
2205                   it->updateme = 0;
2206                   if (it->realized)
2207                     {
2208                        _item_unrealize(it);
2209                        _item_realize(it, num, 0);
2210                        evas_object_smart_callback_call(it->wd->obj,
2211                                                        "realized", it);
2212                     }
2213                   else
2214                     {
2215                        _item_realize(it, num, 1);
2216                        _item_unrealize(it);
2217                     }
2218                   if ((it->minw != itminw) || (it->minh != itminh))
2219                      recalc = 1;
2220                }
2221              num++;
2222           }
2223         itb->updateme = 0;
2224         if (recalc)
2225           {
2226              position = 1;
2227              itb->changed = EINA_TRUE;
2228              _item_block_recalc(itb, num0, 0, 1);
2229              _item_block_position(itb, num0);
2230           }
2231      }
2232    if (position)
2233      {
2234         if (wd->calc_job) ecore_job_del(wd->calc_job);
2235         wd->calc_job = ecore_job_add(_calc_job, wd);
2236      }
2237 }
2238
2239 static void
2240 _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
2241 {
2242    Pan *sd = evas_object_smart_data_get(obj);
2243 //   Evas_Coord ow, oh;
2244 //   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2245 //   ow = sd->wd->minw - ow;
2246 //   if (ow < 0) ow = 0;
2247 //   oh = sd->wd->minh - oh;
2248 //   if (oh < 0) oh = 0;
2249 //   if (x < 0) x = 0;
2250 //   if (y < 0) y = 0;
2251 //   if (x > ow) x = ow;
2252 //   if (y > oh) y = oh;
2253    if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2254
2255    if(sd->wd->reoder_moved)
2256      {
2257         sd->wd->pan_x = x;
2258         if(sd->wd->pan_y >= sd->wd->minh) 
2259           sd->wd->pan_y = sd->wd->minh;
2260         else 
2261           {
2262              if(sd->wd->pan_y < y )
2263                 sd->wd->pan_y = y + 5 + abs(sd->wd->reoder_pan_y - sd->wd->pan_y) / 100;
2264              else
2265                 sd->wd->pan_y = y - 5 - abs(sd->wd->reoder_pan_y - sd->wd->pan_y) / 100;
2266           }
2267      }
2268    else 
2269     {
2270        sd->wd->pan_x = x;
2271        sd->wd->pan_y = y;
2272     }
2273    evas_object_smart_changed(obj);
2274 }
2275
2276 static void
2277 _pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
2278 {
2279    Pan *sd = evas_object_smart_data_get(obj);
2280
2281    if (x) *x = sd->wd->pan_x;
2282    if (y) *y = sd->wd->pan_y;
2283
2284    if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH) 
2285      {
2286         int git_cnt = 0, git_h = 0;
2287         Elm_Genlist_GroupItem *git;
2288
2289         EINA_INLIST_FOREACH(sd->wd->group_items, git)
2290           {
2291              git_cnt++;
2292              git_h = git->h;
2293           }
2294
2295         if (sd->wd->minh != (git_h+1) * git_cnt) 
2296           {
2297              sd->wd->minh = (git_h+1) * git_cnt;
2298           }
2299      }
2300
2301 }
2302
2303 static void
2304 _pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
2305 {
2306    Pan *sd = evas_object_smart_data_get(obj);
2307    Evas_Coord ow, oh;
2308
2309    evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2310    ow = sd->wd->minw - ow;
2311    if (ow < 0) ow = 0;
2312    oh = sd->wd->minh - oh;
2313    if (oh < 0) oh = 0;
2314    if (x) *x = ow;
2315    if (y) *y = oh;
2316 }
2317
2318 static void
2319 _pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
2320 {
2321    Pan *sd = evas_object_smart_data_get(obj);
2322
2323    if (w) *w = sd->wd->minw;
2324    if (h) *h = sd->wd->minh;
2325 }
2326
2327 static void
2328 _pan_add(Evas_Object *obj)
2329 {
2330    Pan *sd;
2331    Evas_Object_Smart_Clipped_Data *cd;
2332
2333    _pan_sc.add(obj);
2334    cd = evas_object_smart_data_get(obj);
2335    sd = ELM_NEW(Pan);
2336    if (!sd) return;
2337    sd->__clipped_data = *cd;
2338    free(cd);
2339    evas_object_smart_data_set(obj, sd);
2340 }
2341
2342 static void
2343 _pan_del(Evas_Object *obj)
2344 {
2345    Pan *sd = evas_object_smart_data_get(obj);
2346
2347    if (!sd) return;
2348    _pan_sc.del(obj);
2349 }
2350
2351 static void
2352 _pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
2353 {
2354    Pan *sd = evas_object_smart_data_get(obj);
2355    Evas_Coord ow, oh;
2356
2357    evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2358    if ((ow == w) && (oh == h)) return;
2359 /* don't do this... use wd->compress mode
2360    if (sd->wd->mode == ELM_LIST_COMPRESS)
2361      {
2362         Item_Block *itb;
2363         // this is nasty - but no choice. have to mark all as not mincalced.
2364         EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2365           {
2366              Eina_List *l;
2367              Elm_Genlist_Item *it;
2368
2369              EINA_LIST_FOREACH(itb->items, l, it)
2370              it->mincalcd = EINA_FALSE;
2371
2372              itb->changed = EINA_TRUE;
2373           }
2374      }
2375  */
2376    if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2377    sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2378 }
2379
2380 static void
2381 _pan_calculate(Evas_Object *obj)
2382 {
2383    Pan *sd = evas_object_smart_data_get(obj);
2384    Item_Block *itb;
2385    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2386    int in = 0;
2387    Elm_Genlist_GroupItem *git;
2388
2389    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2390    if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND) return;
2391
2392
2393    if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
2394      {
2395         sd->wd->group_items_moved = EINA_TRUE;
2396         sd->wd->contract_pan_y = sd->wd->pan_y;      
2397         EINA_INLIST_FOREACH(sd->wd->group_items, git)
2398           {
2399              git->visible = EINA_TRUE;
2400              evas_object_raise(git->base);
2401              evas_object_resize(git->base, sd->wd->minw, git->h);
2402              evas_object_move(git->base, git->x, git->y + sd->wd->pan_y * -1);
2403              evas_object_show(git->base);
2404           }
2405      }
2406
2407    if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return;
2408
2409    if (sd->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)
2410       (void)_edit_mode_reset(sd->wd);
2411    EINA_INLIST_FOREACH(sd->wd->group_items, git)
2412      {
2413         git->visible = EINA_FALSE;
2414      }
2415
2416    evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2417    EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2418      {
2419         itb->w = sd->wd->minw;
2420         if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2421                                 itb->y - sd->wd->pan_y + oy,
2422                                 itb->w, itb->h,
2423                                 cvx, cvy, cvw, cvh))
2424           {
2425              if ((!itb->realized) || (itb->changed))
2426                 _item_block_realize(itb, in, 0);
2427              _item_block_position(itb,  in);
2428           }
2429         else
2430           {
2431              if (itb->realized) _item_block_unrealize(itb);
2432           }
2433         in += itb->count;
2434      }
2435
2436    if (sd->wd->effect_mode && 
2437        (sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND || sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT))
2438      {
2439         _item_flip_effect_show(sd->wd);
2440         sd->wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, sd->wd);
2441      }
2442
2443    if (sd->wd->effect_mode && sd->wd->edit_mode_effect_mode) 
2444       sd->wd->item_moving_effect_timer = ecore_animator_add(_edit_mode_item_moving_effect_cb, sd->wd);
2445
2446    EINA_INLIST_FOREACH(sd->wd->group_items, git)
2447      {
2448         if (git->visible)
2449           {
2450              evas_object_raise(git->base);
2451              evas_object_resize(git->base, git->w, git->h - 1);
2452              evas_object_move(git->base, git->x, git->y);
2453              if (!sd->wd->pinch_zoom_reserve)
2454                 evas_object_show(git->base);
2455              else 
2456                 evas_object_hide(git->base);
2457           }
2458         else
2459            evas_object_hide(git->base);
2460      }
2461    if ((sd->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER) && (sd->wd->ed->reorder_item))
2462      {
2463         evas_object_raise(sd->wd->ed->reorder_item->base);
2464         evas_object_raise(sd->wd->ed->reorder_item->edit_obj);
2465      }
2466    if (sd->wd->select_all_item) 
2467       evas_object_raise(sd->wd->select_all_item->base);
2468 }
2469
2470 static void
2471 _pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
2472 {
2473    Pan *sd = evas_object_smart_data_get(obj);
2474
2475    if (sd->wd->effect_mode && sd->wd->multi_down) return;
2476    if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return;
2477
2478    if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2479    sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2480 }
2481
2482 static void
2483 _hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2484 {
2485    Widget_Data *wd = elm_widget_data_get(obj);
2486    if (!wd) return;
2487    elm_smart_scroller_hold_set(wd->scr, 1);
2488 }
2489
2490 static void
2491 _hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2492 {
2493    Widget_Data *wd = elm_widget_data_get(obj);
2494    if (!wd) return;
2495    elm_smart_scroller_hold_set(wd->scr, 0);
2496 }
2497
2498 static void
2499 _freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2500 {
2501    Widget_Data *wd = elm_widget_data_get(obj);
2502    if (!wd) return;
2503    elm_smart_scroller_freeze_set(wd->scr, 1);
2504 }
2505
2506 static void
2507 _freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2508 {
2509    Widget_Data *wd = elm_widget_data_get(obj);
2510    if (!wd) return;
2511    elm_smart_scroller_freeze_set(wd->scr, 0);
2512 }
2513
2514 static void
2515 _scroll_edge_left(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2516 {
2517    Evas_Object *obj = data;
2518    evas_object_smart_callback_call(obj, "scroll,edge,left", NULL);
2519 }
2520
2521 static void
2522 _scroll_edge_right(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2523 {
2524    Evas_Object *obj = data;
2525    evas_object_smart_callback_call(obj, "scroll,edge,right", NULL);
2526 }
2527
2528 static void
2529 _scroll_edge_top(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2530 {
2531    Evas_Object *obj = data;
2532    evas_object_smart_callback_call(obj, "scroll,edge,top", NULL);
2533 }
2534
2535 static void
2536 _scroll_edge_bottom(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2537 {
2538    Evas_Object *obj = data;
2539    evas_object_smart_callback_call(obj, "scroll,edge,bottom", NULL);
2540 }
2541
2542 /**
2543  * Add a new Genlist object
2544  *
2545  * @param parent The parent object
2546  * @return The new object or NULL if it cannot be created
2547  *
2548  * @ingroup Genlist
2549  */
2550 EAPI Evas_Object *
2551 elm_genlist_add(Evas_Object *parent)
2552 {
2553    Evas_Object *obj;
2554    Evas *e;
2555    Widget_Data *wd;
2556    Evas_Coord minw, minh;
2557    static Evas_Smart *smart = NULL;
2558
2559    if (!parent) return NULL;
2560    if (!smart)
2561      {
2562         static Evas_Smart_Class sc;
2563
2564         evas_object_smart_clipped_smart_set(&_pan_sc);
2565         sc = _pan_sc;
2566         sc.name = "elm_genlist_pan";
2567         sc.version = EVAS_SMART_CLASS_VERSION;
2568         sc.add = _pan_add;
2569         sc.del = _pan_del;
2570         sc.resize = _pan_resize;
2571         sc.move = _pan_move;
2572         sc.calculate = _pan_calculate;
2573         if (!(smart = evas_smart_class_new(&sc))) return NULL;
2574      }
2575    wd = ELM_NEW(Widget_Data);
2576    e = evas_object_evas_get(parent);
2577    obj = elm_widget_add(e);
2578    ELM_SET_WIDTYPE(widtype, "genlist");
2579    elm_widget_type_set(obj, "genlist");
2580    elm_widget_sub_object_add(parent, obj);
2581    elm_widget_data_set(obj, wd);
2582    elm_widget_del_hook_set(obj, _del_hook);
2583    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
2584    elm_widget_theme_hook_set(obj, _theme_hook);
2585    elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
2586
2587    wd->scr = elm_smart_scroller_add(e);
2588    elm_smart_scroller_widget_set(wd->scr, obj);
2589    elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
2590    elm_widget_resize_object_set(obj, wd->scr);
2591
2592         elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
2593
2594    evas_object_smart_callback_add(wd->scr, "edge,left", _scroll_edge_left, obj);
2595    evas_object_smart_callback_add(wd->scr, "edge,right", _scroll_edge_right, obj);
2596    evas_object_smart_callback_add(wd->scr, "edge,top", _scroll_edge_top, obj);
2597    evas_object_smart_callback_add(wd->scr, "edge,bottom", _scroll_edge_bottom, obj);
2598
2599    wd->obj = obj;
2600    wd->mode = ELM_LIST_SCROLL;
2601    wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
2602    wd->max_items_per_block = 32;
2603    wd->longpress_timeout = _elm_config->longpress_timeout;
2604         wd->max_git_num = 0;
2605
2606    evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
2607    evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
2608    evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
2609    evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
2610
2611    wd->pan_smart = evas_object_smart_add(e, smart);
2612    wd->pan = evas_object_smart_data_get(wd->pan_smart);
2613    wd->pan->wd = wd;
2614
2615    elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
2616                                      _pan_set, _pan_get,
2617                                      _pan_max_get, _pan_child_size_get);
2618
2619    edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
2620                              &minw, &minh);
2621    evas_object_size_hint_min_set(obj, minw, minh);
2622
2623    _sizing_eval(obj);
2624    return obj;
2625 }
2626
2627 static Elm_Genlist_Item *
2628 _item_new(Widget_Data *wd, const Elm_Genlist_Item_Class *itc,
2629           const void *data, Elm_Genlist_Item *parent,
2630           Elm_Genlist_Item_Flags flags,
2631           Evas_Smart_Cb func,
2632           const void *func_data)
2633 {
2634    Elm_Genlist_Item *it;
2635
2636    it = calloc(1, sizeof(Elm_Genlist_Item));
2637    if (!it) return NULL;
2638    it->wd = wd;
2639    it->itc = itc;
2640    it->data = data;
2641    it->parent = parent;
2642    it->flags = flags;
2643    it->func.func = func;
2644    it->func.data = func_data;
2645    it->expanded_depth = 0;
2646    return it;
2647 }
2648
2649 static void
2650 _item_block_add(Widget_Data *wd, Elm_Genlist_Item *it)
2651 {
2652    Item_Block *itb = NULL;
2653
2654    if (!it->rel)
2655      {
2656 newblock:
2657         if (it->rel)
2658           {
2659              itb = calloc(1, sizeof(Item_Block));
2660              if (!itb) return;
2661              itb->wd = wd;
2662              if (!it->rel->block)
2663                {
2664                   it->rel->block = itb;
2665                   wd->blocks = 
2666                      eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
2667                   itb->items = eina_list_append(itb->items, it);
2668                }
2669              else
2670                {
2671                   if (it->before)
2672                     {
2673                        wd->blocks = 
2674                           eina_inlist_prepend_relative(wd->blocks, 
2675                                                        EINA_INLIST_GET(itb), 
2676                                                        EINA_INLIST_GET(it->rel->block));
2677                        itb->items = 
2678                           eina_list_prepend_relative(itb->items, it, it->rel);
2679                     }
2680                   else
2681                     {
2682                        wd->blocks = 
2683                           eina_inlist_append_relative(wd->blocks, 
2684                                                       EINA_INLIST_GET(itb), 
2685                                                       EINA_INLIST_GET(it->rel->block));
2686                        itb->items = 
2687                           eina_list_append_relative(itb->items, it, it->rel);
2688                     }
2689                }
2690           }
2691         else
2692           {
2693              if (it->before)
2694                {
2695                   if (wd->blocks)
2696                     {
2697                        itb = (Item_Block *)(wd->blocks);
2698                        if (itb->count >= wd->max_items_per_block)
2699                          {
2700                             itb = calloc(1, sizeof(Item_Block));
2701                             if (!itb) return;
2702                             itb->wd = wd;
2703                             wd->blocks = 
2704                               eina_inlist_prepend(wd->blocks, 
2705                                                   EINA_INLIST_GET(itb));
2706                          }
2707                     }
2708                   else
2709                     {
2710                        itb = calloc(1, sizeof(Item_Block));
2711                        if (!itb) return;
2712                        itb->wd = wd;
2713                        wd->blocks = 
2714                           eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
2715                     }
2716                   itb->items = eina_list_prepend(itb->items, it);
2717                }
2718              else
2719                {
2720                   if (wd->blocks)
2721                     {
2722                        itb = (Item_Block *)(wd->blocks->last);
2723                        if (itb->count >= wd->max_items_per_block)
2724                          {
2725                             itb = calloc(1, sizeof(Item_Block));
2726                             if (!itb) return;
2727                             itb->wd = wd;
2728                             wd->blocks = 
2729                                eina_inlist_append(wd->blocks, 
2730                                                   EINA_INLIST_GET(itb));
2731                          }
2732                     }
2733                   else
2734                     {
2735                        itb = calloc(1, sizeof(Item_Block));
2736                        if (!itb) return;
2737                        itb->wd = wd;
2738                        wd->blocks = 
2739                           eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
2740                     }
2741                   itb->items = eina_list_append(itb->items, it);
2742                }
2743           }
2744      }
2745    else
2746      {
2747         itb = it->rel->block;
2748         if (!itb) goto newblock;
2749         if (it->before)
2750            itb->items = eina_list_prepend_relative(itb->items, it, it->rel);
2751         else
2752            itb->items = eina_list_append_relative(itb->items, it, it->rel);
2753      }
2754    itb->count++;
2755    itb->changed = EINA_TRUE;
2756    it->block = itb;
2757
2758    if (!itb->wd)
2759         itb->wd = wd;
2760
2761    if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
2762    itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
2763    if (it->rel)
2764      {
2765         it->rel->relcount--;
2766         if ((it->rel->delete_me) && (!it->rel->relcount))
2767            _item_del(it->rel);
2768         it->rel = NULL;
2769      }
2770    if (itb->count > itb->wd->max_items_per_block)
2771      {
2772         int newc;
2773         Item_Block *itb2;
2774         Elm_Genlist_Item *it2;
2775
2776         newc = itb->count / 2;
2777         itb2 = calloc(1, sizeof(Item_Block));
2778         if (!itb2) return;
2779         itb2->wd = wd;
2780         wd->blocks = 
2781            eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2), 
2782                                        EINA_INLIST_GET(itb));
2783         itb2->changed = EINA_TRUE;
2784         while ((itb->count > newc) && (itb->items))
2785           {
2786              Eina_List *l;
2787
2788              l = eina_list_last(itb->items);
2789              it2 = l->data;
2790              itb->items = eina_list_remove_list(itb->items, l);
2791              itb->count--;
2792
2793              itb2->items = eina_list_prepend(itb2->items, it2);
2794              it2->block = itb2;
2795              itb2->count++;
2796           }
2797      }
2798 }
2799
2800 static int
2801 _queue_proecess(Widget_Data *wd, int norender)
2802 {
2803    int n, showme = 0;
2804    double t0, t;
2805
2806    t0 = ecore_time_get();
2807    for (n = 0; (wd->queue) && (n < 128); n++)
2808      {
2809         Elm_Genlist_Item *it;
2810
2811         it = wd->queue->data;
2812         wd->queue = eina_list_remove_list(wd->queue, wd->queue);
2813         it->queued = EINA_FALSE;
2814         _item_block_add(wd, it);
2815         t = ecore_time_get();
2816         if (it->block->changed)
2817           {
2818              showme = _item_block_recalc(it->block, it->block->num, 1, norender);
2819              it->block->changed = 0;
2820           }
2821         if (showme) it->block->showme = 1;
2822         if (eina_inlist_count(wd->blocks) > 1)
2823           {
2824              if ((t - t0) > (ecore_animator_frametime_get())) break;
2825           }
2826      }
2827    return n;
2828 }
2829
2830 static Eina_Bool
2831 _item_idler(void *data)
2832 {
2833    Widget_Data *wd = data;
2834
2835   //xxx
2836   //static double q_start = 0.0;
2837   //if (q_start == 0.0) q_start = ecore_time_get();
2838   //xxx
2839   
2840    if (_queue_proecess(wd, 1) > 0)
2841      {
2842         if (wd->calc_job) ecore_job_del(wd->calc_job);
2843         wd->calc_job = ecore_job_add(_calc_job, wd);
2844      }
2845    if (!wd->queue)
2846      {
2847        //xxx
2848        //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
2849        //xxx
2850         wd->queue_idler = NULL;
2851                   if (wd->pinch_zoom_reserve)
2852                          _elm_genlist_pinch_zoom_execute(wd->obj, 1);    
2853         return ECORE_CALLBACK_CANCEL;
2854      }
2855    return ECORE_CALLBACK_RENEW;
2856 }
2857
2858 static void
2859 _item_queue(Widget_Data *wd, Elm_Genlist_Item *it)
2860 {
2861         if (!wd->queue_exception)
2862   {
2863    if (it->queued) return;
2864    wd->queue = eina_list_append(wd->queue, it);
2865    it->queued = EINA_TRUE;
2866    wd->item_count++;
2867   }
2868    while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
2869      {
2870         if (wd->queue_idler)
2871           {
2872              ecore_idler_del(wd->queue_idler);
2873              wd->queue_idler = NULL;
2874           }
2875         _queue_proecess(wd, 0);
2876      }
2877    if (!wd->queue_idler) wd->queue_idler = ecore_idler_add(_item_idler, wd);
2878    if (wd->queue_exception)
2879      {
2880         wd->queue = eina_list_append(wd->queue, it);
2881         it->queued = EINA_TRUE;
2882      }
2883 }
2884
2885 /**
2886  * Append item to the end of the genlist
2887  *
2888  * This appends the given item to the end of the list or the end of the
2889  * children if the parent is given.
2890  *
2891  * @param obj The genlist object
2892  * @param itc The item class for the item
2893  * @param data The item data
2894  * @param parent The parent item, or NULL if none
2895  * @param flags Item flags
2896  * @param func Convenience function called when item selected
2897  * @param func_data Data passed to @p func above.
2898  * @return A handle to the item added or NULL if not possible
2899  *
2900  * @ingroup Genlist
2901  */
2902 EAPI Elm_Genlist_Item *
2903 elm_genlist_item_append(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
2904                         const void *data, Elm_Genlist_Item *parent,
2905                         Elm_Genlist_Item_Flags flags,
2906                         Evas_Smart_Cb func, const void *func_data)
2907 {
2908    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2909    Widget_Data *wd = elm_widget_data_get(obj);
2910    Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
2911    if (!wd) return NULL;
2912    if (!it) return NULL;
2913    if (!it->parent)
2914      {
2915         wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
2916         it->rel = NULL;
2917
2918      }
2919    else
2920      {
2921         Elm_Genlist_Item *it2 = NULL;
2922         Eina_List *ll = eina_list_last(it->parent->items);
2923         if (ll) it2 = ll->data;
2924         it->parent->items = eina_list_append(it->parent->items, it);
2925         if (!it2) it2 = it->parent;
2926         wd->items = 
2927            eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), 
2928                                        EINA_INLIST_GET(it2));
2929         it->rel = it2;
2930         it->rel->relcount++;
2931      }
2932    it->before = 0;
2933    _item_queue(wd, it);
2934    return it;
2935 }
2936
2937 /**
2938  * Prepend item at start of the genlist
2939  *
2940  * This adds an item to the beginning of the list or beginning of the children
2941  * of the parent if given.
2942  *
2943  * @param obj The genlist object
2944  * @param itc The item class for the item
2945  * @param data The item data
2946  * @param parent The parent item, or NULL if none
2947  * @param flags Item flags
2948  * @param func Convenience function called when item selected
2949  * @param func_data Data passed to @p func above.
2950  * @return A handle to the item added or NULL if not possible
2951  *
2952  * @ingroup Genlist
2953  */
2954 EAPI Elm_Genlist_Item *
2955 elm_genlist_item_prepend(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
2956                          const void *data, Elm_Genlist_Item *parent,
2957                          Elm_Genlist_Item_Flags flags,
2958                          Evas_Smart_Cb func, const void *func_data)
2959 {
2960    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2961    Widget_Data *wd = elm_widget_data_get(obj);
2962    Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
2963    if (!wd) return NULL;
2964    if (!it) return NULL;
2965    if (!it->parent)
2966       wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
2967    else
2968      {
2969         printf("FIXME: 12 tree not handled yet\n");
2970      }
2971    it->rel = NULL;
2972    it->before = 1;
2973    _item_queue(wd, it);
2974    return it;
2975 }
2976
2977 /**
2978  * Insert item before another in the genlist
2979  *
2980  * This inserts an item before another in the list. It will be in the same tree
2981  * level as the item it is inseted before.
2982  *
2983  * @param obj The genlist object
2984  * @param itc The item class for the item
2985  * @param data The item data
2986  * @param before The item to insert before
2987  * @param flags Item flags
2988  * @param func Convenience function called when item selected
2989  * @param func_data Data passed to @p func above.
2990  * @return A handle to the item added or NULL if not possible
2991  *
2992  * @ingroup Genlist
2993  */
2994 EAPI Elm_Genlist_Item *
2995 elm_genlist_item_insert_before(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
2996                                const void *data, Elm_Genlist_Item *before,
2997                                Elm_Genlist_Item_Flags flags,
2998                                Evas_Smart_Cb func, const void *func_data)
2999 {
3000    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3001    EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3002    Widget_Data *wd = elm_widget_data_get(obj);
3003    Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data);
3004    if (!wd) return NULL;
3005    if (!it) return NULL;
3006    if (!it->parent)
3007       wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), 
3008                                                EINA_INLIST_GET(before));
3009    else
3010      {
3011         printf("FIXME: 13 tree not handled yet\n");
3012      }
3013    it->rel = before;
3014    it->rel->relcount++;
3015    it->before = 1;
3016    _item_queue(wd, it);
3017    return it;
3018 }
3019
3020 /**
3021  * Insert and item after another in the genlst
3022  *
3023  * This inserts an item after another in the list. It will be in the same tree
3024  * level as the item it is inseted after.
3025  *
3026  * @param obj The genlist object
3027  * @param itc The item class for the item
3028  * @param data The item data
3029  * @param after The item to insert after
3030  * @param flags Item flags
3031  * @param func Convenience function called when item selected
3032  * @param func_data Data passed to @p func above.
3033  * @return A handle to the item added or NULL if not possible
3034  *
3035  * @ingroup Genlist
3036  */
3037 EAPI Elm_Genlist_Item *
3038 elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
3039                               const void *data, Elm_Genlist_Item *after,
3040                               Elm_Genlist_Item_Flags flags,
3041                               Evas_Smart_Cb func, const void *func_data)
3042 {
3043    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3044    EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3045    Widget_Data *wd = elm_widget_data_get(obj);
3046    Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data);
3047    if (!wd) return NULL;
3048    if (!it) return NULL;
3049    if (!it->parent)
3050      wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), 
3051                                              EINA_INLIST_GET(after));
3052    else
3053      {
3054         printf("FIXME: 14 tree not handled yet\n");
3055      }
3056    it->rel = after;
3057    it->rel->relcount++;
3058    it->before = 0;
3059    _item_queue(wd, it);
3060    return it;
3061 }
3062
3063 /**
3064  * Clear the genlist
3065  *
3066  * This clears all items in the list, leaving it empty.
3067  *
3068  * @param obj The genlist object
3069  *
3070  * @ingroup Genlist
3071  */
3072 EAPI void
3073 elm_genlist_clear(Evas_Object *obj)
3074 {
3075    ELM_CHECK_WIDTYPE(obj, widtype);
3076    Widget_Data *wd = elm_widget_data_get(obj);
3077    if (!wd) return;
3078
3079    wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
3080    wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE;
3081    elm_smart_scroller_hold_set(wd->scr, 0);
3082    elm_smart_scroller_freeze_set(wd->scr, 0);
3083    elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0);
3084    elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
3085    wd->max_git_num  = 0;
3086    wd->pinch_zoom_reserve = EINA_FALSE;
3087
3088    if (wd->item_moving_effect_timer)
3089      {
3090         //  ecore_timer_del(wd->item_moving_effect_timer);
3091         wd->item_moving_effect_timer = NULL;
3092      }
3093
3094    while (wd->group_items)
3095      {
3096         _groupitem_remove((Elm_Genlist_GroupItem *)wd->group_items, EINA_FALSE);
3097      }
3098
3099    if (wd->walking > 0)
3100      {
3101         Elm_Genlist_Item *it;
3102
3103         wd->clear_me = 1;
3104         EINA_INLIST_FOREACH(wd->items, it)
3105           {
3106              it->delete_me = 1;
3107           }
3108         return;
3109      }
3110    wd->clear_me = 0;
3111    while (wd->items)
3112      {
3113         Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items);
3114
3115         wd->items = eina_inlist_remove(wd->items, wd->items);
3116         if (it->realized) _item_unrealize(it);
3117         if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj);
3118         if (it->long_timer) ecore_timer_del(it->long_timer);
3119         free(it);
3120      }
3121    while (wd->blocks)
3122      {
3123         Item_Block *itb = (Item_Block *)(wd->blocks);
3124
3125         wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
3126         if (itb->items) eina_list_free(itb->items);
3127         free(itb);
3128      }
3129    if (wd->calc_job)
3130      {
3131         ecore_job_del(wd->calc_job);
3132         wd->calc_job = NULL;
3133      }
3134    if (wd->queue_idler)
3135      {
3136         ecore_idler_del(wd->queue_idler);
3137         wd->queue_idler = NULL;
3138      }
3139    if (wd->queue)
3140      {
3141         eina_list_free(wd->queue);
3142         wd->queue = NULL;
3143      }
3144    if (wd->selected)
3145      {
3146         eina_list_free(wd->selected);
3147         wd->selected = NULL;
3148      }
3149    wd->show_item = NULL;
3150    wd->pan_x = 0;
3151    wd->pan_y = 0;
3152    wd->minw = 0;
3153    wd->minh = 0;
3154
3155    if (wd->alpha_bg)
3156       evas_object_del(wd->alpha_bg);
3157    wd->alpha_bg = NULL;
3158
3159    if (wd->pan_smart)
3160      {
3161         evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3162         evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3163      }
3164    _sizing_eval(obj);
3165 }
3166
3167 /**
3168  * Enable or disable multi-select in the genlist
3169  *
3170  * This enables (EINA_TRUE) or disableds (EINA_FALSE) multi-select in the list. This allows
3171  * more than 1 item to be selected.
3172  *
3173  * @param obj The genlist object
3174  * @param multi Multi-select enable/disable
3175  *
3176  * @ingroup Genlist
3177  */
3178 EAPI void
3179 elm_genlist_multi_select_set(Evas_Object *obj, Eina_Bool multi)
3180 {
3181    ELM_CHECK_WIDTYPE(obj, widtype);
3182    Widget_Data *wd = elm_widget_data_get(obj);
3183    if (!wd) return;
3184    wd->multi = multi;
3185 }
3186
3187 /**
3188  * Gets if multi-select in genlist is enable or disable
3189  *
3190  * @param obj The genlist object
3191  * @return Multi-select enable/disable
3192  * (EINA_TRUE = enabled/EINA_FALSE = disabled)
3193  *
3194  * @ingroup Genlist
3195  */
3196 EAPI Eina_Bool
3197 elm_genlist_multi_select_get(const Evas_Object *obj)
3198 {
3199    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3200    Widget_Data *wd = elm_widget_data_get(obj);
3201    if (!wd) return EINA_FALSE;
3202    return wd->multi;
3203 }
3204
3205 /**
3206  * Get the selectd item in the genlist
3207  *
3208  * This gets the selected item in the list (if multi-select is enabled only
3209  * the first item in the list is selected - which is not very useful, so see
3210  * elm_genlist_selected_items_get()for when multi-select is used).
3211  *
3212  * If no item is selected, NULL is returned.
3213  *
3214  * @param obj The genlist object
3215  * @return The selected item, or NULL if none.
3216  *
3217  * @ingroup Genlist
3218  */
3219 EAPI Elm_Genlist_Item *
3220 elm_genlist_selected_item_get(const Evas_Object *obj)
3221 {
3222    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3223    Widget_Data *wd = elm_widget_data_get(obj);
3224    if (!wd) return NULL;
3225    if (wd->selected) return wd->selected->data;
3226    return NULL;
3227 }
3228
3229 /**
3230  * Get a list of selected items in the genlist
3231  *
3232  * This retgurns a list of the selected items. This list pointer is only valid
3233  * so long as no items are selected or unselected (or unselected implicitly
3234  * by deletion). The list contains Elm_Genlist_Item pointers.
3235  *
3236  * @param obj The genlist object
3237  * @return The list of selected items, nor NULL if none are selected.
3238  *
3239  * @ingroup Genlist
3240  */
3241 EAPI const Eina_List *
3242 elm_genlist_selected_items_get(const Evas_Object *obj)
3243 {
3244    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3245    Widget_Data *wd = elm_widget_data_get(obj);
3246    if (!wd) return NULL;
3247    return wd->selected;
3248 }
3249
3250 /**
3251  * Get a list of realized items in genlist
3252  *
3253  * This returns a list of the realized items in the genlist. The list
3254  * contains Elm_Genlist_Item pointers. The list must be freed by the
3255  * caller when done with eina_list_free(). The item pointers in the list
3256  * are only vallid so long as those items are not deleted or the genlist is
3257  * not deleted.
3258  *
3259  * @param obj The genlist object
3260  * @return The list of realized items, nor NULL if none are realized.
3261  *
3262  * @ingroup Genlist
3263  */
3264 EAPI Eina_List *
3265 elm_genlist_realized_items_get(const Evas_Object *obj)
3266 {
3267    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3268    Widget_Data *wd = elm_widget_data_get(obj);
3269    Eina_List *list = NULL;
3270    Item_Block *itb;
3271    Eina_Bool done = EINA_FALSE;
3272    if (!wd) return NULL;
3273    EINA_INLIST_FOREACH(wd->blocks, itb)
3274      {
3275         if (itb->realized)
3276           {
3277              Eina_List *l;
3278              Elm_Genlist_Item *it;
3279
3280              done = 1;
3281              EINA_LIST_FOREACH(itb->items, l, it)
3282                {
3283                   if (it->realized) list = eina_list_append(list, it);
3284                }
3285           }
3286         else
3287           {
3288              if (done) break;
3289           }
3290      }
3291    return list;
3292 }
3293
3294 /**
3295  * Get the item that is at the x, y canvas coords
3296  *
3297  * This returns the item at the given coordinates (which are canvas relative
3298  * not object-relative). If an item is at that coordinate, that item handle
3299  * is returned, and if @p posret is not NULL, the integer pointed to is set
3300  * to a value of -1, 0 or 1, depending if the coordinate is on the upper
3301  * portion of that item (-1), on the middle section (0) or on the lower part
3302  * (1). If NULL is returned as an item (no item found there), then posret
3303  * may indicate -1 or 1 based if the coordinate is above or below all items
3304  * respectively in the genlist.
3305  *
3306  * @param it The item
3307  * @param x The input x coordinate
3308  * @param y The input y coordinate
3309  * @param posret The position relative to the item returned here
3310  * @return The item at the coordinates or NULL if none
3311  *
3312  * @ingroup Genlist
3313  */
3314 EAPI Elm_Genlist_Item *
3315 elm_genlist_at_xy_item_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *posret)
3316 {
3317    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3318    Widget_Data *wd = elm_widget_data_get(obj);
3319    Evas_Coord ox, oy, ow, oh;
3320    Item_Block *itb;
3321    Evas_Coord lasty;
3322    if (!wd) return NULL;
3323    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
3324    lasty = oy;
3325    EINA_INLIST_FOREACH(wd->blocks, itb)
3326      {
3327         Eina_List *l;
3328         Elm_Genlist_Item *it;
3329
3330         if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
3331                                  oy + itb->y - itb->wd->pan_y,
3332                                  itb->w, itb->h, x, y, 1, 1))
3333            continue;
3334         EINA_LIST_FOREACH(itb->items, l, it)
3335           {
3336              Evas_Coord itx, ity;
3337
3338              itx = ox + itb->x + it->x - itb->wd->pan_x;
3339              ity = oy + itb->y + it->y - itb->wd->pan_y;
3340              if (ELM_RECTS_INTERSECT(itx, ity, it->w, it->h, x, y, 1, 1))
3341                {
3342                   if (posret)
3343                     {
3344                        if (y <= (ity + (it->h / 4))) *posret = -1;
3345                        else if (y >= (ity + it->h - (it->h / 4))) *posret = 1;
3346                        else *posret = 0;
3347                     }
3348                   return it;
3349                }
3350              lasty = ity + it->h;
3351           }
3352      }
3353    if (posret)
3354      {
3355         if (y > lasty) *posret = 1;
3356         else *posret = -1;
3357      }
3358    return NULL;
3359 }
3360
3361 /**
3362  * Get the first item in the genlist
3363  *
3364  * This returns the first item in the list.
3365  *
3366  * @param obj The genlist object
3367  * @return The first item, or NULL if none
3368  *
3369  * @ingroup Genlist
3370  */
3371 EAPI Elm_Genlist_Item *
3372 elm_genlist_first_item_get(const Evas_Object *obj)
3373 {
3374    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3375    Widget_Data *wd = elm_widget_data_get(obj);
3376    if (!wd) return NULL;
3377    if (!wd->items) return NULL;
3378    Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items);
3379    while ((it) && (it->delete_me))
3380      it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next);
3381    return it;
3382 }
3383
3384 /**
3385  * Get the last item in the genlist
3386  *
3387  * This returns the last item in the list.
3388  *
3389  * @return The last item, or NULL if none
3390  *
3391  * @ingroup Genlist
3392  */
3393 EAPI Elm_Genlist_Item *
3394 elm_genlist_last_item_get(const Evas_Object *obj)
3395 {
3396    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3397    Widget_Data *wd = elm_widget_data_get(obj);
3398    if (!wd->items) return NULL;
3399    Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items->last);
3400    if (!wd) return NULL;
3401    while ((it) && (it->delete_me))
3402      it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev);
3403    return it;
3404 }
3405
3406 /**
3407  * Get the next item in the genlist
3408  *
3409  * This returns the item after the item @p it.
3410  *
3411  * @param it The item
3412  * @return The item after @p it, or NULL if none
3413  *
3414  * @ingroup Genlist
3415  */
3416 EAPI Elm_Genlist_Item *
3417 elm_genlist_item_next_get(const Elm_Genlist_Item *it)
3418 {
3419    while (it)
3420      {
3421         it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next);
3422         if ((it) && (!it->delete_me)) break;
3423      }
3424    return (Elm_Genlist_Item *)it;
3425 }
3426
3427 /**
3428  * Get the previous item in the genlist
3429  *
3430  * This returns the item before the item @p it.
3431  *
3432  * @param it The item
3433  * @return The item before @p it, or NULL if none
3434  *
3435  * @ingroup Genlist
3436  */
3437 EAPI Elm_Genlist_Item *
3438 elm_genlist_item_prev_get(const Elm_Genlist_Item *it)
3439 {
3440    while (it)
3441      {
3442         it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev);
3443         if ((it) && (!it->delete_me)) break;
3444      }
3445    return (Elm_Genlist_Item *)it;
3446 }
3447
3448 /**
3449  * Get the genlist object from an item
3450  *
3451  * This returns the genlist object itself that an item belongs to.
3452  *
3453  * @param it The item
3454  * @return The genlist object
3455  *
3456  * @ingroup Genlist
3457  */
3458 EAPI Evas_Object *
3459 elm_genlist_item_genlist_get(const Elm_Genlist_Item *it)
3460 {
3461    if (!it) return NULL;
3462    return it->wd->obj;
3463 }
3464
3465 /**
3466  * Get the parent item of the given item
3467  *
3468  * This returns the prent item of the item @p it given.
3469  *
3470  * @param it The item
3471  * @return The parent of the item or NULL if none
3472  *
3473  * @ingroup Genlist
3474  */
3475 EAPI Elm_Genlist_Item *
3476 elm_genlist_item_parent_get(const Elm_Genlist_Item *it)
3477 {
3478    if (!it) return NULL;
3479    return it->parent;
3480 }
3481
3482 /**
3483  * Clear all sub-items (children) of the given item
3484  *
3485  * This clears all items that are children (or their descendants) of the
3486  * given item @p it.
3487  *
3488  * @param it The item
3489  *
3490  * @ingroup Genlist
3491  */
3492 EAPI void
3493 elm_genlist_item_subitems_clear(Elm_Genlist_Item *it)
3494 {
3495    if (!it) return;
3496    Eina_List *tl = NULL, *l;
3497    Elm_Genlist_Item *it2;
3498
3499    EINA_LIST_FOREACH(it->items, l, it2)
3500      tl = eina_list_append(tl, it2);
3501    EINA_LIST_FREE(tl, it2)
3502      elm_genlist_item_del(it2);
3503 }
3504
3505 /**
3506  * Set the selected state of an item
3507  *
3508  * This sets the selected state (1 selected, 0 not selected) of the given
3509  * item @p it.
3510  *
3511  * @param it The item
3512  * @param selected The slected state
3513  *
3514  * @ingroup Genlist
3515  */
3516 EAPI void
3517 elm_genlist_item_selected_set(Elm_Genlist_Item *it, Eina_Bool selected)
3518 {
3519    if (!it) return;
3520    ELM_CHECK_WIDTYPE(it->wd->obj, widtype);
3521    Widget_Data *wd = elm_widget_data_get(it->wd->obj);
3522    if (!wd) return;
3523    if (it->delete_me) return;
3524    selected = !!selected;
3525    if (it->selected == selected) return;
3526
3527    if (selected)
3528      {
3529         if (!wd->multi)
3530           {
3531              while (wd->selected)
3532                 _item_unselect(wd->selected->data);
3533           }
3534         _item_hilight(it);
3535         _item_select(it);
3536      }
3537    else
3538      _item_unselect(it);
3539 }
3540
3541 /**
3542  * Get the selected state of an item
3543  *
3544  * This gets the selected state of an item (1 selected, 0 not selected).
3545  *
3546  * @param it The item
3547  * @return The selected state
3548  *
3549  * @ingroup Genlist
3550  */
3551 EAPI Eina_Bool
3552 elm_genlist_item_selected_get(const Elm_Genlist_Item *it)
3553 {
3554    if (!it) return EINA_FALSE;
3555    return it->selected;
3556 }
3557
3558 /**
3559  * Sets the expanded state of an item (if it's a parent)
3560  *
3561  * This expands or contracts a parent iterm (thus showing or hiding the
3562  * children).
3563  *
3564  * @param it The item
3565  * @param expanded The expanded state (1 expanded, 0 not expanded).
3566  *
3567  * @ingroup Genlist
3568  */
3569 EAPI void
3570 elm_genlist_item_expanded_set(Elm_Genlist_Item *it, Eina_Bool expanded)
3571 {
3572    if (!it) return;
3573    if (it->expanded == expanded || it->disabled) return;
3574    it->expanded = expanded;
3575    it->wd->expand_item = it;   
3576         it->effect_done = EINA_FALSE;   
3577    if (it->expanded)
3578      {
3579         it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND;
3580         if (it->realized)
3581           edje_object_signal_emit(it->base, "elm,state,expanded", "elm");
3582         evas_object_smart_callback_call(it->wd->obj, "expanded", it);
3583
3584      }
3585    else
3586      {
3587         it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT;
3588         if (it->realized)
3589           edje_object_signal_emit(it->base, "elm,state,contracted", "elm");
3590         evas_object_smart_callback_call(it->wd->obj, "contracted", it);
3591      }
3592 }
3593
3594 /**
3595  * Get the expanded state of an item
3596  *
3597  * This gets the expanded state of an item
3598  *
3599  * @param it The item
3600  * @return Thre expanded state
3601  *
3602  * @ingroup Genlist
3603  */
3604 EAPI Eina_Bool
3605 elm_genlist_item_expanded_get(const Elm_Genlist_Item *it)
3606 {
3607    if (!it) return EINA_FALSE;
3608    return it->expanded;
3609 }
3610
3611 /**
3612  * Get the depth of expanded item
3613  *
3614  * @param it The genlist item object
3615  * @return The depth of expanded item
3616  *
3617  * @ingroup Genlist
3618  */
3619 EAPI int
3620 elm_genlist_item_expanded_depth_get(const Elm_Genlist_Item *it)
3621 {
3622    if (!it) return 0;
3623    return it->expanded_depth;
3624 }
3625
3626 /**
3627  * Sets the disabled state of an item.
3628  *
3629  * A disabled item cannot be selected or unselected. It will also change
3630  * appearance to appear disabled. This sets the disabled state (1 disabled, 0
3631  * not disabled).
3632  *
3633  * @param it The item
3634  * @param disabled The disabled state
3635  *
3636  * @ingroup Genlist
3637  */
3638 EAPI void
3639 elm_genlist_item_disabled_set(Elm_Genlist_Item *it, Eina_Bool disabled)
3640 {
3641    if (!it) return;
3642    if (it->disabled == disabled) return;
3643    if (it->delete_me) return;
3644    it->disabled = disabled;
3645    if (it->realized)
3646      {
3647         if (it->disabled)
3648           edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
3649         else
3650           edje_object_signal_emit(it->base, "elm,state,enabled", "elm");
3651      }
3652 }
3653
3654 /**
3655  * Get the disabled state of an item
3656  *
3657  * This gets the disabld state of the given item.
3658  *
3659  * @param it The item
3660  * @return The disabled state
3661  *
3662  * @ingroup Genlist
3663  */
3664 EAPI Eina_Bool
3665 elm_genlist_item_disabled_get(const Elm_Genlist_Item *it)
3666 {
3667    if (!it) return EINA_FALSE;
3668    if (it->delete_me) return EINA_FALSE;
3669    return it->disabled;
3670 }
3671
3672 /**
3673  * Sets the display only state of an item.
3674  *
3675  * A display only item cannot be selected or unselected. It is for display
3676  * only and not selecting or otherwise clicking, dragging etc. by the user,
3677  * thus finger size rules will not be applied to this item.
3678  *
3679  * @param it The item
3680  * @param display_only The display only state
3681  *
3682  * @ingroup Genlist
3683  */
3684 EAPI void
3685 elm_genlist_item_display_only_set(Elm_Genlist_Item *it, Eina_Bool display_only)
3686 {
3687    if (!it) return;
3688    if (!it->block) return;
3689    if (it->display_only == display_only) return;
3690    if (it->delete_me) return;
3691    it->display_only = display_only;
3692    it->mincalcd = EINA_FALSE;
3693    it->updateme = EINA_TRUE;
3694    it->block->updateme = EINA_TRUE;
3695    if (it->wd->update_job) ecore_job_del(it->wd->update_job);
3696    it->wd->update_job = ecore_job_add(_update_job, it->wd);
3697 }
3698
3699 /**
3700  * Get the display only state of an item
3701  *
3702  * This gets the display only state of the given item.
3703  *
3704  * @param it The item
3705  * @return The display only state
3706  *
3707  * @ingroup Genlist
3708  */
3709 EAPI Eina_Bool
3710 elm_genlist_item_display_only_get(const Elm_Genlist_Item *it)
3711 {
3712    if (!it) return EINA_FALSE;
3713    if (it->delete_me) return EINA_FALSE;
3714    return it->display_only;
3715 }
3716
3717 /**
3718  * Show the given item
3719  *
3720  * This causes genlist to jump to the given item @p it and show it (by scrolling),
3721  * if it is not fully visible.
3722  *
3723  * @param it The item
3724  *
3725  * @ingroup Genlist
3726  */
3727 EAPI void
3728 elm_genlist_item_show(Elm_Genlist_Item *it)
3729 {
3730    if (!it) return;
3731    if (it->delete_me) return;
3732    if ((it->queued) || (!it->mincalcd))
3733      {
3734         it->wd->show_item = it;
3735         it->wd->bring_in = 1;
3736         it->showme = EINA_TRUE;
3737         return;
3738      }
3739    if (it->wd->show_item)
3740      {
3741         it->wd->show_item->showme = EINA_FALSE;
3742         it->wd->show_item = NULL;
3743      }
3744    elm_smart_scroller_child_region_show(it->wd->scr,
3745                                         it->x + it->block->x,
3746                                         it->y + it->block->y,
3747                                         it->block->w, it->h);
3748 }
3749
3750 /**
3751  * Bring in the given item
3752  *
3753  * This causes genlist to jump to the given item @p it and show it (by scrolling),
3754  * if it is not fully visible. This may use animation to do so and take a
3755  * period of time
3756  *
3757  * @param it The item
3758  *
3759  * @ingroup Genlist
3760  */
3761 EAPI void
3762 elm_genlist_item_bring_in(Elm_Genlist_Item *it)
3763 {
3764    if (!it) return;
3765    if (it->delete_me) return;
3766    if ((it->queued) || (!it->mincalcd))
3767      {
3768         it->wd->show_item = it;
3769         it->wd->bring_in = 1;
3770         it->showme = EINA_TRUE;
3771         return;
3772      }
3773    if (it->wd->show_item)
3774      {
3775         it->wd->show_item->showme = EINA_FALSE;
3776         it->wd->show_item = NULL;
3777      }
3778    elm_smart_scroller_region_bring_in(it->wd->scr,
3779                                       it->x + it->block->x,
3780                                       it->y + it->block->y,
3781                                       it->block->w, it->h);
3782 }
3783
3784 /**
3785  * Show the given item at the top
3786  *
3787  * This causes genlist to jump to the given item @p it and show it (by scrolling),
3788  * if it is not fully visible.
3789  *
3790  * @param it The item
3791  *
3792  * @ingroup Genlist
3793  */
3794 EAPI void
3795 elm_genlist_item_top_show(Elm_Genlist_Item *it)
3796 {
3797    if (!it) return;
3798    Evas_Coord ow, oh;
3799
3800    if (it->delete_me) return;
3801    if ((it->queued) || (!it->mincalcd))
3802      {
3803         it->wd->show_item = it;
3804         it->wd->bring_in = 1;
3805         it->showme = EINA_TRUE;
3806         return;
3807      }
3808    if (it->wd->show_item)
3809      {
3810         it->wd->show_item->showme = EINA_FALSE;
3811         it->wd->show_item = NULL;
3812      }
3813    evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3814    elm_smart_scroller_child_region_show(it->wd->scr,
3815                                         it->x + it->block->x,
3816                                         it->y + it->block->y,
3817                                         it->block->w, oh);
3818 }
3819
3820 /**
3821  * Bring in the given item at the top
3822  *
3823  * This causes genlist to jump to the given item @p it and show it (by scrolling),
3824  * if it is not fully visible. This may use animation to do so and take a
3825  * period of time
3826  *
3827  * @param it The item
3828  *
3829  * @ingroup Genlist
3830  */
3831 EAPI void
3832 elm_genlist_item_top_bring_in(Elm_Genlist_Item *it)
3833 {
3834    if (!it) return;
3835    Evas_Coord ow, oh;
3836
3837    if (it->delete_me) return;
3838    if ((it->queued) || (!it->mincalcd))
3839      {
3840         it->wd->show_item = it;
3841         it->wd->bring_in = 1;
3842         it->showme = EINA_TRUE;
3843         return;
3844      }
3845    if (it->wd->show_item)
3846      {
3847         it->wd->show_item->showme = EINA_FALSE;
3848         it->wd->show_item = NULL;
3849      }
3850    evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3851    elm_smart_scroller_region_bring_in(it->wd->scr,
3852                                       it->x + it->block->x,
3853                                       it->y + it->block->y,
3854                                       it->block->w, oh);
3855 }
3856
3857 /**
3858  * Show the given item at the middle
3859  *
3860  * This causes genlist to jump to the given item @p it and show it (by scrolling),
3861  * if it is not fully visible.
3862  *
3863  * @param it The item
3864  *
3865  * @ingroup Genlist
3866  */
3867 EAPI void
3868 elm_genlist_item_middle_show(Elm_Genlist_Item *it)
3869 {
3870    if (!it) return;
3871    Evas_Coord ow, oh;
3872
3873    if (it->delete_me) return;
3874    if ((it->queued) || (!it->mincalcd))
3875      {
3876         it->wd->show_item = it;
3877         it->wd->bring_in = 1;
3878         it->showme = EINA_TRUE;
3879         return;
3880      }
3881    if (it->wd->show_item)
3882      {
3883         it->wd->show_item->showme = EINA_FALSE;
3884         it->wd->show_item = NULL;
3885      }
3886    evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3887    elm_smart_scroller_child_region_show(it->wd->scr,
3888                                         it->x + it->block->x,
3889                                         it->y + it->block->y - oh/2 + it->h/2,
3890                                         it->block->w, oh);
3891 }
3892
3893
3894 /**
3895  * Bring in the given item at the middle
3896  *
3897  * This causes genlist to jump to the given item @p it and show it (by scrolling),
3898  * if it is not fully visible. This may use animation to do so and take a
3899  * period of time
3900  *
3901  * @param it The item
3902  *
3903  * @ingroup Genlist
3904  */
3905 EAPI void
3906 elm_genlist_item_middle_bring_in(Elm_Genlist_Item *it)
3907 {
3908    if (!it) return;
3909    Evas_Coord ow, oh;
3910
3911    if (it->delete_me) return;
3912    if ((it->queued) || (!it->mincalcd))
3913      {
3914         it->wd->show_item = it;
3915         it->wd->bring_in = 1;
3916         it->showme = EINA_TRUE;
3917         return;
3918      }
3919    if (it->wd->show_item)
3920      {
3921         it->wd->show_item->showme = EINA_FALSE;
3922         it->wd->show_item = NULL;
3923      }
3924    evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3925    elm_smart_scroller_region_bring_in(it->wd->scr,
3926                                       it->x + it->block->x,
3927                                       it->y + it->block->y - oh/2 + it->h/2,
3928                                       it->block->w, oh);
3929 }
3930
3931 /**
3932  * Delete a given item
3933  *
3934  * This deletes the item from genlist and calls the genlist item del class
3935  * callback defined in the item class, if it is set.
3936  *
3937  * @param it The item
3938  *
3939  * @ingroup Genlist
3940  */
3941 EAPI void
3942 elm_genlist_item_del(Elm_Genlist_Item *it)
3943 {
3944    if (!it) return;
3945    if ((it->relcount > 0) || (it->walking > 0))
3946      {
3947         elm_genlist_item_subitems_clear(it);
3948         it->delete_me = EINA_TRUE;
3949         if (it->wd->show_item == it) it->wd->show_item = NULL;
3950         if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
3951         if (it->block)
3952           {
3953              if (it->realized) _item_unrealize(it);
3954              it->block->changed = EINA_TRUE;
3955              if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
3956              it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
3957           }
3958         if (it->itc->func.del)
3959            it->itc->func.del((void *)it->data, it->wd->obj);
3960         return;
3961      }
3962    _item_del(it);
3963 }
3964
3965 /**
3966  * Set the data item from the genlist item
3967  *
3968  * This set the data value passed on the elm_genlist_item_append() and
3969  * related item addition calls. This function will also call
3970  * elm_genlist_item_update() so the item will be updated to reflect the
3971  * new data.
3972  *
3973  * @param it The item
3974  * @param data The new data pointer to set
3975  *
3976  * @ingroup Genlist
3977  */
3978 EAPI void
3979 elm_genlist_item_data_set(Elm_Genlist_Item *it, const void *data)
3980 {
3981    if (!it) return;
3982    it->data = data;
3983    elm_genlist_item_update(it);
3984 }
3985
3986 /**
3987  * Get the data item from the genlist item
3988  *
3989  * This returns the data value passed on the elm_genlist_item_append() and
3990  * related item addition calls.
3991  *
3992  * @param it The item
3993  * @return The data pointer provided when created
3994  *
3995  * @ingroup Genlist
3996  */
3997 EAPI const void *
3998 elm_genlist_item_data_get(const Elm_Genlist_Item *it)
3999 {
4000    if (!it) return NULL;
4001    return it->data;
4002 }
4003
4004 /**
4005  * Get the real evas object of the genlist item
4006  *
4007  * This returns the actual evas object used for the specified genlist item.
4008  * This may be NULL as it may not be created, and ma be deleted at any time
4009  * by genlist. Do not modify this object (move, resize, show, hide etc.) as
4010  * genlist is controlling it. This function is for querying, emitting
4011  * custom signals or hooking lower level callbacks for events. Do not
4012  * delete this object under any circumstances.
4013  *
4014  * @param it The item
4015  * @return The objct pointer
4016  *
4017  * @ingroup Genlist
4018  */
4019 EAPI const Evas_Object *
4020 elm_genlist_item_object_get(const Elm_Genlist_Item *it)
4021 {
4022    if (!it) return NULL;
4023    return it->base;
4024 }
4025
4026 /**
4027  * Update the contents of an item
4028  *
4029  * This updates an item by calling all the item class functions again to get
4030  * the icons, labels and states. Use this when the original item data has
4031  * changed and the changes are desired to be reflected.
4032  *
4033  * @param it The item
4034  *
4035  * @ingroup Genlist
4036  */
4037 EAPI void
4038 elm_genlist_item_update(Elm_Genlist_Item *it)
4039 {
4040    if (!it) return;
4041    if (!it->block) return;
4042    if (it->delete_me) return;
4043    it->mincalcd = EINA_FALSE;
4044    it->updateme = EINA_TRUE;
4045    it->block->updateme = EINA_TRUE;
4046    if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4047    it->wd->update_job = ecore_job_add(_update_job, it->wd);
4048 }
4049
4050 /**
4051  * Update the item class of an item
4052  *
4053  * @param it The item
4054  * @parem itc The item class for the item
4055  *
4056  * @ingroup Genlist
4057  */
4058 EAPI void
4059 elm_genlist_item_item_class_update(Elm_Genlist_Item *it, const Elm_Genlist_Item_Class *itc)
4060 {
4061    if (!it) return;
4062    if (!it->block) return;
4063    if (!itc) return;
4064    if (it->delete_me) return;
4065    it->itc = itc;
4066    elm_genlist_item_update(it);
4067 }
4068
4069 /**
4070  * This sets the horizontal stretching mode
4071  *
4072  * This sets the mode used for sizing items horizontally. Valid modes are
4073  * ELM_LIST_LIMIT and ELM_LIST_SCROLL. The default is ELM_LIST_SCROLL. This
4074  * mode means that if items are too wide to fit, the scroller will scroll
4075  * horizontally. Otherwise items are expanded to fill the width of the
4076  * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded
4077  * to the viewport width and limited to that size.
4078  *
4079  * @param obj The genlist object
4080  * @param mode The mode to use
4081  *
4082  * @ingroup Genlist
4083  */
4084 EAPI void
4085 elm_genlist_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode)
4086 {
4087    ELM_CHECK_WIDTYPE(obj, widtype);
4088    Widget_Data *wd = elm_widget_data_get(obj);
4089    if (!wd) return;
4090    if (wd->mode == mode) return;
4091    wd->mode = mode;
4092    _sizing_eval(obj);
4093 }
4094
4095 /**
4096  * Gets the horizontal stretching mode
4097  *
4098  * @param obj The genlist object
4099  * @return The mode to use
4100  * (ELM_LIST_LIMIT, ELM_LIST_SCROLL, ELM_LIST_LIMIT)
4101  *
4102  * @ingroup Genlist
4103  */
4104 EAPI Elm_List_Mode
4105 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4106 {
4107    ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4108    Widget_Data *wd = elm_widget_data_get(obj);
4109    if (!wd) return ELM_LIST_LAST;
4110    return wd->mode;
4111 }
4112
4113 /**
4114  * Set the always select mode.
4115  *
4116  * Items will only call their selection func and callback when first becoming
4117  * selected. Any further clicks will do nothing, unless you enable always
4118  * select with elm_genlist_always_select_mode_set(). This means even if
4119  * selected, every click will make the selected callbacks be called.
4120  *
4121  * @param obj The genlist object
4122  * @param always_select The always select mode
4123  * (EINA_TRUE = on, EINA_FALSE = off)
4124  *
4125  * @ingroup Genlist
4126  */
4127 EAPI void
4128 elm_genlist_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select)
4129 {
4130    ELM_CHECK_WIDTYPE(obj, widtype);
4131    Widget_Data *wd = elm_widget_data_get(obj);
4132    if (!wd) return;
4133    wd->always_select = always_select;
4134 }
4135
4136 /**
4137  * Get the always select mode.
4138  *
4139  * @param obj The genlist object
4140  * @return The always select mode
4141  * (EINA_TRUE = on, EINA_FALSE = off)
4142  *
4143  * @ingroup Genlist
4144  */
4145 EAPI Eina_Bool
4146 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4147 {
4148    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4149    Widget_Data *wd = elm_widget_data_get(obj);
4150    if (!wd) return EINA_FALSE;
4151    return wd->always_select;
4152 }
4153
4154 /**
4155  * Set no select mode
4156  *
4157  * This will turn off the ability to select items entirely and they will
4158  * neither appear selected nor call selected callback functions.
4159  *
4160  * @param obj The genlist object
4161  * @param no_select The no select mode
4162  * (EINA_TRUE = on, EINA_FALSE = off)
4163  *
4164  * @ingroup Genlist
4165  */
4166 EAPI void
4167 elm_genlist_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select)
4168 {
4169    ELM_CHECK_WIDTYPE(obj, widtype);
4170    Widget_Data *wd = elm_widget_data_get(obj);
4171    if (!wd) return;
4172    wd->no_select = no_select;
4173 }
4174
4175 /**
4176  * Gets no select mode
4177  *
4178  * @param obj The genlist object
4179  * @return The no select mode
4180  * (EINA_TRUE = on, EINA_FALSE = off)
4181  *
4182  * @ingroup Genlist
4183  */
4184 EAPI Eina_Bool
4185 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4186 {
4187    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4188    Widget_Data *wd = elm_widget_data_get(obj);
4189    if (!wd) return EINA_FALSE;
4190    return wd->no_select;
4191 }
4192
4193 /**
4194  * Set compress mode
4195  *
4196  * This will enable the compress mode where items are "compressed" horizontally
4197  * to fit the genlist scrollable viewport width. This is special for genlist.
4198  * Do not rely on elm_genlist_horizontal_mode_set() being set to
4199  * ELM_LIST_COMPRESS to work as genlist needs to handle it specially.
4200  *
4201  * @param obj The genlist object
4202  * @param compress The compress mode
4203  * (EINA_TRUE = on, EINA_FALSE = off)
4204  *
4205  * @ingroup Genlist
4206  */
4207 EAPI void
4208 elm_genlist_compress_mode_set(Evas_Object *obj, Eina_Bool compress)
4209 {
4210    ELM_CHECK_WIDTYPE(obj, widtype);
4211    Widget_Data *wd = elm_widget_data_get(obj);
4212    if (!wd) return;
4213    wd->compress = compress;
4214 }
4215
4216 /**
4217  * Get the compress mode
4218  *
4219  * @param obj The genlist object
4220  * @return The compress mode
4221  * (EINA_TRUE = on, EINA_FALSE = off)
4222  *
4223  * @ingroup Genlist
4224  */
4225 EAPI Eina_Bool
4226 elm_genlist_compress_mode_get(const Evas_Object *obj)
4227 {
4228    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4229    Widget_Data *wd = elm_widget_data_get(obj);
4230    if (!wd) return EINA_FALSE;
4231    return wd->compress;
4232 }
4233
4234 /**
4235  * Set bounce mode
4236  *
4237  * This will enable or disable the scroller bounce mode for the genlist. See 
4238  * elm_scroller_bounce_set() for details
4239  *
4240  * @param obj The genlist object
4241  * @param h_bounce Allow bounce horizontally
4242  * @param v_bounce Allow bounce vertically
4243  *
4244  * @ingroup Genlist
4245  */
4246 EAPI void
4247 elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
4248 {
4249    ELM_CHECK_WIDTYPE(obj, widtype);
4250    Widget_Data *wd = elm_widget_data_get(obj);
4251    if (!wd) return;
4252    elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4253 }
4254
4255 /**
4256  * Get the bounce mode
4257  *
4258  * @param obj The genlist object
4259  * @param h_bounce Allow bounce horizontally
4260  * @param v_bounce Allow bounce vertically
4261  *
4262  * @ingroup Genlist
4263  */
4264 EAPI void
4265 elm_genlist_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
4266 {
4267    ELM_CHECK_WIDTYPE(obj, widtype);
4268    Widget_Data *wd = elm_widget_data_get(obj);
4269    if (!wd) return;
4270    elm_smart_scroller_bounce_allow_get(obj, h_bounce, v_bounce);
4271 }
4272
4273 /**
4274  * Set homogenous mode
4275  *
4276  * This will enable the homogeneous mode where items are of the same height and width
4277  * so that genlist may do the lazy-loading at its maximum.  This implies 'compressed' mode
4278  *
4279  * @param obj The genlist object
4280  * @param homogeneous Assume the items within the genlist are of the same height and width
4281  * (EINA_TRUE = on, EINA_FALSE = off)
4282  *
4283  * @ingroup Genlist
4284  */
4285 EAPI void
4286 elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous)
4287 {
4288    ELM_CHECK_WIDTYPE(obj, widtype);
4289    Widget_Data *wd = elm_widget_data_get(obj);
4290    if (!wd) return;
4291    if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4292    wd->homogeneous = homogeneous;
4293 }
4294
4295 /**
4296  * Get the homogenous mode
4297  *
4298  * @param obj The genlist object
4299  * @return Assume the items within the genlist are of the same height and width
4300  * (EINA_TRUE = on, EINA_FALSE = off)
4301  *
4302  * @ingroup Genlist
4303  */
4304 EAPI Eina_Bool
4305 elm_genlist_homogeneous_get(const Evas_Object *obj)
4306 {
4307    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4308    Widget_Data *wd = elm_widget_data_get(obj);
4309    if (!wd) return EINA_FALSE;
4310    return wd->homogeneous;
4311 }
4312
4313 /**
4314  * Set the maximum number of items within an item block
4315  *
4316  * This will configure the block count to tune to the target with particular performance matrix.
4317  *
4318  * @param obj The genlist object
4319  * @param n   Maximum number of items within an item block
4320  *
4321  * @ingroup Genlist
4322  */
4323 EAPI void
4324 elm_genlist_block_count_set(Evas_Object *obj, int n)
4325 {
4326    ELM_CHECK_WIDTYPE(obj, widtype);
4327    Widget_Data *wd = elm_widget_data_get(obj);
4328    if (!wd) return;
4329    wd->max_items_per_block = n;
4330 }
4331
4332 /**
4333  * Get the maximum number of items within an item block
4334  *
4335  * @param obj The genlist object
4336  * @return Maximum number of items within an item block
4337  *
4338  * @ingroup Genlist
4339  */
4340 EAPI int
4341 elm_genlist_block_count_get(const Evas_Object *obj)
4342 {
4343    ELM_CHECK_WIDTYPE(obj, widtype) 0;
4344    Widget_Data *wd = elm_widget_data_get(obj);
4345    if (!wd) return 0;
4346    return wd->max_items_per_block;
4347 }
4348
4349 /**
4350  * Set the timeout in seconds for the longpress event
4351  * 
4352  * @param obj The genlist object
4353  * @param timeout timeout in seconds
4354  * 
4355  * @ingroup Genlist
4356  */
4357 EAPI void
4358 elm_genlist_longpress_timeout_set(Evas_Object *obj, double timeout)
4359 {
4360    ELM_CHECK_WIDTYPE(obj, widtype);
4361    Widget_Data *wd = elm_widget_data_get(obj);
4362    if (!wd) return;
4363    wd->longpress_timeout = timeout;
4364 }
4365
4366 /**
4367  * Get the timeout in seconds for the longpress event
4368  * 
4369  * @param obj The genlist object
4370  * @return timeout in seconds
4371  * 
4372  * @ingroup Genlist
4373  */
4374 EAPI double
4375 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4376 {
4377    ELM_CHECK_WIDTYPE(obj, widtype) 0;
4378    Widget_Data *wd = elm_widget_data_get(obj);
4379    if (!wd) return 0;
4380    return wd->longpress_timeout;
4381 }
4382
4383 /**
4384  * Set the scrollbar policy
4385  *
4386  * This sets the scrollbar visibility policy for the given genlist scroller.
4387  * ELM_SMART_SCROLLER_POLICY_AUTO means the scrollber is made visible if it
4388  * is needed, and otherwise kept hidden. ELM_SMART_SCROLLER_POLICY_ON turns
4389  * it on all the time, and ELM_SMART_SCROLLER_POLICY_OFF always keeps it off.
4390  * This applies respectively for the horizontal and vertical scrollbars.
4391  *
4392  * @param obj The genlist object
4393  * @param policy_h Horizontal scrollbar policy
4394  * @param policy_v Vertical scrollbar policy
4395  *
4396  * @ingroup List
4397  */
4398 EAPI void
4399 elm_genlist_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
4400 {
4401    ELM_CHECK_WIDTYPE(obj, widtype);
4402    Widget_Data *wd = elm_widget_data_get(obj);
4403    if (!wd) return;
4404    if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4405        (policy_v >= ELM_SCROLLER_POLICY_LAST))
4406      return;
4407    if (wd->scr)
4408      elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4409 }
4410
4411 EAPI void
4412 elm_genlist_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
4413 {
4414    ELM_CHECK_WIDTYPE(obj, widtype);
4415    Widget_Data *wd = elm_widget_data_get(obj);
4416    Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
4417    if ((!wd) || (!wd->scr)) return;
4418    elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
4419    if (policy_h) *policy_h = (Elm_Scroller_Policy) s_policy_h;
4420    if (policy_v) *policy_v = (Elm_Scroller_Policy) s_policy_v;
4421 }
4422
4423 // added for item moving animation.
4424 static Eina_Bool
4425 _group_item_contract_moving_effect_timer_cb(void *data)
4426 {
4427    Evas_Object *obj = (Evas_Object *)data;
4428    Widget_Data *wd = elm_widget_data_get(obj);   
4429
4430    Item_Block  *itb = NULL;
4431    Elm_Genlist_GroupItem *git;
4432    Elm_Genlist_Item *it;
4433    const Eina_List *l;
4434    int cnt = 0, git_count = 0;
4435    double added_gy = 1;
4436
4437    int hide_git = 0, git_cnt = 0, list_start_y = 0;
4438
4439    int *git_array = NULL;
4440    int base_git = 0, base_git_num = 0;
4441    int tmp_y = 0,  devide_size = 1;
4442    double t;
4443
4444    Eina_Bool finish = EINA_FALSE;
4445
4446    Evas_Coord ox, oy, ow, oh;
4447    if (!wd)
4448       return ECORE_CALLBACK_CANCEL;
4449
4450    if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE)
4451       return ECORE_CALLBACK_CANCEL;
4452
4453    git_array = (int*)malloc(sizeof(int) * wd->max_git_num);
4454    t = ecore_loop_time_get();
4455
4456    if (t - wd->effect_start >= 5.0) 
4457       finish = EINA_TRUE;
4458
4459    if (wd->item_count < 100)
4460       devide_size = 8 * _elm_config->scale;
4461    else if (wd->item_count < 500)
4462       devide_size = (8 - (devide_size / 100)) * _elm_config->scale;
4463    else
4464       devide_size = 2 * _elm_config->scale;
4465
4466    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4467
4468    list_start_y = oy;
4469    if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
4470       list_start_y += wd->select_all_item->h;
4471
4472    EINA_INLIST_FOREACH(wd->group_items, git)
4473      {
4474         git_array[git_cnt++]  =  git->y;
4475         if (git->y < list_start_y) 
4476            hide_git++;
4477         edje_object_signal_emit(git->base, "elm,state,alpha,disable", "elm");
4478      }
4479    base_git_num = hide_git;
4480
4481    EINA_INLIST_FOREACH(wd->group_items, git)
4482      {
4483         base_git = list_start_y + git->h * (git->num-1) + git->num;
4484         git->old_y = git->y;
4485         added_gy = abs(base_git - git->y) / devide_size;
4486         if (added_gy < 1.0)
4487            added_gy = 1.0;
4488
4489         if (!git->down && git->old_y < list_start_y) 
4490           {
4491              git->finish_y = base_git;
4492              git->down = 1;
4493              git->y = list_start_y - (git->h+1) * hide_git--;
4494
4495              git->old_y = 0;
4496           }
4497         else if (!git->down && git->y < base_git)
4498            git->down = 1;
4499
4500         if (wd->pinch_zoom_reserve)
4501            git->y = base_git;
4502         else 
4503           {
4504
4505              if (git->down) 
4506                {
4507                   if (git->y < base_git) 
4508                     {
4509                        git->y +=added_gy;
4510                        if (git->y > base_git)
4511                           git->y = base_git;
4512                     }
4513                }
4514              else 
4515                {
4516                   if (git->y > base_git)  
4517                      git->y -= added_gy;
4518
4519                   if (git->y < base_git)
4520                      git->y = base_git;
4521                }
4522           }
4523         if (git->num - 1 == cnt && git->y == base_git)
4524            git_count++;
4525
4526         evas_object_resize(git->base, wd->minw, git->h);
4527         evas_object_move(git->base, git->x, git->y);
4528         evas_object_raise(git->base);        
4529         if (git->y < list_start_y)
4530            evas_object_lower(git->base); 
4531         else
4532            evas_object_raise(git->base);
4533         evas_object_show(git->base);      
4534
4535         EINA_INLIST_FOREACH(wd->blocks, itb)
4536           {
4537              EINA_LIST_FOREACH(itb->items, l, it)
4538                {
4539                   if (it->group_item == git) 
4540                     {
4541                        if (it->group_item->old_y)
4542                           it->old_scrl_y -= (it->group_item->old_y - it->group_item->y);
4543
4544                        if (git_array[it->group_item->num+1] <=  it->old_scrl_y || added_gy == 1.0)
4545                          {
4546                             evas_object_color_set(it->base, 0,0,0,0);
4547                             evas_object_color_set(it->edit_obj, 0,0,0,0);
4548                          }
4549                        _move_edit_controls(it,it->scrl_x, it->old_scrl_y);
4550                        evas_object_resize(it->base, itb->wd->minw-(it->pad_left+it->pad_right), it->h);
4551                        evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
4552                        evas_object_raise(it->group_item->base);
4553                        evas_object_show(it->base);
4554                     }
4555                }
4556           }
4557         if (git_count == git_cnt) 
4558           {
4559              finish = EINA_TRUE;
4560              break;
4561           }
4562         if (wd->select_all_item)  evas_object_raise(wd->select_all_item->base);
4563         cnt++;
4564      }
4565    free(git_array);
4566
4567    if (finish) // finish animation
4568      {
4569         added_gy = 1;
4570         EINA_INLIST_FOREACH(wd->group_items, git)
4571            git->down = 0;
4572
4573         wd->pan_y = 0;
4574         wd->contract_pan_y = 0;
4575         wd->pinch_zoom_reserve = EINA_FALSE;
4576         wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH;
4577         elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0);
4578         elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
4579
4580         //                fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT  FINISH   \n");         
4581
4582         tmp_y  =0 ;
4583         // added for event
4584         EINA_INLIST_FOREACH(wd->blocks, itb)
4585           { 
4586              if (itb->realized) {
4587                   EINA_LIST_FOREACH(itb->items, l, it)
4588                     {
4589                        if (it->realized) {
4590                             it->scrl_y = oy + tmp_y;
4591                             tmp_y += it->h;
4592                             // need to handle edit mode
4593                             evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
4594                             evas_object_move(it->edit_obj, it->scrl_x, it->old_scrl_y);
4595                             evas_object_color_set(it->base, 0,0,0,0);
4596                             evas_object_show(it->base);
4597                        }
4598                     }
4599              }
4600
4601           }
4602         evas_object_lower(wd->alpha_bg);
4603         evas_object_hide(wd->alpha_bg);
4604
4605         return ECORE_CALLBACK_CANCEL;      
4606      }
4607
4608    return ECORE_CALLBACK_RENEW;
4609 }
4610
4611 // added for item moving animation.
4612 static Eina_Bool
4613 _group_item_expand_moving_effect_timer_cb(void *data)
4614 {
4615    Evas_Object *obj = (Evas_Object *)data;
4616    Widget_Data *wd = elm_widget_data_get(obj);
4617    Elm_Genlist_GroupItem *git, *tmp_git;
4618    Item_Block *itb = NULL;   
4619    Elm_Genlist_Item *it;
4620    const Eina_List *l;
4621    int cnt = 0, git_count = 0, git_cnt = 0, git_tmp_y = 0, in = 0, start_in = 0;
4622    int tmp = 0, show_git_cnt = 0, scroll_y = 0, top_git = 0 , git_h = 0, scroll_pan_y = 0, down = 0;
4623    int up_cnt = 1, down_cnt = 1, it_h = 0, devide_size = 1;
4624    static int last_git_y = 0;
4625
4626    double t;
4627
4628    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
4629
4630    static double added_gy = 0; // temp value for animation speed
4631    static double added_gy2 = 0;
4632    Eina_Bool finish = EINA_FALSE;
4633    if (!wd)
4634       return ECORE_CALLBACK_CANCEL;
4635
4636    if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE)
4637       return ECORE_CALLBACK_CANCEL;
4638
4639    t = ecore_loop_time_get();
4640
4641    top_git = wd->pinch_it;
4642
4643    if (top_git< 1)
4644       top_git = 1;
4645    else if (top_git >= wd->max_git_num)
4646       top_git = wd->max_git_num - 1;    
4647
4648    if (wd->item_count < 100)
4649       devide_size = 8 * _elm_config->scale;
4650    else if (wd->item_count < 500)
4651       devide_size = (8 - (devide_size / 100)) * _elm_config->scale;
4652    else
4653       devide_size = 2 * _elm_config->scale;
4654
4655    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4656    evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
4657    if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
4658       oy += wd->select_all_item->h;
4659    // calculate git count and srcroll move position
4660    EINA_INLIST_FOREACH(wd->group_items, git)
4661      {
4662         if (git_cnt == top_git - 1) 
4663            scroll_y = tmp;
4664
4665         if (!scroll_y)
4666           {
4667              EINA_INLIST_FOREACH(wd->blocks, itb)
4668                {             
4669                   EINA_LIST_FOREACH(itb->items, l, it)
4670                     {
4671                        if (it->group_item == git) 
4672                           tmp += it->h;
4673                        it_h = it->h;
4674                     }
4675                }
4676           }
4677         git_h = git->h;
4678         git_cnt++;
4679
4680      }
4681    scroll_pan_y = scroll_y + git_h * (top_git-1) ;
4682
4683    if (t - wd->effect_start >= 5.0) 
4684       finish = EINA_TRUE;
4685
4686    // items realize
4687    EINA_INLIST_FOREACH(wd->blocks, itb)
4688      {
4689         if ((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh) 
4690             || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh))
4691           {
4692              if (!itb->realized)
4693                {
4694                   start_in = in;
4695                   EINA_LIST_FOREACH(itb->items, l, it)
4696                     {
4697                        _item_realize(it, start_in, 0);
4698                        it->realized = EINA_TRUE;
4699                        start_in++;
4700                     }
4701                   itb->realized = EINA_TRUE;
4702                   itb->want_unrealize = EINA_FALSE;         
4703
4704                }
4705           }
4706         else
4707           {
4708              if (itb->realized) _item_block_unrealize(itb);
4709           }
4710         in += itb->count;
4711      }
4712
4713    // set group item finish y and items y position of group item and items. 
4714    tmp = 0;
4715    git_tmp_y = oy;   
4716    EINA_INLIST_FOREACH(wd->group_items, git)
4717      {
4718         if (git->num >= top_git)
4719           {
4720              git->finish_y = git_tmp_y; 
4721              git_tmp_y += git->h;
4722              tmp = git->y + git->h;
4723
4724           }
4725         else 
4726            git->finish_y =  -1 * oh;
4727
4728         EINA_INLIST_FOREACH(wd->blocks, itb)
4729           { 
4730              EINA_LIST_FOREACH(itb->items, l, it)
4731                {
4732                   if (it->group_item == git) 
4733                     {
4734                        if (git->finish_y !=  -1 * oh)
4735                          {
4736                             it->old_scrl_y = tmp;
4737                             git_tmp_y += it->h;
4738                             added_gy2 = abs(git->finish_y - git->y) / devide_size;
4739                             tmp += it->h - added_gy2;
4740                          }
4741                        else
4742                           it->old_scrl_y = -1 * oh;
4743                     }
4744                }
4745           }
4746
4747         if (git->finish_y  >= oy && git->finish_y < oy+oh)
4748            show_git_cnt++;
4749      }
4750
4751    EINA_INLIST_FOREACH(wd->group_items, git)
4752      {
4753         down = 0;
4754
4755         evas_object_move(git->base, git->x, git->y);
4756         if (git->y >= oy)
4757           {
4758              evas_object_raise(git->base);
4759              evas_object_show(git->base);
4760           }
4761         else 
4762           {
4763              evas_object_lower(git->base);
4764              evas_object_hide(git->base);
4765           }
4766
4767         added_gy = abs(git->finish_y - git->y) / devide_size;
4768         if (added_gy < 1.0) added_gy = 1.0;
4769         if (git->y > git->finish_y)
4770           {
4771              if (git->y > oy)
4772                 git->y -= added_gy; 
4773              if (git->num >= top_git)
4774                 up_cnt++;
4775              down = 0;
4776           }
4777         else if (git->y < git->finish_y)
4778           {
4779              git->y += added_gy;
4780              down_cnt++;
4781              down = 1;
4782           }
4783
4784         if ((!down && git->y < git->finish_y) || (down && git->y > git->finish_y))
4785            git->y = git->finish_y; 
4786
4787         if (git_cnt-1 == cnt)
4788            last_git_y = git->y;
4789
4790         if (git->num == top_git && git->y == oy)
4791           {
4792              evas_object_move(git->base, git->x, git->y);
4793              evas_object_show(git->base);
4794              git_count = 0;
4795              EINA_INLIST_FOREACH(wd->group_items, tmp_git)
4796                {
4797                   if (tmp_git->y == tmp_git->finish_y && tmp_git->y > oy && tmp_git->y < oy+oh)
4798                     {
4799                        git_count++;        
4800                     }
4801                }
4802           }
4803
4804         EINA_INLIST_FOREACH(wd->blocks, itb)
4805           { 
4806              EINA_LIST_FOREACH(itb->items, l, it)
4807                {
4808                   if (it->group_item == git)
4809                     {
4810
4811                        if ((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh) 
4812                            || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh))
4813                          {            
4814                             evas_object_resize(it->base, wd->minw-(it->pad_left+it->pad_right), it->h);
4815                             evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
4816                             _move_edit_controls(it, it->scrl_x, it->old_scrl_y);
4817                             evas_object_color_set(it->edit_obj, 255,255,255,255);
4818                             evas_object_color_set(it->base, 255,255,255,255);
4819                             evas_object_raise(it->base);
4820                             evas_object_raise(it->group_item->base);
4821                          }
4822                     }
4823                }
4824           }
4825
4826         cnt++;
4827
4828         if (git_count + 1  == show_git_cnt) 
4829            finish = EINA_TRUE;
4830      }
4831    if (finish) 
4832      {
4833         added_gy = 0;
4834         added_gy2 = 0;
4835         last_git_y  = 0;
4836
4837         wd->pan_y = scroll_y + (git_h) * (top_git-1) ;
4838
4839         EINA_INLIST_FOREACH(wd->group_items, git)
4840           {
4841              edje_object_signal_emit(git->base, "elm,state,alpha,enable", "elm");                       
4842           }
4843         EINA_INLIST_FOREACH(wd->blocks, itb)
4844           { 
4845              EINA_LIST_FOREACH(itb->items, l, it)
4846                {
4847                   _item_unselect(it);
4848                }
4849           }
4850         wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE;
4851         fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND  FINISH   \n");
4852         elm_smart_scroller_hold_set(wd->scr, 0);
4853         elm_smart_scroller_freeze_set(wd->scr, 0);
4854         elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0);
4855         elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
4856         //                printf("_group_item_expand_moving_effect_timer_cb  FINISH \n");
4857         evas_object_lower(wd->alpha_bg);
4858         evas_object_hide(wd->alpha_bg);
4859         //       evas_object_smart_changed(wd->pan_smart);
4860         if (wd->calc_job) ecore_job_del(wd->calc_job);
4861         wd->calc_job = ecore_job_add(_calc_job, wd);
4862
4863         return ECORE_CALLBACK_CANCEL;
4864      }      
4865
4866    return ECORE_CALLBACK_RENEW;
4867 }
4868
4869 static int
4870 _item_pinch_recalc(Evas_Object *obj, int emode)
4871 {
4872    Item_Block *itb = NULL;
4873
4874    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
4875    Widget_Data *wd = elm_widget_data_get(obj);
4876
4877    if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND)
4878       return EINA_FALSE;
4879
4880    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4881    evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
4882
4883    if (emode)
4884      {
4885         if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE)
4886           {
4887              wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT;
4888
4889              elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1);
4890              elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_FALSE);
4891              evas_object_raise(wd->alpha_bg);
4892              evas_object_show(wd->alpha_bg);
4893
4894              wd->effect_start =  ecore_loop_time_get();
4895              wd->item_moving_effect_timer = ecore_animator_add(_group_item_contract_moving_effect_timer_cb, obj);
4896           }
4897      }
4898    else if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
4899      {
4900         elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1);
4901
4902         evas_object_raise(wd->alpha_bg);
4903         evas_object_show(wd->alpha_bg);
4904
4905         wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND;
4906         EINA_INLIST_FOREACH(wd->blocks, itb)
4907           {
4908              if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
4909                                      itb->y - wd->pan_y + oy,
4910                                      itb->w, itb->h,
4911                                      cvx, cvy, cvw, cvh))
4912                {
4913                   if (itb->realized) _item_block_unrealize(itb);
4914                   itb->realized = EINA_FALSE;
4915                }
4916           }
4917
4918         wd->effect_start =  ecore_loop_time_get();
4919         wd->item_moving_effect_timer = ecore_animator_add(_group_item_expand_moving_effect_timer_cb, obj);
4920      }
4921
4922    return EINA_TRUE;
4923 }
4924
4925 static Evas_Object*
4926 create_tray_alpha_bg(const Evas_Object *obj)
4927 {
4928    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4929    Widget_Data *wd = elm_widget_data_get(obj);
4930    if (!wd) return NULL;
4931
4932    Evas_Object *bg = NULL;
4933    Evas_Coord ox, oy, ow, oh;
4934
4935    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4936    bg  =  evas_object_rectangle_add(evas_object_evas_get(wd->obj));
4937    evas_object_color_set(bg , 0,0,0,0);
4938    evas_object_resize(bg , ow, oh);
4939    evas_object_move(bg , ox, oy);
4940    evas_object_show(bg);
4941    evas_object_hide(bg);
4942    return bg ;
4943 }
4944
4945 static void
4946 _elm_genlist_pinch_zoom_execute(Evas_Object *obj, Eina_Bool emode)
4947 {
4948    ELM_CHECK_WIDTYPE(obj, widtype);
4949    Widget_Data *wd = elm_widget_data_get(obj);
4950    if (!wd || !wd->pinch_zoom) return;   
4951    if (!wd->queue_idler)
4952      {
4953         if (!wd->alpha_bg)
4954            wd->alpha_bg = create_tray_alpha_bg(obj);
4955         _item_pinch_recalc(obj, emode);
4956      }
4957 }
4958
4959 /**
4960  * Set pinch zoom mode
4961  * 
4962  * @param obj The genlist object
4963  * @param emode 
4964  * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out)
4965  * 
4966  * @ingroup Genlist
4967  */
4968 EAPI void
4969 elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Eina_Bool emode)
4970 {
4971    ELM_CHECK_WIDTYPE(obj, widtype);
4972    Widget_Data *wd = elm_widget_data_get(obj);
4973    if (!wd || !wd->pinch_zoom) return;   
4974    wd->pinch_zoom_reserve = emode;
4975 }
4976
4977 /**
4978  * Get pinch zoom mode
4979  * 
4980  * @param obj The genlist object
4981  * @return The pinch mode
4982  * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out)
4983  * 
4984  * @ingroup Genlist
4985  */
4986 EAPI Eina_Bool
4987 elm_genlist_pinch_zoom_mode_get(const Evas_Object *obj)
4988 {
4989    Widget_Data *wd = elm_widget_data_get(obj);
4990    if (!wd) return EINA_FALSE;
4991    if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
4992       return EINA_TRUE;
4993    else return EINA_FALSE;
4994 }
4995
4996 EAPI void
4997 elm_genlist_pinch_zoom_set(Evas_Object *obj, Eina_Bool emode)
4998 {
4999    Widget_Data *wd = elm_widget_data_get(obj);
5000    if (!wd) return;
5001    wd->pinch_zoom = emode;
5002 }
5003
5004 // added for item moving animation.
5005 static Eina_Bool
5006 _item_moving_effect_timer_cb(void *data)
5007 {
5008    Widget_Data *wd = data;
5009    Item_Block *itb;
5010    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
5011    Elm_Genlist_Item *it;
5012    const Eina_List *l;
5013    int expanded_cnt = 0;
5014    int cnt = 0;
5015    static double added_gy =25;
5016    static int count = 0;
5017    if (!wd) return EINA_FALSE;
5018    if (added_gy < 1) added_gy = 1;
5019
5020    count++;
5021    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5022    evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
5023
5024    EINA_INLIST_FOREACH(wd->blocks, itb)
5025      {
5026         itb->w = wd->minw;
5027         if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
5028                                 itb->y - wd->pan_y + oy,
5029                                 itb->w, itb->h,
5030                                 cvx, cvy, cvw, cvh))
5031           {
5032              EINA_LIST_FOREACH(itb->items, l, it)
5033                {
5034                   if (!it->old_scrl_y)
5035                      it->old_scrl_y  = it->scrl_y;
5036                   if (it->parent && it->parent->expanded && !it->showme)
5037                     {
5038                        evas_object_hide(it->base);
5039                     }
5040                   else evas_object_show(it->base);
5041
5042                   evas_object_show(it->base);
5043
5044                   if (itb && itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
5045                     {
5046                        if (it->old_scrl_y && it->old_scrl_y < it->scrl_y) {
5047                             it->old_scrl_y += added_gy;
5048                        }
5049                        if (it->old_scrl_y >= it->scrl_y) {
5050                             it->list_expanded = 1;
5051                             it->old_scrl_y = it->scrl_y;
5052                        }
5053                     }
5054                   else if (itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
5055                     {
5056                        if (it->old_scrl_y && it->old_scrl_y > it->scrl_y) 
5057                          {
5058
5059                             it->old_scrl_y -= added_gy;
5060                          }
5061
5062                        if (it->old_scrl_y <= it->scrl_y) {
5063                             it->list_expanded = 1;
5064                             it->old_scrl_y = it->scrl_y;
5065                        }
5066                     }
5067                   expanded_cnt += it->list_expanded;
5068                   cnt++;
5069
5070                   _move_edit_controls(it,it->scrl_x, it->scrl_y);
5071                   evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h);
5072                   evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
5073                   evas_object_raise(it->base);
5074                }
5075           }
5076      }
5077    if (expanded_cnt == cnt)
5078      {
5079         if (wd->item_moving_effect_timer)
5080           {
5081              added_gy = 25;
5082              count = 0;
5083              wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
5084              EINA_INLIST_FOREACH(wd->blocks, itb)
5085                {
5086                   EINA_LIST_FOREACH(itb->items, l, it)
5087                     {
5088                        it->list_expanded = 0;
5089                     }
5090                }
5091
5092           }
5093         return ECORE_CALLBACK_CANCEL;
5094      }
5095    return ECORE_CALLBACK_RENEW;
5096 }
5097
5098 // added for edit mode item moving animation.
5099 static Eina_Bool
5100 _edit_mode_item_moving_effect_cb(void *data)
5101 {
5102    Widget_Data *wd = data;
5103    Item_Block *itb;
5104    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
5105    Elm_Genlist_Item *it, *select_all_item;
5106    const Eina_List *l;
5107    int expanded_cnt = 0;
5108    static double added_gy = 9;
5109    static float count = 0;
5110    int finish = 0;
5111    static float select_all_y = 0;
5112
5113    if (!wd) return EINA_FALSE;
5114    count++;
5115
5116    if (!wd->select_all_item)
5117       return ECORE_CALLBACK_CANCEL;
5118
5119    static float dy = 9;
5120    dy -= 0.5;
5121    if (dy < 1.0)
5122       dy = 1.0f;
5123
5124    select_all_y += (dy);
5125
5126    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5127    evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
5128
5129    EINA_INLIST_FOREACH(wd->blocks, itb)
5130      {
5131         itb->w = wd->minw;
5132         if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
5133                                 itb->y - wd->pan_y + oy,
5134                                 itb->w, itb->h,
5135                                 cvx, cvy, cvw, cvh))
5136
5137           {
5138              EINA_LIST_FOREACH(itb->items, l, it)
5139                {
5140
5141                   evas_object_show(it->base);
5142                   if (it->old_pad_left < it->pad_left)
5143                     {
5144                        it->old_pad_left += dy;
5145                        if (it->old_pad_left >= it->pad_left)
5146                          {
5147                             it->list_expanded = 1;
5148                             it->old_pad_left = it->pad_left;
5149                          }
5150                     }
5151                   if (it->old_pad_left > it->pad_left) 
5152                     {
5153                        it->old_pad_left -= dy;
5154                        if (it->old_pad_left <= it->pad_left)
5155                          {
5156                             it->list_expanded = 1;
5157                             it->old_pad_left = it->pad_left;
5158                          }
5159
5160                     }
5161                   if (it->old_scrl_y < it->scrl_y)
5162                     {
5163                        it->old_scrl_y += (dy) ;
5164                        if (it->old_scrl_y >= it->scrl_y)
5165                          {
5166                             it->list_expanded = 1;
5167                             it->old_scrl_y = it->scrl_y;
5168                          }
5169
5170                     }
5171                   if (it->old_scrl_y > it->scrl_y) 
5172                     {
5173                        it->old_scrl_y -= (dy);               
5174                        if (it->old_scrl_y <= it->scrl_y)
5175                          {
5176                             it->list_expanded = 1;
5177                             it->old_scrl_y = it->scrl_y;
5178                          }
5179
5180                     }
5181
5182                   select_all_item = itb->wd->select_all_item;
5183                   evas_object_resize(select_all_item->base, itb->w, select_all_item->h);  
5184                   if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
5185                      evas_object_move(select_all_item->base, ox, oy - select_all_y);
5186                   else if (select_all_y <=  select_all_item->h)
5187                      evas_object_move(select_all_item->base, ox, oy - select_all_item->h + select_all_y);
5188                   evas_object_raise(select_all_item->base);
5189                   evas_object_show(select_all_item->base);
5190
5191                   expanded_cnt += it->list_expanded;
5192
5193                   evas_object_move(it->base, it->scrl_x+it->old_pad_left, it->old_scrl_y);
5194                   evas_object_move(it->edit_obj, it->scrl_x, it->old_scrl_y);
5195                   evas_object_raise(it->edit_obj);
5196                   evas_object_raise(it->base);
5197
5198                   evas_object_show(it->edit_obj);
5199                   evas_object_show(it->base);         
5200
5201                   if (select_all_y >= wd->select_all_item->h && it->list_expanded == 1) 
5202                     {
5203                        finish = 1;         
5204                        evas_object_raise(it->edit_obj);            
5205                        break;
5206                     }
5207                }
5208           }
5209      }
5210
5211    if (finish)
5212      {
5213         if (wd->item_moving_effect_timer)
5214           {
5215              added_gy = 9;
5216              count = 0;
5217              select_all_y = 0;
5218              dy = 9;
5219              wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
5220              EINA_INLIST_FOREACH(wd->blocks, itb)
5221                {
5222                   EINA_LIST_FOREACH(itb->items, l, it)
5223                     {
5224                        it->list_expanded = 0;
5225                     }
5226                }
5227              if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
5228                {
5229                   if (wd->select_all_item)
5230                     {
5231                        if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item);
5232                        free(wd->select_all_item);
5233                     }
5234                   wd->select_all_item = NULL;         
5235                }
5236           }
5237         wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
5238         wd->effect_mode = 0;
5239
5240         if (wd->calc_job) ecore_job_del(wd->calc_job);
5241         wd->calc_job = ecore_job_add(_calc_job, wd);      
5242         return ECORE_CALLBACK_CANCEL;
5243      }
5244    return ECORE_CALLBACK_RENEW;
5245 }
5246
5247
5248 // added for item moving animation.
5249 static int
5250 _item_flip_effect_show(void *data)
5251 {
5252    Widget_Data *wd = data;
5253    Item_Block *itb;
5254    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
5255
5256    if (!wd) return EINA_FALSE;
5257
5258    Elm_Genlist_Item *it;
5259    Evas_Object *base ;
5260    const Eina_List *l;
5261    int start = 0, end = 0;
5262
5263    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5264    evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
5265
5266    EINA_INLIST_FOREACH(wd->blocks, itb)
5267      {
5268         itb->w = wd->minw;
5269         if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
5270                                 itb->y - wd->pan_y + oy,
5271                                 itb->w, itb->h,
5272                                 cvx, cvy, cvw, cvh))
5273           {
5274              EINA_LIST_FOREACH(itb->items, l, it)
5275                {
5276                   if (it->parent && it->wd->expand_item == it->parent && !it->effect_done)
5277                     {
5278                        if (!start) start = it->scrl_y;
5279                        base = (Evas_Object *) it->base;
5280                        edje_object_signal_emit(it->base, "flip_item", "");
5281                        end = it->scrl_y + it->h;
5282                        it->effect_done = EINA_TRUE;
5283                     }
5284                }
5285           }
5286      }
5287    wd->expand_item_cnt = end - start;
5288    return ECORE_CALLBACK_CANCEL;
5289 }
5290
5291 EAPI void
5292 elm_genlist_effect_set(const Evas_Object *obj, Eina_Bool emode)
5293 {
5294    ELM_CHECK_WIDTYPE(obj, widtype);
5295    Widget_Data *wd = elm_widget_data_get(obj);
5296    if (!wd) return;
5297    wd->effect_mode = emode;
5298    wd->point_rect = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5299    evas_object_resize(wd->point_rect, 10, 25);
5300    evas_object_color_set(wd->point_rect, 255, 0, 0, 130);   
5301    evas_object_show(wd->point_rect);
5302    evas_object_hide(wd->point_rect);
5303 }
5304
5305 /*
5306    EAPI void
5307    elm_genlist_edit_mode_effect_set(const Evas_Object *obj, Eina_Bool emode)
5308    {
5309    ELM_CHECK_WIDTYPE(obj, widtype);
5310    Widget_Data *wd = elm_widget_data_get(obj);
5311    if (!wd) return;
5312    wd->edit_mode_effect_mode = emode;
5313    }
5314    */
5315
5316 EAPI void
5317 elm_genlist_queue_exception_set(const Evas_Object *obj, Eina_Bool emode)
5318 {
5319    ELM_CHECK_WIDTYPE(obj, widtype);
5320    Widget_Data *wd = elm_widget_data_get(obj);
5321    if (!wd) return;
5322    wd->queue_exception = emode;
5323
5324    fprintf(stderr, "=================> Caution!!! <========================\n");
5325    fprintf(stderr, "==> elm_genlist_queue_exception_set() is for demo. <===\n");
5326    fprintf(stderr, "==> Do not use this API                             <==\n");
5327    fprintf(stderr, "=======================================================\n");
5328 }
5329
5330 static void
5331 _delete_confirm_cb(void *data, Evas_Object *obj, void *event_info)
5332 {
5333    Widget_Data *wd = data;
5334    evas_object_hide(wd->ed->del_confirm);
5335    if (wd->ed->ec && wd->ed->ec->remove)
5336       wd->ed->ec->remove(wd->obj, wd->ed->del_item);
5337    wd->ed->del_item = NULL;
5338 }
5339
5340 static void
5341 _hide_delete_confirm_object (void *data, Evas_Object *obj, const char *emission, const char *source)
5342 {
5343    const char *del_icon_part;
5344    Elm_Genlist_Item *it = data;
5345    del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm");
5346    if (del_icon_part)
5347       edje_object_part_unswallow(it->edit_obj, it->wd->ed->del_confirm);
5348    evas_object_hide(it->wd->ed->del_confirm);
5349 }
5350
5351 EAPI void
5352 _edit_item_check_set(Elm_Genlist_Item  *it, Eina_Bool del_confirm_state)
5353 {
5354    if (del_confirm_state)
5355      {
5356         it->del_confirm_state = 0;
5357         it->delete_check = 0;
5358         edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm");
5359         it->wd->selct_all = 0;
5360         if (elm_genlist_item_parent_get(it))
5361           edje_object_signal_emit(elm_genlist_item_parent_get(it)->edit_obj, "elm,state,del,animated,enable", "elm");
5362         if (it->wd->select_all_item)
5363           edje_object_signal_emit(it->wd->select_all_item->base, "elm,state,del,animated,enable", "elm");
5364         if (!it->wd->selct_all && it->wd->ed->ec->item_selected)
5365           it->wd->ed->ec->item_selected(it->data, it, it->delete_check);
5366      }
5367    else
5368      {
5369         edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm");
5370         it->del_confirm_state = 1;
5371         it->delete_check = 1;
5372      }
5373 }
5374
5375 EAPI void
5376 _edit_subitems_check(Elm_Genlist_Item *it)
5377 {
5378    if (!it) return;
5379    Eina_List *tl = NULL, *l;
5380    Elm_Genlist_Item *it2;
5381
5382    EINA_LIST_FOREACH(it->items, l, it2)
5383      tl = eina_list_append(tl, it2);
5384    EINA_LIST_FREE(tl, it2)
5385      _edit_item_check_set(it2, !elm_genlist_item_parent_get(it2)->del_confirm_state);
5386 }
5387
5388 static void
5389 _remove_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5390 {
5391    const char *del_conf_style;
5392    Elm_Genlist_Item *it = data;
5393    if (_edit_mode_reset(it->wd))
5394       return;
5395
5396    if (it->edit_long_timer) 
5397      {
5398         ecore_timer_del(it->edit_long_timer);
5399         it->edit_long_timer = NULL;
5400      }
5401    _edit_item_check_set(it, it->del_confirm_state);
5402    _edit_subitems_check(it);
5403    it->wd->ed->del_item = it;
5404
5405    if (!it->wd->selct_all && it->wd->ed->ec->item_selected)
5406       it->wd->ed->ec->item_selected(it->data, it, it->delete_check);
5407    del_conf_style = edje_object_data_get(it->edit_obj, "del_button_style");
5408    if (del_conf_style)
5409       elm_object_style_set(it->wd->ed->del_confirm, del_conf_style);
5410
5411    /*
5412       del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm");
5413       if (del_icon_part)
5414       edje_object_part_swallow(it->edit_obj, del_icon_part, it->wd->ed->del_confirm);
5415       evas_object_show(it->wd->ed->del_confirm);
5416       */
5417 }
5418
5419 static void
5420 _insert_new_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5421 {
5422    Elm_Genlist_Item *it = data;
5423
5424    if (_edit_mode_reset(it->wd))
5425       return;
5426
5427    if (it->wd->ed->ec && it->wd->ed->ec->insert_new)
5428       it->wd->ed->ec->insert_new(it->wd->obj, it);
5429 }
5430
5431 static Eina_Bool
5432 _edit_mode_reset(Widget_Data *wd)
5433 {
5434    /*
5435       if (wd->ed->del_confirm_state)
5436       {
5437    //edje_object_signal_emit(wd->ed->del_item->edit_obj, "elm,state,delete", "elm");
5438    //wd->ed->del_confirm_state = 0;
5439    //wd->ed->del_item = NULL;
5440    return EINA_TRUE;
5441    }
5442    */
5443    return EINA_FALSE;
5444 }
5445
5446 static void
5447 _reorder_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
5448 {
5449    Elm_Genlist_Item *it = data;
5450    Evas_Event_Mouse_Down *ev = event_info;
5451    Evas_Coord x, y;
5452
5453    if (it->wd->edit_field && !it->renamed)
5454       elm_genlist_item_rename_mode_set(it, 0);
5455
5456    if (!(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER))
5457       return;
5458
5459    if (_edit_mode_reset(it->wd))
5460       return;
5461
5462    it->dragging = 0;
5463    it->down = 1;
5464    it->reoder_cavas_x = ev->canvas.x;
5465    it->reoder_cavas_y = ev->canvas.y;
5466
5467    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
5468    it->dx = ev->canvas.x - x;
5469    it->dy = ev->canvas.y - y;
5470
5471    if (it->edit_long_timer)
5472      {
5473         ecore_timer_del(it->edit_long_timer);
5474         it->edit_long_timer = NULL;
5475      }
5476    if (it->realized)
5477       it->edit_long_timer = ecore_timer_add(0.3,_edit_long_press, it);
5478    else
5479       it->edit_long_timer = NULL;
5480 }
5481
5482 static void
5483 _reorder_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
5484 {
5485    Elm_Genlist_Item *it = data;
5486
5487    Item_Block *itb;
5488    EINA_INLIST_FOREACH(it->wd->blocks, itb)
5489      {
5490         itb->reoder_y = 0;              
5491      }
5492    if (it->edit_long_timer)
5493      {
5494         ecore_timer_del(it->edit_long_timer);
5495         it->edit_long_timer = NULL;
5496      }
5497
5498    it->down = 0;
5499    it->wd->reoder_moved = EINA_FALSE;
5500
5501    if (it->wd->ed->ec->selected)
5502       it->wd->ed->ec->selected(NULL, it, 1);
5503
5504    if (it->reordering && it->wd->ed->reorder_item)
5505      {
5506         it->wd->ed->reorder_item->reordering = 0;
5507         edje_object_signal_emit(it->wd->ed->reorder_item->edit_obj, "elm,action,item,reorder_end", "elm");
5508         elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
5509
5510         if ((!it->wd->ed->reorder_rel) || (!it->wd->ed->ec->move) ||
5511             (!it->wd->ed->ec->move(it->wd->obj, it->wd->ed->reorder_item, it->wd->ed->reorder_rel, EINA_TRUE)))
5512           {
5513              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);
5514              _move_edit_controls(it,it->wd->ed->reorder_item->scrl_x, it->wd->ed->reorder_item->scrl_y);
5515           }
5516         it->wd->ed->reorder_item = NULL;
5517         it->wd->ed->reorder_rel = NULL;
5518         return;
5519      }
5520 }
5521
5522 static void
5523 _reorder_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
5524 {
5525    Elm_Genlist_Item *it = data;
5526    Evas_Event_Mouse_Move *ev = event_info;
5527
5528    if ((it->dragging) && (it->down))
5529      {
5530         if (it->edit_long_timer)
5531           {
5532              ecore_timer_del(it->edit_long_timer);
5533              it->edit_long_timer = NULL;
5534           }
5535
5536         evas_object_smart_callback_call(it->wd->obj, "drag", it);
5537         //      return;
5538      }
5539
5540    Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
5541
5542    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
5543    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
5544    x = ev->cur.canvas.x - x;
5545    y = ev->cur.canvas.y - y;
5546    dx = x - it->dx;
5547    adx = dx;
5548    if (adx < 0) adx = -dx;
5549    dy = y - it->dy;
5550    ady = dy;
5551    if (ady < 0) ady = -dy;
5552    minw /= 2;
5553    minh /= 2;
5554    if ((adx > minw) || (ady > minh))
5555      {
5556         it->dragging = 1;
5557         if (it->edit_long_timer)
5558           {
5559              ecore_timer_del(it->edit_long_timer);
5560              it->edit_long_timer = NULL;
5561           }
5562      }
5563
5564    if (it->reordering && it->wd->ed->reorder_item)
5565      {
5566         int y = ev->cur.canvas.y - it->wd->ed->reorder_item->dy;
5567         evas_object_raise(it->wd->ed->reorder_item->base);
5568         evas_object_move(it->wd->ed->reorder_item->base, it->wd->ed->reorder_item->scrl_x+it->pad_left, y);
5569         evas_object_show(it->wd->ed->reorder_item->base);
5570         _move_edit_controls(it,it->wd->ed->reorder_item->scrl_x, y);
5571
5572         it->block->updateme = EINA_TRUE;
5573
5574         if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5575         it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
5576
5577         return;
5578      }
5579 }
5580
5581 static void
5582 _select_all_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
5583 {
5584    Item_Block *itb;
5585    Elm_Genlist_Item *select_all_it = data, *it;
5586    Eina_List *l;
5587    Widget_Data *wd = select_all_it->wd;
5588    if (!wd) return;
5589
5590    if (!wd->selct_all) 
5591       edje_object_signal_emit(select_all_it->base, "elm,state,del_confirm", "elm");
5592    else
5593       edje_object_signal_emit(select_all_it->base, "elm,state,del,animated,enable", "elm");
5594
5595    EINA_INLIST_FOREACH(wd->blocks, itb)
5596      {
5597         EINA_LIST_FOREACH(itb->items, l, it)
5598           {
5599              if (!wd->selct_all) 
5600                {
5601                   it->delete_check = 1;
5602                   it->del_confirm_state = 1;
5603                   edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm");
5604                }
5605              else 
5606                {
5607                   it->delete_check = 0;
5608                   it->del_confirm_state = 0;
5609                   edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm");
5610                }
5611           }
5612      }
5613    wd->selct_all ^= 0xFF;
5614
5615    if (wd->ed->ec->item_selected)
5616       wd->ed->ec->item_selected(select_all_it->data, select_all_it, wd->selct_all);
5617    if (wd->calc_job) ecore_job_del(wd->calc_job);
5618    wd->calc_job = ecore_job_add(_calc_job, wd); 
5619 }
5620
5621 static void
5622 _move_edit_controls(Elm_Genlist_Item *it, int itx, int ity)
5623 {
5624    if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
5625       return;
5626    evas_object_resize(it->edit_obj,it->w, it->h);
5627    evas_object_move(it->edit_obj, itx, ity);
5628    evas_object_raise(it->edit_obj);
5629 }
5630
5631 static void
5632 _edit_controls_eval(Elm_Genlist_Item *it)
5633 {
5634    int itmode = 0;
5635    const char *pad_str;
5636    int pad = 0;
5637    it->pad_left = 0;
5638    it->pad_right = 0;
5639    Evas_Object *icon;
5640    char buf[1024];
5641
5642    if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE && !it->edit_obj)
5643       return;
5644
5645    if (it->itc->func.editmode_get)
5646       itmode = it->itc->func.editmode_get(it->data, it->wd->obj, it->wd->edit_mode);
5647    itmode &= it->wd->edit_mode;
5648
5649    if (itmode & ELM_GENLIST_EDIT_MODE_SELECTALL)
5650       itmode |= ELM_GENLIST_EDIT_MODE_SELECT;
5651
5652    if (!it->edit_obj)
5653      {
5654         it->edit_obj = edje_object_add(evas_object_evas_get(it->wd->obj));
5655         edje_object_scale_set(it->edit_obj, elm_widget_scale_get(it->wd->obj) *
5656                               _elm_config->scale);
5657         evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart);
5658         elm_widget_sub_object_add(it->wd->obj, it->edit_obj);
5659         if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf));
5660         else strncpy(buf, "item", sizeof(buf));
5661         if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf));
5662         // if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
5663         strncat(buf, "/", sizeof(buf) - strlen(buf));
5664
5665         if (it->wd->ed->ec->item_style && strcmp(it->wd->ed->ec->item_style, "default")) 
5666           {
5667              strncat(buf, it->wd->ed->ec->item_style, sizeof(buf) - strlen(buf));
5668              _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", buf, elm_widget_style_get(it->wd->obj));
5669           }
5670         else
5671           {
5672              _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", "item/edit_control", elm_widget_style_get(it->wd->obj));
5673           }
5674
5675         //  edje_object_signal_callback_add(it->edit_obj, "elm,action,edit,reset",
5676         //        "elm", _edit_mode_reset, it);
5677      }
5678
5679    pad_str = edje_object_data_get(it->edit_obj, "icon_width");
5680    if (pad_str) pad = atoi(pad_str);
5681
5682    if ((itmode & ELM_GENLIST_EDIT_MODE_INSERT))
5683      {
5684         if (it->wd->animate_edit_controls)
5685            edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,enable", "elm");
5686         else
5687            edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm");
5688
5689         edje_object_signal_callback_add(it->edit_obj, "elm,action,item,insert",
5690                                         "elm", _insert_new_item_cb, it);
5691         it->pad_left += pad * _elm_config->scale;
5692      }
5693    else
5694      {
5695         if (it->wd->animate_edit_controls)
5696            edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,disable", "elm");
5697         else
5698            edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm");
5699
5700         edje_object_signal_callback_del(it->edit_obj, "elm,action,item,insert",
5701                                         "elm", _insert_new_item_cb);
5702      }
5703
5704    if ((itmode & ELM_GENLIST_EDIT_MODE_DELETE) || (itmode & ELM_GENLIST_EDIT_MODE_SELECT))
5705      {
5706         if (it->wd->animate_edit_controls)
5707            edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm");
5708         else
5709            edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm");
5710
5711         edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete",
5712                                         "elm", _remove_item_cb);
5713         edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm",
5714                                         "elm", _hide_delete_confirm_object);
5715
5716         edje_object_signal_callback_add(it->edit_obj, "elm,action,item,delete",
5717                                         "elm", _remove_item_cb, it);
5718
5719         edje_object_signal_callback_add(it->edit_obj, "elm,action,hide,del_confirm",
5720                                         "elm", _hide_delete_confirm_object, it);
5721         it->pad_left += pad * _elm_config->scale;
5722         evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5723                                        _reorder_mouse_down, it);
5724      }
5725    else
5726      {
5727         if (it->wd->animate_edit_controls)
5728            edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,disable", "elm");
5729         else
5730            edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm");
5731
5732         edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete",
5733                                         "elm", _remove_item_cb);
5734         edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm",
5735                                         "elm", _hide_delete_confirm_object);
5736         evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5737                                        _reorder_mouse_down);
5738      }
5739
5740    if ((itmode & ELM_GENLIST_EDIT_MODE_REORDER))
5741      {
5742         const char* reorder_part;
5743
5744         reorder_part = edje_object_data_get(it->edit_obj, "reorder");
5745         if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part))
5746           {
5747              edje_object_part_object_get(it->edit_obj, reorder_part);
5748
5749              evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5750                                             _reorder_mouse_down);
5751              evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
5752                                             _reorder_mouse_up);
5753              evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
5754                                             _reorder_mouse_move);
5755
5756              evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5757                                             _reorder_mouse_down, it);
5758              evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
5759                                             _reorder_mouse_up, it);
5760              evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
5761                                             _reorder_mouse_move, it);
5762           }
5763         //  it->pad_right += pad * _elm_config->scale;
5764      }
5765    else
5766      {
5767         const char* reorder_part;
5768
5769         reorder_part = edje_object_data_get(it->edit_obj, "reorder");
5770         if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part))
5771           {
5772
5773              if (itmode == ELM_GENLIST_EDIT_MODE_NONE) 
5774                {
5775                   evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5776                                                  _reorder_mouse_down);
5777                   evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
5778                                                  _reorder_mouse_up);
5779                   evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
5780                                                  _reorder_mouse_move);
5781                }
5782           }
5783      }
5784
5785    if (it->wd->edit_mode != 0xF0) {
5786         if (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE) 
5787           {
5788              if (it->itc->func.icon_get)
5789                {
5790                   edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,enable", "elm");
5791
5792                   const Eina_List *l;
5793                   const char *key;
5794
5795                   it->icons = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "icons"));
5796                   EINA_LIST_FOREACH(it->icons, l, key)
5797                     {
5798                        Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data);
5799
5800                        if (ic)
5801                          {
5802                             it->edit_icon_objs = eina_list_append(it->edit_icon_objs, ic);
5803                             edje_object_part_swallow(it->edit_obj, key, ic);
5804                             evas_object_show(ic);
5805                             //  elm_widget_sub_object_add(it->wd->obj, ic);
5806                          }
5807                     }
5808                }                
5809           }
5810         else 
5811           {
5812              edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm");
5813              EINA_LIST_FREE(it->edit_icon_objs, icon)
5814                 evas_object_del(icon);
5815
5816              Evas_Object *editfield;
5817              EINA_LIST_FREE(it->wd->edit_field, editfield)
5818                 evas_object_del(editfield);
5819           }
5820    }
5821
5822    if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)//Unrealize
5823      {
5824         evas_object_del(it->edit_obj);
5825         it->edit_obj = NULL;
5826         return;
5827      }
5828    _move_edit_controls(it,it->scrl_x, it->scrl_y);
5829    evas_object_show(it->edit_obj);
5830 }
5831
5832 static void
5833 _notify_item_position(Elm_Genlist_Item *it)
5834 {
5835    const Eina_List *l;
5836    if (it->parent)
5837      {
5838         l = eina_list_last(it->parent->items);
5839
5840         //Check if the Item is First Node or Last node of its Parent & raise signal.
5841         if (it->parent->items->data != it &&  l->data != it)
5842           {
5843              edje_object_signal_emit(it->base, "normal_item", "elm");
5844           } 
5845         else 
5846           {
5847              if (it->parent->items->data == it)
5848                 edje_object_signal_emit(it->base, "first_item", "elm");
5849
5850              if (l->data == it)
5851                 edje_object_signal_emit(it->base, "last_item", "elm");
5852           }
5853      }
5854 }
5855
5856 static int
5857 _get_space_for_reorder_item(Elm_Genlist_Item *it)
5858 {
5859    int top=0;
5860    Evas_Coord rox, roy, row, roh;
5861    if (!it->wd->ed) return 0;
5862    if (!(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER) || !it->wd->ed->reorder_item)
5863       return 0;
5864    evas_object_geometry_get(it->wd->ed->reorder_item->base, &rox, &roy, &row, &roh);
5865    top = (ELM_RECTS_INTERSECT(it->scrl_x, it->scrl_y, it->w, it->h,
5866                               rox, roy+roh/2, row, 1));
5867    if (top)
5868      {
5869         it->wd->ed->reorder_rel = it;
5870         it->scrl_y+=it->wd->ed->reorder_item->h;
5871         it->reorder_check = 1;
5872         return it->wd->ed->reorder_item->h;
5873      }
5874    return 0;
5875 }
5876
5877 /**
5878  * Add Group Item to the genlist
5879  *
5880  * @param obj The genlist object
5881  * @param itc The item class for the item
5882  * @param data The group item data
5883  */
5884 EAPI Elm_Genlist_GroupItem *
5885 elm_genlist_groupitem_add(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
5886                           const void *data)
5887 {
5888    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5889    Elm_Genlist_GroupItem *git;
5890    Widget_Data *wd = elm_widget_data_get(obj);
5891
5892    git = calloc(1, sizeof(Elm_Genlist_GroupItem));
5893    if (!git) return NULL;
5894    git->wd = wd;
5895    git->itc = itc;
5896    git->data = data;
5897
5898    wd->group_items = eina_inlist_append(wd->group_items, EINA_INLIST_GET(git));
5899    return git;
5900 }
5901
5902 /**
5903  * Delete a given groupitem
5904  *
5905  * This deletes the group item from genlist and calls the genlist group item del class
5906  * callback defined in the item class, if it is set.
5907  *
5908  * @param git The group item
5909  *
5910  * @ingroup Genlist
5911  */
5912 EAPI void
5913 elm_genlist_groupitem_del(Elm_Genlist_GroupItem *git)
5914 {
5915    _groupitem_remove(git, EINA_TRUE);
5916 }
5917
5918 /**
5919  * Append item to the end of the genlist with Group Item
5920  *
5921  * This appends the given item to the end of the list or the end of the
5922  * children if the parent is given.
5923  *
5924  * @param obj The genlist object
5925  * @param itc The item class for the item
5926  * @param data The item data
5927  * @param parent The parent item, or NULL if none
5928  * @param flags Item flags
5929  * @param git Group Item
5930  * @param func Convenience function called when item selected
5931  * @param func_data Data passed to @p func above.
5932  * @return A handle to the item added or NULL if not possible
5933  *
5934  * @ingroup Genlist
5935  */
5936 EAPI Elm_Genlist_Item *
5937 elm_genlist_item_append_with_group(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
5938                                    const void *data, Elm_Genlist_Item *parent,
5939                                    Elm_Genlist_Item_Flags flags, Elm_Genlist_GroupItem *git,
5940                                    Evas_Smart_Cb func, const void *func_data)
5941 {
5942    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5943    Widget_Data *wd = elm_widget_data_get(obj);
5944    parent = NULL;
5945    Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
5946    Elm_Genlist_GroupItem *pgit = NULL;
5947    Elm_Genlist_Item *it2 = NULL;
5948    Eina_List *ll = NULL;
5949    if (!wd) return NULL;
5950    if (!it) return NULL;
5951    if (!git) return NULL;
5952
5953    pgit = git;
5954    while (pgit)
5955      {
5956         ll = eina_list_last(pgit->items);
5957         if (ll) 
5958           {
5959              it2 = ll->data;
5960              break;
5961           }
5962         if (!(EINA_INLIST_GET(pgit)->prev)) break;
5963         pgit = (Elm_Genlist_GroupItem *)(EINA_INLIST_GET(pgit)->prev);
5964      }
5965    if (it2)
5966      {
5967         wd->items =
5968            eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
5969                                        EINA_INLIST_GET(it2));
5970         it->rel = it2;
5971         it->rel->relcount++;
5972      } 
5973    else 
5974      {
5975         wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
5976         it->rel = NULL;
5977      }
5978    git->items = eina_list_append(git->items, it);
5979    it->before = 0;
5980    it->group_item = git;
5981    _item_queue(wd, it);
5982    return it;
5983 }
5984
5985 /**
5986  * Prepend item at start of the genlist with Group Item
5987  *
5988  * This adds the given item to the beginning of the list or beginning of the
5989  * children if the parent is given.
5990  *
5991  * @param obj The genlist object
5992  * @param itc The item class for the item
5993  * @param data The item data
5994  * @param parent The parent item, or NULL if none
5995  * @param flags Item flags
5996  * @param git Group Item
5997  * @param func Convenience function called when item selected
5998  * @param func_data Data passed to @p func above.
5999  * @return A handle to the item added or NULL if not possible
6000  *
6001  * @ingroup Genlist
6002  */
6003 EAPI Elm_Genlist_Item *
6004 elm_genlist_item_prepend_with_group(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
6005                                     const void *data, Elm_Genlist_Item *parent,
6006                                     Elm_Genlist_Item_Flags flags, Elm_Genlist_GroupItem *git,
6007                                     Evas_Smart_Cb func, const void *func_data)
6008 {
6009    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6010    Widget_Data *wd = elm_widget_data_get(obj);
6011    parent = NULL;
6012    Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
6013    Elm_Genlist_GroupItem *pgit = NULL;
6014    Elm_Genlist_Item *it2 = NULL;
6015    Eina_List *ll = NULL;
6016    Eina_Bool new_group = EINA_FALSE;
6017    if (!wd) return NULL;
6018    if (!it) return NULL;
6019    if (!git) return NULL;
6020
6021    pgit = git;
6022    while (pgit)
6023      {
6024         if(new_group)
6025            ll = eina_list_last(pgit->items);
6026         else
6027            ll = pgit->items;
6028
6029         if (ll) 
6030           {
6031              it2 = ll->data;
6032              break;
6033           }
6034         if (!(EINA_INLIST_GET(pgit)->prev)) break;
6035         pgit = (Elm_Genlist_GroupItem *)(EINA_INLIST_GET(pgit)->prev);
6036         new_group = EINA_TRUE;
6037      }
6038    if (it2)
6039      {
6040         if(new_group)
6041            wd->items =
6042               eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
6043                                           EINA_INLIST_GET(it2));
6044         else        
6045            wd->items =
6046               eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
6047                                            EINA_INLIST_GET(it2));
6048         it->rel = it2;
6049         it->rel->relcount++;
6050      } 
6051    else 
6052      {
6053         wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
6054         it->rel = NULL;
6055      }
6056    git->items = eina_list_prepend(git->items, it);
6057    if(!new_group)
6058       it->before = 1;
6059    else
6060       it->before = 0;
6061
6062    it->group_item = git;
6063    _item_queue(wd, it);
6064    return it;
6065 }
6066
6067 /**
6068  * Moves the Genlist Item
6069  */
6070 EAPI void
6071 elm_genlist_item_move_after(Elm_Genlist_Item *it, Elm_Genlist_Item *after)
6072 {
6073    if (!it) return;
6074    if (!after) return;
6075
6076    Elm_Genlist_Item *next_item = elm_genlist_item_next_get(after);
6077
6078    if (it->y == after->y  &&  after->reorder_check && it->reorder_check)
6079      {
6080         if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6081         it->wd->calc_job = ecore_job_add(_calc_job, it->wd);    
6082         return;
6083      }
6084
6085    it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6086    _item_block_del(it);
6087
6088    if ((!next_item  && after->reorder_check) || (next_item && !after->reorder_check)) 
6089      {
6090
6091         if (next_item && !after->reorder_check  && it == after)
6092           {
6093              it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it),
6094                                                          EINA_INLIST_GET(next_item));
6095              it->rel = next_item;
6096           }
6097         else
6098           {
6099              it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it),
6100                                                          EINA_INLIST_GET(after));
6101              it->rel = after;
6102           }
6103
6104         it->rel->relcount++;
6105         it->before = 0;
6106      }
6107    else
6108      {
6109         if (after)
6110           {
6111              it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it),
6112                                                           EINA_INLIST_GET(after));
6113              it->rel = after;
6114              it->rel->relcount++;
6115           }
6116         else
6117           {
6118              it->wd->items = eina_inlist_prepend(it->wd->items, EINA_INLIST_GET(it));
6119           }
6120         it->before = 1;
6121      }
6122    after->reorder_check = 0;
6123    _item_queue(it->wd, it);
6124 }
6125
6126 EAPI void
6127 elm_genlist_set_edit_mode(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class)
6128 {
6129    fprintf(stderr, "=================> Caution!!! <========================\n");
6130    fprintf(stderr, "==> elm_genlist_set_edit_mode() is deprecated. <=======\n");
6131    fprintf(stderr, "==> Please use elm_genlist_edit_mode_set() instead. <==\n");
6132    fprintf(stderr, "=======================================================\n");
6133
6134    elm_genlist_edit_mode_set(obj, emode, edit_class);
6135 }
6136
6137 /**
6138  * Set Genlist edit mode
6139  *
6140  * This sets Genlist edit mode.
6141  *
6142  * @param obj The Genlist object
6143  * @param emode ELM_GENLIST_EDIT_MODE_{NONE & REORDER & INSERT & DELETE & SELECT & SELECT_ALL}
6144  * @param edit_class Genlist edit class (Elm_Genlist_Edit_Class structure)
6145  *
6146  * @ingroup Genlist
6147  */
6148 EAPI void
6149 elm_genlist_edit_mode_set(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class)
6150 {
6151    Elm_Genlist_Item *it;
6152    Eina_List *l;
6153    Item_Block *itb;
6154
6155    static Elm_Genlist_Item_Class itc;
6156
6157    ELM_CHECK_WIDTYPE(obj, widtype);
6158    Widget_Data *wd = elm_widget_data_get(obj);
6159    if (!wd) return;
6160    if (wd->edit_mode == emode) return;
6161
6162    wd->edit_mode = emode;
6163    wd->animate_edit_controls = 1;
6164
6165    if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
6166       wd->edit_mode |= ELM_GENLIST_EDIT_MODE_SELECT;
6167
6168    if (wd->edit_mode_effect_mode)
6169      {
6170         wd->effect_mode = EINA_TRUE;
6171         wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE;
6172      }
6173
6174    if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
6175      {
6176         if (wd->ed) free (wd->ed);
6177         wd->ed = NULL;
6178      }
6179    else
6180      {
6181         if (!wd->ed)
6182            wd->ed = calloc(1, sizeof(Edit_Data));
6183
6184         wd->ed->ec = edit_class;
6185
6186         if (((wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT)) && !wd->ed->del_confirm)
6187           {
6188              wd->ed->del_confirm = elm_button_add(wd->obj);
6189              elm_button_label_set(wd->ed->del_confirm, "Delete");
6190              evas_object_smart_member_add(wd->ed->del_confirm, wd->pan_smart);
6191              edje_object_scale_set(wd->ed->del_confirm, elm_widget_scale_get(wd->ed->del_confirm) *
6192                                    _elm_config->scale);
6193              evas_object_smart_callback_add(wd->ed->del_confirm, "clicked", _delete_confirm_cb, wd);
6194           }
6195      }
6196    EINA_INLIST_FOREACH(wd->blocks, itb)
6197      {
6198         EINA_LIST_FOREACH(itb->items, l, it)
6199           {
6200              it->delete_check = 0;
6201              it->del_confirm_state = 0;
6202              _item_unselect(it);
6203              _edit_controls_eval(it);
6204           }
6205      }
6206    if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
6207      {
6208         if (edit_class->select_all_item_style && strcmp(edit_class->select_all_item_style, "default"))
6209            itc.item_style = edit_class->select_all_item_style;
6210         else
6211            itc.item_style = "select_all";
6212         itc.func.label_get = NULL;
6213         itc.func.icon_get = NULL;
6214         itc.func.del = NULL;
6215         itc.func.editmode_get = NULL;
6216
6217         wd->select_all_item = _item_new(wd, &itc, (void *)(edit_class->select_all_data), NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
6218
6219         if (!wd) return;
6220         if (!wd->select_all_item) return;
6221
6222         _item_realize(wd->select_all_item, 0, 0);
6223         edje_object_signal_callback_add(wd->select_all_item->base, "elm,action,select,press", "elm", _select_all_down, wd->select_all_item);
6224
6225         wd->select_all_item->rel = NULL;
6226         wd->select_all_item->selected = 0;
6227         wd->select_all_item->before = 1;
6228         wd->select_all_item->block = NULL;
6229         wd->select_all_minh = wd->minh + wd->select_all_item->h;
6230      }
6231    else if (wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE)
6232      {
6233         if (wd->select_all_item)
6234           {
6235              if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item);
6236              free(wd->select_all_item);
6237           }
6238         wd->select_all_item = NULL;
6239      }
6240    edje_object_signal_emit(wd->scr, "elm,state,edit,animated,enable", "elm");
6241
6242    if (wd->calc_job) ecore_job_del(wd->calc_job);
6243    wd->calc_job = ecore_job_add(_calc_job, wd);
6244 }
6245
6246 /**
6247  * Delete selected items in genlist edit mode.
6248  *
6249  * @param obj The genlist object
6250  *
6251  * @ingroup Genlist
6252  */
6253 EAPI void
6254 elm_genlist_edit_selected_items_del(Evas_Object *obj)
6255 {
6256    Elm_Genlist_Item *it;
6257    Eina_List *l;
6258    Item_Block *itb = NULL;
6259    Evas_Object *icon;     
6260    ELM_CHECK_WIDTYPE(obj, widtype);
6261    Widget_Data *wd = elm_widget_data_get(obj);
6262    if (!wd) return;
6263    if (!wd->blocks) return;
6264
6265    EINA_INLIST_FOREACH(wd->blocks, itb)
6266      {
6267         if (!wd->blocks) break;
6268
6269         if (itb)
6270           {
6271              EINA_LIST_FOREACH(itb->items, l, it)
6272                {
6273                   if (it->delete_check) 
6274                     {
6275                        it->wd->effect_mode = EINA_TRUE;
6276
6277                        if (!wd->selct_all) 
6278                          {
6279                             itb->wd->minh -= it->h;
6280                             itb->wd->select_all_minh -= it->h;
6281                          }
6282
6283                        if ((it->relcount > 0) || (it->walking > 0))
6284                          {
6285                             elm_genlist_item_subitems_clear(it);
6286                             it->delete_me = EINA_TRUE;
6287                             if (it->wd->show_item == it) it->wd->show_item = NULL;
6288                             if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6289                             if (it->block)
6290                               {
6291                                  if (it->realized) _item_unrealize(it);
6292                                  it->block->changed = EINA_TRUE;
6293                               }
6294                             if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj);
6295                             return;
6296                          }
6297
6298                        it->wd->walking -= it->walking;
6299                        if (it->wd->show_item == it) it->wd->show_item = NULL;
6300                        if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6301                        if (it->realized) _item_unrealize(it);
6302
6303                        EINA_LIST_FREE(it->edit_icon_objs, icon)
6304                           evas_object_del(icon);
6305
6306                        Evas_Object *editfield;
6307                        EINA_LIST_FREE(it->wd->edit_field, editfield)
6308                           evas_object_del(editfield);
6309
6310                        evas_object_del(it->edit_obj);
6311                        it->edit_obj = NULL;      
6312
6313                        itb->items = eina_list_remove(itb->items, it);
6314                        itb->count--;
6315                        itb->changed = EINA_TRUE;
6316                        if ((!it->delete_me) && (it->itc->func.del))
6317                           it->itc->func.del(it->data, it->wd->obj);
6318                        it->delete_me = EINA_TRUE;
6319                        if (it->queued)
6320                           it->wd->queue = eina_list_remove(it->wd->queue, it);
6321                        it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6322                        if (it->parent)
6323                           it->parent->items = eina_list_remove(it->parent->items, it);
6324                        if (it->long_timer) ecore_timer_del(it->long_timer);
6325                        if (it->group_item)
6326                           it->group_item->items = eina_list_remove(it->group_item->items,it);
6327                        free(it);
6328                     }
6329                }
6330           }
6331      }
6332
6333    evas_render(evas_object_evas_get(wd->obj));
6334    if (wd->calc_job) ecore_job_del(wd->calc_job);
6335    wd->calc_job = ecore_job_add(_calc_job, wd); 
6336 }
6337
6338 EAPI void
6339 elm_genlist_selected_items_del(Evas_Object *obj)
6340 {
6341    fprintf(stderr, "=================> Caution!!! <========================\n");
6342    fprintf(stderr, "==> elm_genlist_selected_items_del() is deprecated. <=======\n");
6343    fprintf(stderr, "==> Please use elm_genlist_edit_selected_items_del() instead. <==\n");
6344    fprintf(stderr, "=======================================================\n");
6345    elm_genlist_edit_selected_items_del(obj);
6346 }
6347
6348 /**
6349  * Get a list of selected items in genlist
6350  *
6351  * This returns a list of the selected items in the genlist. The list
6352  * contains Elm_Genlist_Item pointers. The list must be freed by the
6353  * caller when done with eina_list_free(). The item pointers in the list
6354  * are only vallid so long as those items are not deleted or the genlist is
6355  * not deleted.
6356  *
6357  * @param obj The genlist object
6358  * @return The list of selected items, nor NULL if none are selected.
6359  *
6360  * @ingroup Genlist
6361  */
6362 EAPI Eina_List *
6363 elm_genlist_edit_selected_items_get(const Evas_Object *obj)
6364 {
6365    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6366    Widget_Data *wd = elm_widget_data_get(obj);
6367    Eina_List *list = NULL;
6368    Item_Block *itb;
6369    if (!wd) return NULL;
6370
6371    EINA_INLIST_FOREACH(wd->blocks, itb)
6372      {
6373         Eina_List *l;
6374         Elm_Genlist_Item *it;
6375
6376         EINA_LIST_FOREACH(itb->items, l, it)
6377           {
6378              if (it->delete_check) list = eina_list_append(list, it);
6379           }
6380
6381      }
6382    return list;
6383 }
6384
6385 /**
6386  * Set a given item's rename mode
6387  *
6388  * This renames the item's label from genlist 
6389  *
6390  * @param it The item
6391  * @param emode set if emode is EINA_TRUE, unset if emode is EINA_FALSE
6392  *
6393  * @ingroup Genlist
6394  */
6395 EAPI void
6396 elm_genlist_item_rename_mode_set(Elm_Genlist_Item *it, int emode)
6397 {
6398    if (!it) return;
6399
6400    const Eina_List *l, *list, *l2;
6401    const char *label, *rename_swallow_part;
6402    char *s;
6403    Eina_Bool done = EINA_FALSE;
6404    int label_cnt = 0 , swallow_part_cnt = 0;
6405
6406    Item_Block *itb;
6407    Evas_Object *editfield;
6408    Evas_Object *entry = NULL;
6409    int edit_field_cnt = 0;
6410    Evas_Object *icon;   
6411
6412    if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
6413      {
6414         it->wd->edit_mode = 0xF0;
6415         _edit_controls_eval(it);
6416      }
6417
6418    EINA_INLIST_FOREACH(it->wd->blocks, itb)
6419      {
6420         if (itb->realized)
6421           {
6422              Eina_List *l;
6423              Elm_Genlist_Item *it;
6424
6425              done = EINA_TRUE;
6426              EINA_LIST_FOREACH(itb->items, l, it)
6427                {
6428                   if (it->renamed)
6429                     {
6430                        it->renamed = EINA_FALSE;
6431
6432                        EINA_LIST_FOREACH(it->wd->edit_field, l2, editfield)
6433                          {
6434                             entry = elm_editfield_entry_get(editfield);
6435                             const char *text = elm_entry_entry_get(entry);
6436
6437                             if (it->itc->func.label_changed)
6438                                it->itc->func.label_changed(it->data, it, text, edit_field_cnt++);
6439                          }
6440                        Ecore_IMF_Context *imf = elm_entry_imf_context_get(entry);
6441                        ecore_imf_context_input_panel_hide(imf);
6442
6443                        Evas_Object *editfield;
6444                        EINA_LIST_FREE(it->wd->edit_field, editfield)
6445                           evas_object_del(editfield);
6446
6447                        if (it->wd->edit_mode)
6448                          {
6449                             if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_INSERT))
6450                                edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm");
6451
6452                             if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT))
6453                                edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm");
6454
6455                             if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER))
6456                                edje_object_signal_emit(it->edit_obj, "elm,state,rename,disable", "elm");                                  
6457                          }
6458                        if (it->edit_obj)
6459                          {
6460                             evas_object_del(it->edit_obj);
6461                             it->edit_obj = NULL;
6462                          }
6463                        EINA_LIST_FREE(it->edit_icon_objs, icon)
6464                           evas_object_del(icon);
6465                     }
6466                }
6467           }
6468         else
6469           {
6470              if (done) break;
6471           }
6472      }
6473
6474    //           if (emode != ELM_GENLIST_RENAME_MODE_NONE) 
6475    if (emode != 0) 
6476      {
6477         it->renamed = EINA_TRUE;
6478
6479         it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
6480         EINA_LIST_FOREACH(it->labels, list, label)
6481           {
6482              edje_object_signal_emit(it->edit_obj, "elm,state,rename,enable", "elm");
6483              edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm");
6484              edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm");
6485              edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm");
6486
6487              if (it->itc->func.label_get)
6488                {
6489                   it->renamed = EINA_TRUE;
6490                   swallow_part_cnt = 0;
6491
6492                   EINA_LIST_FREE(it->edit_icon_objs, icon)
6493                      evas_object_del(icon);
6494                   Eina_List *rename = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "rename"));
6495                   EINA_LIST_FOREACH(rename, l, rename_swallow_part)
6496                     {
6497                        if (label_cnt == swallow_part_cnt)
6498                          {
6499                             editfield = elm_editfield_add(it->wd->obj);
6500                             it->wd->edit_field = eina_list_append(it->wd->edit_field, editfield);
6501
6502                             elm_editfield_entry_single_line_set(editfield, EINA_TRUE);  
6503                             elm_editfield_eraser_set(editfield, EINA_TRUE);
6504                             edje_object_part_swallow(it->edit_obj, rename_swallow_part, editfield);
6505                             elm_widget_sub_object_add(it->edit_obj, editfield);
6506
6507                             evas_object_show(editfield);
6508
6509                             s = it->itc->func.label_get(it->data, it->wd->obj, list->data);
6510
6511                             if (s)
6512                               {
6513                                  Evas_Object *entry = elm_editfield_entry_get(editfield);
6514                                  elm_entry_entry_set(entry,s);
6515
6516                                  free(s);
6517                               }
6518                             else
6519                                elm_editfield_guide_text_set(editfield, "Text Input");
6520                          }
6521                        swallow_part_cnt++;
6522                     }
6523                   label_cnt++;
6524                }
6525           }                     
6526      }
6527
6528    if (it->wd->edit_mode == 0xF0)
6529      {
6530         it->wd->edit_mode = 0;
6531      }
6532 }