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