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