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