elm diskselector: Fixed elm_diskselector_item_selected_set() hanging bug. Patch by...
[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              evas_object_del(it->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            evas_object_del(it->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) || (!wd->scroller)) return;
968    if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
969        (policy_v >= ELM_SCROLLER_POLICY_LAST))
970      return;
971    elm_smart_scroller_policy_set(wd->scroller, policy_h, policy_v);
972 }
973
974 EAPI void
975 elm_diskselector_clear(Evas_Object *obj)
976 {
977    ELM_CHECK_WIDTYPE(obj, widtype);
978    Widget_Data *wd = elm_widget_data_get(obj);
979    Elm_Diskselector_Item *it;
980
981    if (!wd) return;
982    if (!wd->items) return;
983
984    wd->selected_item = NULL;
985    EINA_LIST_FREE(wd->items, it) _item_del(it);
986    _round_items_del(wd);
987    _sizing_eval(obj);
988 }
989
990 EAPI const Eina_List *
991 elm_diskselector_items_get(const Evas_Object *obj)
992 {
993    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
994    Widget_Data *wd = elm_widget_data_get(obj);
995    if (!wd) return NULL;
996    return wd->items;
997 }
998
999 EAPI Elm_Diskselector_Item *
1000 elm_diskselector_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
1001 {
1002    Elm_Diskselector_Item *it;
1003    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1004    Widget_Data *wd = elm_widget_data_get(obj);
1005    if (!wd) return NULL;
1006
1007    it = _item_new(obj, icon, label, func, data);
1008    wd->items = eina_list_append(wd->items, it);
1009    it->node = eina_list_last(wd->items);
1010    wd->item_count++;
1011    if (wd->round)
1012      {
1013         _round_items_del(wd);
1014         wd->r_items = eina_list_append(wd->r_items, it);
1015         _round_items_add(wd);
1016         if (wd->last)
1017           elm_box_pack_start(wd->main_box, wd->last->base.view);
1018         if (wd->s_last)
1019           elm_box_pack_start(wd->main_box, wd->s_last->base.view);
1020         elm_box_pack_end(wd->main_box, it->base.view);
1021         if (wd->first)
1022           elm_box_pack_end(wd->main_box, wd->first->base.view);
1023         if (wd->second)
1024           elm_box_pack_end(wd->main_box, wd->second->base.view);
1025      }
1026    else
1027      {
1028         elm_box_unpack(wd->main_box, wd->right_blank);
1029         elm_box_pack_end(wd->main_box, it->base.view);
1030         elm_box_pack_end(wd->main_box, wd->right_blank);
1031      }
1032    if (!wd->selected_item)
1033      wd->selected_item = it;
1034    if (!wd->idler)
1035      wd->idler = ecore_idler_add(_move_scroller, obj);
1036    _sizing_eval(obj);
1037    return it;
1038 }
1039
1040 EAPI void
1041 elm_diskselector_item_del(Elm_Diskselector_Item * it)
1042 {
1043    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1044    Elm_Diskselector_Item *dit;
1045    Elm_Diskselector_Item *item;
1046    Eina_List *l;
1047    int i = 0;
1048    Widget_Data *wd = elm_widget_data_get(it->base.widget);
1049    if (!wd) return;
1050
1051    elm_box_unpack(wd->main_box, it->base.view);
1052
1053    if (wd->round)
1054      wd->r_items = eina_list_remove(wd->r_items, it);
1055
1056    wd->items = eina_list_remove(wd->items, it);
1057
1058    if (wd->selected_item == it)
1059      {
1060         dit = (Elm_Diskselector_Item *) eina_list_nth(wd->items, 0);
1061         if (dit != it)
1062           wd->selected_item = dit;
1063         else
1064           wd->selected_item = eina_list_nth(wd->items, 1);
1065
1066         _selected_item_indicate(wd->selected_item);
1067      }
1068
1069    _item_del(it);
1070    wd->item_count -= 1;
1071
1072    if (wd->round)
1073      {
1074         if (!wd->item_count)
1075           {
1076              evas_object_hide(wd->first->base.view);
1077              evas_object_hide(wd->second->base.view);
1078              evas_object_hide(wd->last->base.view);
1079              evas_object_hide(wd->s_last->base.view);
1080
1081              EINA_LIST_FOREACH(wd->under_items, l, item)
1082                 evas_object_hide(item->base.view);
1083
1084              EINA_LIST_FOREACH(wd->over_items, l, item)
1085                 evas_object_hide(item->base.view);
1086           }
1087         else
1088           {
1089              dit = eina_list_nth(wd->items, 0);
1090              if (dit)
1091                {
1092                   eina_stringshare_replace(&wd->first->label, dit->label);
1093                   edje_object_part_text_set(wd->first->base.view, "elm.text",
1094                                             wd->first->label);
1095                }
1096              dit = eina_list_nth(wd->items, 1);
1097              if (dit)
1098                {
1099                   eina_stringshare_replace(&wd->second->label, dit->label);
1100                   edje_object_part_text_set(wd->second->base.view, "elm.text",
1101                                             wd->second->label);
1102                }
1103              // if more than 3 itmes should be displayed
1104              for (i = 2; i < CEIL(wd->display_item_num); i++)
1105                {
1106                   dit = eina_list_nth(wd->items, i);
1107                   item = eina_list_nth(wd->over_items, i - 2);
1108                   eina_stringshare_replace(&item->label, dit->label);
1109                   edje_object_part_text_set(item->base.view, "elm.text", item->label);
1110                }
1111
1112              dit = eina_list_nth(wd->items, eina_list_count(wd->items) - 1);
1113              if (dit)
1114                {
1115                   eina_stringshare_replace(&wd->last->label, dit->label);
1116                   edje_object_part_text_set(wd->last->base.view, "elm.text",
1117                                             wd->last->label);
1118                }
1119              dit = eina_list_nth(wd->items, eina_list_count(wd->items) - 2);
1120              if (dit)
1121                {
1122                   eina_stringshare_replace(&wd->s_last->label, dit->label);
1123                   edje_object_part_text_set(wd->s_last->base.view, "elm.text",
1124                                             wd->s_last->label);
1125                }
1126              // if more than 3 itmes should be displayed
1127              for (i = 3; i <= CEIL(wd->display_item_num); i++)
1128                {
1129                   dit = eina_list_nth(wd->items, wd->item_count - i);
1130                   item = eina_list_nth(wd->under_items, i - 3);
1131                   eina_stringshare_replace(&item->label, dit->label);
1132                   edje_object_part_text_set(item->base.view, "elm.text", item->label);
1133                }
1134           }
1135      }
1136    wd->check_idler = ecore_idler_add(_check_string, wd);
1137    _sizing_eval(wd->self);
1138 }
1139
1140 EAPI const char *
1141 elm_diskselector_item_label_get(const Elm_Diskselector_Item * it)
1142 {
1143    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1144    return it->label;
1145 }
1146
1147 EAPI void
1148 elm_diskselector_item_label_set(Elm_Diskselector_Item * it, const char *label)
1149 {
1150    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1151    eina_stringshare_replace(&it->label, label);
1152    edje_object_part_text_set(it->base.view, "elm.text", it->label);
1153 }
1154
1155 EAPI Elm_Diskselector_Item *
1156 elm_diskselector_selected_item_get(const Evas_Object *obj)
1157 {
1158    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1159    Widget_Data *wd = elm_widget_data_get(obj);
1160    if (!wd) return NULL;
1161    return wd->selected_item;
1162 }
1163
1164 EAPI void
1165 elm_diskselector_item_selected_set(Elm_Diskselector_Item *it, Eina_Bool selected)
1166 {
1167    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1168    Widget_Data *wd;
1169    wd = elm_widget_data_get(it->base.widget);
1170    if (!wd) return;
1171
1172    if ((wd->selected_item == it) && (selected))
1173      return;
1174
1175    if ((wd->selected_item == it) && (!selected))
1176      wd->selected_item = eina_list_data_get(wd->items);
1177    else
1178      {
1179         wd->selected_item = it;
1180         _selected_item_indicate(wd->selected_item);
1181      }
1182
1183    if (!wd->idler)
1184      wd->idler = ecore_idler_add(_move_scroller, it->base.widget);
1185 }
1186
1187 EAPI Eina_Bool
1188 elm_diskselector_item_selected_get(const Elm_Diskselector_Item *it)
1189 {
1190    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1191    Widget_Data *wd;
1192
1193    wd = elm_widget_data_get(it->base.widget);
1194    if (!wd) return EINA_FALSE;
1195    return (wd->selected_item == it);
1196 }
1197
1198 EAPI void
1199 elm_diskselector_item_del_cb_set(Elm_Diskselector_Item *it, Evas_Smart_Cb func)
1200 {
1201    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1202    elm_widget_item_del_cb_set(it, func);
1203 }
1204
1205 EAPI void *
1206 elm_diskselector_item_data_get(const Elm_Diskselector_Item *it)
1207 {
1208    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1209    return elm_widget_item_data_get(it);
1210 }
1211
1212 EAPI Evas_Object *
1213 elm_diskselector_item_icon_get(const Elm_Diskselector_Item *it)
1214 {
1215    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1216    return it->icon;
1217 }
1218
1219 EAPI void
1220 elm_diskselector_item_icon_set(Elm_Diskselector_Item *it, Evas_Object *icon)
1221 {
1222    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it);
1223    if (it->icon == icon) return;
1224    if (it->icon)
1225      evas_object_del(it->icon);
1226    it->icon = icon;
1227    if (it->base.view)
1228      edje_object_part_swallow(it->base.view, "elm.swallow.icon", icon);
1229 }
1230
1231 EAPI Elm_Diskselector_Item *
1232 elm_diskselector_item_prev_get(const Elm_Diskselector_Item *it)
1233 {
1234    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1235    if (it->node->prev) return it->node->prev->data;
1236    else return NULL;
1237 }
1238
1239 EAPI Elm_Diskselector_Item *
1240 elm_diskselector_item_next_get(const Elm_Diskselector_Item *it)
1241 {
1242    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1243    if (it->node->next) return it->node->next->data;
1244    else return NULL;
1245 }
1246
1247 EAPI Elm_Diskselector_Item *
1248 elm_diskselector_first_item_get(const Evas_Object *obj)
1249 {
1250    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1251    Widget_Data *wd;
1252
1253    wd = elm_widget_data_get(obj);
1254    if (!wd || !wd->items)
1255      return NULL;
1256
1257    return eina_list_data_get(wd->items);
1258 }
1259
1260 EAPI Elm_Diskselector_Item *
1261 elm_diskselector_last_item_get(const Evas_Object *obj)
1262 {
1263    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1264
1265    Widget_Data *wd;
1266    wd = elm_widget_data_get(obj);
1267    if (!wd || !wd->items)
1268      return NULL;
1269
1270    return eina_list_data_get(eina_list_last(wd->items));
1271 }
1272
1273 EAPI void
1274 elm_diskselector_item_tooltip_text_set(Elm_Diskselector_Item *item, const char *text)
1275 {
1276    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1277    elm_widget_item_tooltip_text_set(item, text);
1278 }
1279
1280 EAPI void
1281 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)
1282 {
1283    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1284    elm_widget_item_tooltip_content_cb_set(item, func, data, del_cb);
1285 }
1286
1287 EAPI void
1288 elm_diskselector_item_tooltip_unset(Elm_Diskselector_Item *item)
1289 {
1290    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1291    elm_widget_item_tooltip_unset(item);
1292 }
1293
1294 EAPI void
1295 elm_diskselector_item_tooltip_style_set(Elm_Diskselector_Item *item, const char *style)
1296 {
1297    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1298    elm_widget_item_tooltip_style_set(item, style);
1299 }
1300
1301 EAPI const char *
1302 elm_diskselector_item_tooltip_style_get(const Elm_Diskselector_Item *item)
1303 {
1304    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, NULL);
1305    return elm_widget_item_tooltip_style_get(item);
1306 }
1307
1308 EAPI void
1309 elm_diskselector_item_cursor_set(Elm_Diskselector_Item *item, const char *cursor)
1310 {
1311    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1312    elm_widget_item_cursor_set(item, cursor);
1313 }
1314
1315 EAPI const char *
1316 elm_diskselector_item_cursor_get(const Elm_Diskselector_Item *item)
1317 {
1318    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, NULL);
1319    return elm_widget_item_cursor_get(item);
1320 }
1321
1322 EAPI void
1323 elm_diskselector_item_cursor_unset(Elm_Diskselector_Item *item)
1324 {
1325    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1326    elm_widget_item_cursor_unset(item);
1327 }
1328
1329 EAPI void
1330 elm_diskselector_item_cursor_style_set(Elm_Diskselector_Item *item, const char *style)
1331 {
1332    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1333    elm_widget_item_cursor_style_set(item, style);
1334 }
1335
1336 EAPI const char *
1337 elm_diskselector_item_cursor_style_get(const Elm_Diskselector_Item *item)
1338 {
1339    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, NULL);
1340    return elm_widget_item_cursor_style_get(item);
1341 }
1342
1343 EAPI void
1344 elm_diskselector_item_cursor_engine_only_set(Elm_Diskselector_Item *item, Eina_Bool engine_only)
1345 {
1346    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item);
1347    elm_widget_item_cursor_engine_only_set(item, engine_only);
1348 }
1349
1350 EAPI Eina_Bool
1351 elm_diskselector_item_cursor_engine_only_get(const Elm_Diskselector_Item *item)
1352 {
1353    ELM_DISKSELECTOR_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
1354    return elm_widget_item_cursor_engine_only_get(item);
1355 }
1356
1357 EAPI void
1358 elm_diskselector_display_item_num_set(Evas_Object *obj, int num)
1359 {
1360    ELM_CHECK_WIDTYPE(obj, widtype);
1361    Widget_Data *wd = elm_widget_data_get(obj);
1362    if (!wd) return;
1363    if (num < DISPLAY_ITEM_NUM_MIN) num = DISPLAY_ITEM_NUM_MIN;
1364    wd->display_item_num = num;
1365    wd->display_item_num_by_api = EINA_TRUE;
1366 }
1367
1368 EAPI int
1369 elm_diskselector_display_item_num_get(const Evas_Object *item)
1370 {
1371    ELM_CHECK_WIDTYPE(item, widtype) (-1);
1372    Widget_Data *wd = elm_widget_data_get(item);
1373    if (!wd) return -1;
1374    return wd->display_item_num;
1375 }