elementary/segment_control, panes, photocam, photo, win, toolbar, thumb, slideshow...
[framework/uifw/elementary.git] / src / lib / elm_segment_control.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup SegmentControl SegmentControl
6  *
7  * SegmentControl Widget is a horizontal control made of multiple segment items,
8  * each segment item functioning similar to discrete two state button. A segment
9  * control groups the the items together and provides compact single button with
10  * multiple equal size segments. Segment item size is determined by base widget
11  * size and the number of items added.
12  * Only one Segment item can be at selected state. A segment item can display
13  * combination of Text and any Evas_Object like Images or other widget.
14  *
15  * Signals that you can add callbacks for are:
16  *
17  * "changed" -when the user clicks on a segment item which is not previously
18  *            selected and get selected. The event_info parameter is the
19  *            segment item index.
20  */
21 typedef struct _Widget_Data Widget_Data;
22
23 struct _Widget_Data
24 {
25    Evas_Object *obj;
26    Evas_Object *base;
27    Eina_List *seg_items;
28    int item_count;
29    Elm_Segment_Item *selected_item;
30    int item_width;
31 };
32
33 struct _Elm_Segment_Item
34 {
35    Elm_Widget_Item base;
36    Evas_Object *icon;
37    const char *label;
38    int seg_index;
39 };
40
41 static const char *widtype = NULL;
42 static void _sizing_eval(Evas_Object *obj);
43 static void _del_hook(Evas_Object *obj);
44 static void _theme_hook(Evas_Object *obj);
45 static void _disable_hook(Evas_Object *obj);
46 static void _item_free(Elm_Segment_Item *it);
47 static void _segment_off(Elm_Segment_Item *it);
48 static void _segment_on(Elm_Segment_Item *it);
49 static void _position_items(Widget_Data *wd);
50 static void _on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj
51                             __UNUSED__, void *event_info __UNUSED__);
52 static void _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj
53                       __UNUSED__, void *event_info __UNUSED__);
54 static void _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj
55                         __UNUSED__, void *event_info __UNUSED__);
56 static void _swallow_item_objects(Elm_Segment_Item *it);
57 static void _update_list(Widget_Data *wd);
58 static Elm_Segment_Item * _item_find(const Evas_Object *obj, int index);
59 static Elm_Segment_Item* _item_new(Evas_Object *obj, Evas_Object *icon,
60                                    const char *label);
61
62 static const char SIG_CHANGED[] = "changed";
63
64 static const Evas_Smart_Cb_Description _signals[] = {
65    {SIG_CHANGED, ""},
66    {NULL, NULL}
67 };
68
69 static void
70 _sizing_eval(Evas_Object *obj)
71 {
72    Widget_Data *wd;
73    Evas_Coord minw = -1, minh = -1;
74    Evas_Coord w, h;
75
76    wd = elm_widget_data_get(obj);
77    if (!wd) return;
78
79    elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh);
80    edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
81    elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh);
82
83    evas_object_size_hint_min_get(obj, &w, &h);
84    if (w > minw) minw = w;
85    if (h > minh) minh = h;
86    evas_object_size_hint_min_set(obj, minw, minh);
87 }
88
89 static void
90 _del_hook(Evas_Object *obj)
91 {
92    Elm_Segment_Item *it;
93    Widget_Data *wd;
94
95    wd = elm_widget_data_get(obj);
96    if (!wd) return;
97
98    EINA_LIST_FREE(wd->seg_items, it) _item_free(it);
99
100    free(wd);
101 }
102
103 static void
104 _theme_hook(Evas_Object *obj)
105 {
106    Eina_List *l;
107    Eina_Bool rtl;
108    Elm_Segment_Item *it;
109    Widget_Data *wd;
110
111    wd = elm_widget_data_get(obj);
112    if (!wd) return;
113
114    _elm_widget_mirrored_reload(obj);
115    rtl = elm_widget_mirrored_get(obj);
116    edje_object_mirrored_set(wd->base, rtl);
117
118    _elm_theme_object_set(obj, wd->base, "segment_control", "base",
119                          elm_widget_style_get(obj));
120    edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base)
121                          *_elm_config->scale);
122
123    EINA_LIST_FOREACH(wd->seg_items, l, it)
124      {
125         _elm_theme_object_set(obj, it->base.view, "segment_control",
126                               "item", elm_widget_style_get(obj));
127         edje_object_scale_set(it->base.view, elm_widget_scale_get(it->base.view)
128                               *_elm_config->scale);
129         edje_object_mirrored_set(it->base.view, rtl);
130      }
131
132    _update_list(wd);
133 }
134
135 static void
136 _disable_hook(Evas_Object *obj)
137 {
138    Widget_Data *wd;
139
140    wd = elm_widget_data_get(obj);
141    if (!wd) return;
142    _update_list(wd);
143 }
144
145 // TODO:  Elm_widget elm_widget_focus_list_next_get  supports only Elm_widget list,
146 // Not the Elm_Widget_item. Focus switching with in widget not supported until
147 // it is supported in elm_widget
148 #if 0
149 static void *
150 _elm_list_data_get(const Eina_List *list)
151 {
152    Elm_Segment_Item *it = eina_list_data_get(list);
153
154    if (it) return NULL;
155
156    edje_object_signal_emit(it->base.view, "elm,state,segment,selected", "elm");
157    return it->base.view;
158 }
159
160 static Eina_Bool
161 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir,
162                  Evas_Object **next)
163 {
164    static int count=0;
165    Widget_Data *;
166    const Eina_List *items;
167    void *(*list_data_get) (const Eina_List *list);
168
169    wd = elm_widget_data_get(obj);
170    if ((!wd)) return EINA_FALSE;
171
172    /* Focus chain */
173    /* TODO: Change this to use other chain */
174    if ((items = elm_widget_focus_custom_chain_get(obj)))
175      list_data_get = eina_list_data_get;
176    else
177      {
178         items = wd->seg_items;
179         list_data_get = _elm_list_data_get;
180         if (!items) return EINA_FALSE;
181      }
182    return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
183 }
184 #endif
185
186 static void
187 _item_free(Elm_Segment_Item *it)
188 {
189    Widget_Data *wd;
190
191    if (!it) return;
192
193    wd = elm_widget_item_data_get(it);
194    if (!wd) return;
195
196    if (wd->selected_item == it) wd->selected_item = NULL;
197    if (wd->seg_items) wd->seg_items = eina_list_remove(wd->seg_items, it);
198
199    elm_widget_item_pre_notify_del(it);
200
201    if (it->icon) evas_object_del(it->icon);
202    if (it->label) eina_stringshare_del(it->label);
203
204    elm_widget_item_del(it);
205 }
206
207 static void
208 _segment_off(Elm_Segment_Item *it)
209 {
210    Widget_Data *wd;
211
212    if (!it) return;
213
214    wd = elm_widget_item_data_get(it);
215    if (!wd) return;
216
217    edje_object_signal_emit(it->base.view, "elm,state,segment,normal", "elm");
218
219    if (wd->selected_item == it) wd->selected_item = NULL;
220 }
221
222 static void
223 _segment_on(Elm_Segment_Item *it)
224 {
225    Widget_Data *wd;
226
227    if (!it) return;
228
229    wd = elm_widget_item_data_get(it);
230    if (!wd) return;
231    if (it == wd->selected_item) return;
232
233    if (wd->selected_item) _segment_off(wd->selected_item);
234
235    edje_object_signal_emit(it->base.view, "elm,state,segment,selected", "elm");
236
237    wd->selected_item = it;
238    evas_object_smart_callback_call(wd->obj, SIG_CHANGED, (void*) it->seg_index);
239 }
240
241 static void
242 _position_items(Widget_Data *wd)
243 {
244    Eina_List *l;
245    Elm_Segment_Item *it;
246    Eina_Bool rtl;
247    int bx, by, bw, bh, pos;
248
249    wd->item_count = eina_list_count(wd->seg_items);
250    if (wd->item_count <= 0) return;
251
252    evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh);
253    wd->item_width = bw / wd->item_count;
254    rtl = elm_widget_mirrored_get(wd->obj);
255
256    if (rtl)
257      pos = bx + bw - wd->item_width;
258    else
259      pos = bx;
260
261    EINA_LIST_FOREACH(wd->seg_items, l, it)
262      {
263         evas_object_move(it->base.view, pos, by);
264         evas_object_resize(it->base.view, wd->item_width, bh);
265         if (rtl)
266           pos -= wd->item_width;
267         else
268           pos += wd->item_width;
269      }
270    _sizing_eval(wd->obj);
271 }
272
273 static void
274 _on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
275                 void *event_info __UNUSED__)
276 {
277    Widget_Data *wd;
278
279    wd = elm_widget_data_get(data);
280    if (!wd) return;
281
282    _position_items(wd);
283
284 }
285
286 static void
287 _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
288           void *event_info)
289 {
290    Widget_Data *wd;
291    Elm_Segment_Item *it;
292    Evas_Event_Mouse_Up *ev;
293    Evas_Coord x, y, w, h;
294
295    it = data;
296    if (!it) return;
297
298    wd = elm_widget_item_data_get(it);
299    if (!wd) return;
300
301    if (elm_widget_disabled_get(wd->obj)) return;
302
303    if (it == wd->selected_item) return;
304
305    ev = event_info;
306    evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
307
308    if ((ev->output.x >= x) && (ev->output.x <= (x + w)) && (ev->output.y >= y)
309        && (ev->output.y <= (y + h)))
310      _segment_on(it);
311    else
312      edje_object_signal_emit(it->base.view, "elm,state,segment,normal", "elm");
313 }
314
315 static void
316 _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
317             void *event_info __UNUSED__)
318 {
319    Widget_Data *wd;
320    Elm_Segment_Item *it;
321
322    it = data;
323    if (!it) return;
324
325    wd = elm_widget_item_data_get(it);
326    if (!wd) return;
327
328    if (elm_widget_disabled_get(wd->obj)) return;
329
330    if (it == wd->selected_item) return;
331
332    edje_object_signal_emit(it->base.view, "elm,state,segment,pressed", "elm");
333 }
334
335 static void
336 _swallow_item_objects(Elm_Segment_Item *it)
337 {
338    if (!it) return;
339
340    if (it->icon)
341      {
342         edje_object_part_swallow(it->base.view, "elm.swallow.icon", it->icon);
343         edje_object_signal_emit(it->base.view, "elm,state,icon,visible", "elm");
344      }
345    else
346      edje_object_signal_emit(it->base.view, "elm,state,icon,hidden", "elm");
347
348    if (it->label)
349      edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
350    else
351      edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
352    edje_object_message_signal_process(it->base.view);
353 }
354
355 static void
356 _update_list(Widget_Data *wd)
357 {
358    Eina_List *l;
359    Elm_Segment_Item *it;
360    Eina_Bool rtl;
361    int index = 0;
362
363    _position_items(wd);
364
365    if (wd->item_count == 1)
366      {
367         it = eina_list_nth(wd->seg_items, 0);
368         it->seg_index = 0;
369
370         //Set the segment type
371         edje_object_signal_emit(it->base.view,
372                                 "elm,type,segment,single", "elm");
373
374         //Set the segment state
375         if (wd->selected_item == it)
376           edje_object_signal_emit(it->base.view,
377                                   "elm,state,segment,selected", "elm");
378         else
379           edje_object_signal_emit(it->base.view,
380                                   "elm,state,segment,normal", "elm");
381
382         if (elm_widget_disabled_get(wd->obj))
383           edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm");
384
385         _swallow_item_objects(it);
386         return;
387      }
388
389    rtl = elm_widget_mirrored_get(wd->obj);
390    EINA_LIST_FOREACH(wd->seg_items, l, it)
391      {
392         it->seg_index = index;
393
394         //Set the segment type
395         if (index == 0)
396           {
397              if (rtl)
398                edje_object_signal_emit(it->base.view,
399                                        "elm,type,segment,right", "elm");
400              else
401                edje_object_signal_emit(it->base.view,
402                                        "elm,type,segment,left", "elm");
403           }
404         else if (index == (wd->item_count - 1))
405           {
406              if (rtl)
407                edje_object_signal_emit(it->base.view,
408                                        "elm,type,segment,left", "elm");
409              else
410                edje_object_signal_emit(it->base.view,
411                                        "elm,type,segment,right", "elm");
412           }
413         else
414           edje_object_signal_emit(it->base.view,
415                                   "elm,type,segment,middle", "elm");
416
417         //Set the segment state
418         if (wd->selected_item == it)
419           edje_object_signal_emit(it->base.view,
420                                   "elm,state,segment,selected", "elm");
421         else
422           edje_object_signal_emit(it->base.view,
423                                   "elm,state,segment,normal", "elm");
424
425         if (elm_widget_disabled_get(wd->obj))
426           edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm");
427
428         _swallow_item_objects(it);
429         index++;
430      }
431 }
432
433 static Elm_Segment_Item *
434 _item_find(const Evas_Object *obj, int index)
435 {
436    Widget_Data *wd;
437    Elm_Segment_Item *it;
438
439    wd = elm_widget_data_get(obj);
440    if (!wd) return NULL;
441
442    it = eina_list_nth(wd->seg_items, index);
443    return it;
444 }
445
446 static Elm_Segment_Item*
447 _item_new(Evas_Object *obj, Evas_Object *icon, const char *label)
448 {
449    Elm_Segment_Item *it;
450    Widget_Data *wd;
451
452    wd = elm_widget_data_get(obj);
453    if (!wd) return NULL;
454
455    it = elm_widget_item_new(obj, Elm_Segment_Item);
456    if (!it) return NULL;
457    elm_widget_item_data_set(it, wd);
458
459    it->base.view = edje_object_add(evas_object_evas_get(obj));
460    edje_object_scale_set(it->base.view, elm_widget_scale_get(it->base.view)
461                          *_elm_config->scale);
462    evas_object_smart_member_add(it->base.view, obj);
463    elm_widget_sub_object_add(obj, it->base.view);
464    _elm_theme_object_set(obj, it->base.view, "segment_control", "item",
465                          elm_object_style_get(obj));
466    edje_object_mirrored_set(it->base.view,
467                             elm_widget_mirrored_get(it->base.widget));
468
469    if (label)
470      eina_stringshare_replace(&it->label, label);
471    if (it->label)
472      edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
473    else
474      edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
475    edje_object_message_signal_process(it->base.view);
476    edje_object_part_text_set(it->base.view, "elm.text", label);
477
478    it->icon = icon;
479    if (it->icon) elm_widget_sub_object_add(it->base.view, it->icon);
480    evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_DOWN,
481                                   _mouse_down, it);
482    evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_UP,
483                                   _mouse_up, it);
484    evas_object_show(it->base.view);
485
486    return it;
487 }
488
489 /**
490  * Create new SegmentControl.
491  * @param [in] parent The parent object
492  * @return The new object or NULL if it cannot be created
493  *
494  * @ingroup SegmentControl
495  */
496 EAPI Evas_Object *
497 elm_segment_control_add(Evas_Object *parent)
498 {
499    Evas_Object *obj;
500    Evas *e;
501    Widget_Data *wd;
502
503    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
504
505    ELM_SET_WIDTYPE(widtype, "segment_control");
506    elm_widget_type_set(obj, "segment_control");
507    elm_widget_sub_object_add(parent, obj);
508    elm_widget_data_set(obj, wd);
509    elm_widget_del_hook_set(obj, _del_hook);
510    elm_widget_theme_hook_set(obj, _theme_hook);
511    elm_widget_disable_hook_set(obj, _disable_hook);
512
513    // TODO: Focus switch support to Elm_widget_Item not supported yet.
514 #if 0
515    elm_widget_focus_next_hook_set(obj, _focus_next_hook);
516 #endif
517
518    wd->obj = obj;
519
520    wd->base = edje_object_add(e);
521    edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base)
522                          *_elm_config->scale);
523    _elm_theme_object_set(obj, wd->base, "segment_control", "base", "default");
524    elm_widget_resize_object_set(obj, wd->base);
525
526    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
527                                   _on_move_resize, obj);
528    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
529                                   _on_move_resize, obj);
530
531    evas_object_smart_callbacks_descriptions_set(obj, _signals);
532
533    return obj;
534 }
535
536 /**
537  * Add new segment item to SegmentControl.
538  * @param [in] obj The SegmentControl object
539  * @param [in] icon Any Objects like icon, Label, layout etc
540  * @param [in] label The label for added segment item.
541  *             Note that, NULL is different from empty string "".
542  * @return The new segment item or NULL if it cannot be created
543  *
544  * @ingroup SegmentControl
545  */
546 EAPI Elm_Segment_Item *
547 elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon,
548                              const char *label)
549 {
550    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
551    Elm_Segment_Item *it;
552    Widget_Data *wd;
553
554    wd = elm_widget_data_get(obj);
555    if (!wd) return NULL;
556
557    it = _item_new(obj, icon, label);
558    if (!it) return NULL;
559
560    wd->seg_items = eina_list_append(wd->seg_items, it);
561    _update_list(wd);
562
563    return it;
564 }
565
566 /**
567  * Insert a new segment item to SegmentControl.
568  * @param [in] obj The SegmentControl object
569  * @param [in] icon Any Objects like icon, Label, layout etc
570  * @param [in] label The label for added segment item.
571  *        Note that, NULL is different from empty string "".
572  * @param [in] index Segment item location. Value should be between 0 and
573  *        Existing total item count( @see elm_segment_control_item_count_get() )
574  * @return The new segment item or NULL if it cannot be created
575  *
576  * @ingroup SegmentControl
577  */
578 EAPI Elm_Segment_Item *
579 elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon,
580                                    const char *label, int index)
581 {
582    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
583    Elm_Segment_Item *it, *it_rel;
584    Widget_Data *wd;
585
586    wd = elm_widget_data_get(obj);
587    if (!wd) return NULL;
588    if (index < 0) index = 0;
589
590    it = _item_new(obj, icon, label);
591    if (!it) return NULL;
592
593    it_rel = _item_find(obj, index);
594    if (it_rel)
595      wd->seg_items = eina_list_prepend_relative(wd->seg_items, it, it_rel);
596    else
597      wd->seg_items = eina_list_append(wd->seg_items, it);
598
599    _update_list(wd);
600    return it;
601 }
602
603 /**
604  * Delete a segment item from SegmentControl
605  * @param [in] obj The SegmentControl object
606  * @param [in] it The segment item to be deleted
607  *
608  * @ingroup SegmentControl
609  */
610 EAPI void
611 elm_segment_control_item_del(Elm_Segment_Item *it)
612 {
613    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
614    Widget_Data *wd;
615
616    wd = elm_widget_item_data_get(it);
617    if (!wd) return;
618
619    _item_free(it);
620    _update_list(wd);
621 }
622
623 /**
624  * Delete a segment item of given index from SegmentControl
625  * @param [in] obj The SegmentControl object
626  * @param [in] index The position at which segment item to be deleted.
627  *
628  * @ingroup SegmentControl
629  */
630 EAPI void
631 elm_segment_control_item_del_at(Evas_Object *obj, int index)
632 {
633    ELM_CHECK_WIDTYPE(obj, widtype);
634    Elm_Segment_Item *it;
635    Widget_Data *wd;
636
637    wd = elm_widget_data_get(obj);
638    if (!wd) return;
639
640    it = _item_find(obj, index);
641    if (!it) return;
642    _item_free(it);
643    _update_list(wd);
644 }
645
646 /**
647  * Get the label of a segment item.
648  * @param [in] obj The SegmentControl object
649  * @param [in] index The index of the segment item
650  * @return The label of the segment item
651  *
652  * @ingroup SegmentControl
653  */
654 EAPI const char*
655 elm_segment_control_item_label_get(const Evas_Object *obj, int index)
656 {
657    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
658    Elm_Segment_Item *it;
659
660    it = _item_find(obj, index);
661    if (it) return it->label;
662
663    return NULL;
664 }
665
666 /**
667  * Set the label of a segment item.
668  * @param [in] it The SegmentControl Item
669  * @param [in] label New label text.
670  *
671  * @ingroup SegmentControl
672  */
673 EAPI void
674 elm_segment_control_item_label_set(Elm_Segment_Item* it, const char* label)
675 {
676    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
677    Widget_Data *wd;
678
679    wd = elm_widget_item_data_get(it);
680    if (!wd) return;
681
682    eina_stringshare_replace(&it->label, label);
683    if (it->label)
684      edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
685    else
686      edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
687    edje_object_message_signal_process(it->base.view);
688    //label can be NULL also.
689    edje_object_part_text_set(it->base.view, "elm.text", it->label);
690 }
691
692 /**
693  * Get the icon of a segment item of SegmentControl
694  * @param [in] obj The SegmentControl object
695  * @param [in] index The index of the segment item
696  * @return The icon object.
697  *
698  * @ingroup SegmentControl
699  */
700 EAPI Evas_Object *
701 elm_segment_control_item_icon_get(const Evas_Object *obj, int index)
702 {
703    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
704    Elm_Segment_Item *it;
705
706    it = _item_find(obj, index);
707    if (it) return it->icon;
708
709    return NULL;
710 }
711
712 /**
713  * Set the Icon to the segment item
714  * @param [in] it The SegmentControl Item
715  * @param [in] icon Objects like Layout, Icon, Label etc...
716  *
717  * @ingroup SegmentControl
718  */
719 EAPI void
720 elm_segment_control_item_icon_set(Elm_Segment_Item *it, Evas_Object *icon)
721 {
722    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
723
724    //Remove the existing icon
725    if (it->icon)
726      {
727         edje_object_part_unswallow(it->base.view, it->icon);
728         evas_object_del(it->icon);
729         it->icon = NULL;
730      }
731
732    it->icon = icon;
733    if (it->icon)
734      {
735         elm_widget_sub_object_add(it->base.view, it->icon);
736         edje_object_part_swallow(it->base.view, "elm.swallow.icon", it->icon);
737         edje_object_signal_emit(it->base.view, "elm,state,icon,visible", "elm");
738      }
739    else
740      edje_object_signal_emit(it->base.view, "elm,state,icon,hidden", "elm");
741 }
742
743 /**
744  * Get the Segment items count from SegmentControl
745  * @param [in] obj The SegmentControl object
746  * @return Segment items count.
747  *
748  * @ingroup SegmentControl
749  */
750 EAPI int
751 elm_segment_control_item_count_get(const Evas_Object *obj)
752 {
753    ELM_CHECK_WIDTYPE(obj, widtype) 0;
754    Widget_Data *wd;
755
756    wd = elm_widget_data_get(obj);
757    if (!wd) return 0;
758
759    return eina_list_count(wd->seg_items);
760 }
761
762 /**
763  * Get the base object of segment item.
764  * @param [in] it The Segment item
765  * @return obj The base object of the segment item.
766  *
767  * @ingroup SegmentControl
768  */
769 EAPI Evas_Object*
770 elm_segment_control_item_object_get(const Elm_Segment_Item *it)
771 {
772    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
773
774    return it->base.view;
775 }
776
777 /**
778  * Get the selected segment item in the SegmentControl
779  * @param [in] obj The SegmentControl object
780  * @return Selected Segment Item. NULL if none of segment item is selected.
781  *
782  * @ingroup SegmentControl
783  */
784 EAPI Elm_Segment_Item*
785 elm_segment_control_item_selected_get(const Evas_Object *obj)
786 {
787    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
788    Widget_Data *wd;
789
790    wd = elm_widget_data_get(obj);
791    if (!wd) return NULL;
792
793    return wd->selected_item;
794 }
795
796 /**
797  * Select/unselect a particular segment item of SegmentControl
798  * @param [in] it The Segment item that is to be selected or unselected.
799  * @param [in] select Passing EINA_TRUE will select the segment item and
800  *             EINA_FALSE will unselect.
801  *
802  * @ingroup SegmentControl
803  */
804 EAPI void
805 elm_segment_control_item_selected_set(Elm_Segment_Item *it, Eina_Bool select)
806 {
807    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
808    Widget_Data *wd;
809
810    wd = elm_widget_item_data_get(it);
811    if (!wd) return;
812
813    if (it == wd->selected_item)
814      {
815         //already in selected state.
816         if (select) return;
817
818         //unselect case
819         _segment_off(it);
820      }
821    else if (select)
822      _segment_on(it);
823
824    return;
825 }
826
827 /**
828  * Get the Segment Item from the specified Index.
829  * @param [in] obj The Segment Control object.
830  * @param [in] index The index of the segment item.
831  * @return The Segment item.
832  *
833  * @ingroup SegmentControl
834  */
835 EAPI Elm_Segment_Item *
836 elm_segment_control_item_get(const Evas_Object *obj, int index)
837 {
838    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
839    Elm_Segment_Item *it;
840
841    it = _item_find(obj, index);
842
843    return it;
844 }
845
846 /**
847  * Get the index of a Segment item in the SegmentControl
848  * @param [in] it The Segment Item.
849  * @return Segment Item index.
850  *
851  * @ingroup SegmentControl
852  */
853 EAPI int
854 elm_segment_control_item_index_get(const Elm_Segment_Item *it)
855 {
856    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, -1);
857
858    return it->seg_index;
859 }