[SegmentControl] When selected segment deleted then selection shifted to other segment.
[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         if(it->label_wd)
385           {
386              edje_object_signal_emit(it->base, "elm,state,label,visible", "elm");
387              elm_label_text_color_set(it->label_wd, 0x00,0x00, 0x00, 0xff);
388           }
389
390         return;
391      }
392
393    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
394      {
395         if(i==0)
396           {
397              _elm_theme_object_set(obj, it->base, "segment", "base/first", elm_object_style_get(it->obj));
398           }
399         else if(i==wd->count-1)
400           {
401              _elm_theme_object_set(obj, it->base, "segment", "base/last", elm_object_style_get(it->obj));
402           }
403         else
404           {
405              _elm_theme_object_set(obj, it->base, "segment", "base/default", elm_object_style_get(it->obj));
406
407           }
408           
409         if(it->label && !it->label_wd)
410           {
411              edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
412              edje_object_part_text_set(it->base, "elm.text", it->label);
413           }
414         else
415            edje_object_signal_emit(it->base, "elm,state,text,hidden", "elm");
416
417         if (it->icon && edje_object_part_swallow_get(it->base, "elm.swallow.content") == NULL)
418           {
419              if(it->icon)
420                {
421                   edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
422                   edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
423                }
424              else
425                 edje_object_signal_emit(it->base, "elm,state,icon,hidden", "elm");
426           }
427         if(it->label_wd)
428           {
429              edje_object_signal_emit(it->base, "elm,state,label,visible", "elm");
430           }
431         if(it->sel)
432            _signal_segment_on((void*)it);
433
434         i++;
435      }
436
437      i = 0;
438      EINA_LIST_FOREACH(wd->seg_ctrl, l, seg_it)
439        {
440           if(wd->del_index == 0)
441             {
442               if (i == 0)
443                 {
444                    next_sel_it = seg_it;
445                    _signal_segment_on((void*)next_sel_it);
446                    break;
447                 }
448             }
449           else
450             {
451                if (i == wd->del_index-1)
452                   next_sel_it = seg_it;
453                if (i == wd->del_index)
454                  {
455                     del_it = seg_it;
456                     break;
457                  }
458              }
459           i++;
460        }
461      if(next_sel_it && del_it && del_it->sel)
462         _signal_segment_on((void*)next_sel_it);
463 }
464
465
466 static void 
467 _refresh_segment_ids(Evas_Object *obj)
468 {
469    Elm_Segment_Item *it;
470    Eina_List *l;
471    int i = 0;
472    Widget_Data *wd = elm_widget_data_get(obj);
473    if (!wd) return;
474
475    if ((wd->insert_index > 0) && wd->cur_seg_id >= wd->insert_index)
476      {
477         ++wd->cur_seg_id;
478         wd->insert_index = 0;
479      }
480    if (wd->del_index > 0)
481      {
482         if (wd->cur_seg_id >= wd->del_index)
483            --wd->cur_seg_id;
484         wd->del_index = -1;
485      }
486
487    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
488      {
489         it->segment_id = i;
490         i++;
491      }
492 }
493
494 static void 
495 _state_value_set(Evas_Object *obj)
496 {
497    Elm_Segment_Item *it;
498    Eina_List *l;
499    Evas_Coord mw, mh, x, y;
500
501    int w1=0, w2, i=0;
502    unsigned int count ;
503    Widget_Data *wd = elm_widget_data_get(obj);
504    if (!wd) return;
505    
506    count = eina_list_count(wd->seg_ctrl);
507    if (count > 0)
508      wd->item_width = wd->width/count;
509    if (wd->ani_it)
510      {
511         evas_object_geometry_get(wd->ani_it->base, &x, &y, &w1, NULL);
512         if (wd->ani_it->delete_me)
513           {
514              w1-=(wd->item_width/5);
515              if( w1< 0) w1 = 0;
516           }
517         else
518         {
519            w1+=(wd->item_width/5);
520            if( w1 > wd->item_width )
521               w1 = wd->item_width;
522         }
523         w2 = (wd->width-w1)/(count -1);
524      }
525    else
526       w2 = wd->item_width;
527           
528    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
529     {
530        edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0);
531        evas_object_size_hint_weight_set(it->base, 1.0, 1.0);
532        evas_object_size_hint_align_set(it->base, -1.0, -1.0);
533         
534                 
535        if(wd->ani_it  && it == wd->ani_it)
536          {
537             evas_object_resize(it->base, w1, wd->height);
538             evas_object_size_hint_min_set(it->base, w1, wd->height);
539             evas_object_size_hint_max_set(it->base, w1, wd->height);
540          }
541        else
542          {
543             evas_object_resize(it->base, w2, wd->height);
544             evas_object_size_hint_min_set(it->base, w2, wd->height);
545             evas_object_size_hint_max_set(it->base, w2, wd->height);
546         }
547        ++i;
548     }
549
550     return;
551 }
552
553
554 static int *
555 _animator_animate_add_cb(Evas_Object *obj)
556 {
557    int w;
558    Widget_Data *wd = elm_widget_data_get(obj);
559    if (!wd) return 0;
560
561    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
562    if( w <  wd->item_width )
563      {
564          _state_value_set(obj);
565          evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
566          return (int*) ECORE_CALLBACK_RENEW;
567      }
568    else
569      {
570         ecore_animator_del(wd->ani);
571         wd->ani = NULL;
572         wd->ani_it = NULL;
573         return (int*) ECORE_CALLBACK_CANCEL;
574      }
575 }
576
577
578 static int *
579 _animator_animate_del_cb(Evas_Object *obj)
580 {
581    int w;
582    Widget_Data *wd = elm_widget_data_get(obj);
583    if (!wd) return 0;\r
584
585    evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
586    if( w >  0 )
587      {
588         _state_value_set(obj);
589         evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
590         return (int*) ECORE_CALLBACK_RENEW;
591      }
592    else
593      {
594         _item_free(obj, wd->ani_it );
595         _refresh_segment_ids(obj);
596         ecore_animator_del(wd->ani);
597         wd->ani = NULL;
598         wd->ani_it = NULL;
599         _update_list(obj);
600         wd->id = eina_list_count(wd->seg_ctrl);
601         return (int*) ECORE_CALLBACK_CANCEL;
602      }
603 }
604
605 static Elm_Segment_Item *
606 _item_find(Evas_Object *obj, unsigned int index)
607 {
608    Elm_Segment_Item *it;
609    Eina_List *l;
610    int i = 0;
611    Widget_Data *wd = elm_widget_data_get(obj);
612    if (!wd) return NULL;
613
614    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
615      {
616         if (i == index) return it;
617         i++;
618      }
619      return NULL;
620 }
621
622 /**
623  * Add a new segmentcontrol to the parent
624  * @param parent The parent object
625  * @return The new object or NULL if it cannot be created
626  *
627  * @ingroup SegmentControl SegmentControl
628  */
629 EAPI Evas_Object *
630 elm_segment_control_add(Evas_Object *parent)
631 {
632    Evas_Object *obj;
633    Evas *e;
634    Widget_Data *wd;
635
636    const char *deffont, *maxheight, *wpad, *hpad;
637
638    wd = ELM_NEW(Widget_Data);
639    e = evas_object_evas_get(parent);
640    if(!e) return NULL;
641    obj = elm_widget_add(e);
642    elm_widget_type_set(obj, "segmented-control");
643    elm_widget_sub_object_add(parent, obj);
644    elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
645    elm_widget_data_set(obj, wd);
646    elm_widget_del_hook_set(obj, _del_hook);
647    elm_widget_theme_hook_set(obj, _theme_hook);
648
649    wd->base = edje_object_add(e);
650    _elm_theme_object_set(obj, wd->base, "segmented-control", "base", "default");
651    elm_widget_resize_object_set(obj, wd->base);
652    wd->box = evas_object_box_add(e);
653    evas_object_box_layout_set(wd->box, _layout, wd, NULL);
654    elm_widget_sub_object_add(obj, wd->box);
655    edje_object_part_swallow(wd->base, "elm.swallow.content", wd->box);
656    evas_object_show(wd->box);
657
658    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _object_resize, obj);
659    wd->id = 0;
660    wd->del_index = -1;
661    wd->insert_index = -1;
662    wd->cur_seg_id = -1;
663
664    deffont = edje_object_data_get(wd->base, "default_font_size");
665    if (deffont) wd->cur_fontsize = atoi(deffont);
666    else wd->cur_fontsize = 1;
667
668    maxheight = edje_object_data_get(wd->base, "max_height");
669    if (maxheight) wd->max_height = atoi(maxheight);
670    else wd->max_height = 1;
671
672    wpad = edje_object_data_get(wd->base, "w_pad");
673    if (wpad) wd->w_pad = atoi(wpad);
674    else wd->w_pad = 1;
675
676    hpad = edje_object_data_get(wd->base, "h_pad");
677    if (hpad) wd->h_pad = atoi(hpad);
678    else wd->h_pad = 1;
679
680    return obj;
681 }
682
683 EAPI Elm_Segment_Item *
684 elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
685 {
686    Elm_Segment_Item *it;
687    Widget_Data *wd = elm_widget_data_get(obj);
688    if(!wd) return NULL;
689
690    it = _item_new(obj, label, icon);
691    if(!it) return NULL;
692
693    wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
694    wd->id = eina_list_count(wd->seg_ctrl);
695    //_update_list(obj);
696    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
697    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
698    evas_object_event_callback_add(it->base, EVAS_CALLBACK_RESIZE, _object_item_resize, it);
699    wd->insert_index = -1;
700    wd->del_index = -1;
701    _refresh_segment_ids(obj);
702
703    if(animate && it->segment_id && wd->ani_it == NULL)
704      {
705         evas_object_resize(it->base, 1, wd->height);
706         wd->ani_it = it;
707         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
708      }
709    else
710       _state_value_set(obj);
711    evas_object_show( it->base);
712
713    evas_object_box_append(wd->box, it->base);
714    evas_object_smart_calculate(wd->box);
715
716    return it;
717 }
718
719 /**
720  * Add a new segment item to segmentcontrol
721  * @param obj The SegmentControl object
722  * @param icon The icon object for added segment item
723  * @param label The label for added segment item
724  * @param animate If 1 the action be animated with sliding effects default 0.
725  * @return The new segment item or NULL if it cannot be created
726  *
727  * @ingroup SegmentControl SegmentControl
728  */
729 EAPI Elm_Segment_Item *
730 elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
731 {
732    Elm_Segment_Item * it;
733    it = elm_segment_control_item_add(obj, icon, label, animate);
734 \r
735     return it;\r
736 }
737
738 EAPI Elm_Segment_Item *
739 elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
740 {
741    Elm_Segment_Item *it, *it_rel;
742    Widget_Data *wd = elm_widget_data_get(obj);
743    if(!wd) return NULL;
744
745    it = _item_new(obj, label, icon);
746    it_rel = _item_find(obj, index);
747    if (!it_rel)
748      {
749       wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
750      }
751    else
752      {
753         if (!it) return NULL;
754         wd->seg_ctrl = eina_list_prepend_relative(wd->seg_ctrl, it, it_rel);
755      }
756    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
757    evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
758    evas_object_event_callback_add(it->base, EVAS_CALLBACK_RESIZE, _object_item_resize, it);
759    wd->insert_index = index;
760    wd->id = eina_list_count(wd->seg_ctrl);
761    _refresh_segment_ids(obj);
762
763    //_update_list(obj);
764    if(animate && it->segment_id && wd->ani_it == NULL)
765      {
766         wd->ani_it = it;
767         evas_object_resize(it->base, 1, wd->height);
768         wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
769      }
770    else
771       _state_value_set(obj);
772
773    evas_object_show( it->base);
774
775    if(index >= wd->id-1)
776      {
777         evas_object_box_append(wd->box,  it->base);
778      }
779    else
780      {
781         evas_object_box_insert_at(wd->box,  it->base, index);
782      }
783
784    evas_object_smart_calculate(wd->box);
785
786    return it ;
787 }
788 /**
789  * Insert a new segment item to segmentcontrol
790  * @param obj The SegmentControl object
791  * @param icon The icon object for added segment item
792  * @param label The label for added segment item
793  * @param index The position at which segment item to be inserted
794  * @param animate If 1 the action be animated with sliding effects default 0.
795  * @return The new segment item or NULL if it cannot be created
796  *
797  * @ingroup SegmentControl SegmentControl
798  */
799 EAPI void
800 elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
801 {
802    Elm_Segment_Item *it;
803    it = elm_segment_control_item_insert_at(obj, icon, label, index, animate);
804
805    return;
806 }
807
808 EAPI void
809 elm_segment_control_item_del(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
810 {
811    Elm_Segment_Item *it;
812    Widget_Data *wd = elm_widget_data_get(obj);
813    if(!wd) return;
814
815
816    it = item;
817    if(!it) return;
818
819    wd->del_index = it->segment_id;
820    if(animate && it->segment_id && wd->ani_it == NULL)
821      {
822         it->delete_me = EINA_TRUE;
823         wd->ani_it = it;
824         wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
825      }
826    else
827      {
828         evas_object_box_remove(wd->box, it->base);
829         evas_object_smart_calculate(wd->box);
830
831         _item_free(obj, it);
832         _refresh_segment_ids(obj);
833         _state_value_set(obj);
834         //_update_list(obj);
835      }
836    wd->id = eina_list_count(wd->seg_ctrl);
837    return;
838 }
839
840 /**
841  * Delete a segment item to segmentcontrol
842  * @param obj The SegmentControl object
843  * @param index The position at which segment item to be deleted
844  * @param animate If 1 the action be animated with sliding effects default 0.
845  *
846  * @ingroup SegmentControl SegmentControl
847  */
848 EAPI void
849 elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
850 {
851    elm_segment_control_item_del(obj, item, animate);
852
853    return;
854 }
855
856 EAPI void
857 elm_segment_control_item_del_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
858 {
859    Elm_Segment_Item *it;
860    Widget_Data *wd = elm_widget_data_get(obj);
861    if(!wd) return;
862
863    it = _item_find(obj, index);
864
865    if(!it) return;
866
867    wd->del_index = index;
868    if(animate && it->segment_id)
869      {
870         if(wd->ani_it == NULL)
871         {
872            wd->ani_it = it;
873            it->delete_me = EINA_TRUE;
874            wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
875         }
876      }
877    else
878      {
879         evas_object_box_remove(wd->box, it->base);
880         evas_object_smart_calculate(wd->box);
881         _item_free(obj, it);
882         _refresh_segment_ids(obj);
883         _state_value_set(obj);
884         //_update_list(obj);
885      }
886    wd->id = eina_list_count(wd->seg_ctrl);
887    return;
888 }
889
890 /**
891  * Delete a segment item of given index to segmentcontrol
892  * @param obj The SegmentControl object
893  * @param index The position at which segment item to be deleted
894  * @param animate If 1 the action be animated with sliding effects default 0.
895  *
896  * @ingroup SegmentControl SegmentControl
897  */
898 EAPI void
899 elm_segment_control_delete_segment_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
900 {
901    elm_segment_control_item_del_at( obj, index, animate);
902
903    return;
904 }
905
906
907 EAPI const char *
908 elm_segment_control_item_label_get(Evas_Object *obj, unsigned int index)
909 {
910    Elm_Segment_Item *it_rel;
911    Widget_Data *wd = elm_widget_data_get(obj);
912    if(!wd) return NULL;
913
914    it_rel = _item_find(obj, index);
915
916    if(it_rel) return it_rel->label;
917
918    return NULL;
919 }
920
921 /**
922  * Get the label of a segment item of segmentcontrol
923  * @param obj The SegmentControl object
924  * @param index The index of the segment item
925  * @return The label of the segment item
926  *
927  * @ingroup SegmentControl SegmentControl
928  */
929 EAPI const char *
930 elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index)
931 {
932    char *label;
933    label = elm_segment_control_item_label_get( obj, index);
934   
935    return label;
936 }
937
938 EAPI Evas_Object *
939 elm_segment_control_item_icon_get(Evas_Object *obj, unsigned int index)
940 {
941    Elm_Segment_Item *seg_rel;
942    Widget_Data *wd = elm_widget_data_get(obj);
943    if(!wd) return NULL;
944
945    seg_rel = _item_find(obj, index);
946
947    if(seg_rel) return seg_rel->icon;
948
949    return NULL;
950 }
951
952 /**
953  * Get the icon of a segment item of segmentcontrol
954  * @param obj The SegmentControl object
955  * @param index The index of the segment item
956  * @return The icon object or NULL if it is not found.
957  *
958  * @ingroup SegmentControl SegmentControl
959  */
960 EAPI Evas_Object *
961 elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index)
962 {
963    Evas_Object *icon;
964    icon = elm_segment_control_item_icon_get( obj, index);
965
966    return icon;
967 }
968
969 EAPI Elm_Segment_Item *
970 elm_segment_control_item_selected_get(const Evas_Object *obj)
971 {
972    Elm_Segment_Item *it;
973    Eina_List *l;
974    Widget_Data *wd = elm_widget_data_get(obj);
975    if(!wd || !wd->seg_ctrl) return NULL;
976
977    EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
978      {
979        if(it->segment_id == wd->cur_seg_id && it->sel)
980           return it;
981       }
982     return NULL;
983  }
984
985 /**
986  * Get the currently selected segment item of segmentcontrol
987  * @param obj The SegmentControl object
988  * @return The selected Segment item
989  *
990  * @ingroup SegmentControl SegmentControl
991  */
992 EAPI Elm_Segment_Item *
993 elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value)
994 {
995    Elm_Segment_Item *it;
996    it = elm_segment_control_item_selected_get( obj);
997    if(!it) return NULL;
998    if(it->sel)
999       *value = it->segment_id;
1000    else
1001       *value = -1;
1002    \r
1003     return it;
1004  }
1005
1006
1007 EAPI int
1008 elm_segment_control_item_count_get(Evas_Object *obj)
1009 {
1010    Widget_Data *wd = elm_widget_data_get(obj);
1011    if(!wd) return 0;
1012
1013    return wd->id;
1014 }
1015
1016 /**
1017  * Get the count of segments of segmentcontrol
1018  * @param obj The SegmentControl object
1019  * @return The count of Segment items
1020  *
1021  * @ingroup SegmentControl SegmentControl
1022  */
1023 EAPI int
1024 elm_segment_control_get_segment_count(Evas_Object *obj)
1025 {
1026    int id;
1027    id = elm_segment_control_item_count_get( obj);
1028
1029    return id;
1030 }
1031
1032 /**
1033  * Get the base object of segment item in segmentcontrol
1034  * @param obj The Segment item
1035  * @return obj The base object of the segment item
1036  *
1037  * @ingroup SegmentControl SegmentControl
1038  */
1039 EAPI Evas_Object *
1040 elm_segment_control_item_object_get(Elm_Segment_Item *it)
1041 {
1042    if (!it) return NULL;
1043    
1044    return it->base;
1045 }
1046
1047 /**
1048  * Select/unselect a particular segment item of segmentcontrol
1049  * @param item The Segment item that is to be selected or unselected.
1050  * @param select If 1 the segment item is selected and if 0 it will be unselected.
1051  *
1052  * @ingroup SegmentControl SegmentControl
1053  */
1054 EAPI void
1055 elm_segment_control_item_selected_set( Elm_Segment_Item *item, Eina_Bool select)
1056 {
1057    if(!item) return;
1058    Widget_Data *wd = elm_widget_data_get(item->obj);
1059    if(!wd) return;
1060
1061    if(select)
1062      {
1063         if(item->segment_id == wd->cur_seg_id && wd->cur_seg_id) return;
1064
1065         item->sel = EINA_TRUE;
1066       }
1067    else if(item->segment_id == wd->cur_seg_id)
1068       {
1069          item->sel = EINA_FALSE;
1070          wd->cur_seg_id = -1;
1071          _signal_segment_off(item);
1072       } 
1073
1074    return;
1075
1076 }
1077
1078 /**
1079  * Get a particular indexed segment item of segmentcontrol
1080  * @param obj The Segment control object.
1081  * @param index The index of the segment item.
1082  * @return The corresponding Segment item.
1083  *
1084  * @ingroup SegmentControl SegmentControl
1085  */
1086 EAPI Elm_Segment_Item *
1087 elm_segment_control_item_get_at(Evas_Object *obj, unsigned int index)
1088 {
1089    Elm_Segment_Item *it;
1090    it = _item_find(obj, index);
1091
1092    return it;
1093 }
1094 \r
1095 /**
1096  * Get the index of a Segment item of Segmentcontrol
1097  * @param item The Segment item.
1098  * @return The corresponding index of the Segment item.
1099  *
1100  * @ingroup SegmentControl SegmentControl
1101  */
1102 EAPI int
1103 elm_segment_control_item_index_get(Elm_Segment_Item *item)
1104 {
1105    if(!item) return -1;
1106    Widget_Data *wd = elm_widget_data_get(item->obj);
1107    if(!wd) return -1;
1108
1109    return item->segment_id;
1110 }
1111
1112 /**
1113  * Set The Label widget to a Segment item of Segmentcontrol
1114  * @param item The Segment item.
1115  * @param label The Label.
1116  * @return Evas_Object The Label widget.
1117  *
1118  * @ingroup SegmentControl SegmentControl
1119  */
1120 EAPI Evas_Object *
1121 elm_segment_control_item_label_object_set(Elm_Segment_Item *item, char *label)
1122 {
1123    if(!item) return NULL;
1124    Widget_Data *wd = elm_widget_data_get(item->obj);
1125    if(!wd) return NULL;
1126    if(!label) return NULL;
1127
1128    item->label_wd = elm_label_add(item->obj);
1129    elm_label_label_set(item->label_wd, label);
1130    elm_label_text_align_set(item->label_wd, "middle");
1131    elm_label_ellipsis_set(item->label_wd, 1);
1132    elm_label_line_wrap_set(item->label_wd, 1);
1133    eina_stringshare_replace(&item->label, label);
1134    elm_object_style_set(item->label_wd, "segment");
1135
1136    return item->label_wd;
1137 }
1138