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
_queue_timer(void * data)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
_queue_queue(Evas_Object * obj)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_loop_add(0.00001, _queue_timer, obj);
223 }
224 
225 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)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
_queue_remove(Evas_Object * obj,E_Widget_Queue_Item * qi,int del)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
_queue_clear(Evas_Object * obj)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
_e_wid_disable_hook(Evas_Object * obj)284 _e_wid_disable_hook(Evas_Object *obj)
285 {
286    Eina_Bool disabled;
287    E_Widget_Data *wd;
288 
289    disabled = e_widget_disabled_get(obj);
290    wd = e_widget_data_get(obj);
291    if (!wd) return;
292    e_ilist_disabled_set(wd->o_ilist, disabled);
293    evas_object_freeze_events_set(wd->o_scrollframe, disabled);
294 }
295 
296 /* externally accessible functions */
297 E_API Evas_Object *
e_widget_ilist_add(Evas * evas,int icon_w,int icon_h,const char ** value)298 e_widget_ilist_add(Evas *evas, int icon_w, int icon_h, const char **value)
299 {
300    Evas_Object *obj, *o;
301    E_Widget_Data *wd;
302 
303    wd = E_NEW(E_Widget_Data, 1);
304    if (!wd) return NULL;
305 
306    obj = e_widget_add(evas);
307 
308    e_widget_del_hook_set(obj, _e_wid_del_hook);
309    e_widget_focus_hook_set(obj, _e_wid_focus_hook);
310    e_widget_disable_hook_set(obj, _e_wid_disable_hook);
311    e_widget_data_set(obj, wd);
312 
313    wd->value = value;
314 
315    o = e_scrollframe_add(evas);
316    wd->o_scrollframe = o;
317    evas_object_show(o);
318    e_widget_sub_object_add(obj, o);
319    e_widget_resize_object_set(obj, o);
320    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
321                                   _e_wid_focus_steal, obj);
322 
323    o = e_ilist_add(evas);
324    wd->o_ilist = o;
325    e_ilist_icon_size_set(o, icon_w, icon_h);
326    evas_object_event_callback_add(wd->o_scrollframe, EVAS_CALLBACK_RESIZE,
327                                   _e_wid_cb_scrollframe_resize, o);
328    e_scrollframe_child_set(wd->o_scrollframe, o);
329    e_widget_sub_object_add(obj, o);
330    evas_object_show(o);
331    evas_object_smart_callback_add(o, "selected", _e_wid_cb_selected, obj);
332 
333    evas_object_resize(obj, 32, 32);
334    e_widget_size_min_set(obj, 32, 32);
335    return obj;
336 }
337 
338 E_API void
e_widget_ilist_freeze(Evas_Object * obj)339 e_widget_ilist_freeze(Evas_Object *obj)
340 {
341    E_Widget_Data *wd;
342 
343    wd = e_widget_data_get(obj);
344    if (!wd) return;
345    e_ilist_freeze(wd->o_ilist);
346 }
347 
348 E_API void
e_widget_ilist_thaw(Evas_Object * obj)349 e_widget_ilist_thaw(Evas_Object *obj)
350 {
351    E_Widget_Data *wd;
352 
353    wd = e_widget_data_get(obj);
354    if (!wd) return;
355    e_ilist_thaw(wd->o_ilist);
356 }
357 
358 E_API void
e_widget_ilist_append(Evas_Object * obj,Evas_Object * icon,const char * label,void (* func)(void * data),void * data,const char * val)359 e_widget_ilist_append(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val)
360 {
361    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, 0, CMD_APPEND, 0);
362 /*
363    E_Widget_Data *wd;
364    E_Widget_Callback *wcb;
365 
366    wcb = E_NEW(E_Widget_Callback, 1);
367    if (!wcb) return;
368 
369    wd = e_widget_data_get(obj);
370    wcb->func = func;
371    wcb->data = data;
372    if (val) wcb->value = strdup(val);
373    wd->callbacks = eina_list_append(wd->callbacks, wcb);
374    e_ilist_append(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
375    if (icon) evas_object_show(icon);
376  */
377 }
378 
379 E_API void
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)380 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)
381 {
382    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, 0, CMD_APPEND, 0);
383 }
384 
385 E_API void
e_widget_ilist_header_append_relative(Evas_Object * obj,Evas_Object * icon,const char * label,int relative)386 e_widget_ilist_header_append_relative(Evas_Object *obj, Evas_Object *icon, const char *label, int relative)
387 {
388    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, relative, CMD_APPEND_RELATIVE, 0);
389 }
390 
391 E_API void
e_widget_ilist_header_prepend_relative(Evas_Object * obj,Evas_Object * icon,const char * label,int relative)392 e_widget_ilist_header_prepend_relative(Evas_Object *obj, Evas_Object *icon, const char *label, int relative)
393 {
394    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, relative, CMD_PREPEND_RELATIVE, 0);
395 }
396 
397 E_API void
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)398 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)
399 {
400    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, relative, CMD_APPEND_RELATIVE, 0);
401 /*
402    E_Widget_Data *wd;
403    E_Widget_Callback *wcb, *rcb;
404 
405    wcb = E_NEW(E_Widget_Callback, 1);
406    if (!wcb) return;
407 
408    wd = e_widget_data_get(obj);
409    wcb->func = func;
410    wcb->data = data;
411    if (val) wcb->value = strdup(val);
412 
413    rcb = eina_list_nth(wd->callbacks, relative);
414    if (rcb)
415      {
416         wd->callbacks = eina_list_append_relative(wd->callbacks, wcb, rcb);
417         e_ilist_append_relative(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, relative);
418      }
419    else
420      {
421         wd->callbacks = eina_list_append(wd->callbacks, wcb);
422         e_ilist_append(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
423      }
424 
425    if (icon) evas_object_show(icon);
426  */
427 }
428 
429 E_API void
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)430 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)
431 {
432    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, relative, CMD_APPEND_RELATIVE, 0);
433 }
434 
435 E_API void
e_widget_ilist_prepend(Evas_Object * obj,Evas_Object * icon,const char * label,void (* func)(void * data),void * data,const char * val)436 e_widget_ilist_prepend(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val)
437 {
438    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, 0, CMD_PREPEND, 0);
439 /*
440    E_Widget_Data *wd;
441    E_Widget_Callback *wcb;
442 
443    wcb = E_NEW(E_Widget_Callback, 1);
444    if (!wcb) return;
445 
446    wd = e_widget_data_get(obj);
447    wcb->func = func;
448    wcb->data = data;
449    if (val) wcb->value = strdup(val);
450    wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
451    e_ilist_prepend(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
452    if (icon) evas_object_show(icon);
453  */
454 }
455 
456 E_API void
e_widget_ilist_header_prepend(Evas_Object * obj,Evas_Object * icon,const char * label)457 e_widget_ilist_header_prepend(Evas_Object *obj, Evas_Object *icon, const char *label)
458 {
459    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, 0, CMD_PREPEND, 0);
460 }
461 
462 E_API void
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)463 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)
464 {
465    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, 0, CMD_PREPEND, 0);
466 }
467 
468 E_API void
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)469 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)
470 {
471    _queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, relative, CMD_PREPEND_RELATIVE, 0);
472 /*
473    E_Widget_Data *wd;
474    E_Widget_Callback *wcb, *rcb;
475 
476    wcb = E_NEW(E_Widget_Callback, 1);
477    if (!wcb) return;
478 
479    wd = e_widget_data_get(obj);
480    wcb->func = func;
481    wcb->data = data;
482    if (val) wcb->value = strdup(val);
483 
484    rcb = eina_list_nth(wd->callbacks, relative);
485    if (rcb)
486      {
487         wd->callbacks = eina_list_prepend_relative(wd->callbacks, wcb, rcb);
488         e_ilist_prepend_relative(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, relative);
489      }
490    else
491      {
492         wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
493         e_ilist_prepend(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
494      }
495 
496    if (icon) evas_object_show(icon);
497  */
498 }
499 
500 E_API void
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)501 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)
502 {
503    _queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, relative, CMD_PREPEND_RELATIVE, 0);
504 }
505 
506 E_API void
e_widget_ilist_header_append(Evas_Object * obj,Evas_Object * icon,const char * label)507 e_widget_ilist_header_append(Evas_Object *obj, Evas_Object *icon, const char *label)
508 {
509    _queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, 0, CMD_APPEND, 0);
510 /*
511    E_Widget_Data *wd;
512    E_Widget_Callback *wcb;
513 
514    wcb = E_NEW(E_Widget_Callback, 1);
515    if (!wcb) return;
516 
517    wd = e_widget_data_get(obj);
518    wd->callbacks = eina_list_append(wd->callbacks, wcb);
519    e_ilist_append(wd->o_ilist, icon, label, 1, NULL, NULL, NULL, NULL);
520    if (icon) evas_object_show(icon);
521  */
522 }
523 
524 E_API void
e_widget_ilist_selector_set(Evas_Object * obj,int selector)525 e_widget_ilist_selector_set(Evas_Object *obj, int selector)
526 {
527    E_Widget_Data *wd;
528 
529    wd = e_widget_data_get(obj);
530    if (!wd) return;
531    e_ilist_selector_set(wd->o_ilist, selector);
532 }
533 
534 E_API void
e_widget_ilist_go(Evas_Object * obj)535 e_widget_ilist_go(Evas_Object *obj)
536 {
537    E_Widget_Data *wd;
538    Evas_Coord mw, mh, vw, vh, w, h;
539 
540    wd = e_widget_data_get(obj);
541    if (!wd) return;
542    wd->o_widget = obj;
543    e_ilist_size_min_get(wd->o_ilist, &mw, &mh);
544    evas_object_resize(wd->o_ilist, mw, mh);
545    e_scrollframe_child_viewport_size_get(wd->o_scrollframe, &vw, &vh);
546    evas_object_geometry_get(wd->o_scrollframe, NULL, NULL, &w, &h);
547    if (mw > vw)
548      {
549         Evas_Coord wmw, wmh;
550 
551         e_widget_size_min_get(obj, &wmw, &wmh);
552         e_widget_size_min_set(obj, mw + (w - vw), wmh);
553      }
554    else if (mw < vw)
555      evas_object_resize(wd->o_ilist, vw, mh);
556 }
557 
558 E_API void
e_widget_ilist_clear(Evas_Object * obj)559 e_widget_ilist_clear(Evas_Object *obj)
560 {
561    E_Widget_Data *wd;
562    E_Widget_Callback *wcb;
563 
564    wd = e_widget_data_get(obj);
565    if (!wd) return;
566    _queue_clear(obj);
567    e_ilist_clear(wd->o_ilist);
568    e_scrollframe_child_pos_set(wd->o_scrollframe, 0, 0);
569    EINA_LIST_FREE(wd->callbacks, wcb)
570      {
571         eina_stringshare_del(wcb->value);
572         free(wcb);
573      }
574 }
575 
576 E_API int
e_widget_ilist_count(Evas_Object * obj)577 e_widget_ilist_count(Evas_Object *obj)
578 {
579    E_Widget_Data *wd;
580 
581    wd = e_widget_data_get(obj);
582    if (!wd) return 0;
583 
584    if (wd->queue.queue)
585      {
586         E_Widget_Queue_Item *qi;
587         Eina_List *l;
588         int cnt = 0;
589 
590         EINA_LIST_FOREACH(wd->queue.queue, l, qi)
591           if (qi->command == CMD_ADD) cnt++;
592 
593         return cnt + e_ilist_count(wd->o_ilist);
594      }
595    else
596      return e_ilist_count(wd->o_ilist);
597 }
598 
599 E_API const Eina_List *
e_widget_ilist_items_get(Evas_Object * obj)600 e_widget_ilist_items_get(Evas_Object *obj)
601 {
602    E_Widget_Data *wd;
603 
604    wd = e_widget_data_get(obj);
605    if (!wd) return NULL;
606    return e_ilist_items_get(wd->o_ilist);
607 }
608 
609 E_API Eina_Bool
e_widget_ilist_nth_is_header(Evas_Object * obj,int n)610 e_widget_ilist_nth_is_header(Evas_Object *obj, int n)
611 {
612    E_Widget_Data *wd;
613 
614    wd = e_widget_data_get(obj);
615    if (!wd) return EINA_FALSE;
616    return e_ilist_nth_is_header(wd->o_ilist, n);
617 }
618 
619 E_API void
e_widget_ilist_nth_label_set(Evas_Object * obj,int n,const char * label)620 e_widget_ilist_nth_label_set(Evas_Object *obj, int n, const char *label)
621 {
622    _queue_append(obj, CMD_LABEL_SET, NULL, NULL, label, 0, NULL, NULL, NULL, 0, 0, n);
623 /*
624    E_Widget_Data *wd;
625 
626    wd = e_widget_data_get(obj);
627    e_ilist_nth_label_set(wd->o_ilist, n, label);
628  */
629 }
630 
631 E_API const char *
e_widget_ilist_nth_label_get(Evas_Object * obj,int n)632 e_widget_ilist_nth_label_get(Evas_Object *obj, int n)
633 {
634    E_Widget_Data *wd;
635 
636    wd = e_widget_data_get(obj);
637    if (!wd) return NULL;
638    return e_ilist_nth_label_get(wd->o_ilist, n);
639 }
640 
641 E_API void
e_widget_ilist_nth_icon_set(Evas_Object * obj,int n,Evas_Object * icon)642 e_widget_ilist_nth_icon_set(Evas_Object *obj, int n, Evas_Object *icon)
643 {
644    _queue_append(obj, CMD_ICON_SET, icon, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
645 /*
646    E_Widget_Data *wd;
647 
648    wd = e_widget_data_get(obj);
649    e_ilist_nth_icon_set(wd->o_ilist, n, icon);
650  */
651 }
652 
653 E_API Evas_Object *
e_widget_ilist_nth_icon_get(Evas_Object * obj,int n)654 e_widget_ilist_nth_icon_get(Evas_Object *obj, int n)
655 {
656    E_Widget_Data *wd;
657 
658    wd = e_widget_data_get(obj);
659    if (!wd) return NULL;
660    return e_ilist_nth_icon_get(wd->o_ilist, n);
661 }
662 
663 E_API void
e_widget_ilist_nth_end_set(Evas_Object * obj,int n,Evas_Object * end)664 e_widget_ilist_nth_end_set(Evas_Object *obj, int n, Evas_Object *end)
665 {
666    _queue_append(obj, CMD_END_SET, NULL, end, NULL, 0, NULL, NULL, NULL, 0, 0, n);
667 }
668 
669 E_API Evas_Object *
e_widget_ilist_nth_end_get(Evas_Object * obj,int n)670 e_widget_ilist_nth_end_get(Evas_Object *obj, int n)
671 {
672    E_Widget_Data *wd;
673 
674    wd = e_widget_data_get(obj);
675    if (!wd) return NULL;
676    return e_ilist_nth_end_get(wd->o_ilist, n);
677 }
678 
679 E_API void *
e_widget_ilist_nth_data_get(Evas_Object * obj,int n)680 e_widget_ilist_nth_data_get(Evas_Object *obj, int n)
681 {
682    E_Widget_Data *wd;
683    E_Widget_Callback *wcb;
684 
685    wd = e_widget_data_get(obj);
686    if (!wd) return NULL;
687    wcb = eina_list_nth(wd->callbacks, n);
688 
689    if (!wcb)
690      return NULL;
691    else
692      return wcb->data;
693 }
694 
695 E_API const char *
e_widget_ilist_nth_value_get(Evas_Object * obj,int n)696 e_widget_ilist_nth_value_get(Evas_Object *obj, int n)
697 {
698    E_Widget_Data *wd;
699    E_Widget_Callback *wcb;
700 
701    wd = e_widget_data_get(obj);
702    if (!wd) return NULL;
703    wcb = eina_list_nth(wd->callbacks, n);
704 
705    if (!wcb)
706      return NULL;
707    else
708      return wcb->value;
709 }
710 
711 /**
712  * Return if the given item returned by e_widget_ilist_items_get()
713  * is a header.
714  *
715  * This avoids expensive lookups to the nth element, however it's not
716  * able to check any validity on the given pointer and may crash. Be
717  * sure to use only with valid return of e_widget_ilist_items_get().
718  */
719 E_API Eina_Bool
e_widget_ilist_item_is_header(const E_Ilist_Item * it)720 e_widget_ilist_item_is_header(const E_Ilist_Item *it)
721 {
722    return it->header;
723 }
724 
725 /**
726  * Return the label of given item returned by e_widget_ilist_items_get().
727  *
728  * This avoids expensive lookups to the nth element, however it's not
729  * able to check any validity on the given pointer and may crash. Be
730  * sure to use only with valid return of e_widget_ilist_items_get().
731  */
732 E_API const char *
e_widget_ilist_item_label_get(const E_Ilist_Item * it)733 e_widget_ilist_item_label_get(const E_Ilist_Item *it)
734 {
735    return it->label;
736 }
737 
738 /**
739  * Return the icon of given item returned by e_widget_ilist_items_get().
740  *
741  * This avoids expensive lookups to the nth element, however it's not
742  * able to check any validity on the given pointer and may crash. Be
743  * sure to use only with valid return of e_widget_ilist_items_get().
744  *
745  * Do not delete this object!
746  */
747 E_API Evas_Object *
e_widget_ilist_item_icon_get(const E_Ilist_Item * it)748 e_widget_ilist_item_icon_get(const E_Ilist_Item *it)
749 {
750    return it->o_icon;
751 }
752 
753 /**
754  * Return the end of given item returned by e_widget_ilist_items_get().
755  *
756  * This avoids expensive lookups to the nth element, however it's not
757  * able to check any validity on the given pointer and may crash. Be
758  * sure to use only with valid return of e_widget_ilist_items_get().
759  *
760  * Do not delete this object!
761  */
762 E_API Evas_Object *
e_widget_ilist_item_end_get(const E_Ilist_Item * it)763 e_widget_ilist_item_end_get(const E_Ilist_Item *it)
764 {
765    return it->o_end;
766 }
767 
768 /**
769  * Return the data of given item returned by e_widget_ilist_items_get().
770  *
771  * This avoids expensive lookups to the nth element, however it's not
772  * able to check any validity on the given pointer and may crash. Be
773  * sure to use only with valid return of e_widget_ilist_items_get().
774  *
775  * Do not delete this object!
776  */
777 E_API void *
e_widget_ilist_item_data_get(const E_Ilist_Item * it)778 e_widget_ilist_item_data_get(const E_Ilist_Item *it)
779 {
780    E_Widget_Callback *wcb = it->data2;
781 
782    if (!wcb)
783      return NULL;
784    else
785      return wcb->data;
786 }
787 
788 E_API const char *
e_widget_ilist_item_value_get(const E_Ilist_Item * it)789 e_widget_ilist_item_value_get(const E_Ilist_Item *it)
790 {
791    E_Widget_Callback *wcb = it->data2;
792 
793    if (!wcb)
794      return NULL;
795    else
796      return wcb->value;
797 }
798 
799 /**
800  * Show the nth element of an ilist
801  * @param obj the ilist
802  * @param n the number of the element to show
803  * @param top if true, place this item at the top, otherwise scroll just
804  * enough to show the element (from the current position).
805  */
806 E_API void
e_widget_ilist_nth_show(Evas_Object * obj,int n,int top)807 e_widget_ilist_nth_show(Evas_Object *obj, int n, int top)
808 {
809    _queue_append(obj, CMD_SHOW, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, top, n);
810 /*
811    E_Widget_Data *wd;
812    Evas_Coord x, y, w, h;
813 
814    wd = e_widget_data_get(obj);
815    e_ilist_nth_geometry_get(wd->o_ilist, n, &x, &y, &w, &h);
816    if (top)
817      e_scrollframe_child_pos_set(wd->o_scrollframe, x, y);
818    else
819      e_scrollframe_child_region_show(wd->o_scrollframe, x, y, w, h);
820  */
821 }
822 
823 E_API void
e_widget_ilist_selected_set(Evas_Object * obj,int n)824 e_widget_ilist_selected_set(Evas_Object *obj, int n)
825 {
826    _queue_append(obj, CMD_SELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
827 /*
828    E_Widget_Data *wd;
829 
830    wd = e_widget_data_get(obj);
831    e_ilist_selected_set(wd->o_ilist, n);
832  */
833 }
834 
835 E_API const Eina_List *
e_widget_ilist_selected_items_get(Evas_Object * obj)836 e_widget_ilist_selected_items_get(Evas_Object *obj)
837 {
838    E_Widget_Data *wd;
839 
840    wd = e_widget_data_get(obj);
841    if (!wd) return NULL;
842    return e_ilist_selected_items_get(wd->o_ilist);
843 }
844 
845 E_API int
e_widget_ilist_selected_get(Evas_Object * obj)846 e_widget_ilist_selected_get(Evas_Object *obj)
847 {
848    E_Widget_Data *wd;
849 
850    wd = e_widget_data_get(obj);
851    if (!wd) return 0;
852    return e_ilist_selected_get(wd->o_ilist);
853 }
854 
855 E_API const char *
e_widget_ilist_selected_label_get(Evas_Object * obj)856 e_widget_ilist_selected_label_get(Evas_Object *obj)
857 {
858    E_Widget_Data *wd;
859 
860    wd = e_widget_data_get(obj);
861    if (!wd) return NULL;
862    return e_ilist_selected_label_get(wd->o_ilist);
863 }
864 
865 E_API Evas_Object *
e_widget_ilist_selected_icon_get(Evas_Object * obj)866 e_widget_ilist_selected_icon_get(Evas_Object *obj)
867 {
868    E_Widget_Data *wd;
869 
870    wd = e_widget_data_get(obj);
871    if (!wd) return NULL;
872    return e_ilist_selected_icon_get(wd->o_ilist);
873 }
874 
875 E_API void *
e_widget_ilist_selected_data_get(Evas_Object * obj)876 e_widget_ilist_selected_data_get(Evas_Object *obj)
877 {
878    E_Widget_Data *wd;
879    E_Widget_Callback *wcb;
880 
881    wd = e_widget_data_get(obj);
882    if (!wd) return NULL;
883    wcb = eina_list_nth(wd->callbacks, e_ilist_selected_get(wd->o_ilist));
884 
885    return wcb ? wcb->data : NULL;
886 }
887 
888 E_API Evas_Object *
e_widget_ilist_selected_end_get(Evas_Object * obj)889 e_widget_ilist_selected_end_get(Evas_Object *obj)
890 {
891    E_Widget_Data *wd;
892 
893    wd = e_widget_data_get(obj);
894    if (!wd) return NULL;
895    return e_ilist_selected_end_get(wd->o_ilist);
896 }
897 
898 E_API int
e_widget_ilist_selected_count_get(Evas_Object * obj)899 e_widget_ilist_selected_count_get(Evas_Object *obj)
900 {
901    E_Widget_Data *wd;
902 
903    wd = e_widget_data_get(obj);
904    if (!wd) return 0;
905    return e_ilist_selected_count_get(wd->o_ilist);
906 }
907 
908 E_API const char *
e_widget_ilist_selected_value_get(Evas_Object * obj)909 e_widget_ilist_selected_value_get(Evas_Object *obj)
910 {
911    E_Widget_Data *wd;
912    E_Widget_Callback *wcb;
913 
914    wd = e_widget_data_get(obj);
915    if (!wd) return NULL;
916    wcb = eina_list_nth(wd->callbacks, e_ilist_selected_get(wd->o_ilist));
917 
918    if (!wcb)
919      return NULL;
920    else
921      return wcb->value;
922 }
923 
924 E_API void
e_widget_ilist_unselect(Evas_Object * obj)925 e_widget_ilist_unselect(Evas_Object *obj)
926 {
927    _queue_append(obj, CMD_UNSELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, 0);
928 /*
929    E_Widget_Data *wd;
930 
931    wd = e_widget_data_get(obj);
932    if ((wd->value) && *(wd->value))
933        {
934           free(*(wd->value));
935  *(wd->value) = NULL;
936        }
937    e_ilist_unselect(wd->o_ilist);
938  */
939 }
940 
941 E_API void
e_widget_ilist_remove_num(Evas_Object * obj,int n)942 e_widget_ilist_remove_num(Evas_Object *obj, int n)
943 {
944 /*    _queue_append(obj, CMD_REMOVE, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n); */
945    E_Widget_Callback *wcb;
946    E_Widget_Data *wd;
947    Eina_List *item;
948 
949    if (n < 0) return;
950    wd = e_widget_data_get(obj);
951    if (!wd) return;
952    e_ilist_remove_num(wd->o_ilist, n);
953    item = eina_list_nth_list(wd->callbacks, n);
954    if (item)
955      {
956         wcb = eina_list_data_get(item);
957         if (wcb) eina_stringshare_del(wcb->value);
958         free(wcb);
959         wd->callbacks = eina_list_remove_list(wd->callbacks, item);
960      }
961 }
962 
963 E_API void
e_widget_ilist_multi_select_set(Evas_Object * obj,Eina_Bool multi)964 e_widget_ilist_multi_select_set(Evas_Object *obj, Eina_Bool multi)
965 {
966    E_Widget_Data *wd;
967 
968    wd = e_widget_data_get(obj);
969    if (!wd) return;
970    e_ilist_multi_select_set(wd->o_ilist, multi);
971 }
972 
973 E_API Eina_Bool
e_widget_ilist_multi_select_get(Evas_Object * obj)974 e_widget_ilist_multi_select_get(Evas_Object *obj)
975 {
976    E_Widget_Data *wd;
977 
978    wd = e_widget_data_get(obj);
979    if (!wd) return EINA_FALSE;
980    return e_ilist_multi_select_get(wd->o_ilist);
981 }
982 
983 E_API void
e_widget_ilist_multi_select(Evas_Object * obj,int n)984 e_widget_ilist_multi_select(Evas_Object *obj, int n)
985 {
986    _queue_append(obj, CMD_MULTI_SELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
987 /*
988    E_Widget_Data *wd;
989 
990    wd = e_widget_data_get(obj);
991    e_ilist_multi_select(wd->o_ilist, n);
992  */
993 }
994 
995 E_API void
e_widget_ilist_range_select(Evas_Object * obj,int n)996 e_widget_ilist_range_select(Evas_Object *obj, int n)
997 {
998    _queue_append(obj, CMD_RANGE_SELECT, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, 0, n);
999 /*
1000    E_Widget_Data *wd;
1001 
1002    wd = e_widget_data_get(obj);
1003    e_ilist_range_select(wd->o_ilist, n);
1004  */
1005 }
1006 
1007 E_API Eina_Bool
e_widget_ilist_custom_edje_file_set(Evas_Object * obj,const char * file,const char * group)1008 e_widget_ilist_custom_edje_file_set(Evas_Object *obj, const char *file, const char *group)
1009 {
1010    E_Widget_Data *wd;
1011 
1012    wd = e_widget_data_get(obj);
1013    if (!wd) return EINA_FALSE;
1014    if (group)
1015      {
1016         char buf[1024];
1017 
1018         snprintf(buf, sizeof(buf), "%s/scrollframe", group);
1019         e_scrollframe_custom_edje_file_set(wd->o_scrollframe, file, buf);
1020      }
1021    return e_ilist_custom_edje_file_set(wd->o_ilist, file, group);
1022 }
1023 
1024 E_API void
e_widget_ilist_preferred_size_get(Evas_Object * obj,Evas_Coord * w,Evas_Coord * h)1025 e_widget_ilist_preferred_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
1026 {
1027    Evas_Coord ww, hh, mw, mh, vw, vh;
1028    E_Widget_Data *wd;
1029 
1030    wd = e_widget_data_get(obj);
1031    if (!wd) return;
1032    evas_object_geometry_get(wd->o_scrollframe, NULL, NULL, &ww, &hh);
1033    evas_object_resize(wd->o_scrollframe, 200, 200);
1034    e_scrollframe_child_viewport_size_get(wd->o_scrollframe, &vw, &vh);
1035    e_ilist_size_min_get(wd->o_ilist, &mw, &mh);
1036    evas_object_resize(wd->o_scrollframe, ww, hh);
1037    if (w) *w = 200 - vw + mw;
1038    if (h) *h = 200 - vh + mh;
1039 }
1040 
1041 static void
_e_wid_del_hook(Evas_Object * obj)1042 _e_wid_del_hook(Evas_Object *obj)
1043 {
1044    E_Widget_Data *wd;
1045    E_Widget_Callback *wcb;
1046 
1047    wd = e_widget_data_get(obj);
1048    if (!wd) return;
1049    _queue_clear(obj);
1050    EINA_LIST_FREE(wd->callbacks, wcb)
1051      {
1052         if (wcb) eina_stringshare_del(wcb->value);
1053         free(wcb);
1054      }
1055    free(wd);
1056 }
1057 
1058 static void
_e_wid_focus_hook(Evas_Object * obj)1059 _e_wid_focus_hook(Evas_Object *obj)
1060 {
1061    E_Widget_Data *wd;
1062 
1063    wd = e_widget_data_get(obj);
1064    if (!wd) return;
1065    if (e_widget_focus_get(obj))
1066      {
1067         edje_object_signal_emit(e_scrollframe_edje_object_get(wd->o_scrollframe), "e,state,focused", "e");
1068         evas_object_focus_set(wd->o_ilist, 1);
1069      }
1070    else
1071      {
1072         edje_object_signal_emit(e_scrollframe_edje_object_get(wd->o_scrollframe), "e,state,unfocused", "e");
1073         evas_object_focus_set(wd->o_ilist, 0);
1074      }
1075 }
1076 
1077 static void
_e_wid_cb_scrollframe_resize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1078 _e_wid_cb_scrollframe_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1079 {
1080    Evas_Coord mw, mh, vw, vh, w, h;
1081 
1082    e_scrollframe_child_viewport_size_get(obj, &vw, &vh);
1083    e_ilist_size_min_get(data, &mw, &mh);
1084    evas_object_geometry_get(data, NULL, NULL, &w, &h);
1085    if (vw >= mw)
1086      {
1087         if (w != vw) evas_object_resize(data, vw, h);
1088         evas_object_smart_callback_call(data, "changed", obj);
1089      }
1090 }
1091 
1092 static void
_e_wid_cb_item_sel(void * data,void * data2)1093 _e_wid_cb_item_sel(void *data, void *data2)
1094 {
1095    E_Widget_Data *wd;
1096    Evas_Coord x, y, w, h;
1097    E_Widget_Callback *wcb;
1098 
1099    wd = data;
1100    wcb = data2;
1101    e_ilist_selected_geometry_get(wd->o_ilist, &x, &y, &w, &h);
1102    e_scrollframe_child_region_show(wd->o_scrollframe, x, y, w, h);
1103    if (wd->o_widget)
1104      {
1105         if (wd->value)
1106           {
1107              if (*(wd->value)) eina_stringshare_del(*(wd->value));
1108              if (wcb->value)
1109                *(wd->value) = eina_stringshare_ref(wcb->value);
1110              else
1111                *(wd->value) = NULL;
1112           }
1113         if (wcb->func) wcb->func(wcb->data);
1114         e_widget_change(wd->o_widget);
1115      }
1116 }
1117 
1118 static void
_e_wid_cb_item_hilight(void * data,void * data2 EINA_UNUSED)1119 _e_wid_cb_item_hilight(void *data, void *data2 EINA_UNUSED)
1120 {
1121    E_Widget_Data *wd;
1122    Evas_Coord x, y, w, h;
1123 
1124    wd = data;
1125    e_ilist_selected_geometry_get(wd->o_ilist, &x, &y, &w, &h);
1126    e_scrollframe_child_region_show(wd->o_scrollframe, x, y, w, h);
1127 }
1128 
1129 static void
_e_wid_cb_selected(void * data,Evas_Object * obj EINA_UNUSED,void * event_info)1130 _e_wid_cb_selected(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
1131 {
1132    evas_object_smart_callback_call(data, "selected", event_info);
1133 }
1134 
1135 static void
_e_wid_focus_steal(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1136 _e_wid_focus_steal(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1137 {
1138    e_widget_focus_steal(data);
1139 }
1140 
1141