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