Merge from TIZEN 2.3
[platform/core/uifw/e17.git] / src / bin / e_ilist.c
1 #include "e.h"
2
3 #define SMART_NAME     "e_ilist"
4 #define API_ENTRY      E_Smart_Data * sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME)))
5 #define INTERNAL_ENTRY E_Smart_Data * sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
6
7 typedef struct _E_Smart_Data E_Smart_Data;
8 struct _E_Smart_Data
9 {
10    Evas_Coord    x, y, w, h, iw, ih;
11    Evas_Object  *o_smart, *o_edje, *o_box;
12    Eina_List    *items;
13    Eina_List    *selected_items;
14    int           selected;
15    const char *theme;
16    unsigned char selector : 1;
17    unsigned char multi_select : 1;
18    unsigned char on_hold : 1;
19
20    struct
21    {
22       char        *buf;
23       unsigned int size;
24       Ecore_Timer *timer;
25    } typebuf;
26 };
27
28 static void      _e_smart_init(void);
29 static void      _e_smart_add(Evas_Object *obj);
30 static void      _e_smart_del(Evas_Object *obj);
31 static void      _e_smart_show(Evas_Object *obj);
32 static void      _e_smart_hide(Evas_Object *obj);
33 static void      _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
34 static void      _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
35 static void      _e_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
36 static void      _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
37 static void      _e_smart_clip_unset(Evas_Object *obj);
38 static void      _e_smart_reconfigure(E_Smart_Data *sd);
39 static void      _e_smart_event_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
40 static void      _e_smart_event_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info);
41 static void      _e_smart_event_key_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
42
43 static void      _e_typebuf_add(Evas_Object *obj, const char *s);
44 static void      _e_typebuf_match(Evas_Object *obj);
45 static Eina_Bool _e_typebuf_timer_cb(void *data);
46 static void      _e_typebuf_timer_update(Evas_Object *obj);
47 static void      _e_typebuf_timer_delete(Evas_Object *obj);
48 static void      _e_typebuf_clean(Evas_Object *obj);
49
50 static void      _e_ilist_item_theme_set(E_Ilist_Item *si, Eina_Bool custom, Eina_Bool header, Eina_Bool even);
51 static void      _e_ilist_widget_hack_cb(E_Smart_Data *sd, Evas_Object *obj __UNUSED__, Evas_Object *scr);
52
53 static void      _item_select(E_Ilist_Item *si);
54 static void      _item_unselect(E_Ilist_Item *si);
55
56 static Evas_Smart *_e_smart = NULL;
57
58 EAPI Evas_Object *
59 e_ilist_add(Evas *evas)
60 {
61    _e_smart_init();
62    return evas_object_smart_add(evas, _e_smart);
63 }
64
65 EAPI void
66 e_ilist_append(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, int header, void (*func)(void *data, void *data2), void (*func_hilight)(void *data, void *data2), void *data, void *data2)
67 {
68    E_Ilist_Item *si;
69    Evas_Coord mw = 0, mh = 0;
70    int isodd;
71    const char *stacking;
72
73    API_ENTRY return;
74    si = E_NEW(E_Ilist_Item, 1);
75    si->sd = sd;
76    si->o_base = edje_object_add(evas_object_evas_get(sd->o_smart));
77
78    isodd = eina_list_count(sd->items) & 0x1;
79    _e_ilist_item_theme_set(si, !!sd->theme, header, !isodd);
80    if (label)
81      {
82         si->label = eina_stringshare_add(label);
83         edje_object_part_text_set(si->o_base, "e.text.label", label);
84      }
85
86    si->o_icon = icon;
87    if (si->o_icon)
88      {
89         edje_extern_object_min_size_set(si->o_icon, sd->iw, sd->ih);
90         edje_object_part_swallow(si->o_base, "e.swallow.icon", si->o_icon);
91         evas_object_show(si->o_icon);
92      }
93    si->o_end = end;
94    if (si->o_end)
95      {
96         Evas_Coord ew = 0, eh = 0;
97
98         evas_object_size_hint_min_get(si->o_end, &ew, &eh);
99         if ((ew <= 0) || (eh <= 0))
100           {
101              ew = sd->iw;
102              eh = sd->ih;
103           }
104         edje_extern_object_min_size_set(si->o_end, ew, eh);
105         edje_object_part_swallow(si->o_base, "e.swallow.end", si->o_end);
106         evas_object_show(si->o_end);
107      }
108    si->func = func;
109    si->func_hilight = func_hilight;
110    si->data = data;
111    si->data2 = data2;
112    si->header = header;
113    sd->items = eina_list_append(sd->items, si);
114
115    edje_object_size_min_calc(si->o_base, &mw, &mh);
116    e_box_freeze(sd->o_box);
117    e_box_pack_end(sd->o_box, si->o_base);
118    e_box_pack_options_set(si->o_base, 1, 1, 1, 1, 0.5, 0.5,
119                           mw, mh, 99999, 99999);
120    stacking = edje_object_data_get(si->o_base, "stacking");
121    if (stacking)
122      {
123         if (!strcmp(stacking, "below")) evas_object_lower(si->o_base);
124         else if (!strcmp(stacking, "above"))
125           evas_object_raise(si->o_base);
126      }
127    e_box_thaw(sd->o_box);
128
129    evas_object_lower(sd->o_box);
130    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_DOWN,
131                                   _e_smart_event_mouse_down, si);
132    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_UP,
133                                   _e_smart_event_mouse_up, si);
134    evas_object_show(si->o_base);
135 }
136
137 EAPI void
138 e_ilist_append_relative(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, int header, void (*func)(void *data, void *data2), void (*func_hilight)(void *data, void *data2), void *data, void *data2, int relative)
139 {
140    E_Ilist_Item *si, *ri;
141    Evas_Coord mw = 0, mh = 0;
142    int isodd;
143    const char *stacking;
144
145    API_ENTRY return;
146    si = E_NEW(E_Ilist_Item, 1);
147    si->sd = sd;
148    si->o_base = edje_object_add(evas_object_evas_get(sd->o_smart));
149
150    isodd = eina_list_count(sd->items) & 0x1;
151    _e_ilist_item_theme_set(si, !!sd->theme, header, !isodd);
152    if (label)
153      {
154         si->label = eina_stringshare_add(label);
155         edje_object_part_text_set(si->o_base, "e.text.label", label);
156      }
157
158    si->o_icon = icon;
159    if (si->o_icon)
160      {
161         edje_extern_object_min_size_set(si->o_icon, sd->iw, sd->ih);
162         edje_object_part_swallow(si->o_base, "e.swallow.icon", si->o_icon);
163         evas_object_show(si->o_icon);
164      }
165    si->o_end = end;
166    if (si->o_end)
167      {
168         Evas_Coord ew = 0, eh = 0;
169         evas_object_size_hint_min_get(si->o_end, &ew, &eh);
170         if ((ew <= 0) || (eh <= 0))
171           {
172              ew = sd->iw;
173              eh = sd->ih;
174           }
175         edje_extern_object_min_size_set(si->o_end, ew, eh);
176         edje_object_part_swallow(si->o_base, "e.swallow.end", si->o_end);
177         evas_object_show(si->o_end);
178      }
179    si->func = func;
180    si->func_hilight = func_hilight;
181    si->data = data;
182    si->data2 = data2;
183    si->header = header;
184
185    ri = eina_list_nth(sd->items, relative);
186    if (ri)
187      sd->items = eina_list_append_relative(sd->items, si, ri);
188    else
189      sd->items = eina_list_append(sd->items, si);
190
191    edje_object_size_min_calc(si->o_base, &mw, &mh);
192    e_box_freeze(sd->o_box);
193    if (ri)
194      e_box_pack_after(sd->o_box, si->o_base, ri->o_base);
195    else
196      e_box_pack_end(sd->o_box, si->o_base);
197    e_box_pack_options_set(si->o_base, 1, 1, 1, 1, 0.5, 0.5,
198                           mw, mh, 99999, 99999);
199    stacking = edje_object_data_get(si->o_base, "stacking");
200    if (stacking)
201      {
202         if (!strcmp(stacking, "below")) evas_object_lower(si->o_base);
203         else if (!strcmp(stacking, "above"))
204           evas_object_raise(si->o_base);
205      }
206    e_box_thaw(sd->o_box);
207
208    evas_object_lower(sd->o_box);
209    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_DOWN,
210                                   _e_smart_event_mouse_down, si);
211    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_UP,
212                                   _e_smart_event_mouse_up, si);
213    evas_object_show(si->o_base);
214 }
215
216 EAPI void
217 e_ilist_prepend(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, int header, void (*func)(void *data, void *data2), void (*func_hilight)(void *data, void *data2), void *data, void *data2)
218 {
219    E_Ilist_Item *si;
220    Evas_Coord mw = 0, mh = 0;
221    int isodd;
222
223    API_ENTRY return;
224    si = E_NEW(E_Ilist_Item, 1);
225    si->sd = sd;
226    si->o_base = edje_object_add(evas_object_evas_get(sd->o_smart));
227
228    isodd = eina_list_count(sd->items) & 0x1;
229    _e_ilist_item_theme_set(si, !!sd->theme, header, !isodd);
230    if (label)
231      {
232         si->label = eina_stringshare_add(label);
233         edje_object_part_text_set(si->o_base, "e.text.label", label);
234      }
235
236    si->o_icon = icon;
237    if (si->o_icon)
238      {
239         edje_extern_object_min_size_set(si->o_icon, sd->iw, sd->ih);
240         edje_object_part_swallow(si->o_base, "e.swallow.icon", si->o_icon);
241         evas_object_show(si->o_icon);
242      }
243    si->o_end = end;
244    if (si->o_end)
245      {
246         Evas_Coord ew = 0, eh = 0;
247         evas_object_size_hint_min_get(si->o_end, &ew, &eh);
248         if ((ew <= 0) || (eh <= 0))
249           {
250              ew = sd->iw;
251              eh = sd->ih;
252           }
253         edje_extern_object_min_size_set(si->o_end, ew, eh);
254         edje_object_part_swallow(si->o_base, "e.swallow.end", si->o_end);
255         evas_object_show(si->o_end);
256      }
257    si->func = func;
258    si->func_hilight = func_hilight;
259    si->data = data;
260    si->data2 = data2;
261    si->header = header;
262    sd->items = eina_list_prepend(sd->items, si);
263
264    edje_object_size_min_calc(si->o_base, &mw, &mh);
265    e_box_freeze(sd->o_box);
266    e_box_pack_start(sd->o_box, si->o_base);
267    e_box_pack_options_set(si->o_base, 1, 1, 1, 1, 0.5, 0.5,
268                           mw, mh, 99999, 99999);
269    e_box_thaw(sd->o_box);
270
271    evas_object_lower(sd->o_box);
272    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_DOWN,
273                                   _e_smart_event_mouse_down, si);
274    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_UP,
275                                   _e_smart_event_mouse_up, si);
276    evas_object_show(si->o_base);
277 }
278
279 EAPI void
280 e_ilist_prepend_relative(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, int header, void (*func)(void *data, void *data2), void (*func_hilight)(void *data, void *data2), void *data, void *data2, int relative)
281 {
282    E_Ilist_Item *si, *ri;
283    Evas_Coord mw = 0, mh = 0;
284    int isodd;
285
286    API_ENTRY return;
287    si = E_NEW(E_Ilist_Item, 1);
288    si->sd = sd;
289    si->o_base = edje_object_add(evas_object_evas_get(sd->o_smart));
290
291    isodd = eina_list_count(sd->items) & 0x1;
292    _e_ilist_item_theme_set(si, !!sd->theme, header, !isodd);
293    if (label)
294      {
295         si->label = eina_stringshare_add(label);
296         edje_object_part_text_set(si->o_base, "e.text.label", label);
297      }
298
299    si->o_icon = icon;
300    if (si->o_icon)
301      {
302         edje_extern_object_min_size_set(si->o_icon, sd->iw, sd->ih);
303         edje_object_part_swallow(si->o_base, "e.swallow.icon", si->o_icon);
304         evas_object_show(si->o_icon);
305      }
306    si->o_end = end;
307    if (si->o_end)
308      {
309         Evas_Coord ew = 0, eh = 0;
310
311         evas_object_size_hint_min_get(si->o_end, &ew, &eh);
312         if ((ew <= 0) || (eh <= 0))
313           {
314              ew = sd->iw;
315              eh = sd->ih;
316           }
317         edje_extern_object_min_size_set(si->o_end, ew, eh);
318         edje_object_part_swallow(si->o_base, "e.swallow.end", si->o_end);
319         evas_object_show(si->o_end);
320      }
321    si->func = func;
322    si->func_hilight = func_hilight;
323    si->data = data;
324    si->data2 = data2;
325    si->header = header;
326
327    ri = eina_list_nth(sd->items, relative);
328    if (ri)
329      sd->items = eina_list_prepend_relative(sd->items, si, ri);
330    else
331      sd->items = eina_list_prepend(sd->items, si);
332
333    edje_object_size_min_calc(si->o_base, &mw, &mh);
334    e_box_freeze(sd->o_box);
335    if (ri)
336      e_box_pack_before(sd->o_box, si->o_base, ri->o_base);
337    else
338      e_box_pack_end(sd->o_box, si->o_base);
339    e_box_pack_options_set(si->o_base, 1, 1, 1, 1, 0.5, 0.5,
340                           mw, mh, 99999, 99999);
341    e_box_thaw(sd->o_box);
342
343    evas_object_lower(sd->o_box);
344    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_DOWN,
345                                   _e_smart_event_mouse_down, si);
346    evas_object_event_callback_add(si->o_base, EVAS_CALLBACK_MOUSE_UP,
347                                   _e_smart_event_mouse_up, si);
348    evas_object_show(si->o_base);
349 }
350
351 EAPI void
352 e_ilist_clear(Evas_Object *obj)
353 {
354    E_Ilist_Item *si = NULL;
355
356    API_ENTRY return;
357
358    e_ilist_freeze(obj);
359    EINA_LIST_FREE(sd->items, si)
360      {
361         if (!si) continue;
362         if (si->o_icon) evas_object_del(si->o_icon);
363         if (si->o_end) evas_object_del(si->o_end);
364         if (si->label) eina_stringshare_del(si->label);
365         evas_object_del(si->o_base);
366         E_FREE(si);
367      }
368    if (sd->selected_items) sd->selected_items = eina_list_free(sd->selected_items);
369    e_ilist_thaw(obj);
370    sd->selected = -1;
371 }
372
373 EAPI void
374 e_ilist_freeze(Evas_Object *obj)
375 {
376    API_ENTRY return;
377    e_box_freeze(sd->o_box);
378 }
379
380 EAPI void
381 e_ilist_thaw(Evas_Object *obj)
382 {
383    API_ENTRY return;
384    e_box_thaw(sd->o_box);
385 }
386
387 EAPI int
388 e_ilist_count(Evas_Object *obj)
389 {
390    API_ENTRY return 0;
391    return eina_list_count(sd->items);
392 }
393
394 EAPI int
395 e_ilist_selector_get(Evas_Object *obj)
396 {
397    API_ENTRY return 0;
398    return sd->selector;
399 }
400
401 EAPI void
402 e_ilist_selector_set(Evas_Object *obj, int selector)
403 {
404    API_ENTRY return;
405    sd->selector = selector;
406 }
407
408 EAPI Eina_Bool
409 e_ilist_multi_select_get(Evas_Object *obj)
410 {
411    API_ENTRY return 0;
412    return sd->multi_select;
413 }
414
415 EAPI void
416 e_ilist_multi_select_set(Evas_Object *obj, Eina_Bool multi)
417 {
418    API_ENTRY return;
419    sd->multi_select = multi;
420 }
421
422 EAPI void
423 e_ilist_size_min_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
424 {
425    API_ENTRY return;
426    e_box_size_min_get(sd->o_box, w, h);
427 }
428
429 EAPI void
430 e_ilist_unselect(Evas_Object *obj)
431 {
432    E_Ilist_Item *si = NULL;
433
434    API_ENTRY return;
435
436    if (!sd->items) return;
437    if (sd->selected < 0) return;
438    EINA_LIST_FREE(sd->selected_items, si)
439      {
440         if (!si) continue;
441         _item_unselect(si);
442      }
443    sd->selected = -1;
444 }
445
446 EAPI void
447 e_ilist_selected_set(Evas_Object *obj, int n)
448 {
449    E_Ilist_Item *si = NULL;
450    int i;
451
452    API_ENTRY return;
453    if (!sd->items) return;
454
455    i = eina_list_count(sd->items);
456    if (n >= i) n = i - 1;
457    else if (n < 0)
458      n = 0;
459
460    e_ilist_unselect(obj);
461    if (!(si = eina_list_nth(sd->items, n))) return;
462
463    /* NB: Remove this if headers ever become selectable */
464    while (si->header && ((++n) < i))
465      if (!(si = eina_list_nth(sd->items, n))) return;
466    while (si->header && ((--n) >= 0))
467      if (!(si = eina_list_nth(sd->items, n))) return;
468    if (si->header) return;
469
470    _item_select(si);
471    sd->selected = n;
472    if (si->func_hilight) si->func_hilight(si->data, si->data2);
473    if (sd->selector) return;
474    if (!sd->on_hold)
475      {
476         if (si->func) si->func(si->data, si->data2);
477      }
478 }
479
480 EAPI const Eina_List *
481 e_ilist_selected_items_get(Evas_Object *obj)
482 {
483    API_ENTRY return NULL;
484    return sd->selected_items;
485 }
486
487 EAPI int
488 e_ilist_selected_get(Evas_Object *obj)
489 {
490    Eina_List *l = NULL;
491    E_Ilist_Item *li = NULL;
492    int i, j;
493
494    API_ENTRY return -1;
495    if (!sd->items) return -1;
496    if (!sd->multi_select)
497      return sd->selected;
498    j = -1;
499    i = 0;
500    EINA_LIST_FOREACH(sd->selected_items, l, li)
501      {
502         if (li && li->selected) j = i;
503         i++;
504      }
505    return j;
506 }
507
508 EAPI const char *
509 e_ilist_selected_label_get(Evas_Object *obj)
510 {
511    E_Ilist_Item *si = NULL;
512
513    API_ENTRY return NULL;
514    if (!sd->items) return NULL;
515    if (sd->multi_select) return NULL;
516    if (sd->selected < 0) return NULL;
517    si = eina_list_nth(sd->items, sd->selected);
518    if (si)
519      {
520         if (!si->label)
521           {
522              si->label =
523                eina_stringshare_add(edje_object_part_text_get(si->o_base,
524                                                               "e.text.label"));
525           }
526         if (si->label) return si->label;
527      }
528    return NULL;
529 }
530
531 EAPI void *
532 e_ilist_selected_data_get(Evas_Object *obj)
533 {
534    E_Ilist_Item *si = NULL;
535
536    API_ENTRY return NULL;
537    if (!sd->items) return NULL;
538    if (sd->multi_select) return NULL;
539    if (sd->selected < 0) return NULL;
540    si = eina_list_nth(sd->items, sd->selected);
541    if (si) return si->data;
542    return NULL;
543 }
544
545 EAPI void *
546 e_ilist_selected_data2_get(Evas_Object *obj)
547 {
548    E_Ilist_Item *si = NULL;
549
550    API_ENTRY return NULL;
551    if (!sd->items) return NULL;
552    if (sd->multi_select) return NULL;
553    if (sd->selected < 0) return NULL;
554    si = eina_list_nth(sd->items, sd->selected);
555    if (si) return si->data2;
556    return NULL;
557 }
558
559 EAPI Evas_Object *
560 e_ilist_selected_icon_get(Evas_Object *obj)
561 {
562    E_Ilist_Item *si = NULL;
563
564    API_ENTRY return NULL;
565    if (!sd->items) return NULL;
566    if (sd->multi_select) return NULL;
567    if (sd->selected < 0) return NULL;
568    si = eina_list_nth(sd->items, sd->selected);
569    if (si) return si->o_icon;
570    return NULL;
571 }
572
573 EAPI Evas_Object *
574 e_ilist_selected_end_get(Evas_Object *obj)
575 {
576    E_Ilist_Item *si = NULL;
577
578    API_ENTRY return NULL;
579    if (!sd->items) return NULL;
580    if (sd->multi_select) return NULL;
581    if (sd->selected < 0) return NULL;
582    si = eina_list_nth(sd->items, sd->selected);
583    if (si) return si->o_end;
584    return NULL;
585 }
586
587 EAPI void
588 e_ilist_selected_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
589 {
590    E_Ilist_Item *si = NULL;
591
592    API_ENTRY return;
593    if (!sd->items) return;
594    if (sd->selected < 0) return;
595    if (!(si = eina_list_nth(sd->items, sd->selected))) return;
596    evas_object_geometry_get(si->o_base, x, y, w, h);
597    *x -= sd->x;
598    *y -= sd->y;
599 }
600
601 EAPI int
602 e_ilist_selected_count_get(Evas_Object *obj)
603 {
604    API_ENTRY return 0;
605    if (!sd->items) return 0;
606    return eina_list_count(sd->selected_items);
607 }
608
609 EAPI void
610 e_ilist_remove_num(Evas_Object *obj, int n)
611 {
612    E_Ilist_Item *si = NULL;
613    Eina_List *item;
614
615    API_ENTRY return;
616    if (!sd->items) return;
617    item = eina_list_nth_list(sd->items, n);
618    if (!item) return;
619    si = eina_list_data_get(item);
620    if (!si) return;
621    sd->items = eina_list_remove_list(sd->items, item);
622    if (si->selected) sd->selected_items = eina_list_remove(sd->selected_items, si);
623
624    if (sd->selected == n) sd->selected = -1;
625    if (si->o_icon) evas_object_del(si->o_icon);
626    if (si->o_end) evas_object_del(si->o_end);
627    if (si->label) eina_stringshare_del(si->label);
628    evas_object_del(si->o_base);
629    E_FREE(si);
630 }
631
632 EAPI const char *
633 e_ilist_nth_label_get(Evas_Object *obj, int n)
634 {
635    E_Ilist_Item *si = NULL;
636
637    API_ENTRY return NULL;
638    if (!sd->items) return NULL;
639    si = eina_list_nth(sd->items, n);
640    if (si)
641      {
642         if (!si->label)
643           {
644              si->label =
645                eina_stringshare_add(edje_object_part_text_get(si->o_base,
646                                                               "e.text.label"));
647           }
648         if (si->label) return si->label;
649      }
650    return NULL;
651 }
652
653 EAPI void
654 e_ilist_nth_label_set(Evas_Object *obj, int n, const char *label)
655 {
656    E_Ilist_Item *si = NULL;
657
658    /* check for a NULL label first...simpler, faster check then doing
659     * API_ENTRY check first */
660    if (!label) return;
661    API_ENTRY return;
662    if (!sd->items) return;
663    si = eina_list_nth(sd->items, n);
664    if (si)
665      {
666         if (eina_stringshare_replace(&si->label, label))
667           edje_object_part_text_set(si->o_base, "e.text.label", label);
668      }
669 }
670
671 EAPI Evas_Object *
672 e_ilist_nth_icon_get(Evas_Object *obj, int n)
673 {
674    E_Ilist_Item *si = NULL;
675
676    API_ENTRY return NULL;
677    if (!sd->items) return NULL;
678    si = eina_list_nth(sd->items, n);
679    if (si) return si->o_icon;
680    return NULL;
681 }
682
683 EAPI void
684 e_ilist_nth_icon_set(Evas_Object *obj, int n, Evas_Object *icon)
685 {
686    E_Ilist_Item *si = NULL;
687
688    API_ENTRY return;
689    if (!sd->items) return;
690    if (!(si = eina_list_nth(sd->items, n))) return;
691    if (si->o_icon)
692      {
693         edje_object_part_unswallow(si->o_base, si->o_icon);
694         evas_object_del(si->o_icon);
695      }
696    si->o_icon = icon;
697    if (si->o_icon)
698      {
699         edje_extern_object_min_size_set(si->o_icon, sd->iw, sd->ih);
700         edje_object_part_swallow(si->o_base, "e.swallow.icon", si->o_icon);
701         evas_object_show(si->o_icon);
702      }
703 }
704
705 EAPI Evas_Object *
706 e_ilist_nth_end_get(Evas_Object *obj, int n)
707 {
708    E_Ilist_Item *si = NULL;
709
710    API_ENTRY return NULL;
711    if (!sd->items) return NULL;
712    si = eina_list_nth(sd->items, n);
713    if (si) return si->o_end;
714    return NULL;
715 }
716
717 EAPI void
718 e_ilist_nth_end_set(Evas_Object *obj, int n, Evas_Object *end)
719 {
720    E_Ilist_Item *si = NULL;
721
722    API_ENTRY return;
723    if (!sd->items) return;
724    if (!(si = eina_list_nth(sd->items, n))) return;
725    if (si->o_end)
726      {
727         edje_object_part_unswallow(si->o_base, si->o_end);
728         evas_object_del(si->o_end);
729      }
730    si->o_end = end;
731    if (si->o_end)
732      {
733         edje_extern_object_min_size_set(si->o_end, sd->iw, sd->ih);
734         edje_object_part_swallow(si->o_base, "e.swallow.end", si->o_end);
735         evas_object_show(si->o_end);
736      }
737 }
738
739 EAPI Eina_Bool
740 e_ilist_nth_is_header(Evas_Object *obj, int n)
741 {
742    E_Ilist_Item *si = NULL;
743
744    API_ENTRY return 0;
745    if (!sd->items) return 0;
746    si = eina_list_nth(sd->items, n);
747    if (si) return si->header;
748    return 0;
749 }
750
751 EAPI void
752 e_ilist_nth_geometry_get(Evas_Object *obj, int n, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
753 {
754    E_Ilist_Item *si = NULL;
755
756    API_ENTRY return;
757    if (!sd->items) return;
758    if (!(si = eina_list_nth(sd->items, n))) return;
759    evas_object_geometry_get(si->o_base, x, y, w, h);
760    *x -= sd->x;
761    *y -= sd->y;
762 }
763
764 EAPI void
765 e_ilist_icon_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
766 {
767    Eina_List *l = NULL;
768    E_Ilist_Item *si = NULL;
769
770    API_ENTRY return;
771    if ((sd->iw == w) && (sd->ih == h)) return;
772    sd->iw = w;
773    sd->ih = h;
774    EINA_LIST_FOREACH(sd->items, l, si)
775      {
776         Evas_Coord mw = 0, mh = 0;
777
778         if (!si) continue;
779         if (!si->o_icon) continue;
780         edje_extern_object_min_size_set(si->o_icon, w, h);
781         edje_object_part_swallow(si->o_base, "e.swallow.icon", si->o_icon);
782
783         if (si->o_end)
784           {
785              Evas_Coord ew = 0, eh = 0;
786
787              evas_object_size_hint_min_get(si->o_end, &ew, &eh);
788              if ((ew <= 0) || (eh <= 0))
789                {
790                   ew = w;
791                   eh = h;
792                }
793              edje_extern_object_min_size_set(si->o_end, ew, eh);
794           }
795
796         edje_object_size_min_calc(si->o_base, &mw, &mh);
797         e_box_pack_options_set(si->o_icon, 1, 1, 1, 0, 0.5, 0.5,
798                                mw, mh, 99999, 99999);
799      }
800 }
801
802 EAPI const Eina_List *
803 e_ilist_items_get(Evas_Object *obj)
804 {
805    API_ENTRY return NULL;
806    return sd->items;
807 }
808
809 EAPI void
810 e_ilist_multi_select(Evas_Object *obj, int n)
811 {
812    E_Ilist_Item *si = NULL;
813    int i;
814
815    API_ENTRY return;
816    if ((!sd->items) || (!sd->multi_select)) return;
817
818    i = eina_list_count(sd->items);
819    if (n >= i) n = i - 1;
820    else if (n < 0)
821      n = 0;
822
823    if (!(si = eina_list_nth(sd->items, n))) return;
824    if (si->header) return;
825    sd->selected = n;
826    if (si->selected)
827      {
828         _item_unselect(si);
829         if (si->func_hilight) si->func_hilight(si->data, si->data2);
830         if (sd->selector) return;
831         if (!sd->on_hold)
832           {
833              if (si->func) si->func(si->data, si->data2);
834           }
835         return;
836      }
837    _item_select(si);
838    if (si->func_hilight) si->func_hilight(si->data, si->data2);
839    if (sd->selector) return;
840    if (!sd->on_hold)
841      {
842         if (si->func) si->func(si->data, si->data2);
843      }
844 }
845
846 EAPI void
847 e_ilist_range_select(Evas_Object *obj, int n)
848 {
849    int i, j, dir;
850
851    API_ENTRY return;
852    if ((!sd->items) || (!sd->multi_select)) return;
853
854    i = eina_list_count(sd->items);
855    if (n >= i) n = i - 1;
856    else if (n < 0)
857      n = 0;
858
859    if (n < sd->selected) dir = 0;
860    else dir = 1;
861
862    if (!eina_list_nth(sd->items, n)) return;
863    if (dir == 1)
864      {
865         for (j = (sd->selected + 1); ((j < i) && (j <= n)); j++)
866           e_ilist_multi_select(sd->o_smart, j);
867      }
868    else
869      {
870         for (j = (sd->selected - 1); ((j >= 0) && (j >= n)); j--)
871           e_ilist_multi_select(sd->o_smart, j);
872      }
873 }
874
875 EAPI Eina_Bool
876 e_ilist_custom_edje_file_set(Evas_Object *obj, const char *file, const char *group)
877 {
878    Eina_List *l;
879    E_Ilist_Item *si;
880    Eina_Bool even = EINA_FALSE;
881
882    API_ENTRY return EINA_FALSE;
883
884    if (!edje_object_file_set(sd->o_edje, file, group)) return EINA_FALSE;
885    eina_stringshare_replace(&sd->theme, group);
886
887    EINA_LIST_FOREACH(sd->items, l, si)
888      {
889         _e_ilist_item_theme_set(si, !!sd->theme, si->header, even);
890         if (si->o_icon)
891           edje_object_part_swallow(si->o_base, "e.swallow.icon", si->o_icon);
892         if (si->o_end)
893           edje_object_part_swallow(si->o_base, "e.swallow.end", si->o_end);
894         even = !even;
895      }
896    return EINA_TRUE;
897 }
898
899 /* SMART FUNCTIONS */
900 static void
901 _e_smart_init(void)
902 {
903    if (_e_smart) return;
904    {
905       static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NAME_VERSION(SMART_NAME);
906       if (!sc.add)
907         {
908            sc.add = _e_smart_add;
909            sc.del = _e_smart_del;
910            sc.move = _e_smart_move;
911            sc.resize = _e_smart_resize;
912            sc.show = _e_smart_show;
913            sc.hide = _e_smart_hide;
914            sc.color_set = _e_smart_color_set;
915            sc.clip_set = _e_smart_clip_set;
916            sc.clip_unset = _e_smart_clip_unset;
917         }
918       _e_smart = evas_smart_class_new(&sc);
919    }
920 }
921
922 static void
923 _e_smart_add(Evas_Object *obj)
924 {
925    E_Smart_Data *sd;
926    Evas *e;
927
928    sd = calloc(1, sizeof(E_Smart_Data));
929    if (!sd) return;
930    evas_object_smart_data_set(obj, sd);
931
932    e = evas_object_evas_get(obj);
933
934    sd->o_smart = obj;
935    sd->x = sd->y = sd->w = sd->h = 0;
936    sd->iw = sd->ih = 24;
937    sd->selected = -1;
938    sd->multi_select = 0;
939
940    sd->typebuf.buf = NULL;
941    sd->typebuf.size = 0;
942    sd->typebuf.timer = NULL;
943
944    sd->o_box = e_box_add(e);
945    e_box_align_set(sd->o_box, 0.0, 0.0);
946    e_box_homogenous_set(sd->o_box, 0);
947    evas_object_smart_member_add(sd->o_box, obj);
948    evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
949                                   _e_smart_event_key_down, sd);
950    evas_object_propagate_events_set(obj, 0);
951
952    sd->o_edje = edje_object_add(e);
953    e_theme_edje_object_set(sd->o_edje, "base/theme/widgets", "e/ilist");
954    evas_object_smart_member_add(sd->o_edje, obj);
955
956    evas_object_smart_callback_add(obj, "changed", (Evas_Smart_Cb)_e_ilist_widget_hack_cb, sd);
957 }
958
959 static void
960 _e_smart_del(Evas_Object *obj)
961 {
962    INTERNAL_ENTRY;
963
964    _e_typebuf_clean(obj);
965
966    e_ilist_clear(obj);
967    evas_object_del(sd->o_box);
968    evas_object_del(sd->o_edje);
969    eina_stringshare_del(sd->theme);
970    free(sd);
971 }
972
973 static void
974 _e_smart_show(Evas_Object *obj)
975 {
976    INTERNAL_ENTRY;
977    evas_object_show(sd->o_edje);
978    evas_object_show(sd->o_box);
979 }
980
981 static void
982 _e_smart_hide(Evas_Object *obj)
983 {
984    INTERNAL_ENTRY;
985    evas_object_hide(sd->o_edje);
986    evas_object_hide(sd->o_box);
987 }
988
989 static void
990 _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
991 {
992    INTERNAL_ENTRY;
993    if ((sd->x == x) && (sd->y == y)) return;
994    sd->x = x;
995    sd->y = y;
996    _e_smart_reconfigure(sd);
997 }
998
999 static void
1000 _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
1001 {
1002    INTERNAL_ENTRY;
1003    if ((sd->w == w) && (sd->h == h)) return;
1004    sd->w = w;
1005    sd->h = h;
1006    _e_smart_reconfigure(sd);
1007 }
1008
1009 static void
1010 _e_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
1011 {
1012    INTERNAL_ENTRY;
1013    evas_object_color_set(sd->o_edje, r, g, b, a);
1014    evas_object_color_set(sd->o_box, r, g, b, a);
1015 }
1016
1017 static void
1018 _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
1019 {
1020    INTERNAL_ENTRY;
1021    evas_object_clip_set(sd->o_edje, clip);
1022    evas_object_clip_set(sd->o_box, clip);
1023 }
1024
1025 static void
1026 _e_smart_clip_unset(Evas_Object *obj)
1027 {
1028    INTERNAL_ENTRY;
1029    evas_object_clip_unset(sd->o_edje);
1030    evas_object_clip_unset(sd->o_box);
1031 }
1032
1033 static void
1034 _e_smart_reconfigure(E_Smart_Data *sd)
1035 {
1036    evas_object_move(sd->o_edje, sd->x, sd->y);
1037    evas_object_resize(sd->o_edje, sd->w, sd->h);
1038    evas_object_move(sd->o_box, sd->x, sd->y);
1039    evas_object_resize(sd->o_box, sd->w, sd->h);
1040 }
1041
1042 static void
1043 _e_smart_event_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1044 {
1045    E_Smart_Data *sd;
1046    Evas_Event_Mouse_Down *ev;
1047    E_Ilist_Item *si;
1048
1049    ev = event_info;
1050    si = data;
1051    sd = si->sd;
1052
1053    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = 1;
1054    else sd->on_hold = 0;
1055
1056    /* NB: Remove if headers ever become selectable */
1057    if (si->header) return;
1058
1059    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1060      evas_object_smart_callback_call(sd->o_smart, "selected", NULL);
1061 }
1062
1063 static void
1064 _e_smart_event_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1065 {
1066    E_Smart_Data *sd;
1067    Evas_Event_Mouse_Up *ev;
1068    E_Ilist_Item *si, *item;
1069    Eina_List *l = NULL;
1070    int i;
1071
1072    ev = event_info;
1073    si = data;
1074    sd = si->sd;
1075
1076    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = 1;
1077    else sd->on_hold = 0;
1078
1079    /* NB: Remove if headers ever become selectable */
1080    if (si->header) return;
1081
1082    if (sd->on_hold)
1083      {
1084         sd->on_hold = 0;
1085         return;
1086      }
1087
1088    if (!sd->items) return;
1089
1090    i = 0;
1091    EINA_LIST_FOREACH(sd->items, l, item)
1092      {
1093         if (item == si)
1094           {
1095              if (!sd->multi_select)
1096                e_ilist_selected_set(sd->o_smart, i);
1097              else
1098                {
1099                   if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1100                     e_ilist_range_select(sd->o_smart, i);
1101                   else if (evas_key_modifier_is_set(ev->modifiers, "Control"))
1102                     e_ilist_multi_select(sd->o_smart, i);
1103                   else
1104                     e_ilist_selected_set(sd->o_smart, i);
1105                }
1106              break;
1107           }
1108         i++;
1109      }
1110
1111    if (!sd->selector) return;
1112    if (!(si = eina_list_nth(sd->items, sd->selected))) return;
1113    if (si->func) si->func(si->data, si->data2);
1114 }
1115
1116 static void
1117 _e_smart_event_key_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
1118 {
1119    Evas_Event_Key_Down *ev;
1120    E_Smart_Data *sd;
1121    E_Ilist_Item *si;
1122    int n, ns;
1123
1124    sd = data;
1125    ev = event_info;
1126    ns = sd->selected;
1127
1128    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = 1;
1129    else sd->on_hold = 0;
1130
1131    if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
1132      {
1133         n = ns;
1134         do
1135           {
1136              if (n == 0)
1137                {
1138                   n = ns;
1139                   break;
1140                }
1141              --n;
1142              si = eina_list_nth(sd->items, n);
1143           }
1144         while ((si) && (si->header));
1145         if (n != ns)
1146           {
1147              if (!sd->multi_select)
1148                e_ilist_selected_set(sd->o_smart, n);
1149              else if (evas_key_modifier_is_set(ev->modifiers, "Control"))
1150                e_ilist_multi_select(sd->o_smart, n);
1151              else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1152                e_ilist_range_select(sd->o_smart, n);
1153              else
1154                e_ilist_selected_set(sd->o_smart, n);
1155           }
1156      }
1157    else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
1158      {
1159         n = ns;
1160         do
1161           {
1162              if (n == ((int)eina_list_count(sd->items) - 1))
1163                {
1164                   n = ns;
1165                   break;
1166                }
1167              ++n;
1168              si = eina_list_nth(sd->items, n);
1169           }
1170         while ((si) && (si->header));
1171         if (n != ns)
1172           {
1173              if (!sd->multi_select)
1174                e_ilist_selected_set(sd->o_smart, n);
1175              else if (evas_key_modifier_is_set(ev->modifiers, "Control"))
1176                e_ilist_multi_select(sd->o_smart, n);
1177              else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1178                e_ilist_range_select(sd->o_smart, n);
1179              else
1180                e_ilist_selected_set(sd->o_smart, n);
1181           }
1182      }
1183    else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
1184      {
1185         n = -1;
1186         do
1187           {
1188              if (n == ((int)eina_list_count(sd->items) - 1))
1189                {
1190                   n = ns;
1191                   break;
1192                }
1193              ++n;
1194              si = eina_list_nth(sd->items, n);
1195           }
1196         while ((si) && (si->header));
1197         if (n != ns)
1198           {
1199              if (!sd->multi_select)
1200                e_ilist_selected_set(sd->o_smart, n);
1201              else if (evas_key_modifier_is_set(ev->modifiers, "Control"))
1202                e_ilist_multi_select(sd->o_smart, n);
1203              else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1204                e_ilist_range_select(sd->o_smart, n);
1205              else
1206                e_ilist_selected_set(sd->o_smart, n);
1207           }
1208      }
1209    else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
1210      {
1211         n = eina_list_count(sd->items);
1212         do
1213           {
1214              if (n == 0)
1215                {
1216                   n = ns;
1217                   break;
1218                }
1219              --n;
1220              si = eina_list_nth(sd->items, n);
1221           }
1222         while ((si) && (si->header));
1223         if (n != ns)
1224           {
1225              if (!sd->multi_select)
1226                e_ilist_selected_set(sd->o_smart, n);
1227              else if (evas_key_modifier_is_set(ev->modifiers, "Control"))
1228                e_ilist_multi_select(sd->o_smart, n);
1229              else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1230                e_ilist_range_select(sd->o_smart, n);
1231              else
1232                e_ilist_selected_set(sd->o_smart, n);
1233           }
1234      }
1235    else if ((!strcmp(ev->keyname, "Return")) ||
1236             (!strcmp(ev->keyname, "KP_Enter")) ||
1237             (!strcmp(ev->keyname, "space") && !sd->typebuf.buf))
1238      {
1239         if (!sd->on_hold)
1240           {
1241              si = eina_list_nth(sd->items, sd->selected);
1242              if (si)
1243                {
1244                   if (si->func) si->func(si->data, si->data2);
1245                }
1246           }
1247      }
1248    else if (!strcmp(ev->keyname, "Escape"))
1249      _e_typebuf_clean(obj);
1250    else if (strcmp(ev->keyname, "BackSpace") && strcmp(ev->keyname, "Tab") && ev->string)
1251      _e_typebuf_add(obj, ev->string);
1252
1253    sd->on_hold = 0;
1254 }
1255
1256 static void
1257 _e_ilist_widget_hack_cb(E_Smart_Data *sd, Evas_Object *obj __UNUSED__, Evas_Object *scr)
1258 {
1259    int w, h;
1260    e_scrollframe_child_viewport_size_get(scr, &w, &h);
1261    evas_object_resize(sd->o_edje, w, h);
1262 }
1263
1264 static void
1265 _e_typebuf_add(Evas_Object *obj, const char *s)
1266 {
1267    int len;
1268
1269    INTERNAL_ENTRY;
1270
1271    if (!sd->typebuf.buf)
1272      {
1273         sd->typebuf.buf = malloc(16);
1274         if (sd->typebuf.buf)
1275           {
1276              sd->typebuf.size = 16;
1277              sd->typebuf.buf[0] = '\0';
1278           }
1279         else
1280           {
1281              _e_typebuf_clean(obj);
1282              return;
1283           }
1284      }
1285
1286    len = strlen(sd->typebuf.buf);
1287    if (len + strlen(s) + 2 + 1 >= sd->typebuf.size)
1288      {
1289         char *p = realloc(sd->typebuf.buf, sd->typebuf.size + strlen(s) + 16);
1290         if (p)
1291           {
1292              sd->typebuf.buf = p;
1293              sd->typebuf.size = sd->typebuf.size + strlen(s) + 16;
1294           }
1295         else
1296           {
1297              _e_typebuf_clean(obj);
1298              return;
1299           }
1300      }
1301
1302    strcat(sd->typebuf.buf, s);
1303    edje_object_part_text_set(sd->o_edje, "e.text.typebuf_label", sd->typebuf.buf);
1304    edje_object_signal_emit(sd->o_edje, "e,state,typebuf,start", "e");
1305    _e_typebuf_match(obj);
1306    _e_typebuf_timer_update(obj);
1307 }
1308
1309 static void
1310 _e_typebuf_match(Evas_Object *obj)
1311 {
1312    char *match;
1313    Eina_List *l;
1314    int n;
1315    E_Ilist_Item *si = NULL;
1316
1317    INTERNAL_ENTRY;
1318
1319    match = malloc(strlen(sd->typebuf.buf) + 2 + 1);
1320    if (!match) return;
1321
1322    strcpy(match, "*");
1323    strcat(match, sd->typebuf.buf);
1324    strcat(match, "*");
1325
1326    n = 0;
1327    EINA_LIST_FOREACH(sd->items, l, si)
1328      {
1329         const char *label = NULL;
1330
1331         if (si)
1332           {
1333              if (si->label)
1334                label = si->label;
1335              else
1336                label = edje_object_part_text_get(si->o_base, "e.text.label");
1337
1338              if (e_util_glob_case_match(label, match))
1339                {
1340                   e_ilist_selected_set(obj, n);
1341                   break;
1342                }
1343           }
1344         n++;
1345      }
1346
1347    free(match);
1348 }
1349
1350 static Eina_Bool
1351 _e_typebuf_timer_cb(void *data)
1352 {
1353    Evas_Object *obj = data;
1354
1355    _e_typebuf_clean(obj);
1356    return ECORE_CALLBACK_CANCEL;
1357 }
1358
1359 static void
1360 _e_typebuf_timer_update(Evas_Object *obj)
1361 {
1362    INTERNAL_ENTRY;
1363
1364    if (sd->typebuf.timer)
1365      ecore_timer_del(sd->typebuf.timer);
1366
1367    sd->typebuf.timer = ecore_timer_add(3.0, _e_typebuf_timer_cb, obj);
1368 }
1369
1370 static void
1371 _e_typebuf_timer_delete(Evas_Object *obj)
1372 {
1373    INTERNAL_ENTRY;
1374
1375    if (sd->typebuf.timer)
1376      {
1377         ecore_timer_del(sd->typebuf.timer);
1378         sd->typebuf.timer = NULL;
1379      }
1380 }
1381
1382 static void
1383 _e_typebuf_clean(Evas_Object *obj)
1384 {
1385    INTERNAL_ENTRY;
1386
1387    E_FREE(sd->typebuf.buf);
1388    sd->typebuf.size = 0;
1389    _e_typebuf_timer_delete(obj);
1390    edje_object_signal_emit(sd->o_edje, "e,state,typebuf,stop", "e");
1391 }
1392
1393 static void
1394 _item_select(E_Ilist_Item *si)
1395 {
1396    const char *selectraise;
1397    E_Smart_Data *sd = si->sd;
1398    si->selected = EINA_TRUE;
1399    selectraise = edje_object_data_get(si->o_base, "selectraise");
1400    if ((selectraise) && (!strcmp(selectraise, "on")))
1401      evas_object_raise(si->o_base);
1402    edje_object_signal_emit(si->o_base, "e,state,selected", "e");
1403    if (si->o_icon)
1404      {
1405         if (strcmp(evas_object_type_get(si->o_icon), "e_icon"))
1406           edje_object_signal_emit(si->o_icon, "e,state,selected", "e");
1407         else
1408           e_icon_selected_set(si->o_icon, EINA_TRUE);
1409      }
1410    sd->selected_items = eina_list_append(sd->selected_items, si);
1411 }
1412
1413 static void
1414 _item_unselect(E_Ilist_Item *si)
1415 {
1416    const char *stacking, *selectraise;
1417    E_Smart_Data *sd = si->sd;
1418    si->selected = EINA_FALSE;
1419    edje_object_signal_emit(si->o_base, "e,state,unselected", "e");
1420    if (si->o_icon)
1421      {
1422         if (strcmp(evas_object_type_get(si->o_icon), "e_icon"))
1423           edje_object_signal_emit(si->o_icon, "e,state,unselected", "e");
1424         else
1425           e_icon_selected_set(si->o_icon, EINA_FALSE);
1426      }
1427    stacking = edje_object_data_get(si->o_base, "stacking");
1428    selectraise = edje_object_data_get(si->o_base, "selectraise");
1429    if ((selectraise) && (!strcmp(selectraise, "on")))
1430      {
1431         if ((stacking) && (!strcmp(stacking, "below")))
1432           evas_object_lower(si->o_base);
1433      }
1434    sd->selected_items = eina_list_remove(sd->selected_items, si);
1435 }
1436
1437 static void
1438 _e_ilist_item_theme_set(E_Ilist_Item *si, Eina_Bool custom, Eina_Bool header, Eina_Bool even)
1439 {
1440    E_Smart_Data *sd = si->sd;
1441    const char *file;
1442    char buf[4096];
1443
1444    if ((!custom) || (!sd->theme))
1445      {
1446         if (header)
1447           {
1448              if (!even)
1449                {
1450                   if (!e_theme_edje_object_set(si->o_base, "base/theme/widgets",
1451                                                "e/widgets/ilist_header_odd"))
1452                     e_theme_edje_object_set(si->o_base, "base/theme/widgets",
1453                                             "e/widgets/ilist_header");
1454                }
1455              else
1456                e_theme_edje_object_set(si->o_base, "base/theme/widgets",
1457                                        "e/widgets/ilist_header");
1458           }
1459         else
1460           {
1461              if (!even)
1462                e_theme_edje_object_set(si->o_base, "base/theme/widgets",
1463                                        "e/widgets/ilist_odd");
1464              else
1465                e_theme_edje_object_set(si->o_base, "base/theme/widgets",
1466                                        "e/widgets/ilist");
1467           }
1468         return;
1469      }
1470    edje_object_file_get(sd->o_edje, &file, NULL);
1471    if (header)
1472      {
1473         if (even)
1474           {
1475              snprintf(buf, sizeof(buf), "%s/ilist_header", sd->theme);
1476              if (edje_object_file_set(si->o_base, file, buf)) return;
1477              _e_ilist_item_theme_set(si, EINA_FALSE, header, even);
1478              return;
1479           }
1480         snprintf(buf, sizeof(buf), "%s/ilist_header_odd", sd->theme);
1481         if (edje_object_file_set(si->o_base, file, buf)) return;
1482         _e_ilist_item_theme_set(si, EINA_FALSE, header, even);
1483         return;
1484      }
1485    if (even)
1486      {
1487         snprintf(buf, sizeof(buf), "%s/ilist", sd->theme);
1488         if (edje_object_file_set(si->o_base, file, buf)) return;
1489         _e_ilist_item_theme_set(si, EINA_FALSE, header, even);
1490         return;
1491      }
1492    snprintf(buf, sizeof(buf), "%s/ilist_odd", sd->theme);
1493    if (edje_object_file_set(si->o_base, file, buf)) return;
1494    _e_ilist_item_theme_set(si, EINA_FALSE, header, even);
1495    return;
1496 }