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