The problem that e17 couldn't move/resize window when the window fetch the rotation...
[platform/core/uifw/e17.git] / src / bin / e_widget_ilist.c
1 #include "e.h"
2
3 typedef struct _E_Widget_Queue_Item E_Widget_Queue_Item;
4 typedef struct _E_Widget_Data       E_Widget_Data;
5 typedef struct _E_Widget_Callback   E_Widget_Callback;
6
7 struct _E_Widget_Data
8 {
9    Evas_Object *o_widget, *o_scrollframe, *o_ilist;
10    Eina_List   *callbacks;
11    const char       **value;
12    struct
13    {
14       Eina_List   *queue;
15       Ecore_Timer *timer;
16       int          count;
17       int          show_nth;
18       int          select_nth;
19    } queue;
20 };
21
22 struct _E_Widget_Callback
23 {
24    void  (*func)(void *data);
25    void *data;
26    const char *value;
27 };
28
29 struct _E_Widget_Queue_Item
30 {
31    int          command;
32    Evas_Object *icon;
33    Evas_Object *end;
34    const char  *label;
35    int          header;
36    void         (*func)(void *data);
37    void        *data;
38    const char  *val;
39    int          relative, use_relative;
40    int          item;
41 };
42
43 static void      _e_wid_del_hook(Evas_Object *obj);
44 static void      _e_wid_focus_hook(Evas_Object *obj);
45 static void      _e_wid_cb_scrollframe_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
46 static void      _e_wid_cb_item_sel(void *data, void *data2);
47 static void      _e_wid_cb_item_hilight(void *data, void *data2);
48 static void      _e_wid_cb_selected(void *data, Evas_Object *obj, void *event_info);
49 static void      _e_wid_focus_steal(void *data, Evas *e, Evas_Object *obj, void *event_info);
50
51 static Eina_Bool _queue_timer(void *data);
52 static void      _queue_queue(Evas_Object *obj);
53 static void      _queue_append(Evas_Object *obj, int command, Evas_Object *icon, Evas_Object *end, const char *label, int header, void (*func)(void *data), void *data, const char *val, int relative, int use_relative, int item);
54 static void      _queue_remove(Evas_Object *obj, E_Widget_Queue_Item *qi, int del);
55
56 enum
57 {
58    CMD_ADD,
59    CMD_REMOVE,
60    CMD_APPEND,
61    CMD_PREPEND,
62    CMD_APPEND_RELATIVE,
63    CMD_PREPEND_RELATIVE,
64    CMD_SELECT,
65    CMD_UNSELECT,
66    CMD_RANGE_SELECT,
67    CMD_MULTI_SELECT,
68    CMD_LABEL_SET,
69    CMD_ICON_SET,
70    CMD_END_SET,
71    CMD_SHOW
72 };
73
74 static Eina_Bool
75 _queue_timer(void *data)
76 {
77    Evas_Object *obj;
78    E_Widget_Data *wd;
79    int num;
80    double start = ecore_time_get();
81
82    obj = data;
83    wd = e_widget_data_get(obj);
84    if (!wd) return EINA_FALSE;
85    wd->queue.timer = NULL;
86    e_widget_ilist_freeze(obj);
87    num = 0;
88    while (wd->queue.queue)
89      {
90         E_Widget_Queue_Item *qi;
91
92         qi = eina_list_data_get(wd->queue.queue);
93         if (qi->command == CMD_ADD)
94           {
95              E_Widget_Callback *wcb, *rcb;
96
97              wcb = E_NEW(E_Widget_Callback, 1);
98              if (!wcb) break;
99              wcb->func = qi->func;
100              wcb->data = qi->data;
101              if (qi->val) wcb->value = eina_stringshare_add(qi->val);
102              if (qi->use_relative == CMD_APPEND)
103                {
104                   wd->callbacks = eina_list_append(wd->callbacks, wcb);
105                   e_ilist_append(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
106                                  _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
107                }
108              else if (qi->use_relative == CMD_PREPEND)
109                {
110                   wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
111                   e_ilist_prepend(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
112                                   _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
113                }
114              else if (qi->use_relative == CMD_APPEND_RELATIVE)
115                {
116                   rcb = eina_list_nth(wd->callbacks, qi->relative);
117                   if (rcb)
118                     {
119                        wd->callbacks = eina_list_append_relative(wd->callbacks, wcb, rcb);
120                        e_ilist_append_relative(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
121                                                _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, qi->relative);
122                     }
123                   else
124                     {
125                        wd->callbacks = eina_list_append(wd->callbacks, wcb);
126                        e_ilist_append(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
127                                       _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
128                     }
129                }
130              else if (qi->use_relative == CMD_PREPEND_RELATIVE)
131                {
132                   rcb = eina_list_nth(wd->callbacks, qi->relative);
133                   if (rcb)
134                     {
135                        wd->callbacks = eina_list_prepend_relative(wd->callbacks, wcb, rcb);
136                        e_ilist_prepend_relative(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
137                                                 _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, qi->relative);
138                     }
139                   else
140                     {
141                        wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
142                        e_ilist_prepend(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
143                                        _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
144                     }
145                }
146              else
147                {
148                   E_FREE(wcb);
149                }
150              if (qi->icon) evas_object_show(qi->icon);
151              if (qi->end) evas_object_show(qi->end);
152           }
153         else if (qi->command == CMD_LABEL_SET)
154           e_ilist_nth_label_set(wd->o_ilist, qi->item, qi->label);
155         else if (qi->command == CMD_ICON_SET)
156           e_ilist_nth_icon_set(wd->o_ilist, qi->item, qi->icon);
157         else if (qi->command == CMD_SHOW)
158           {
159              Evas_Coord x, y, w, h;
160              if (num > 0) break;
161
162              e_ilist_nth_geometry_get(wd->o_ilist, qi->item, &x, &y, &w, &h);
163              if (qi->use_relative)
164                e_scrollframe_child_pos_set(wd->o_scrollframe, x, y);
165              else
166                e_scrollframe_child_region_show(wd->o_scrollframe, x, y + h, w, h);
167           }
168         else if (qi->command == CMD_SELECT)
169           e_ilist_selected_set(wd->o_ilist, qi->item);
170         else if (qi->command == CMD_UNSELECT)
171           {
172              if ((wd->value) && *(wd->value))
173                {
174                   eina_stringshare_del(*(wd->value));
175                   *(wd->value) = NULL;
176                }
177              e_ilist_unselect(wd->o_ilist);
178           }
179 #if 0
180         else if (qi->command == CMD_REMOVE)
181           {
182              E_Widget_Callback *wcb;
183              Eina_List *item;
184
185              e_ilist_remove_num(wd->o_ilist, qi->item);
186              item = eina_list_nth_list(wd->callbacks, qi->item);
187              if (item)
188                {
189                   wcb = eina_list_data_get(item);
190                   if (wcb && wcb->value) eina_stringshare_del(wcb->value);
191                   free(wcb);
192                   wd->callbacks = eina_list_remove_list(wd->callbacks, item);
193                }
194           }
195 #endif
196         else if (qi->command == CMD_MULTI_SELECT)
197           e_ilist_multi_select(wd->o_ilist, qi->item);
198         else if (qi->command == CMD_RANGE_SELECT)
199           e_ilist_range_select(wd->o_ilist, qi->item);
200         else if (qi->command == CMD_END_SET)
201           e_ilist_nth_end_set(wd->o_ilist, qi->item, qi->end);
202         _queue_remove(obj, qi, 0);
203
204         if ((num++ >= 10) && (ecore_time_get() - start > 0.01))
205           break;
206      }
207    e_widget_ilist_thaw(obj);
208    e_widget_ilist_go(obj);
209    _queue_queue(obj);
210    return ECORE_CALLBACK_CANCEL;
211 }
212
213 static void
214 _queue_queue(Evas_Object *obj)
215 {
216    E_Widget_Data *wd;
217
218    wd = e_widget_data_get(obj);
219    if (!wd) return;
220    if (!wd->queue.queue) return;
221    if (wd->queue.timer) return;
222    wd->queue.timer = ecore_timer_add(0.00001, _queue_timer, obj);
223 }
224
225 static void
226 _queue_append(Evas_Object *obj, int command, Evas_Object *icon, Evas_Object *end,
227               const char *label, int header, void (*func)(void *data), void *data,
228               const char *val, int relative, int use_relative, int item)
229 {
230    E_Widget_Data *wd;
231    E_Widget_Queue_Item *qi;
232
233    wd = e_widget_data_get(obj);
234    if (!wd) return;
235    qi = E_NEW(E_Widget_Queue_Item, 1);
236    if (!qi) return;
237    qi->command = command;
238    qi->icon = icon;
239    qi->end = end;
240    qi->label = eina_stringshare_add(label);
241    qi->header = header;
242    qi->func = func;
243    qi->data = data;
244    qi->val = eina_stringshare_add(val);
245    qi->relative = relative;
246    qi->use_relative = use_relative;
247    qi->item = item;
248    wd->queue.queue = eina_list_append(wd->queue.queue, qi);
249    _queue_queue(obj);
250 }
251
252 static void
253 _queue_remove(Evas_Object *obj, E_Widget_Queue_Item *qi, int del)
254 {
255    E_Widget_Data *wd;
256
257    wd = e_widget_data_get(obj);
258    if (!wd) return;
259    wd->queue.queue = eina_list_remove(wd->queue.queue, qi);
260    if (del)
261      {
262         if (qi->icon) evas_object_del(qi->icon);
263         if (qi->end) evas_object_del(qi->end);
264      }
265    eina_stringshare_del(qi->label);
266    eina_stringshare_del(qi->val);
267    free(qi);
268 }
269
270 static void
271 _queue_clear(Evas_Object *obj)
272 {
273    E_Widget_Data *wd;
274
275    wd = e_widget_data_get(obj);
276    if (!wd) return;
277    while (wd->queue.queue)
278      _queue_remove(obj, eina_list_data_get(wd->queue.queue), 1);
279    if (wd->queue.timer) ecore_timer_del(wd->queue.timer);
280    wd->queue.timer = NULL;
281 }
282
283 static void
284 _e_wid_disable_hook(Evas_Object *obj)
285 {
286    E_Ilist_Item *ili;
287    const Eina_List *l;
288    Eina_Bool disabled;
289    E_Widget_Data *wd;
290
291    disabled = e_widget_disabled_get(obj);
292    wd = e_widget_data_get(obj);
293    if (!wd) return;
294
295    EINA_LIST_FOREACH(e_widget_ilist_items_get(obj), l, ili)
296      {
297         if (disabled)
298           edje_object_signal_emit(ili->o_base, "e,state,disabled", "e");
299         else
300           edje_object_signal_emit(ili->o_base, "e,state,enabled", "e");
301      }
302    evas_object_freeze_events_set(wd->o_scrollframe, disabled);
303 }
304
305 /* externally accessible functions */
306 EAPI Evas_Object *
307 e_widget_ilist_add(Evas *evas, int icon_w, int icon_h, const char **value)
308 {
309    Evas_Object *obj, *o;
310    E_Widget_Data *wd;
311
312    wd = E_NEW(E_Widget_Data, 1);
313    if (!wd) return NULL;
314
315    obj = e_widget_add(evas);
316
317    e_widget_del_hook_set(obj, _e_wid_del_hook);
318    e_widget_focus_hook_set(obj, _e_wid_focus_hook);
319    e_widget_disable_hook_set(obj, _e_wid_disable_hook);
320    e_widget_data_set(obj, wd);
321
322    wd->value = value;
323
324    o = e_scrollframe_add(evas);
325    wd->o_scrollframe = o;
326    evas_object_show(o);
327    e_widget_sub_object_add(obj, o);
328    e_widget_resize_object_set(obj, o);
329    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
330                                   _e_wid_focus_steal, obj);
331
332    o = e_ilist_add(evas);
333    wd->o_ilist = o;
334    e_ilist_icon_size_set(o, icon_w, icon_h);
335    evas_object_event_callback_add(wd->o_scrollframe, EVAS_CALLBACK_RESIZE,
336                                   _e_wid_cb_scrollframe_resize, o);
337    e_scrollframe_child_set(wd->o_scrollframe, o);
338    e_widget_sub_object_add(obj, o);
339    evas_object_show(o);
340    evas_object_smart_callback_add(o, "selected", _e_wid_cb_selected, obj);
341
342    evas_object_resize(obj, 32, 32);
343    e_widget_size_min_set(obj, 32, 32);
344    return obj;
345 }
346
347 EAPI void
348 e_widget_ilist_freeze(Evas_Object *obj)
349 {
350    E_Widget_Data *wd;
351
352    wd = e_widget_data_get(obj);
353    if (!wd) return;
354    e_ilist_freeze(wd->o_ilist);
355 }
356
357 EAPI void
358 e_widget_ilist_thaw(Evas_Object *obj)
359 {
360    E_Widget_Data *wd;
361
362    wd = e_widget_data_get(obj);
363    if (!wd) return;
364    e_ilist_thaw(wd->o_ilist);
365 }
366
367 EAPI void
368 e_widget_ilist_append(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val)
369 {
370    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, 0, CMD_APPEND, 0);
371 /*
372    E_Widget_Data *wd;
373    E_Widget_Callback *wcb;
374
375    wcb = E_NEW(E_Widget_Callback, 1);
376    if (!wcb) return;
377
378    wd = e_widget_data_get(obj);
379    wcb->func = func;
380    wcb->data = data;
381    if (val) wcb->value = strdup(val);
382    wd->callbacks = eina_list_append(wd->callbacks, wcb);
383    e_ilist_append(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
384    if (icon) evas_object_show(icon);
385  */
386 }
387
388 EAPI void
389 e_widget_ilist_append_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val)
390 {
391    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, 0, CMD_APPEND, 0);
392 }
393
394 EAPI void
395 e_widget_ilist_header_append_relative(Evas_Object *obj, Evas_Object *icon, const char *label, int relative)
396 {
397    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, relative, CMD_APPEND_RELATIVE, 0);
398 }
399
400 EAPI void
401 e_widget_ilist_header_prepend_relative(Evas_Object *obj, Evas_Object *icon, const char *label, int relative)
402 {
403    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, relative, CMD_PREPEND_RELATIVE, 0);
404 }
405
406 EAPI void
407 e_widget_ilist_append_relative(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
408 {
409    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, relative, CMD_APPEND_RELATIVE, 0);
410 /*
411    E_Widget_Data *wd;
412    E_Widget_Callback *wcb, *rcb;
413
414    wcb = E_NEW(E_Widget_Callback, 1);
415    if (!wcb) return;
416
417    wd = e_widget_data_get(obj);
418    wcb->func = func;
419    wcb->data = data;
420    if (val) wcb->value = strdup(val);
421
422    rcb = eina_list_nth(wd->callbacks, relative);
423    if (rcb)
424      {
425         wd->callbacks = eina_list_append_relative(wd->callbacks, wcb, rcb);
426         e_ilist_append_relative(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, relative);
427      }
428    else
429      {
430         wd->callbacks = eina_list_append(wd->callbacks, wcb);
431         e_ilist_append(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
432      }
433
434    if (icon) evas_object_show(icon);
435  */
436 }
437
438 EAPI void
439 e_widget_ilist_append_relative_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
440 {
441    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, relative, CMD_APPEND_RELATIVE, 0);
442 }
443
444 EAPI void
445 e_widget_ilist_prepend(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val)
446 {
447    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, 0, CMD_PREPEND, 0);
448 /*
449    E_Widget_Data *wd;
450    E_Widget_Callback *wcb;
451
452    wcb = E_NEW(E_Widget_Callback, 1);
453    if (!wcb) return;
454
455    wd = e_widget_data_get(obj);
456    wcb->func = func;
457    wcb->data = data;
458    if (val) wcb->value = strdup(val);
459    wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
460    e_ilist_prepend(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
461    if (icon) evas_object_show(icon);
462  */
463 }
464
465 EAPI void
466 e_widget_ilist_header_prepend(Evas_Object *obj, Evas_Object *icon, const char *label)
467 {
468    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, 0, CMD_PREPEND, 0);
469 }
470
471 EAPI void
472 e_widget_ilist_prepend_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val)
473 {
474    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, 0, CMD_PREPEND, 0);
475 }
476
477 EAPI void
478 e_widget_ilist_prepend_relative(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
479 {
480    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, relative, CMD_PREPEND_RELATIVE, 0);
481 /*
482    E_Widget_Data *wd;
483    E_Widget_Callback *wcb, *rcb;
484
485    wcb = E_NEW(E_Widget_Callback, 1);
486    if (!wcb) return;
487
488    wd = e_widget_data_get(obj);
489    wcb->func = func;
490    wcb->data = data;
491    if (val) wcb->value = strdup(val);
492
493    rcb = eina_list_nth(wd->callbacks, relative);
494    if (rcb)
495      {
496         wd->callbacks = eina_list_prepend_relative(wd->callbacks, wcb, rcb);
497         e_ilist_prepend_relative(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, relative);
498      }
499    else
500      {
501         wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
502         e_ilist_prepend(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
503      }
504
505    if (icon) evas_object_show(icon);
506  */
507 }
508
509 EAPI void
510 e_widget_ilist_prepend_relative_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
511 {
512    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, relative, CMD_PREPEND_RELATIVE, 0);
513 }
514
515 EAPI void
516 e_widget_ilist_header_append(Evas_Object *obj, Evas_Object *icon, const char *label)
517 {
518    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, 0, CMD_APPEND, 0);
519 /*
520    E_Widget_Data *wd;
521    E_Widget_Callback *wcb;
522
523    wcb = E_NEW(E_Widget_Callback, 1);
524    if (!wcb) return;
525
526    wd = e_widget_data_get(obj);
527    wd->callbacks = eina_list_append(wd->callbacks, wcb);
528    e_ilist_append(wd->o_ilist, icon, label, 1, NULL, NULL, NULL, NULL);
529    if (icon) evas_object_show(icon);
530  */
531 }
532
533 EAPI void
534 e_widget_ilist_selector_set(Evas_Object *obj, int selector)
535 {
536    E_Widget_Data *wd;
537
538    wd = e_widget_data_get(obj);
539    if (!wd) return;
540    e_ilist_selector_set(wd->o_ilist, selector);
541 }
542
543 EAPI void
544 e_widget_ilist_go(Evas_Object *obj)
545 {
546    E_Widget_Data *wd;
547    Evas_Coord mw, mh, vw, vh, w, h;
548
549    wd = e_widget_data_get(obj);
550    if (!wd) return;
551    wd->o_widget = obj;
552    e_ilist_size_min_get(wd->o_ilist, &mw, &mh);
553    evas_object_resize(wd->o_ilist, mw, mh);
554    e_scrollframe_child_viewport_size_get(wd->o_scrollframe, &vw, &vh);
555    evas_object_geometry_get(wd->o_scrollframe, NULL, NULL, &w, &h);
556    if (mw > vw)
557      {
558         Evas_Coord wmw, wmh;
559
560         e_widget_size_min_get(obj, &wmw, &wmh);
561         e_widget_size_min_set(obj, mw + (w - vw), wmh);
562      }
563    else if (mw < vw)
564      evas_object_resize(wd->o_ilist, vw, mh);
565 }
566
567 EAPI void
568 e_widget_ilist_clear(Evas_Object *obj)
569 {
570    E_Widget_Data *wd;
571    E_Widget_Callback *wcb;
572
573    wd = e_widget_data_get(obj);
574    if (!wd) return;
575    _queue_clear(obj);
576    e_ilist_clear(wd->o_ilist);
577    e_scrollframe_child_pos_set(wd->o_scrollframe, 0, 0);
578    EINA_LIST_FREE(wd->callbacks, wcb)
579      {
580         eina_stringshare_del(wcb->value);
581         free(wcb);
582      }
583 }
584
585 EAPI int
586 e_widget_ilist_count(Evas_Object *obj)
587 {
588    E_Widget_Data *wd;
589
590    wd = e_widget_data_get(obj);
591    if (!wd) return 0;
592
593    if (wd->queue.queue)
594      {
595         E_Widget_Queue_Item *qi;
596         Eina_List *l;
597         int cnt = 0;
598
599         EINA_LIST_FOREACH(wd->queue.queue, l, qi)
600           if (qi->command == CMD_ADD) cnt++;
601
602         return cnt + e_ilist_count(wd->o_ilist);
603      }
604    else
605      return e_ilist_count(wd->o_ilist);
606 }
607
608 EAPI const Eina_List *
609 e_widget_ilist_items_get(Evas_Object *obj)
610 {
611    E_Widget_Data *wd;
612
613    wd = e_widget_data_get(obj);
614    if (!wd) return NULL;
615    return e_ilist_items_get(wd->o_ilist);
616 }
617
618 EAPI Eina_Bool
619 e_widget_ilist_nth_is_header(Evas_Object *obj, int n)
620 {
621    E_Widget_Data *wd;
622
623    wd = e_widget_data_get(obj);
624    if (!wd) return EINA_FALSE;
625    return e_ilist_nth_is_header(wd->o_ilist, n);
626 }
627
628 EAPI void
629 e_widget_ilist_nth_label_set(Evas_Object *obj, int n, const char *label)
630 {
631    _queue_append(obj, CMD_LABEL_SET, NULL, NULL, label, 0, NULL, NULL, NULL, 0, 0, n);
632 /*
633    E_Widget_Data *wd;
634
635    wd = e_widget_data_get(obj);
636    e_ilist_nth_label_set(wd->o_ilist, n, label);
637  */
638 }
639
640 EAPI const char *
641 e_widget_ilist_nth_label_get(Evas_Object *obj, int n)
642 {
643    E_Widget_Data *wd;
644
645    wd = e_widget_data_get(obj);
646    if (!wd) return NULL;
647    return e_ilist_nth_label_get(wd->o_ilist, n);
648 }
649
650 EAPI void
651 e_widget_ilist_nth_icon_set(Evas_Object *obj, int n, Evas_Object *icon)
652 {
653    _queue_append(obj, CMD_ICON_SET, icon, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
654 /*
655    E_Widget_Data *wd;
656
657    wd = e_widget_data_get(obj);
658    e_ilist_nth_icon_set(wd->o_ilist, n, icon);
659  */
660 }
661
662 EAPI Evas_Object *
663 e_widget_ilist_nth_icon_get(Evas_Object *obj, int n)
664 {
665    E_Widget_Data *wd;
666
667    wd = e_widget_data_get(obj);
668    if (!wd) return NULL;
669    return e_ilist_nth_icon_get(wd->o_ilist, n);
670 }
671
672 EAPI void
673 e_widget_ilist_nth_end_set(Evas_Object *obj, int n, Evas_Object *end)
674 {
675    _queue_append(obj, CMD_END_SET, NULL, end, NULL, 0, NULL, NULL, NULL, 0, 0, n);
676 }
677
678 EAPI Evas_Object *
679 e_widget_ilist_nth_end_get(Evas_Object *obj, int n)
680 {
681    E_Widget_Data *wd;
682
683    wd = e_widget_data_get(obj);
684    if (!wd) return NULL;
685    return e_ilist_nth_end_get(wd->o_ilist, n);
686 }
687
688 EAPI void *
689 e_widget_ilist_nth_data_get(Evas_Object *obj, int n)
690 {
691    E_Widget_Data *wd;
692    E_Widget_Callback *wcb;
693
694    wd = e_widget_data_get(obj);
695    if (!wd) return NULL;
696    wcb = eina_list_nth(wd->callbacks, n);
697
698    if (!wcb)
699      return NULL;
700    else
701      return wcb->data;
702 }
703
704 EAPI const char *
705 e_widget_ilist_nth_value_get(Evas_Object *obj, int n)
706 {
707    E_Widget_Data *wd;
708    E_Widget_Callback *wcb;
709
710    wd = e_widget_data_get(obj);
711    if (!wd) return NULL;
712    wcb = eina_list_nth(wd->callbacks, n);
713
714    if (!wcb)
715      return NULL;
716    else
717      return wcb->value;
718 }
719
720 /**
721  * Return if the given item returned by e_widget_ilist_items_get()
722  * is a header.
723  *
724  * This avoid expensive lookups to the nth element, however it's not
725  * able to check any validity on the given pointer and may crash. Be
726  * sure to use only with valid return of e_widget_ilist_items_get().
727  */
728 EAPI Eina_Bool
729 e_widget_ilist_item_is_header(const E_Ilist_Item *it)
730 {
731    return it->header;
732 }
733
734 /**
735  * Return the label of given item returned by e_widget_ilist_items_get().
736  *
737  * This avoid expensive lookups to the nth element, however it's not
738  * able to check any validity on the given pointer and may crash. Be
739  * sure to use only with valid return of e_widget_ilist_items_get().
740  */
741 EAPI const char *
742 e_widget_ilist_item_label_get(const E_Ilist_Item *it)
743 {
744    return it->label;
745 }
746
747 /**
748  * Return the icon of given item returned by e_widget_ilist_items_get().
749  *
750  * This avoid expensive lookups to the nth element, however it's not
751  * able to check any validity on the given pointer and may crash. Be
752  * sure to use only with valid return of e_widget_ilist_items_get().
753  *
754  * Do not delete this object!
755  */
756 EAPI Evas_Object *
757 e_widget_ilist_item_icon_get(const E_Ilist_Item *it)
758 {
759    return it->o_icon;
760 }
761
762 /**
763  * Return the end of given item returned by e_widget_ilist_items_get().
764  *
765  * This avoid expensive lookups to the nth element, however it's not
766  * able to check any validity on the given pointer and may crash. Be
767  * sure to use only with valid return of e_widget_ilist_items_get().
768  *
769  * Do not delete this object!
770  */
771 EAPI Evas_Object *
772 e_widget_ilist_item_end_get(const E_Ilist_Item *it)
773 {
774    return it->o_end;
775 }
776
777 /**
778  * Return the data of given item returned by e_widget_ilist_items_get().
779  *
780  * This avoid expensive lookups to the nth element, however it's not
781  * able to check any validity on the given pointer and may crash. Be
782  * sure to use only with valid return of e_widget_ilist_items_get().
783  *
784  * Do not delete this object!
785  */
786 EAPI void *
787 e_widget_ilist_item_data_get(const E_Ilist_Item *it)
788 {
789    E_Widget_Callback *wcb = it->data2;
790
791    if (!wcb)
792      return NULL;
793    else
794      return wcb->data;
795 }
796
797 EAPI const char *
798 e_widget_ilist_item_value_get(const E_Ilist_Item *it)
799 {
800    E_Widget_Callback *wcb = it->data2;
801
802    if (!wcb)
803      return NULL;
804    else
805      return wcb->value;
806 }
807
808 /**
809  * Show the nth element of an ilist
810  * @param obj the ilist
811  * @param n the number of the element to show
812  * @param top if true, place this item at the top, otherwise scroll just
813  * enough to show the element (from the current position).
814  */
815 EAPI void
816 e_widget_ilist_nth_show(Evas_Object *obj, int n, int top)
817 {
818    _queue_append(obj, CMD_SHOW, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, top, n);
819 /*
820    E_Widget_Data *wd;
821    Evas_Coord x, y, w, h;
822
823    wd = e_widget_data_get(obj);
824    e_ilist_nth_geometry_get(wd->o_ilist, n, &x, &y, &w, &h);
825    if (top)
826      e_scrollframe_child_pos_set(wd->o_scrollframe, x, y);
827    else
828      e_scrollframe_child_region_show(wd->o_scrollframe, x, y, w, h);
829  */
830 }
831
832 EAPI void
833 e_widget_ilist_selected_set(Evas_Object *obj, int n)
834 {
835    _queue_append(obj, CMD_SELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
836 /*
837    E_Widget_Data *wd;
838
839    wd = e_widget_data_get(obj);
840    e_ilist_selected_set(wd->o_ilist, n);
841  */
842 }
843
844 EAPI const Eina_List *
845 e_widget_ilist_selected_items_get(Evas_Object *obj)
846 {
847    E_Widget_Data *wd;
848
849    wd = e_widget_data_get(obj);
850    if (!wd) return NULL;
851    return e_ilist_selected_items_get(wd->o_ilist);
852 }
853
854 EAPI int
855 e_widget_ilist_selected_get(Evas_Object *obj)
856 {
857    E_Widget_Data *wd;
858
859    wd = e_widget_data_get(obj);
860    if (!wd) return 0;
861    return e_ilist_selected_get(wd->o_ilist);
862 }
863
864 EAPI const char *
865 e_widget_ilist_selected_label_get(Evas_Object *obj)
866 {
867    E_Widget_Data *wd;
868
869    wd = e_widget_data_get(obj);
870    if (!wd) return NULL;
871    return e_ilist_selected_label_get(wd->o_ilist);
872 }
873
874 EAPI Evas_Object *
875 e_widget_ilist_selected_icon_get(Evas_Object *obj)
876 {
877    E_Widget_Data *wd;
878
879    wd = e_widget_data_get(obj);
880    if (!wd) return NULL;
881    return e_ilist_selected_icon_get(wd->o_ilist);
882 }
883
884 EAPI void *
885 e_widget_ilist_selected_data_get(Evas_Object *obj)
886 {
887    E_Widget_Data *wd;
888    E_Widget_Callback *wcb;
889
890    wd = e_widget_data_get(obj);
891    if (!wd) return NULL;
892    wcb = eina_list_nth(wd->callbacks, e_ilist_selected_get(wd->o_ilist));
893
894    return wcb ? wcb->data : NULL;
895 }
896
897 EAPI Evas_Object *
898 e_widget_ilist_selected_end_get(Evas_Object *obj)
899 {
900    E_Widget_Data *wd;
901
902    wd = e_widget_data_get(obj);
903    if (!wd) return NULL;
904    return e_ilist_selected_end_get(wd->o_ilist);
905 }
906
907 EAPI int
908 e_widget_ilist_selected_count_get(Evas_Object *obj)
909 {
910    E_Widget_Data *wd;
911
912    wd = e_widget_data_get(obj);
913    if (!wd) return 0;
914    return e_ilist_selected_count_get(wd->o_ilist);
915 }
916
917 EAPI const char *
918 e_widget_ilist_selected_value_get(Evas_Object *obj)
919 {
920    E_Widget_Data *wd;
921    E_Widget_Callback *wcb;
922
923    wd = e_widget_data_get(obj);
924    if (!wd) return NULL;
925    wcb = eina_list_nth(wd->callbacks, e_ilist_selected_get(wd->o_ilist));
926
927    if (!wcb)
928      return NULL;
929    else
930      return wcb->value;
931 }
932
933 EAPI void
934 e_widget_ilist_unselect(Evas_Object *obj)
935 {
936    _queue_append(obj, CMD_UNSELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, 0);
937 /*
938    E_Widget_Data *wd;
939
940    wd = e_widget_data_get(obj);
941    if ((wd->value) && *(wd->value))
942        {
943           free(*(wd->value));
944  *(wd->value) = NULL;
945        }
946    e_ilist_unselect(wd->o_ilist);
947  */
948 }
949
950 EAPI void
951 e_widget_ilist_remove_num(Evas_Object *obj, int n)
952 {
953 /*    _queue_append(obj, CMD_REMOVE, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n); */
954    E_Widget_Callback *wcb;
955    E_Widget_Data *wd;
956    Eina_List *item;
957
958    wd = e_widget_data_get(obj);
959    if (!wd) return;
960    e_ilist_remove_num(wd->o_ilist, n);
961    item = eina_list_nth_list(wd->callbacks, n);
962    if (item)
963      {
964         wcb = eina_list_data_get(item);
965         if (wcb) eina_stringshare_del(wcb->value);
966         free(wcb);
967         wd->callbacks = eina_list_remove_list(wd->callbacks, item);
968      }
969 }
970
971 EAPI void
972 e_widget_ilist_multi_select_set(Evas_Object *obj, Eina_Bool multi)
973 {
974    E_Widget_Data *wd;
975
976    wd = e_widget_data_get(obj);
977    if (!wd) return;
978    e_ilist_multi_select_set(wd->o_ilist, multi);
979 }
980
981 EAPI Eina_Bool
982 e_widget_ilist_multi_select_get(Evas_Object *obj)
983 {
984    E_Widget_Data *wd;
985
986    wd = e_widget_data_get(obj);
987    if (!wd) return EINA_FALSE;
988    return e_ilist_multi_select_get(wd->o_ilist);
989 }
990
991 EAPI void
992 e_widget_ilist_multi_select(Evas_Object *obj, int n)
993 {
994    _queue_append(obj, CMD_MULTI_SELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
995 /*
996    E_Widget_Data *wd;
997
998    wd = e_widget_data_get(obj);
999    e_ilist_multi_select(wd->o_ilist, n);
1000  */
1001 }
1002
1003 EAPI void
1004 e_widget_ilist_range_select(Evas_Object *obj, int n)
1005 {
1006    _queue_append(obj, CMD_RANGE_SELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
1007 /*
1008    E_Widget_Data *wd;
1009
1010    wd = e_widget_data_get(obj);
1011    e_ilist_range_select(wd->o_ilist, n);
1012  */
1013 }
1014
1015 EAPI Eina_Bool
1016 e_widget_ilist_custom_edje_file_set(Evas_Object *obj, const char *file, const char *group)
1017 {
1018    E_Widget_Data *wd;
1019    char buf[1024];
1020
1021    wd = e_widget_data_get(obj);
1022    if (!wd) return EINA_FALSE;
1023    if (group)
1024      {
1025         snprintf(buf, sizeof(buf), "%s/scrollframe", group);
1026         e_scrollframe_custom_edje_file_set(wd->o_scrollframe, file, group);
1027      }
1028    return e_ilist_custom_edje_file_set(wd->o_ilist, file, group);
1029 }
1030
1031 EAPI void
1032 e_widget_ilist_preferred_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
1033 {
1034    Evas_Coord ww, hh, mw, mh, vw, vh;
1035    E_Widget_Data *wd;
1036
1037    wd = e_widget_data_get(obj);
1038    if (!wd) return;
1039    evas_object_geometry_get(wd->o_scrollframe, NULL, NULL, &ww, &hh);
1040    evas_object_resize(wd->o_scrollframe, 200, 200);
1041    e_scrollframe_child_viewport_size_get(wd->o_scrollframe, &vw, &vh);
1042    e_ilist_size_min_get(wd->o_ilist, &mw, &mh);
1043    evas_object_resize(wd->o_scrollframe, ww, hh);
1044    if (w) *w = 200 - vw + mw;
1045    if (h) *h = 200 - vh + mh;
1046 }
1047
1048 static void
1049 _e_wid_del_hook(Evas_Object *obj)
1050 {
1051    E_Widget_Data *wd;
1052    E_Widget_Callback *wcb;
1053
1054    wd = e_widget_data_get(obj);
1055    if (!wd) return;
1056    _queue_clear(obj);
1057    EINA_LIST_FREE(wd->callbacks, wcb)
1058      {
1059         if (wcb) eina_stringshare_del(wcb->value);
1060         free(wcb);
1061      }
1062    free(wd);
1063 }
1064
1065 static void
1066 _e_wid_focus_hook(Evas_Object *obj)
1067 {
1068    E_Widget_Data *wd;
1069
1070    wd = e_widget_data_get(obj);
1071    if (!wd) return;
1072    if (e_widget_focus_get(obj))
1073      {
1074         edje_object_signal_emit(e_scrollframe_edje_object_get(wd->o_scrollframe), "e,state,focused", "e");
1075         evas_object_focus_set(wd->o_ilist, 1);
1076      }
1077    else
1078      {
1079         edje_object_signal_emit(e_scrollframe_edje_object_get(wd->o_scrollframe), "e,state,unfocused", "e");
1080         evas_object_focus_set(wd->o_ilist, 0);
1081      }
1082 }
1083
1084 static void
1085 _e_wid_cb_scrollframe_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
1086 {
1087    Evas_Coord mw, mh, vw, vh, w, h;
1088
1089    e_scrollframe_child_viewport_size_get(obj, &vw, &vh);
1090    e_ilist_size_min_get(data, &mw, &mh);
1091    evas_object_geometry_get(data, NULL, NULL, &w, &h);
1092    if (vw >= mw)
1093      {
1094         if (w != vw) evas_object_resize(data, vw, h);
1095         evas_object_smart_callback_call(data, "changed", obj);
1096      }
1097 }
1098
1099 static void
1100 _e_wid_cb_item_sel(void *data, void *data2)
1101 {
1102    E_Widget_Data *wd;
1103    Evas_Coord x, y, w, h;
1104    E_Widget_Callback *wcb;
1105
1106    wd = data;
1107    wcb = data2;
1108    e_ilist_selected_geometry_get(wd->o_ilist, &x, &y, &w, &h);
1109    e_scrollframe_child_region_show(wd->o_scrollframe, x, y, w, h);
1110    if (wd->o_widget)
1111      {
1112         if (wd->value)
1113           {
1114              if (*(wd->value)) eina_stringshare_del(*(wd->value));
1115              if (wcb->value)
1116                *(wd->value) = eina_stringshare_ref(wcb->value);
1117              else
1118                *(wd->value) = NULL;
1119           }
1120         if (wcb->func) wcb->func(wcb->data);
1121         e_widget_change(wd->o_widget);
1122      }
1123 }
1124
1125 static void
1126 _e_wid_cb_item_hilight(void *data, void *data2 __UNUSED__)
1127 {
1128    E_Widget_Data *wd;
1129    Evas_Coord x, y, w, h;
1130
1131    wd = data;
1132    e_ilist_selected_geometry_get(wd->o_ilist, &x, &y, &w, &h);
1133    e_scrollframe_child_region_show(wd->o_scrollframe, x, y, w, h);
1134 }
1135
1136 static void
1137 _e_wid_cb_selected(void *data, Evas_Object *obj __UNUSED__, void *event_info)
1138 {
1139    evas_object_smart_callback_call(data, "selected", event_info);
1140 }
1141
1142 static void
1143 _e_wid_focus_steal(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1144 {
1145    e_widget_focus_steal(data);
1146 }
1147