elementary/diskselector - Elm_Diskselector_Item -> Elm_Object_Item
[framework/uifw/elementary.git] / src / lib / elm_diskselector.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "els_scroller.h"
4
5 #ifndef MAX
6 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
7 #endif
8
9 #ifndef CEIL
10 #define CEIL(a) (((a) % 2 != 0) ? ((a) / 2 + 1) : ((a) / 2))
11 #endif
12
13 #define DISPLAY_ITEM_NUM_MIN 3
14
15 typedef struct _Widget_Data Widget_Data;
16 typedef struct _Elm_Diskselector_Item Elm_Diskselector_Item;
17
18 struct _Widget_Data
19 {
20    Evas_Object *self;
21    Evas_Object *scroller;
22    Evas_Object *main_box;
23    Evas_Object *left_blank;
24    Evas_Object *right_blank;
25    Elm_Diskselector_Item *selected_item;
26    Elm_Diskselector_Item *first;
27    Elm_Diskselector_Item *second;
28    Elm_Diskselector_Item *s_last;
29    Elm_Diskselector_Item *last;
30    Eina_List *items;
31    Eina_List *r_items;
32    Eina_List *over_items;
33    Eina_List *under_items;
34    int item_count, len_threshold, len_side, display_item_num;
35    Ecore_Idle_Enterer *idler;
36    Ecore_Idle_Enterer *check_idler;
37    Evas_Coord minw, minh;
38    Eina_Bool init:1;
39    Eina_Bool round:1;
40    Eina_Bool display_item_num_by_api:1;
41 };
42
43 struct _Elm_Diskselector_Item
44 {
45    ELM_WIDGET_ITEM;
46    Eina_List *node;
47    Evas_Object *icon;
48    const char *label;
49    Evas_Smart_Cb func;
50 };
51
52 static const char *widtype = NULL;
53
54 static Eina_Bool _move_scroller(void *data);
55 static void _del_hook(Evas_Object * obj);
56 static void _del_pre_hook(Evas_Object * obj);
57 static void _sizing_eval(Evas_Object * obj);
58 static void _theme_hook(Evas_Object * obj);
59 static void _on_focus_hook(void *data, Evas_Object *obj);
60 static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info);
61 static void _sub_del(void *data, Evas_Object * obj, void *event_info);
62 static void _round_items_del(Widget_Data *wd);
63 static void _scroller_move_cb(void *data, Evas_Object *obj, void *event_info);
64 static void _item_click_cb(void *data, Evas_Object *obj __UNUSED__,
65                            const char *emission __UNUSED__,
66                            const char *source __UNUSED__);
67 static void _selected_item_indicate(Elm_Diskselector_Item *it);
68
69 static const char SIG_SELECTED[] = "selected";
70 static const Evas_Smart_Cb_Description _signals[] = {
71        {SIG_SELECTED, ""},
72        {NULL, NULL}
73 };
74
75 static void
76 _diskselector_object_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
77 {
78    Widget_Data *wd;
79    Evas_Coord w, h;
80
81    wd = elm_widget_data_get(data);
82    if (!wd) return;
83
84    if ((wd->minw == -1) && (wd->minh == -1))
85       elm_coords_finger_size_adjust(6, &wd->minw, 1, &wd->minh);
86    edje_object_size_min_restricted_calc
87       (elm_smart_scroller_edje_object_get
88           (wd->scroller), &wd->minw, &wd->minh, wd->minw, wd->minh);
89    evas_object_size_hint_min_set(obj, wd->minw, wd->minh);
90    evas_object_size_hint_max_set(obj, -1, -1);
91
92    evas_object_geometry_get(wd->scroller, NULL, NULL, &w, &h);
93    if (wd->round)
94      evas_object_resize(wd->main_box, (w / wd->display_item_num) * (wd->item_count + (CEIL(wd->display_item_num) * 2)), h);
95    else
96      evas_object_resize(wd->main_box, (w / wd->display_item_num) * (wd->item_count + CEIL(wd->display_item_num)), h);
97
98    elm_smart_scroller_paging_set(wd->scroller, 0, 0,
99                                  (int)(w / wd->display_item_num), 0);
100
101    if (!wd->idler)
102      wd->idler = ecore_idle_enterer_before_add(_move_scroller, data);
103 }
104
105 static Elm_Diskselector_Item *
106 _item_new(Evas_Object *obj, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data)
107 {
108    Elm_Diskselector_Item *it;
109    const char *style = elm_widget_style_get(obj);
110
111    it = elm_widget_item_new(obj, Elm_Diskselector_Item);
112    if (!it) return NULL;
113
114    it->label = eina_stringshare_add(label);
115    it->icon = icon;
116    it->func = func;
117    it->base.data = data;
118    VIEW(it) = edje_object_add(evas_object_evas_get(obj));
119    _elm_theme_object_set(obj, VIEW(it), "diskselector", "item", style);
120    evas_object_size_hint_weight_set(VIEW(it), EVAS_HINT_EXPAND,
121                                     EVAS_HINT_EXPAND);
122    evas_object_size_hint_align_set(VIEW(it), EVAS_HINT_FILL,
123                                    EVAS_HINT_FILL);
124    evas_object_show(VIEW(it));
125
126    if (it->label)
127      {
128         edje_object_part_text_set(VIEW(it), "elm.text", it->label);
129         edje_object_signal_callback_add(VIEW(it), "elm,action,click", "", _item_click_cb, it);
130      }
131    if (it->icon)
132      {
133         evas_object_size_hint_min_set(it->icon, 24, 24);
134         evas_object_size_hint_max_set(it->icon, 40, 40);
135         edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon);
136         evas_object_show(it->icon);
137         elm_widget_sub_object_add(obj, it->icon);
138      }
139    return it;
140 }
141
142 static void
143 _item_del(Elm_Diskselector_Item *item)
144 {
145    if (!item) return;
146    eina_stringshare_del(item->label);
147    if (item->icon)
148      evas_object_del(item->icon);
149    elm_widget_item_del(item);
150 }
151
152 static void
153 _theme_data_get(Widget_Data *wd)
154 {
155    const char* str;
156    str = edje_object_data_get(wd->right_blank, "len_threshold");
157    if (str) wd->len_threshold = MAX(0, atoi(str));
158    else wd->len_threshold = 0;
159
160    if (!wd->display_item_num_by_api)
161      {
162         str = edje_object_data_get(wd->right_blank, "display_item_num");
163         if (str) wd->display_item_num = MAX(DISPLAY_ITEM_NUM_MIN, atoi(str));
164         else wd->display_item_num = DISPLAY_ITEM_NUM_MIN;
165      }
166
167    str = edje_object_data_get(wd->right_blank, "min_width");
168    if (str) wd->minw = MAX(-1, atoi(str));
169    else wd->minw = -1;
170
171    str = edje_object_data_get(wd->right_blank, "min_height");
172    if (str) wd->minh = MAX(-1, atoi(str));
173    else wd->minh = -1;
174 }
175
176 static void
177 _del_hook(Evas_Object * obj)
178 {
179    Widget_Data *wd = elm_widget_data_get(obj);
180    if (!wd) return;
181    free(wd);
182 }
183
184 static void
185 _del_pre_hook(Evas_Object * obj)
186 {
187    Elm_Diskselector_Item *it;
188    Eina_List *l;
189
190    Widget_Data *wd = elm_widget_data_get(obj);
191    if (!wd) return;
192
193    if (wd->left_blank)
194      evas_object_del(wd->left_blank);
195    if (wd->right_blank)
196      evas_object_del(wd->right_blank);
197    if (wd->last)
198      {
199         eina_stringshare_del(wd->last->label);
200         evas_object_del(wd->VIEW(last));
201         free(wd->last);
202      }
203    if (wd->s_last)
204      {
205         eina_stringshare_del(wd->s_last->label);
206         evas_object_del(wd->VIEW(s_last));
207         free(wd->s_last);
208      }
209    if (wd->second)
210      {
211         eina_stringshare_del(wd->second->label);
212         evas_object_del(wd->VIEW(second));
213         free(wd->second);
214      }
215    if (wd->first)
216      {
217         eina_stringshare_del(wd->first->label);
218         evas_object_del(wd->VIEW(first));
219         free(wd->first);
220      }
221
222    EINA_LIST_FOREACH(wd->under_items, l, it)
223      {
224         if (it)
225           {
226              eina_stringshare_del(it->label);
227              evas_object_del(VIEW(it));
228              free(it);
229           }
230      }
231
232    EINA_LIST_FOREACH(wd->over_items, l, it)
233    {
234      if (it)
235         {
236            eina_stringshare_del(it->label);
237            evas_object_del(VIEW(it));
238            free(it);
239         }
240    }
241
242    EINA_LIST_FREE(wd->items, it) _item_del(it);
243    eina_list_free(wd->r_items);
244 }
245
246 static void
247 _sizing_eval(Evas_Object * obj)
248 {
249    Widget_Data *wd = elm_widget_data_get(obj);
250    if (!wd) return;
251    _diskselector_object_resize(obj, NULL, obj, NULL);
252 }
253
254 static void
255 _theme_hook(Evas_Object * obj)
256 {
257    Eina_List *l;
258    Elm_Diskselector_Item *it;
259    Widget_Data *wd = elm_widget_data_get(obj);
260    if (!wd) return;
261
262    if (wd->scroller)
263      elm_smart_scroller_object_theme_set(obj, wd->scroller, "diskselector",
264                                          "base", elm_widget_style_get(obj));
265    if (wd->round)
266      {
267         EINA_LIST_FOREACH(wd->r_items, l, it)
268           {
269              _elm_theme_object_set(obj, VIEW(it), "diskselector", "item",
270                                    elm_widget_style_get(obj));
271              edje_object_part_text_set(VIEW(it), "elm.text", it->label);
272           }
273      }
274    else
275      {
276         EINA_LIST_FOREACH(wd->items, l, it)
277           {
278              _elm_theme_object_set(obj, VIEW(it), "diskselector", "item",
279                                    elm_widget_style_get(obj));
280              edje_object_part_text_set(VIEW(it), "elm.text", it->label);
281           }
282      }
283    _elm_theme_object_set(obj, wd->right_blank, "diskselector", "item",
284                                    elm_widget_style_get(obj));
285    _theme_data_get(wd);
286    _sizing_eval(obj);
287 }
288
289 static void
290 _sub_del(void *data __UNUSED__, Evas_Object * obj, void *event_info)
291 {
292    Widget_Data *wd = elm_widget_data_get(obj);
293    Evas_Object *sub = event_info;
294    Elm_Diskselector_Item *it;
295    const Eina_List *l;
296
297    if (!wd) return;
298    if (!sub) abort();
299    if (sub == wd->scroller)
300      wd->scroller = NULL;
301    else
302      {
303         EINA_LIST_FOREACH(wd->items, l, it)
304           {
305              if (sub == it->icon)
306                {
307                   it->icon = NULL;
308                   _sizing_eval(obj);
309                   break;
310                }
311           }
312      }
313 }
314
315 static void
316 _select_item(Elm_Diskselector_Item *it)
317 {
318    if (!it) return;
319    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
320    wd->selected_item = it;
321    _selected_item_indicate(wd->selected_item);
322    if (it->func) it->func((void *)it->base.data, WIDGET(it), it);
323    evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
324 }
325
326 static void
327 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
328 {
329    Widget_Data *wd = elm_widget_data_get(obj);
330    if (!wd)
331      return;
332
333    if (elm_widget_focus_get(obj))
334      {
335         edje_object_signal_emit(wd->self, "elm,action,focus", "elm");
336         evas_object_focus_set(wd->self, EINA_TRUE);
337      }
338    else
339      {
340         edje_object_signal_emit(wd->self, "elm,action,unfocus", "elm");
341         evas_object_focus_set(wd->self, EINA_FALSE);
342      }
343 }
344
345 static Eina_Bool
346 _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
347 {
348    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
349    Evas_Event_Key_Down *ev = event_info;
350    Widget_Data *wd = elm_widget_data_get(obj);
351    if (!wd) return EINA_FALSE;
352    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
353    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
354
355    Elm_Diskselector_Item *it = NULL;
356    Eina_List *l;
357
358    if (!wd->selected_item) {
359         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
360         return EINA_TRUE;
361    }
362
363    if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")) ||
364        (!strcmp(ev->keyname, "Up"))  || (!strcmp(ev->keyname, "KP_Up")))
365      {
366         l = wd->selected_item->node->prev;
367         if ((!l) && (wd->round))
368           l = eina_list_last(wd->items);
369      }
370    else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")) ||
371             (!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
372      {
373         l = wd->selected_item->node->next;
374         if ((!l) && (wd->round))
375           l = wd->items;
376      }
377    else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
378      l = wd->items;
379    else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
380      l = eina_list_last(wd->items);
381    else return EINA_FALSE;
382
383    if (l)
384      it = eina_list_data_get(l);
385
386    if (it)
387      {
388         wd->selected_item = it;
389         if (!wd->idler)
390           wd->idler = ecore_idle_enterer_before_add(_move_scroller, obj);
391      }
392
393    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
394    return EINA_TRUE;
395 }
396
397 static int
398 _count_letter(const char *str)
399 {
400    int pos = 0;
401    int code = 0, chnum;
402
403    for (chnum = 0; ; chnum++)
404      {
405         pos = evas_string_char_next_get(str, pos, &code);
406         if (code == 0) break;
407      }
408    return chnum;
409 }
410
411 static int
412 _check_letter(const char *str, int length)
413 {
414    int pos = 0;
415    int code = 0, chnum;
416
417    for (chnum = 0; ; chnum++)
418      {
419         if (chnum == length) break;
420         pos = evas_string_char_next_get(str, pos, &code);
421         if (code == 0) break;
422      }
423    return pos;
424 }
425
426 static Eina_Bool
427 _check_string(void *data)
428 {
429    int mid, steps, length, diff;
430    Elm_Diskselector_Item *it;
431    Eina_List *list, *l;
432    Evas_Coord ox, ow;
433    char buf[1024];
434    Widget_Data *wd = data;
435
436    evas_object_geometry_get(wd->scroller, &ox, NULL, &ow, NULL);
437    if (ow <= 0)
438      return EINA_FALSE;
439    if (!wd->init)
440      return EINA_FALSE;
441    if (!wd->round)
442      list = wd->items;
443    else
444      list = wd->r_items;
445
446    EINA_LIST_FOREACH(list, l, it)
447      {
448         Evas_Coord x, w;
449         int len;
450         evas_object_geometry_get(VIEW(it), &x, NULL, &w, NULL);
451         /* item not visible */
452         if ((x + w <= ox) || (x >= ox + ow))
453           continue;
454
455         len = _count_letter(it->label);
456 //        // FIXME: len should be # of ut8f letters. ie count using utf8 string walk, not stringshare len
457 //        len = eina_stringshare_strlen(it->label);
458
459         if (x <= ox + 5)
460           edje_object_signal_emit(VIEW(it), "elm,state,left_side",
461                                   "elm");
462         else if (x + w >= ox + ow - 5)
463           edje_object_signal_emit(VIEW(it), "elm,state,right_side",
464                                   "elm");
465         else
466           {
467              if ((wd->len_threshold) && (len > wd->len_threshold))
468                edje_object_signal_emit(VIEW(it), "elm,state,center_small",
469                                        "elm");
470              else
471                edje_object_signal_emit(VIEW(it), "elm,state,center",
472                                        "elm");
473           }
474
475         // if len is les that the limit len, skip anyway
476         if (len <= wd->len_side)
477           continue;
478
479         steps = len - wd->len_side + 1;
480         mid = x + w / 2;
481         if (mid <= ox + ow / 2)
482           diff = (ox + ow / 2) - mid;
483         else
484           diff = mid - (ox + ow / 2);
485
486         length = len - (int)(diff * steps / (ow / 3));
487         length = MAX(length, wd->len_side);
488         // limit string len to "length" ut8f chars
489         length = _check_letter(it->label, length);
490         // cut it off at byte mark returned form _check_letter
491         strncpy(buf, it->label, length);
492         buf[length] = '\0';
493         edje_object_part_text_set(VIEW(it), "elm.text", buf);
494      }
495
496    if (wd->check_idler)
497      ecore_idle_enterer_del(wd->check_idler);
498    wd->check_idler = NULL;
499    return EINA_FALSE;
500 }
501
502 static void
503 _selected_item_indicate(Elm_Diskselector_Item *it)
504 {
505    Elm_Diskselector_Item *item;
506    Eina_List *l;
507    Widget_Data *wd;
508    wd = elm_widget_data_get(WIDGET(it));
509
510    if (!wd) return;
511
512    EINA_LIST_FOREACH(wd->r_items, l, item)
513      {
514         if (!strcmp(item->label, it->label)) edje_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
515         else
516            edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
517      }
518 }
519
520 static void
521 _item_click_cb(void *data, Evas_Object *obj __UNUSED__,
522                const char *emission __UNUSED__, const char *source __UNUSED__)
523 {
524    Elm_Diskselector_Item *it = data;
525
526    if (!it) return;
527
528    Widget_Data *wd;
529    wd = elm_widget_data_get(WIDGET(it));
530
531    if (!wd) return;
532
533    if (wd->selected_item != it)
534      {
535         wd->selected_item = it;
536         _selected_item_indicate(wd->selected_item);
537      }
538
539    if (it->func) it->func((void *)it->base.data, WIDGET(it), it);
540 }
541
542 static void
543 _scroller_move_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
544 {
545    Evas_Coord x, y, w, h, bw;
546    Widget_Data *wd = data;
547
548    _check_string(wd);
549    elm_smart_scroller_child_pos_get(obj, &x, &y);
550    elm_smart_scroller_child_viewport_size_get(obj, &w, &h);
551    if (wd->round)
552      {
553         evas_object_geometry_get(wd->main_box, NULL, NULL, &bw, NULL);
554         if (x > ((w / wd->display_item_num) * (wd->item_count + (wd->display_item_num % 2))))
555            elm_smart_scroller_child_region_show(wd->scroller,
556                                                x - ((w / wd->display_item_num) * wd->item_count),
557                                                y, w, h);
558         else if (x < 0)
559            elm_smart_scroller_child_region_show(wd->scroller,
560                                                x + ((w / wd->display_item_num) * wd->item_count),
561                                                y, w, h);
562      }
563 }
564
565 static void
566 _scroller_stop_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
567 {
568    Elm_Diskselector_Item *it;
569    Widget_Data *wd = data;
570    Evas_Coord x, w, ow;
571    Eina_List *l, *list;
572
573    if (wd->idler)
574      return;
575
576    if (!wd->round)
577      list = wd->items;
578    else
579      list = wd->r_items;
580
581    evas_object_geometry_get(wd->scroller, NULL, NULL, &ow, NULL);
582    EINA_LIST_FOREACH(list, l, it)
583      {
584         evas_object_geometry_get(VIEW(it), &x, NULL, &w, NULL);
585         if (abs((int)(ow / 2 - (int)(x + w / 2))) < 10)
586           break;
587      }
588
589    if (!it)
590      return;
591
592    _select_item(it);
593 }
594
595 static Eina_Bool
596 _move_scroller(void *data)
597 {
598    Evas_Object *obj = data;
599    Widget_Data *wd;
600    Eina_List *list, *l;
601    Elm_Diskselector_Item *dit;
602    Evas_Coord y, w, h;
603    int i;
604
605    wd = elm_widget_data_get(obj);
606    if (!wd) return EINA_FALSE;
607
608    if (!wd->round)
609      {
610         i = 0;
611         list = wd->items;
612      }
613    else
614      {
615         i = 1;
616         list = wd->r_items;
617      }
618
619    EINA_LIST_FOREACH(list, l, dit)
620      {
621         if (wd->selected_item == dit)
622            break;
623         i++;
624      }
625
626    if (wd->round) i -= CEIL(wd->display_item_num);
627
628    if (!dit)
629      {
630         wd->selected_item =
631            (Elm_Diskselector_Item *) eina_list_nth(wd->items, 0);
632         return EINA_FALSE;
633      }
634
635    evas_object_geometry_get(wd->scroller, NULL, &y, &w, &h);
636    elm_smart_scroller_child_region_show(wd->scroller, w / wd->display_item_num * i, y, w, h);
637    _select_item(dit);
638    if (wd->idler)
639      {
640         ecore_idle_enterer_del(wd->idler);
641         wd->idler = NULL;
642      }
643    wd->init = EINA_TRUE;
644    _check_string(wd);
645
646    return EINA_TRUE;
647 }
648
649 static void
650 _round_item_del(Widget_Data *wd, Elm_Diskselector_Item *it)
651 {
652    if (!it) return;
653    elm_box_unpack(wd->main_box, VIEW(it));
654    wd->r_items = eina_list_remove(wd->r_items, it);
655    eina_stringshare_del(it->label);
656    evas_object_del(VIEW(it));
657    free(it);
658 }
659
660 static void
661 _round_items_del(Widget_Data *wd)
662 {
663    Eina_List *l;
664    Elm_Diskselector_Item * it;
665
666    _round_item_del(wd, wd->last);
667    wd->last = NULL;
668    _round_item_del(wd, wd->s_last);
669    wd->s_last = NULL;
670    _round_item_del(wd, wd->second);
671    wd->second = NULL;
672    _round_item_del(wd, wd->first);
673    wd->first = NULL;
674
675    EINA_LIST_FOREACH(wd->under_items, l, it)
676      {
677         _round_item_del(wd, it);
678      }
679    wd->under_items = eina_list_free(wd->under_items);
680
681    EINA_LIST_FOREACH(wd->over_items, l, it)
682      {
683         _round_item_del(wd, it);
684      }
685    wd->over_items = eina_list_free(wd->over_items);
686 }
687
688 static void
689 _round_items_add(Widget_Data *wd)
690 {
691    Elm_Diskselector_Item *dit;
692    Elm_Diskselector_Item *it;
693    Elm_Diskselector_Item *temp_it;
694    int i = 0;
695    dit = it = eina_list_nth(wd->items, 0);
696    if (!dit) return;
697
698    if (!wd->first)
699      {
700         wd->first = _item_new(WIDGET(it), it->icon, it->label, it->func,
701                               it->base.data);
702         wd->first->node = it->node;
703         wd->r_items = eina_list_append(wd->r_items, wd->first);
704      }
705
706    it = eina_list_nth(wd->items, 1);
707    if (!it)
708      it = dit;
709    if (!wd->second)
710      {
711         wd->second = _item_new(WIDGET(it), it->icon, it->label, it->func,
712                                it->base.data);
713         wd->second->node = it->node;
714         wd->r_items = eina_list_append(wd->r_items, wd->second);
715      }
716
717    // if more than 3 itmes should be displayed
718    for (i = 2; i < CEIL(wd->display_item_num); i++)
719      {
720         it = eina_list_nth(wd->items, i);
721         if (!it) it = dit;
722         temp_it = _item_new(WIDGET(it), it->icon, it->label, it->func, it->base.data);
723         wd->over_items = eina_list_append(wd->over_items, temp_it);
724         wd->r_items = eina_list_append(wd->r_items, temp_it);
725      }
726
727    it = eina_list_nth(wd->items, wd->item_count - 1);
728    if (!it)
729      it = dit;
730    if (!wd->last)
731      {
732         wd->last = _item_new(WIDGET(it), it->icon, it->label, it->func,
733                              it->base.data);
734         wd->last->node = it->node;
735         wd->r_items = eina_list_prepend(wd->r_items, wd->last);
736      }
737
738    it = eina_list_nth(wd->items, wd->item_count - 2);
739    if (!it)
740      it = dit;
741    if (!wd->s_last)
742      {
743         wd->s_last = _item_new(WIDGET(it), it->icon, it->label, it->func,
744                                it->base.data);
745         wd->s_last->node = it->node;
746         wd->r_items = eina_list_prepend(wd->r_items, wd->s_last);
747      }
748
749    // if more than 3 itmes should be displayed
750    for (i = 3; i <= CEIL(wd->display_item_num); i++)
751      {
752         it = eina_list_nth(wd->items, wd->item_count - i);
753         if (!it) it = dit;
754         temp_it = _item_new(WIDGET(it), it->icon, it->label, it->func, it->base.data);
755         wd->under_items = eina_list_append(wd->under_items, temp_it);
756         wd->r_items = eina_list_prepend(wd->r_items, temp_it);
757      }
758 }
759
760 static void
761 _item_icon_set(Elm_Diskselector_Item *it, Evas_Object *icon)
762 {
763    if (it->icon == icon) return;
764    if (it->icon)
765      evas_object_del(it->icon);
766    it->icon = icon;
767    if (VIEW(it))
768      {
769         evas_object_size_hint_min_set(it->icon, 24, 24);
770         evas_object_size_hint_max_set(it->icon, 40, 40);
771         edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon);
772         evas_object_show(it->icon);
773         elm_widget_sub_object_add(WIDGET(it), it->icon);
774      }
775 }
776
777 static void
778 _check_identical_item(Elm_Diskselector_Item *it, Evas_Object *icon)
779 {
780    Widget_Data *wd;
781    Elm_Diskselector_Item *dit;
782    Eina_List *l;
783    int idx = 0;
784    int ic = 0;
785    int ac = 0;
786
787    wd = elm_widget_data_get(WIDGET(it));
788    if (!wd) return;
789
790    if (wd->round)
791      {
792         // Get index from indentical item from round items
793         EINA_LIST_FOREACH(wd->r_items, l, dit)
794           {
795              if (it == dit) break;
796              idx++;
797           }
798
799         // No item to match
800         ic = eina_list_count(wd->r_items);
801         if (idx >= ic) return;
802         dit = NULL;
803
804         // Number of added items: CEIL(wd->display_item_num)
805         ac = CEIL(wd->display_item_num);
806
807         if (((idx >= 0) && (idx < ac)) ||
808             ((idx >= ac) && (idx < (2 * ac))))
809           {
810               // Selected item: under, low region
811              dit = eina_list_nth(wd->r_items,
812                                  idx + ic - (2 * ac));
813           }
814         else if (((idx >= (ic - ac)) && (idx < ic)) ||
815                  ((idx >= (ic - (2 * ac))) && (idx < ic - ac)))
816           {
817               // Selected item: over, high region
818               dit = eina_list_nth(wd->r_items,
819                                   idx - ic + (2 * ac));
820           }
821
822         if(dit) _item_icon_set(dit, icon);
823         _sizing_eval(wd->self);
824      }
825 }
826
827 EAPI Evas_Object *
828 elm_diskselector_add(Evas_Object *parent)
829 {
830    Evas *e;
831    Evas_Object *obj;
832    Widget_Data *wd;
833
834    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
835
836    ELM_SET_WIDTYPE(widtype, "diskselector");
837    elm_widget_type_set(obj, "diskselector");
838    elm_widget_sub_object_add(parent, obj);
839    elm_widget_data_set(obj, wd);
840    elm_widget_del_hook_set(obj, _del_hook);
841    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
842    elm_widget_theme_hook_set(obj, _theme_hook);
843    elm_widget_can_focus_set(obj, EINA_TRUE);
844    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
845    elm_widget_event_hook_set(obj, _event_hook);
846
847    wd->self = obj;
848    wd->item_count = 0;
849    wd->round = EINA_FALSE;
850    wd->init = EINA_FALSE;
851    wd->len_side = 3;
852    wd->display_item_num_by_api = EINA_FALSE;
853
854    wd->scroller = elm_smart_scroller_add(e);
855    elm_smart_scroller_widget_set(wd->scroller, obj);
856    _theme_hook(obj);
857    elm_widget_resize_object_set(obj, wd->scroller);
858    elm_smart_scroller_policy_set(wd->scroller, ELM_SMART_SCROLLER_POLICY_OFF,
859                                  ELM_SMART_SCROLLER_POLICY_OFF);
860    elm_smart_scroller_bounce_allow_set(wd->scroller, EINA_TRUE, EINA_FALSE);
861    evas_object_smart_callback_add(wd->scroller, "scroll", _scroller_move_cb,
862                                   wd);
863    evas_object_smart_callback_add(wd->scroller, "animate,stop",
864                                   _scroller_stop_cb, wd);
865    _elm_theme_object_set(obj, wd->scroller, "diskselector", "base",
866                          "default");
867    evas_object_event_callback_add(wd->scroller, EVAS_CALLBACK_RESIZE,
868                                   _diskselector_object_resize, obj);
869
870    wd->main_box = elm_box_add(parent);
871    elm_box_horizontal_set(wd->main_box, EINA_TRUE);
872    elm_box_homogeneous_set(wd->main_box, EINA_TRUE);
873    evas_object_size_hint_weight_set(wd->main_box, EVAS_HINT_EXPAND,
874                                     EVAS_HINT_EXPAND);
875    evas_object_size_hint_align_set(wd->main_box, EVAS_HINT_FILL,
876                                    EVAS_HINT_FILL);
877    _elm_theme_object_set(obj, wd->main_box, "diskselector", "base",
878                          "default");
879    elm_widget_sub_object_add(obj, wd->main_box);
880
881    elm_smart_scroller_child_set(wd->scroller, wd->main_box);
882
883    wd->left_blank = edje_object_add(evas_object_evas_get(obj));
884    _elm_theme_object_set(obj, wd->left_blank, "diskselector", "item",
885                          "default");
886    evas_object_size_hint_weight_set(wd->left_blank, EVAS_HINT_EXPAND,
887                                     EVAS_HINT_EXPAND);
888    evas_object_size_hint_align_set(wd->left_blank, EVAS_HINT_FILL,
889                                    EVAS_HINT_FILL);
890    elm_box_pack_end(wd->main_box, wd->left_blank);
891    evas_object_show(wd->left_blank);
892
893    wd->right_blank = edje_object_add(evas_object_evas_get(obj));
894    _elm_theme_object_set(obj, wd->right_blank, "diskselector", "item",
895                          "default");
896    evas_object_size_hint_weight_set(wd->right_blank, EVAS_HINT_EXPAND,
897                                     EVAS_HINT_EXPAND);
898    evas_object_size_hint_align_set(wd->right_blank, EVAS_HINT_FILL,
899                                    EVAS_HINT_FILL);
900    elm_box_pack_end(wd->main_box, wd->right_blank);
901    evas_object_show(wd->right_blank);
902
903    _theme_data_get(wd);
904
905    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
906    evas_object_smart_callbacks_descriptions_set(obj, _signals);
907    _sizing_eval(obj);
908    return obj;
909 }
910
911 EAPI Eina_Bool
912 elm_diskselector_round_get(const Evas_Object *obj)
913 {
914    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
915    Widget_Data *wd = elm_widget_data_get(obj);
916    if (!wd) return EINA_FALSE;
917    return wd->round;
918 }
919
920 EAPI void
921 elm_diskselector_round_set(Evas_Object * obj, Eina_Bool round)
922 {
923    Eina_List *elist;
924    Elm_Diskselector_Item *it;
925
926    ELM_CHECK_WIDTYPE(obj, widtype);
927    Widget_Data *wd = elm_widget_data_get(obj);
928    if (!wd) return;
929
930    if (wd->round == round)
931      return;
932
933    wd->round = round;
934    if (round)
935      {
936         wd->r_items = eina_list_clone(wd->items);
937         elm_box_unpack(wd->main_box, wd->left_blank);
938         evas_object_hide(wd->left_blank);
939         elm_box_unpack(wd->main_box, wd->right_blank);
940         evas_object_hide(wd->right_blank);
941         if (!wd->items)
942           return;
943
944         _round_items_add(wd);
945
946         if (wd->last)
947           elm_box_pack_start(wd->main_box, wd->VIEW(last));
948         if (wd->s_last)
949           elm_box_pack_start(wd->main_box, wd->VIEW(s_last));
950
951         // if more than 3 items should be displayed
952         EINA_LIST_FOREACH(wd->under_items, elist, it)
953            elm_box_pack_start(wd->main_box, VIEW(it));
954
955         if (wd->first)
956           elm_box_pack_end(wd->main_box, wd->VIEW(first));
957         if (wd->second)
958           elm_box_pack_end(wd->main_box, wd->VIEW(second));
959
960         // if more than 3 items should be displayed
961         EINA_LIST_FOREACH(wd->over_items, elist, it)
962            elm_box_pack_end(wd->main_box, VIEW(it));
963      }
964    else
965      {
966         _round_items_del(wd);
967         elm_box_pack_start(wd->main_box, wd->left_blank);
968         elm_box_pack_end(wd->main_box, wd->right_blank);
969         eina_list_free(wd->r_items);
970         wd->r_items = NULL;
971      }
972
973    _selected_item_indicate(wd->selected_item);
974    _sizing_eval(obj);
975 }
976
977 EAPI int
978 elm_diskselector_side_label_length_get(const Evas_Object *obj)
979 {
980    ELM_CHECK_WIDTYPE(obj, widtype) 0;
981    Widget_Data *wd = elm_widget_data_get(obj);
982    if (!wd) return 0;
983    return wd->len_side;
984 }
985
986 EAPI void
987 elm_diskselector_side_label_length_set(Evas_Object *obj, int len)
988 {
989    ELM_CHECK_WIDTYPE(obj, widtype);
990    Widget_Data *wd = elm_widget_data_get(obj);
991    if (!wd) return;
992    wd->len_side = len;
993 }
994
995 EAPI void
996 elm_diskselector_side_label_lenght_set(Evas_Object *obj, int len)
997 {
998    return elm_diskselector_side_label_length_set(obj, len);
999 }
1000
1001 EAPI int
1002 elm_diskselector_side_label_lenght_get(const Evas_Object *obj)
1003 {
1004    return elm_diskselector_side_label_length_get(obj);
1005 }
1006
1007 EAPI void
1008 elm_diskselector_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
1009 {
1010    ELM_CHECK_WIDTYPE(obj, widtype);
1011    Widget_Data *wd = elm_widget_data_get(obj);
1012    if (!wd) return;
1013    if (wd->scroller)
1014      elm_smart_scroller_bounce_allow_set(wd->scroller, h_bounce, v_bounce);
1015 }
1016
1017 EAPI void
1018 elm_diskselector_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
1019 {
1020    ELM_CHECK_WIDTYPE(obj, widtype);
1021    Widget_Data *wd = elm_widget_data_get(obj);
1022    if (!wd) return;
1023    elm_smart_scroller_bounce_allow_get(wd->scroller, h_bounce, v_bounce);
1024 }
1025
1026 EAPI void
1027 elm_diskselector_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
1028 {
1029    ELM_CHECK_WIDTYPE(obj, widtype);
1030    Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
1031    Widget_Data *wd = elm_widget_data_get(obj);
1032    if ((!wd) || (!wd->scroller)) return;
1033    elm_smart_scroller_policy_get(wd->scroller, &s_policy_h, &s_policy_v);
1034    *policy_h = (Elm_Scroller_Policy) s_policy_h;
1035    *policy_v = (Elm_Scroller_Policy) s_policy_v;
1036 }
1037
1038 EAPI void
1039 elm_diskselector_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
1040 {
1041    ELM_CHECK_WIDTYPE(obj, widtype);
1042    Widget_Data *wd = elm_widget_data_get(obj);
1043    if ((!wd) || (!wd->scroller)) return;
1044    if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
1045        (policy_v >= ELM_SCROLLER_POLICY_LAST))
1046      return;
1047    elm_smart_scroller_policy_set(wd->scroller, policy_h, policy_v);
1048 }
1049
1050 EAPI void
1051 elm_diskselector_clear(Evas_Object *obj)
1052 {
1053    ELM_CHECK_WIDTYPE(obj, widtype);
1054    Widget_Data *wd = elm_widget_data_get(obj);
1055    Elm_Diskselector_Item *it;
1056
1057    if (!wd) return;
1058    if (!wd->items) return;
1059
1060    wd->selected_item = NULL;
1061    EINA_LIST_FREE(wd->items, it) _item_del(it);
1062    _round_items_del(wd);
1063    _sizing_eval(obj);
1064 }
1065
1066 EAPI const Eina_List *
1067 elm_diskselector_items_get(const Evas_Object *obj)
1068 {
1069    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1070    Widget_Data *wd = elm_widget_data_get(obj);
1071    if (!wd) return NULL;
1072    return wd->items;
1073 }
1074
1075 EAPI Elm_Object_Item *
1076 elm_diskselector_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
1077 {
1078    Elm_Diskselector_Item *it;
1079    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1080    Widget_Data *wd = elm_widget_data_get(obj);
1081    if (!wd) return NULL;
1082
1083    it = _item_new(obj, icon, label, func, data);
1084    wd->items = eina_list_append(wd->items, it);
1085    it->node = eina_list_last(wd->items);
1086    wd->item_count++;
1087    if (wd->round)
1088      {
1089         _round_items_del(wd);
1090         wd->r_items = eina_list_append(wd->r_items, it);
1091         _round_items_add(wd);
1092         if (wd->last)
1093           elm_box_pack_start(wd->main_box, wd->VIEW(last));
1094         if (wd->s_last)
1095           elm_box_pack_start(wd->main_box, wd->VIEW(s_last));
1096         elm_box_pack_end(wd->main_box, VIEW(it));
1097         if (wd->first)
1098           elm_box_pack_end(wd->main_box, wd->VIEW(first));
1099         if (wd->second)
1100           elm_box_pack_end(wd->main_box, wd->VIEW(second));
1101      }
1102    else
1103      {
1104         elm_box_unpack(wd->main_box, wd->right_blank);
1105         elm_box_pack_end(wd->main_box, VIEW(it));
1106         elm_box_pack_end(wd->main_box, wd->right_blank);
1107      }
1108    if (!wd->selected_item)
1109      wd->selected_item = it;
1110    if (!wd->idler)
1111      wd->idler = ecore_idle_enterer_before_add(_move_scroller, obj);
1112    _sizing_eval(obj);
1113    return (Elm_Object_Item *) it;
1114 }
1115
1116 EAPI void
1117 elm_diskselector_item_del(Elm_Object_Item * it)
1118 {
1119    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1120    Elm_Diskselector_Item *item, *item2, *dit;
1121    Eina_List *l;
1122    int i = 0;
1123    Widget_Data *wd;
1124    item = (Elm_Diskselector_Item *) it;
1125    wd = elm_widget_data_get(WIDGET(item));
1126    if (!wd) return;
1127
1128    elm_box_unpack(wd->main_box, VIEW(item));
1129
1130    if (wd->round)
1131      wd->r_items = eina_list_remove(wd->r_items, item);
1132
1133    wd->items = eina_list_remove(wd->items, item);
1134
1135    if (wd->selected_item == item)
1136      {
1137         dit = (Elm_Diskselector_Item *) eina_list_nth(wd->items, 0);
1138         if (dit != item)
1139           wd->selected_item = dit;
1140         else
1141           wd->selected_item = eina_list_nth(wd->items, 1);
1142
1143         _selected_item_indicate(wd->selected_item);
1144      }
1145
1146    _item_del(item);
1147    wd->item_count -= 1;
1148
1149    if (wd->round)
1150      {
1151         if (!wd->item_count)
1152           {
1153              evas_object_hide(wd->VIEW(first));
1154              evas_object_hide(wd->VIEW(second));
1155              evas_object_hide(wd->VIEW(last));
1156              evas_object_hide(wd->VIEW(s_last));
1157
1158              EINA_LIST_FOREACH(wd->under_items, l, item2)
1159                evas_object_hide(VIEW(item2));
1160
1161              EINA_LIST_FOREACH(wd->over_items, l, item2)
1162                evas_object_hide(VIEW(item2));
1163           }
1164         else
1165           {
1166              dit = eina_list_nth(wd->items, 0);
1167              if (dit)
1168                {
1169                   eina_stringshare_replace(&wd->first->label, dit->label);
1170                   edje_object_part_text_set(wd->VIEW(first), "elm.text",
1171                                             wd->first->label);
1172                }
1173              dit = eina_list_nth(wd->items, 1);
1174              if (dit)
1175                {
1176                   eina_stringshare_replace(&wd->second->label, dit->label);
1177                   edje_object_part_text_set(wd->VIEW(second), "elm.text",
1178                                             wd->second->label);
1179                }
1180              // if more than 3 itmes should be displayed
1181              for (i = 2; i < CEIL(wd->display_item_num); i++)
1182                {
1183                   dit = eina_list_nth(wd->items, i);
1184                   item2 = eina_list_nth(wd->over_items, i - 2);
1185                   eina_stringshare_replace(&item2->label, dit->label);
1186                   edje_object_part_text_set(VIEW(item2), "elm.text", item2->label);
1187                }
1188
1189              dit = eina_list_nth(wd->items, eina_list_count(wd->items) - 1);
1190              if (dit)
1191                {
1192                   eina_stringshare_replace(&wd->last->label, dit->label);
1193                   edje_object_part_text_set(wd->VIEW(last), "elm.text",
1194                                             wd->last->label);
1195                }
1196              dit = eina_list_nth(wd->items, eina_list_count(wd->items) - 2);
1197              if (dit)
1198                {
1199                   eina_stringshare_replace(&wd->s_last->label, dit->label);
1200                   edje_object_part_text_set(wd->VIEW(s_last), "elm.text",
1201                                             wd->s_last->label);
1202                }
1203              // if more than 3 itmes should be displayed
1204              for (i = 3; i <= CEIL(wd->display_item_num); i++)
1205                {
1206                   dit = eina_list_nth(wd->items, wd->item_count - i);
1207                   item2 = eina_list_nth(wd->under_items, i - 3);
1208                   eina_stringshare_replace(&item2->label, dit->label);
1209                   edje_object_part_text_set(VIEW(item2), "elm.text",
1210                                             item2->label);
1211                }
1212           }
1213      }
1214    wd->check_idler = ecore_idle_enterer_before_add(_check_string, wd);
1215    _sizing_eval(wd->self);
1216 }
1217
1218 EAPI const char *
1219 elm_diskselector_item_label_get(const Elm_Object_Item * it)
1220 {
1221    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1222    return ((Elm_Diskselector_Item *) it)->label;
1223 }
1224
1225 EAPI void
1226 elm_diskselector_item_label_set(Elm_Object_Item * it, const char *label)
1227 {
1228    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1229    Elm_Diskselector_Item *item = (Elm_Diskselector_Item *) it;
1230    eina_stringshare_replace(&item->label, label);
1231    edje_object_part_text_set(VIEW(item), "elm.text", item->label);
1232 }
1233
1234 EAPI Elm_Object_Item *
1235 elm_diskselector_selected_item_get(const Evas_Object *obj)
1236 {
1237    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1238    Widget_Data *wd = elm_widget_data_get(obj);
1239    if (!wd) return NULL;
1240    return (Elm_Object_Item *) wd->selected_item;
1241 }
1242
1243 EAPI void
1244 elm_diskselector_item_selected_set(Elm_Object_Item *it, Eina_Bool selected)
1245 {
1246    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1247    Widget_Data *wd;
1248    Elm_Diskselector_Item *item = (Elm_Diskselector_Item *) it;
1249    wd = elm_widget_data_get(WIDGET(item));
1250    if (!wd) return;
1251
1252    if ((wd->selected_item == item) && (selected))
1253      return;
1254
1255    if ((wd->selected_item == item) && (!selected))
1256      wd->selected_item = eina_list_data_get(wd->items);
1257    else
1258      {
1259         wd->selected_item = item;
1260         _selected_item_indicate(wd->selected_item);
1261      }
1262
1263    if (!wd->idler)
1264      wd->idler = ecore_idle_enterer_before_add(_move_scroller, WIDGET(item));
1265 }
1266
1267 EAPI Eina_Bool
1268 elm_diskselector_item_selected_get(const Elm_Object_Item *it)
1269 {
1270    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1271    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
1272    if (!wd) return EINA_FALSE;
1273    return (wd->selected_item == ((Elm_Diskselector_Item *) it));
1274 }
1275
1276 EAPI void
1277 elm_diskselector_item_del_cb_set(Elm_Object_Item *it, Evas_Smart_Cb func)
1278 {
1279    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1280    elm_widget_item_del_cb_set(it, func);
1281 }
1282
1283 EAPI void *
1284 elm_diskselector_item_data_get(const Elm_Object_Item *it)
1285 {
1286    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1287    return elm_widget_item_data_get(it);
1288 }
1289
1290 EAPI Evas_Object *
1291 elm_diskselector_item_icon_get(const Elm_Object_Item *it)
1292 {
1293    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1294    return ((Elm_Diskselector_Item *) it)->icon;
1295 }
1296
1297 EAPI void
1298 elm_diskselector_item_icon_set(Elm_Object_Item *it, Evas_Object *icon)
1299 {
1300    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1301    _item_icon_set((Elm_Diskselector_Item *) it, icon);
1302    _check_identical_item((Elm_Diskselector_Item *) it, icon);
1303 }
1304
1305 EAPI Elm_Object_Item *
1306 elm_diskselector_item_prev_get(const Elm_Object_Item *it)
1307 {
1308    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1309    Elm_Diskselector_Item *item = (Elm_Diskselector_Item *) it;
1310    if (item->node->prev) return item->node->prev->data;
1311    else return NULL;
1312 }
1313
1314 EAPI Elm_Object_Item *
1315 elm_diskselector_item_next_get(const Elm_Object_Item *it)
1316 {
1317    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1318    Elm_Diskselector_Item *item = (Elm_Diskselector_Item *) it;
1319    if (item->node->next) return item->node->next->data;
1320    else return NULL;
1321 }
1322
1323 EAPI Elm_Object_Item *
1324 elm_diskselector_first_item_get(const Evas_Object *obj)
1325 {
1326    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1327    Widget_Data *wd = elm_widget_data_get(obj);
1328    if (!wd || !wd->items) return NULL;
1329    return eina_list_data_get(wd->items);
1330 }
1331
1332 EAPI Elm_Object_Item *
1333 elm_diskselector_last_item_get(const Evas_Object *obj)
1334 {
1335    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1336    Widget_Data *wd = elm_widget_data_get(obj);
1337    if (!wd || !wd->items) return NULL;
1338    return eina_list_data_get(eina_list_last(wd->items));
1339 }
1340
1341 EAPI void
1342 elm_diskselector_item_tooltip_text_set(Elm_Object_Item *it, const char *text)
1343 {
1344    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1345    elm_widget_item_tooltip_text_set(it, text);
1346 }
1347
1348 EAPI void
1349 elm_diskselector_item_tooltip_content_cb_set(Elm_Object_Item *it, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
1350 {
1351    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1352    elm_widget_item_tooltip_content_cb_set(it, func, data, del_cb);
1353 }
1354
1355 EAPI void
1356 elm_diskselector_item_tooltip_unset(Elm_Object_Item *it)
1357 {
1358    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1359    elm_widget_item_tooltip_unset(it);
1360 }
1361
1362 EAPI void
1363 elm_diskselector_item_tooltip_style_set(Elm_Object_Item *it, const char *style)
1364 {
1365    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1366    elm_widget_item_tooltip_style_set(it, style);
1367 }
1368
1369 EAPI const char *
1370 elm_diskselector_item_tooltip_style_get(const Elm_Object_Item *it)
1371 {
1372    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1373    return elm_widget_item_tooltip_style_get(it);
1374 }
1375
1376 EAPI void
1377 elm_diskselector_item_cursor_set(Elm_Object_Item *it, const char *cursor)
1378 {
1379    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1380    elm_widget_item_cursor_set(it, cursor);
1381 }
1382
1383 EAPI const char *
1384 elm_diskselector_item_cursor_get(const Elm_Object_Item *it)
1385 {
1386    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1387    return elm_widget_item_cursor_get(it);
1388 }
1389
1390 EAPI void
1391 elm_diskselector_item_cursor_unset(Elm_Object_Item *it)
1392 {
1393    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1394    elm_widget_item_cursor_unset(it);
1395 }
1396
1397 EAPI void
1398 elm_diskselector_item_cursor_style_set(Elm_Object_Item *it, const char *style)
1399 {
1400    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1401    elm_widget_item_cursor_style_set(it, style);
1402 }
1403
1404 EAPI const char *
1405 elm_diskselector_item_cursor_style_get(const Elm_Object_Item *it)
1406 {
1407    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1408    return elm_widget_item_cursor_style_get(it);
1409 }
1410
1411 EAPI void
1412 elm_diskselector_item_cursor_engine_only_set(Elm_Object_Item *it, Eina_Bool engine_only)
1413 {
1414    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1415    elm_widget_item_cursor_engine_only_set(it, engine_only);
1416 }
1417
1418 EAPI Eina_Bool
1419 elm_diskselector_item_cursor_engine_only_get(const Elm_Object_Item *it)
1420 {
1421    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1422    return elm_widget_item_cursor_engine_only_get(it);
1423 }
1424
1425 EAPI void
1426 elm_diskselector_display_item_num_set(Evas_Object *obj, int num)
1427 {
1428    ELM_CHECK_WIDTYPE(obj, widtype);
1429    Widget_Data *wd = elm_widget_data_get(obj);
1430    if (!wd) return;
1431    if (num < DISPLAY_ITEM_NUM_MIN) num = DISPLAY_ITEM_NUM_MIN;
1432    wd->display_item_num = num;
1433    wd->display_item_num_by_api = EINA_TRUE;
1434 }
1435
1436 EAPI int
1437 elm_diskselector_display_item_num_get(const Evas_Object *item)
1438 {
1439    ELM_CHECK_WIDTYPE(item, widtype) (-1);
1440    Widget_Data *wd = elm_widget_data_get(item);
1441    if (!wd) return -1;
1442    return wd->display_item_num;
1443 }