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