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