Merge branch 'master' of 165.213.180.234:/git/slp/pkgs/elementary
[framework/uifw/elementary.git] / src / lib / elm_segment_control.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup SegmentControl SegmentControl
6  * @ingroup Elementary
7  *
8  * SegmentControl object is a horizontal control made of multiple segments,
9  * each segment 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;
267    const char *minfont, *deffont, *maxfont, *maxheight;
268    int minfontsize, maxfontsize, cur_fontsize = 0, max_height = 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
285    maxheight = edje_object_data_get(wd->base, "max_height");
286    if (maxheight) max_height = atoi(maxheight);
287    else max_height = h;
288
289    if(it->label_wd) 
290      {
291         elm_label_fontsize_set(it->label_wd, cur_fontsize);
292         elm_label_wrap_width_set(it->label_wd, w-4);
293         elm_label_wrap_height_set(it->label_wd, max_height-6);
294         elm_label_text_color_set(it->label_wd, 0xFF,0xFF, 0xFF, 0xff);
295         if (edje_object_part_swallow_get(it->base, "elm.swallow.label.content") == NULL)
296           {
297              edje_object_part_unswallow(it->base, it->label_wd);
298           }
299         edje_object_part_swallow(it->base, "elm.swallow.label.content", it->label_wd);
300         edje_object_signal_emit(it->base, "elm,state,label,visible", "elm");
301      }
302 }
303
304 static void 
305 _object_item_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
306 {
307    ecore_job_add(_segment_item_resizing, (Evas_Object *)data);
308 }
309
310 static Elm_Segment_Item*
311 _item_new(Evas_Object *obj, const char *label, Evas_Object *icon)
312 {
313    Elm_Segment_Item *it; 
314    Evas_Coord mw, mh; 
315    Widget_Data *wd = elm_widget_data_get(obj);
316    if (!wd) return NULL;
317
318    it = calloc(1, sizeof(   Elm_Segment_Item));
319    if (!it) return NULL;
320
321    if(obj) it->obj = obj;
322    it->delete_me = EINA_FALSE;
323    it->segment_id = wd->id;
324    it->label_wd = NULL;
325
326    it->base = edje_object_add(evas_object_evas_get(obj));
327    _elm_theme_object_set(obj, it->base, "segment", "base", elm_object_style_get(it->base));
328
329    if (it->label) eina_stringshare_del(it->label);
330    if (label)
331      {
332         it->label = eina_stringshare_add(label);
333      }
334    else
335      {
336          it->label = NULL;
337      }
338    if ((it->icon != icon) && (it->icon))
339       elm_widget_sub_object_del(obj, it->icon);
340    it->icon = icon;
341    if (icon)
342      {
343         elm_widget_sub_object_add(obj, icon);
344         Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
345         elm_coords_finger_size_adjust(1, &minw, 1, &minh);
346         elm_coords_finger_size_adjust(1, &minw, 1, &minh);
347
348         evas_object_size_hint_weight_set(it->base, 1.0, -1.0);
349         evas_object_size_hint_align_set(it->base, 1.0, -1.0);
350         evas_object_size_hint_min_set(it->base, -1, -1);
351         evas_object_size_hint_max_set(it->base, maxw, maxh);
352      }
353
354    edje_object_size_min_restricted_calc(obj, &mw, &mh, 0, 0);
355    evas_object_size_hint_weight_set(obj, 1.0, 1.0);
356    evas_object_size_hint_align_set(obj, -1.0, -1.0);
357
358    return it;
359 }
360
361
362 static void 
363 _update_list(Evas_Object *obj)
364 {
365    Elm_Segment_Item *it;
366    Eina_List *l;
367    int i = 0;
368  
369    Widget_Data *wd = elm_widget_data_get(obj);
370    if (!wd) return;
371
372    wd->count = eina_list_count(wd->seg_ctrl);
373    if(wd->count == 1)
374      {
375         it = _item_find(obj, 0);
376         _elm_theme_object_set(obj, it->base, "segment", "base", "single");\r
377         edje_object_signal_emit(it->base, "elm,state,segment,on", "elm");
378         if(!it->label_wd)
379           {
380              edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
381              edje_object_signal_emit(it->base, "elm,state,text,change", "elm");
382           }
383         edje_object_message_signal_process(it->base);
384
385         if(it->label)
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         return;
392      }
393
394    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
395      {
396         if(i==0)
397           {
398              _elm_theme_object_set(obj, it->base, "segment", "base", "first");
399           }
400         else if(i==wd->count-1)
401           {
402              _elm_theme_object_set(obj, it->base, "segment", "base", "last");
403           }
404         else
405           {
406              _elm_theme_object_set(obj, it->base, "segment", "base", "default");
407
408           }
409           
410         if(!it->label_wd)
411           {
412              edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
413           }
414         edje_object_message_signal_process(it->base);
415
416         if(it->label)
417           edje_object_part_text_set(it->base, "elm.text", it->label);
418
419         edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
420         edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
421
422         i++;
423      }
424 }
425
426
427 static void 
428 _refresh_segment_ids(Evas_Object *obj)
429 {
430    Elm_Segment_Item *it;
431    Eina_List *l;
432    int i = 0;
433    Widget_Data *wd = elm_widget_data_get(obj);
434    if (!wd) return;
435  
436    if (wd->insert_index && wd->cur_seg_id >= wd->insert_index)
437      {
438         ++wd->cur_seg_id;
439         wd->insert_index = 0;
440      }
441    if (wd->del_index)
442      {
443         if (wd->cur_seg_id >= wd->del_index)
444            --wd->cur_seg_id;
445         wd->del_index =0;
446      }
447
448    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
449      {
450         it->segment_id = i;
451         i++;
452      }
453 }
454
455 static void 
456 _state_value_set(Evas_Object *obj)
457 {
458    Elm_Segment_Item *it;
459    Eina_List *l;
460    Evas_Coord mw, mh, x, y, w, h, xx = 0, yy;
461
462    int w1=0, w2, i=0;
463    unsigned int count ;
464    Widget_Data *wd = elm_widget_data_get(obj);
465    if (!wd) return;
466    
467    count = eina_list_count(wd->seg_ctrl);
468    if (count > 0)
469      wd->item_width = wd->width/count;
470    if (wd->ani_it)
471      {
472         evas_object_geometry_get(wd->ani_it->base, &x, &y, &w1, NULL);
473         if (wd->ani_it->delete_me)
474           {
475              w1-=(wd->item_width/5);
476              if( w1< 0) w1 = 0;
477           }
478         else
479         {
480            w1+=(wd->item_width/5);
481            if( w1 > wd->item_width )
482               w1 = wd->item_width;
483         }
484         w2 = (wd->width-w1)/(count -1);
485      }
486    else
487       w2 = wd->item_width;
488           
489    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
490     {
491        edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0);
492        evas_object_size_hint_weight_set(it->base, 1.0, 1.0);
493        evas_object_size_hint_align_set(it->base, -1.0, -1.0);
494            evas_object_geometry_get(wd->base, &x, &y, &w, &h);
495         
496            if(xx == 0)
497                 xx = 16;
498                 if(yy == 0)
499                 yy= 137;
500                 
501        if(wd->ani_it  && it == wd->ani_it)
502          {
503             evas_object_resize(it->base, w1, wd->height);
504             evas_object_size_hint_min_set(it->base, w1, wd->height);
505             evas_object_size_hint_max_set(it->base, w1, wd->height);
506 #if 0
507             evas_object_move(it->base, xx, yy);
508             xx+=w1;
509 #endif      
510          }
511        else
512          {
513             evas_object_resize(it->base, w2, wd->height);
514             evas_object_size_hint_min_set(it->base, w2, wd->height);
515             evas_object_size_hint_max_set(it->base, w2, wd->height);
516 #if 0
517             evas_object_move(it->base, xx, yy);
518             xx+=w2;
519 #endif      
520         }
521        ++i;
522     }
523
524     return;
525 }
526
527
528 static int *
529 _animator_animate_add_cb(Evas_Object *obj)
530 {
531    int w;
532    Widget_Data *wd = elm_widget_data_get(obj);
533    if (!wd) return 0;
534
535    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
536    if( w <  wd->item_width )
537      {
538          _state_value_set(obj);
539          evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
540          return ECORE_CALLBACK_RENEW;
541      }
542    else
543      {
544         ecore_animator_del(wd->ani);
545         wd->ani = NULL;
546         wd->ani_it = NULL;
547         return ECORE_CALLBACK_CANCEL;
548      }
549 }
550
551
552 static int *
553 _animator_animate_del_cb(Evas_Object *obj)
554 {
555    int w;
556    Widget_Data *wd = elm_widget_data_get(obj);
557    if (!wd) return 0;\r
558
559    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
560    if( w >  0 )
561      {
562         _state_value_set(obj);
563         evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
564         return ECORE_CALLBACK_RENEW;
565      }
566    else
567      {
568         _item_free(obj, wd->ani_it );
569         _refresh_segment_ids(obj);
570         ecore_animator_del(wd->ani);
571         wd->ani = NULL;
572         wd->ani_it = NULL;
573         _update_list(obj);
574         wd->id = eina_list_count(wd->seg_ctrl);
575         return ECORE_CALLBACK_CANCEL;
576      }
577 }
578
579 static Elm_Segment_Item *
580 _item_find(Evas_Object *obj, unsigned int index)
581 {
582    Elm_Segment_Item *it;
583    Eina_List *l;
584    int i = 0;
585    Widget_Data *wd = elm_widget_data_get(obj);
586    if (!wd) return NULL;
587
588    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
589      {
590         if (i == index) return it;
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    Elm_Segment_Item *it;
601    Eina_List *l;
602    Widget_Data *wd = elm_widget_data_get(obj);
603    if (!wd)
604    return NULL;
605
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 /**
617  * Add a new segmentcontrol to the parent
618  * @param parent The parent object
619  * @return The new object or NULL if it cannot be created
620  *
621  * @ingroup SegmentControl SegmentControl
622  */
623 EAPI Evas_Object *
624 elm_segment_control_add(Evas_Object *parent)
625 {
626    Evas_Object *obj;
627    Evas *e;
628    Widget_Data *wd;
629
630    wd = ELM_NEW(Widget_Data);
631    e = evas_object_evas_get(parent);
632    if(!e) return NULL;
633    obj = elm_widget_add(e);
634    elm_widget_type_set(obj, "segmented-control");
635    elm_widget_sub_object_add(parent, obj);
636    elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
637    elm_widget_data_set(obj, wd);
638    elm_widget_del_hook_set(obj, _del_hook);
639    elm_widget_theme_hook_set(obj, _theme_hook);
640
641    wd->base = edje_object_add(e);
642    _elm_theme_object_set(obj, wd->base, "segmented-control", "base", "default");
643    elm_widget_resize_object_set(obj, wd->base);
644    wd->box = evas_object_box_add(e);
645    evas_object_box_layout_set(wd->box, _layout, wd, NULL);
646    elm_widget_sub_object_add(obj, wd->box);
647    edje_object_part_swallow(wd->base, "elm.swallow.content", wd->box);
648    evas_object_show(wd->box);
649 #if 0   
650    wd->box = elm_layout_add(e);
651    elm_layout_theme_set(wd->box, "segmented-control", "base", "default");
652    edje_object_part_swallow(wd->base, "elm.swallow.content", wd->box);
653    evas_object_show(wd->box);
654 #endif   
655
656    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _object_resize, obj);
657    wd->id = 0;
658    wd->del_index = 0;
659    wd->insert_index = 0;
660    wd->cur_seg_id = -1;
661    wd->selected = EINA_FALSE;
662
663    return obj;
664 }
665
666 /**
667  * Add a new segment item to segmentcontrol
668  * @param obj The SegmentControl object
669  * @param icon The icon object for added segment item
670  * @param label The label for added segment item 
671  * @param animate If 1 the action be animated with sliding effects default 0.
672  * @return The new segment item or NULL if it cannot be created
673  *
674  * @ingroup SegmentControl SegmentControl
675  */
676
677 EAPI Elm_Segment_Item *
678 elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
679 {
680    Elm_Segment_Item *it;
681    Widget_Data *wd = elm_widget_data_get(obj);
682    if(!wd) return NULL;
683
684    it = _item_new(obj, label, icon);
685    if(!it) return NULL;
686
687    wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
688    wd->id = eina_list_count(wd->seg_ctrl);
689    //_update_list(obj);
690    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
691    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
692    evas_object_event_callback_add(it->base, EVAS_CALLBACK_RESIZE, _object_item_resize, it);
693    wd->insert_index = 0;
694    wd->del_index = 0;
695    _refresh_segment_ids(obj);
696
697    if(animate && it->segment_id && wd->ani_it == NULL)
698      {
699         evas_object_resize(it->base, 1, wd->height);
700         wd->ani_it = it;
701         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
702      }
703    else
704       _state_value_set(obj);
705    evas_object_show( it->base);
706
707    evas_object_box_append(wd->box, it->base);
708 #if 0
709    elm_layout_content_set(wd->box,  "elm.swallow.content",  it->base);
710 #endif   
711    evas_object_smart_calculate(wd->box);
712
713    return it;
714 }
715
716 /**
717  * Add a new segment item to segmentcontrol
718  * @param obj The SegmentControl object
719  * @param icon The icon object for added segment item
720  * @param label The label for added segment item 
721  * @param animate If 1 the action be animated with sliding effects default 0.
722  * @return The new segment item or NULL if it cannot be created
723  *
724  * @ingroup SegmentControl SegmentControl
725  */
726
727 EAPI Elm_Segment_Item *
728 elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
729 {
730    EAPI Elm_Segment_Item * it;
731    it = elm_segment_control_item_add(obj, icon, label, animate);
732 \r
733     return it;\r
734 }
735
736 /**
737  * Insert a new segment item to segmentcontrol
738  * @param obj The SegmentControl object
739  * @param icon The icon object for added segment item
740  * @param label The label for added segment item
741  * @param index The position at which segment item to be inserted
742  * @param animate If 1 the action be animated with sliding effects default 0.
743  * @return The new segment item or NULL if it cannot be created
744  *
745  * @ingroup SegmentControl SegmentControl
746  */
747
748 EAPI Elm_Segment_Item *
749 elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
750 {
751    Elm_Segment_Item *it, *it_rel;
752    Widget_Data *wd = elm_widget_data_get(obj);
753    if(!wd) return NULL;
754
755    it = _item_new(obj, label, icon);
756    it_rel = _item_find(obj, index);
757    if (!it_rel)
758      {
759       wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
760      }
761    else
762      {
763         if (!it) return NULL;
764         wd->seg_ctrl = eina_list_prepend_relative(wd->seg_ctrl, it, it_rel);
765      }
766    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
767    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
768    evas_object_event_callback_add(it->base, EVAS_CALLBACK_RESIZE, _object_item_resize, it);
769    wd->insert_index = index;
770    wd->id = eina_list_count(wd->seg_ctrl);
771    _refresh_segment_ids(obj);
772
773    //_update_list(obj);
774    if(animate && it->segment_id && wd->ani_it == NULL)
775      {
776         wd->ani_it = it;
777         evas_object_resize(it->base, 1, wd->height);
778         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
779      }
780    else
781       _state_value_set(obj);
782
783    evas_object_show( it->base);
784
785    if(index >= wd->id-1)
786      {
787         evas_object_box_append(wd->box,  it->base);
788      }
789    else
790      {
791         evas_object_box_insert_at(wd->box,  it->base, index);
792      }
793
794    evas_object_smart_calculate(wd->box);
795
796    return it ;
797 }
798
799 /**
800  * Insert a new segment item to segmentcontrol
801  * @param obj The SegmentControl object
802  * @param icon The icon object for added segment item
803  * @param label The label for added segment item
804  * @param index The position at which segment item to be inserted
805  * @param animate If 1 the action be animated with sliding effects default 0.
806  *
807  * @ingroup SegmentControl SegmentControl
808  */
809
810 EAPI void
811 elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
812 {
813    Elm_Segment_Item *it;
814    it = elm_segment_control_item_insert_at(obj, icon, label, index, animate);
815
816    return;
817 }
818
819 /**
820  * Delete a segment item to segmentcontrol
821  * @param obj The SegmentControl object
822  * @param item The Segment item to be deleted
823  * @param animate If 1 the action be animated with sliding effects default 0.
824  *
825  * @ingroup SegmentControl SegmentControl
826  */
827 EAPI void
828 elm_segment_control_item_del(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
829 {
830    Elm_Segment_Item *it;
831    Widget_Data *wd = elm_widget_data_get(obj);
832    if(!wd) return;
833
834    if(!item) return;
835
836    it = _item_search(obj, item);
837    if(!it) return;
838
839    wd->del_index = it->segment_id;
840    if(animate && it->segment_id && wd->ani_it == NULL)
841      {
842         it->delete_me = EINA_TRUE;
843         wd->ani_it = it;
844         wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
845      }
846    else
847      {
848         evas_object_box_remove(wd->box, it->base);
849         evas_object_smart_calculate(wd->box);
850 #if 0
851          elm_layout_content_unset(wd->box, "elm.swallow.content");
852 #endif
853         _item_free(obj, it);
854         _refresh_segment_ids(obj);
855         _state_value_set(obj);
856         //_update_list(obj);
857      }
858    wd->id = eina_list_count(wd->seg_ctrl);
859    return;
860 }
861
862 /**
863  * Delete a segment item to segmentcontrol
864  * @param obj The SegmentControl object
865  * @param item The Segment item to be deleted
866  * @param animate If 1 the action be animated with sliding effects default 0.
867  *
868  * @ingroup SegmentControl SegmentControl
869  */
870
871 EAPI void
872 elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
873 {
874    elm_segment_control_item_del(obj, item, animate);
875
876    return;
877 }
878
879 /**
880  * Delete a segment item to segmentcontrol
881  * @param obj The SegmentControl object
882  * @param index The position at which segment item to be deleted
883  * @param animate If 1 the action be animated with sliding effects default 0.
884  *
885  * @ingroup SegmentControl SegmentControl
886  */
887
888 EAPI void
889 elm_segment_control_item_del_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
890 {
891    Elm_Segment_Item *it;
892    Widget_Data *wd = elm_widget_data_get(obj);
893    if(!wd) return;
894
895    it = _item_find(obj, index);
896
897    if(!it) return;
898
899    wd->del_index = index;
900    if(animate && it->segment_id)
901      {
902         if(wd->ani_it == NULL)
903         {
904            wd->ani_it = it;
905            it->delete_me = EINA_TRUE;
906            wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
907         }
908      }
909    else
910      {
911         evas_object_box_remove(wd->box, it->base);
912         evas_object_smart_calculate(wd->box);
913         _item_free(obj, it);
914         _refresh_segment_ids(obj);
915         _state_value_set(obj);
916         //_update_list(obj);
917      }
918    wd->id = eina_list_count(wd->seg_ctrl);
919    return;
920 }
921
922 /**
923  * Delete a segment item to segmentcontrol
924  * @param obj The SegmentControl object
925  * @param index The position at which segment item to be deleted
926  * @param animate If 1 the action be animated with sliding effects default 0.
927  *
928  * @ingroup SegmentControl SegmentControl
929  */
930
931 EAPI void
932 elm_segment_control_delete_segment_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
933 {
934    elm_segment_control_item_del_at( obj, index, animate);
935
936    return;
937 }
938
939 /**
940  * Get the label of a segment item of segmentcontrol
941  * @param obj The SegmentControl object
942  * @param index The index of the segment item
943  * @return The label of the segment item
944  *
945  * @ingroup SegmentControl SegmentControl
946  */
947
948 EAPI const char *
949 elm_segment_control_item_label_get(Evas_Object *obj, unsigned int index)
950 {
951    Elm_Segment_Item *it_rel;
952    Widget_Data *wd = elm_widget_data_get(obj);
953    if(!wd) return NULL;
954
955    it_rel = _item_find(obj, index);
956
957    if(it_rel) return it_rel->label;
958
959    return NULL;
960 }
961
962 /**
963  * Get the label of a segment item of segmentcontrol
964  * @param obj The SegmentControl object
965  * @param index The index of the segment item
966  * @return The label of the segment item
967  *
968  * @ingroup SegmentControl SegmentControl
969  */
970
971 EAPI const char *
972 elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index)
973 {
974    char *label;
975    label = elm_segment_control_item_label_get( obj, index);
976   
977    return label;
978 }
979
980 /**
981  * Get the icon of a segment item of segmentcontrol
982  * @param obj The SegmentControl object
983  * @param index The index of the segment item
984  * @return The icon object or NULL if it is not found.
985  *
986  * @ingroup SegmentControl SegmentControl
987  */
988
989 EAPI Evas_Object *
990 elm_segment_control_item_icon_get(Evas_Object *obj, unsigned int index)
991 {
992    Elm_Segment_Item *seg_rel;
993    Widget_Data *wd = elm_widget_data_get(obj);
994    if(!wd) return NULL;
995
996    seg_rel = _item_find(obj, index);
997
998    if(seg_rel) return seg_rel->icon;
999
1000    return NULL;
1001 }
1002
1003 /**
1004  * Get the icon of a segment item of segmentcontrol
1005  * @param obj The SegmentControl object
1006  * @param index The index of the segment item
1007  * @return The icon object or NULL if it is not found.
1008  *
1009  * @ingroup SegmentControl SegmentControl
1010  */
1011
1012 EAPI Evas_Object *
1013 elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index)
1014 {
1015    Evas_Object *icon;
1016    icon = elm_segment_control_item_icon_get( obj, index);
1017
1018    return icon;
1019 }
1020
1021 /**
1022  * Get the currently selected segment item of segmentcontrol
1023  * @param obj The SegmentControl object
1024  * @return The selected Segment item
1025  *
1026  * @ingroup SegmentControl SegmentControl
1027  */
1028
1029 EAPI Elm_Segment_Item *
1030 elm_segment_control_item_selected_get(const Evas_Object *obj)
1031 {
1032    Elm_Segment_Item *it;
1033    Eina_List *l;
1034    Widget_Data *wd = elm_widget_data_get(obj);
1035    if(!wd || !wd->seg_ctrl) return NULL;
1036
1037    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
1038      {
1039        if(it->segment_id == wd->cur_seg_id)
1040        return it;
1041       }
1042     return NULL;
1043  }
1044
1045 /**
1046  * Get the currently selected segment item of segmentcontrol
1047  * @param obj The SegmentControl object
1048  * @param value The current segment item id
1049  * @return The selected Segment item
1050  *
1051  * @ingroup SegmentControl SegmentControl
1052  */
1053
1054 EAPI Elm_Segment_Item *
1055 elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value)
1056 {
1057    Elm_Segment_Item *it;
1058    it = elm_segment_control_item_selected_get( obj);
1059    *value = it->segment_id;
1060    \r
1061     return it;
1062  }
1063
1064 /**
1065  * Get the count of segments of segmentcontrol
1066  * @param obj The SegmentControl object
1067  * @return The count of Segment items
1068  *
1069  * @ingroup SegmentControl SegmentControl
1070  */
1071
1072 EAPI int
1073 elm_segment_control_item_count_get(Evas_Object *obj)
1074 {
1075    Widget_Data *wd = elm_widget_data_get(obj);
1076    if(!wd) return 0;
1077
1078    return wd->id;
1079 }
1080
1081 /**
1082  * Get the count of segments of segmentcontrol
1083  * @param obj The SegmentControl object
1084  * @return The count of Segment items
1085  *
1086  * @ingroup SegmentControl SegmentControl
1087  */
1088
1089 EAPI int
1090 elm_segment_control_get_segment_count(Evas_Object *obj)
1091 {
1092    int id;
1093    id = elm_segment_control_item_count_get( obj);
1094
1095    return id;
1096 }
1097
1098 /**
1099  * Get the base object of segment item in segmentcontrol
1100  * @param obj The Segment item
1101  * @return obj The base object of the segment item
1102  *
1103  * @ingroup SegmentControl SegmentControl
1104  */
1105
1106 EAPI Evas_Object *
1107 elm_segment_control_item_object_get(Elm_Segment_Item *it)
1108 {
1109    if (!it) return NULL;
1110    
1111    return it->base;
1112 }
1113
1114 /**
1115  * Select/unselect a particular segment item of segmentcontrol
1116  * @param item The Segment item that is to be selected or unselected.
1117  * @param select If 1 the segment item is selected and if 0 it will be unselected.
1118  *
1119  * @ingroup SegmentControl SegmentControl
1120  */
1121
1122 EAPI void
1123 elm_segment_control_item_selected_set( Elm_Segment_Item *item, Eina_Bool select)
1124 {
1125    if(!item) return;
1126    Widget_Data *wd = elm_widget_data_get(item->obj);
1127    if(!wd) return;
1128
1129    if(select)
1130      {
1131       if(item->segment_id == wd->cur_seg_id) return;
1132         
1133       if(!item->label_wd)
1134         {       
1135            edje_object_signal_emit(item->base, "elm,action,focus", "elm");
1136            edje_object_signal_emit(item->base, "elm,state,text,visible", "elm");
1137         }
1138       _signal_segment_on(item);
1139
1140       }
1141    else if(item->segment_id == wd->cur_seg_id)
1142       {
1143        wd->selected = EINA_FALSE;
1144        wd->cur_seg_id = -1;
1145        _signal_segment_off(item); 
1146       } 
1147
1148    return;
1149
1150 }
1151
1152 /**
1153  * Get a particular indexed segment item of segmentcontrol
1154  * @param obj The Segment control object.
1155  * @param index The index of the segment item.
1156  * @return The corresponding Segment item.
1157  *
1158  * @ingroup SegmentControl SegmentControl
1159  */
1160
1161 EAPI Elm_Segment_Item *
1162 elm_segment_control_item_get_at(Evas_Object *obj, unsigned int index)
1163 {
1164    Elm_Segment_Item *it;
1165    it = _item_find(obj, index);
1166
1167    return it;
1168 }
1169 \r
1170 /**
1171  * Get the index of a Segment item of Segmentcontrol
1172  * @param item The Segment item.
1173  * @return The corresponding index of the Segment item.
1174  *
1175  * @ingroup SegmentControl SegmentControl
1176  */
1177
1178 EAPI int
1179 elm_segment_control_item_index_get(Elm_Segment_Item *item)
1180 {
1181    if(!item) return -1;
1182    Widget_Data *wd = elm_widget_data_get(item->obj);
1183    if(!wd) return NULL;
1184
1185    return item->segment_id;
1186 }
1187
1188 /**
1189  * Set The Label widget to a Segment item of Segmentcontrol
1190  * @param item The Segment item.
1191  * @param label The Label.
1192  * @return Evas_Object The Label widget.
1193  *
1194  * @ingroup SegmentControl SegmentControl
1195  */
1196
1197 EAPI Evas_Object *
1198 elm_segment_control_item_label_object_set(Elm_Segment_Item *item, char *label)
1199 {
1200    if(!item) return NULL;
1201    Widget_Data *wd = elm_widget_data_get(item->obj);
1202    if(!wd) return NULL;
1203    if(!label) return NULL;
1204
1205    item->label_wd = elm_label_add(item->obj);   
1206    elm_label_label_set(item->label_wd, label);
1207    elm_label_text_align_set(item->label_wd, "middle");
1208    elm_label_ellipsis_set(item->label_wd, 1);
1209    elm_label_line_wrap_set(item->label_wd, 1);
1210    eina_stringshare_replace(&item->label, label);
1211
1212    return item->label_wd;
1213 }
1214