[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 item 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 segment items 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    Elm_Segment_Item *ani_it;
21    Ecore_Animator *ani;
22    void *data;
23    int width, height;
24    int id;
25    int item_width;
26    int cur_fontsize;
27    int max_height, w_pad, h_pad;
28    unsigned int count;
29    unsigned int insert_index;
30    unsigned int del_index;
31    unsigned int cur_seg_id;
32    double scale_factor;
33    Eina_Bool selected : 1;
34 };
35
36 struct _Elm_Segment_Item
37 {
38    Evas_Object *obj;
39    Evas_Object *base;
40    Evas_Object *icon;
41    Evas_Object *label_wd;
42    const char *label;
43    int segment_id;
44    Eina_Bool delete_me : 1;
45 };
46
47 static void _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
48 static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
49 static void _signal_segment_on(void *data);
50 static void _signal_segment_off(void *data);
51 static void _theme_hook(Evas_Object *obj);
52 static void _item_free(Evas_Object *obj, Elm_Segment_Item *it);
53 static void _del_hook(Evas_Object *obj);
54 static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
55 static void _segment_resizing(void *data);
56 static void _object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
57 static void _update_list(Evas_Object *obj);
58 static void _refresh_segment_ids(Evas_Object *obj);
59 static void _state_value_set(Evas_Object *obj);
60
61 static Elm_Segment_Item* _item_new(Evas_Object *obj, const char *label, Evas_Object *icon);
62 static Elm_Segment_Item *_item_find(Evas_Object *obj, unsigned int index);
63
64 static int * _animator_animate_add_cb(Evas_Object *obj);
65 static int * _animator_animate_del_cb(Evas_Object *obj);
66
67 static void
68 _on_focus_hook(void *data, Evas_Object *obj)
69 {
70    Widget_Data *wd = elm_widget_data_get(obj);
71    if (!wd) return;
72
73    if (elm_widget_focus_get(obj))
74      evas_object_focus_set((Evas_Object *)wd->seg_ctrl, 1);
75    else
76      evas_object_focus_set((Evas_Object *)wd->seg_ctrl, 0);
77 }
78
79 static void
80 _signal_segment_off(void *data)
81 {
82     Elm_Segment_Item *item = (Elm_Segment_Item *) data;
83     Widget_Data *wd = elm_widget_data_get(item->obj);
84     if (!wd) return;
85     
86     edje_object_signal_emit(item->base, "elm,action,unfocus", "elm");
87     edje_object_signal_emit(item->base, "elm,state,segment,off", "elm");
88     if(!item->label_wd)
89       {
90          edje_object_signal_emit(item->base, "elm,state,text,visible", "elm");
91       }
92     if(item->label_wd)
93       {
94          elm_label_text_color_set(item->label_wd, 0xff,0xff, 0xff, 0xff);
95       }
96
97     return;
98 }
99    
100 static void
101 _signal_segment_on(void *data)
102 {
103    Elm_Segment_Item *item = (Elm_Segment_Item *) data;
104    Elm_Segment_Item *it;
105    Eina_List *l;
106    
107    Widget_Data *wd = elm_widget_data_get(item->obj);
108    if (!wd) return;
109
110    wd->selected = EINA_TRUE;
111
112    edje_object_signal_emit(item->base, "elm,state,segment,on", "elm");
113    edje_object_signal_emit(item->base, "elm,action,focus", "elm");
114    if(!item->label_wd)
115      edje_object_signal_emit(item->base, "elm,state,text,change", "elm");
116
117    if (item->segment_id == wd->cur_seg_id) return;
118
119    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
120      {
121         if (it->segment_id == wd->cur_seg_id)
122           {
123              _signal_segment_off (it);
124              break;
125           }
126      }
127    wd->cur_seg_id = item->segment_id;
128    evas_object_smart_callback_call(item->obj, "changed", (void*)wd->cur_seg_id);
129
130    return;
131 }
132
133 static void
134 _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
135 {
136    Elm_Segment_Item *item = (Elm_Segment_Item *) data;
137    Widget_Data *wd = elm_widget_data_get(item->obj);
138    if (!wd) return;
139    Evas_Coord wrap_width = 0, wrap_height = 0, w = 0, h = 0;
140
141    if (item->segment_id == wd->cur_seg_id)
142      {
143        wd->selected = EINA_TRUE;
144        return;
145      }
146     _signal_segment_on(item);
147     if(item->label_wd)
148        elm_label_text_color_set(item->label_wd, 0x00,0x00, 0x00, 0xff);
149
150      wd->selected = EINA_FALSE;
151      return;
152
153 }
154
155 static void
156 _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info)
157 {
158    Elm_Segment_Item *item = (Elm_Segment_Item *) data;
159    Widget_Data *wd = elm_widget_data_get(item->obj);
160
161    if (!wd) return;
162    
163    edje_object_signal_emit(item->base, "elm,action,focus", "elm");
164
165 }
166
167 static void
168 _theme_hook(Evas_Object *obj)
169 {
170    _elm_theme_object_set(obj, obj, "segmented-control", "base", elm_widget_style_get(obj));
171
172    return;
173 }
174
175 static void
176 _item_free(Evas_Object *obj, Elm_Segment_Item *it)
177 {
178    Widget_Data *wd = elm_widget_data_get(obj);
179    if (!wd) return;
180
181    if(wd->seg_ctrl)
182      wd->seg_ctrl = eina_list_remove(wd->seg_ctrl, it);
183
184    if(it->icon) evas_object_del(it->icon);
185    if(it->label_wd) 
186      {
187         evas_object_del(it->label_wd);
188         it->label_wd = NULL;
189         if (edje_object_part_swallow_get(it->base, "elm.swallow.label.content") == NULL) 
190           {
191              edje_object_part_unswallow(it->base, it->label_wd);
192           }
193      }
194    if(it->base) evas_object_del(it->base);
195    if(it->label) eina_stringshare_del(it->label);
196
197    if(it)
198      free(it);
199    it = NULL;
200    return;
201 }
202
203 static void
204 _del_hook(Evas_Object *obj)
205 {
206    Widget_Data *wd = elm_widget_data_get(obj);
207    Elm_Segment_Item *it;
208    Eina_List *l, *clear = NULL;
209
210    EINA_LIST_FOREACH(wd->seg_ctrl, l, it) clear = eina_list_append(clear, it);
211    EINA_LIST_FREE(clear, it) _item_free(obj, it);
212
213    if(wd) free(wd);
214    wd = NULL;
215
216    return;
217 }
218
219
220 static void
221 _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
222 {
223    Widget_Data *wd = data;
224    if (!wd) return;
225    _els_box_layout(o, priv, 1, 0); /* making box layout non homogenous */
226
227    return;
228 }
229
230 static void
231 _segment_resizing(void *data)
232 {
233    Widget_Data *wd = elm_widget_data_get((Evas_Object *)data);
234    if (!wd) return;
235    Evas_Coord w = 0, h = 0;
236
237    evas_object_geometry_get(wd->base, NULL, NULL, &w, &h);
238    wd->item_width = wd->width = w;
239    wd->height = h;
240
241    _state_value_set((Evas_Object *)data);
242 }
243
244 static void 
245 _object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
246 {
247    Widget_Data *wd;
248    if(!data) return;
249    wd = elm_widget_data_get((Evas_Object *)data);
250    if(!wd) return;
251
252    ecore_job_add(_segment_resizing, (Evas_Object *)data);
253 }
254
255 static void
256 _segment_item_resizing(void *data)
257 {
258    Widget_Data *wd;
259    Elm_Segment_Item *it = (Elm_Segment_Item *)data; 
260    wd = elm_widget_data_get(it->obj);
261
262    if(!wd) return;
263    Evas_Coord w = 0, h = 0;
264    
265    _update_list(it->obj);
266    evas_object_geometry_get(it->base, NULL, NULL, &w, &h);
267
268    if(wd->max_height == 1) wd->max_height = h;
269
270    if(it->label_wd) 
271      {
272         elm_label_wrap_width_set(it->label_wd, w-wd->w_pad);
273         elm_label_wrap_height_set(it->label_wd, wd->max_height-wd->h_pad);
274         if (it->segment_id == wd->cur_seg_id)
275           {
276             elm_label_text_color_set(it->label_wd, 0x00,0x00, 0x00, 0xff);
277           }
278         else
279            elm_label_text_color_set(it->label_wd, 0xFF,0xFF, 0xFF, 0xff);
280         if (edje_object_part_swallow_get(it->base, "elm.swallow.label.content") == NULL)
281           {
282              edje_object_part_unswallow(it->base, it->label_wd);
283           }
284         edje_object_part_swallow(it->base, "elm.swallow.label.content", it->label_wd);
285         edje_object_signal_emit(it->base, "elm,state,label,visible", "elm");
286         if (it->segment_id == wd->cur_seg_id)
287           {
288             elm_label_text_color_set(it->label_wd, 0x00,0x00, 0x00, 0xff);
289           }
290         else
291            elm_label_text_color_set(it->label_wd, 0xFF,0xFF, 0xFF, 0xff);
292      }
293 }
294
295 static void 
296 _object_item_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
297 {
298    ecore_job_add(_segment_item_resizing, (Evas_Object *)data);
299 }
300
301 static Elm_Segment_Item*
302 _item_new(Evas_Object *obj, const char *label, Evas_Object *icon)
303 {
304    Elm_Segment_Item *it; 
305    Evas_Coord mw, mh; 
306    Widget_Data *wd = elm_widget_data_get(obj);
307    if (!wd) return NULL;
308
309    it = calloc(1, sizeof(   Elm_Segment_Item));
310    if (!it) return NULL;
311
312    if(obj) it->obj = obj;
313    it->delete_me = EINA_FALSE;
314    it->segment_id = wd->id;
315    it->label_wd = NULL;
316
317    it->base = edje_object_add(evas_object_evas_get(obj));
318    _elm_theme_object_set(obj, it->obj, "segment", "base/default", elm_object_style_get(it->obj));
319
320    if (it->label) eina_stringshare_del(it->label);
321    if (label)
322      {
323         it->label = eina_stringshare_add(label);
324      }
325
326    if ((it->icon != icon) && (it->icon))
327       elm_widget_sub_object_del(obj, it->icon);
328    it->icon = icon;
329    if (it->icon)
330      {
331         elm_widget_sub_object_add(obj, icon);
332         Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
333         elm_coords_finger_size_adjust(1, &minw, 1, &minh);
334         elm_coords_finger_size_adjust(1, &minw, 1, &minh);
335
336         evas_object_size_hint_weight_set(it->base, 1.0, -1.0);
337         evas_object_size_hint_align_set(it->base, 1.0, -1.0);
338         evas_object_size_hint_min_set(it->base, -1, -1);
339         evas_object_size_hint_max_set(it->base, maxw, maxh);
340      }
341
342    edje_object_size_min_restricted_calc(obj, &mw, &mh, 0, 0);
343    evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
344    evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
345
346    return it;
347 }
348
349
350 static void 
351 _update_list(Evas_Object *obj)
352 {
353    Elm_Segment_Item *it;
354    Eina_List *l;
355    int i = 0;
356  
357    Widget_Data *wd = elm_widget_data_get(obj);
358    if (!wd) return;
359
360    wd->count = eina_list_count(wd->seg_ctrl);
361    if(wd->count == 1)
362      {
363         it = _item_find(obj, 0);
364         _elm_theme_object_set(obj, it->base, "segment", "base/single", elm_object_style_get(it->obj));\r
365         edje_object_signal_emit(it->base, "elm,state,segment,on", "elm");
366         if(!it->label_wd)
367           {
368              edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
369              edje_object_signal_emit(it->base, "elm,state,text,change", "elm");
370           }
371
372         if(it->label)
373            edje_object_part_text_set(it->base, "elm.text", it->label);
374         if (it->icon && edje_object_part_swallow_get(it->base, "elm.swallow.content") == NULL)
375           {
376         edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
377         edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
378           }
379         edje_object_message_signal_process(it->base);
380
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", elm_object_style_get(it->obj));
389           }
390         else if(i==wd->count-1)
391           {
392              _elm_theme_object_set(obj, it->base, "segment", "base/last", elm_object_style_get(it->obj));
393           }
394         else
395           {
396              _elm_theme_object_set(obj, it->base, "segment", "base/default", elm_object_style_get(it->obj));
397
398           }
399           
400         if(!it->label_wd)
401           {
402              edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
403           }
404
405         if(it->label)
406           edje_object_part_text_set(it->base, "elm.text", it->label);
407
408         if (it->icon && edje_object_part_swallow_get(it->base, "elm.swallow.content") == NULL)
409           {
410         edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
411         edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
412           }
413         edje_object_message_signal_process(it->base);
414
415         i++;
416      }
417    if(wd->data && wd->selected)
418      {
419         _signal_segment_on(wd->data);
420         wd->selected = EINA_FALSE;
421      }
422 }
423
424
425 static void 
426 _refresh_segment_ids(Evas_Object *obj)
427 {
428    Elm_Segment_Item *it;
429    Eina_List *l;
430    int i = 0;
431    Widget_Data *wd = elm_widget_data_get(obj);
432    if (!wd) return;
433  
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
446    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
447      {
448         it->segment_id = i;
449         i++;
450      }
451 }
452
453 static void 
454 _state_value_set(Evas_Object *obj)
455 {
456    Elm_Segment_Item *it;
457    Eina_List *l;
458    Evas_Coord mw, mh, x, y;
459
460    int w1=0, w2, i=0;
461    unsigned int count ;
462    Widget_Data *wd = elm_widget_data_get(obj);
463    if (!wd) return;
464    
465    count = eina_list_count(wd->seg_ctrl);
466    if (count > 0)
467      wd->item_width = wd->width/count;
468    if (wd->ani_it)
469      {
470         evas_object_geometry_get(wd->ani_it->base, &x, &y, &w1, NULL);
471         if (wd->ani_it->delete_me)
472           {
473              w1-=(wd->item_width/5);
474              if( w1< 0) w1 = 0;
475           }
476         else
477         {
478            w1+=(wd->item_width/5);
479            if( w1 > wd->item_width )
480               w1 = wd->item_width;
481         }
482         w2 = (wd->width-w1)/(count -1);
483      }
484    else
485       w2 = wd->item_width;
486           
487    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
488     {
489        edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0);
490        evas_object_size_hint_weight_set(it->base, 1.0, 1.0);
491        evas_object_size_hint_align_set(it->base, -1.0, -1.0);
492         
493                 
494        if(wd->ani_it  && it == wd->ani_it)
495          {
496             evas_object_resize(it->base, w1, wd->height);
497             evas_object_size_hint_min_set(it->base, w1, wd->height);
498             evas_object_size_hint_max_set(it->base, w1, wd->height);
499          }
500        else
501          {
502             evas_object_resize(it->base, w2, wd->height);
503             evas_object_size_hint_min_set(it->base, w2, wd->height);
504             evas_object_size_hint_max_set(it->base, w2, wd->height);
505         }
506        ++i;
507     }
508
509     return;
510 }
511
512
513 static int *
514 _animator_animate_add_cb(Evas_Object *obj)
515 {
516    int w;
517    Widget_Data *wd = elm_widget_data_get(obj);
518    if (!wd) return 0;
519
520    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
521    if( w <  wd->item_width )
522      {
523          _state_value_set(obj);
524          evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
525          return (int*) ECORE_CALLBACK_RENEW;
526      }
527    else
528      {
529         ecore_animator_del(wd->ani);
530         wd->ani = NULL;
531         wd->ani_it = NULL;
532         return (int*) ECORE_CALLBACK_CANCEL;
533      }
534 }
535
536
537 static int *
538 _animator_animate_del_cb(Evas_Object *obj)
539 {
540    int w;
541    Widget_Data *wd = elm_widget_data_get(obj);
542    if (!wd) return 0;\r
543
544    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
545    if( w >  0 )
546      {
547         _state_value_set(obj);
548         evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
549         return (int*) ECORE_CALLBACK_RENEW;
550      }
551    else
552      {
553         _item_free(obj, wd->ani_it );
554         _refresh_segment_ids(obj);
555         ecore_animator_del(wd->ani);
556         wd->ani = NULL;
557         wd->ani_it = NULL;
558         _update_list(obj);
559         wd->id = eina_list_count(wd->seg_ctrl);
560         return (int*) ECORE_CALLBACK_CANCEL;
561      }
562 }
563
564 static Elm_Segment_Item *
565 _item_find(Evas_Object *obj, unsigned int index)
566 {
567    Elm_Segment_Item *it;
568    Eina_List *l;
569    int i = 0;
570    Widget_Data *wd = elm_widget_data_get(obj);
571    if (!wd) return NULL;
572
573    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
574      {
575         if (i == index) return it;
576         i++;
577      }
578      return NULL;
579 }
580
581
582 static Elm_Segment_Item *
583 _item_search(Evas_Object *obj, Elm_Segment_Item *item)
584 {
585    Elm_Segment_Item *it;
586    Eina_List *l;
587    Widget_Data *wd = elm_widget_data_get(obj);
588    if (!wd)
589    return NULL;
590
591    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
592      {
593         if (it == item) {
594            return it;
595         }
596      }
597    return NULL;
598 }
599
600
601 /**
602  * Add a new segmentcontrol to the parent
603  * @param parent The parent object
604  * @return The new object or NULL if it cannot be created
605  *
606  * @ingroup SegmentControl SegmentControl
607  */
608 EAPI Evas_Object *
609 elm_segment_control_add(Evas_Object *parent)
610 {
611    Evas_Object *obj;
612    Evas *e;
613    Widget_Data *wd;
614
615    const char *deffont, *maxheight, *wpad, *hpad;
616
617    wd = ELM_NEW(Widget_Data);
618    e = evas_object_evas_get(parent);
619    if(!e) return NULL;
620    obj = elm_widget_add(e);
621    elm_widget_type_set(obj, "segmented-control");
622    elm_widget_sub_object_add(parent, obj);
623    elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
624    elm_widget_data_set(obj, wd);
625    elm_widget_del_hook_set(obj, _del_hook);
626    elm_widget_theme_hook_set(obj, _theme_hook);
627
628    wd->base = edje_object_add(e);
629    _elm_theme_object_set(obj, wd->base, "segmented-control", "base", "default");
630    elm_widget_resize_object_set(obj, wd->base);
631    wd->box = evas_object_box_add(e);
632    evas_object_box_layout_set(wd->box, _layout, wd, NULL);
633    elm_widget_sub_object_add(obj, wd->box);
634    edje_object_part_swallow(wd->base, "elm.swallow.content", wd->box);
635    evas_object_show(wd->box);
636
637    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _object_resize, obj);
638    wd->id = 0;
639    wd->del_index = 0;
640    wd->insert_index = 0;
641    wd->cur_seg_id = -1;
642    wd->selected = EINA_FALSE;
643
644    deffont = edje_object_data_get(wd->base, "default_font_size");
645    if (deffont) wd->cur_fontsize = atoi(deffont);
646    else wd->cur_fontsize = 1;
647
648    maxheight = edje_object_data_get(wd->base, "max_height");
649    if (maxheight) wd->max_height = atoi(maxheight);
650    else wd->max_height = 1;
651
652    wpad = edje_object_data_get(wd->base, "w_pad");
653    if (wpad) wd->w_pad = atoi(wpad);
654    else wd->w_pad = 1;
655
656    hpad = edje_object_data_get(wd->base, "h_pad");
657    if (hpad) wd->h_pad = atoi(hpad);
658    else wd->h_pad = 1;
659
660    return obj;
661 }
662
663 EAPI Elm_Segment_Item *
664 elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
665 {
666    Elm_Segment_Item *it;
667    Widget_Data *wd = elm_widget_data_get(obj);
668    if(!wd) return NULL;
669
670    it = _item_new(obj, label, icon);
671    if(!it) return NULL;
672
673    wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
674    wd->id = eina_list_count(wd->seg_ctrl);
675    //_update_list(obj);
676    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
677    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
678    evas_object_event_callback_add(it->base, EVAS_CALLBACK_RESIZE, _object_item_resize, it);
679    wd->insert_index = 0;
680    wd->del_index = 0;
681    _refresh_segment_ids(obj);
682
683    if(animate && it->segment_id && wd->ani_it == NULL)
684      {
685         evas_object_resize(it->base, 1, wd->height);
686         wd->ani_it = it;
687         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
688      }
689    else
690       _state_value_set(obj);
691    evas_object_show( it->base);
692
693    evas_object_box_append(wd->box, it->base);
694    evas_object_smart_calculate(wd->box);
695
696    return it;
697 }
698
699 /**
700  * Add a new segment item to segmentcontrol
701  * @param obj The SegmentControl object
702  * @param icon The icon object for added segment item
703  * @param label The label for added segment item
704  * @param animate If 1 the action be animated with sliding effects default 0.
705  * @return The new segment item or NULL if it cannot be created
706  *
707  * @ingroup SegmentControl SegmentControl
708  */
709 EAPI Elm_Segment_Item *
710 elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
711 {
712    Elm_Segment_Item * it;
713    it = elm_segment_control_item_add(obj, icon, label, animate);
714 \r
715     return it;\r
716 }
717
718 EAPI Elm_Segment_Item *
719 elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
720 {
721    Elm_Segment_Item *it, *it_rel;
722    Widget_Data *wd = elm_widget_data_get(obj);
723    if(!wd) return NULL;
724
725    it = _item_new(obj, label, icon);
726    it_rel = _item_find(obj, index);
727    if (!it_rel)
728      {
729       wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
730      }
731    else
732      {
733         if (!it) return NULL;
734         wd->seg_ctrl = eina_list_prepend_relative(wd->seg_ctrl, it, it_rel);
735      }
736    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
737    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
738    evas_object_event_callback_add(it->base, EVAS_CALLBACK_RESIZE, _object_item_resize, it);
739    wd->insert_index = index;
740    wd->id = eina_list_count(wd->seg_ctrl);
741    _refresh_segment_ids(obj);
742
743    //_update_list(obj);
744    if(animate && it->segment_id && wd->ani_it == NULL)
745      {
746         wd->ani_it = it;
747         evas_object_resize(it->base, 1, wd->height);
748         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
749      }
750    else
751       _state_value_set(obj);
752
753    evas_object_show( it->base);
754
755    if(index >= wd->id-1)
756      {
757         evas_object_box_append(wd->box,  it->base);
758      }
759    else
760      {
761         evas_object_box_insert_at(wd->box,  it->base, index);
762      }
763
764    evas_object_smart_calculate(wd->box);
765
766    return it ;
767 }
768 /**
769  * Insert a new segment item to segmentcontrol
770  * @param obj The SegmentControl object
771  * @param icon The icon object for added segment item
772  * @param label The label for added segment item
773  * @param index The position at which segment item to be inserted
774  * @param animate If 1 the action be animated with sliding effects default 0.
775  * @return The new segment item or NULL if it cannot be created
776  *
777  * @ingroup SegmentControl SegmentControl
778  */
779 EAPI void
780 elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
781 {
782    Elm_Segment_Item *it;
783    it = elm_segment_control_item_insert_at(obj, icon, label, index, animate);
784
785    return;
786 }
787
788 EAPI void
789 elm_segment_control_item_del(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
790 {
791    Elm_Segment_Item *it;
792    Widget_Data *wd = elm_widget_data_get(obj);
793    if(!wd) return;
794
795
796 //   it = _item_search(obj, item);
797    it = item;
798    if(!it) return;
799
800    wd->del_index = it->segment_id;
801    if(animate && it->segment_id && wd->ani_it == NULL)
802      {
803         it->delete_me = EINA_TRUE;
804         wd->ani_it = it;
805         wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
806      }
807    else
808      {
809         evas_object_box_remove(wd->box, it->base);
810         evas_object_smart_calculate(wd->box);
811
812         _item_free(obj, it);
813         _refresh_segment_ids(obj);
814         _state_value_set(obj);
815         //_update_list(obj);
816      }
817    wd->id = eina_list_count(wd->seg_ctrl);
818    return;
819 }
820
821 /**
822  * Delete a segment item to segmentcontrol
823  * @param obj The SegmentControl object
824  * @param index The position at which segment item to be deleted
825  * @param animate If 1 the action be animated with sliding effects default 0.
826  *
827  * @ingroup SegmentControl SegmentControl
828  */
829 EAPI void
830 elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
831 {
832    elm_segment_control_item_del(obj, item, animate);
833
834    return;
835 }
836
837 EAPI void
838 elm_segment_control_item_del_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
839 {
840    Elm_Segment_Item *it;
841    Widget_Data *wd = elm_widget_data_get(obj);
842    if(!wd) return;
843
844    it = _item_find(obj, index);
845
846    if(!it) return;
847
848    wd->del_index = index;
849    if(animate && it->segment_id)
850      {
851         if(wd->ani_it == NULL)
852         {
853            wd->ani_it = it;
854            it->delete_me = EINA_TRUE;
855            wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
856         }
857      }
858    else
859      {
860         evas_object_box_remove(wd->box, it->base);
861         evas_object_smart_calculate(wd->box);
862         _item_free(obj, it);
863         _refresh_segment_ids(obj);
864         _state_value_set(obj);
865         //_update_list(obj);
866      }
867    wd->id = eina_list_count(wd->seg_ctrl);
868    return;
869 }
870
871 /**
872  * Delete a segment item of given index to segmentcontrol
873  * @param obj The SegmentControl object
874  * @param index The position at which segment item to be deleted
875  * @param animate If 1 the action be animated with sliding effects default 0.
876  *
877  * @ingroup SegmentControl SegmentControl
878  */
879 EAPI void
880 elm_segment_control_delete_segment_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
881 {
882    elm_segment_control_item_del_at( obj, index, animate);
883
884    return;
885 }
886
887
888 EAPI const char *
889 elm_segment_control_item_label_get(Evas_Object *obj, unsigned int index)
890 {
891    Elm_Segment_Item *it_rel;
892    Widget_Data *wd = elm_widget_data_get(obj);
893    if(!wd) return NULL;
894
895    it_rel = _item_find(obj, index);
896
897    if(it_rel) return it_rel->label;
898
899    return NULL;
900 }
901
902 /**
903  * Get the label of a segment item of segmentcontrol
904  * @param obj The SegmentControl object
905  * @param index The index of the segment item
906  * @return The label of the segment item
907  *
908  * @ingroup SegmentControl SegmentControl
909  */
910 EAPI const char *
911 elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index)
912 {
913    char *label;
914    label = elm_segment_control_item_label_get( obj, index);
915   
916    return label;
917 }
918
919 EAPI Evas_Object *
920 elm_segment_control_item_icon_get(Evas_Object *obj, unsigned int index)
921 {
922    Elm_Segment_Item *seg_rel;
923    Widget_Data *wd = elm_widget_data_get(obj);
924    if(!wd) return NULL;
925
926    seg_rel = _item_find(obj, index);
927
928    if(seg_rel) return seg_rel->icon;
929
930    return NULL;
931 }
932
933 /**
934  * Get the icon of a segment item of segmentcontrol
935  * @param obj The SegmentControl object
936  * @param index The index of the segment item
937  * @return The icon object or NULL if it is not found.
938  *
939  * @ingroup SegmentControl SegmentControl
940  */
941 EAPI Evas_Object *
942 elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index)
943 {
944    Evas_Object *icon;
945    icon = elm_segment_control_item_icon_get( obj, index);
946
947    return icon;
948 }
949
950 EAPI Elm_Segment_Item *
951 elm_segment_control_item_selected_get(const Evas_Object *obj)
952 {
953    Elm_Segment_Item *it;
954    Eina_List *l;
955    Widget_Data *wd = elm_widget_data_get(obj);
956    if(!wd || !wd->seg_ctrl) return NULL;
957
958    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
959      {
960        if(it->segment_id == wd->cur_seg_id)
961        return it;
962       }
963     return NULL;
964  }
965
966 /**
967  * Get the currently selected segment item of segmentcontrol
968  * @param obj The SegmentControl object
969  * @return The selected Segment item
970  *
971  * @ingroup SegmentControl SegmentControl
972  */
973 EAPI Elm_Segment_Item *
974 elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value)
975 {
976    Elm_Segment_Item *it;
977    it = elm_segment_control_item_selected_get( obj);
978    *value = it->segment_id;
979    \r
980     return it;
981  }
982
983
984 EAPI int
985 elm_segment_control_item_count_get(Evas_Object *obj)
986 {
987    Widget_Data *wd = elm_widget_data_get(obj);
988    if(!wd) return 0;
989
990    return wd->id;
991 }
992
993 /**
994  * Get the count of segments of segmentcontrol
995  * @param obj The SegmentControl object
996  * @return The count of Segment items
997  *
998  * @ingroup SegmentControl SegmentControl
999  */
1000 EAPI int
1001 elm_segment_control_get_segment_count(Evas_Object *obj)
1002 {
1003    int id;
1004    id = elm_segment_control_item_count_get( obj);
1005
1006    return id;
1007 }
1008
1009 /**
1010  * Get the base object of segment item in segmentcontrol
1011  * @param obj The Segment item
1012  * @return obj The base object of the segment item
1013  *
1014  * @ingroup SegmentControl SegmentControl
1015  */
1016 EAPI Evas_Object *
1017 elm_segment_control_item_object_get(Elm_Segment_Item *it)
1018 {
1019    if (!it) return NULL;
1020    
1021    return it->base;
1022 }
1023
1024 /**
1025  * Select/unselect a particular segment item of segmentcontrol
1026  * @param item The Segment item that is to be selected or unselected.
1027  * @param select If 1 the segment item is selected and if 0 it will be unselected.
1028  *
1029  * @ingroup SegmentControl SegmentControl
1030  */
1031 EAPI void
1032 elm_segment_control_item_selected_set( Elm_Segment_Item *item, Eina_Bool select)
1033 {
1034    if(!item) return;
1035    Widget_Data *wd = elm_widget_data_get(item->obj);
1036    if(!wd) return;
1037
1038    if(select)
1039      {
1040       if(item->segment_id == wd->cur_seg_id) return;
1041       wd->selected = EINA_TRUE;
1042       if(wd->data)
1043         {       
1044            evas_object_del((Evas_Object *)wd->data);
1045            wd->data = NULL;
1046         }
1047       wd->data = item;
1048
1049       }
1050    else if(item->segment_id == wd->cur_seg_id)
1051       {
1052        wd->selected = EINA_FALSE;
1053        wd->cur_seg_id = -1;
1054        _signal_segment_off(item); 
1055       } 
1056
1057    return;
1058
1059 }
1060
1061 /**
1062  * Get a particular indexed segment item of segmentcontrol
1063  * @param obj The Segment control object.
1064  * @param index The index of the segment item.
1065  * @return The corresponding Segment item.
1066  *
1067  * @ingroup SegmentControl SegmentControl
1068  */
1069 EAPI Elm_Segment_Item *
1070 elm_segment_control_item_get_at(Evas_Object *obj, unsigned int index)
1071 {
1072    Elm_Segment_Item *it;
1073    it = _item_find(obj, index);
1074
1075    return it;
1076 }
1077 \r
1078 /**
1079  * Get the index of a Segment item of Segmentcontrol
1080  * @param item The Segment item.
1081  * @return The corresponding index of the Segment item.
1082  *
1083  * @ingroup SegmentControl SegmentControl
1084  */
1085 EAPI int
1086 elm_segment_control_item_index_get(Elm_Segment_Item *item)
1087 {
1088    if(!item) return -1;
1089    Widget_Data *wd = elm_widget_data_get(item->obj);
1090    if(!wd) return -1;
1091
1092    return item->segment_id;
1093 }
1094
1095 /**
1096  * Set The Label widget to a Segment item of Segmentcontrol
1097  * @param item The Segment item.
1098  * @param label The Label.
1099  * @return Evas_Object The Label widget.
1100  *
1101  * @ingroup SegmentControl SegmentControl
1102  */
1103 EAPI Evas_Object *
1104 elm_segment_control_item_label_object_set(Elm_Segment_Item *item, char *label)
1105 {
1106    if(!item) return NULL;
1107    Widget_Data *wd = elm_widget_data_get(item->obj);
1108    if(!wd) return NULL;
1109    if(!label) return NULL;
1110
1111    item->label_wd = elm_label_add(item->obj);   
1112    elm_label_label_set(item->label_wd, label);
1113    elm_label_text_align_set(item->label_wd, "middle");
1114    elm_label_ellipsis_set(item->label_wd, 1);
1115    elm_label_line_wrap_set(item->label_wd, 1);
1116    eina_stringshare_replace(&item->label, label);
1117
1118    return item->label_wd;
1119 }
1120