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