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