[SegmentControl] Updated.
[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  * @ingroup Elementary
7  *
8  * SegmentControl object is a horizontal control made of multiple segments,
9  * each segment functioning as a discrete button. A segmented control affords a compact means to group together a number of controls.
10  * A segmented control can display a title or an image. The UISegmentedControl object automatically resizes segments to fit proportionally
11  * within their superview unless they have a specific width set. When you add and remove segments,
12  * you can request that the action be animated with sliding and fading effects.
13  */
14 typedef struct _Widget_Data Widget_Data;
15 struct _Widget_Data
16 {
17    Evas_Object *box;
18    Evas_Object *base;
19    Eina_List *seg_ctrl;
20    int width, height;
21    int id;
22    int item_width;
23
24    Elm_Segment_Item *ani_it;
25    Ecore_Animator *ani;
26    unsigned int count;
27    unsigned int insert_index;
28    unsigned int del_index;
29    unsigned int cur_seg_id;
30    double scale_factor;
31    Eina_Bool longpressed : 1;
32    Eina_Bool selected : 1;
33 };
34
35 struct _Elm_Segment_Item
36 {
37    Evas_Object *obj;
38    Evas_Object *base;
39    Evas_Object *icon;
40    const char *label;
41    Eina_Bool delete_me : 1;
42    int segment_id;
43    Ecore_Timer *long_timer;
44 };
45
46 static void _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
47 static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
48 static void _signal_segment_on(void *data);
49 static void _theme_hook(Evas_Object *obj);
50 static void _item_free(Evas_Object *obj, Elm_Segment_Item *it);
51 static void _del_hook(Evas_Object *obj);
52 static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
53 static void _update_list(Evas_Object *obj);
54 static void _refresh_segment_ids(Evas_Object *obj);
55 static void _state_value_set(Evas_Object *obj);
56
57 static Elm_Segment_Item* _item_new(Evas_Object *obj, const char *label, Evas_Object *icon);
58 static Elm_Segment_Item *_item_find(Evas_Object *obj, unsigned int index);
59
60 static int * _animator_animate_add_cb(Evas_Object *obj);
61 static int * _animator_animate_del_cb(Evas_Object *obj);
62
63 static void
64 _on_focus_hook(void *data, Evas_Object *obj)
65 {
66    Widget_Data *wd = elm_widget_data_get(obj);
67    if (!wd) return;
68    Elm_Segment_Item *it;
69    Eina_List *l;
70
71    if (elm_widget_focus_get(obj))
72      {
73         edje_object_signal_emit((Evas_Object *)wd->seg_ctrl, "elm,action,focus", "elm");
74         evas_object_focus_set((Evas_Object *)wd->seg_ctrl, 1);
75      }
76    else
77      {
78         edje_object_signal_emit((Evas_Object *)wd->seg_ctrl, "elm,action,unfocus", "elm");
79         evas_object_focus_set((Evas_Object *)wd->seg_ctrl, 0);
80         wd->selected = EINA_FALSE;
81
82         EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
83           {
84              if (it->segment_id == wd->cur_seg_id) {
85                 edje_object_signal_emit(it->base, "elm,action,unfocus", "elm");
86                 edje_object_signal_emit(it->base, "elm,state,segment,off", "elm");
87                 edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
88                 break;
89              }
90           }
91         wd->cur_seg_id = -1;
92      }
93 }
94
95 static void
96 _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
97 {
98    Elm_Segment_Item *item = (Elm_Segment_Item *) data;
99    Widget_Data *wd = elm_widget_data_get(item->obj);
100
101    if (!wd) return;
102
103    if(wd->selected == EINA_TRUE)
104      {
105             wd->selected = EINA_FALSE;
106             return;
107          }
108
109    if(wd->longpressed == EINA_FALSE)
110      {
111        edje_object_signal_emit(item->base, "elm,action,unfocus", "elm");
112        edje_object_signal_emit(item->base, "elm,state,text,visible", "elm");
113      }
114    if (item->long_timer)
115      {
116        ecore_timer_del(item->long_timer);
117        item->long_timer = NULL;
118      }
119
120 }
121
122 static void
123 _signal_segment_on(void *data)
124 {
125    Elm_Segment_Item *item = (Elm_Segment_Item *) data;
126    Widget_Data *wd = elm_widget_data_get(item->obj);
127
128    if (!wd) return;
129
130    if (item->long_timer)
131      {
132        ecore_timer_del(item->long_timer);
133        item->long_timer = NULL;
134      }
135    wd->longpressed = EINA_TRUE;
136    edje_object_signal_emit(item->base, "elm,state,segment,on", "elm");
137    edje_object_signal_emit(item->base, "elm,state,text,change", "elm");
138
139    Elm_Segment_Item *it;
140    Eina_List *l;
141
142    if (item->segment_id == wd->cur_seg_id)
143      {
144         wd->cur_seg_id = item->segment_id;
145         evas_object_smart_callback_call(item->obj, "changed", (void*)wd->cur_seg_id);
146         return;
147      }
148    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
149      {
150         if (it->segment_id == wd->cur_seg_id)
151           {
152              edje_object_signal_emit(it->base, "elm,action,unfocus", "elm");
153              edje_object_signal_emit(it->base, "elm,state,segment,off", "elm");
154              edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
155              break;
156           }
157      }
158    wd->cur_seg_id = item->segment_id;
159    evas_object_smart_callback_call(item->obj, "changed", (void*)wd->cur_seg_id);
160    return;
161 }
162
163 static void
164 _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info)
165 {
166    Elm_Segment_Item *item = (Elm_Segment_Item *) data;
167    Widget_Data *wd = elm_widget_data_get(item->obj);
168
169    if (!wd) return;
170    wd->longpressed = EINA_FALSE;
171
172    if (item->segment_id == wd->cur_seg_id)
173      {
174            wd->selected = EINA_TRUE;
175            return;
176      }
177
178    edje_object_signal_emit(item->base, "elm,action,focus", "elm");
179    edje_object_signal_emit(item->base, "elm,state,text,visible", "elm");
180
181    if (item->long_timer) ecore_timer_del(item->long_timer);
182    item->long_timer = ecore_timer_add(0.5, _signal_segment_on, item);
183 }
184
185 static void
186 _theme_hook(Evas_Object *obj)
187 {
188    _elm_theme_object_set(obj, obj, "segmented-control", "base", elm_widget_style_get(obj));
189
190    return;
191 }
192
193 static void
194 _item_free(Evas_Object *obj, Elm_Segment_Item *it)
195 {
196    Widget_Data *wd = elm_widget_data_get(obj);
197    if (!wd) return;
198
199    if(wd->seg_ctrl)
200         wd->seg_ctrl = eina_list_remove(wd->seg_ctrl, it);
201
202    if(it->icon) evas_object_del(it->icon);
203    if(it->base) evas_object_del(it->base);
204    if(it->label) eina_stringshare_del(it->label);
205    if (it->long_timer) ecore_timer_del(it->long_timer);
206
207    if(it)
208       free(it);
209    it = NULL;
210    return;
211 }
212
213 static void
214 _del_hook(Evas_Object *obj)
215 {
216    Widget_Data *wd = elm_widget_data_get(obj);
217    Elm_Segment_Item *it;
218    Eina_List *l, *clear = NULL;
219
220    EINA_LIST_FOREACH(wd->seg_ctrl, l, it) clear = eina_list_append(clear, it);
221    EINA_LIST_FREE(clear, it) _item_free(obj, it);
222
223    if(wd) free(wd);
224    wd = NULL;
225
226    return;
227 }
228
229
230 static void
231 _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
232 {
233    Widget_Data *wd = data;
234    if (!wd) return;
235    _els_box_layout(o, priv, 1, 0); /* making box layout non homogenous */
236
237    return;
238 }
239
240 static void
241 _segment_resizing(void *data)
242 {
243    Widget_Data *wd = elm_widget_data_get((Evas_Object *)data);
244    if (!wd) return;
245    Evas_Coord w = 0, h = 0;
246
247    evas_object_geometry_get(wd->base, NULL, NULL, &w, &h);
248    wd->item_width = wd->width = w;
249    wd->height = h;
250    _state_value_set((Evas_Object *)data);
251 }
252
253 static void _object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
254 {
255    Widget_Data *wd;
256    if(!data) return;
257    wd = elm_widget_data_get((Evas_Object *)data);
258    if(!wd) return;
259
260    ecore_job_add(_segment_resizing, (Evas_Object *)data);
261 }
262
263 /**
264  * Add a new segmentcontrol to the parent
265  * @param parent The parent object
266  * @return The new object or NULL if it cannot be created
267  *
268  * @ingroup SegmentControl SegmentControl
269  */
270 EAPI Evas_Object *
271 elm_segment_control_add(Evas_Object *parent)
272 {
273    Evas_Object *obj;
274    Evas *e;
275    Widget_Data *wd;
276
277    wd = ELM_NEW(Widget_Data);
278    e = evas_object_evas_get(parent);
279    obj = elm_widget_add(e);
280    elm_widget_type_set(obj, "segmented-control");
281    elm_widget_sub_object_add(parent, obj);
282    elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
283    elm_widget_data_set(obj, wd);
284    elm_widget_del_hook_set(obj, _del_hook);
285    elm_widget_theme_hook_set(obj, _theme_hook);
286
287    wd->base = edje_object_add(e);
288    _elm_theme_object_set(obj, wd->base, "segmented-control", "base", "default");
289    elm_widget_resize_object_set(obj, wd->base);
290    wd->box = evas_object_box_add(e);
291    evas_object_box_layout_set(wd->box, _layout, wd, NULL);
292    elm_widget_sub_object_add(obj, wd->box);
293    edje_object_part_swallow(wd->base, "elm.swallow.content", wd->box);
294    evas_object_show(wd->box);
295
296    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _object_resize, obj);
297    wd->id = 0;
298    wd->del_index = 0;
299    wd->insert_index = 0;
300    wd->cur_seg_id = -1;
301    wd->selected = EINA_FALSE;
302
303    return obj;
304 }
305
306 static Elm_Segment_Item*
307 _item_new(Evas_Object *obj, const char *label, Evas_Object *icon)
308 {
309    Widget_Data *wd = elm_widget_data_get(obj);
310    if (!wd) return NULL;
311
312    Elm_Segment_Item *it;
313    it = calloc(1, sizeof(   Elm_Segment_Item));
314    if (!it) return NULL;
315
316    Evas_Coord mw, mh;
317
318    if(obj) it->obj = obj;
319    it->delete_me = EINA_FALSE;
320    it->segment_id = wd->id;
321
322    it->base = edje_object_add(evas_object_evas_get(obj));
323    _elm_theme_object_set(obj, it->base, "segment", "base", elm_object_style_get(it->base));
324
325    if (it->label) eina_stringshare_del(it->label);
326    if (label)
327      {
328         it->label = eina_stringshare_add(label);
329      }
330    else
331      {
332         it->label = NULL;
333      }
334
335    if ((it->icon != icon) && (it->icon))
336       elm_widget_sub_object_del(obj, it->icon);
337    it->icon = icon;
338    if (icon)
339      {
340         elm_widget_sub_object_add(obj, icon);
341         Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
342         elm_coords_finger_size_adjust(1, &minw, 1, &minh);
343         elm_coords_finger_size_adjust(1, &minw, 1, &minh);
344
345         evas_object_size_hint_weight_set(it->base, 1.0, -1.0);
346         evas_object_size_hint_align_set(it->base, 1.0, -1.0);
347         evas_object_size_hint_min_set(it->base, -1, -1);
348         evas_object_size_hint_max_set(it->base, maxw, maxh);
349      }
350
351    edje_object_size_min_restricted_calc(obj, &mw, &mh, 0, 0);
352    evas_object_size_hint_weight_set(obj, 1.0, 1.0);
353    evas_object_size_hint_align_set(obj, -1.0, -1.0);
354
355    return it;
356 }
357
358
359 static void _update_list(Evas_Object *obj)
360 {
361    Widget_Data *wd = elm_widget_data_get(obj);
362    if (!wd) return;
363
364    Elm_Segment_Item *it;
365    Eina_List *l;
366    int i = 0;
367    wd->count = eina_list_count(wd->seg_ctrl);
368
369    if(wd->count == 1)
370      {
371         it = _item_find(obj, 0);
372         _elm_theme_object_set(obj, it->base, "segment", "base", "single");              edje_object_signal_emit(it->base, "elm,state,segment,on", "elm");
373         edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
374         edje_object_signal_emit(it->base, "elm,state,text,change", "elm");
375         edje_object_message_signal_process(it->base);
376
377         edje_object_part_text_set(it->base, "elm.text", it->label);
378
379         edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
380         edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
381         return;
382      }
383
384    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
385      {
386         if(i==0)
387           {
388              _elm_theme_object_set(obj, it->base, "segment", "base", "first");
389           }
390         else if(i==wd->count-1)
391           {
392              _elm_theme_object_set(obj, it->base, "segment", "base", "last");
393           }
394         else
395           {
396              _elm_theme_object_set(obj, it->base, "segment", "base", "default");
397           }
398
399         edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
400         edje_object_message_signal_process(it->base);
401
402         edje_object_part_text_set(it->base, "elm.text", it->label);
403
404         edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
405         edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
406
407         i++;
408      }
409 }
410
411
412 static void _refresh_segment_ids(Evas_Object *obj)
413 {
414    Widget_Data *wd = elm_widget_data_get(obj);
415    if (!wd) return;
416    Elm_Segment_Item *it;
417    Eina_List *l;
418    if (wd->insert_index && wd->cur_seg_id >= wd->insert_index)
419      {
420         ++wd->cur_seg_id;
421         wd->insert_index = 0;
422      }
423    if (wd->del_index)
424      {
425         if (wd->cur_seg_id >= wd->del_index)
426            --wd->cur_seg_id;
427            wd->del_index =0;
428      }
429    int i = 0;
430    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
431      {
432         it->segment_id = i;
433         i++;
434      }
435 }
436
437 static void _state_value_set(Evas_Object *obj)
438 {
439    Widget_Data *wd = elm_widget_data_get(obj);
440    if (!wd) return;
441    Elm_Segment_Item *it;
442    Eina_List *l;
443    Evas_Coord mw, mh, x, y;
444    int w1=0, w2;
445    unsigned int count = eina_list_count(wd->seg_ctrl);
446    if (count > 0)
447      wd->item_width = wd->width/count;
448    if (wd->ani_it)
449      {
450         evas_object_geometry_get(wd->ani_it->base, &x, &y, &w1, NULL);
451         if (wd->ani_it->delete_me)
452           {
453              w1-=(wd->item_width/15);
454              if( w1< 0) w1 = 0;
455           }
456         else
457         {
458            w1+=(wd->item_width/15);
459            if( w1 > wd->item_width )
460               w1 = wd->item_width;
461         }
462         w2 = (wd->width-w1)/(count -1);
463      }
464    else
465       w2 = wd->item_width;
466
467    int i=0;
468
469    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
470     {
471        edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0);
472        evas_object_size_hint_weight_set(it->base, 1.0, 1.0);
473        evas_object_size_hint_align_set(it->base, -1.0, -1.0);
474
475        if(wd->ani_it  && it == wd->ani_it)
476          {
477             evas_object_resize(it->base, w1, wd->height);
478             evas_object_size_hint_min_set(it->base, w1, wd->height);
479             evas_object_size_hint_max_set(it->base, w1, wd->height);
480          }
481        else
482          {
483             evas_object_resize(it->base, w2, wd->height);
484             evas_object_size_hint_min_set(it->base, w2, wd->height);
485             evas_object_size_hint_max_set(it->base, w2, wd->height);
486          }
487        ++i;
488     }
489
490     return;
491 }
492
493
494 static int *
495 _animator_animate_add_cb(Evas_Object *obj)
496 {
497    Widget_Data *wd = elm_widget_data_get(obj);
498    if (!wd) return 0;
499
500    int w;
501    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
502    if( w <  wd->item_width )
503      {
504          _state_value_set(obj);
505          evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
506          return ECORE_CALLBACK_RENEW;
507      }
508    else
509      {
510         ecore_animator_del(wd->ani);
511         wd->ani = NULL;
512         wd->ani_it = NULL;
513         return ECORE_CALLBACK_CANCEL;
514      }
515 }
516
517
518 static int *
519 _animator_animate_del_cb(Evas_Object *obj)
520 {
521    Widget_Data *wd = elm_widget_data_get(obj);
522    if (!wd) return 0;
523    int w;
524    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
525    if( w >  0 )
526      {
527         _state_value_set(obj);
528         evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
529         return ECORE_CALLBACK_RENEW;
530      }
531    else
532      {
533         _item_free(obj, wd->ani_it );
534         _refresh_segment_ids(obj);
535         ecore_animator_del(wd->ani);
536         wd->ani = NULL;
537         wd->ani_it = NULL;
538         _update_list(obj);
539         wd->id = eina_list_count(wd->seg_ctrl);
540         return ECORE_CALLBACK_CANCEL;
541      }
542 }
543
544 /**
545  * Add a new segment to segmentcontrol
546  * @param obj The SegmentControl object
547  * @param icon The icon object for added segment
548  * @param label The label for added segment
549  * @param animate If 1 the action be animated with sliding effects default 0.
550  * @return The new segment or NULL if it cannot be created
551  *
552  * @ingroup SegmentControl SegmentControl
553  */
554
555 EAPI Elm_Segment_Item *
556 elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
557 {
558    Widget_Data *wd = elm_widget_data_get(obj);
559    if(!wd) return NULL;
560
561    Elm_Segment_Item *it;
562
563    it = _item_new(obj, label, icon);
564    if(!it) return NULL;
565
566    wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
567    wd->id = eina_list_count(wd->seg_ctrl);
568    _update_list(obj);
569    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
570    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
571    wd->insert_index = 0;
572    wd->del_index = 0;
573    _refresh_segment_ids(obj);
574
575    if(animate && it->segment_id && wd->ani_it == NULL)
576      {
577         evas_object_resize(it->base, 1, wd->height);
578         wd->ani_it = it;
579         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
580      }
581    else
582       _state_value_set(obj);
583    evas_object_show( it->base);
584
585    evas_object_box_append(wd->box, it->base);
586    evas_object_smart_calculate(wd->box);
587
588    return it;
589 }
590
591
592 static Elm_Segment_Item *
593 _item_find(Evas_Object *obj, unsigned int index)
594 {
595    Widget_Data *wd = elm_widget_data_get(obj);
596    if (!wd) return NULL;
597
598    Elm_Segment_Item *it;
599    Eina_List *l;
600    int i = 0;
601    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
602      {
603         if (i == index) {
604            return it;
605         }
606         i++;
607      }
608      return NULL;
609 }
610
611
612 static Elm_Segment_Item *
613 _item_search(Evas_Object *obj, Elm_Segment_Item *item)
614 {
615    Widget_Data *wd = elm_widget_data_get(obj);
616    if (!wd)
617    return NULL;
618
619    Elm_Segment_Item *it;
620    Eina_List *l;
621    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
622      {
623         if (it == item) {
624            return it;
625         }
626      }
627    return NULL;
628 }
629
630 /**
631  * Insert a new segment to segmentcontrol
632  * @param obj The SegmentControl object
633  * @param icon The icon object for added segment
634  * @param label The label for added segment
635  * @param index The position at which segment to be inserted
636  * @param animate If 1 the action be animated with sliding effects default 0.
637  * @return The new segment or NULL if it cannot be created
638  *
639  * @ingroup SegmentControl SegmentControl
640  */
641 EAPI void
642 elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
643 {
644    Widget_Data *wd = elm_widget_data_get(obj);
645    if(!wd) return;
646
647    Elm_Segment_Item *it, *it_rel;
648
649    it = _item_new(obj, label, icon);
650    it_rel = _item_find(obj, index);
651    if (!it_rel)
652      {
653       wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
654      }
655    else
656      {
657         if (!it) return;
658         wd->seg_ctrl = eina_list_prepend_relative(wd->seg_ctrl, it, it_rel);
659      }
660    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
661    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
662    wd->insert_index = index;
663    wd->id = eina_list_count(wd->seg_ctrl);
664    _refresh_segment_ids(obj);
665
666    _update_list(obj);
667    if(animate && it->segment_id && wd->ani_it == NULL)
668      {
669         wd->ani_it = it;
670         evas_object_resize(it->base, 1, wd->height);
671         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
672      }
673    else
674       _state_value_set(obj);
675
676    evas_object_show( it->base);
677
678    if(index >= wd->id-1)
679      {
680         evas_object_box_append(wd->box,  it->base);
681      }
682    else
683      {
684         evas_object_box_insert_at(wd->box,  it->base, index);
685      }
686
687    evas_object_smart_calculate(wd->box);
688    return;
689 }
690
691 /**
692  * Delete a segment to segmentcontrol
693  * @param obj The SegmentControl object
694  * @param item The Segment to be deleted
695  * @param animate If 1 the action be animated with sliding effects default 0.
696  *
697  * @ingroup SegmentControl SegmentControl
698  */
699 EAPI void
700 elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
701 {
702    Widget_Data *wd = elm_widget_data_get(obj);
703    if(!wd) return;
704
705    if(!item) return;
706
707    Elm_Segment_Item *it;
708    it = _item_search(obj, item);
709
710    if(!it) return;
711    wd->del_index = it->segment_id;
712    if(animate && it->segment_id && wd->ani_it == NULL)
713      {
714         it->delete_me = EINA_TRUE;
715         wd->ani_it = it;
716         wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
717      }
718    else
719      {
720         evas_object_box_remove(wd->box, it->base);
721         evas_object_smart_calculate(wd->box);
722         _item_free(obj, it);
723         _refresh_segment_ids(obj);
724         _state_value_set(obj);
725         _update_list(obj);
726      }
727    wd->id = eina_list_count(wd->seg_ctrl);
728    return;
729 }
730
731 /**
732  * Delete a segment to segmentcontrol
733  * @param obj The SegmentControl object
734  * @param index The position at which segment to be deleted
735  * @param animate If 1 the action be animated with sliding effects default 0.
736  *
737  * @ingroup SegmentControl SegmentControl
738  */
739
740 EAPI void
741 elm_segment_control_delete_segment_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
742 {
743    Widget_Data *wd = elm_widget_data_get(obj);
744    if(!wd) return;
745    Elm_Segment_Item *it;
746
747    it = _item_find(obj, index);
748
749    if(!it) return;
750
751    wd->del_index = index;
752    if(animate && it->segment_id)
753      {
754         if(wd->ani_it == NULL)
755         {
756            wd->ani_it = it;
757            it->delete_me = EINA_TRUE;
758            wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
759         }
760      }
761    else
762      {
763         evas_object_box_remove(wd->box, it->base);
764         evas_object_smart_calculate(wd->box);
765         _item_free(obj, it);
766         _refresh_segment_ids(obj);
767         _state_value_set(obj);
768         _update_list(obj);
769      }
770    wd->id = eina_list_count(wd->seg_ctrl);
771    return;
772 }
773
774 /**
775  * Get the label of a segment of segmentcontrol
776  * @param obj The SegmentControl object
777  * @param index The index of the segment
778  * @return The label
779  *
780  * @ingroup SegmentControl SegmentControl
781  */
782
783 EAPI const char *
784 elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index)
785 {
786    Elm_Segment_Item *it_rel;
787    Widget_Data *wd = elm_widget_data_get(obj);
788    if(!wd) return NULL;
789
790    it_rel = _item_find(obj, index);
791
792    if(it_rel) return it_rel->label;
793
794    return NULL;
795 }
796
797 /**
798  * Get the icon of a segment of segmentcontrol
799  * @param obj The SegmentControl object
800  * @param index The index of the segment
801  * @return The icon object
802  *
803  * @ingroup SegmentControl SegmentControl
804  */
805
806 EAPI Evas_Object *
807 elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index)
808 {
809    Elm_Segment_Item *seg_rel;
810    Widget_Data *wd = elm_widget_data_get(obj);
811    if(!wd) return NULL;
812
813    seg_rel = _item_find(obj, index);
814
815    if(seg_rel) return seg_rel->icon;
816
817    return NULL;
818 }
819
820 /**
821  * Get the currently selected segment of segmentcontrol
822  * @param obj The SegmentControl object
823  * @param value The current segment id
824  * @return The selected Segment
825  *
826  * @ingroup SegmentControl SegmentControl
827  */
828
829 EAPI Elm_Segment_Item *
830 elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value)
831 {
832    Widget_Data *wd = elm_widget_data_get(obj);
833    if(!wd || !wd->seg_ctrl) return NULL;
834
835    Elm_Segment_Item *it;
836    Eina_List *l;
837
838    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
839      {
840         if(it->segment_id == wd->cur_seg_id)
841           {
842              *value = wd->cur_seg_id;
843              return it;
844           }
845      }
846    return NULL;
847 }
848
849 /**
850  * Get the count of segments of segmentcontrol
851  * @param obj The SegmentControl object
852  * @return The count of Segments
853  *
854  * @ingroup SegmentControl SegmentControl
855  */
856
857 EAPI int
858 elm_segment_control_get_segment_count(Evas_Object *obj)
859 {
860    Widget_Data *wd = elm_widget_data_get(obj);
861    if(!wd) return 0;
862
863    return wd->id;
864 }
865