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