elementary/map - map supports language,changed
[framework/uifw/elementary.git] / src / lib / elm_segment_control.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_segment_control.h"
4
5 EAPI const char ELM_SEGMENT_CONTROL_SMART_NAME[] = "elm_segment_control";
6
7 static const char SIG_CHANGED[] = "changed";
8 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
9    {SIG_CHANGED, ""},
10    {NULL, NULL}
11 };
12
13 EVAS_SMART_SUBCLASS_NEW
14   (ELM_SEGMENT_CONTROL_SMART_NAME, _elm_segment_control,
15   Elm_Segment_Control_Smart_Class, Elm_Layout_Smart_Class,
16   elm_layout_smart_class_get, _smart_callbacks);
17
18 static void
19 _elm_segment_control_smart_sizing_eval(Evas_Object *obj)
20 {
21    Evas_Coord minw = -1, minh = -1;
22    Evas_Coord w, h;
23    int item_count;
24
25    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
26
27    item_count = eina_list_count(sd->items);
28
29    elm_coords_finger_size_adjust(item_count, &minw, 1, &minh);
30    edje_object_size_min_restricted_calc
31      (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
32    elm_coords_finger_size_adjust(item_count, &minw, 1, &minh);
33
34    evas_object_size_hint_min_get(obj, &w, &h);
35
36    if (w > minw) minw = w;
37    if (h > minh) minh = h;
38
39    evas_object_size_hint_min_set(obj, minw, minh);
40 }
41
42 static void
43 _item_free(Elm_Segment_Item *it)
44 {
45    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
46
47    if (sd->selected_item == it) sd->selected_item = NULL;
48    if (sd->items) sd->items = eina_list_remove(sd->items, it);
49
50    if (it->icon) evas_object_del(it->icon);
51    if (it->label) eina_stringshare_del(it->label);
52 }
53
54 static void
55 _position_items(Elm_Segment_Control_Smart_Data *sd)
56 {
57    Eina_List *l;
58    Eina_Bool rtl;
59    int item_count;
60    Elm_Segment_Item *it;
61    int bx, by, bw, bh, pos;
62
63    item_count = eina_list_count(sd->items);
64    if (item_count <= 0) return;
65
66    evas_object_geometry_get
67      (ELM_WIDGET_DATA(sd)->resize_obj, &bx, &by, &bw, &bh);
68    sd->item_width = bw / item_count;
69    rtl = elm_widget_mirrored_get(ELM_WIDGET_DATA(sd)->obj);
70
71    if (rtl) pos = bx + bw - sd->item_width;
72    else pos = bx;
73
74    EINA_LIST_FOREACH(sd->items, l, it)
75      {
76         evas_object_move(VIEW(it), pos, by);
77         evas_object_resize(VIEW(it), sd->item_width, bh);
78         if (rtl) pos -= sd->item_width;
79         else pos += sd->item_width;
80      }
81
82    elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj);
83 }
84
85 static void
86 _swallow_item_objects(Elm_Segment_Item *it)
87 {
88    if (!it) return;
89
90    if (it->icon)
91      {
92         edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon);
93         edje_object_signal_emit(VIEW(it), "elm,state,icon,visible", "elm");
94      }
95    else edje_object_signal_emit(VIEW(it), "elm,state,icon,hidden", "elm");
96
97    if (it->label)
98      {
99         edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label);
100         edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm");
101      }
102    else
103      edje_object_signal_emit(VIEW(it), "elm,state,text,hidden", "elm");
104
105    edje_object_message_signal_process(VIEW(it));
106 }
107
108 static void
109 _update_list(Elm_Segment_Control_Smart_Data *sd)
110 {
111    int idx = 0;
112    Eina_List *l;
113    Eina_Bool rtl;
114    int item_count;
115    Elm_Segment_Item *it;
116
117    _position_items(sd);
118
119    item_count = eina_list_count(sd->items);
120
121    if (item_count == 1)
122      {
123         it = eina_list_nth(sd->items, 0);
124         it->seg_index = 0;
125
126         //Set the segment type
127         edje_object_signal_emit(VIEW(it), "elm,type,segment,single", "elm");
128
129         //Set the segment state
130         if (sd->selected_item == it)
131           edje_object_signal_emit
132             (VIEW(it), "elm,state,segment,selected", "elm");
133         else
134           edje_object_signal_emit(VIEW(it), "elm,state,segment,normal", "elm");
135
136         if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj))
137           edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
138         else
139           edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
140
141         _swallow_item_objects(it);
142         return;
143      }
144
145    rtl = elm_widget_mirrored_get(ELM_WIDGET_DATA(sd)->obj);
146    EINA_LIST_FOREACH(sd->items, l, it)
147      {
148         it->seg_index = idx;
149
150         //Set the segment type
151         if (idx == 0)
152           {
153              if (rtl)
154                edje_object_signal_emit
155                  (VIEW(it), "elm,type,segment,right", "elm");
156              else
157                edje_object_signal_emit
158                  (VIEW(it), "elm,type,segment,left", "elm");
159           }
160         else if (idx == (item_count - 1))
161           {
162              if (rtl)
163                edje_object_signal_emit
164                  (VIEW(it), "elm,type,segment,left", "elm");
165              else
166                edje_object_signal_emit
167                  (VIEW(it), "elm,type,segment,right", "elm");
168           }
169         else
170           edje_object_signal_emit(VIEW(it), "elm,type,segment,middle", "elm");
171
172         //Set the segment state
173         if (sd->selected_item == it)
174           edje_object_signal_emit
175             (VIEW(it), "elm,state,segment,selected", "elm");
176         else
177           edje_object_signal_emit(VIEW(it), "elm,state,segment,normal", "elm");
178
179         if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj))
180           edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
181         else
182           edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
183
184         _swallow_item_objects(it);
185         idx++;
186      }
187 }
188
189 static Eina_Bool
190 _elm_segment_control_smart_theme(Evas_Object *obj)
191 {
192    Eina_List *l;
193    Eina_Bool rtl;
194    Elm_Segment_Item *it;
195
196    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
197
198    if (!ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->theme(obj))
199      return EINA_FALSE;
200
201    rtl = elm_widget_mirrored_get(obj);
202
203    EINA_LIST_FOREACH(sd->items, l, it)
204      {
205         elm_widget_theme_object_set
206           (obj, VIEW(it), "segment_control", "item",
207           elm_widget_style_get(obj));
208         edje_object_scale_set(VIEW(it), elm_widget_scale_get(VIEW(it)) *
209                               elm_config_scale_get());
210         edje_object_mirrored_set(VIEW(it), rtl);
211      }
212
213    _update_list(sd);
214
215    return EINA_TRUE;
216 }
217
218 static Eina_Bool
219 _elm_segment_control_smart_disable(Evas_Object *obj)
220 {
221    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
222
223    if (!ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->disable(obj))
224      return EINA_FALSE;
225
226    _update_list(sd);
227
228    return EINA_TRUE;
229 }
230
231 // TODO: elm_widget_focus_list_next_get supports only Elm_widget list,
232 // not the Elm_Widget_item. Focus switching within widget not
233 // supported until it is supported in elm_widget
234 #if 0
235 static void *
236 _elm_list_data_get(const Eina_List *list)
237 {
238    Elm_Segment_Item *it = eina_list_data_get(list);
239
240    if (it) return NULL;
241
242    edje_object_signal_emit(VIEW(it), "elm,state,segment,selected", "elm");
243
244    return VIEW(it);
245 }
246
247 static Eina_Bool
248 _elm_segment_control_smart_focus_next(const Evas_Object *obj,
249                                       Elm_Focus_Direction dir,
250                                       Evas_Object **next)
251 {
252    static int count = 0;
253    const Eina_List *items;
254    void *(*list_data_get)(const Eina_List *list);
255
256    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
257
258    /* Focus chain */
259    if ((items = elm_widget_focus_custom_chain_get(obj)))
260      list_data_get = eina_list_data_get;
261    else
262      {
263         items = sd->items;
264         list_data_get = _elm_list_data_get;
265         if (!items) return EINA_FALSE;
266      }
267
268    return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
269 }
270
271 #endif
272
273 static void
274 _segment_off(Elm_Segment_Item *it)
275 {
276    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
277
278    edje_object_signal_emit(VIEW(it), "elm,state,segment,normal", "elm");
279
280    if (sd->selected_item == it) sd->selected_item = NULL;
281 }
282
283 static void
284 _segment_on(Elm_Segment_Item *it)
285 {
286    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
287
288    if (it == sd->selected_item) return;
289
290    if (sd->selected_item) _segment_off(sd->selected_item);
291
292    edje_object_signal_emit(VIEW(it), "elm,state,segment,selected", "elm");
293
294    sd->selected_item = it;
295    evas_object_smart_callback_call(ELM_WIDGET_DATA(sd)->obj, SIG_CHANGED, it);
296 }
297
298 static void
299 _on_move_resize(void *data, Evas *e __UNUSED__,
300                 Evas_Object *obj __UNUSED__,
301                 void *event_info __UNUSED__)
302 {
303    ELM_SEGMENT_CONTROL_DATA_GET(data, sd);
304
305    _position_items(sd);
306 }
307
308 static void
309 _on_mouse_up(void *data,
310              Evas *e __UNUSED__,
311              Evas_Object *obj __UNUSED__,
312              void *event_info)
313 {
314    Elm_Segment_Item *it;
315    Evas_Event_Mouse_Up *ev;
316    Evas_Coord x, y, w, h;
317
318    it = data;
319    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
320
321    if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj)) return;
322
323    if (it == sd->selected_item) return;
324
325    ev = event_info;
326    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
327
328    if ((ev->canvas.x >= x) && (ev->output.x <= (x + w)) && (ev->canvas.y >= y)
329        && (ev->canvas.y <= (y + h)))
330      _segment_on(it);
331    else
332      edje_object_signal_emit(VIEW(it), "elm,state,segment,normal", "elm");
333 }
334
335 static void
336 _on_mouse_down(void *data,
337                Evas *e __UNUSED__,
338                Evas_Object *obj __UNUSED__,
339                void *event_info __UNUSED__)
340 {
341    Elm_Segment_Item *it;
342
343    it = data;
344    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
345
346    if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj)) return;
347
348    if (it == sd->selected_item) return;
349
350    edje_object_signal_emit(VIEW(it), "elm,state,segment,pressed", "elm");
351 }
352
353 static Elm_Segment_Item *
354 _item_find(const Evas_Object *obj,
355            int idx)
356 {
357    Elm_Segment_Item *it;
358
359    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
360
361    it = eina_list_nth(sd->items, idx);
362    return it;
363 }
364
365 static void
366 _item_text_set_hook(Elm_Object_Item *it,
367                     const char *part,
368                     const char *label)
369 {
370    Elm_Segment_Item *item;
371    char buf[1024];
372    item = (Elm_Segment_Item *)it;
373
374    if ((!part) || (!strcmp(part, "default")) ||
375        (!strcmp(part, "elm.text")))
376      {
377         eina_stringshare_replace(&item->label, label);
378         if (label)
379           edje_object_signal_emit(VIEW(item), "elm,state,text,visible", "elm");
380         else
381           edje_object_signal_emit(VIEW(item), "elm,state,text,hidden", "elm");
382      }
383    else
384      {
385         if (label)
386           {
387              snprintf(buf, sizeof(buf), "elm,state,%s,visible", part);
388              edje_object_signal_emit(VIEW(item), buf, "elm");
389           }
390         else
391           {
392              snprintf(buf, sizeof(buf), "elm,state,%s,hidden", part);
393              edje_object_signal_emit(VIEW(item), buf, "elm");
394           }
395      }
396
397    edje_object_message_signal_process(VIEW(item));
398    //label can be NULL also.
399    edje_object_part_text_escaped_set(VIEW(item), part, label);
400 }
401
402 static const char *
403 _item_text_get_hook(const Elm_Object_Item *it,
404                     const char *part)
405 {
406    char buf[1024];
407
408    if (!part || !strcmp(part, "default"))
409      snprintf(buf, sizeof(buf), "elm.text");
410    else
411      snprintf(buf, sizeof(buf), "%s", part);
412
413    return edje_object_part_text_get(VIEW(it), buf);
414 }
415
416 static void
417 _item_content_set_hook(Elm_Object_Item *it,
418                        const char *part,
419                        Evas_Object *content)
420 {
421    Elm_Segment_Item *item;
422    char buf[1024];
423    item = (Elm_Segment_Item *)it;
424
425    if (!part || !strcmp("icon", part))
426      {
427         if (content == item->icon) return;
428
429         if (item->icon) evas_object_del(item->icon);
430         item->icon = content;
431         if (!item->icon)
432           {
433              elm_widget_sub_object_add(VIEW(item), item->icon);
434              edje_object_part_swallow(VIEW(item), "elm.swallow.icon", item->icon);
435              edje_object_signal_emit(VIEW(item), "elm,state,icon,visible", "elm");
436           }
437         else
438           edje_object_signal_emit(VIEW(item), "elm,state,icon,hidden", "elm");
439      }
440    else
441      {
442         if (content)
443           {
444              edje_object_part_swallow(VIEW(it), part, content);
445              snprintf(buf, sizeof(buf), "elm,state,%s,visible", part);
446              edje_object_signal_emit(VIEW(item), buf, "elm");
447           }
448         else
449           {
450              snprintf(buf, sizeof(buf), "elm,state,%s,hidden", part);
451              edje_object_signal_emit(VIEW(item), buf, "elm");
452           }
453      }
454 }
455
456 static Evas_Object *
457 _item_content_get_hook(const Elm_Object_Item *it,
458                        const char *part)
459 {
460    Elm_Segment_Item *item;
461    item = (Elm_Segment_Item *)it;
462
463    if (part && !strcmp(part, "icon"))
464      return item->icon;
465    else
466      return edje_object_part_swallow_get(VIEW(item), part);
467 }
468
469 static Eina_Bool
470 _item_del_pre_hook(Elm_Object_Item *it)
471 {
472    Elm_Segment_Item *item = (Elm_Segment_Item *)it;
473    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
474
475    _item_free(item);
476    _update_list(sd);
477
478    return EINA_TRUE;
479 }
480
481 static char *
482 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
483 {
484    const char *txt = NULL;
485    Elm_Segment_Item *it = (Elm_Segment_Item *)data;
486    ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, NULL);
487
488    if (!txt) txt = it->label;
489    if (txt) return strdup(txt);
490
491    return NULL;
492 }
493
494 static char *
495 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
496 {
497    Elm_Segment_Item *it = (Elm_Segment_Item *)data;
498    ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, NULL);
499    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
500
501    if (ELM_WIDGET_DATA(sd)->disabled)
502      return strdup(E_("State: Disabled"));
503
504    if (it == sd->selected_item)
505      return strdup(E_("State: Selected"));
506    else
507      return strdup(E_("State: Unselected"));
508 }
509
510 static void
511 _access_widget_item_register(Elm_Segment_Item *it)
512 {
513    Elm_Access_Info *ai;
514
515    _elm_access_widget_item_register((Elm_Widget_Item *)it);
516
517    ai = _elm_access_object_get(it->base.access_obj);
518
519    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Segment Control Item"));
520    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
521    _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
522 }
523
524 static Elm_Segment_Item *
525 _item_new(Evas_Object *obj,
526           Evas_Object *icon,
527           const char *label)
528 {
529    Elm_Segment_Item *it;
530
531    it = elm_widget_item_new(obj, Elm_Segment_Item);
532    if (!it) return NULL;
533
534    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
535    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
536    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
537    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
538    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
539
540    VIEW(it) = edje_object_add(evas_object_evas_get(obj));
541    edje_object_scale_set
542      (VIEW(it), elm_widget_scale_get(VIEW(it)) * elm_config_scale_get());
543    evas_object_smart_member_add(VIEW(it), obj);
544
545    elm_widget_sub_object_add(obj, VIEW(it));
546    elm_widget_theme_object_set
547      (obj, VIEW(it), "segment_control", "item", elm_object_style_get(obj));
548    edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(WIDGET(it)));
549
550    if (label) eina_stringshare_replace(&it->label, label);
551    if (it->label)
552      edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm");
553    else
554      edje_object_signal_emit(VIEW(it), "elm,state,text,hidden", "elm");
555    edje_object_message_signal_process(VIEW(it));
556    edje_object_part_text_escaped_set(VIEW(it), "elm.text", label);
557
558    it->icon = icon;
559    if (it->icon) elm_widget_sub_object_add(VIEW(it), it->icon);
560    evas_object_event_callback_add
561      (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, it);
562    evas_object_event_callback_add
563      (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _on_mouse_up, it);
564    evas_object_show(VIEW(it));
565
566    // ACCESS
567    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
568      _access_widget_item_register(it);
569
570    return it;
571 }
572
573 static void
574 _elm_segment_control_smart_add(Evas_Object *obj)
575 {
576    EVAS_SMART_DATA_ALLOC(obj, Elm_Segment_Control_Smart_Data);
577
578    ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->base.add(obj);
579
580    elm_layout_theme_set
581      (obj, "segment_control", "base", elm_widget_style_get(obj));
582
583    evas_object_event_callback_add
584      (obj, EVAS_CALLBACK_RESIZE, _on_move_resize, obj);
585    evas_object_event_callback_add
586      (obj, EVAS_CALLBACK_MOVE, _on_move_resize, obj);
587
588    elm_layout_sizing_eval(obj);
589 }
590
591 static void
592 _elm_segment_control_smart_del(Evas_Object *obj)
593 {
594    Elm_Segment_Item *it;
595
596    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
597
598    EINA_LIST_FREE (sd->items, it)
599      {
600         _item_free(it);
601         elm_widget_item_free(it);
602      }
603
604    ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->base.del(obj);
605 }
606
607 static Eina_Bool
608 _elm_segment_control_smart_focus_next(const Evas_Object *obj,
609                            Elm_Focus_Direction dir,
610                            Evas_Object **next)
611 {
612    Eina_List *items = NULL;
613    Eina_List *l;
614    Elm_Segment_Item *it;
615
616    ELM_SEGMENT_CONTROL_CHECK(obj) EINA_FALSE;
617    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
618
619    EINA_LIST_FOREACH(sd->items, l, it)
620      items = eina_list_append(items, it->base.access_obj);
621
622    return elm_widget_focus_list_next_get
623             (obj, items, eina_list_data_get, dir, next);
624 }
625
626 static void
627 _access_obj_process(Elm_Segment_Control_Smart_Data * sd, Eina_Bool is_access)
628 {
629    Eina_List *l;
630    Elm_Segment_Item *it;
631
632    EINA_LIST_FOREACH(sd->items, l, it)
633      {
634         if (is_access) _access_widget_item_register(it);
635         else
636           _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
637      }
638 }
639
640 static void
641 _access_hook(Evas_Object *obj, Eina_Bool is_access)
642 {
643    ELM_SEGMENT_CONTROL_CHECK(obj);
644    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
645    
646    if (is_access)
647      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
648      _elm_segment_control_smart_focus_next;
649    else
650      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
651    _access_obj_process(sd, is_access);
652 }
653
654 static void
655 _elm_segment_control_smart_set_user(Elm_Segment_Control_Smart_Class *sc)
656 {
657    ELM_WIDGET_CLASS(sc)->base.add = _elm_segment_control_smart_add;
658    ELM_WIDGET_CLASS(sc)->base.del = _elm_segment_control_smart_del;
659
660    ELM_WIDGET_CLASS(sc)->theme = _elm_segment_control_smart_theme;
661    ELM_WIDGET_CLASS(sc)->disable = _elm_segment_control_smart_disable;
662
663 #if 0
664    ELM_WIDGET_CLASS(sc)->focus_next = _elm_segment_control_smart_focus_next;
665 #else
666    ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
667 #endif
668
669    ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
670
671    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_segment_control_smart_sizing_eval;
672
673    // ACCESS
674    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
675      ELM_WIDGET_CLASS(sc)->focus_next = _elm_segment_control_smart_focus_next;
676
677    ELM_WIDGET_CLASS(sc)->access = _access_hook;
678 }
679
680 EAPI const Elm_Segment_Control_Smart_Class *
681 elm_segment_control_smart_class_get(void)
682 {
683    static Elm_Segment_Control_Smart_Class _sc =
684      ELM_SEGMENT_CONTROL_SMART_CLASS_INIT_NAME_VERSION
685        (ELM_SEGMENT_CONTROL_SMART_NAME);
686    static const Elm_Segment_Control_Smart_Class *class = NULL;
687    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
688
689    if (class)
690      return class;
691
692    _elm_segment_control_smart_set(&_sc);
693    esc->callbacks = _smart_callbacks;
694    class = &_sc;
695
696    return class;
697 }
698
699 EAPI Evas_Object *
700 elm_segment_control_add(Evas_Object *parent)
701 {
702    Evas_Object *obj;
703
704    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
705
706    obj = elm_widget_add(_elm_segment_control_smart_class_new(), parent);
707    if (!obj) return NULL;
708
709    if (!elm_widget_sub_object_add(parent, obj))
710      ERR("could not add %p as sub object of %p", obj, parent);
711
712    return obj;
713 }
714
715 EAPI Elm_Object_Item *
716 elm_segment_control_item_add(Evas_Object *obj,
717                              Evas_Object *icon,
718                              const char *label)
719 {
720    Elm_Segment_Item *it;
721
722    ELM_SEGMENT_CONTROL_CHECK(obj) NULL;
723    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
724
725    it = _item_new(obj, icon, label);
726    if (!it) return NULL;
727
728    sd->items = eina_list_append(sd->items, it);
729    _update_list(sd);
730
731    return (Elm_Object_Item *)it;
732 }
733
734 EAPI Elm_Object_Item *
735 elm_segment_control_item_insert_at(Evas_Object *obj,
736                                    Evas_Object *icon,
737                                    const char *label,
738                                    int idx)
739 {
740    Elm_Segment_Item *it, *it_rel;
741
742    ELM_SEGMENT_CONTROL_CHECK(obj) NULL;
743    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
744
745    if (idx < 0) idx = 0;
746
747    it = _item_new(obj, icon, label);
748    if (!it) return NULL;
749
750    it_rel = _item_find(obj, idx);
751    if (it_rel) sd->items = eina_list_prepend_relative(sd->items, it, it_rel);
752    else sd->items = eina_list_append(sd->items, it);
753
754    _update_list(sd);
755
756    return (Elm_Object_Item *)it;
757 }
758
759 EAPI void
760 elm_segment_control_item_del_at(Evas_Object *obj,
761                                 int idx)
762 {
763    Elm_Segment_Item *it;
764
765    ELM_SEGMENT_CONTROL_CHECK(obj);
766
767    it = _item_find(obj, idx);
768    if (!it) return;
769
770    elm_object_item_del((Elm_Object_Item *)it);
771 }
772
773 EAPI const char *
774 elm_segment_control_item_label_get(const Evas_Object *obj,
775                                    int idx)
776 {
777    Elm_Segment_Item *it;
778
779    ELM_SEGMENT_CONTROL_CHECK(obj) NULL;
780
781    it = _item_find(obj, idx);
782    if (it) return it->label;
783
784    return NULL;
785 }
786
787 EAPI Evas_Object *
788 elm_segment_control_item_icon_get(const Evas_Object *obj,
789                                   int idx)
790 {
791    ELM_SEGMENT_CONTROL_CHECK(obj) NULL;
792
793    Elm_Segment_Item *it = _item_find(obj, idx);
794    if (it) return it->icon;
795
796    return NULL;
797 }
798
799 EAPI int
800 elm_segment_control_item_count_get(const Evas_Object *obj)
801 {
802    ELM_SEGMENT_CONTROL_CHECK(obj) 0;
803    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
804
805    return eina_list_count(sd->items);
806 }
807
808 EAPI Evas_Object *
809 elm_segment_control_item_object_get(const Elm_Object_Item *it)
810 {
811    ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, NULL);
812
813    return VIEW(it);
814 }
815
816 EAPI Elm_Object_Item *
817 elm_segment_control_item_selected_get(const Evas_Object *obj)
818 {
819    ELM_SEGMENT_CONTROL_CHECK(obj) NULL;
820    ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
821
822    return (Elm_Object_Item *)sd->selected_item;
823 }
824
825 EAPI void
826 elm_segment_control_item_selected_set(Elm_Object_Item *it,
827                                       Eina_Bool selected)
828 {
829    Elm_Segment_Item *item = (Elm_Segment_Item *)it;
830
831    ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it);
832    ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
833
834    if (item == sd->selected_item)
835      {
836         //already in selected state.
837         if (selected) return;
838
839         //unselect case
840         _segment_off(item);
841      }
842    else if (selected)
843      _segment_on(item);
844 }
845
846 EAPI Elm_Object_Item *
847 elm_segment_control_item_get(const Evas_Object *obj,
848                              int idx)
849 {
850    ELM_SEGMENT_CONTROL_CHECK(obj) NULL;
851
852    return (Elm_Object_Item *)_item_find(obj, idx);
853 }
854
855 EAPI int
856 elm_segment_control_item_index_get(const Elm_Object_Item *it)
857 {
858    ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, -1);
859
860    return ((Elm_Segment_Item *)it)->seg_index;
861 }