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