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