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