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