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