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