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