1 #include <Elementary.h>
3 #include "els_scroller.h"
6 #define MAX_ITEMS_PER_BLOCK 32
7 #define LONGPRESS_TIMEOUT 1.0
10 * @defgroup Genlist Genlist
13 * The Aim was to have more expansive list that the simple list in
14 * Elementary that could have more flexible items and allow many more entries
15 * while still being fast and low on memory usage. At the same time it was
16 * also made to be able to do tree structures. But the price to pay is more
17 * complexity when it comes to usage. If all you want is a simple list with
18 * icons and a single label, use the normal List object.
20 * Signals that you can add callbacks for are:
22 * clicked - This is called when a user has double-clicked an item. The
23 * event_info parameter is the genlist item that was double-clicked.
25 * selected - This is called when a user has made an item selected. The
26 * event_info parameter is the genlist item that was selected.
28 * unselected - This is called when a user has made an item unselected. The
29 * event_info parameter is the genlist item that was unselected.
31 * expanded - This is called when elm_genlist_item_expanded_set() is called
32 * and the item is now meant to be expanded. The event_info parameter is the
33 * genlist item that was indicated to expand. It is the job of this callback
34 * to then fill in the child items.
36 * contracted - This is called when elm_genlist_item_expanded_set() is called
37 * and the item is now meant to be contracted. The event_info parameter is
38 * the genlist item that was indicated to contract. It is the job of this
39 * callback to then delete the child items
41 * expand,request - This is called when a user has indicated they want to
42 * expand a tree branch item. The callback should decide if the item can
43 * expand (has any children) and then call elm_genlist_item_expanded_set()
44 * appropriately to set the state. The event_info parameter is the genlist
45 * item that was indicated to expand.
47 * contract,request - This is called when a user has indicated they want to
48 * contract a tree branch item. The callback should decide if the item can
49 * contract (has any children) and then call elm_genlist_item_expanded_set()
50 * appropriately to set the state. The event_info parameter is the genlist
51 * item that was indicated to contract.
53 * realized - This is called when the item in the list is created as a real
54 * evas object. event_info parameter is the genlist item that was created.
55 * The object may be deleted at any time, so it is up to the caller to
56 * not use the object pointer from elm_genlist_item_object_get() in a way
57 * where it may point to freed objects.
59 * unrealized - This is called just before an item is unrealized. After
60 * this call icon objects provideed will be deleted and the item object
61 * itself delete or be put into a floating cache.
63 * drag,start,up - This is called when the item in the list has been dragged
66 * drag,start,down - This is called when the item in the list has been dragged
67 * (not scrolled) down.
69 * drag,start,left - This is called when the item in the list has been dragged
70 * (not scrolled) left.
72 * drag,start,right - This is called when the item in the list has been dragged
73 * (not scrolled) right.
75 * drag,stop - This is called when the item in the list has stopped being
78 * drag - This is called when the item in the list is being dragged.
80 * longpressed - This is called when the item is pressed for a certain amount
81 * of time. By default it's 1 second.
83 * scroll,edge,top - This is called when the genlist is scrolled until the top
86 * scroll,edge,bottom - This is called when the genlist is scrolled until the
89 * scroll,edge,left - This is called when the genlist is scrolled until the
92 * scroll,edge,right - This is called when the genlist is scrolled until the
95 * Genlist has a fairly large API, mostly because it's relatively complex,
96 * trying to be both expansive, powerful and efficient. First we will begin
97 * an overview o the theory behind genlist.
99 * Evas tracks every object you create. Every time it processes an event
100 * (mouse move, down, up etc.) it needs to walk through objects and find out
101 * what event that affects. Even worse every time it renders display updates,
102 * in order to just calculate what to re-draw, it needs to walk through many
103 * many many objects. Thus, the more objects you keep active, the more
104 * overhead Evas has in just doing its work. It is advisable to keep your
105 * active objects to the minimum working set you need. Also remember that
106 * object creation and deletion carries an overhead, so there is a
107 * middle-ground, which is not easily determined. But don't keep massive lists
108 * of objects you can't see or use. Genlist does this with list objects. It
109 * creates and destroys them dynamically as you scroll around. It groups them
110 * into blocks so it can determine the visibility etc. of a whole block at
111 * once as opposed to having to walk the whole list. This 2-level list allows
112 * for very large numbers of items to be in the list (tests have used up to
113 * 2,000,000 items). Also genlist employs a queue for adding items. As items
114 * may be different sizes, every item added needs to be calculated as to its
115 * size and thus this presents a lot of overhead on populating the list, this
116 * genlist employs a queue. Any item added is queued and spooled off over
117 * time, actually appearing some time later, so if your list has many members
118 * you may find it takes a while for them to all appear, with your process
119 * consuming a lot of CPU while it is busy spooling.
121 * Genlist also implements a tree structure, but it does so with callbacks to
122 * the application, with the application filling in tree structures when
123 * requested (allowing for efficient building of a very deep tree that could
124 * even be used for file-management). See the above smart signal callbacks for
127 * An item in the genlist world can have 0 or more text labels (they can be
128 * regular text or textblock ??that's up to the style to determine), 0 or
129 * more icons (which are simply objects swallowed into the genlist item) and
130 * 0 or more boolean states that can be used for check, radio or other
131 * indicators by the edje theme style. An item may be one of several styles
132 * (Elementary provides 2 by default - ?
\9cdefault??and ?
\9cdouble_label?? but this
133 * can be extended by system or application custom themes/overlays/extensions).
135 * In order to implement the ability to add and delete items on the fly,
136 * Genlist implements a class/callback system where the application provides
137 * a structure with information about that type of item (genlist may contain
138 * multiple different items with different classes, states and styles).
139 * Genlist will call the functions in this struct (methods) when an item is
140 * ?
\9crealized??(that is created dynamically while scrolling). All objects will
141 * simply be deleted when no longer needed with evas_object_del(). The
142 * Elm_Genlist_Item_Class structure contains the following members:
144 * item_style - This is a constant string and simply defines the name of the
145 * item style. It must be specified and the default should be ?
\9cdefault??
147 * func.label_get - This function is called when an actual item object is
148 * created. The data parameter is the data parameter passed to
149 * elm_genlist_item_append() and related item creation functions. The obj
150 * parameter is the genlist object and the part parameter is the string name
151 * of the text part in the edje design that is listed as one of the possible
152 * labels that can be set. This function must return a strudup()'ed string as
153 * the caller will free() it when done.
155 * func.icon_get - This function is called when an actual item object is
156 * created. The data parameter is the data parameter passed to
157 * elm_genlist_item_append() and related item creation functions. The obj
158 * parameter is the genlist object and the part parameter is the string name
159 * of the icon part in the edje design that is listed as one of the possible
160 * icons that can be set. This must return NULL for no object or a valid
161 * object. The object will be deleted by genlist on shutdown or when the item
164 * func.state_get - This function is called when an actual item object is
165 * created. The data parameter is the data parameter passed to
166 * elm_genlist_item_append() and related item creation functions. The obj
167 * parameter is the genlist object and the part parameter is the string name
168 * of the state part in the edje design that is listed as one of the possible
169 * states that can be set. Return 0 for false or 1 for true. Genlist will
170 * emit a signal to the edje object with ?
\9celm,state,XXX,active???
\9celm??when
171 * true (the default is false), where XXX is the name of the part.
173 * func.del - This is called when elm_genlist_item_del() is called on an
174 * item, elm_genlist_clear() is called on the genlist, or
175 * elm_genlist_item_subitems_clear() is called to clear sub-items. This is
176 * intended for use when actual genlist items are deleted, so any backing
177 * data attached to the item (e.g. its data parameter on creation) can be
180 * Items can be added by several calls. All of them return a Elm_Genlist_Item
181 * handle that is an internal member inside the genlist. They all take a data
182 * parameter that is meant to be used for a handle to the applications
183 * internal data (eg the struct with the original item data). The parent
184 * parameter is the parent genlist item this belongs to if it is a tree, and
185 * NULL if there is no parent. The flags can be a bitmask of
186 * ELM_GENLIST_ITEM_NONE and ELM_GENLIST_ITEM_SUBITEMS. If
187 * ELM_GENLIST_ITEM_SUBITEMS is set then this item is displayed as a item
188 * that is able to expand and have child items. The func parameter is a
189 * convenience callback that is called when the item is selected and the data
190 * parameter will be the func_data parameter, obj be the genlist object and
191 * vent_info will be the genlist item.
193 * elm_genlist_item_append() appends an item to the end of the list, or if
194 * there is a parent, to the end of all the child items of the parent.
195 * elm_genlist_item_prepend() is the same but prepends to the beginning of
196 * the list or children list. elm_genlist_item_insert_before() inserts at
197 * item before another item and elm_genlist_item_insert_after() inserts after
198 * the indicated item.
200 * The application can clear the list with elm_genlist_clear() which deletes
201 * all the items in the list and elm_genlist_item_del() will delete a specific
202 * item. elm_genlist_item_subitems_clear() will clear all items that are
203 * children of the indicated parent item.
205 * If the application wants multiple items to be able to be selected,
206 * elm_genlist_multi_select_set() can enable this. If the list is
207 * single-selection only (the default), then elm_genlist_selected_item_get()
208 * will return the selected item, if any, or NULL I none is selected. If the
209 * list is multi-select then elm_genlist_selected_items_get() will return a
210 * list (that is only valid as long as no items are modified (added, deleted,
211 * selected or unselected).
213 * To help inspect list items you can jump to the item at the top of the list
214 * with elm_genlist_first_item_get() which will return the item pointer, and
215 * similarly elm_genlist_last_item_get() gets the item at the end of the list.
216 * elm_genlist_item_next_get() and elm_genlist_item_prev_get() get the next
217 * and previous items respectively relative to the indicated item. Using
218 * these calls you can walk the entire item list/tree. Note that as a tree
219 * the items are flattened in the list, so elm_genlist_item_parent_get() will
220 * let you know which item is the parent (and thus know how to skip them if
223 * There are also convenience functions. elm_genlist_item_genlist_get() will
224 * return the genlist object the item belongs to. elm_genlist_item_show()
225 * will make the scroller scroll to show that specific item so its visible.
226 * elm_genlist_item_data_get() returns the data pointer set by the item
227 * creation functions.
229 * If an item changes (state of boolean changes, label or icons change),
230 * then use elm_genlist_item_update() to have genlist update the item with
231 * the new state. Genlist will re-realize the item thus call the functions
232 * in the _Elm_Genlist_Item_Class for that item.
234 * To programmatically (un)select an item use elm_genlist_item_selected_set().
235 * To get its selected state use elm_genlist_item_selected_get(). Similarly
236 * to expand/contract and item and get its expanded state, use
237 * elm_genlist_item_expanded_set() and elm_genlist_item_expanded_get(). And
238 * again to make an item disabled (unable to be selected and appear
239 * differently) use elm_genlist_item_disabled_set() to set this and
240 * elm_genlist_item_disabled_get() to get the disabled state.
242 * In general to indicate how the genlist should expand items horizontally to
243 * fill the list area, use elm_genlist_horizontal_mode_set(). Valid modes are
244 * ELM_LIST_LIMIT and ELM_LIST_SCROLL . The default is ELM_LIST_SCROLL. This
245 * mode means that if items are too wide to fit, the scroller will scroll
246 * horizontally. Otherwise items are expanded to fill the width of the
247 * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded
248 * to the viewport width and limited to that size. This can be combined with
249 * a different style that uses edjes' ellipsis feature (cutting text off like
250 * this: ?
\9ctex...??.
252 * Items will only call their selection func and callback when first becoming
253 * selected. Any further clicks will do nothing, unless you enable always
254 * select with elm_genlist_always_select_mode_set(). This means even if
255 * selected, every click will make the selected callbacks be called.
256 * elm_genlist_no_select_mode_set() will turn off the ability to select
257 * items entirely and they will neither appear selected nor call selected
258 * callback functions.
260 * Remember that you can create new styles and add you own theme augmentation
261 * per application with elm_theme_extension_add(). If you absolutely must
262 * have a specific style that overrides any theme the user or system sets up
263 * you can use elm_theme_overlay_add() to add such a file.
266 typedef struct _Widget_Data Widget_Data;
267 typedef struct _Item_Block Item_Block;
268 typedef struct _Pan Pan;
269 typedef struct _Edit_Data Edit_Data;
271 typedef enum _Elm_Genlist_Item_Move_effect_Mode
273 ELM_GENLIST_ITEM_MOVE_EFFECT_NONE = 0,
274 ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND = (1 << 0),
275 ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT = (1 << 1),
276 ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE = (1 << 2),
277 } Elm_Genlist_Item_Move_effect_Mode;
279 typedef enum _Elm_Genlist_Item_Pinchzoom_effect_Mode
281 ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE = 0,
282 ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND = (1 << 0),
283 ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT = (1 << 1),
284 ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH = (1 << 2),
285 ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND_FINISH = (1 << 3),
286 } Elm_Genlist_Item_Pinchzoom_effect_Mode;
288 #define GROUP_ALIGN_NORTH 1
289 #define GROUP_ALIGN_WEST 2
293 Evas_Object *obj, *scr, *pan_smart;
294 Eina_Inlist *items, *blocks;
296 Evas_Coord pan_x, pan_y, minw, minh;
297 Ecore_Job *calc_job, *update_job;
298 Ecore_Idler *queue_idler;
299 Eina_List *queue, *selected;
300 Elm_Genlist_Item *show_item;
302 Eina_Bool on_hold : 1;
304 Eina_Bool always_select : 1;
305 Eina_Bool longpressed : 1;
306 Eina_Bool wasselected : 1;
307 Eina_Bool no_select : 1;
308 Eina_Bool bring_in : 1;
309 Eina_Bool compress : 1;
310 Eina_Bool homogeneous : 1;
311 Eina_Bool clear_me : 1;
315 int max_items_per_block;
316 double longpress_timeout;
317 Eina_Inlist *group_items;
318 Eina_List *menuopened;
321 Eina_Bool animate_edit_controls :1;
324 Evas_Coord td1_x, td1_y, tu1_x, tu1_y;
325 Evas_Coord td2_x, td2_y, tu2_x, tu2_y;
326 Evas_Coord d1_x, d1_y, d2_x, d2_y;
327 Evas_Coord acc_x1, acc_y1, acc_x2, acc_y2;
328 Evas_Coord prev_multi_x, prev_multi_y;
329 Eina_Bool multi_down : 1;
330 Eina_Bool multi_touch : 1;
331 Eina_List *edit_field;
332 Eina_Bool selct_all : 1;
333 Elm_Genlist_Item *select_all_item;
335 Eina_Bool effect_mode : 1;
336 Eina_Bool edit_mode_effect_mode : 1;
337 Eina_Bool pinch_zoom : 1;
338 Eina_Bool pinch_zoom_reserve : 1;
339 int move_effect_mode;
340 int pinchzoom_effect_mode;
343 Ecore_Animator *item_moving_effect_timer;
344 Evas_Object *alpha_bg;
345 Evas_Object *point_rect;
346 Elm_Genlist_Item *expand_item;
349 Evas_Coord start_y_pos;
351 Eina_Bool queue_exception : 1;
353 Eina_Bool reoder_moved : 1;
355 Eina_Bool group_items_moved : 1;
360 Elm_Genlist_Edit_Class *ec;
361 Elm_Genlist_Item *del_item;
362 Elm_Genlist_Item *reorder_item;
363 Elm_Genlist_Item *reorder_rel;
364 Evas_Object *del_confirm;
374 Evas_Coord x, y, w, h, minw, minh;
375 Eina_Bool want_unrealize : 1;
376 Eina_Bool realized : 1;
377 Eina_Bool changed : 1;
378 Eina_Bool updateme : 1;
379 Eina_Bool showme : 1;
383 struct _Elm_Genlist_Item
389 Evas_Coord x, y, w, h, minw, minh;
390 const Elm_Genlist_Item_Class *itc;
392 Elm_Genlist_Item *parent;
393 Elm_Genlist_Item_Flags flags;
399 Evas_Object *spacer, *base;
400 Eina_List *labels, *icons, *states, *icon_objs;
401 Ecore_Timer *long_timer;
402 Evas_Coord dx, dy, scrl_x, scrl_y;
403 Evas_Coord reoder_cavas_x, reoder_cavas_y;
405 Elm_Genlist_Item *rel;
410 Eina_Bool before : 1;
412 Eina_Bool want_unrealize : 1;
413 Eina_Bool realized : 1;
414 Eina_Bool selected : 1;
415 Eina_Bool hilighted : 1;
416 Eina_Bool expanded : 1;
417 Eina_Bool disabled : 1;
418 Eina_Bool display_only : 1;
419 Eina_Bool mincalcd : 1;
420 Eina_Bool queued : 1;
421 Eina_Bool showme : 1;
422 Eina_Bool delete_me : 1;
424 Eina_Bool dragging : 1;
425 Eina_Bool updateme : 1;
426 Eina_Bool delete_check : 1;
427 Eina_Bool del_confirm_state : 1;
428 Eina_Bool reordering : 1;
429 Eina_Bool menuopened : 1;
430 Eina_Bool select_all_item : 1;
431 Eina_Bool reorder_check: 1;
432 Eina_Bool renamed : 1;
434 int pad_left, pad_right;
436 Evas_Coord old_scrl_y;
437 Evas_Coord old_pad_left;
439 Eina_Bool effect_done : 1;
440 Elm_Genlist_GroupItem *group_item;
441 Evas_Object *edit_obj;
442 Eina_List *edit_icon_objs;
443 Ecore_Timer *edit_long_timer;
446 #define ELM_GENLIST_ITEM_FROM_INLIST(item) \
447 ((item) ? EINA_INLIST_CONTAINER_GET(item, Elm_Genlist_Item) : NULL)
451 Evas_Object_Smart_Clipped_Data __clipped_data;
455 struct _Elm_Genlist_GroupItem
460 Evas_Coord x, y, w, h, minw, minh;
461 const Elm_Genlist_Item_Class *itc;
469 Eina_List *labels, *icons, *states, *icon_objs;
471 Eina_Bool realized : 1;
472 Eina_Bool delete_me : 1;
473 Eina_Bool visible : 1;
474 Eina_Bool mincalcd : 1;
476 Evas_Coord old_y, finish_y;
479 Eina_Bool update_finish_y : 1;
482 static const char *widtype = NULL;
483 static void _del_hook(Evas_Object *obj);
484 static void _theme_hook(Evas_Object *obj);
485 //static void _show_region_hook(void *data, Evas_Object *obj);
486 static void _sizing_eval(Evas_Object *obj);
487 static void _item_unrealize(Elm_Genlist_Item *it);
488 static void _item_block_unrealize(Item_Block *itb);
489 static void _calc_job(void *data);
490 static void _groupitem_remove(Elm_Genlist_GroupItem *git, Eina_Bool update_items);
491 static void _groupitem_unrealize(Elm_Genlist_GroupItem *git);
492 static Eina_Bool _edit_mode_reset(Widget_Data *wd);
493 static void _edit_controls_eval(Elm_Genlist_Item *it);
494 static void _move_edit_controls(Elm_Genlist_Item *it, int itx, int ity);
495 static Eina_Bool _item_moving_effect_timer_cb(void *data);
496 static Eina_Bool _edit_mode_item_moving_effect_cb(void *data);
497 static int _item_flip_effect_show(void *data);
498 static void _elm_genlist_pinch_zoom_execute(Evas_Object *obj, Eina_Bool emode);
499 static void _delete_confirm_cb(void *data, Evas_Object *obj, void *event_info);
500 static void _select_all_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
501 static void _notify_item_position(Elm_Genlist_Item *it);
502 static void _notify_item_position(Elm_Genlist_Item *it);
503 static int _get_space_for_reorder_item(Elm_Genlist_Item *it);
505 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
508 _del_hook(Evas_Object *obj)
510 Widget_Data *wd = elm_widget_data_get(obj);
512 if (wd->calc_job) ecore_job_del(wd->calc_job);
513 if (wd->update_job) ecore_job_del(wd->update_job);
518 _del_pre_hook(Evas_Object *obj)
520 Widget_Data *wd = elm_widget_data_get(obj);
522 evas_object_del(wd->pan_smart);
523 wd->pan_smart = NULL;
524 elm_genlist_clear(obj);
528 _theme_hook(Evas_Object *obj)
530 Widget_Data *wd = elm_widget_data_get(obj);
532 Elm_Genlist_GroupItem *git;
534 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
535 // edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
536 EINA_INLIST_FOREACH(wd->group_items, git)
538 _groupitem_unrealize(git);
540 EINA_INLIST_FOREACH(wd->blocks, itb)
543 Elm_Genlist_Item *it;
545 if (itb->realized) _item_block_unrealize(itb);
546 EINA_LIST_FOREACH(itb->items, l, it)
547 it->mincalcd = EINA_FALSE;
549 itb->changed = EINA_TRUE;
551 if (wd->calc_job) ecore_job_del(wd->calc_job);
552 wd->calc_job = ecore_job_add(_calc_job, wd);
558 _show_region_hook(void *data, Evas_Object *obj)
560 Widget_Data *wd = elm_widget_data_get(data);
561 Evas_Coord x, y, w, h;
563 elm_widget_show_region_get(obj, &x, &y, &w, &h);
564 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
569 _sizing_eval(Evas_Object *obj)
571 Widget_Data *wd = elm_widget_data_get(obj);
572 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
574 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
575 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
577 if (wd->mode != ELM_LIST_LIMIT) minw = -1;
580 Evas_Coord vmw, vmh, vw, vh;
584 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
585 if ((minw > 0) && (vw < minw)) vw = minw;
586 else if ((maxw > 0) && (vw > maxw)) vw = maxw;
588 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
591 evas_object_size_hint_min_set(obj, minw, minh);
592 evas_object_size_hint_max_set(obj, maxw, maxh);
596 _item_hilight(Elm_Genlist_Item *it)
598 const char *selectraise;
600 if ((it->wd->no_select) || (it->delete_me) || (it->hilighted) || (it->disabled) ||
601 (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)) return;
603 edje_object_signal_emit(it->base, "elm,state,selected", "elm");
604 selectraise = edje_object_data_get(it->base, "selectraise");
605 if ((selectraise) && (!strcmp(selectraise, "on")))
607 evas_object_raise(it->base);
608 if (it->group_item && it->group_item->realized)
609 evas_object_raise(it->group_item->base);
611 it->hilighted = EINA_TRUE;
615 _item_block_del(Elm_Genlist_Item *it)
618 Item_Block *itb = it->block;
620 itb->items = eina_list_remove(itb->items, it);
622 itb->changed = EINA_TRUE;
623 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
624 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
627 il = EINA_INLIST_GET(itb);
628 Item_Block *itbn = (Item_Block *)(il->next);
630 it->parent->items = eina_list_remove(it->parent->items, it);
632 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
634 if (itbn) itbn->changed = EINA_TRUE;
638 if (itb->count < itb->wd->max_items_per_block/2)
640 il = EINA_INLIST_GET(itb);
641 Item_Block *itbp = (Item_Block *)(il->prev);
642 Item_Block *itbn = (Item_Block *)(il->next);
643 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
645 Elm_Genlist_Item *it2;
647 EINA_LIST_FREE(itb->items, it2)
650 itbp->items = eina_list_append(itbp->items, it2);
652 itbp->changed = EINA_TRUE;
654 it->wd->blocks = eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
657 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
661 Eina_List *last = eina_list_last(itb->items);
662 Elm_Genlist_Item *it2 = last->data;
665 itb->items = eina_list_remove_list(itb->items, last);
666 itbn->items = eina_list_prepend(itbn->items, it2);
668 itbn->changed = EINA_TRUE;
671 eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
679 _item_del(Elm_Genlist_Item *it)
681 elm_genlist_item_subitems_clear(it);
682 it->wd->walking -= it->walking;
683 if (it->wd->show_item == it) it->wd->show_item = NULL;
684 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
685 if (it->realized) _item_unrealize(it);
686 if (it->block) _item_block_del(it);
687 if ((!it->delete_me) && (it->itc->func.del))
688 it->itc->func.del(it->data, it->wd->obj);
689 it->delete_me = EINA_TRUE;
691 it->wd->queue = eina_list_remove(it->wd->queue, it);
692 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
694 it->parent->items = eina_list_remove(it->parent->items, it);
695 if (it->long_timer) ecore_timer_del(it->long_timer);
698 it->group_item->items = eina_list_remove(it->group_item->items,it);
704 _item_select(Elm_Genlist_Item *it)
706 if ((it->wd->no_select) || (it->delete_me) || (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)) return;
709 if (it->wd->always_select) goto call;
712 it->selected = EINA_TRUE;
713 it->wd->selected = eina_list_append(it->wd->selected, it);
717 if (it->func.func) it->func.func((void *)it->func.data, it->wd->obj, it);
719 evas_object_smart_callback_call(it->wd->obj, "selected", it);
722 if ((it->wd->clear_me) && (!it->wd->walking))
723 elm_genlist_clear(it->wd->obj);
726 if ((!it->walking) && (it->delete_me))
728 if (!it->relcount) _item_del(it);
734 _item_unselect(Elm_Genlist_Item *it)
736 const char *stacking, *selectraise;
738 if ((it->delete_me) || (!it->hilighted)) return;
740 edje_object_signal_emit(it->base, "elm,state,unselected", "elm");
741 stacking = edje_object_data_get(it->base, "stacking");
742 selectraise = edje_object_data_get(it->base, "selectraise");
743 if ((selectraise) && (!strcmp(selectraise, "on")))
745 if ((stacking) && (!strcmp(stacking, "below")))
746 evas_object_lower(it->base);
748 it->hilighted = EINA_FALSE;
751 it->selected = EINA_FALSE;
752 it->wd->selected = eina_list_remove(it->wd->selected, it);
753 evas_object_smart_callback_call(it->wd->obj, "unselected", it);
758 _item_slide(Elm_Genlist_Item *it, Eina_Bool slide_to_right)
761 Elm_Genlist_Item *it2;
762 const char *allow_slide;
764 allow_slide = edje_object_data_get(it->base, "allow_slide");
768 if (atoi(allow_slide) != 1)
774 edje_object_signal_emit(it->base, "elm,state,slide,right", "elm");
775 it->wd->menuopened = eina_list_append(it->wd->menuopened, it);
777 EINA_LIST_FOREACH(it->wd->menuopened, l, it2)
781 it2->menuopened = EINA_FALSE;
782 edje_object_signal_emit(it2->base, "elm,state,slide,left", "elm");
783 it2->wd->menuopened = eina_list_remove(it2->wd->menuopened, it2);
790 edje_object_signal_emit(it->base, "elm,state,slide,left", "elm");
791 it->wd->menuopened = eina_list_remove(it->wd->menuopened, it);
794 it->menuopened = slide_to_right;
798 _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
800 Elm_Genlist_Item *it = data;
801 Evas_Event_Mouse_Move *ev = event_info;
802 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
803 Evas_Coord acc_x, acc_y;
805 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
807 if (!it->wd->on_hold)
809 it->wd->on_hold = EINA_TRUE;
810 if (!it->wd->wasselected)
814 if ((it->dragging) && (it->down))
818 ecore_timer_del(it->long_timer);
819 it->long_timer = NULL;
821 evas_object_smart_callback_call(it->wd->obj, "drag", it);
824 if ((!it->down)/* || (it->wd->on_hold)*/ || (it->wd->longpressed))
828 ecore_timer_del(it->long_timer);
829 it->long_timer = NULL;
834 if (it->wd->multi_down)
836 acc_x = ev->prev.canvas.x - ev->cur.canvas.x;
838 it->wd->acc_x1 = it->wd->acc_x1 - acc_x;
840 it->wd->acc_x1 = it->wd->acc_x1 + acc_x;
842 acc_y = ev->prev.canvas.y - ev->cur.canvas.y;
844 it->wd->acc_y1 = it->wd->acc_y1 - acc_y;
846 it->wd->acc_y1 = it->wd->acc_y1 + acc_y;
851 if (!it->display_only)
852 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
853 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
854 x = ev->cur.canvas.x - x;
855 y = ev->cur.canvas.y - y;
858 if (adx < 0) adx = -dx;
861 if (ady < 0) ady = -dy;
864 if ((adx > minw) || (ady > minh))
869 ecore_timer_del(it->long_timer);
870 it->long_timer = NULL;
872 if (!it->wd->wasselected)
877 evas_object_smart_callback_call(it->wd->obj, "drag,start,up", it);
882 evas_object_smart_callback_call(it->wd->obj,
883 "drag,start,left", it);
888 evas_object_smart_callback_call(it->wd->obj,
889 "drag,start,right", it);
897 evas_object_smart_callback_call(it->wd->obj,
898 "drag,start,down", it);
903 evas_object_smart_callback_call(it->wd->obj,
904 "drag,start,left", it);
909 evas_object_smart_callback_call(it->wd->obj,
910 "drag,start,right", it);
919 _long_press(void *data)
921 Elm_Genlist_Item *it = data;
923 it->long_timer = NULL;
924 if ((it->disabled) || (it->dragging)) return ECORE_CALLBACK_CANCEL;
925 it->wd->longpressed = EINA_TRUE;
926 evas_object_smart_callback_call(it->wd->obj, "longpressed", it);
927 return ECORE_CALLBACK_CANCEL;
931 _edit_long_press(void *data)
933 Elm_Genlist_Item *it = data, *it_tmp;
935 static Eina_Bool contracted = EINA_FALSE;
939 it->edit_long_timer = NULL;
940 if ((it->disabled) || (it->dragging)) return 0;
942 EINA_INLIST_FOREACH(it->wd->blocks, itb)
944 EINA_LIST_FOREACH(itb->items, l, it_tmp)
946 if(!it_tmp->parent && elm_genlist_item_expanded_get(it_tmp))
948 elm_genlist_item_expanded_set(it_tmp, EINA_FALSE);
949 contracted = EINA_TRUE;
956 contracted = EINA_FALSE;
960 edje_object_signal_emit(it->edit_obj, "elm,action,item,reorder_start", "elm");
962 evas_object_geometry_get(it->base, &x, &y, NULL, NULL);
964 it->dx = it->reoder_cavas_x - x;
965 it->dy = it->reoder_cavas_y - y;
967 evas_object_raise(it->base);
968 evas_object_raise(it->edit_obj);
970 it->wd->ed->reorder_item = it;
971 it->wd->ed->reorder_item->reordering = 1;
972 it->wd->ed->reorder_rel = NULL;
973 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
974 it->wd->reoder_pan_y = it->wd->pan_y;
975 it->wd->reoder_moved = EINA_TRUE;
981 _multi_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
983 Elm_Genlist_Item *it = data;
984 Evas_Event_Multi_Down *ev = event_info;
985 Evas_Coord dx, dy, adx, ady;
989 ecore_timer_del(it->long_timer);
990 it->long_timer = NULL;
993 dx = it->wd->td1_x - ev->canvas.x;
995 if (adx < 0) adx = -dx;
996 dy = it->wd->td1_y - ev->canvas.y;
998 if (ady < 0) ady = -dy;
1000 if (adx < 60 && ady < 60)
1003 it->wd->multi_down = 1;
1004 it->wd->td2_x = ev->canvas.x;
1005 it->wd->td2_y = ev->canvas.y;
1007 if (it->wd->effect_mode && it->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
1009 evas_object_move(it->wd->point_rect, 2, (it->wd->td1_y + it->wd->td2_y) / 2);
1010 evas_object_raise(it->wd->point_rect);
1011 evas_object_show(it->wd->point_rect);
1013 fprintf(stderr, "\n MULTI_DOWN - BUTTON ID = %d, x= %d, y= %d\n", ev->device, it->wd->td2_x, it->wd->td2_y);
1018 _multi_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
1020 Elm_Genlist_Item *it = data;
1021 Evas_Event_Multi_Up *ev = event_info;
1022 Evas_Coord dy, uy, ady, auy;
1023 int multi_y_avg = 0;
1025 fprintf(stderr, "\n MULTI_UP - x= %d, y= %d down= %d multi_down= %d\n", ev->canvas.x, ev->canvas.y, it->down, it->wd->multi_down);
1027 if (!it->wd->multi_down)
1030 it->wd->multi_down = 0;
1031 it->wd->tu2_x = ev->canvas.x;
1032 it->wd->tu2_y = ev->canvas.y;
1033 it->wd->d2_x = ev->canvas.x - it->wd->td2_x;
1034 it->wd->d2_y = ev->canvas.y - it->wd->td2_y;
1036 evas_object_lower(it->wd->point_rect);
1037 evas_object_hide(it->wd->point_rect);
1041 it->wd->multi_touch = EINA_TRUE;
1045 fprintf(stderr, "CHECK d1_x= %d, d2_x= %d, d1_y= %d, d2_y= %d\n", it->wd->d1_x, it->wd->d2_x, it->wd->d1_y, it->wd->d2_y);
1047 if ((it->wd->d1_x > 180) && (it->wd->d2_x > 180))
1049 // Two finger : Left -> Right
1050 fprintf(stderr, "L->R acc_y1= %d, acc_y2= %d\n", it->wd->acc_y1, it->wd->acc_y2);
1051 if (it->wd->acc_y1 < 200 && it->wd->acc_y2 < 200)
1052 evas_object_smart_callback_call(it->wd->obj, "multi_touch,left,right", it);
1054 else if ((it->wd->d1_y > 180) && (it->wd->d2_y > 180))
1056 // Two finger : Top -> Bottom
1057 fprintf(stderr, "T->B acc_x1= %d, acc_x2= %d\n", it->wd->acc_x1, it->wd->acc_x2);
1058 if (it->wd->acc_x1 < 200 && it->wd->acc_x2 < 200)
1059 evas_object_smart_callback_call(it->wd->obj, "multi_touch,top,bottom", it);
1063 dy = it->wd->td1_y - it->wd->td2_y;
1069 uy = it->wd->tu1_y - it->wd->tu2_y;
1079 // Two finger : Pinch Out
1080 evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,out", it);
1082 if (it->wd->effect_mode == EINA_TRUE)
1083 _elm_genlist_pinch_zoom_execute(it->wd->obj, 1);
1090 // Two finger : Pinch In
1091 evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,in", it);
1093 if (it->wd->effect_mode == EINA_TRUE)
1095 multi_y_avg= (it->wd->td1_y + it->wd->td2_y) / 2;
1096 it->wd->pinch_it = (multi_y_avg / it->group_item->h + it->wd->contract_pan_y / it->group_item->h) - 2;
1097 fprintf(stderr," pinch,in!! it ================ it->y = %d it->old_y = %d it = %d it->wd->td1_y = %d it->wd->td2_y = %d pinch_it = %d it->wd->contract_pan_y = %d\n", it->y, it->old_scrl_y, it->old_scrl_y / 30, it->wd->td1_y, it->wd->td2_y, it->wd->pinch_it, it->wd->contract_pan_y);
1098 _elm_genlist_pinch_zoom_execute(it->wd->obj, 0);
1108 it->wd->prev_multi_x = 0;
1109 it->wd->prev_multi_y = 0;
1114 _multi_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
1116 Elm_Genlist_Item *it = data;
1117 Evas_Event_Multi_Move *ev = event_info;
1118 Evas_Coord acc_x, acc_y;
1120 if (!it->wd->prev_multi_x)
1122 it->wd->prev_multi_x = ev->cur.canvas.x;
1123 it->wd->prev_multi_y = ev->cur.canvas.y;
1127 acc_x = it->wd->prev_multi_x - ev->cur.canvas.x;
1129 it->wd->acc_x2 = it->wd->acc_x2 - acc_x;
1131 it->wd->acc_x2 = it->wd->acc_x2 + acc_x;
1133 acc_y = it->wd->prev_multi_y - ev->cur.canvas.y;
1135 it->wd->acc_y2 = it->wd->acc_y2 - acc_y;
1137 it->wd->acc_y2 = it->wd->acc_y2 + acc_y;
1139 it->wd->prev_multi_x = ev->cur.canvas.x;
1140 it->wd->prev_multi_y = ev->cur.canvas.y;
1144 _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
1146 Elm_Genlist_Item *it = data;
1147 Evas_Event_Mouse_Down *ev = event_info;
1150 it->wd->group_items_moved = EINA_FALSE;
1151 it->wd->td1_x = ev->canvas.x;
1152 it->wd->td1_y = ev->canvas.y;
1153 if (it->wd->effect_mode && it->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
1155 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_TRUE);
1159 if (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)
1160 (void)_edit_mode_reset(it->wd);
1161 if (ev->button != 1) return;
1162 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1164 it->wd->on_hold = EINA_TRUE;
1167 if (it->wd->edit_field && !it->renamed)
1168 elm_genlist_item_rename_mode_set(it, 0);
1172 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1173 it->dx = ev->canvas.x - x;
1174 it->dy = ev->canvas.y - y;
1175 it->wd->longpressed = EINA_FALSE;
1176 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1177 else it->wd->on_hold = EINA_FALSE;
1178 if (it->wd->on_hold) return;
1179 it->wd->wasselected = it->selected;
1181 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1182 evas_object_smart_callback_call(it->wd->obj, "clicked", it);
1183 if (it->long_timer) ecore_timer_del(it->long_timer);
1185 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press, it);
1187 it->long_timer = NULL;
1191 _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1193 Elm_Genlist_Item *it = data;
1194 Evas_Event_Mouse_Up *ev = event_info;
1195 Eina_Bool dragged = EINA_FALSE;
1196 Evas_Coord dy, uy, ady, auy;
1199 if (ev->button != 1) return;
1204 it->wd->tu1_x = ev->canvas.x;
1205 it->wd->tu1_y = ev->canvas.y;
1206 it->wd->d1_x = ev->canvas.x - it->wd->td1_x;
1207 it->wd->d1_y = ev->canvas.y - it->wd->td1_y;
1209 // evas_object_lower(it->wd->point_rect);
1210 // evas_object_hide(it->wd->point_rect);
1211 if (it->wd->effect_mode && it->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return;
1213 if (!it->wd->multi_down && it->wd->multi_touch == EINA_TRUE)
1215 if ((it->wd->d1_x > 180) && (it->wd->d2_x > 180))
1217 // Two finger : Left -> Right
1218 fprintf(stderr, "L->R acc_y1= %d, acc_y2= %d\n", it->wd->acc_y1, it->wd->acc_y2);
1219 if (it->wd->acc_y1 < 200 && it->wd->acc_y2 < 200)
1220 evas_object_smart_callback_call(it->wd->obj, "multi_touch,left,right", it);
1222 else if ((it->wd->d1_y > 180) && (it->wd->d2_y > 180))
1224 // Two finger : Top -> Bottom
1225 fprintf(stderr, "T->B acc_x1= %d, acc_x2= %d\n", it->wd->acc_x1, it->wd->acc_x2);
1226 if (it->wd->acc_x1 < 200 && it->wd->acc_x2 < 200)
1227 evas_object_smart_callback_call(it->wd->obj, "multi_touch,top,bottom", it);
1231 dy = it->wd->td1_y - it->wd->td2_y;
1232 if (dy < 0) ady = -dy;
1235 uy = it->wd->tu1_y - it->wd->tu2_y;
1236 if (uy < 0) auy = -uy;
1243 // Two finger : Pinch Out
1244 evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,out", it);
1245 if (it->wd->effect_mode == EINA_TRUE)
1246 _elm_genlist_pinch_zoom_execute(it->wd->obj, 1);
1253 // Two finger : Pinch In
1254 evas_object_smart_callback_call(it->wd->obj, "multi_touch,pinch,in", it);
1255 if (it->wd->effect_mode == EINA_TRUE)
1257 multi_y_avg= (it->wd->td1_y + it->wd->td2_y) / 2;
1258 it->wd->pinch_it = (multi_y_avg / it->group_item->h + it->wd->contract_pan_y / it->group_item->h) - 2;
1259 fprintf(stderr,"mouse up pinch,in!! it ================ it->y = %d it->old_y = %d it = %d it->wd->td1_y = %d it->wd->td2_y = %d pinch_it = %d it->wd->contract_pan_y = %d \n", it->y, it->old_scrl_y, it->old_scrl_y / 30, it->wd->td1_y, it->wd->td2_y, it->wd->pinch_it, it->wd->contract_pan_y);
1260 _elm_genlist_pinch_zoom_execute(it->wd->obj, 0);
1271 it->wd->prev_multi_x = 0;
1272 it->wd->prev_multi_y = 0;
1273 it->wd->multi_down = 0;
1276 it->wd->multi_touch = EINA_FALSE;
1278 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1279 else it->wd->on_hold = EINA_FALSE;
1282 ecore_timer_del(it->long_timer);
1283 it->long_timer = NULL;
1288 evas_object_smart_callback_call(it->wd->obj, "drag,stop", it);
1291 if (it->wd->on_hold)
1293 it->wd->longpressed = EINA_FALSE;
1294 it->wd->on_hold = EINA_FALSE;
1297 if (it->wd->longpressed)
1299 it->wd->longpressed = EINA_FALSE;
1300 if (!it->wd->wasselected)
1302 it->wd->wasselected = 0;
1307 if (it->want_unrealize)
1309 _item_unrealize(it);
1310 if (it->block->want_unrealize)
1311 _item_block_unrealize(it->block);
1314 if ((it->disabled) || (dragged)) return;
1315 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1318 if (!it->selected && !it->menuopened)
1323 else _item_unselect(it);
1329 Widget_Data *wd = it->wd;
1332 while (wd->selected) _item_unselect(wd->selected->data);
1337 const Eina_List *l, *l_next;
1338 Elm_Genlist_Item *it2;
1340 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1341 if (it2 != it) _item_unselect(it2);
1342 //_item_hilight(it);
1345 if (!it->menuopened)
1354 _signal_expand_toggle(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1356 Elm_Genlist_Item *it = data;
1359 evas_object_smart_callback_call(it->wd->obj, "contract,request", it);
1361 evas_object_smart_callback_call(it->wd->obj, "expand,request", it);
1365 _signal_expand(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1367 Elm_Genlist_Item *it = data;
1370 evas_object_smart_callback_call(it->wd->obj, "expand,request", it);
1374 _signal_contract(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1376 Elm_Genlist_Item *it = data;
1379 evas_object_smart_callback_call(it->wd->obj, "contract,request", it);
1383 _group_item_click_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1385 Elm_Genlist_GroupItem *git = data;
1386 elm_smart_scroller_bounce_allow_set(git->wd->scr, EINA_FALSE, EINA_TRUE);
1387 if (git->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
1389 if(!git->wd->group_items_moved)
1391 git->wd->pinch_it = git->num;
1392 _elm_genlist_pinch_zoom_execute(git->wd->obj, 0);
1394 git->wd->group_items_moved = EINA_FALSE;
1400 _groupitem_realize(Elm_Genlist_Item *it, int calc)
1404 Elm_Genlist_GroupItem *git = it->group_item;
1405 Evas_Coord ox, oy, ow, oh;
1407 if (calc && git->realized)
1409 git->wd->start_y_pos += it->h;
1412 if ((git->realized) || (git->delete_me)) return;
1413 git->base = edje_object_add(evas_object_evas_get(git->wd->obj));
1414 edje_object_scale_set(git->base, elm_widget_scale_get(git->wd->obj) *
1415 _elm_config->scale);
1416 evas_object_smart_member_add(git->base, git->wd->pan_smart);
1417 elm_widget_sub_object_add(git->wd->obj, git->base);
1419 strncpy(buf, "item/", sizeof(buf));
1420 strncat(buf, git->itc->item_style, sizeof(buf) - strlen(buf));
1421 _elm_theme_object_set(git->wd->obj, git->base, "genlist", buf, elm_widget_style_get(git->wd->obj));
1423 align = edje_object_data_get(git->base, "orientation");
1424 git->align = GROUP_ALIGN_NORTH;
1427 if (!strcmp(align, "top"))
1428 git->align = GROUP_ALIGN_NORTH;
1429 else if (!strcmp(align, "left"))
1430 git->align = GROUP_ALIGN_WEST;
1431 else git->align = GROUP_ALIGN_NORTH;
1434 if (git->itc->func.label_get)
1439 git->labels = _elm_stringlist_get(edje_object_data_get(git->base, "labels"));
1440 EINA_LIST_FOREACH(git->labels, l, key)
1442 char *s = git->itc->func.label_get(git->data, git->wd->obj, l->data);
1446 edje_object_part_text_set(git->base, l->data, s);
1452 if (git->itc->func.icon_get)
1457 git->icons = _elm_stringlist_get(edje_object_data_get(git->base, "icons"));
1458 EINA_LIST_FOREACH(git->icons, l, key)
1460 Evas_Object *ic = git->itc->func.icon_get(git->data, git->wd->obj, l->data);
1464 git->icon_objs = eina_list_append(git->icon_objs, ic);
1465 edje_object_part_swallow(git->base, key, ic);
1466 evas_object_show(ic);
1467 elm_widget_sub_object_add(git->wd->obj, ic);
1472 if (git->itc->func.state_get)
1477 git->states = _elm_stringlist_get(edje_object_data_get(git->base, "states"));
1478 EINA_LIST_FOREACH(git->states, l, key)
1480 Eina_Bool on = git->itc->func.state_get(git->data, git->wd->obj, l->data);
1484 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1485 edje_object_signal_emit(git->base, buf, "elm");
1491 Evas_Coord mw = -1, mh = -1;
1493 edje_object_size_min_restricted_calc(git->base, &mw, &mh, mw, mh);
1495 git->w = git->minw = mw;
1496 git->h = git->minh = mh;
1497 git->mincalcd = EINA_TRUE;
1499 evas_object_geometry_get(git->wd->pan_smart, &ox, &oy, &ow, &oh);
1502 git->update_finish_y = EINA_TRUE;
1504 git->y = git->finish_y = oy + git->wd->start_y_pos;
1505 git->wd->start_y_pos += it->h + git->h;
1507 git->num = ++git->wd->max_git_num;
1509 edje_object_signal_callback_add(git->base, "elm,title_action,item,click",
1510 "elm", _group_item_click_cb, git);
1511 evas_object_show(git->base);
1513 git->realized = EINA_TRUE;
1517 _groupitem_unrealize(Elm_Genlist_GroupItem *git)
1521 if (!git->realized) return;
1522 evas_object_del(git->base);
1524 _elm_stringlist_free(git->labels);
1526 _elm_stringlist_free(git->icons);
1528 _elm_stringlist_free(git->states);
1530 EINA_LIST_FREE(git->icon_objs, icon)
1531 evas_object_del(icon);
1533 if (git->wd->max_git_num)
1534 git->wd->max_git_num--;
1536 git->realized = EINA_FALSE;
1540 _groupitem_remove(Elm_Genlist_GroupItem *git, Eina_Bool update_items)
1542 Elm_Genlist_Item *it;
1548 _groupitem_unrealize(git);
1550 git->wd->group_items = eina_inlist_remove(git->wd->group_items,EINA_INLIST_GET(git));
1554 EINA_LIST_FOREACH(git->items,l, it)
1556 it->group_item = NULL;
1557 elm_genlist_item_update(it);
1561 if (git->itc->func.del) git->itc->func.del(git->data, git->wd->obj);
1566 _item_realize(Elm_Genlist_Item *it, int in, int calc)
1568 Elm_Genlist_Item *it2;
1569 const char *stacking;
1570 const char *treesize;
1572 int depth, tsize = 20;
1574 if ((it->realized) || (it->delete_me)) return;
1575 it->base = edje_object_add(evas_object_evas_get(it->wd->obj));
1576 edje_object_scale_set(it->base, elm_widget_scale_get(it->wd->obj) *
1577 _elm_config->scale);
1578 evas_object_smart_member_add(it->base, it->wd->pan_smart);
1579 elm_widget_sub_object_add(it->wd->obj, it->base);
1581 if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf));
1582 else strncpy(buf, "item", sizeof(buf));
1583 if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1585 if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
1586 strncat(buf, "/", sizeof(buf) - strlen(buf));
1587 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1589 _elm_theme_object_set(it->wd->obj, it->base, "genlist", buf, elm_widget_style_get(it->wd->obj));
1590 it->spacer = evas_object_rectangle_add(evas_object_evas_get(it->wd->obj));
1591 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1592 elm_widget_sub_object_add(it->wd->obj, it->spacer);
1593 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent) depth += 1;
1594 it->expanded_depth = depth;
1595 treesize = edje_object_data_get(it->base, "treesize");
1596 if (treesize) tsize = atoi(treesize);
1597 evas_object_size_hint_min_set(it->spacer,
1598 (depth * tsize) * _elm_config->scale, 1);
1599 edje_object_part_swallow(it->base, "elm.swallow.pad", it->spacer);
1602 edje_object_signal_callback_add(it->base, "elm,action,expand,toggle",
1603 "elm", _signal_expand_toggle, it);
1604 edje_object_signal_callback_add(it->base, "elm,action,expand", "elm",
1605 _signal_expand, it);
1606 edje_object_signal_callback_add(it->base, "elm,action,contract",
1607 "elm", _signal_contract, it);
1608 stacking = edje_object_data_get(it->base, "stacking");
1611 if (!strcmp(stacking, "below")) evas_object_lower(it->base);
1612 else if (!strcmp(stacking, "above")) evas_object_raise(it->base);
1614 evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN,
1616 evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP,
1618 evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_MOVE,
1620 evas_object_event_callback_add(it->base, EVAS_CALLBACK_MULTI_DOWN,
1622 evas_object_event_callback_add(it->base, EVAS_CALLBACK_MULTI_UP,
1624 evas_object_event_callback_add(it->base, EVAS_CALLBACK_MULTI_MOVE,
1626 if (it->selected && !it->menuopened)
1627 edje_object_signal_emit(it->base, "elm,state,selected", "elm");
1629 edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
1631 edje_object_signal_emit(it->base, "elm,state,expanded", "elm");
1634 if ((calc) && (it->wd->homogeneous) && (it->wd->item_width))
1636 /* homogenous genlist shortcut */
1639 it->w = it->minw = it->wd->item_width;
1640 it->h = it->minh = it->wd->item_height;
1641 it->mincalcd = EINA_TRUE;
1646 if (!strcmp(it->itc->item_style, "select_all"))
1651 it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
1652 EINA_LIST_FOREACH(it->labels, l, key) {
1653 edje_object_part_text_set(it->base, l->data, "Select all");
1657 if (it->itc->func.label_get)
1662 it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
1663 EINA_LIST_FOREACH(it->labels, l, key)
1665 char *s = it->itc->func.label_get
1666 ((void *)it->data, it->wd->obj, l->data);
1670 edje_object_part_text_set(it->base, l->data, s);
1674 edje_object_part_text_set(it->base, l->data, "");*/
1677 if (it->itc->func.icon_get)
1682 it->icons = _elm_stringlist_get(edje_object_data_get(it->base, "icons"));
1683 EINA_LIST_FOREACH(it->icons, l, key)
1685 Evas_Object *ic = it->itc->func.icon_get
1686 ((void *)it->data, it->wd->obj, l->data);
1690 it->icon_objs = eina_list_append(it->icon_objs, ic);
1691 edje_object_part_swallow(it->base, key, ic);
1692 evas_object_show(ic);
1693 elm_widget_sub_object_add(it->wd->obj, ic);
1697 if (it->itc->func.state_get)
1702 it->states = _elm_stringlist_get(edje_object_data_get(it->base, "states"));
1703 EINA_LIST_FOREACH(it->states, l, key)
1705 Eina_Bool on = it->itc->func.state_get
1706 (it->data, it->wd->obj, l->data);
1710 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1711 edje_object_signal_emit(it->base, buf, "elm");
1715 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1716 edje_object_signal_emit(it->base, buf, "elm");
1722 Evas_Coord mw = -1, mh = -1;
1724 if (!it->display_only)
1725 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1726 edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
1727 if (!it->display_only)
1728 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1729 it->w = it->minw = mw;
1730 it->h = it->minh = mh;
1731 it->mincalcd = EINA_TRUE;
1733 if ((!in) && (it->wd->homogeneous))
1735 it->wd->item_width = mw;
1736 it->wd->item_height = mh;
1739 if (!calc) evas_object_show(it->base);
1742 it->realized = EINA_TRUE;
1743 it->want_unrealize = EINA_FALSE;
1745 _groupitem_realize(it, calc);
1746 if (ELM_GENLIST_EDIT_MODE_NONE != it->wd->edit_mode)
1749 EINA_LIST_FREE(it->edit_icon_objs, icon)
1750 evas_object_del(icon);
1751 _edit_controls_eval(it);
1756 _item_unrealize(Elm_Genlist_Item *it)
1760 if (!it->realized) return;
1761 it->menuopened = EINA_FALSE;
1762 it->wd->menuopened = eina_list_remove(it->wd->menuopened, it);
1765 ecore_timer_del(it->long_timer);
1766 it->long_timer = NULL;
1768 evas_object_del(it->base);
1770 evas_object_del(it->spacer);
1773 evas_object_del(it->edit_obj);
1774 it->edit_obj = NULL;
1775 _elm_stringlist_free(it->labels);
1777 _elm_stringlist_free(it->icons);
1779 _elm_stringlist_free(it->states);
1781 EINA_LIST_FREE(it->icon_objs, icon)
1782 evas_object_del(icon);
1784 EINA_LIST_FREE(it->edit_icon_objs, icon)
1785 evas_object_del(icon);
1788 it->realized = EINA_FALSE;
1789 it->want_unrealize = EINA_FALSE;
1793 _item_block_recalc(Item_Block *itb, int in, int qadd, int norender)
1796 Elm_Genlist_Item *it;
1797 Evas_Coord minw = 0, minh = 0;
1798 int showme = 0, changed = 0;
1800 Elm_Genlist_GroupItem *git = NULL;
1803 EINA_LIST_FOREACH(itb->items, l, it)
1805 if (it->delete_me) continue;
1806 showme |= it->showme;
1811 if (!it->mincalcd) changed = 1;
1814 _item_realize(it, in, 1);
1815 _item_unrealize(it);
1820 _item_realize(it, in, 1);
1821 _item_unrealize(it);
1826 Eina_Bool was_realized = it->realized;
1828 _item_realize(it, in, 0);
1830 evas_object_smart_callback_call(it->wd->obj, "realized", it);
1833 if (minw < it->minw) minw = it->minw;
1838 if (git != it->group_item)
1840 git = it->group_item;
1842 if (git && git->align == GROUP_ALIGN_NORTH && git->items->data == it) //Add Place holder for Group title
1852 itb->changed = EINA_FALSE;
1853 /* force an evas norender to garbage collect deleted objects */
1854 if (norender) evas_norender(evas_object_evas_get(itb->wd->obj));
1859 _item_block_realize(Item_Block *itb, int in, int full)
1862 Elm_Genlist_Item *it;
1864 if (itb->realized) return;
1865 EINA_LIST_FOREACH(itb->items, l, it)
1867 if (it->delete_me) continue;
1870 Eina_Bool was_realized = it->realized;
1872 _item_realize(it, in, 0);
1874 evas_object_smart_callback_call(it->wd->obj, "realized", it);
1878 itb->realized = EINA_TRUE;
1879 itb->want_unrealize = EINA_FALSE;
1883 _item_block_unrealize(Item_Block *itb)
1886 Elm_Genlist_Item *it;
1889 if (!itb->realized) return;
1890 EINA_LIST_FOREACH(itb->items, l, it)
1892 if (it->dragging || it->reordering)
1895 it->want_unrealize = EINA_TRUE;
1898 _item_unrealize(it);
1902 itb->realized = EINA_FALSE;
1903 itb->want_unrealize = EINA_TRUE;
1906 itb->want_unrealize = EINA_FALSE;
1910 _item_block_position(Item_Block *itb, int in)
1913 Elm_Genlist_Item *it;
1914 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1917 Elm_Genlist_GroupItem *git = NULL;
1918 Elm_Genlist_Item *select_all_item = NULL;
1920 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
1921 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy, &cvw, &cvh);
1923 if (itb->wd->select_all_item &&
1924 (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL))
1927 select_all_item = itb->wd->select_all_item;
1929 evas_object_resize(select_all_item->base, itb->w, select_all_item->h);
1930 evas_object_move(select_all_item->base, ox, oy);
1931 evas_object_raise(select_all_item->base);
1933 if (itb->wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE)
1934 evas_object_show(select_all_item->base);
1936 evas_object_hide(select_all_item->base);
1937 y = select_all_item->h;
1940 EINA_LIST_FOREACH(itb->items, l, it)
1942 if (it->delete_me) continue;
1946 vis = (ELM_RECTS_INTERSECT(itb->x - it->wd->pan_x + ox,
1947 itb->y - it->wd->pan_y + oy,
1949 cvx, cvy, cvw, cvh));
1950 if ((itb->realized) && (!it->realized))
1954 Eina_Bool was_realized = it->realized;
1956 _item_realize(it, in, 0);
1958 evas_object_smart_callback_call(it->wd->obj,
1964 _notify_item_position(it);
1967 it->scrl_x = ox + itb->x + it->x - itb->wd->pan_x;
1968 it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y;;
1969 if (git != it->group_item)
1971 git = it->group_item;
1974 git->visible = EINA_TRUE; //Mark Group Item to make it visible
1975 if (git->items->data == it)
1976 git->y = it->scrl_y;
1977 if (GROUP_ALIGN_NORTH == git->align)
1980 if (git->items->data == it)
1982 it->scrl_y += git->minh;
1990 git->x = ox + itb->x - itb->wd->pan_x;
1995 if (git->align == GROUP_ALIGN_WEST)
1998 it->scrl_x += git->x + git->w;
1999 git->h = (it->scrl_y + it->h) - git->y ;
2002 git->y = it->scrl_y;
2006 if (git->align == GROUP_ALIGN_NORTH)
2009 if ((git->y + git->h) > (it->scrl_y + it->h))
2010 git->y = (it->scrl_y + it->h) - git->minh;
2012 if (git->update_finish_y)
2014 git->finish_y += oy;
2015 git->update_finish_y = EINA_FALSE;
2020 is_reorder = _get_space_for_reorder_item(it);
2024 if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && !itb->reoder_y)
2026 itb->reoder_y -= it->h;
2027 it->scrl_y = oy + itb->y + it->y - itb->wd->pan_y + itb->reoder_y;
2029 else if (it != it->wd->ed->reorder_item && is_reorder && in > 0 && !(in % it->wd->max_items_per_block) && itb->reoder_y)
2036 if (!it->reordering)
2038 if ((!it->wd->effect_mode ||
2039 (it->wd->effect_mode && it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_NONE)) && !it->wd->pinch_zoom_reserve)
2041 _move_edit_controls(it,it->scrl_x, it->scrl_y);
2042 evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h);
2044 evas_object_move(it->base, it->scrl_x+it->pad_left, it->scrl_y);
2046 if (it->delete_check)
2048 edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm");
2049 edje_object_signal_emit(it->base, "elm,state,del_confirm", "elm");
2051 evas_object_show(it->base);
2052 it->old_pad_left = it->pad_left;
2053 it->old_scrl_y = it->scrl_y;
2061 _item_unrealize(it);
2064 if (!it->reordering)
2070 if (itb->wd->select_all_item &&
2071 (itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT || itb->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL))
2072 evas_object_raise(select_all_item->base);
2076 itb->wd->animate_edit_controls = 0;
2078 git->visible = EINA_TRUE;
2083 _calc_job(void *data)
2085 Widget_Data *wd = data;
2087 Evas_Coord minw = -1, minh = 0, y = 0, ow;
2088 Item_Block *chb = NULL;
2089 int in = 0, minw_change = 0;
2093 EINA_INLIST_FOREACH(wd->blocks, itb)
2098 showme = itb->showme;
2102 if (itb->realized) _item_block_unrealize(itb);
2106 if (itb->realized) _item_block_unrealize(itb);
2107 showme = _item_block_recalc(itb, in, 0, 1);
2113 if (minw == -1) minw = itb->minw;
2114 else if (minw < itb->minw)
2123 if ((showme) && (wd->show_item) && (wd->show_item->mincalcd))
2125 wd->show_item->showme = 0;
2127 elm_smart_scroller_region_bring_in(wd->scr,
2128 wd->show_item->x + wd->show_item->block->x,
2129 wd->show_item->y + wd->show_item->block->y,
2130 wd->show_item->block->w,
2133 elm_smart_scroller_child_region_show(wd->scr,
2134 wd->show_item->x + wd->show_item->block->x,
2135 wd->show_item->y + wd->show_item->block->y,
2136 wd->show_item->block->w,
2138 wd->show_item = NULL;
2143 EINA_INLIST_FOREACH(wd->blocks, itb)
2149 if ((chb) && (EINA_INLIST_GET(chb)->next))
2151 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2153 if (itb->realized) _item_block_unrealize(itb);
2156 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
2157 if (minw < ow) minw = ow;
2158 if ((minw != wd->minw) || (minh != wd->minh) || wd->select_all_item)
2162 if (wd->select_all_item)
2163 wd->minh += wd->select_all_item->h;
2164 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2165 _sizing_eval(wd->obj);
2167 wd->calc_job = NULL;
2168 evas_object_smart_changed(wd->pan_smart);
2172 _update_job(void *data)
2174 Widget_Data *wd = data;
2177 int num, num0, position = 0, recalc = 0;
2179 wd->update_job = NULL;
2181 EINA_INLIST_FOREACH(wd->blocks, itb)
2183 Evas_Coord itminw, itminh;
2184 Elm_Genlist_Item *it;
2190 _item_block_position(itb, num);
2195 EINA_LIST_FOREACH(itb->items, l2, it)
2205 _item_unrealize(it);
2206 _item_realize(it, num, 0);
2207 evas_object_smart_callback_call(it->wd->obj,
2212 _item_realize(it, num, 1);
2213 _item_unrealize(it);
2215 if ((it->minw != itminw) || (it->minh != itminh))
2224 itb->changed = EINA_TRUE;
2225 _item_block_recalc(itb, num0, 0, 1);
2226 _item_block_position(itb, num0);
2231 if (wd->calc_job) ecore_job_del(wd->calc_job);
2232 wd->calc_job = ecore_job_add(_calc_job, wd);
2237 _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
2239 Pan *sd = evas_object_smart_data_get(obj);
2240 // Evas_Coord ow, oh;
2241 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2242 // ow = sd->wd->minw - ow;
2243 // if (ow < 0) ow = 0;
2244 // oh = sd->wd->minh - oh;
2245 // if (oh < 0) oh = 0;
2246 // if (x < 0) x = 0;
2247 // if (y < 0) y = 0;
2248 // if (x > ow) x = ow;
2249 // if (y > oh) y = oh;
2250 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2252 if(sd->wd->reoder_moved)
2255 if(sd->wd->pan_y >= sd->wd->minh)
2256 sd->wd->pan_y = sd->wd->minh;
2259 if(sd->wd->pan_y < y )
2260 sd->wd->pan_y = y + 5 + abs(sd->wd->reoder_pan_y - sd->wd->pan_y) / 100;
2262 sd->wd->pan_y = y - 5 - abs(sd->wd->reoder_pan_y - sd->wd->pan_y) / 100;
2270 evas_object_smart_changed(obj);
2274 _pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
2276 Pan *sd = evas_object_smart_data_get(obj);
2278 if (x) *x = sd->wd->pan_x;
2279 if (y) *y = sd->wd->pan_y;
2281 if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
2283 int git_cnt = 0, git_h = 0;
2284 Elm_Genlist_GroupItem *git;
2286 EINA_INLIST_FOREACH(sd->wd->group_items, git)
2292 if (sd->wd->minh != (git_h+1) * git_cnt)
2294 sd->wd->minh = (git_h+1) * git_cnt;
2301 _pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
2303 Pan *sd = evas_object_smart_data_get(obj);
2306 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2307 ow = sd->wd->minw - ow;
2309 oh = sd->wd->minh - oh;
2316 _pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
2318 Pan *sd = evas_object_smart_data_get(obj);
2320 if (w) *w = sd->wd->minw;
2321 if (h) *h = sd->wd->minh;
2325 _pan_add(Evas_Object *obj)
2328 Evas_Object_Smart_Clipped_Data *cd;
2331 cd = evas_object_smart_data_get(obj);
2334 sd->__clipped_data = *cd;
2336 evas_object_smart_data_set(obj, sd);
2340 _pan_del(Evas_Object *obj)
2342 Pan *sd = evas_object_smart_data_get(obj);
2349 _pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
2351 Pan *sd = evas_object_smart_data_get(obj);
2354 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2355 if ((ow == w) && (oh == h)) return;
2356 /* don't do this... use wd->compress mode
2357 if (sd->wd->mode == ELM_LIST_COMPRESS)
2360 // this is nasty - but no choice. have to mark all as not mincalced.
2361 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2364 Elm_Genlist_Item *it;
2366 EINA_LIST_FOREACH(itb->items, l, it)
2367 it->mincalcd = EINA_FALSE;
2369 itb->changed = EINA_TRUE;
2373 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2374 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2378 _pan_calculate(Evas_Object *obj)
2380 Pan *sd = evas_object_smart_data_get(obj);
2382 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2384 Elm_Genlist_GroupItem *git;
2386 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2387 if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND) return;
2390 if (sd->wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
2392 sd->wd->group_items_moved = EINA_TRUE;
2393 sd->wd->contract_pan_y = sd->wd->pan_y;
2394 EINA_INLIST_FOREACH(sd->wd->group_items, git)
2396 git->visible = EINA_TRUE;
2397 evas_object_raise(git->base);
2398 evas_object_resize(git->base, sd->wd->minw, git->h);
2399 evas_object_move(git->base, git->x, git->y + sd->wd->pan_y * -1);
2400 evas_object_show(git->base);
2404 if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return;
2406 if (sd->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)
2407 (void)_edit_mode_reset(sd->wd);
2408 EINA_INLIST_FOREACH(sd->wd->group_items, git)
2410 git->visible = EINA_FALSE;
2413 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2414 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2416 itb->w = sd->wd->minw;
2417 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2418 itb->y - sd->wd->pan_y + oy,
2420 cvx, cvy, cvw, cvh))
2422 if ((!itb->realized) || (itb->changed))
2423 _item_block_realize(itb, in, 0);
2424 _item_block_position(itb, in);
2428 if (itb->realized) _item_block_unrealize(itb);
2433 if (sd->wd->effect_mode &&
2434 (sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND || sd->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT))
2436 _item_flip_effect_show(sd->wd);
2437 sd->wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, sd->wd);
2440 if (sd->wd->effect_mode && sd->wd->edit_mode_effect_mode)
2441 sd->wd->item_moving_effect_timer = ecore_animator_add(_edit_mode_item_moving_effect_cb, sd->wd);
2443 EINA_INLIST_FOREACH(sd->wd->group_items, git)
2447 evas_object_raise(git->base);
2448 evas_object_resize(git->base, git->w, git->h - 1);
2449 evas_object_move(git->base, git->x, git->y);
2450 if (!sd->wd->pinch_zoom_reserve)
2451 evas_object_show(git->base);
2453 evas_object_hide(git->base);
2456 evas_object_hide(git->base);
2458 if ((sd->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER) && (sd->wd->ed->reorder_item))
2460 evas_object_raise(sd->wd->ed->reorder_item->base);
2461 evas_object_raise(sd->wd->ed->reorder_item->edit_obj);
2463 if (sd->wd->select_all_item)
2464 evas_object_raise(sd->wd->select_all_item->base);
2468 _pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
2470 Pan *sd = evas_object_smart_data_get(obj);
2472 if (sd->wd->effect_mode && sd->wd->multi_down) return;
2473 if (sd->wd->effect_mode && sd->wd->pinchzoom_effect_mode != ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE) return;
2475 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2476 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2480 _hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2482 Widget_Data *wd = elm_widget_data_get(obj);
2484 elm_smart_scroller_hold_set(wd->scr, 1);
2488 _hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2490 Widget_Data *wd = elm_widget_data_get(obj);
2492 elm_smart_scroller_hold_set(wd->scr, 0);
2496 _freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2498 Widget_Data *wd = elm_widget_data_get(obj);
2500 elm_smart_scroller_freeze_set(wd->scr, 1);
2504 _freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2506 Widget_Data *wd = elm_widget_data_get(obj);
2508 elm_smart_scroller_freeze_set(wd->scr, 0);
2512 _scroll_edge_left(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2514 Evas_Object *obj = data;
2515 evas_object_smart_callback_call(obj, "scroll,edge,left", NULL);
2519 _scroll_edge_right(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2521 Evas_Object *obj = data;
2522 evas_object_smart_callback_call(obj, "scroll,edge,right", NULL);
2526 _scroll_edge_top(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2528 Evas_Object *obj = data;
2529 evas_object_smart_callback_call(obj, "scroll,edge,top", NULL);
2533 _scroll_edge_bottom(void *data, Evas_Object *scr __UNUSED__, void *event_info __UNUSED__)
2535 Evas_Object *obj = data;
2536 evas_object_smart_callback_call(obj, "scroll,edge,bottom", NULL);
2540 * Add a new Genlist object
2542 * @param parent The parent object
2543 * @return The new object or NULL if it cannot be created
2548 elm_genlist_add(Evas_Object *parent)
2553 Evas_Coord minw, minh;
2554 static Evas_Smart *smart = NULL;
2556 if (!parent) return NULL;
2559 static Evas_Smart_Class sc;
2561 evas_object_smart_clipped_smart_set(&_pan_sc);
2563 sc.name = "elm_genlist_pan";
2564 sc.version = EVAS_SMART_CLASS_VERSION;
2567 sc.resize = _pan_resize;
2568 sc.move = _pan_move;
2569 sc.calculate = _pan_calculate;
2570 if (!(smart = evas_smart_class_new(&sc))) return NULL;
2572 wd = ELM_NEW(Widget_Data);
2573 e = evas_object_evas_get(parent);
2574 obj = elm_widget_add(e);
2575 ELM_SET_WIDTYPE(widtype, "genlist");
2576 elm_widget_type_set(obj, "genlist");
2577 elm_widget_sub_object_add(parent, obj);
2578 elm_widget_data_set(obj, wd);
2579 elm_widget_del_hook_set(obj, _del_hook);
2580 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
2581 elm_widget_theme_hook_set(obj, _theme_hook);
2583 wd->scr = elm_smart_scroller_add(e);
2584 elm_smart_scroller_widget_set(wd->scr, obj);
2585 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
2586 elm_widget_resize_object_set(obj, wd->scr);
2588 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
2590 evas_object_smart_callback_add(wd->scr, "edge,left", _scroll_edge_left, obj);
2591 evas_object_smart_callback_add(wd->scr, "edge,right", _scroll_edge_right, obj);
2592 evas_object_smart_callback_add(wd->scr, "edge,top", _scroll_edge_top, obj);
2593 evas_object_smart_callback_add(wd->scr, "edge,bottom", _scroll_edge_bottom, obj);
2596 wd->mode = ELM_LIST_SCROLL;
2597 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
2598 wd->max_items_per_block = 32;
2599 wd->longpress_timeout = LONGPRESS_TIMEOUT;
2600 wd->max_git_num = 0;
2602 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
2603 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
2604 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
2605 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
2607 wd->pan_smart = evas_object_smart_add(e, smart);
2608 wd->pan = evas_object_smart_data_get(wd->pan_smart);
2611 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
2613 _pan_max_get, _pan_child_size_get);
2615 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
2617 evas_object_size_hint_min_set(obj, minw, minh);
2623 static Elm_Genlist_Item *
2624 _item_new(Widget_Data *wd, const Elm_Genlist_Item_Class *itc,
2625 const void *data, Elm_Genlist_Item *parent,
2626 Elm_Genlist_Item_Flags flags,
2628 const void *func_data)
2630 Elm_Genlist_Item *it;
2632 it = calloc(1, sizeof(Elm_Genlist_Item));
2633 if (!it) return NULL;
2637 it->parent = parent;
2639 it->func.func = func;
2640 it->func.data = func_data;
2641 it->expanded_depth = 0;
2646 _item_block_add(Widget_Data *wd, Elm_Genlist_Item *it)
2648 Item_Block *itb = NULL;
2655 itb = calloc(1, sizeof(Item_Block));
2658 if (!it->rel->block)
2660 it->rel->block = itb;
2662 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
2663 itb->items = eina_list_append(itb->items, it);
2670 eina_inlist_prepend_relative(wd->blocks,
2671 EINA_INLIST_GET(itb),
2672 EINA_INLIST_GET(it->rel->block));
2674 eina_list_prepend_relative(itb->items, it, it->rel);
2679 eina_inlist_append_relative(wd->blocks,
2680 EINA_INLIST_GET(itb),
2681 EINA_INLIST_GET(it->rel->block));
2683 eina_list_append_relative(itb->items, it, it->rel);
2693 itb = (Item_Block *)(wd->blocks);
2694 if (itb->count >= wd->max_items_per_block)
2696 itb = calloc(1, sizeof(Item_Block));
2700 eina_inlist_prepend(wd->blocks,
2701 EINA_INLIST_GET(itb));
2706 itb = calloc(1, sizeof(Item_Block));
2710 eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
2712 itb->items = eina_list_prepend(itb->items, it);
2718 itb = (Item_Block *)(wd->blocks->last);
2719 if (itb->count >= wd->max_items_per_block)
2721 itb = calloc(1, sizeof(Item_Block));
2725 eina_inlist_append(wd->blocks,
2726 EINA_INLIST_GET(itb));
2731 itb = calloc(1, sizeof(Item_Block));
2735 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
2737 itb->items = eina_list_append(itb->items, it);
2743 itb = it->rel->block;
2744 if (!itb) goto newblock;
2746 itb->items = eina_list_prepend_relative(itb->items, it, it->rel);
2748 itb->items = eina_list_append_relative(itb->items, it, it->rel);
2751 itb->changed = EINA_TRUE;
2757 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
2758 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
2761 it->rel->relcount--;
2762 if ((it->rel->delete_me) && (!it->rel->relcount))
2766 if (itb->count > itb->wd->max_items_per_block)
2770 Elm_Genlist_Item *it2;
2772 newc = itb->count / 2;
2773 itb2 = calloc(1, sizeof(Item_Block));
2777 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
2778 EINA_INLIST_GET(itb));
2779 itb2->changed = EINA_TRUE;
2780 while ((itb->count > newc) && (itb->items))
2784 l = eina_list_last(itb->items);
2786 itb->items = eina_list_remove_list(itb->items, l);
2789 itb2->items = eina_list_prepend(itb2->items, it2);
2797 _queue_proecess(Widget_Data *wd, int norender)
2802 t0 = ecore_time_get();
2803 for (n = 0; (wd->queue) && (n < 128); n++)
2805 Elm_Genlist_Item *it;
2807 it = wd->queue->data;
2808 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
2809 it->queued = EINA_FALSE;
2810 _item_block_add(wd, it);
2811 t = ecore_time_get();
2812 if (it->block->changed)
2814 showme = _item_block_recalc(it->block, it->block->num, 1, norender);
2815 it->block->changed = 0;
2817 if (showme) it->block->showme = 1;
2818 if (eina_inlist_count(wd->blocks) > 1)
2820 if ((t - t0) > (ecore_animator_frametime_get())) break;
2827 _item_idler(void *data)
2829 Widget_Data *wd = data;
2832 //static double q_start = 0.0;
2833 //if (q_start == 0.0) q_start = ecore_time_get();
2836 if (_queue_proecess(wd, 1) > 0)
2838 if (wd->calc_job) ecore_job_del(wd->calc_job);
2839 wd->calc_job = ecore_job_add(_calc_job, wd);
2844 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
2846 wd->queue_idler = NULL;
2847 if (wd->pinch_zoom_reserve)
2848 _elm_genlist_pinch_zoom_execute(wd->obj, 1);
2849 return ECORE_CALLBACK_CANCEL;
2851 return ECORE_CALLBACK_RENEW;
2855 _item_queue(Widget_Data *wd, Elm_Genlist_Item *it)
2857 if (!wd->queue_exception)
2859 if (it->queued) return;
2860 wd->queue = eina_list_append(wd->queue, it);
2861 it->queued = EINA_TRUE;
2864 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
2866 if (wd->queue_idler)
2868 ecore_idler_del(wd->queue_idler);
2869 wd->queue_idler = NULL;
2871 _queue_proecess(wd, 0);
2873 if (!wd->queue_idler) wd->queue_idler = ecore_idler_add(_item_idler, wd);
2874 if (wd->queue_exception)
2876 wd->queue = eina_list_append(wd->queue, it);
2877 it->queued = EINA_TRUE;
2882 * Append item to the end of the genlist
2884 * This appends the given item to the end of the list or the end of the
2885 * children if the parent is given.
2887 * @param obj The genlist object
2888 * @param itc The item class for the item
2889 * @param data The item data
2890 * @param parent The parent item, or NULL if none
2891 * @param flags Item flags
2892 * @param func Convenience function called when item selected
2893 * @param func_data Data passed to @p func above.
2894 * @return A handle to the item added or NULL if not possible
2898 EAPI Elm_Genlist_Item *
2899 elm_genlist_item_append(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
2900 const void *data, Elm_Genlist_Item *parent,
2901 Elm_Genlist_Item_Flags flags,
2902 Evas_Smart_Cb func, const void *func_data)
2904 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2905 Widget_Data *wd = elm_widget_data_get(obj);
2906 Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
2907 if (!wd) return NULL;
2908 if (!it) return NULL;
2911 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
2917 Elm_Genlist_Item *it2 = NULL;
2918 Eina_List *ll = eina_list_last(it->parent->items);
2919 if (ll) it2 = ll->data;
2920 it->parent->items = eina_list_append(it->parent->items, it);
2921 if (!it2) it2 = it->parent;
2923 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
2924 EINA_INLIST_GET(it2));
2926 it->rel->relcount++;
2929 _item_queue(wd, it);
2934 * Prepend item at start of the genlist
2936 * This adds an item to the beginning of the list or beginning of the children
2937 * of the parent if given.
2939 * @param obj The genlist object
2940 * @param itc The item class for the item
2941 * @param data The item data
2942 * @param parent The parent item, or NULL if none
2943 * @param flags Item flags
2944 * @param func Convenience function called when item selected
2945 * @param func_data Data passed to @p func above.
2946 * @return A handle to the item added or NULL if not possible
2950 EAPI Elm_Genlist_Item *
2951 elm_genlist_item_prepend(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
2952 const void *data, Elm_Genlist_Item *parent,
2953 Elm_Genlist_Item_Flags flags,
2954 Evas_Smart_Cb func, const void *func_data)
2956 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2957 Widget_Data *wd = elm_widget_data_get(obj);
2958 Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
2959 if (!wd) return NULL;
2960 if (!it) return NULL;
2962 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
2965 printf("FIXME: 12 tree not handled yet\n");
2969 _item_queue(wd, it);
2974 * Insert item before another in the genlist
2976 * This inserts an item before another in the list. It will be in the same tree
2977 * level as the item it is inseted before.
2979 * @param obj The genlist object
2980 * @param itc The item class for the item
2981 * @param data The item data
2982 * @param before The item to insert before
2983 * @param flags Item flags
2984 * @param func Convenience function called when item selected
2985 * @param func_data Data passed to @p func above.
2986 * @return A handle to the item added or NULL if not possible
2990 EAPI Elm_Genlist_Item *
2991 elm_genlist_item_insert_before(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
2992 const void *data, Elm_Genlist_Item *before,
2993 Elm_Genlist_Item_Flags flags,
2994 Evas_Smart_Cb func, const void *func_data)
2996 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2997 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
2998 Widget_Data *wd = elm_widget_data_get(obj);
2999 Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data);
3000 if (!wd) return NULL;
3001 if (!it) return NULL;
3003 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3004 EINA_INLIST_GET(before));
3007 printf("FIXME: 13 tree not handled yet\n");
3010 it->rel->relcount++;
3012 _item_queue(wd, it);
3017 * Insert and item after another in the genlst
3019 * This inserts an item after another in the list. It will be in the same tree
3020 * level as the item it is inseted after.
3022 * @param obj The genlist object
3023 * @param itc The item class for the item
3024 * @param data The item data
3025 * @param after The item to insert after
3026 * @param flags Item flags
3027 * @param func Convenience function called when item selected
3028 * @param func_data Data passed to @p func above.
3029 * @return A handle to the item added or NULL if not possible
3033 EAPI Elm_Genlist_Item *
3034 elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
3035 const void *data, Elm_Genlist_Item *after,
3036 Elm_Genlist_Item_Flags flags,
3037 Evas_Smart_Cb func, const void *func_data)
3039 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3040 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3041 Widget_Data *wd = elm_widget_data_get(obj);
3042 Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data);
3043 if (!wd) return NULL;
3044 if (!it) return NULL;
3046 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3047 EINA_INLIST_GET(after));
3050 printf("FIXME: 14 tree not handled yet\n");
3053 it->rel->relcount++;
3055 _item_queue(wd, it);
3062 * This clears all items in the list, leaving it empty.
3064 * @param obj The genlist object
3069 elm_genlist_clear(Evas_Object *obj)
3071 ELM_CHECK_WIDTYPE(obj, widtype);
3072 Widget_Data *wd = elm_widget_data_get(obj);
3075 wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
3076 wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE;
3077 elm_smart_scroller_hold_set(wd->scr, 0);
3078 elm_smart_scroller_freeze_set(wd->scr, 0);
3079 elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0);
3080 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
3081 wd->max_git_num = 0;
3082 wd->pinch_zoom_reserve = EINA_FALSE;
3084 if (wd->item_moving_effect_timer)
3086 // ecore_timer_del(wd->item_moving_effect_timer);
3087 wd->item_moving_effect_timer = NULL;
3090 while (wd->group_items)
3092 _groupitem_remove((Elm_Genlist_GroupItem *)wd->group_items, EINA_FALSE);
3095 if (wd->walking > 0)
3097 Elm_Genlist_Item *it;
3100 EINA_INLIST_FOREACH(wd->items, it)
3109 Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items);
3111 wd->items = eina_inlist_remove(wd->items, wd->items);
3112 if (it->realized) _item_unrealize(it);
3113 if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj);
3114 if (it->long_timer) ecore_timer_del(it->long_timer);
3119 Item_Block *itb = (Item_Block *)(wd->blocks);
3121 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
3122 if (itb->items) eina_list_free(itb->items);
3127 ecore_job_del(wd->calc_job);
3128 wd->calc_job = NULL;
3130 if (wd->queue_idler)
3132 ecore_idler_del(wd->queue_idler);
3133 wd->queue_idler = NULL;
3137 eina_list_free(wd->queue);
3142 eina_list_free(wd->selected);
3143 wd->selected = NULL;
3145 wd->show_item = NULL;
3152 evas_object_del(wd->alpha_bg);
3153 wd->alpha_bg = NULL;
3157 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3158 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3164 * Enable or disable multi-select in the genlist
3166 * This enables (EINA_TRUE) or disableds (EINA_FALSE) multi-select in the list. This allows
3167 * more than 1 item to be selected.
3169 * @param obj The genlist object
3170 * @param multi Multi-select enable/disable
3175 elm_genlist_multi_select_set(Evas_Object *obj, Eina_Bool multi)
3177 ELM_CHECK_WIDTYPE(obj, widtype);
3178 Widget_Data *wd = elm_widget_data_get(obj);
3184 * Gets if multi-select in genlist is enable or disable
3186 * @param obj The genlist object
3187 * @return Multi-select enable/disable
3188 * (EINA_TRUE = enabled/EINA_FALSE = disabled)
3193 elm_genlist_multi_select_get(const Evas_Object *obj)
3195 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3196 Widget_Data *wd = elm_widget_data_get(obj);
3197 if (!wd) return EINA_FALSE;
3203 * Get the selectd item in the genlist
3205 * This gets the selected item in the list (if multi-select is enabled only
3206 * the first item in the list is selected - which is not very useful, so see
3207 * elm_genlist_selected_items_get()for when multi-select is used).
3209 * If no item is selected, NULL is returned.
3211 * @param obj The genlist object
3212 * @return The selected item, or NULL if none.
3216 EAPI Elm_Genlist_Item *
3217 elm_genlist_selected_item_get(const Evas_Object *obj)
3219 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3220 Widget_Data *wd = elm_widget_data_get(obj);
3221 if (!wd) return NULL;
3222 if (wd->selected) return wd->selected->data;
3227 * Get a list of selected items in the genlist
3229 * This retgurns a list of the selected items. This list pointer is only valid
3230 * so long as no items are selected or unselected (or unselected implicitly
3231 * by deletion). The list contains Elm_Genlist_Item pointers.
3233 * @param obj The genlist object
3234 * @return The list of selected items, nor NULL if none are selected.
3238 EAPI const Eina_List *
3239 elm_genlist_selected_items_get(const Evas_Object *obj)
3241 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3242 Widget_Data *wd = elm_widget_data_get(obj);
3243 if (!wd) return NULL;
3244 return wd->selected;
3248 * Get a list of realized items in genlist
3250 * This returns a list of the realized items in the genlist. The list
3251 * contains Elm_Genlist_Item pointers. The list must be freed by the
3252 * caller when done with eina_list_free(). The item pointers in the list
3253 * are only vallid so long as those items are not deleted or the genlist is
3256 * @param obj The genlist object
3257 * @return The list of realized items, nor NULL if none are realized.
3262 elm_genlist_realized_items_get(const Evas_Object *obj)
3264 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3265 Widget_Data *wd = elm_widget_data_get(obj);
3266 Eina_List *list = NULL;
3268 Eina_Bool done = EINA_FALSE;
3269 if (!wd) return NULL;
3270 EINA_INLIST_FOREACH(wd->blocks, itb)
3275 Elm_Genlist_Item *it;
3278 EINA_LIST_FOREACH(itb->items, l, it)
3280 if (it->realized) list = eina_list_append(list, it);
3292 * Get the item that is at the x, y canvas coords
3294 * This returns the item at the given coordinates (which are canvas relative
3295 * not object-relative). If an item is at that coordinate, that item handle
3296 * is returned, and if @p posret is not NULL, the integer pointed to is set
3297 * to a value of -1, 0 or 1, depending if the coordinate is on the upper
3298 * portion of that item (-1), on the middle section (0) or on the lower part
3299 * (1). If NULL is returned as an item (no item found there), then posret
3300 * may indicate -1 or 1 based if the coordinate is above or below all items
3301 * respectively in the genlist.
3303 * @param it The item
3304 * @param x The input x coordinate
3305 * @param y The input y coordinate
3306 * @param posret The position relative to the item returned here
3307 * @return The item at the coordinates or NULL if none
3311 EAPI Elm_Genlist_Item *
3312 elm_genlist_at_xy_item_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *posret)
3314 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3315 Widget_Data *wd = elm_widget_data_get(obj);
3316 Evas_Coord ox, oy, ow, oh;
3319 if (!wd) return NULL;
3320 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
3322 EINA_INLIST_FOREACH(wd->blocks, itb)
3325 Elm_Genlist_Item *it;
3327 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
3328 oy + itb->y - itb->wd->pan_y,
3329 itb->w, itb->h, x, y, 1, 1))
3331 EINA_LIST_FOREACH(itb->items, l, it)
3333 Evas_Coord itx, ity;
3335 itx = ox + itb->x + it->x - itb->wd->pan_x;
3336 ity = oy + itb->y + it->y - itb->wd->pan_y;
3337 if (ELM_RECTS_INTERSECT(itx, ity, it->w, it->h, x, y, 1, 1))
3341 if (y <= (ity + (it->h / 4))) *posret = -1;
3342 else if (y >= (ity + it->h - (it->h / 4))) *posret = 1;
3347 lasty = ity + it->h;
3352 if (y > lasty) *posret = 1;
3359 * Get the first item in the genlist
3361 * This returns the first item in the list.
3363 * @param obj The genlist object
3364 * @return The first item, or NULL if none
3368 EAPI Elm_Genlist_Item *
3369 elm_genlist_first_item_get(const Evas_Object *obj)
3371 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3372 Widget_Data *wd = elm_widget_data_get(obj);
3373 if (!wd) return NULL;
3374 if (!wd->items) return NULL;
3375 Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items);
3376 while ((it) && (it->delete_me))
3377 it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next);
3382 * Get the last item in the genlist
3384 * This returns the last item in the list.
3386 * @return The last item, or NULL if none
3390 EAPI Elm_Genlist_Item *
3391 elm_genlist_last_item_get(const Evas_Object *obj)
3393 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3394 Widget_Data *wd = elm_widget_data_get(obj);
3395 if (!wd->items) return NULL;
3396 Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items->last);
3397 if (!wd) return NULL;
3398 while ((it) && (it->delete_me))
3399 it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev);
3404 * Get the next item in the genlist
3406 * This returns the item after the item @p it.
3408 * @param it The item
3409 * @return The item after @p it, or NULL if none
3413 EAPI Elm_Genlist_Item *
3414 elm_genlist_item_next_get(const Elm_Genlist_Item *it)
3418 it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next);
3419 if ((it) && (!it->delete_me)) break;
3421 return (Elm_Genlist_Item *)it;
3425 * Get the previous item in the genlist
3427 * This returns the item before the item @p it.
3429 * @param it The item
3430 * @return The item before @p it, or NULL if none
3434 EAPI Elm_Genlist_Item *
3435 elm_genlist_item_prev_get(const Elm_Genlist_Item *it)
3439 it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev);
3440 if ((it) && (!it->delete_me)) break;
3442 return (Elm_Genlist_Item *)it;
3446 * Get the genlist object from an item
3448 * This returns the genlist object itself that an item belongs to.
3450 * @param it The item
3451 * @return The genlist object
3456 elm_genlist_item_genlist_get(const Elm_Genlist_Item *it)
3458 if (!it) return NULL;
3463 * Get the parent item of the given item
3465 * This returns the prent item of the item @p it given.
3467 * @param it The item
3468 * @return The parent of the item or NULL if none
3472 EAPI Elm_Genlist_Item *
3473 elm_genlist_item_parent_get(const Elm_Genlist_Item *it)
3475 if (!it) return NULL;
3480 * Clear all sub-items (children) of the given item
3482 * This clears all items that are children (or their descendants) of the
3485 * @param it The item
3490 elm_genlist_item_subitems_clear(Elm_Genlist_Item *it)
3493 Eina_List *tl = NULL, *l;
3494 Elm_Genlist_Item *it2;
3496 EINA_LIST_FOREACH(it->items, l, it2)
3497 tl = eina_list_append(tl, it2);
3498 EINA_LIST_FREE(tl, it2)
3499 elm_genlist_item_del(it2);
3503 * Set the selected state of an item
3505 * This sets the selected state (1 selected, 0 not selected) of the given
3508 * @param it The item
3509 * @param selected The slected state
3514 elm_genlist_item_selected_set(Elm_Genlist_Item *it, Eina_Bool selected)
3517 ELM_CHECK_WIDTYPE(it->wd->obj, widtype);
3518 Widget_Data *wd = elm_widget_data_get(it->wd->obj);
3520 if (it->delete_me) return;
3521 selected = !!selected;
3522 if (it->selected == selected) return;
3528 while (wd->selected)
3529 _item_unselect(wd->selected->data);
3539 * Get the selected state of an item
3541 * This gets the selected state of an item (1 selected, 0 not selected).
3543 * @param it The item
3544 * @return The selected state
3549 elm_genlist_item_selected_get(const Elm_Genlist_Item *it)
3551 if (!it) return EINA_FALSE;
3552 return it->selected;
3556 * Sets the expanded state of an item (if it's a parent)
3558 * This expands or contracts a parent iterm (thus showing or hiding the
3561 * @param it The item
3562 * @param expanded The expanded state (1 expanded, 0 not expanded).
3567 elm_genlist_item_expanded_set(Elm_Genlist_Item *it, Eina_Bool expanded)
3570 if (it->expanded == expanded || it->disabled) return;
3571 it->expanded = expanded;
3572 it->wd->expand_item = it;
3573 it->effect_done = EINA_FALSE;
3576 it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND;
3578 edje_object_signal_emit(it->base, "elm,state,expanded", "elm");
3579 evas_object_smart_callback_call(it->wd->obj, "expanded", it);
3584 it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT;
3586 edje_object_signal_emit(it->base, "elm,state,contracted", "elm");
3587 evas_object_smart_callback_call(it->wd->obj, "contracted", it);
3592 * Get the expanded state of an item
3594 * This gets the expanded state of an item
3596 * @param it The item
3597 * @return Thre expanded state
3602 elm_genlist_item_expanded_get(const Elm_Genlist_Item *it)
3604 if (!it) return EINA_FALSE;
3605 return it->expanded;
3609 * Get the depth of expanded item
3611 * @param it The genlist item object
3612 * @return The depth of expanded item
3617 elm_genlist_item_expanded_depth_get(const Elm_Genlist_Item *it)
3620 return it->expanded_depth;
3624 * Sets the disabled state of an item.
3626 * A disabled item cannot be selected or unselected. It will also change
3627 * appearance to appear disabled. This sets the disabled state (1 disabled, 0
3630 * @param it The item
3631 * @param disabled The disabled state
3636 elm_genlist_item_disabled_set(Elm_Genlist_Item *it, Eina_Bool disabled)
3639 if (it->disabled == disabled) return;
3640 if (it->delete_me) return;
3641 it->disabled = disabled;
3645 edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
3647 edje_object_signal_emit(it->base, "elm,state,enabled", "elm");
3652 * Get the disabled state of an item
3654 * This gets the disabld state of the given item.
3656 * @param it The item
3657 * @return The disabled state
3662 elm_genlist_item_disabled_get(const Elm_Genlist_Item *it)
3664 if (!it) return EINA_FALSE;
3665 if (it->delete_me) return EINA_FALSE;
3666 return it->disabled;
3670 * Sets the display only state of an item.
3672 * A display only item cannot be selected or unselected. It is for display
3673 * only and not selecting or otherwise clicking, dragging etc. by the user,
3674 * thus finger size rules will not be applied to this item.
3676 * @param it The item
3677 * @param display_only The display only state
3682 elm_genlist_item_display_only_set(Elm_Genlist_Item *it, Eina_Bool display_only)
3685 if (!it->block) return;
3686 if (it->display_only == display_only) return;
3687 if (it->delete_me) return;
3688 it->display_only = display_only;
3689 it->mincalcd = EINA_FALSE;
3690 it->updateme = EINA_TRUE;
3691 it->block->updateme = EINA_TRUE;
3692 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
3693 it->wd->update_job = ecore_job_add(_update_job, it->wd);
3697 * Get the display only state of an item
3699 * This gets the display only state of the given item.
3701 * @param it The item
3702 * @return The display only state
3707 elm_genlist_item_display_only_get(const Elm_Genlist_Item *it)
3709 if (!it) return EINA_FALSE;
3710 if (it->delete_me) return EINA_FALSE;
3711 return it->display_only;
3715 * Show the given item
3717 * This causes genlist to jump to the given item @p it and show it (by scrolling),
3718 * if it is not fully visible.
3720 * @param it The item
3725 elm_genlist_item_show(Elm_Genlist_Item *it)
3728 if (it->delete_me) return;
3729 if ((it->queued) || (!it->mincalcd))
3731 it->wd->show_item = it;
3732 it->wd->bring_in = 1;
3733 it->showme = EINA_TRUE;
3736 if (it->wd->show_item)
3738 it->wd->show_item->showme = EINA_FALSE;
3739 it->wd->show_item = NULL;
3741 elm_smart_scroller_child_region_show(it->wd->scr,
3742 it->x + it->block->x,
3743 it->y + it->block->y,
3744 it->block->w, it->h);
3748 * Bring in the given item
3750 * This causes genlist to jump to the given item @p it and show it (by scrolling),
3751 * if it is not fully visible. This may use animation to do so and take a
3754 * @param it The item
3759 elm_genlist_item_bring_in(Elm_Genlist_Item *it)
3762 if (it->delete_me) return;
3763 if ((it->queued) || (!it->mincalcd))
3765 it->wd->show_item = it;
3766 it->wd->bring_in = 1;
3767 it->showme = EINA_TRUE;
3770 if (it->wd->show_item)
3772 it->wd->show_item->showme = EINA_FALSE;
3773 it->wd->show_item = NULL;
3775 elm_smart_scroller_region_bring_in(it->wd->scr,
3776 it->x + it->block->x,
3777 it->y + it->block->y,
3778 it->block->w, it->h);
3782 * Show the given item at the top
3784 * This causes genlist to jump to the given item @p it and show it (by scrolling),
3785 * if it is not fully visible.
3787 * @param it The item
3792 elm_genlist_item_top_show(Elm_Genlist_Item *it)
3797 if (it->delete_me) return;
3798 if ((it->queued) || (!it->mincalcd))
3800 it->wd->show_item = it;
3801 it->wd->bring_in = 1;
3802 it->showme = EINA_TRUE;
3805 if (it->wd->show_item)
3807 it->wd->show_item->showme = EINA_FALSE;
3808 it->wd->show_item = NULL;
3810 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3811 elm_smart_scroller_child_region_show(it->wd->scr,
3812 it->x + it->block->x,
3813 it->y + it->block->y,
3818 * Bring in the given item at the top
3820 * This causes genlist to jump to the given item @p it and show it (by scrolling),
3821 * if it is not fully visible. This may use animation to do so and take a
3824 * @param it The item
3829 elm_genlist_item_top_bring_in(Elm_Genlist_Item *it)
3834 if (it->delete_me) return;
3835 if ((it->queued) || (!it->mincalcd))
3837 it->wd->show_item = it;
3838 it->wd->bring_in = 1;
3839 it->showme = EINA_TRUE;
3842 if (it->wd->show_item)
3844 it->wd->show_item->showme = EINA_FALSE;
3845 it->wd->show_item = NULL;
3847 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3848 elm_smart_scroller_region_bring_in(it->wd->scr,
3849 it->x + it->block->x,
3850 it->y + it->block->y,
3855 * Show the given item at the middle
3857 * This causes genlist to jump to the given item @p it and show it (by scrolling),
3858 * if it is not fully visible.
3860 * @param it The item
3865 elm_genlist_item_middle_show(Elm_Genlist_Item *it)
3870 if (it->delete_me) return;
3871 if ((it->queued) || (!it->mincalcd))
3873 it->wd->show_item = it;
3874 it->wd->bring_in = 1;
3875 it->showme = EINA_TRUE;
3878 if (it->wd->show_item)
3880 it->wd->show_item->showme = EINA_FALSE;
3881 it->wd->show_item = NULL;
3883 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3884 elm_smart_scroller_child_region_show(it->wd->scr,
3885 it->x + it->block->x,
3886 it->y + it->block->y - oh/2 + it->h/2,
3892 * Bring in the given item at the middle
3894 * This causes genlist to jump to the given item @p it and show it (by scrolling),
3895 * if it is not fully visible. This may use animation to do so and take a
3898 * @param it The item
3903 elm_genlist_item_middle_bring_in(Elm_Genlist_Item *it)
3908 if (it->delete_me) return;
3909 if ((it->queued) || (!it->mincalcd))
3911 it->wd->show_item = it;
3912 it->wd->bring_in = 1;
3913 it->showme = EINA_TRUE;
3916 if (it->wd->show_item)
3918 it->wd->show_item->showme = EINA_FALSE;
3919 it->wd->show_item = NULL;
3921 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
3922 elm_smart_scroller_region_bring_in(it->wd->scr,
3923 it->x + it->block->x,
3924 it->y + it->block->y - oh/2 + it->h/2,
3929 * Delete a given item
3931 * This deletes the item from genlist and calls the genlist item del class
3932 * callback defined in the item class, if it is set.
3934 * @param it The item
3939 elm_genlist_item_del(Elm_Genlist_Item *it)
3942 if ((it->relcount > 0) || (it->walking > 0))
3944 elm_genlist_item_subitems_clear(it);
3945 it->delete_me = EINA_TRUE;
3946 if (it->wd->show_item == it) it->wd->show_item = NULL;
3947 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
3950 if (it->realized) _item_unrealize(it);
3951 it->block->changed = EINA_TRUE;
3952 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
3953 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
3955 if (it->itc->func.del)
3956 it->itc->func.del((void *)it->data, it->wd->obj);
3963 * Set the data item from the genlist item
3965 * This set the data value passed on the elm_genlist_item_append() and
3966 * related item addition calls. This function will also call
3967 * elm_genlist_item_update() so the item will be updated to reflect the
3970 * @param it The item
3971 * @param data The new data pointer to set
3976 elm_genlist_item_data_set(Elm_Genlist_Item *it, const void *data)
3980 elm_genlist_item_update(it);
3984 * Get the data item from the genlist item
3986 * This returns the data value passed on the elm_genlist_item_append() and
3987 * related item addition calls.
3989 * @param it The item
3990 * @return The data pointer provided when created
3995 elm_genlist_item_data_get(const Elm_Genlist_Item *it)
3997 if (!it) return NULL;
4002 * Get the real evas object of the genlist item
4004 * This returns the actual evas object used for the specified genlist item.
4005 * This may be NULL as it may not be created, and ma be deleted at any time
4006 * by genlist. Do not modify this object (move, resize, show, hide etc.) as
4007 * genlist is controlling it. This function is for querying, emitting
4008 * custom signals or hooking lower level callbacks for events. Do not
4009 * delete this object under any circumstances.
4011 * @param it The item
4012 * @return The objct pointer
4016 EAPI const Evas_Object *
4017 elm_genlist_item_object_get(const Elm_Genlist_Item *it)
4019 if (!it) return NULL;
4024 * Update the contents of an item
4026 * This updates an item by calling all the item class functions again to get
4027 * the icons, labels and states. Use this when the original item data has
4028 * changed and the changes are desired to be reflected.
4030 * @param it The item
4035 elm_genlist_item_update(Elm_Genlist_Item *it)
4038 if (!it->block) return;
4039 if (it->delete_me) return;
4040 it->mincalcd = EINA_FALSE;
4041 it->updateme = EINA_TRUE;
4042 it->block->updateme = EINA_TRUE;
4043 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4044 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4048 * Update the item class of an item
4050 * @param it The item
4051 * @parem itc The item class for the item
4056 elm_genlist_item_item_class_update(Elm_Genlist_Item *it, const Elm_Genlist_Item_Class *itc)
4059 if (!it->block) return;
4061 if (it->delete_me) return;
4063 elm_genlist_item_update(it);
4067 * This sets the horizontal stretching mode
4069 * This sets the mode used for sizing items horizontally. Valid modes are
4070 * ELM_LIST_LIMIT and ELM_LIST_SCROLL. The default is ELM_LIST_SCROLL. This
4071 * mode means that if items are too wide to fit, the scroller will scroll
4072 * horizontally. Otherwise items are expanded to fill the width of the
4073 * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded
4074 * to the viewport width and limited to that size.
4076 * @param obj The genlist object
4077 * @param mode The mode to use
4082 elm_genlist_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode)
4084 ELM_CHECK_WIDTYPE(obj, widtype);
4085 Widget_Data *wd = elm_widget_data_get(obj);
4087 if (wd->mode == mode) return;
4093 * Gets the horizontal stretching mode
4095 * @param obj The genlist object
4096 * @return The mode to use
4097 * (ELM_LIST_LIMIT, ELM_LIST_SCROLL, ELM_LIST_LIMIT)
4102 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4104 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4105 Widget_Data *wd = elm_widget_data_get(obj);
4106 if (!wd) return ELM_LIST_LAST;
4111 * Set the always select mode.
4113 * Items will only call their selection func and callback when first becoming
4114 * selected. Any further clicks will do nothing, unless you enable always
4115 * select with elm_genlist_always_select_mode_set(). This means even if
4116 * selected, every click will make the selected callbacks be called.
4118 * @param obj The genlist object
4119 * @param always_select The always select mode
4120 * (EINA_TRUE = on, EINA_FALSE = off)
4125 elm_genlist_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select)
4127 ELM_CHECK_WIDTYPE(obj, widtype);
4128 Widget_Data *wd = elm_widget_data_get(obj);
4130 wd->always_select = always_select;
4134 * Get the always select mode.
4136 * @param obj The genlist object
4137 * @return The always select mode
4138 * (EINA_TRUE = on, EINA_FALSE = off)
4143 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4145 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4146 Widget_Data *wd = elm_widget_data_get(obj);
4147 if (!wd) return EINA_FALSE;
4148 return wd->always_select;
4152 * Set no select mode
4154 * This will turn off the ability to select items entirely and they will
4155 * neither appear selected nor call selected callback functions.
4157 * @param obj The genlist object
4158 * @param no_select The no select mode
4159 * (EINA_TRUE = on, EINA_FALSE = off)
4164 elm_genlist_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select)
4166 ELM_CHECK_WIDTYPE(obj, widtype);
4167 Widget_Data *wd = elm_widget_data_get(obj);
4169 wd->no_select = no_select;
4173 * Gets no select mode
4175 * @param obj The genlist object
4176 * @return The no select mode
4177 * (EINA_TRUE = on, EINA_FALSE = off)
4182 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4184 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4185 Widget_Data *wd = elm_widget_data_get(obj);
4186 if (!wd) return EINA_FALSE;
4187 return wd->no_select;
4193 * This will enable the compress mode where items are "compressed" horizontally
4194 * to fit the genlist scrollable viewport width. This is special for genlist.
4195 * Do not rely on elm_genlist_horizontal_mode_set() being set to
4196 * ELM_LIST_COMPRESS to work as genlist needs to handle it specially.
4198 * @param obj The genlist object
4199 * @param compress The compress mode
4200 * (EINA_TRUE = on, EINA_FALSE = off)
4205 elm_genlist_compress_mode_set(Evas_Object *obj, Eina_Bool compress)
4207 ELM_CHECK_WIDTYPE(obj, widtype);
4208 Widget_Data *wd = elm_widget_data_get(obj);
4210 wd->compress = compress;
4214 * Get the compress mode
4216 * @param obj The genlist object
4217 * @return The compress mode
4218 * (EINA_TRUE = on, EINA_FALSE = off)
4223 elm_genlist_compress_mode_get(const Evas_Object *obj)
4225 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4226 Widget_Data *wd = elm_widget_data_get(obj);
4227 if (!wd) return EINA_FALSE;
4228 return wd->compress;
4234 * This will enable or disable the scroller bounce mode for the genlist. See
4235 * elm_scroller_bounce_set() for details
4237 * @param obj The genlist object
4238 * @param h_bounce Allow bounce horizontally
4239 * @param v_bounce Allow bounce vertically
4244 elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
4246 ELM_CHECK_WIDTYPE(obj, widtype);
4247 Widget_Data *wd = elm_widget_data_get(obj);
4249 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4253 * Get the bounce mode
4255 * @param obj The genlist object
4256 * @param h_bounce Allow bounce horizontally
4257 * @param v_bounce Allow bounce vertically
4262 elm_genlist_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
4264 ELM_CHECK_WIDTYPE(obj, widtype);
4265 Widget_Data *wd = elm_widget_data_get(obj);
4267 elm_smart_scroller_bounce_allow_get(obj, h_bounce, v_bounce);
4271 * Set homogenous mode
4273 * This will enable the homogeneous mode where items are of the same height and width
4274 * so that genlist may do the lazy-loading at its maximum. This implies 'compressed' mode
4276 * @param obj The genlist object
4277 * @param homogeneous Assume the items within the genlist are of the same height and width
4278 * (EINA_TRUE = on, EINA_FALSE = off)
4283 elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous)
4285 ELM_CHECK_WIDTYPE(obj, widtype);
4286 Widget_Data *wd = elm_widget_data_get(obj);
4288 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4289 wd->homogeneous = homogeneous;
4293 * Get the homogenous mode
4295 * @param obj The genlist object
4296 * @return Assume the items within the genlist are of the same height and width
4297 * (EINA_TRUE = on, EINA_FALSE = off)
4302 elm_genlist_homogeneous_get(const Evas_Object *obj)
4304 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4305 Widget_Data *wd = elm_widget_data_get(obj);
4306 if (!wd) return EINA_FALSE;
4307 return wd->homogeneous;
4311 * Set the maximum number of items within an item block
4313 * This will configure the block count to tune to the target with particular performance matrix.
4315 * @param obj The genlist object
4316 * @param n Maximum number of items within an item block
4321 elm_genlist_block_count_set(Evas_Object *obj, int n)
4323 ELM_CHECK_WIDTYPE(obj, widtype);
4324 Widget_Data *wd = elm_widget_data_get(obj);
4326 wd->max_items_per_block = n;
4330 * Get the maximum number of items within an item block
4332 * @param obj The genlist object
4333 * @return Maximum number of items within an item block
4338 elm_genlist_block_count_get(const Evas_Object *obj)
4340 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4341 Widget_Data *wd = elm_widget_data_get(obj);
4343 return wd->max_items_per_block;
4347 * Set the timeout in seconds for the longpress event
4349 * @param obj The genlist object
4350 * @param timeout timeout in seconds
4355 elm_genlist_longpress_timeout_set(Evas_Object *obj, double timeout)
4357 ELM_CHECK_WIDTYPE(obj, widtype);
4358 Widget_Data *wd = elm_widget_data_get(obj);
4360 wd->longpress_timeout = timeout;
4364 * Get the timeout in seconds for the longpress event
4366 * @param obj The genlist object
4367 * @return timeout in seconds
4372 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4374 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4375 Widget_Data *wd = elm_widget_data_get(obj);
4377 return wd->longpress_timeout;
4381 * Set the scrollbar policy
4383 * This sets the scrollbar visibility policy for the given genlist scroller.
4384 * ELM_SMART_SCROLLER_POLICY_AUTO means the scrollber is made visible if it
4385 * is needed, and otherwise kept hidden. ELM_SMART_SCROLLER_POLICY_ON turns
4386 * it on all the time, and ELM_SMART_SCROLLER_POLICY_OFF always keeps it off.
4387 * This applies respectively for the horizontal and vertical scrollbars.
4389 * @param obj The genlist object
4390 * @param policy_h Horizontal scrollbar policy
4391 * @param policy_v Vertical scrollbar policy
4396 elm_genlist_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
4398 ELM_CHECK_WIDTYPE(obj, widtype);
4399 Widget_Data *wd = elm_widget_data_get(obj);
4401 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4402 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4405 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4409 elm_genlist_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
4411 ELM_CHECK_WIDTYPE(obj, widtype);
4412 Widget_Data *wd = elm_widget_data_get(obj);
4413 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
4414 if ((!wd) || (!wd->scr)) return;
4415 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
4416 if (policy_h) *policy_h = (Elm_Scroller_Policy) s_policy_h;
4417 if (policy_v) *policy_v = (Elm_Scroller_Policy) s_policy_v;
4420 // added for item moving animation.
4422 _group_item_contract_moving_effect_timer_cb(void *data)
4424 Evas_Object *obj = (Evas_Object *)data;
4425 Widget_Data *wd = elm_widget_data_get(obj);
4427 Item_Block *itb = NULL;
4428 Elm_Genlist_GroupItem *git;
4429 Elm_Genlist_Item *it;
4431 int cnt = 0, git_count = 0;
4432 double added_gy = 1;
4434 int hide_git = 0, git_cnt = 0, list_start_y = 0;
4436 int *git_array = NULL;
4437 int base_git = 0, base_git_num = 0;
4438 int tmp_y = 0, devide_size = 1;
4441 Eina_Bool finish = EINA_FALSE;
4443 Evas_Coord ox, oy, ow, oh;
4445 return ECORE_CALLBACK_CANCEL;
4447 if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE)
4448 return ECORE_CALLBACK_CANCEL;
4450 git_array = (int*)malloc(sizeof(int) * wd->max_git_num);
4451 t = ecore_loop_time_get();
4453 if (t - wd->effect_start >= 5.0)
4456 if (wd->item_count < 100)
4457 devide_size = 8 * _elm_config->scale;
4458 else if (wd->item_count < 500)
4459 devide_size = (8 - (devide_size / 100)) * _elm_config->scale;
4461 devide_size = 2 * _elm_config->scale;
4463 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4466 if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
4467 list_start_y += wd->select_all_item->h;
4469 EINA_INLIST_FOREACH(wd->group_items, git)
4471 git_array[git_cnt++] = git->y;
4472 if (git->y < list_start_y)
4474 edje_object_signal_emit(git->base, "elm,state,alpha,disable", "elm");
4476 base_git_num = hide_git;
4478 EINA_INLIST_FOREACH(wd->group_items, git)
4480 base_git = list_start_y + git->h * (git->num-1) + git->num;
4481 git->old_y = git->y;
4482 added_gy = abs(base_git - git->y) / devide_size;
4486 if (!git->down && git->old_y < list_start_y)
4488 git->finish_y = base_git;
4490 git->y = list_start_y - (git->h+1) * hide_git--;
4494 else if (!git->down && git->y < base_git)
4497 if (wd->pinch_zoom_reserve)
4504 if (git->y < base_git)
4507 if (git->y > base_git)
4513 if (git->y > base_git)
4516 if (git->y < base_git)
4520 if (git->num - 1 == cnt && git->y == base_git)
4523 evas_object_resize(git->base, wd->minw, git->h);
4524 evas_object_move(git->base, git->x, git->y);
4525 evas_object_raise(git->base);
4526 if (git->y < list_start_y)
4527 evas_object_lower(git->base);
4529 evas_object_raise(git->base);
4530 evas_object_show(git->base);
4532 EINA_INLIST_FOREACH(wd->blocks, itb)
4534 EINA_LIST_FOREACH(itb->items, l, it)
4536 if (it->group_item == git)
4538 if (it->group_item->old_y)
4539 it->old_scrl_y -= (it->group_item->old_y - it->group_item->y);
4541 if (git_array[it->group_item->num+1] <= it->old_scrl_y || added_gy == 1.0)
4543 evas_object_color_set(it->base, 0,0,0,0);
4544 evas_object_color_set(it->edit_obj, 0,0,0,0);
4546 _move_edit_controls(it,it->scrl_x, it->old_scrl_y);
4547 evas_object_resize(it->base, itb->wd->minw-(it->pad_left+it->pad_right), it->h);
4548 evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
4549 evas_object_raise(it->group_item->base);
4550 evas_object_show(it->base);
4554 if (git_count == git_cnt)
4559 if (wd->select_all_item) evas_object_raise(wd->select_all_item->base);
4564 if (finish) // finish animation
4567 EINA_INLIST_FOREACH(wd->group_items, git)
4571 wd->contract_pan_y = 0;
4572 wd->pinch_zoom_reserve = EINA_FALSE;
4573 wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH;
4574 elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0);
4575 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
4577 // fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT FINISH \n");
4581 EINA_INLIST_FOREACH(wd->blocks, itb)
4583 if (itb->realized) {
4584 EINA_LIST_FOREACH(itb->items, l, it)
4587 it->scrl_y = oy + tmp_y;
4589 // need to handle edit mode
4590 evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
4591 evas_object_move(it->edit_obj, it->scrl_x, it->old_scrl_y);
4592 evas_object_color_set(it->base, 0,0,0,0);
4593 evas_object_show(it->base);
4599 evas_object_lower(wd->alpha_bg);
4600 evas_object_hide(wd->alpha_bg);
4602 return ECORE_CALLBACK_CANCEL;
4605 return ECORE_CALLBACK_RENEW;
4608 // added for item moving animation.
4610 _group_item_expand_moving_effect_timer_cb(void *data)
4612 Evas_Object *obj = (Evas_Object *)data;
4613 Widget_Data *wd = elm_widget_data_get(obj);
4614 Elm_Genlist_GroupItem *git, *tmp_git;
4615 Item_Block *itb = NULL;
4616 Elm_Genlist_Item *it;
4618 int cnt = 0, git_count = 0, git_cnt = 0, git_tmp_y = 0, in = 0, start_in = 0;
4619 int tmp = 0, show_git_cnt = 0, scroll_y = 0, top_git = 0 , git_h = 0, scroll_pan_y = 0, down = 0;
4620 int up_cnt = 1, down_cnt = 1, it_h = 0, devide_size = 1;
4621 static int last_git_y = 0;
4625 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
4627 static double added_gy = 0; // temp value for animation speed
4628 static double added_gy2 = 0;
4629 Eina_Bool finish = EINA_FALSE;
4631 return ECORE_CALLBACK_CANCEL;
4633 if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE)
4634 return ECORE_CALLBACK_CANCEL;
4636 t = ecore_loop_time_get();
4638 top_git = wd->pinch_it;
4642 else if (top_git >= wd->max_git_num)
4643 top_git = wd->max_git_num - 1;
4645 if (wd->item_count < 100)
4646 devide_size = 8 * _elm_config->scale;
4647 else if (wd->item_count < 500)
4648 devide_size = (8 - (devide_size / 100)) * _elm_config->scale;
4650 devide_size = 2 * _elm_config->scale;
4652 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4653 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
4654 if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
4655 oy += wd->select_all_item->h;
4656 // calculate git count and srcroll move position
4657 EINA_INLIST_FOREACH(wd->group_items, git)
4659 if (git_cnt == top_git - 1)
4664 EINA_INLIST_FOREACH(wd->blocks, itb)
4666 EINA_LIST_FOREACH(itb->items, l, it)
4668 if (it->group_item == git)
4678 scroll_pan_y = scroll_y + git_h * (top_git-1) ;
4680 if (t - wd->effect_start >= 5.0)
4684 EINA_INLIST_FOREACH(wd->blocks, itb)
4686 if ((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh)
4687 || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh))
4692 EINA_LIST_FOREACH(itb->items, l, it)
4694 _item_realize(it, start_in, 0);
4695 it->realized = EINA_TRUE;
4698 itb->realized = EINA_TRUE;
4699 itb->want_unrealize = EINA_FALSE;
4705 if (itb->realized) _item_block_unrealize(itb);
4710 // set group item finish y and items y position of group item and items.
4713 EINA_INLIST_FOREACH(wd->group_items, git)
4715 if (git->num >= top_git)
4717 git->finish_y = git_tmp_y;
4718 git_tmp_y += git->h;
4719 tmp = git->y + git->h;
4723 git->finish_y = -1 * oh;
4725 EINA_INLIST_FOREACH(wd->blocks, itb)
4727 EINA_LIST_FOREACH(itb->items, l, it)
4729 if (it->group_item == git)
4731 if (git->finish_y != -1 * oh)
4733 it->old_scrl_y = tmp;
4735 added_gy2 = abs(git->finish_y - git->y) / devide_size;
4736 tmp += it->h - added_gy2;
4739 it->old_scrl_y = -1 * oh;
4744 if (git->finish_y >= oy && git->finish_y < oy+oh)
4748 EINA_INLIST_FOREACH(wd->group_items, git)
4752 evas_object_move(git->base, git->x, git->y);
4755 evas_object_raise(git->base);
4756 evas_object_show(git->base);
4760 evas_object_lower(git->base);
4761 evas_object_hide(git->base);
4764 added_gy = abs(git->finish_y - git->y) / devide_size;
4765 if (added_gy < 1.0) added_gy = 1.0;
4766 if (git->y > git->finish_y)
4770 if (git->num >= top_git)
4774 else if (git->y < git->finish_y)
4781 if ((!down && git->y < git->finish_y) || (down && git->y > git->finish_y))
4782 git->y = git->finish_y;
4784 if (git_cnt-1 == cnt)
4785 last_git_y = git->y;
4787 if (git->num == top_git && git->y == oy)
4789 evas_object_move(git->base, git->x, git->y);
4790 evas_object_show(git->base);
4792 EINA_INLIST_FOREACH(wd->group_items, tmp_git)
4794 if (tmp_git->y == tmp_git->finish_y && tmp_git->y > oy && tmp_git->y < oy+oh)
4801 EINA_INLIST_FOREACH(wd->blocks, itb)
4803 EINA_LIST_FOREACH(itb->items, l, it)
4805 if (it->group_item == git)
4808 if ((itb->y + itb->h >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh)
4809 || (itb->y >= scroll_pan_y - oh && itb->y <= scroll_pan_y + oh))
4811 evas_object_resize(it->base, wd->minw-(it->pad_left+it->pad_right), it->h);
4812 evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
4813 _move_edit_controls(it, it->scrl_x, it->old_scrl_y);
4814 evas_object_color_set(it->edit_obj, 255,255,255,255);
4815 evas_object_color_set(it->base, 255,255,255,255);
4816 evas_object_raise(it->base);
4817 evas_object_raise(it->group_item->base);
4825 if (git_count + 1 == show_git_cnt)
4834 wd->pan_y = scroll_y + (git_h) * (top_git-1) ;
4836 EINA_INLIST_FOREACH(wd->group_items, git)
4838 edje_object_signal_emit(git->base, "elm,state,alpha,enable", "elm");
4840 EINA_INLIST_FOREACH(wd->blocks, itb)
4842 EINA_LIST_FOREACH(itb->items, l, it)
4847 wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE;
4848 fprintf(stderr,"ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND FINISH \n");
4849 elm_smart_scroller_hold_set(wd->scr, 0);
4850 elm_smart_scroller_freeze_set(wd->scr, 0);
4851 elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 0);
4852 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_TRUE);
4853 // printf("_group_item_expand_moving_effect_timer_cb FINISH \n");
4854 evas_object_lower(wd->alpha_bg);
4855 evas_object_hide(wd->alpha_bg);
4856 // evas_object_smart_changed(wd->pan_smart);
4857 if (wd->calc_job) ecore_job_del(wd->calc_job);
4858 wd->calc_job = ecore_job_add(_calc_job, wd);
4860 return ECORE_CALLBACK_CANCEL;
4863 return ECORE_CALLBACK_RENEW;
4867 _item_pinch_recalc(Evas_Object *obj, int emode)
4869 Item_Block *itb = NULL;
4871 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
4872 Widget_Data *wd = elm_widget_data_get(obj);
4874 if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND)
4877 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4878 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
4882 if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_NONE)
4884 wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT;
4886 elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1);
4887 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE, EINA_FALSE);
4888 evas_object_raise(wd->alpha_bg);
4889 evas_object_show(wd->alpha_bg);
4891 wd->effect_start = ecore_loop_time_get();
4892 wd->item_moving_effect_timer = ecore_animator_add(_group_item_contract_moving_effect_timer_cb, obj);
4895 else if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
4897 elm_smart_scroller_freeze_momentum_animator_set(wd->scr, 1);
4899 evas_object_raise(wd->alpha_bg);
4900 evas_object_show(wd->alpha_bg);
4902 wd->pinchzoom_effect_mode = ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_EXPAND;
4903 EINA_INLIST_FOREACH(wd->blocks, itb)
4905 if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
4906 itb->y - wd->pan_y + oy,
4908 cvx, cvy, cvw, cvh))
4910 if (itb->realized) _item_block_unrealize(itb);
4911 itb->realized = EINA_FALSE;
4915 wd->effect_start = ecore_loop_time_get();
4916 wd->item_moving_effect_timer = ecore_animator_add(_group_item_expand_moving_effect_timer_cb, obj);
4923 create_tray_alpha_bg(const Evas_Object *obj)
4925 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4926 Widget_Data *wd = elm_widget_data_get(obj);
4927 if (!wd) return NULL;
4929 Evas_Object *bg = NULL;
4930 Evas_Coord ox, oy, ow, oh;
4932 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
4933 bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
4934 evas_object_color_set(bg , 0,0,0,0);
4935 evas_object_resize(bg , ow, oh);
4936 evas_object_move(bg , ox, oy);
4937 evas_object_show(bg);
4938 evas_object_hide(bg);
4943 _elm_genlist_pinch_zoom_execute(Evas_Object *obj, Eina_Bool emode)
4945 ELM_CHECK_WIDTYPE(obj, widtype);
4946 Widget_Data *wd = elm_widget_data_get(obj);
4947 if (!wd || !wd->pinch_zoom) return;
4948 if (!wd->queue_idler)
4951 wd->alpha_bg = create_tray_alpha_bg(obj);
4952 _item_pinch_recalc(obj, emode);
4957 * Set pinch zoom mode
4959 * @param obj The genlist object
4961 * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out)
4966 elm_genlist_pinch_zoom_mode_set(Evas_Object *obj, Eina_Bool emode)
4968 ELM_CHECK_WIDTYPE(obj, widtype);
4969 Widget_Data *wd = elm_widget_data_get(obj);
4970 if (!wd || !wd->pinch_zoom) return;
4971 wd->pinch_zoom_reserve = emode;
4975 * Get pinch zoom mode
4977 * @param obj The genlist object
4978 * @return The pinch mode
4979 * (EINA_TRUE = pinch contract (zoom in), EINA_FALSE = pinch expand (zoom out)
4984 elm_genlist_pinch_zoom_mode_get(const Evas_Object *obj)
4986 Widget_Data *wd = elm_widget_data_get(obj);
4987 if (!wd) return EINA_FALSE;
4988 if (wd->pinchzoom_effect_mode == ELM_GENLIST_ITEM_PINCHZOOM_EFFECT_CONTRACT_FINISH)
4990 else return EINA_FALSE;
4994 elm_genlist_pinch_zoom_set(Evas_Object *obj, Eina_Bool emode)
4996 Widget_Data *wd = elm_widget_data_get(obj);
4998 wd->pinch_zoom = emode;
5001 // added for item moving animation.
5003 _item_moving_effect_timer_cb(void *data)
5005 Widget_Data *wd = data;
5007 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
5008 Elm_Genlist_Item *it;
5010 int expanded_cnt = 0;
5012 static double added_gy =25;
5013 static int count = 0;
5014 if (!wd) return EINA_FALSE;
5015 if (added_gy < 1) added_gy = 1;
5018 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5019 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
5021 EINA_INLIST_FOREACH(wd->blocks, itb)
5024 if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
5025 itb->y - wd->pan_y + oy,
5027 cvx, cvy, cvw, cvh))
5029 EINA_LIST_FOREACH(itb->items, l, it)
5031 if (!it->old_scrl_y)
5032 it->old_scrl_y = it->scrl_y;
5033 if (it->parent && it->parent->expanded && !it->showme)
5035 evas_object_hide(it->base);
5037 else evas_object_show(it->base);
5039 evas_object_show(it->base);
5041 if (itb && itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
5043 if (it->old_scrl_y && it->old_scrl_y < it->scrl_y) {
5044 it->old_scrl_y += added_gy;
5046 if (it->old_scrl_y >= it->scrl_y) {
5047 it->list_expanded = 1;
5048 it->old_scrl_y = it->scrl_y;
5051 else if (itb->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
5053 if (it->old_scrl_y && it->old_scrl_y > it->scrl_y)
5056 it->old_scrl_y -= added_gy;
5059 if (it->old_scrl_y <= it->scrl_y) {
5060 it->list_expanded = 1;
5061 it->old_scrl_y = it->scrl_y;
5064 expanded_cnt += it->list_expanded;
5067 _move_edit_controls(it,it->scrl_x, it->scrl_y);
5068 evas_object_resize(it->base, it->w-(it->pad_left+it->pad_right), it->h);
5069 evas_object_move(it->base, it->scrl_x+it->pad_left, it->old_scrl_y);
5070 evas_object_raise(it->base);
5074 if (expanded_cnt == cnt)
5076 if (wd->item_moving_effect_timer)
5080 wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
5081 EINA_INLIST_FOREACH(wd->blocks, itb)
5083 EINA_LIST_FOREACH(itb->items, l, it)
5085 it->list_expanded = 0;
5090 return ECORE_CALLBACK_CANCEL;
5092 return ECORE_CALLBACK_RENEW;
5095 // added for edit mode item moving animation.
5097 _edit_mode_item_moving_effect_cb(void *data)
5099 Widget_Data *wd = data;
5101 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
5102 Elm_Genlist_Item *it, *select_all_item;
5104 int expanded_cnt = 0;
5105 static double added_gy = 9;
5106 static float count = 0;
5108 static float select_all_y = 0;
5110 if (!wd) return EINA_FALSE;
5113 if (!wd->select_all_item)
5114 return ECORE_CALLBACK_CANCEL;
5116 static float dy = 9;
5121 select_all_y += (dy);
5123 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5124 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
5126 EINA_INLIST_FOREACH(wd->blocks, itb)
5129 if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
5130 itb->y - wd->pan_y + oy,
5132 cvx, cvy, cvw, cvh))
5135 EINA_LIST_FOREACH(itb->items, l, it)
5138 evas_object_show(it->base);
5139 if (it->old_pad_left < it->pad_left)
5141 it->old_pad_left += dy;
5142 if (it->old_pad_left >= it->pad_left)
5144 it->list_expanded = 1;
5145 it->old_pad_left = it->pad_left;
5148 if (it->old_pad_left > it->pad_left)
5150 it->old_pad_left -= dy;
5151 if (it->old_pad_left <= it->pad_left)
5153 it->list_expanded = 1;
5154 it->old_pad_left = it->pad_left;
5158 if (it->old_scrl_y < it->scrl_y)
5160 it->old_scrl_y += (dy) ;
5161 if (it->old_scrl_y >= it->scrl_y)
5163 it->list_expanded = 1;
5164 it->old_scrl_y = it->scrl_y;
5168 if (it->old_scrl_y > it->scrl_y)
5170 it->old_scrl_y -= (dy);
5171 if (it->old_scrl_y <= it->scrl_y)
5173 it->list_expanded = 1;
5174 it->old_scrl_y = it->scrl_y;
5179 select_all_item = itb->wd->select_all_item;
5180 evas_object_resize(select_all_item->base, itb->w, select_all_item->h);
5181 if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
5182 evas_object_move(select_all_item->base, ox, oy - select_all_y);
5183 else if (select_all_y <= select_all_item->h)
5184 evas_object_move(select_all_item->base, ox, oy - select_all_item->h + select_all_y);
5185 evas_object_raise(select_all_item->base);
5186 evas_object_show(select_all_item->base);
5188 expanded_cnt += it->list_expanded;
5190 evas_object_move(it->base, it->scrl_x+it->old_pad_left, it->old_scrl_y);
5191 evas_object_move(it->edit_obj, it->scrl_x, it->old_scrl_y);
5192 evas_object_raise(it->edit_obj);
5193 evas_object_raise(it->base);
5195 evas_object_show(it->edit_obj);
5196 evas_object_show(it->base);
5198 if (select_all_y >= wd->select_all_item->h && it->list_expanded == 1)
5201 evas_object_raise(it->edit_obj);
5210 if (wd->item_moving_effect_timer)
5216 wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
5217 EINA_INLIST_FOREACH(wd->blocks, itb)
5219 EINA_LIST_FOREACH(itb->items, l, it)
5221 it->list_expanded = 0;
5224 if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
5226 if (wd->select_all_item)
5228 if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item);
5229 free(wd->select_all_item);
5231 wd->select_all_item = NULL;
5234 wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
5235 wd->effect_mode = 0;
5237 if (wd->calc_job) ecore_job_del(wd->calc_job);
5238 wd->calc_job = ecore_job_add(_calc_job, wd);
5239 return ECORE_CALLBACK_CANCEL;
5241 return ECORE_CALLBACK_RENEW;
5245 // added for item moving animation.
5247 _item_flip_effect_show(void *data)
5249 Widget_Data *wd = data;
5251 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
5253 if (!wd) return EINA_FALSE;
5255 Elm_Genlist_Item *it;
5258 int start = 0, end = 0;
5260 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
5261 evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
5263 EINA_INLIST_FOREACH(wd->blocks, itb)
5266 if (ELM_RECTS_INTERSECT(itb->x - wd->pan_x + ox,
5267 itb->y - wd->pan_y + oy,
5269 cvx, cvy, cvw, cvh))
5271 EINA_LIST_FOREACH(itb->items, l, it)
5273 if (it->parent && it->wd->expand_item == it->parent && !it->effect_done)
5275 if (!start) start = it->scrl_y;
5276 base = (Evas_Object *) it->base;
5277 edje_object_signal_emit(it->base, "flip_item", "");
5278 end = it->scrl_y + it->h;
5279 it->effect_done = EINA_TRUE;
5284 wd->expand_item_cnt = end - start;
5285 return ECORE_CALLBACK_CANCEL;
5289 elm_genlist_effect_set(const Evas_Object *obj, Eina_Bool emode)
5291 ELM_CHECK_WIDTYPE(obj, widtype);
5292 Widget_Data *wd = elm_widget_data_get(obj);
5294 wd->effect_mode = emode;
5295 wd->point_rect = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
5296 evas_object_resize(wd->point_rect, 10, 25);
5297 evas_object_color_set(wd->point_rect, 255, 0, 0, 130);
5298 evas_object_show(wd->point_rect);
5299 evas_object_hide(wd->point_rect);
5304 elm_genlist_edit_mode_effect_set(const Evas_Object *obj, Eina_Bool emode)
5306 ELM_CHECK_WIDTYPE(obj, widtype);
5307 Widget_Data *wd = elm_widget_data_get(obj);
5309 wd->edit_mode_effect_mode = emode;
5314 elm_genlist_queue_exception_set(const Evas_Object *obj, Eina_Bool emode)
5316 ELM_CHECK_WIDTYPE(obj, widtype);
5317 Widget_Data *wd = elm_widget_data_get(obj);
5319 wd->queue_exception = emode;
5321 fprintf(stderr, "=================> Caution!!! <========================\n");
5322 fprintf(stderr, "==> elm_genlist_queue_exception_set() is for demo. <===\n");
5323 fprintf(stderr, "==> Do not use this API <==\n");
5324 fprintf(stderr, "=======================================================\n");
5328 _delete_confirm_cb(void *data, Evas_Object *obj, void *event_info)
5330 Widget_Data *wd = data;
5331 evas_object_hide(wd->ed->del_confirm);
5332 if (wd->ed->ec && wd->ed->ec->remove)
5333 wd->ed->ec->remove(wd->obj, wd->ed->del_item);
5334 wd->ed->del_item = NULL;
5338 _hide_delete_confirm_object (void *data, Evas_Object *obj, const char *emission, const char *source)
5340 const char *del_icon_part;
5341 Elm_Genlist_Item *it = data;
5342 del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm");
5344 edje_object_part_unswallow(it->edit_obj, it->wd->ed->del_confirm);
5345 evas_object_hide(it->wd->ed->del_confirm);
5349 _remove_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5351 const char *del_conf_style;
5352 Elm_Genlist_Item *it = data;
5353 if (_edit_mode_reset(it->wd))
5356 if (it->edit_long_timer)
5358 ecore_timer_del(it->edit_long_timer);
5359 it->edit_long_timer = NULL;
5362 if (it->del_confirm_state)
5364 it->del_confirm_state = 0;
5365 it->delete_check = 0;
5366 edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm");
5367 it->wd->selct_all = 0;
5368 if (it->wd->select_all_item)
5369 edje_object_signal_emit(it->wd->select_all_item->base, "elm,state,del,animated,enable", "elm");
5370 if (!it->wd->selct_all && it->wd->ed->ec->item_selected)
5371 it->wd->ed->ec->item_selected(it->data, it, it->delete_check);
5375 it->del_confirm_state = 1;
5376 it->delete_check = 1;
5377 it->wd->ed->del_item = it;
5379 if (!it->wd->selct_all && it->wd->ed->ec->item_selected)
5380 it->wd->ed->ec->item_selected(it->data, it, it->delete_check);
5381 del_conf_style = edje_object_data_get(it->edit_obj, "del_button_style");
5383 elm_object_style_set(it->wd->ed->del_confirm, del_conf_style);
5386 del_icon_part = edje_object_data_get(it->edit_obj, "del_confirm");
5388 edje_object_part_swallow(it->edit_obj, del_icon_part, it->wd->ed->del_confirm);
5389 evas_object_show(it->wd->ed->del_confirm);
5391 edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm");
5395 _insert_new_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5397 Elm_Genlist_Item *it = data;
5399 if (_edit_mode_reset(it->wd))
5402 if (it->wd->ed->ec && it->wd->ed->ec->insert_new)
5403 it->wd->ed->ec->insert_new(it->wd->obj, it);
5407 _edit_mode_reset(Widget_Data *wd)
5410 if (wd->ed->del_confirm_state)
5412 //edje_object_signal_emit(wd->ed->del_item->edit_obj, "elm,state,delete", "elm");
5413 //wd->ed->del_confirm_state = 0;
5414 //wd->ed->del_item = NULL;
5422 _reorder_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
5424 Elm_Genlist_Item *it = data;
5425 Evas_Event_Mouse_Down *ev = event_info;
5428 if (it->wd->edit_field && !it->renamed)
5429 elm_genlist_item_rename_mode_set(it, 0);
5431 if (!(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER))
5434 if (_edit_mode_reset(it->wd))
5439 it->reoder_cavas_x = ev->canvas.x;
5440 it->reoder_cavas_y = ev->canvas.y;
5442 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
5443 it->dx = ev->canvas.x - x;
5444 it->dy = ev->canvas.y - y;
5446 if (it->edit_long_timer)
5448 ecore_timer_del(it->edit_long_timer);
5449 it->edit_long_timer = NULL;
5452 it->edit_long_timer = ecore_timer_add(0.3,_edit_long_press, it);
5454 it->edit_long_timer = NULL;
5458 _reorder_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
5460 Elm_Genlist_Item *it = data;
5463 EINA_INLIST_FOREACH(it->wd->blocks, itb)
5467 if (it->edit_long_timer)
5469 ecore_timer_del(it->edit_long_timer);
5470 it->edit_long_timer = NULL;
5474 it->wd->reoder_moved = EINA_FALSE;
5476 if (it->wd->ed->ec->selected)
5477 it->wd->ed->ec->selected(NULL, it, 1);
5479 if (it->reordering && it->wd->ed->reorder_item)
5481 it->wd->ed->reorder_item->reordering = 0;
5482 edje_object_signal_emit(it->wd->ed->reorder_item->edit_obj, "elm,action,item,reorder_end", "elm");
5483 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
5485 if ((!it->wd->ed->reorder_rel) || (!it->wd->ed->ec->move) ||
5486 (!it->wd->ed->ec->move(it->wd->obj, it->wd->ed->reorder_item, it->wd->ed->reorder_rel, EINA_TRUE)))
5488 evas_object_move(it->wd->ed->reorder_item->base, it->wd->ed->reorder_item->scrl_x+it->pad_left, it->wd->ed->reorder_item->scrl_y);
5489 _move_edit_controls(it,it->wd->ed->reorder_item->scrl_x, it->wd->ed->reorder_item->scrl_y);
5491 it->wd->ed->reorder_item = NULL;
5492 it->wd->ed->reorder_rel = NULL;
5498 _reorder_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
5500 Elm_Genlist_Item *it = data;
5501 Evas_Event_Mouse_Move *ev = event_info;
5503 if ((it->dragging) && (it->down))
5505 if (it->edit_long_timer)
5507 ecore_timer_del(it->edit_long_timer);
5508 it->edit_long_timer = NULL;
5511 evas_object_smart_callback_call(it->wd->obj, "drag", it);
5515 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
5517 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
5518 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
5519 x = ev->cur.canvas.x - x;
5520 y = ev->cur.canvas.y - y;
5523 if (adx < 0) adx = -dx;
5526 if (ady < 0) ady = -dy;
5529 if ((adx > minw) || (ady > minh))
5532 if (it->edit_long_timer)
5534 ecore_timer_del(it->edit_long_timer);
5535 it->edit_long_timer = NULL;
5539 if (it->reordering && it->wd->ed->reorder_item)
5541 int y = ev->cur.canvas.y - it->wd->ed->reorder_item->dy;
5542 evas_object_raise(it->wd->ed->reorder_item->base);
5543 evas_object_move(it->wd->ed->reorder_item->base, it->wd->ed->reorder_item->scrl_x+it->pad_left, y);
5544 evas_object_show(it->wd->ed->reorder_item->base);
5545 _move_edit_controls(it,it->wd->ed->reorder_item->scrl_x, y);
5547 it->block->updateme = EINA_TRUE;
5549 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5550 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
5557 _select_all_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
5560 Elm_Genlist_Item *select_all_it = data, *it;
5562 Widget_Data *wd = select_all_it->wd;
5566 edje_object_signal_emit(select_all_it->base, "elm,state,del_confirm", "elm");
5568 edje_object_signal_emit(select_all_it->base, "elm,state,del,animated,enable", "elm");
5570 EINA_INLIST_FOREACH(wd->blocks, itb)
5572 EINA_LIST_FOREACH(itb->items, l, it)
5576 it->delete_check = 1;
5577 it->del_confirm_state = 1;
5578 edje_object_signal_emit(it->edit_obj, "elm,state,del_confirm", "elm");
5582 it->delete_check = 0;
5583 it->del_confirm_state = 0;
5584 edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm");
5588 wd->selct_all ^= 0xFF;
5590 if (wd->ed->ec->item_selected)
5591 wd->ed->ec->item_selected(select_all_it->data, select_all_it, wd->selct_all);
5592 if (wd->calc_job) ecore_job_del(wd->calc_job);
5593 wd->calc_job = ecore_job_add(_calc_job, wd);
5597 _move_edit_controls(Elm_Genlist_Item *it, int itx, int ity)
5599 if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
5601 evas_object_resize(it->edit_obj,it->w, it->h);
5602 evas_object_move(it->edit_obj, itx, ity);
5603 evas_object_raise(it->edit_obj);
5607 _edit_controls_eval(Elm_Genlist_Item *it)
5610 const char *pad_str;
5617 if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE && !it->edit_obj)
5620 if (it->itc->func.editmode_get)
5621 itmode = it->itc->func.editmode_get(it->data, it->wd->obj, it->wd->edit_mode);
5622 itmode &= it->wd->edit_mode;
5624 if (itmode & ELM_GENLIST_EDIT_MODE_SELECTALL)
5625 itmode |= ELM_GENLIST_EDIT_MODE_SELECT;
5629 it->edit_obj = edje_object_add(evas_object_evas_get(it->wd->obj));
5630 edje_object_scale_set(it->edit_obj, elm_widget_scale_get(it->wd->obj) *
5631 _elm_config->scale);
5632 evas_object_smart_member_add(it->edit_obj, it->wd->pan_smart);
5633 elm_widget_sub_object_add(it->wd->obj, it->edit_obj);
5634 if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf));
5635 else strncpy(buf, "item", sizeof(buf));
5636 if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf));
5637 // if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
5638 strncat(buf, "/", sizeof(buf) - strlen(buf));
5640 if (it->wd->ed->ec->item_style && strcmp(it->wd->ed->ec->item_style, "default"))
5642 strncat(buf, it->wd->ed->ec->item_style, sizeof(buf) - strlen(buf));
5643 _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", buf, elm_widget_style_get(it->wd->obj));
5647 _elm_theme_object_set(it->wd->obj, it->edit_obj, "genlist", "item/edit_control", elm_widget_style_get(it->wd->obj));
5650 // edje_object_signal_callback_add(it->edit_obj, "elm,action,edit,reset",
5651 // "elm", _edit_mode_reset, it);
5654 pad_str = edje_object_data_get(it->edit_obj, "icon_width");
5655 if (pad_str) pad = atoi(pad_str);
5657 if ((itmode & ELM_GENLIST_EDIT_MODE_INSERT))
5659 if (it->wd->animate_edit_controls)
5660 edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,enable", "elm");
5662 edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm");
5664 edje_object_signal_callback_add(it->edit_obj, "elm,action,item,insert",
5665 "elm", _insert_new_item_cb, it);
5666 it->pad_left += pad * _elm_config->scale;
5670 if (it->wd->animate_edit_controls)
5671 edje_object_signal_emit(it->edit_obj, "elm,state,ins,animated,disable", "elm");
5673 edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm");
5675 edje_object_signal_callback_del(it->edit_obj, "elm,action,item,insert",
5676 "elm", _insert_new_item_cb);
5679 if ((itmode & ELM_GENLIST_EDIT_MODE_DELETE) || (itmode & ELM_GENLIST_EDIT_MODE_SELECT))
5681 if (it->wd->animate_edit_controls)
5682 edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,enable", "elm");
5684 edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm");
5686 edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete",
5687 "elm", _remove_item_cb);
5688 edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm",
5689 "elm", _hide_delete_confirm_object);
5691 edje_object_signal_callback_add(it->edit_obj, "elm,action,item,delete",
5692 "elm", _remove_item_cb, it);
5694 edje_object_signal_callback_add(it->edit_obj, "elm,action,hide,del_confirm",
5695 "elm", _hide_delete_confirm_object, it);
5696 it->pad_left += pad * _elm_config->scale;
5697 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5698 _reorder_mouse_down, it);
5702 if (it->wd->animate_edit_controls)
5703 edje_object_signal_emit(it->edit_obj, "elm,state,del,animated,disable", "elm");
5705 edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm");
5707 edje_object_signal_callback_del(it->edit_obj, "elm,action,item,delete",
5708 "elm", _remove_item_cb);
5709 edje_object_signal_callback_del(it->edit_obj, "elm,action,hide,del_confirm",
5710 "elm", _hide_delete_confirm_object);
5711 evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5712 _reorder_mouse_down);
5715 if ((itmode & ELM_GENLIST_EDIT_MODE_REORDER))
5717 const char* reorder_part;
5719 reorder_part = edje_object_data_get(it->edit_obj, "reorder");
5720 if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part))
5722 edje_object_part_object_get(it->edit_obj, reorder_part);
5724 evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5725 _reorder_mouse_down);
5726 evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
5728 evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
5729 _reorder_mouse_move);
5731 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5732 _reorder_mouse_down, it);
5733 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
5734 _reorder_mouse_up, it);
5735 evas_object_event_callback_add(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
5736 _reorder_mouse_move, it);
5738 // it->pad_right += pad * _elm_config->scale;
5742 const char* reorder_part;
5744 reorder_part = edje_object_data_get(it->edit_obj, "reorder");
5745 if (reorder_part && edje_object_part_exists(it->edit_obj, reorder_part))
5748 if (itmode == ELM_GENLIST_EDIT_MODE_NONE)
5750 evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_DOWN,
5751 _reorder_mouse_down);
5752 evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_UP,
5754 evas_object_event_callback_del(it->edit_obj, EVAS_CALLBACK_MOUSE_MOVE,
5755 _reorder_mouse_move);
5760 if (it->wd->edit_mode != 0xF0) {
5761 if (it->wd->edit_mode != ELM_GENLIST_EDIT_MODE_NONE)
5763 if (it->itc->func.icon_get)
5765 edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,enable", "elm");
5770 it->icons = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "icons"));
5771 EINA_LIST_FOREACH(it->icons, l, key)
5773 Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data);
5777 it->edit_icon_objs = eina_list_append(it->edit_icon_objs, ic);
5778 edje_object_part_swallow(it->edit_obj, key, ic);
5779 evas_object_show(ic);
5780 // elm_widget_sub_object_add(it->wd->obj, ic);
5787 edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm");
5788 EINA_LIST_FREE(it->edit_icon_objs, icon)
5789 evas_object_del(icon);
5791 Evas_Object *editfield;
5792 EINA_LIST_FREE(it->wd->edit_field, editfield)
5793 evas_object_del(editfield);
5797 if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)//Unrealize
5799 evas_object_del(it->edit_obj);
5800 it->edit_obj = NULL;
5803 _move_edit_controls(it,it->scrl_x, it->scrl_y);
5804 evas_object_show(it->edit_obj);
5808 _notify_item_position(Elm_Genlist_Item *it)
5813 l = eina_list_last(it->parent->items);
5815 //Check if the Item is First Node or Last node of its Parent & raise signal.
5816 if (it->parent->items->data != it && l->data != it)
5818 edje_object_signal_emit(it->base, "normal_item", "elm");
5822 if (it->parent->items->data == it)
5823 edje_object_signal_emit(it->base, "first_item", "elm");
5826 edje_object_signal_emit(it->base, "last_item", "elm");
5832 _get_space_for_reorder_item(Elm_Genlist_Item *it)
5835 Evas_Coord rox, roy, row, roh;
5836 if (!it->wd->ed) return 0;
5837 if (!(it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER) || !it->wd->ed->reorder_item)
5839 evas_object_geometry_get(it->wd->ed->reorder_item->base, &rox, &roy, &row, &roh);
5840 top = (ELM_RECTS_INTERSECT(it->scrl_x, it->scrl_y, it->w, it->h,
5841 rox, roy+roh/2, row, 1));
5844 it->wd->ed->reorder_rel = it;
5845 it->scrl_y+=it->wd->ed->reorder_item->h;
5846 it->reorder_check = 1;
5847 return it->wd->ed->reorder_item->h;
5853 * Add Group Item to the genlist
5855 * @param obj The genlist object
5856 * @param itc The item class for the item
5857 * @param data The group item data
5859 EAPI Elm_Genlist_GroupItem *
5860 elm_genlist_groupitem_add(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
5863 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5864 Elm_Genlist_GroupItem *git;
5865 Widget_Data *wd = elm_widget_data_get(obj);
5867 git = calloc(1, sizeof(Elm_Genlist_GroupItem));
5868 if (!git) return NULL;
5873 wd->group_items = eina_inlist_append(wd->group_items, EINA_INLIST_GET(git));
5878 * Delete a given groupitem
5880 * This deletes the group item from genlist and calls the genlist group item del class
5881 * callback defined in the item class, if it is set.
5883 * @param git The group item
5888 elm_genlist_groupitem_del(Elm_Genlist_GroupItem *git)
5890 _groupitem_remove(git, EINA_TRUE);
5894 * Append item to the end of the genlist with Group Item
5896 * This appends the given item to the end of the list or the end of the
5897 * children if the parent is given.
5899 * @param obj The genlist object
5900 * @param itc The item class for the item
5901 * @param data The item data
5902 * @param parent The parent item, or NULL if none
5903 * @param flags Item flags
5904 * @param git Group Item
5905 * @param func Convenience function called when item selected
5906 * @param func_data Data passed to @p func above.
5907 * @return A handle to the item added or NULL if not possible
5911 EAPI Elm_Genlist_Item *
5912 elm_genlist_item_append_with_group(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
5913 const void *data, Elm_Genlist_Item *parent,
5914 Elm_Genlist_Item_Flags flags, Elm_Genlist_GroupItem *git,
5915 Evas_Smart_Cb func, const void *func_data)
5917 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5918 Widget_Data *wd = elm_widget_data_get(obj);
5920 Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
5921 Elm_Genlist_GroupItem *pgit = NULL;
5922 Elm_Genlist_Item *it2 = NULL;
5923 Eina_List *ll = NULL;
5924 if (!wd) return NULL;
5925 if (!it) return NULL;
5926 if (!git) return NULL;
5931 ll = eina_list_last(pgit->items);
5937 if (!(EINA_INLIST_GET(pgit)->prev)) break;
5938 pgit = (Elm_Genlist_GroupItem *)(EINA_INLIST_GET(pgit)->prev);
5943 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
5944 EINA_INLIST_GET(it2));
5946 it->rel->relcount++;
5950 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
5953 git->items = eina_list_append(git->items, it);
5955 it->group_item = git;
5956 _item_queue(wd, it);
5961 * Prepend item at start of the genlist with Group Item
5963 * This adds the given item to the beginning of the list or beginning of the
5964 * children if the parent is given.
5966 * @param obj The genlist object
5967 * @param itc The item class for the item
5968 * @param data The item data
5969 * @param parent The parent item, or NULL if none
5970 * @param flags Item flags
5971 * @param git Group Item
5972 * @param func Convenience function called when item selected
5973 * @param func_data Data passed to @p func above.
5974 * @return A handle to the item added or NULL if not possible
5978 EAPI Elm_Genlist_Item *
5979 elm_genlist_item_prepend_with_group(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
5980 const void *data, Elm_Genlist_Item *parent,
5981 Elm_Genlist_Item_Flags flags, Elm_Genlist_GroupItem *git,
5982 Evas_Smart_Cb func, const void *func_data)
5984 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5985 Widget_Data *wd = elm_widget_data_get(obj);
5987 Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
5988 Elm_Genlist_GroupItem *pgit = NULL;
5989 Elm_Genlist_Item *it2 = NULL;
5990 Eina_List *ll = NULL;
5991 Eina_Bool new_group = EINA_FALSE;
5992 if (!wd) return NULL;
5993 if (!it) return NULL;
5994 if (!git) return NULL;
6000 ll = eina_list_last(pgit->items);
6009 if (!(EINA_INLIST_GET(pgit)->prev)) break;
6010 pgit = (Elm_Genlist_GroupItem *)(EINA_INLIST_GET(pgit)->prev);
6011 new_group = EINA_TRUE;
6017 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
6018 EINA_INLIST_GET(it2));
6021 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
6022 EINA_INLIST_GET(it2));
6024 it->rel->relcount++;
6028 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
6031 git->items = eina_list_prepend(git->items, it);
6037 it->group_item = git;
6038 _item_queue(wd, it);
6043 * Moves the Genlist Item
6046 elm_genlist_item_move_after(Elm_Genlist_Item *it, Elm_Genlist_Item *after)
6050 Elm_Genlist_Item *next_item = elm_genlist_item_next_get(after);
6052 if (it->y == after->y && after->reorder_check && it->reorder_check)
6054 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
6055 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
6059 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6060 _item_block_del(it);
6062 if ((!next_item && after->reorder_check) || (next_item && !after->reorder_check))
6065 if (next_item && !after->reorder_check && it == after)
6067 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it),
6068 EINA_INLIST_GET(next_item));
6069 it->rel = next_item;
6073 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it),
6074 EINA_INLIST_GET(after));
6078 it->rel->relcount++;
6085 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it),
6086 EINA_INLIST_GET(after));
6088 it->rel->relcount++;
6092 it->wd->items = eina_inlist_prepend(it->wd->items, EINA_INLIST_GET(it));
6096 after->reorder_check = 0;
6097 _item_queue(it->wd, it);
6101 elm_genlist_set_edit_mode(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class)
6103 fprintf(stderr, "=================> Caution!!! <========================\n");
6104 fprintf(stderr, "==> elm_genlist_set_edit_mode() is deprecated. <=======\n");
6105 fprintf(stderr, "==> Please use elm_genlist_edit_mode_set() instead. <==\n");
6106 fprintf(stderr, "=======================================================\n");
6108 elm_genlist_edit_mode_set(obj, emode, edit_class);
6112 * Set Genlist edit mode
6114 * This sets Genlist edit mode.
6116 * @param obj The Genlist object
6117 * @param emode ELM_GENLIST_EDIT_MODE_{NONE & REORDER & INSERT & DELETE & SELECT & SELECT_ALL}
6118 * @param edit_class Genlist edit class (Elm_Genlist_Edit_Class structure)
6123 elm_genlist_edit_mode_set(Evas_Object *obj, int emode, Elm_Genlist_Edit_Class *edit_class)
6125 Elm_Genlist_Item *it;
6129 static Elm_Genlist_Item_Class itc;
6131 ELM_CHECK_WIDTYPE(obj, widtype);
6132 Widget_Data *wd = elm_widget_data_get(obj);
6134 if (wd->edit_mode == emode) return;
6136 wd->edit_mode = emode;
6137 wd->animate_edit_controls = 1;
6139 if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
6140 wd->edit_mode |= ELM_GENLIST_EDIT_MODE_SELECT;
6142 if (wd->edit_mode_effect_mode)
6144 wd->effect_mode = EINA_TRUE;
6145 wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE;
6148 if (wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
6150 if (wd->ed) free (wd->ed);
6156 wd->ed = calloc(1, sizeof(Edit_Data));
6158 wd->ed->ec = edit_class;
6160 if (((wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT)) && !wd->ed->del_confirm)
6162 wd->ed->del_confirm = elm_button_add(wd->obj);
6163 elm_button_label_set(wd->ed->del_confirm, "Delete");
6164 evas_object_smart_member_add(wd->ed->del_confirm, wd->pan_smart);
6165 edje_object_scale_set(wd->ed->del_confirm, elm_widget_scale_get(wd->ed->del_confirm) *
6166 _elm_config->scale);
6167 evas_object_smart_callback_add(wd->ed->del_confirm, "clicked", _delete_confirm_cb, wd);
6170 EINA_INLIST_FOREACH(wd->blocks, itb)
6172 EINA_LIST_FOREACH(itb->items, l, it)
6174 it->delete_check = 0;
6175 it->del_confirm_state = 0;
6177 _edit_controls_eval(it);
6180 if (wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECTALL)
6182 if (edit_class->select_all_item_style && strcmp(edit_class->select_all_item_style, "default"))
6183 itc.item_style = edit_class->select_all_item_style;
6185 itc.item_style = "select_all";
6186 itc.func.label_get = NULL;
6187 itc.func.icon_get = NULL;
6188 itc.func.del = NULL;
6189 itc.func.editmode_get = NULL;
6191 wd->select_all_item = _item_new(wd, &itc, (void *)(edit_class->select_all_data), NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
6194 if (!wd->select_all_item) return;
6196 _item_realize(wd->select_all_item, 0, 0);
6197 edje_object_signal_callback_add(wd->select_all_item->base, "elm,action,select,press", "elm", _select_all_down, wd->select_all_item);
6199 wd->select_all_item->rel = NULL;
6200 wd->select_all_item->selected = 0;
6201 wd->select_all_item->before = 1;
6202 wd->select_all_item->block = NULL;
6203 wd->select_all_minh = wd->minh + wd->select_all_item->h;
6205 else if (wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_EDIT_MODE)
6207 if (wd->select_all_item)
6209 if (wd->select_all_item->realized) _item_unrealize(wd->select_all_item);
6210 free(wd->select_all_item);
6212 wd->select_all_item = NULL;
6214 edje_object_signal_emit(wd->scr, "elm,state,edit,animated,enable", "elm");
6216 if (wd->calc_job) ecore_job_del(wd->calc_job);
6217 wd->calc_job = ecore_job_add(_calc_job, wd);
6221 * Delete selected items in genlist edit mode.
6223 * @param obj The genlist object
6228 elm_genlist_edit_selected_items_del(Evas_Object *obj)
6230 Elm_Genlist_Item *it;
6232 Item_Block *itb = NULL;
6234 ELM_CHECK_WIDTYPE(obj, widtype);
6235 Widget_Data *wd = elm_widget_data_get(obj);
6237 if (!wd->blocks) return;
6240 EINA_INLIST_FOREACH(wd->blocks, itb)
6242 if (!wd->blocks) break;
6246 EINA_LIST_FOREACH(itb->items, l, it)
6248 if (it->delete_check)
6250 it->wd->effect_mode = EINA_TRUE;
6254 itb->wd->minh -= it->h;
6255 itb->wd->select_all_minh -= it->h;
6258 if ((it->relcount > 0) || (it->walking > 0))
6260 elm_genlist_item_subitems_clear(it);
6261 it->delete_me = EINA_TRUE;
6262 if (it->wd->show_item == it) it->wd->show_item = NULL;
6263 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6266 if (it->realized) _item_unrealize(it);
6267 it->block->changed = EINA_TRUE;
6269 if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj);
6273 it->wd->walking -= it->walking;
6274 if (it->wd->show_item == it) it->wd->show_item = NULL;
6275 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
6276 if (it->realized) _item_unrealize(it);
6278 EINA_LIST_FREE(it->edit_icon_objs, icon)
6279 evas_object_del(icon);
6281 Evas_Object *editfield;
6282 EINA_LIST_FREE(it->wd->edit_field, editfield)
6283 evas_object_del(editfield);
6285 evas_object_del(it->edit_obj);
6286 it->edit_obj = NULL;
6288 itb->items = eina_list_remove(itb->items, it);
6290 itb->changed = EINA_TRUE;
6291 if ((!it->delete_me) && (it->itc->func.del))
6292 it->itc->func.del(it->data, it->wd->obj);
6293 it->delete_me = EINA_TRUE;
6295 it->wd->queue = eina_list_remove(it->wd->queue, it);
6296 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
6298 it->parent->items = eina_list_remove(it->parent->items, it);
6299 if (it->long_timer) ecore_timer_del(it->long_timer);
6301 it->group_item->items = eina_list_remove(it->group_item->items,it);
6308 evas_render(evas_object_evas_get(wd->obj));
6309 if (wd->calc_job) ecore_job_del(wd->calc_job);
6310 wd->calc_job = ecore_job_add(_calc_job, wd);
6315 elm_genlist_selected_items_del(Evas_Object *obj)
6317 fprintf(stderr, "=================> Caution!!! <========================\n");
6318 fprintf(stderr, "==> elm_genlist_selected_items_del() is deprecated. <=======\n");
6319 fprintf(stderr, "==> Please use elm_genlist_edit_selected_items_del() instead. <==\n");
6320 fprintf(stderr, "=======================================================\n");
6321 elm_genlist_edit_selected_items_del(obj);
6325 * Get a list of selected items in genlist
6327 * This returns a list of the selected items in the genlist. The list
6328 * contains Elm_Genlist_Item pointers. The list must be freed by the
6329 * caller when done with eina_list_free(). The item pointers in the list
6330 * are only vallid so long as those items are not deleted or the genlist is
6333 * @param obj The genlist object
6334 * @return The list of selected items, nor NULL if none are selected.
6339 elm_genlist_edit_selected_items_get(const Evas_Object *obj)
6341 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6342 Widget_Data *wd = elm_widget_data_get(obj);
6343 Eina_List *list = NULL;
6345 if (!wd) return NULL;
6347 EINA_INLIST_FOREACH(wd->blocks, itb)
6350 Elm_Genlist_Item *it;
6352 EINA_LIST_FOREACH(itb->items, l, it)
6354 if (it->delete_check) list = eina_list_append(list, it);
6362 * Set a given item's rename mode
6364 * This renames the item's label from genlist
6366 * @param it The item
6367 * @param emode set if emode is EINA_TRUE, unset if emode is EINA_FALSE
6372 elm_genlist_item_rename_mode_set(Elm_Genlist_Item *it, int emode)
6376 const Eina_List *l, *list, *l2;
6377 const char *label, *rename_swallow_part;
6379 Eina_Bool done = EINA_FALSE;
6380 int label_cnt = 0 , swallow_part_cnt = 0;
6383 Evas_Object *editfield;
6384 Evas_Object *entry = NULL;
6385 int edit_field_cnt = 0;
6388 if (it->wd->edit_mode == ELM_GENLIST_EDIT_MODE_NONE)
6390 it->wd->edit_mode = 0xF0;
6391 _edit_controls_eval(it);
6394 EINA_INLIST_FOREACH(it->wd->blocks, itb)
6399 Elm_Genlist_Item *it;
6402 EINA_LIST_FOREACH(itb->items, l, it)
6406 it->renamed = EINA_FALSE;
6409 EINA_LIST_FOREACH(it->wd->edit_field, l2, editfield)
6411 entry = elm_editfield_entry_get(editfield);
6412 const char *text = elm_entry_entry_get(entry);
6414 if (it->itc->func.label_changed)
6415 it->itc->func.label_changed(it->data, it, text, edit_field_cnt++);
6417 Ecore_IMF_Context *imf = elm_entry_imf_context_get(entry);
6418 ecore_imf_context_input_panel_hide(imf);
6420 Evas_Object *editfield;
6421 EINA_LIST_FREE(it->wd->edit_field, editfield)
6422 evas_object_del(editfield);
6424 if (it->wd->edit_mode)
6426 if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_INSERT))
6427 edje_object_signal_emit(it->edit_obj, "elm,state,ins,enable", "elm");
6429 if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_DELETE) || (it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_SELECT))
6430 edje_object_signal_emit(it->edit_obj, "elm,state,del,enable", "elm");
6432 if ((it->wd->edit_mode & ELM_GENLIST_EDIT_MODE_REORDER))
6433 edje_object_signal_emit(it->edit_obj, "elm,state,rename,disable", "elm");
6437 evas_object_del(it->edit_obj);
6438 it->edit_obj = NULL;
6440 EINA_LIST_FREE(it->edit_icon_objs, icon)
6441 evas_object_del(icon);
6451 // if (emode != ELM_GENLIST_RENAME_MODE_NONE)
6454 it->renamed = EINA_TRUE;
6456 it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
6457 EINA_LIST_FOREACH(it->labels, list, label)
6459 edje_object_signal_emit(it->edit_obj, "elm,state,rename,enable", "elm");
6460 edje_object_signal_emit(it->edit_obj, "elm,state,ins,disable", "elm");
6461 edje_object_signal_emit(it->edit_obj, "elm,state,del,disable", "elm");
6462 edje_object_signal_emit(it->edit_obj, "elm,state,edit_end,disable", "elm");
6464 if (it->itc->func.label_get)
6466 it->renamed = EINA_TRUE;
6467 swallow_part_cnt = 0;
6469 EINA_LIST_FREE(it->edit_icon_objs, icon)
6470 evas_object_del(icon);
6471 Eina_List *rename = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "rename"));
6472 EINA_LIST_FOREACH(rename, l, rename_swallow_part)
6474 if (label_cnt == swallow_part_cnt)
6476 editfield = elm_editfield_add(it->wd->obj);
6477 it->wd->edit_field = eina_list_append(it->wd->edit_field, editfield);
6479 elm_editfield_entry_single_line_set(editfield, EINA_TRUE);
6480 elm_editfield_eraser_set(editfield, EINA_TRUE);
6481 edje_object_part_swallow(it->edit_obj, rename_swallow_part, editfield);
6483 evas_object_show(editfield);
6485 s = it->itc->func.label_get(it->data, it->wd->obj, list->data);
6489 Evas_Object *entry = elm_editfield_entry_get(editfield);
6490 elm_entry_entry_set(entry,s);
6495 elm_editfield_guide_text_set(editfield, "Text Input");
6504 if (it->wd->edit_mode == 0xF0)
6506 it->wd->edit_mode = 0;