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