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