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