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