it's the subtle null derefs that'll get you
[framework/uifw/elementary.git] / src / lib / elm_diskselector.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #ifndef MAX
5 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
6 #endif
7
8 #ifndef CEIL
9 #define CEIL(a) (((a) % 2 != 0) ? ((a) / 2 + 1) : ((a) / 2))
10 #endif
11
12 #define DISPLAY_ITEM_NUM_MIN 3
13
14 typedef struct _Widget_Data Widget_Data;
15
16 struct _Widget_Data
17 {
18    Evas_Object *self;
19    Evas_Object *scroller;
20    Evas_Object *main_box;
21    Evas_Object *left_blank;
22    Evas_Object *right_blank;
23    Elm_Diskselector_Item *selected_item;
24    Elm_Diskselector_Item *first;
25    Elm_Diskselector_Item *second;
26    Elm_Diskselector_Item *s_last;
27    Elm_Diskselector_Item *last;
28    Eina_List *items;
29    Eina_List *r_items;
30    Eina_List *over_items;
31    Eina_List *under_items;
32    int item_count, len_threshold, len_side, display_item_num;
33    Ecore_Idler *idler;
34    Ecore_Idler *check_idler;
35    Evas_Coord minw, minh;
36    Eina_Bool init:1;
37    Eina_Bool round:1;
38    Eina_Bool display_item_num_by_api:1;
39 };
40
41 struct _Elm_Diskselector_Item
42 {
43    Elm_Widget_Item base;
44    Eina_List *node;
45    Evas_Object *icon;
46    const char *label;
47    Evas_Smart_Cb func;
48 };
49
50 static const char *widtype = NULL;
51
52 #define ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, ...)                  \
53    ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
54    ELM_CHECK_WIDTYPE(it->base.widget, widtype) __VA_ARGS__;
55
56 static Eina_Bool _move_scroller(void *data);
57 static void _del_hook(Evas_Object * obj);
58 static void _del_pre_hook(Evas_Object * obj);
59 static void _sizing_eval(Evas_Object * obj);
60 static void _theme_hook(Evas_Object * obj);
61 static void _on_focus_hook(void *data, Evas_Object *obj);
62 static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info);
63 static void _sub_del(void *data, Evas_Object * obj, void *event_info);
64 static void _round_items_del(Widget_Data *wd);
65 static void _scroller_move_cb(void *data, Evas_Object *obj, void *event_info);
66 static void _item_click_cb(void *data, Evas_Object *obj __UNUSED__,
67                            const char *emission __UNUSED__,
68                            const char *source __UNUSED__);
69 static void _selected_item_indicate(Elm_Diskselector_Item *it);
70
71 static const char SIG_SELECTED[] = "selected";
72 static const Evas_Smart_Cb_Description _signals[] = {
73        {SIG_SELECTED, ""},
74        {NULL, NULL}
75 };
76
77 static void
78 _diskselector_object_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
79 {
80    Widget_Data *wd;
81    Evas_Coord w, h;
82
83    wd = elm_widget_data_get(data);
84    if (!wd) return;
85
86    if (wd->minw == -1 && wd->minh == -1) elm_coords_finger_size_adjust(6, &wd->minw, 1, &wd->minh);
87    edje_object_size_min_restricted_calc(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_idler_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    it->base.view = edje_object_add(evas_object_evas_get(obj));
119    _elm_theme_object_set(obj, it->base.view, "diskselector", "item", style);
120    evas_object_size_hint_weight_set(it->base.view, EVAS_HINT_EXPAND,
121                                     EVAS_HINT_EXPAND);
122    evas_object_size_hint_align_set(it->base.view, EVAS_HINT_FILL,
123                                    EVAS_HINT_FILL);
124    evas_object_show(it->base.view);
125
126    if (it->label)
127      {
128         edje_object_part_text_set(it->base.view, "elm.text", it->label);
129         edje_object_signal_callback_add(it->base.view, "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(it->base.view, "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->last->base.view);
201         free(wd->last);
202      }
203    if (wd->s_last)
204      {
205         eina_stringshare_del(wd->s_last->label);
206         evas_object_del(wd->s_last->base.view);
207         free(wd->s_last);
208      }
209    if (wd->second)
210      {
211         eina_stringshare_del(wd->second->label);
212         evas_object_del(wd->second->base.view);
213         free(wd->second);
214      }
215    if (wd->first)
216      {
217         eina_stringshare_del(wd->first->label);
218         evas_object_del(wd->first->base.view);
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              if (wd->first) evas_object_del(wd->first->base.view);
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            if (wd->first) evas_object_del(wd->first->base.view);
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, it->base.view, "diskselector", "item",
270                                    elm_widget_style_get(obj));
271              edje_object_part_text_set(it->base.view, "elm.text", it->label);
272           }
273      }
274    else
275      {
276         EINA_LIST_FOREACH(wd->items, l, it)
277           {
278              _elm_theme_object_set(obj, it->base.view, "diskselector", "item",
279                                    elm_widget_style_get(obj));
280              edje_object_part_text_set(it->base.view, "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(it->base.widget);
320    wd->selected_item = it;
321    _selected_item_indicate(wd->selected_item);
322    if (it->func) it->func((void *)it->base.data, it->base.widget, it);
323    evas_object_smart_callback_call(it->base.widget, 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_idler_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(it->base.view, &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(it->base.view, "elm,state,left_side",
461                                   "elm");
462         else if (x + w >= ox + ow - 5)
463           edje_object_signal_emit(it->base.view, "elm,state,right_side",
464                                   "elm");
465         else
466           {
467              if ((wd->len_threshold) && (len > wd->len_threshold))
468                edje_object_signal_emit(it->base.view, "elm,state,center_small",
469                                        "elm");
470              else
471                edje_object_signal_emit(it->base.view, "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(it->base.view, "elm.text", buf);
494      }
495
496    if (wd->check_idler)
497      ecore_idler_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(it->base.widget);
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(item->base.view, "elm,state,selected", "elm");
515         else
516            edje_object_signal_emit(item->base.view, "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(it->base.widget);
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, it->base.widget, 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(it->base.view, &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 *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      i = 1;
610    else
611      i = 0;
612
613    EINA_LIST_FOREACH(wd->items, l, dit)
614      {
615         if (wd->selected_item == dit)
616           break;
617         i++;
618      }
619    if (!dit)
620      {
621         wd->selected_item =
622            (Elm_Diskselector_Item *) eina_list_nth(wd->items, 0);
623         return EINA_FALSE;
624      }
625
626    evas_object_geometry_get(wd->scroller, NULL, &y, &w, &h);
627    elm_smart_scroller_child_region_show(wd->scroller, w / wd->display_item_num * i, y, w, h);
628    _select_item(dit);
629    if (wd->idler)
630      {
631         ecore_idler_del(wd->idler);
632         wd->idler = NULL;
633      }
634    wd->init = EINA_TRUE;
635    _check_string(wd);
636
637    return EINA_TRUE;
638 }
639
640 static void
641 _round_item_del(Widget_Data *wd, Elm_Diskselector_Item *it)
642 {
643    if (!it) return;
644    elm_box_unpack(wd->main_box, it->base.view);
645    wd->r_items = eina_list_remove(wd->r_items, it);
646    eina_stringshare_del(it->label);
647    evas_object_del(it->base.view);
648    free(it);
649 }
650
651 static void
652 _round_items_del(Widget_Data *wd)
653 {
654    Eina_List *l;
655    Elm_Diskselector_Item * it;
656
657    _round_item_del(wd, wd->last);
658    wd->last = NULL;
659    _round_item_del(wd, wd->s_last);
660    wd->s_last = NULL;
661    _round_item_del(wd, wd->second);
662    wd->second = NULL;
663    _round_item_del(wd, wd->first);
664    wd->first = NULL;
665
666    EINA_LIST_FOREACH(wd->under_items, l, it)
667      {
668         _round_item_del(wd, it);
669         it = NULL;
670      }
671
672    EINA_LIST_FOREACH(wd->over_items, l, it)
673      {
674         _round_item_del(wd, it);
675         it = NULL;
676      }
677 }
678
679 static void
680 _round_items_add(Widget_Data *wd)
681 {
682    Elm_Diskselector_Item *dit;
683    Elm_Diskselector_Item *it;
684    Elm_Diskselector_Item *temp_it;
685    int i = 0;
686    dit = it = eina_list_nth(wd->items, 0);
687    if (!dit) return;
688
689    if (!wd->first)
690      {
691         wd->first = _item_new(it->base.widget, it->icon, it->label, it->func,
692                               it->base.data);
693         wd->first->node = it->node;
694         wd->r_items = eina_list_append(wd->r_items, wd->first);
695      }
696
697    it = eina_list_nth(wd->items, 1);
698    if (!it)
699      it = dit;
700    if (!wd->second)
701      {
702         wd->second = _item_new(it->base.widget, it->icon, it->label, it->func,
703                                it->base.data);
704         wd->second->node = it->node;
705         wd->r_items = eina_list_append(wd->r_items, wd->second);
706      }
707
708    // if more than 3 itmes should be displayed
709    for (i = 2; i < CEIL(wd->display_item_num); i++)
710      {
711         it = eina_list_nth(wd->items, i);
712         if (!it) it = dit;
713         temp_it = _item_new(it->base.widget, it->icon, it->label, it->func, it->base.data);
714         wd->over_items = eina_list_append(wd->over_items, temp_it);
715         wd->r_items = eina_list_append(wd->r_items, temp_it);
716      }
717
718    it = eina_list_nth(wd->items, wd->item_count - 1);
719    if (!it)
720      it = dit;
721    if (!wd->last)
722      {
723         wd->last = _item_new(it->base.widget, it->icon, it->label, it->func,
724                              it->base.data);
725         wd->last->node = it->node;
726         wd->r_items = eina_list_prepend(wd->r_items, wd->last);
727      }
728
729    it = eina_list_nth(wd->items, wd->item_count - 2);
730    if (!it)
731      it = dit;
732    if (!wd->s_last)
733      {
734         wd->s_last = _item_new(it->base.widget, it->icon, it->label, it->func,
735                                it->base.data);
736         wd->s_last->node = it->node;
737         wd->r_items = eina_list_prepend(wd->r_items, wd->s_last);
738      }
739
740    // if more than 3 itmes should be displayed
741    for (i = 3; i <= CEIL(wd->display_item_num); i++)
742      {
743         it = eina_list_nth(wd->items, wd->item_count - i);
744         if (!it) it = dit;
745         temp_it = _item_new(it->base.widget, it->icon, it->label, it->func, it->base.data);
746         wd->under_items = eina_list_append(wd->under_items, temp_it);
747         wd->r_items = eina_list_prepend(wd->r_items, temp_it);
748      }
749 }
750
751 EAPI Evas_Object *
752 elm_diskselector_add(Evas_Object *parent)
753 {
754    Evas *e;
755    Evas_Object *obj;
756    Widget_Data *wd;
757
758    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
759
760    ELM_SET_WIDTYPE(widtype, "diskselector");
761    elm_widget_type_set(obj, "diskselector");
762    elm_widget_sub_object_add(parent, obj);
763    elm_widget_data_set(obj, wd);
764    elm_widget_del_hook_set(obj, _del_hook);
765    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
766    elm_widget_theme_hook_set(obj, _theme_hook);
767    elm_widget_can_focus_set(obj, EINA_TRUE);
768    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
769    elm_widget_event_hook_set(obj, _event_hook);
770
771    wd->self = obj;
772    wd->item_count = 0;
773    wd->round = EINA_FALSE;
774    wd->init = EINA_FALSE;
775    wd->len_side = 3;
776    wd->display_item_num_by_api = EINA_FALSE;
777
778    wd->scroller = elm_smart_scroller_add(e);
779    elm_smart_scroller_widget_set(wd->scroller, obj);
780    _theme_hook(obj);
781    elm_widget_resize_object_set(obj, wd->scroller);
782    elm_smart_scroller_policy_set(wd->scroller, ELM_SMART_SCROLLER_POLICY_OFF,
783                                  ELM_SMART_SCROLLER_POLICY_OFF);
784    elm_smart_scroller_bounce_allow_set(wd->scroller, EINA_TRUE, EINA_FALSE);
785    evas_object_smart_callback_add(wd->scroller, "scroll", _scroller_move_cb,
786                                   wd);
787    evas_object_smart_callback_add(wd->scroller, "animate,stop",
788                                   _scroller_stop_cb, wd);
789    _elm_theme_object_set(obj, wd->scroller, "diskselector", "base",
790                          "default");
791    evas_object_event_callback_add(wd->scroller, EVAS_CALLBACK_RESIZE,
792                                   _diskselector_object_resize, obj);
793
794    wd->main_box = elm_box_add(parent);
795    elm_box_horizontal_set(wd->main_box, EINA_TRUE);
796    elm_box_homogeneous_set(wd->main_box, EINA_TRUE);
797    evas_object_size_hint_weight_set(wd->main_box, EVAS_HINT_EXPAND,
798                                     EVAS_HINT_EXPAND);
799    evas_object_size_hint_align_set(wd->main_box, EVAS_HINT_FILL,
800                                    EVAS_HINT_FILL);
801    _elm_theme_object_set(obj, wd->main_box, "diskselector", "base",
802                          "default");
803    elm_widget_sub_object_add(obj, wd->main_box);
804
805    elm_smart_scroller_child_set(wd->scroller, wd->main_box);
806
807    wd->left_blank = edje_object_add(evas_object_evas_get(obj));
808    _elm_theme_object_set(obj, wd->left_blank, "diskselector", "item",
809                          "default");
810    evas_object_size_hint_weight_set(wd->left_blank, EVAS_HINT_EXPAND,
811                                     EVAS_HINT_EXPAND);
812    evas_object_size_hint_align_set(wd->left_blank, EVAS_HINT_FILL,
813                                    EVAS_HINT_FILL);
814    elm_box_pack_end(wd->main_box, wd->left_blank);
815    evas_object_show(wd->left_blank);
816
817    wd->right_blank = edje_object_add(evas_object_evas_get(obj));
818    _elm_theme_object_set(obj, wd->right_blank, "diskselector", "item",
819                          "default");
820    evas_object_size_hint_weight_set(wd->right_blank, EVAS_HINT_EXPAND,
821                                     EVAS_HINT_EXPAND);
822    evas_object_size_hint_align_set(wd->right_blank, EVAS_HINT_FILL,
823                                    EVAS_HINT_FILL);
824    elm_box_pack_end(wd->main_box, wd->right_blank);
825    evas_object_show(wd->right_blank);
826
827    _theme_data_get(wd);
828
829    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
830    evas_object_smart_callbacks_descriptions_set(obj, _signals);
831    _sizing_eval(obj);
832    return obj;
833 }
834
835 EAPI Eina_Bool
836 elm_diskselector_round_get(const Evas_Object *obj)
837 {
838    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
839    Widget_Data *wd = elm_widget_data_get(obj);
840    if (!wd) return EINA_FALSE;
841    return wd->round;
842 }
843
844 EAPI void
845 elm_diskselector_round_set(Evas_Object * obj, Eina_Bool round)
846 {
847    Eina_List *elist;
848    Elm_Diskselector_Item *it;
849
850    ELM_CHECK_WIDTYPE(obj, widtype);
851    Widget_Data *wd = elm_widget_data_get(obj);
852    if (!wd) return;
853
854    if (wd->round == round)
855      return;
856
857    wd->round = round;
858    if (round)
859      {
860         wd->r_items = eina_list_clone(wd->items);
861         elm_box_unpack(wd->main_box, wd->left_blank);
862         evas_object_hide(wd->left_blank);
863         elm_box_unpack(wd->main_box, wd->right_blank);
864         evas_object_hide(wd->right_blank);
865         if (!wd->items)
866           return;
867
868         _round_items_add(wd);
869
870         if (wd->last)
871           elm_box_pack_start(wd->main_box, wd->last->base.view);
872         if (wd->s_last)
873           elm_box_pack_start(wd->main_box, wd->s_last->base.view);
874
875         // if more than 3 items should be displayed
876         EINA_LIST_FOREACH(wd->under_items, elist, it)
877            elm_box_pack_start(wd->main_box, it->base.view);
878
879         if (wd->first)
880           elm_box_pack_end(wd->main_box, wd->first->base.view);
881         if (wd->second)
882           elm_box_pack_end(wd->main_box, wd->second->base.view);
883
884         // if more than 3 items should be displayed
885         EINA_LIST_FOREACH(wd->over_items, elist, it)
886            elm_box_pack_end(wd->main_box, it->base.view);
887      }
888    else
889      {
890         _round_items_del(wd);
891         elm_box_pack_start(wd->main_box, wd->left_blank);
892         elm_box_pack_end(wd->main_box, wd->right_blank);
893         eina_list_free(wd->r_items);
894         wd->r_items = NULL;
895      }
896
897    _selected_item_indicate(wd->selected_item);
898    _sizing_eval(obj);
899 }
900
901 EAPI int
902 elm_diskselector_side_label_length_get(const Evas_Object *obj)
903 {
904    ELM_CHECK_WIDTYPE(obj, widtype) 0;
905    Widget_Data *wd = elm_widget_data_get(obj);
906    if (!wd) return 0;
907    return wd->len_side;
908 }
909
910 EAPI void
911 elm_diskselector_side_label_length_set(Evas_Object *obj, int len)
912 {
913    ELM_CHECK_WIDTYPE(obj, widtype);
914    Widget_Data *wd = elm_widget_data_get(obj);
915    if (!wd) return;
916    wd->len_side = len;
917 }
918
919 EAPI void
920 elm_diskselector_side_label_lenght_set(Evas_Object *obj, int len)
921 {
922    return elm_diskselector_side_label_length_set(obj, len);
923 }
924
925 EAPI int
926 elm_diskselector_side_label_lenght_get(const Evas_Object *obj)
927 {
928    return elm_diskselector_side_label_length_get(obj);
929 }
930
931 EAPI void
932 elm_diskselector_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
933 {
934    ELM_CHECK_WIDTYPE(obj, widtype);
935    Widget_Data *wd = elm_widget_data_get(obj);
936    if (!wd) return;
937    if (wd->scroller)
938      elm_smart_scroller_bounce_allow_set(wd->scroller, h_bounce, v_bounce);
939 }
940
941 EAPI void
942 elm_diskselector_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
943 {
944    ELM_CHECK_WIDTYPE(obj, widtype);
945    Widget_Data *wd = elm_widget_data_get(obj);
946    if (!wd) return;
947    elm_smart_scroller_bounce_allow_get(wd->scroller, h_bounce, v_bounce);
948 }
949
950 EAPI void
951 elm_diskselector_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
952 {
953    ELM_CHECK_WIDTYPE(obj, widtype);
954    Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
955    Widget_Data *wd = elm_widget_data_get(obj);
956    if ((!wd) || (!wd->scroller)) return;
957    elm_smart_scroller_policy_get(wd->scroller, &s_policy_h, &s_policy_v);
958    *policy_h = (Elm_Scroller_Policy) s_policy_h;
959    *policy_v = (Elm_Scroller_Policy) s_policy_v;
960 }
961
962 EAPI void
963 elm_diskselector_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
964 {
965    ELM_CHECK_WIDTYPE(obj, widtype);
966    Widget_Data *wd = elm_widget_data_get(obj);
967    if (!wd) return;
968    if ((policy_h >= 3) || (policy_v >= 3)) return;
969    if (wd->scroller)
970      elm_smart_scroller_policy_set(wd->scroller, policy_h, policy_v);
971 }
972
973 EAPI void
974 elm_diskselector_clear(Evas_Object *obj)
975 {
976    ELM_CHECK_WIDTYPE(obj, widtype);
977    Widget_Data *wd = elm_widget_data_get(obj);
978    Elm_Diskselector_Item *it;
979
980    if (!wd) return;
981    if (!wd->items) return;
982
983    wd->selected_item = NULL;
984    EINA_LIST_FREE(wd->items, it) _item_del(it);
985    _round_items_del(wd);
986    _sizing_eval(obj);
987 }
988
989 EAPI const Eina_List *
990 elm_diskselector_items_get(const Evas_Object *obj)
991 {
992    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
993    Widget_Data *wd = elm_widget_data_get(obj);
994    if (!wd) return NULL;
995    return wd->items;
996 }
997
998 EAPI Elm_Diskselector_Item *
999 elm_diskselector_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
1000 {
1001    Elm_Diskselector_Item *it;
1002    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1003    Widget_Data *wd = elm_widget_data_get(obj);
1004    if (!wd) return NULL;
1005
1006    it = _item_new(obj, icon, label, func, data);
1007    wd->items = eina_list_append(wd->items, it);
1008    it->node = eina_list_last(wd->items);
1009    wd->item_count++;
1010    if (wd->round)
1011      {
1012         _round_items_del(wd);
1013         wd->r_items = eina_list_append(wd->r_items, it);
1014         _round_items_add(wd);
1015         if (wd->last)
1016           elm_box_pack_start(wd->main_box, wd->last->base.view);
1017         if (wd->s_last)
1018           elm_box_pack_start(wd->main_box, wd->s_last->base.view);
1019         elm_box_pack_end(wd->main_box, it->base.view);
1020         if (wd->first)
1021           elm_box_pack_end(wd->main_box, wd->first->base.view);
1022         if (wd->second)
1023           elm_box_pack_end(wd->main_box, wd->second->base.view);
1024      }
1025    else
1026      {
1027         elm_box_unpack(wd->main_box, wd->right_blank);
1028         elm_box_pack_end(wd->main_box, it->base.view);
1029         elm_box_pack_end(wd->main_box, wd->right_blank);
1030      }
1031    if (!wd->selected_item)
1032      wd->selected_item = it;
1033    if (!wd->idler)
1034      wd->idler = ecore_idler_add(_move_scroller, obj);
1035    _sizing_eval(obj);
1036    return it;
1037 }
1038
1039 EAPI void
1040 elm_diskselector_item_del(Elm_Diskselector_Item * it)
1041 {
1042    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1043    Elm_Diskselector_Item *dit;
1044    Elm_Diskselector_Item *item;
1045    Eina_List *l;
1046    int i = 0;
1047    Widget_Data *wd = elm_widget_data_get(it->base.widget);
1048    if (!wd) return;
1049
1050    elm_box_unpack(wd->main_box, it->base.view);
1051
1052    if (wd->round)
1053      wd->r_items = eina_list_remove(wd->r_items, it);
1054
1055    wd->items = eina_list_remove(wd->items, it);
1056
1057    if (wd->selected_item == it)
1058      {
1059         dit = (Elm_Diskselector_Item *) eina_list_nth(wd->items, 0);
1060         if (dit != it)
1061           wd->selected_item = dit;
1062         else
1063           wd->selected_item = eina_list_nth(wd->items, 1);
1064
1065         _selected_item_indicate(wd->selected_item);
1066      }
1067
1068    _item_del(it);
1069    wd->item_count -= 1;
1070
1071    if (wd->round)
1072      {
1073         if (!wd->item_count)
1074           {
1075              evas_object_hide(wd->first->base.view);
1076              evas_object_hide(wd->second->base.view);
1077              evas_object_hide(wd->last->base.view);
1078              evas_object_hide(wd->s_last->base.view);
1079
1080              EINA_LIST_FOREACH(wd->under_items, l, item)
1081                 evas_object_hide(item->base.view);
1082
1083              EINA_LIST_FOREACH(wd->over_items, l, item)
1084                 evas_object_hide(item->base.view);
1085           }
1086         else
1087           {
1088              dit = eina_list_nth(wd->items, 0);
1089              if (dit)
1090                {
1091                   eina_stringshare_replace(&wd->first->label, dit->label);
1092                   edje_object_part_text_set(wd->first->base.view, "elm.text",
1093                                             wd->first->label);
1094                }
1095              dit = eina_list_nth(wd->items, 1);
1096              if (dit)
1097                {
1098                   eina_stringshare_replace(&wd->second->label, dit->label);
1099                   edje_object_part_text_set(wd->second->base.view, "elm.text",
1100                                             wd->second->label);
1101                }
1102              // if more than 3 itmes should be displayed
1103              for (i = 2; i < CEIL(wd->display_item_num); i++)
1104                {
1105                   dit = eina_list_nth(wd->items, i);
1106                   item = eina_list_nth(wd->over_items, i - 2);
1107                   eina_stringshare_replace(&item->label, dit->label);
1108                   edje_object_part_text_set(item->base.view, "elm.text", item->label);
1109                }
1110
1111              dit = eina_list_nth(wd->items, eina_list_count(wd->items) - 1);
1112              if (dit)
1113                {
1114                   eina_stringshare_replace(&wd->last->label, dit->label);
1115                   edje_object_part_text_set(wd->last->base.view, "elm.text",
1116                                             wd->last->label);
1117                }
1118              dit = eina_list_nth(wd->items, eina_list_count(wd->items) - 2);
1119              if (dit)
1120                {
1121                   eina_stringshare_replace(&wd->s_last->label, dit->label);
1122                   edje_object_part_text_set(wd->s_last->base.view, "elm.text",
1123                                             wd->s_last->label);
1124                }
1125              // if more than 3 itmes should be displayed
1126              for (i = 3; i <= CEIL(wd->display_item_num); i++)
1127                {
1128                   dit = eina_list_nth(wd->items, wd->item_count - i);
1129                   item = eina_list_nth(wd->under_items, i - 3);
1130                   eina_stringshare_replace(&item->label, dit->label);
1131                   edje_object_part_text_set(item->base.view, "elm.text", item->label);
1132                }
1133           }
1134      }
1135    wd->check_idler = ecore_idler_add(_check_string, wd);
1136    _sizing_eval(wd->self);
1137 }
1138
1139 EAPI const char *
1140 elm_diskselector_item_label_get(const Elm_Diskselector_Item * it)
1141 {
1142    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1143    return it->label;
1144 }
1145
1146 EAPI void
1147 elm_diskselector_item_label_set(Elm_Diskselector_Item * it, const char *label)
1148 {
1149    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1150    eina_stringshare_replace(&it->label, label);
1151    edje_object_part_text_set(it->base.view, "elm.text", it->label);
1152 }
1153
1154 EAPI Elm_Diskselector_Item *
1155 elm_diskselector_selected_item_get(const Evas_Object *obj)
1156 {
1157    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1158    Widget_Data *wd = elm_widget_data_get(obj);
1159    if (!wd) return NULL;
1160    return wd->selected_item;
1161 }
1162
1163 EAPI void
1164 elm_diskselector_item_selected_set(Elm_Diskselector_Item *it, Eina_Bool selected)
1165 {
1166    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1167    Widget_Data *wd;
1168    wd = elm_widget_data_get(it->base.widget);
1169    if (!wd) return;
1170
1171    if ((wd->selected_item == it) && (selected))
1172      return;
1173
1174    if ((wd->selected_item == it) && (!selected))
1175      wd->selected_item = eina_list_data_get(wd->items);
1176    else
1177      {
1178         wd->selected_item = it;
1179         _selected_item_indicate(wd->selected_item);
1180      }
1181
1182    if (!wd->idler)
1183      ecore_idler_add(_move_scroller, it->base.widget);
1184 }
1185
1186 EAPI Eina_Bool
1187 elm_diskselector_item_selected_get(const Elm_Diskselector_Item *it)
1188 {
1189    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1190    Widget_Data *wd;
1191
1192    wd = elm_widget_data_get(it->base.widget);
1193    if (!wd) return EINA_FALSE;
1194    return (wd->selected_item == it);
1195 }
1196
1197 EAPI void
1198 elm_diskselector_item_del_cb_set(Elm_Diskselector_Item *it, Evas_Smart_Cb func)
1199 {
1200    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1201    elm_widget_item_del_cb_set(it, func);
1202 }
1203
1204 EAPI void *
1205 elm_diskselector_item_data_get(const Elm_Diskselector_Item *it)
1206 {
1207    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1208    return elm_widget_item_data_get(it);
1209 }
1210
1211 EAPI Evas_Object *
1212 elm_diskselector_item_icon_get(const Elm_Diskselector_Item *it)
1213 {
1214    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1215    return it->icon;
1216 }
1217
1218 EAPI void
1219 elm_diskselector_item_icon_set(Elm_Diskselector_Item *it, Evas_Object *icon)
1220 {
1221    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1222    if (it->icon == icon) return;
1223    if (it->icon)
1224      evas_object_del(it->icon);
1225    it->icon = icon;
1226    if (it->base.view)
1227      edje_object_part_swallow(it->base.view, "elm.swallow.icon", icon);
1228 }
1229
1230 EAPI Elm_Diskselector_Item *
1231 elm_diskselector_item_prev_get(const Elm_Diskselector_Item *it)
1232 {
1233    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1234    if (it->node->prev) return it->node->prev->data;
1235    else return NULL;
1236 }
1237
1238 EAPI Elm_Diskselector_Item *
1239 elm_diskselector_item_next_get(const Elm_Diskselector_Item *it)
1240 {
1241    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1242    if (it->node->next) return it->node->next->data;
1243    else return NULL;
1244 }
1245
1246 EAPI Elm_Diskselector_Item *
1247 elm_diskselector_first_item_get(const Evas_Object *obj)
1248 {
1249    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1250    Widget_Data *wd;
1251
1252    wd = elm_widget_data_get(obj);
1253    if (!wd || !wd->items)
1254      return NULL;
1255
1256    return eina_list_data_get(wd->items);
1257 }
1258
1259 EAPI Elm_Diskselector_Item *
1260 elm_diskselector_last_item_get(const Evas_Object *obj)
1261 {
1262    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1263
1264    Widget_Data *wd;
1265    wd = elm_widget_data_get(obj);
1266    if (!wd || !wd->items)
1267      return NULL;
1268
1269    return eina_list_data_get(eina_list_last(wd->items));
1270 }
1271
1272 EAPI void
1273 elm_diskselector_item_tooltip_text_set(Elm_Diskselector_Item *item, const char *text)
1274 {
1275    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1276    elm_widget_item_tooltip_text_set(item, text);
1277 }
1278
1279 EAPI void
1280 elm_diskselector_item_tooltip_content_cb_set(Elm_Diskselector_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
1281 {
1282    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1283    elm_widget_item_tooltip_content_cb_set(item, func, data, del_cb);
1284 }
1285
1286 EAPI void
1287 elm_diskselector_item_tooltip_unset(Elm_Diskselector_Item *item)
1288 {
1289    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1290    elm_widget_item_tooltip_unset(item);
1291 }
1292
1293 EAPI void
1294 elm_diskselector_item_tooltip_style_set(Elm_Diskselector_Item *item, const char *style)
1295 {
1296    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1297    elm_widget_item_tooltip_style_set(item, style);
1298 }
1299
1300 EAPI const char *
1301 elm_diskselector_item_tooltip_style_get(const Elm_Diskselector_Item *item)
1302 {
1303    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, NULL);
1304    return elm_widget_item_tooltip_style_get(item);
1305 }
1306
1307 EAPI void
1308 elm_diskselector_item_cursor_set(Elm_Diskselector_Item *item, const char *cursor)
1309 {
1310    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1311    elm_widget_item_cursor_set(item, cursor);
1312 }
1313
1314 EAPI const char *
1315 elm_diskselector_item_cursor_get(const Elm_Diskselector_Item *item)
1316 {
1317    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, NULL);
1318    return elm_widget_item_cursor_get(item);
1319 }
1320
1321 EAPI void
1322 elm_diskselector_item_cursor_unset(Elm_Diskselector_Item *item)
1323 {
1324    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1325    elm_widget_item_cursor_unset(item);
1326 }
1327
1328 EAPI void
1329 elm_diskselector_item_cursor_style_set(Elm_Diskselector_Item *item, const char *style)
1330 {
1331    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1332    elm_widget_item_cursor_style_set(item, style);
1333 }
1334
1335 EAPI const char *
1336 elm_diskselector_item_cursor_style_get(const Elm_Diskselector_Item *item)
1337 {
1338    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, NULL);
1339    return elm_widget_item_cursor_style_get(item);
1340 }
1341
1342 EAPI void
1343 elm_diskselector_item_cursor_engine_only_set(Elm_Diskselector_Item *item, Eina_Bool engine_only)
1344 {
1345    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1346    elm_widget_item_cursor_engine_only_set(item, engine_only);
1347 }
1348
1349 EAPI Eina_Bool
1350 elm_diskselector_item_cursor_engine_only_get(const Elm_Diskselector_Item *item)
1351 {
1352    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
1353    return elm_widget_item_cursor_engine_only_get(item);
1354 }
1355
1356 EAPI void
1357 elm_diskselector_display_item_num_set(Evas_Object *obj, int num)
1358 {
1359    ELM_CHECK_WIDTYPE(obj, widtype);
1360    Widget_Data *wd = elm_widget_data_get(obj);
1361    if (!wd) return;
1362    if (num < DISPLAY_ITEM_NUM_MIN) num = DISPLAY_ITEM_NUM_MIN;
1363    wd->display_item_num = num;
1364    wd->display_item_num_by_api = EINA_TRUE;
1365 }