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