[elm_button, elm_index, elm_pagecontrol, elm_segment_control] Updated.
authorPrince Kumar Dubey <prince.dubey@samsung.com>
Wed, 19 May 2010 10:15:18 +0000 (15:45 +0530)
committerPrince Kumar Dubey <prince.dubey@samsung.com>
Wed, 19 May 2010 10:15:18 +0000 (15:45 +0530)
src/lib/Elementary.h.in
src/lib/Makefile.am
src/lib/elm_button.c
src/lib/elm_index.c
src/lib/elm_pagecontrol.c [new file with mode: 0755]
src/lib/elm_segment_control.c [new file with mode: 0755]

index be56f07..2cd74c9 100755 (executable)
@@ -428,10 +428,19 @@ extern "C" {
    EAPI void         elm_box_unpack_all(Evas_Object *obj);
    /* smart callbacks called:
     */
+       typedef enum {
+          UIControlStateDefault,
+          UIControlStateHighlighted,
+          UIControlStateDisabled,
+          UIControlStateFocused,
+          UIControlStateReserved
+       }UIControlState;
 
    EAPI Evas_Object *elm_button_add(Evas_Object *parent);
    EAPI void         elm_button_label_set(Evas_Object *obj, const char *label);
+   EAPI void         elm_button_label_set_for_state(Evas_Object *obj, const char *label, UIControlState state);
    EAPI const char  *elm_button_label_get(const Evas_Object *obj);
+   EAPI const char  *elm_button_label_get_for_state(const Evas_Object *obj, UIControlState state);
    EAPI void         elm_button_icon_set(Evas_Object *obj, Evas_Object *icon);
    EAPI Evas_Object *elm_button_icon_get(const Evas_Object *obj);
    EAPI void         elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on);
@@ -1173,7 +1182,22 @@ extern "C" {
    EAPI void         elm_radio_value_set(Evas_Object *obj, int value);
    EAPI int          elm_radio_value_get(const Evas_Object *obj);
    EAPI void         elm_radio_value_pointer_set(Evas_Object *obj, int *valuep);
-
+   typedef struct _Elm_Segment_Item Elm_Segment_Item;
+   EAPI Evas_Object *elm_segment_control_add(Evas_Object *parent);
+   EAPI Elm_Segment_Item * elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate);
+   EAPI void            elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate);
+   EAPI Evas_Object *elm_segment_control_get_segment_at(Evas_Object *obj, unsigned int index);
+   EAPI void            elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate);
+   EAPI void            elm_segment_control_delete_segment_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate);
+   EAPI const char  *elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index);
+   EAPI Evas_Object *elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index);
+   EAPI Elm_Segment_Item *elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value);
+   EAPI int         elm_segment_control_get_segment_count(Evas_Object *obj);
+
+   EAPI Evas_Object *elm_page_control_add(Evas_Object *parent);
+   EAPI void           elm_page_control_page_count_set(Evas_Object *obj, unsigned int page_count);
+   EAPI        void            elm_page_control_page_id_set(Evas_Object *obj, unsigned int page_id);
+   EAPI unsigned int elm_page_control_page_id_get(Evas_Object *obj);
    EAPI Evas_Object *elm_pager_add(Evas_Object *parent);
    EAPI void         elm_pager_content_push(Evas_Object *obj, Evas_Object *content);
    EAPI void         elm_pager_content_pop(Evas_Object *obj);
index e7c14ad..6f65744 100755 (executable)
@@ -62,6 +62,8 @@ elm_slider.c \
 elm_genlist.c \
 elm_check.c \
 elm_radio.c \
+elm_segment_control.c \
+elm_pagecontrol.c \
 elm_pager.c \
 elm_progressbar.c \
 elm_separator.c \
index 3bccbef..d48cab9 100644 (file)
@@ -24,6 +24,14 @@ struct _Widget_Data
    double ar_threshold;
    double ar_interval;
    Ecore_Timer *timer;
+   const char *clickedlabel;
+   const char *focusedlabel;
+   const char *disabledlabel;
+   const char *defaultlabel;
+   int highlightedstate;
+   int focusedstate;
+   int disabledstate;
+   int defaultstate;
 };
 
 static const char *widtype = NULL;
@@ -37,6 +45,8 @@ static void _signal_clicked(void *data, Evas_Object *obj, const char *emission,
 static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source);
 static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source);
 static void _on_focus_hook(void *data, Evas_Object *obj);
+static void _set_label(Evas_Object *obj, const char *label);
+static void _signal_default_text_set(void *data, Evas_Object *obj, const char *emission, const char *source);
 
 static const char SIG_CLICKED[] = "clicked";
 static const char SIG_REPEATED[] = "repeated";
@@ -54,6 +64,10 @@ _del_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    if (wd->label) eina_stringshare_del(wd->label);
+  if (wd->defaultlabel) eina_stringshare_del(wd->defaultlabel);
+  if (wd->clickedlabel) eina_stringshare_del(wd->clickedlabel);
+  if (wd->focusedlabel) eina_stringshare_del(wd->focusedlabel);
+  if (wd->disabledlabel) eina_stringshare_del(wd->disabledlabel);
    free(wd);
 }
 
@@ -64,11 +78,19 @@ _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
    if (!wd) return;
    if (elm_widget_focus_get(obj))
      {
+      if(wd->focusedstate)
+      {
+       _set_label(obj, wd->focusedlabel);
+      }
        edje_object_signal_emit(wd->btn, "elm,action,focus", "elm");
        evas_object_focus_set(wd->btn, 1);
      }
    else
      {
+       if(wd->defaultlabel)
+               _set_label(obj, wd->defaultlabel);
+       else
+                _set_label(obj, wd->label);
        edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
        evas_object_focus_set(wd->btn, 0);
      }
@@ -102,9 +124,21 @@ _disable_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    if (elm_widget_disabled_get(obj))
+   {
+         if(wd->disabledstate )
+         {
+                 _set_label(obj, wd->disabledlabel);
+         }
      edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
+   }
    else
+   {
+       if(wd->defaultlabel)
+               _set_label(obj, wd->defaultlabel);
+       else
+                _set_label(obj, wd->label);
      edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
+   }
 }
 
 static void
@@ -197,7 +231,10 @@ _signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __
 {
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
-
+       if(wd->highlightedstate)
+       {
+               _set_label(data, wd->clickedlabel);
+       }
    if (wd->autorepeat && !wd->repeating)
      {
        if (wd->ar_threshold <= 0.0)
@@ -208,10 +245,27 @@ _signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __
 }
 
 static void
+_signal_default_text_set(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+       Widget_Data *wd = elm_widget_data_get(data);
+          if (!wd) return;
+               if(wd->defaultlabel)
+                       _set_label(data, wd->defaultlabel);
+               else
+                        _set_label(data, wd->label);
+               return;
+}
+
+static void
 _signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
 {
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
+       if(wd->defaultlabel)
+               _set_label(data, wd->defaultlabel);
+       else
+                _set_label(data, wd->label);
+   evas_object_smart_callback_call(data, "unpressed", NULL);
 
    if (wd->timer)
      {
@@ -251,12 +305,18 @@ elm_button_add(Evas_Object *parent)
 
    wd->btn = edje_object_add(e);
    _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
+   wd->defaultstate = 0;
+   wd->highlightedstate = 0;
+   wd->focusedstate = 0;
+   wd->disabledstate = 0;
    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
                                    _signal_clicked, obj);
    edje_object_signal_callback_add(wd->btn, "elm,action,press", "",
                                    _signal_pressed, obj);
    edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "",
                                    _signal_unpressed, obj);
+   edje_object_signal_callback_add(wd->btn, "elm,action,default,text,set", "",
+               _signal_default_text_set, obj);
    elm_widget_resize_object_set(obj, wd->btn);
 
    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
@@ -293,6 +353,62 @@ elm_button_label_set(Evas_Object *obj, const char *label)
    _sizing_eval(obj);
 }
 
+static void
+_set_label(Evas_Object *obj, const char *label)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   edje_object_message_signal_process(wd->btn);
+   edje_object_part_text_set(wd->btn, "elm.text", label);
+   _sizing_eval(obj);
+}
+/**
+ * Set the label for each state of button
+ *
+ * @param obj The button object
+ * @param label The text will be written on the button
+ * @param state The state of button
+ *
+ * @ingroup Button
+ */
+EAPI void
+elm_button_label_set_for_state(Evas_Object *obj, const char *label, UIControlState state)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord mw, mh;
+
+   if (!wd) return;
+   if(label == NULL) return;
+
+   if(state == UIControlStateDefault)
+       {
+       wd->defaultstate = UIControlStateDefault;
+      if (wd->defaultlabel) eina_stringshare_del(wd->defaultlabel);
+               wd->defaultlabel = eina_stringshare_add(label);
+   }
+   if(state == UIControlStateHighlighted)
+   {
+       wd->highlightedstate = UIControlStateHighlighted;
+      if (wd->clickedlabel) eina_stringshare_del(wd->clickedlabel);
+               wd->clickedlabel = eina_stringshare_add(label);
+       return;
+   }
+   if(state == UIControlStateFocused)
+   {
+       wd->focusedstate = UIControlStateFocused;
+      if (wd->focusedlabel) eina_stringshare_del(wd->focusedlabel);
+               wd->focusedlabel = eina_stringshare_add(label);
+       return;
+   }
+   if(state == UIControlStateDisabled)
+       {
+       wd->disabledstate = UIControlStateDisabled;
+      if (wd->disabledlabel) eina_stringshare_del(wd->disabledlabel);
+               wd->disabledlabel = eina_stringshare_add(label);
+       return;
+   }
+}
+
 EAPI const char *
 elm_button_label_get(const Evas_Object *obj)
 {
@@ -301,6 +417,32 @@ elm_button_label_get(const Evas_Object *obj)
    if (!wd) return NULL;
    return wd->label;
 }
+/**
+ * get the label of button for each state
+ *
+ * @param obj The button object
+ * @param state The state of button
+ * @return The title of button for state
+ *
+ * @ingroup Button
+ */
+EAPI const char*
+elm_button_label_get_for_state(const Evas_Object *obj, UIControlState state)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   if(state == UIControlStateDefault)
+      return wd->defaultlabel;
+   else if(state == UIControlStateHighlighted)
+        return wd->highlightedstate;
+   else if(state == UIControlStateFocused)
+        return wd->focusedlabel;
+   else if(state == UIControlStateDisabled)
+        return wd->disabledlabel;
+   else
+       return NULL;
+}
 
 /**
  * Set the icon used for the button
index af2c1e2..9311bc0 100644 (file)
@@ -8,8 +8,12 @@
  * by letter.
  */
 
+#define MIN_GRP_SIZE 2 //for symmetry it is 2, otherwise it can be 1 and zero have no meaning.
+#define MIN_PIXEL_VALUE 1 //Min pixel value is highly dependent on touch sensitivity support.
+#define MIN_OBJ_HEIGHT 24 //should be taken from .edc file.
 typedef struct _Widget_Data Widget_Data;
 typedef struct _Item Item;
+typedef struct _PlacementPart PlacementPart;
 
 struct _Widget_Data
 {
@@ -24,6 +28,13 @@ struct _Widget_Data
    Eina_Bool horizontal : 1;
    Eina_Bool active : 1;
    Eina_Bool down : 1;
+   int max_supp_items_count;
+   int tot_items_count[2];
+   Evas_Coord pwidth, pheight;
+   int min_obj_height, max_grp_size;
+   int items_count;
+   double scale_factor;
+   const char *special_char;
 };
 
 struct _Item
@@ -34,15 +45,23 @@ struct _Item
    int level;
    Evas_Object *base;
    Eina_Bool selected : 1;
+   int size;
+   const char *vis_letter;
 };
 
 static const char *widtype = NULL;
+struct _PlacementPart
+{
+       int start;
+       int count;
+};
 static void _del_hook(Evas_Object *obj);
 static void _theme_hook(Evas_Object *obj);
 static void _sizing_eval(Evas_Object *obj);
 static void _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level);
 static void _index_box_clear(Evas_Object *obj, Evas_Object *box, int level);
 static void _item_free(Item *it);
+static void _index_process(Evas_Object *obj);
 
 static void
 _del_hook(Evas_Object *obj)
@@ -64,7 +83,7 @@ _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
 {
    Widget_Data *wd = data;
    if (!wd) return;
-   _els_box_layout(o, priv, wd->horizontal, 1);
+   _els_box_layout(o, priv, wd->horizontal, 0); /* making box layout non homogenous */
 }
 
 static void
@@ -147,9 +166,18 @@ _item_new(Evas_Object *obj, const char *letter, const void *item)
    it = calloc(1, sizeof(Item));
    if (!it) return NULL;
    it->obj = obj;
-   it->letter = eina_stringshare_add(letter);
    it->data = item;
    it->level = wd->level;
+   it->size =  wd->min_obj_height;
+   if(letter)
+   {
+               it->letter = eina_stringshare_add(letter);
+               it->vis_letter = eina_stringshare_add(letter);
+   }
+   else
+   {
+       return NULL;
+   }
    return it;
 }
 
@@ -173,6 +201,7 @@ _item_free(Item *it)
    wd->items = eina_list_remove(wd->items, it);
    if (it->base) evas_object_del(it->base);
    eina_stringshare_del(it->letter);
+   eina_stringshare_del(it->vis_letter);
    free(it);
 }
 
@@ -194,6 +223,10 @@ _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level)
         const char *stacking;
 
         if (it->level != level) continue;
+               if(i > wd->max_supp_items_count)
+               {
+                       break;
+               }
         o = edje_object_add(evas_object_evas_get(obj));
         it->base = o;
         if (i & 0x1)
@@ -202,9 +235,12 @@ _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level)
           _elm_theme_object_set(obj, o, "index", "item/vertical", "default");
         edje_object_part_text_set(o, "elm.text", it->letter);
         edje_object_size_min_restricted_calc(o, &mw, &mh, 0, 0);
-        evas_object_size_hint_min_set(o, mw, mh);
         evas_object_size_hint_weight_set(o, 1.0, 1.0);
         evas_object_size_hint_align_set(o, -1.0, -1.0);
+               edje_object_part_text_set(o, "elm.text", it->vis_letter);
+               evas_object_resize(o, mw, it->size);
+               evas_object_size_hint_min_set(o, mw, it->size);
+               evas_object_size_hint_max_set(o, mw, it->size);
         elm_widget_sub_object_add(obj, o);
         evas_object_box_append(box, o);
         stacking = edje_object_data_get(o, "stacking");
@@ -215,6 +251,8 @@ _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level)
           }
         evas_object_show(o);
         i++;
+        if(level == 1)
+               wd->tot_items_count[1] = i;
         evas_object_smart_calculate(box); // force a calc so we know the size
         evas_object_size_hint_min_get(box, &mw, &mh);
         if (mh > h)
@@ -268,6 +306,9 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy)
    Eina_List *l;
    Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy;
    double cdv = 0.5;
+   double cdvv = 0.0;
+   double dmax = 0.0;
+   double dmin = 0.0;
    Evas_Coord dist;
    Eina_Bool change = 0;
    char *label = NULL, *last = NULL;
@@ -279,18 +320,11 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy)
         it_closest  = NULL;
         dist = 0x7fffffff;
         evas_object_geometry_get(wd->bx[i], &bx, &by, &bw, &bh);
+               dmin = (double)(wd->min_obj_height*wd->tot_items_count[1])/(2*(double)bh);
+               dmax = 1-dmin;
         EINA_LIST_FOREACH(wd->items, l, it)
           {
              if (!((it->level == i) && (it->base))) continue;
-             if ((it->base) && (it->level != wd->level))
-               {
-                  if (it->selected)
-                    {
-                       it_closest = it;
-                       break;
-                    }
-                  continue;
-               }
              if (it->selected)
                {
                   it_last = it;
@@ -305,7 +339,7 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy)
              if ((x < dist) || (!it_closest))
                {
                   if (wd->horizontal)
-                    cdv = (double)(xx - bx) / (double)bw; 
+                    cdv = (double)(xx - bx) / (double)bw;
                   else
                     cdv = (double)(yy - by) / (double)bh;
                   it_closest = it;
@@ -313,8 +347,24 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy)
                }
           }
         if ((i == 0) && (wd->level == 0))
-          edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", 
-                                          cdv, cdv);
+        {
+                       if(cdv > dmax || cdv < dmin)
+                       {
+                               if(cdv > dmax)
+                               {
+                                       cdvv = dmax;
+                               }
+                               else
+                               {
+                                       cdvv = dmin;
+                               }
+                               edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", cdv, cdvv);
+                       }
+                       else
+                       {
+                               edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", cdv, cdv);
+                       }
+               }
         if (it_closest) it_closest->selected = 1;
         if (it_closest != it_last)
           {
@@ -367,13 +417,36 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy)
      }
    if (!label) label = strdup("");
    if (!last) last = strdup("");
-   edje_object_part_text_set(wd->base, "elm.text.body", label);
-   edje_object_part_text_set(wd->base, "elm.text", last);
+   if(wd->level_active[1])
+   {
+          if(wd->level == 0)
+          {
+                  if(last)
+                  {
+                          edje_object_part_text_set(wd->base, "elm.text.body", last);
+                          edje_object_signal_emit(wd->base, "color_changed", "");
+                          edje_object_part_text_set(wd->base, "elm.text.last", "_");
+                          edje_object_signal_emit(wd->base, "hide_2nd_level", "");
+                  }
+          }
+          if( wd->level == 1)
+          {
+          edje_object_part_text_set(wd->base, "elm.text", last);
+                  edje_object_signal_emit(wd->base, "hide_first_level", "");
+                  edje_object_signal_emit(wd->base, "revert_back", "");
+          }
+   }
+   else
+   {
+          edje_object_part_text_set(wd->base, "elm.text.body", last);
+          edje_object_signal_emit(wd->base, "color_changed", "");
+          edje_object_part_text_set(wd->base, "elm.text", last);
+   }
    free(label);
    free(last);
 }
 
-static void 
+static void
 _wheel(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
 {
    Widget_Data *wd = elm_widget_data_get(data);
@@ -382,7 +455,7 @@ _wheel(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_in
    if (!wd) return;
 }
 
-static void 
+static void
 _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
 {
    Widget_Data *wd = elm_widget_data_get(data);
@@ -396,11 +469,11 @@ _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *eve
    wd->dy = ev->canvas.y - y;
    elm_index_active_set(data, 1);
    _sel_eval(data, ev->canvas.x, ev->canvas.y);
-   edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer", 
+   edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer",
                                    wd->dx, wd->dy);
 }
 
-static void 
+static void
 _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
 {
    Widget_Data *wd = elm_widget_data_get(data);
@@ -408,6 +481,8 @@ _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event
    void *d;
    if (!wd) return;
    if (ev->button != 1) return;
+   if (wd->level == 1 && wd->delay) ecore_timer_del(wd->delay);
+   wd->delay = NULL;
    wd->down = 0;
    d = (void *)elm_index_item_selected_get(data, wd->level);
    if (d) evas_object_smart_callback_call(data, "selected", d);
@@ -415,12 +490,13 @@ _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event
    edje_object_signal_emit(wd->base, "elm,state,level,0", "elm");
 }
 
-static void 
+static void
 _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
 {
    Widget_Data *wd = elm_widget_data_get(data);
    Evas_Event_Mouse_Move *ev = event_info;
    Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
+   void *d;
    char buf[1024];
    if (!wd) return;
    if (!wd->down) return;
@@ -443,7 +519,7 @@ _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *eve
         if (adx > minw)
           {
              if (wd->level == 0)
-               { 
+               {
                   wd->level = 1;
                   snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level);
                   edje_object_signal_emit(wd->base, buf, "elm");
@@ -457,12 +533,60 @@ _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *eve
                   wd->level = 0;
                   snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level);
                   edje_object_signal_emit(wd->base, buf, "elm");
+                  d = (void *)elm_index_item_selected_get(data, wd->level);
+                                  evas_object_smart_callback_call(data, "changed", d);
+                                  if (wd->delay) ecore_timer_del(wd->delay);
+                                  wd->delay = ecore_timer_add(0.2, _delay_change, data);
                   evas_object_smart_callback_call(data, "level,down", NULL);
                }
           }
      }
    _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y);
 }
+static void
+_index_box_refill_job(void *data)
+{
+       Widget_Data *wd = elm_widget_data_get((Evas_Object *)data);
+       if (!wd) return;
+       const char *string;
+       Evas_Coord pw, ph;
+       evas_object_geometry_get(wd->base, NULL, NULL, &pw, &ph);
+       wd->scale_factor = elm_scale_get();
+       if ( wd->scale_factor == 0.0 ) {
+                       wd->scale_factor = 1.0;
+       }
+       string = edje_object_data_get(wd->base, "min_obj_height");
+       if(string)
+       wd->min_obj_height = (int) (atoi(string))*wd->scale_factor;
+       else
+       wd->min_obj_height == MIN_OBJ_HEIGHT*wd->scale_factor;
+       if(!wd->min_obj_height)
+               return;
+       wd->max_grp_size = wd->min_obj_height - 2*MIN_GRP_SIZE;
+       wd->items_count =    ph/wd->min_obj_height;
+       wd->max_supp_items_count = wd->max_grp_size*(int)((wd->items_count-1)*0.5)+wd->items_count;
+       if(pw != wd->pwidth && ph != wd->pheight)
+       {
+               if(wd->down == 1)
+               {
+                       wd->active = 0;
+                       elm_index_active_set(data, 1);
+               }
+               _index_box_clear((Evas_Object *)data, wd->bx[0], 0);
+               evas_object_smart_calculate( wd->bx[0]);
+               elm_index_item_go((Evas_Object *)data, wd->level);
+               wd->pwidth = pw;
+               wd->pheight = ph;
+       }
+}
+static void _index_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+       Widget_Data *wd;
+       if(!data) return;
+       wd = elm_widget_data_get((Evas_Object *)data);
+       if(!wd) return;
+       ecore_job_add(_index_box_refill_job, (Evas_Object *)data);
+}
 
 /**
  * Add a new index to the parent
@@ -492,6 +616,15 @@ elm_index_add(Evas_Object *parent)
    elm_widget_theme_hook_set(obj, _theme_hook);
 
    wd->horizontal = EINA_FALSE;
+   wd->min_obj_height = 0;
+   wd->max_grp_size = 0;
+   wd->items_count = 0;
+   wd->max_supp_items_count = 0;
+   wd->tot_items_count[0] = 0;
+   wd->tot_items_count[1] = 0;
+   wd->special_char = edje_object_data_get(wd->base, "special_char");
+       if(wd->special_char == NULL);
+               wd->special_char = eina_stringshare_add("*");
 
    wd->base = edje_object_add(e);
    _elm_theme_object_set(obj, wd->base, "index", "base/vertical", "default");
@@ -505,6 +638,7 @@ elm_index_add(Evas_Object *parent)
    evas_object_size_hint_min_set(o, minw, minh);
    edje_object_part_swallow(wd->base, "elm.swallow.event.0", o);
    elm_widget_sub_object_add(obj, o);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _index_object_resize, obj);
    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _wheel, obj);
    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, obj);
    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _mouse_up, obj);
@@ -539,6 +673,106 @@ elm_index_add(Evas_Object *parent)
    return obj;
 }
 
+static int
+_group_count(Evas_Object *obj, int extraIndex, int adj_pos, int vis_pos)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+          if (!wd) return;
+       int group_count = MIN_GRP_SIZE;
+       while(group_count <= wd->max_grp_size)
+       {
+               if(extraIndex <= wd->max_grp_size*adj_pos)
+               {
+                       if(group_count*adj_pos>=extraIndex)
+                               return group_count;
+               }
+               else
+               {
+                       return wd->max_grp_size;
+               }
+               group_count+=MIN_GRP_SIZE;
+       }
+}
+static void
+_index_process(Evas_Object *obj)
+{
+       int extraIndex;
+       int j,i, group_count;
+       Eina_List *l;
+       Item *it;
+       int count;
+       int n;
+       Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if(wd->items_count == 0) return;
+    const int adj_pos = (wd->items_count-1)*0.5;
+       if(wd->tot_items_count[wd->level] <= wd->max_supp_items_count)
+               n = wd->tot_items_count[wd->level];
+       else
+               n = wd->max_supp_items_count;
+       group_count = MIN_GRP_SIZE;
+       int indx[n];
+       const int minh = wd->min_obj_height;
+       EINA_LIST_FOREACH(wd->items, l, it)
+       {
+               it->vis_letter = eina_stringshare_add(it->letter);
+               it->size =  minh;
+       }
+       int remainder;
+       int numberofparts;
+       int N = wd->items_count;
+       for(i=0;i<n;i++)
+       {
+               indx[i] = minh;
+       }
+       extraIndex=n-N;
+       if(extraIndex < 0) return;
+       group_count = _group_count(obj, extraIndex, adj_pos, N);
+       if(group_count <= 0) return;
+       PlacementPart place[adj_pos];
+       remainder = extraIndex%group_count;
+       numberofparts=(extraIndex/group_count)+(remainder == 0? 0: 1);
+       for(i=0;i<numberofparts; i++)
+       {
+               place[i].count=group_count+1;
+               count = (int)(((float)(i+1)/(float)(numberofparts+1))*N);
+               place[i].start= count +i*group_count-1;
+       }
+       if (remainder)
+       {
+               place[numberofparts-1].count=remainder+1;
+       }
+       for(i=0;i<numberofparts;i++)
+       {
+               for(j=0;j<place[i].count; j++)
+               {
+                       indx[((place[i].start)+j)]= MIN_PIXEL_VALUE;
+               }
+               indx[(place[i].start+(place[i].count)/2)] = minh-place[i].count+1;
+       }
+        count = 0;
+        EINA_LIST_FOREACH(wd->items, l, it)
+        {
+                int size = indx[count];
+               count++;
+                if(size == minh)
+                {
+                        it->vis_letter = eina_stringshare_add(it->letter);
+                        continue;
+                }
+                else if(size == 1)
+               {
+                        eina_stringshare_del(it->vis_letter);
+                        it->vis_letter = eina_stringshare_add("");
+                }
+                else
+                {
+                        eina_stringshare_del(it->vis_letter);
+                        it->vis_letter = eina_stringshare_add(wd->special_char);
+                }
+                it->size = size*wd->scale_factor;
+        }
+}
 /**
  * Set the active state of the index programatically
  *
@@ -559,6 +793,7 @@ elm_index_active_set(Evas_Object *obj, Eina_Bool active)
    if (wd->active)
      {
         _index_box_clear(obj, wd->bx[1], 1);
+          _index_process(obj);
         _index_box_auto_fill(obj, wd->bx[0], 0);
         edje_object_signal_emit(wd->base, "elm,state,active", "elm");
      }
@@ -640,6 +875,7 @@ elm_index_item_append(Evas_Object *obj, const char *letter, const void *item)
    it = _item_new(obj, letter, item);
    if (!it) return;
    wd->items = eina_list_append(wd->items, it);
+   wd->tot_items_count[wd->level]++;
    _index_box_clear(obj, wd->bx[wd->level], wd->level);
 }
 
@@ -663,6 +899,7 @@ elm_index_item_prepend(Evas_Object *obj, const char *letter, const void *item)
    it = _item_new(obj, letter, item);
    if (!it) return;
    wd->items = eina_list_prepend(wd->items, it);
+   wd->tot_items_count[wd->level]++;
    _index_box_clear(obj, wd->bx[wd->level], wd->level);
 }
 
@@ -686,6 +923,7 @@ elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void
    if (!relative)
      {
         elm_index_item_append(obj, letter, item);
+        wd->tot_items_count[wd->level]++;
         return;
      }
    it = _item_new(obj, letter, item);
@@ -693,10 +931,12 @@ elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void
    if (!it_rel)
      {
         elm_index_item_append(obj, letter, item);
+        wd->tot_items_count[wd->level]++;
         return;
      }
    if (!it) return;
    wd->items = eina_list_append_relative(wd->items, it, it_rel);
+   wd->tot_items_count[wd->level]++;
    _index_box_clear(obj, wd->bx[wd->level], wd->level);
 }
 
@@ -720,6 +960,7 @@ elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void
    if (!relative)
      {
         elm_index_item_prepend(obj, letter, item);
+        wd->tot_items_count[wd->level]++;
         return;
      }
    it = _item_new(obj, letter, item);
@@ -727,10 +968,12 @@ elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void
    if (!it_rel)
      {
         elm_index_item_append(obj, letter, item);
+        wd->tot_items_count[wd->level]++;
         return;
      }
    if (!it) return;
    wd->items = eina_list_prepend_relative(wd->items, it, it_rel);
+   wd->tot_items_count[wd->level]++;
    _index_box_clear(obj, wd->bx[wd->level], wd->level);
 }
 
@@ -752,6 +995,7 @@ elm_index_item_del(Evas_Object *obj, const void *item)
    it = _item_find(obj, item);
    if (!it) return;
    _item_free(it);
+   wd->tot_items_count[wd->level]--;
    _index_box_clear(obj, wd->bx[wd->level], wd->level);
 }
 
@@ -793,6 +1037,8 @@ elm_index_item_go(Evas_Object *obj, int level __UNUSED__)
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
+   if(level==0)
+   _index_process(obj);
    _index_box_auto_fill(obj, wd->bx[0], 0);
    if (wd->level == 1) _index_box_auto_fill(obj, wd->bx[1], 1);
 }
diff --git a/src/lib/elm_pagecontrol.c b/src/lib/elm_pagecontrol.c
new file mode 100755 (executable)
index 0000000..71c9890
--- /dev/null
@@ -0,0 +1,328 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define PADDING 9
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Page_Item Page_Item;
+
+struct _Widget_Data
+{
+       Evas_Object *base;
+       Evas_Object *hbox;
+       int page_count;
+       Eina_List *page_list;
+       unsigned int cur_page_id;
+       Evas_Object *parent;
+       int padding;
+   double scale_factor;
+};
+struct _Page_Item
+{
+       Evas_Object *obj;
+       Evas_Object *base;
+       const void *data;
+       int page_id;
+       Eina_Bool selected :1;
+};
+
+
+static void _theme_hook(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       _elm_theme_object_set(obj, wd->base, "page_control", "base", elm_widget_style_get(obj));
+}
+
+static void _sizing_eval(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+
+       if (!wd)
+               return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+       evas_object_size_hint_min_set(obj, -1, -1);
+       evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void _item_free(Evas_Object *obj, Page_Item *it)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd)
+               return;
+
+       if (wd->page_list)
+               wd->page_list = eina_list_remove(wd->page_list, it);
+
+       if (it->base)
+               evas_object_del(it->base);
+
+       if (it)
+               free(it);
+       it = NULL;
+       return;
+}
+static void _del_hook(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       Page_Item *it;
+       Eina_List *l, *clear = NULL;
+
+       EINA_LIST_FOREACH(wd->page_list, l, it) clear = eina_list_append(clear, it);
+       EINA_LIST_FREE(clear, it) _item_free(obj, it);
+
+       if (wd)
+               free(wd);
+       wd = NULL;
+
+       return;
+}
+
+static Page_Item *
+_page_find(Evas_Object *obj, unsigned int index)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd)
+               return NULL;
+
+       Page_Item *it;
+       Eina_List *l;
+
+       int i = 0;
+       EINA_LIST_FOREACH(wd->page_list, l, it)
+       {
+               if (i == index) {
+                       return it;
+               }
+               i++;
+       }
+       return NULL;
+}
+
+static void _indicator_click_left(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+       Widget_Data *wd = elm_widget_data_get((Evas_Object *)data);
+       if (!wd)
+               return;
+
+       Page_Item *it;
+       Eina_List *l;
+       double cur_position = 0.0;
+
+       if(wd->cur_page_id <= 0) return;
+       it=_page_find((Evas_Object *)data, wd->cur_page_id);
+       if(!it) return;
+
+       edje_object_signal_emit(it->base, "elm,state,indicator,off", "elm");
+
+       it=_page_find((Evas_Object *)data, it->page_id-1);
+       if(!it) return;
+
+       edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm");
+       wd->cur_page_id = it->page_id;
+   evas_object_smart_callback_call(it->obj, "changed", (void*)wd->cur_page_id);
+
+   if(!wd->page_count)
+       return;
+
+   cur_position = ((double)wd->cur_page_id)/wd->page_count;
+       edje_object_part_drag_value_set(wd->base, "elm.drag.part", cur_position, 0.5);
+}
+
+static void _indicator_click_right(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+       Widget_Data *wd = elm_widget_data_get((Evas_Object *)data);
+       if (!wd)
+               return;
+
+       Page_Item *it;
+       Eina_List *l;
+       double cur_position = 0.0;
+
+       if(wd->cur_page_id >= wd->page_count-1) return;
+
+       it=_page_find((Evas_Object *)data, wd->cur_page_id);
+       if(!it) return;
+
+       edje_object_signal_emit(it->base, "elm,state,indicator,off", "elm");
+
+       it=_page_find((Evas_Object *)data, it->page_id+1);
+       if(!it) return;
+
+       edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm");
+       wd->cur_page_id = it->page_id;
+   evas_object_smart_callback_call(it->obj, "changed", (void*)wd->cur_page_id);
+
+   if(!wd->page_count)
+       return;
+
+   cur_position = ((double)wd->cur_page_id)/wd->page_count;
+       edje_object_part_drag_value_set(wd->base, "elm.drag.part", cur_position, 0);
+
+}
+
+static Page_Item*
+_create_item(Evas_Object *obj, unsigned int page_id)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       Page_Item *it;
+       Evas_Coord mw, mh;
+       it = calloc(1, sizeof(Page_Item));
+       if (!it)
+               return NULL;
+
+       it->obj = obj;
+       it->selected = EINA_FALSE;
+       it->data = it;
+       it->page_id = page_id;
+
+       it->base = edje_object_add(evas_object_evas_get(obj));
+
+       _elm_theme_object_set(obj, it->base, "page", "item", "default");
+       edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0);
+       evas_object_size_hint_weight_set(it->base, 1.0, 1.0);
+       evas_object_size_hint_align_set(it->base, -1.0, -1.0);
+
+       evas_object_resize(it->base, mw, mh);
+       evas_object_size_hint_min_set(it->base, mw, mh);
+       evas_object_size_hint_max_set(it->base, mw, mh);
+
+       return it;
+}
+
+static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
+{
+       Widget_Data *wd = data;
+
+       if (!wd)
+               return;
+       _els_box_layout(o, priv, 1, 0); /* making box layout non homogenous */
+       return;
+}
+
+EAPI Evas_Object *
+elm_page_control_add(Evas_Object *parent)
+{
+       Evas_Object *obj;
+       Evas *e;
+       Widget_Data *wd;
+       const char *padding;
+
+       wd = ELM_NEW(Widget_Data);
+       e = evas_object_evas_get(parent);
+       obj = elm_widget_add(e);
+       elm_widget_type_set(obj, "page_control");
+       elm_widget_sub_object_add(parent, obj);
+       elm_widget_data_set(obj, wd);
+       elm_widget_del_hook_set(obj, _del_hook);
+       elm_widget_theme_hook_set(obj, _theme_hook);
+
+       wd->base = edje_object_add(e);
+       _elm_theme_object_set(obj, wd->base, "page_control", "base", "default");
+       elm_widget_resize_object_set(obj, wd->base);
+
+       edje_object_signal_callback_add(wd->base, "elm,state,indicator,click,left",     "elm", _indicator_click_left, obj);
+       edje_object_signal_callback_add(wd->base, "elm,state,indicator,click,right",    "elm", _indicator_click_right, obj);
+
+       wd->scale_factor = elm_scale_get();
+       if ( wd->scale_factor == 0.0 ) {
+                       wd->scale_factor = 1.0;
+       }
+       padding = edje_object_data_get(wd->base, "padding");
+
+       if(padding)
+               wd->padding = (int) (atoi(padding));
+       else
+               wd->padding == PADDING;
+       wd->hbox = evas_object_box_add(e);
+       evas_object_box_padding_set(wd->hbox, wd->padding, 0);
+       evas_object_size_hint_weight_set(wd->hbox, 0, 0);
+
+       evas_object_box_layout_set(wd->hbox, _layout, wd, NULL);
+       elm_widget_sub_object_add(obj, wd->hbox);
+
+       edje_object_part_swallow(wd->base, "elm.swallow.page", wd->hbox);
+
+       evas_object_show(wd->hbox);
+
+       wd->parent = parent;
+
+       wd->page_count = 0;
+       wd->cur_page_id = 0;
+
+       _sizing_eval(obj);
+
+       return obj;
+}
+
+EAPI void elm_page_control_page_count_set(Evas_Object *obj,    unsigned int page_count)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd)
+               return;
+       if (!page_count)
+               return;
+
+       Evas_Object *controller;
+       Page_Item *it;
+       Evas_Coord mw, mh;
+
+       int i = 0;
+       for (i = 0; i < page_count; i++)
+       {
+               it = _create_item(obj, i);
+               wd->page_list = eina_list_append(wd->page_list, it);
+               if (i == 0)
+               {
+                       edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm");
+                       evas_object_geometry_get(it->base, NULL, NULL, &mw, &mh);
+               }
+
+               evas_object_show(it->base);
+
+               evas_object_box_append(wd->hbox, it->base);
+               evas_object_smart_calculate(wd->hbox);
+
+       }
+       int width = (mw+wd->padding)*page_count+mw;
+       evas_object_resize(wd->hbox, width, mh);
+       evas_object_size_hint_min_set(wd->hbox, width, mh);
+       evas_object_size_hint_max_set(wd->hbox, width, mh);
+       evas_object_smart_calculate(wd->hbox);
+       wd->page_count = page_count;
+}
+
+EAPI
+void elm_page_control_page_id_set(Evas_Object *obj, unsigned int page_id)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd)        return;
+
+       if(page_id >= wd->page_count || page_id == wd->cur_page_id) return;
+
+       Page_Item *it;
+       double cur_position = 0.0;
+       it=_page_find(obj, wd->cur_page_id);
+       if(!it) return;
+
+       edje_object_signal_emit(it->base, "elm,state,indicator,off", "elm");
+       it = _page_find(obj, page_id);
+       if(!it) return;
+
+       edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm");
+       wd->cur_page_id=page_id;
+   cur_position = ((double)wd->cur_page_id)/wd->page_count;
+       edje_object_part_drag_value_set(wd->base, "elm.drag.part", cur_position,0);
+}
+
+EAPI
+unsigned int elm_page_control_page_id_get(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd)        return;
+
+       return wd->cur_page_id;
+}
+
diff --git a/src/lib/elm_segment_control.c b/src/lib/elm_segment_control.c
new file mode 100755 (executable)
index 0000000..e743a7d
--- /dev/null
@@ -0,0 +1,757 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @addtogroup SegmentControl SegmentControl
+ *
+ * The SegmentControl button allows for 1 or more selectors to be created to select 1
+ * of a set of options.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ */
+typedef struct _Widget_Data Widget_Data;
+struct _Widget_Data
+{
+   Evas_Object *box;
+   Evas_Object *base;
+   Eina_List *seg_ctrl;
+   Eina_List *queue;
+   int width, height;
+   int id;
+   int item_width;
+
+   Elm_Segment_Item *ani_it;
+   Ecore_Animator *ani;
+   unsigned int count;
+   unsigned int insert_index;
+   unsigned int del_index;
+   unsigned int cur_seg_id;
+};
+
+struct _Elm_Segment_Item
+{
+   Evas_Object *obj;
+   Evas_Object *base;
+   Evas_Object *icon;
+   const char *label;
+       Eina_Bool delete_me : 1;
+   int segment_id;
+};
+
+static void _sizing_eval(Evas_Object *obj);
+static void _signal_segment_on(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _sizing_eval(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _item_free(Evas_Object *obj, Elm_Segment_Item *it);
+static void _del_hook(Evas_Object *obj);
+static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
+static Elm_Segment_Item * _item_find(Evas_Object *obj, unsigned int index);
+static void _update_list(Evas_Object *obj);
+static void _refresh_segment_ids(Evas_Object *obj);
+static void _state_value_set(Evas_Object *obj);
+static void _queue_list(Evas_Object *obj);
+
+static Elm_Segment_Item* _item_new(Evas_Object *obj, const char *label, Evas_Object *icon);
+static Elm_Segment_Item *_item_find(Evas_Object *obj, unsigned int index);
+
+static int * _animator_animate_add_cb(Evas_Object *obj);
+static int * _animator_animate_del_cb(Evas_Object *obj);
+
+
+static void
+_signal_segment_on(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+       Elm_Segment_Item *item = (Elm_Segment_Item *) data;
+       Widget_Data *wd = elm_widget_data_get(item->obj);
+
+       if (!wd)
+               return;
+
+       edje_object_signal_emit(item->base, "elm,state,segment,on", "elm");
+       edje_object_signal_emit(item->base, "elm,state,text,change", "elm");
+       Elm_Segment_Item *it;
+       Eina_List *l;
+       if (item->segment_id == wd->cur_seg_id)
+       {
+               wd->cur_seg_id = item->segment_id;
+               return;
+       }
+       int i = 0;
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               if (it->segment_id == wd->cur_seg_id) {
+                       edje_object_signal_emit(it->base, "elm,state,segment,off", "elm");
+                       edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
+                        break;
+               }
+       }
+       wd->cur_seg_id = item->segment_id;
+   evas_object_smart_callback_call(item->obj, "changed", (void*)wd->cur_seg_id);
+}
+
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+
+       evas_object_size_hint_weight_set(wd->base, 1.0, -1.0);
+       evas_object_size_hint_align_set(wd->base, 1.0, -1.0);
+   evas_object_size_hint_min_set(wd->base, -1, -1);
+       evas_object_size_hint_max_set(wd->base, maxw, maxh);
+   return;
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   _elm_theme_object_set(obj, obj, "segmented-control", "base", "default");
+
+   return;
+}
+
+static void
+_item_free(Evas_Object *obj, Elm_Segment_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   if(wd->seg_ctrl)
+       wd->seg_ctrl = eina_list_remove(wd->seg_ctrl, it);
+
+   if(it->icon) evas_object_del(it->icon);
+   if(it->base) evas_object_del(it->base);
+   if(it->label) eina_stringshare_del(it->label);
+
+   if(it)
+       free(it);
+   it = NULL;
+       return;
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Segment_Item *it;
+   Eina_List *l, *clear = NULL;
+
+   EINA_LIST_FOREACH(wd->seg_ctrl, l, it) clear = eina_list_append(clear, it);
+   EINA_LIST_FREE(clear, it) _item_free(obj, it);
+
+   if(wd)
+       free(wd);
+   wd = NULL;
+
+   return;
+}
+
+
+static void
+_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
+{
+   Widget_Data *wd = data;
+   if (!wd) return;
+   _els_box_layout(o, priv, 1, 0); /* making box layout non homogenous */
+
+   return;
+}
+
+EAPI Evas_Object *
+elm_segment_control_add(Evas_Object *parent)
+{
+       Evas_Object *obj;
+       Evas *e;
+       Widget_Data *wd;
+       Evas_Coord w, h, x, y;
+
+       wd = ELM_NEW(Widget_Data);
+       e = evas_object_evas_get(parent);
+       obj = elm_widget_add(e);
+       elm_widget_type_set(obj, "segmented-control");
+       elm_widget_sub_object_add(parent, obj);
+       elm_widget_data_set(obj, wd);
+       elm_widget_del_hook_set(obj, _del_hook);
+       elm_widget_theme_hook_set(obj, _theme_hook);
+
+       wd->base = edje_object_add(e);
+       _elm_theme_object_set(obj, wd->base, "segmented-control", "base", "default");
+       elm_widget_resize_object_set(obj, wd->base);
+
+       wd->box = evas_object_box_add(e);
+       evas_object_box_layout_set(wd->box, _layout, wd, NULL);
+       elm_widget_sub_object_add(obj, wd->box);
+       edje_object_part_swallow(wd->base, "elm.swallow.content", wd->box);
+       evas_object_show(wd->box);
+
+       edje_object_part_geometry_get(wd->base, "layout", &x, &y, &w, &h);
+       wd->item_width = wd->width = w;
+       wd->height = h;
+       wd->id = 0;
+       wd->del_index = 0;
+       wd->insert_index = 0;
+
+       return obj;
+}
+
+static Elm_Segment_Item*
+_item_new(Evas_Object *obj, const char *label, Evas_Object *icon)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   Elm_Segment_Item *it;
+   it = calloc(1, sizeof(   Elm_Segment_Item));
+   if (!it) return NULL;
+       Evas_Coord mw, mh;
+
+   if(obj) it->obj = obj;
+   it->delete_me = EINA_FALSE;
+   it->segment_id = wd->id;
+
+   it->base = edje_object_add(evas_object_evas_get(obj));
+   _elm_theme_object_set(obj, it->base, "segment", "base", elm_object_style_get(it->base));
+
+   if (it->label) eina_stringshare_del(it->label);
+   if (label)
+        {
+                       it->label = eina_stringshare_add(label);
+        }
+   else
+        {
+                       it->label = NULL;
+        }
+
+   if ((it->icon != icon) && (it->icon))
+        elm_widget_sub_object_del(obj, it->icon);
+   it->icon = icon;
+   if (icon)
+        {
+               elm_widget_sub_object_add(obj, icon);
+               Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+
+               elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+               elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+
+               evas_object_size_hint_weight_set(it->base, 1.0, -1.0);
+               evas_object_size_hint_align_set(it->base, 1.0, -1.0);
+               evas_object_size_hint_min_set(it->base, -1, -1);
+               evas_object_size_hint_max_set(it->base, maxw, maxh);
+        }
+
+          return it;
+}
+
+
+static void _update_list(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd) return;
+
+       Elm_Segment_Item *it;
+       Eina_List *l;
+       int i = 0;
+       wd->count = eina_list_count(wd->seg_ctrl);
+
+       if(wd->count == 1)
+       {
+               it = _item_find(obj, 0);
+               _elm_theme_object_set(obj, it->base, "segment", "base", "single");
+               edje_object_signal_emit(it->base, "elm,state,segment,on", "elm");
+               edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
+               edje_object_signal_emit(it->base, "elm,state,text,change", "elm");
+               edje_object_message_signal_process(it->base);
+
+               edje_object_part_text_set(it->base, "elm.text", it->label);
+
+               edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
+               edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
+               return;
+       }
+
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               if(i==0)
+               {
+                       _elm_theme_object_set(obj, it->base, "segment", "base", "first");
+               }
+               else if(i==wd->count-1)
+               {
+                       _elm_theme_object_set(obj, it->base, "segment", "base", "last");
+               }
+               else
+               {
+                       _elm_theme_object_set(obj, it->base, "segment", "base", "default");
+               }
+
+               edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
+               edje_object_message_signal_process(it->base);
+
+               edje_object_part_text_set(it->base, "elm.text", it->label);
+
+               edje_object_part_swallow(it->base, "elm.swallow.content", it->icon);
+               edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
+               if(wd->cur_seg_id == i)
+               {
+                       edje_object_signal_emit(it->base, "elm,state,segment,on", "elm");
+                       edje_object_signal_emit(it->base, "elm,state,text,change", "elm");
+               }
+               i++;
+       }
+}
+
+
+static void _refresh_segment_ids(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd) return;
+
+       Elm_Segment_Item *it;
+       Eina_List *l;
+
+       if (wd->insert_index && wd->cur_seg_id >= wd->insert_index)
+       {
+               ++wd->cur_seg_id;
+               wd->insert_index = 0;
+       }
+       if (wd->del_index)
+       {
+               if (wd->cur_seg_id >= wd->del_index)
+                       --wd->cur_seg_id;
+               wd->del_index =0;
+       }
+
+       int i = 0;
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               it->segment_id = i;
+               i++;
+       }
+}
+
+static void _state_value_set(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd) return;
+
+       Elm_Segment_Item *it;
+       Eina_List *l;
+   Evas_Coord w, h, mw, mh, x, y, xx, yy;
+   int w1=0, w2;
+
+
+       unsigned int count = eina_list_count(wd->seg_ctrl);
+
+       if(count > 0)
+               wd->item_width = wd->width/count;
+
+
+       if(wd->ani_it)
+       {
+               evas_object_geometry_get(wd->ani_it->base, &x, &y, &w1, NULL);
+               if(wd->ani_it->delete_me)
+               {
+                       w1-=(wd->item_width/15);
+                       if( w1< 0) w1 = 0;
+               }
+               else
+               {
+                       w1+=(wd->item_width/15);
+                       if( w1 > wd->item_width )
+                                       w1 = wd->item_width;
+               }
+
+                       w2 = (wd->width-w1)/(count -1);
+       }
+       else
+                       w2 = wd->item_width;
+
+       int i=0;
+
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0);
+               evas_object_size_hint_weight_set(it->base, 1.0, 1.0);
+               evas_object_size_hint_align_set(it->base, -1.0, -1.0);
+
+               if(wd->ani_it  && it == wd->ani_it)
+               {
+                       evas_object_resize(it->base, w1, wd->height);
+                       evas_object_size_hint_min_set(it->base, w1, wd->height);
+                       evas_object_size_hint_max_set(it->base, w1, wd->height);
+               }
+               else
+               {
+                       evas_object_resize(it->base, w2, wd->height);
+                       evas_object_size_hint_min_set(it->base, w2, wd->height);
+                       evas_object_size_hint_max_set(it->base, w2, wd->height);
+               }
+
+               ++i;
+       }
+
+       return;
+}
+
+
+static int *
+_animator_animate_add_cb(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd) return;
+
+       int w;
+       evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
+
+       if( w <  wd->item_width )
+       {
+        _state_value_set(obj);
+        evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
+                       return ECORE_CALLBACK_RENEW;
+       }
+       else
+        {
+                ecore_animator_del(wd->ani);
+                wd->ani = NULL;
+                wd->ani_it = NULL;
+                       return ECORE_CALLBACK_CANCEL;
+        }
+}
+
+
+static int *
+_animator_animate_del_cb(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd) return;
+
+       int w;
+       evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
+       if( w >  0 )
+       {
+        _state_value_set(obj);
+        evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL);
+                       return ECORE_CALLBACK_RENEW;
+       }
+       else
+        {
+               _item_free(obj, wd->ani_it );
+               _refresh_segment_ids(obj);
+                ecore_animator_del(wd->ani);
+                wd->ani = NULL;
+                wd->ani_it = NULL;
+               _update_list(obj);
+                       return ECORE_CALLBACK_CANCEL;
+        }
+}
+
+static void _queue_list(Evas_Object *obj)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd) return;
+
+       Elm_Segment_Item *it;
+       Eina_List *l;
+       int i = 0;
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               i++;
+       }
+       wd->count = eina_list_count(wd->seg_ctrl);
+}
+
+EAPI Elm_Segment_Item *
+elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if(!wd) return;
+
+   Evas_Object *seg;
+   Elm_Segment_Item *it;
+
+   it = _item_new(obj, label, icon);
+       if(!it)
+               return;
+
+       wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
+
+       _update_list(obj);
+
+         edje_object_signal_callback_add(it->base, "elm,action,segment,click", "elm", _signal_segment_on, it);
+               ++wd->id;
+          _refresh_segment_ids(obj);
+
+       if(animate && it->segment_id)
+          {
+                       if(wd->ani_it == NULL)
+                       {
+                               evas_object_resize(it->base, 1, wd->height);
+                               wd->ani_it = it;
+                               wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
+                       }
+                       else
+                       {
+                               wd->queue = eina_list_append(wd->queue, it);
+                       }
+          }
+          else
+             _state_value_set(obj);
+       evas_object_show( it->base);
+
+       evas_object_box_append(wd->box, it->base);
+       evas_object_smart_calculate(wd->box);
+
+   return it;
+}
+
+
+static Elm_Segment_Item *
+_item_find(Evas_Object *obj, unsigned int index)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd)
+               return NULL;
+
+       Elm_Segment_Item *it;
+       Eina_List *l;
+
+       int i = 0;
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               if (i == index) {
+                       return it;
+               }
+               i++;
+       }
+       return NULL;
+}
+
+
+static Elm_Segment_Item *
+_item_search(Evas_Object *obj, Elm_Segment_Item *item)
+{
+       Widget_Data *wd = elm_widget_data_get(obj);
+       if (!wd)
+               return NULL;
+
+       Elm_Segment_Item *it;
+       Eina_List *l;
+
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               if (it == item) {
+                       return it;
+               }
+       }
+       return NULL;
+}
+
+EAPI void
+elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if(!wd) return;
+
+   Elm_Segment_Item *it, *it_rel;
+
+   it = _item_new(obj, label, icon);
+   it_rel = _item_find(obj, index);
+   if (!it_rel)
+     {
+      wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it);
+     }
+   else
+   {
+      if (!it) return;
+               wd->seg_ctrl = eina_list_prepend_relative(wd->seg_ctrl, it, it_rel);
+   }
+       edje_object_signal_callback_add(it->base, "elm,action,segment,click", "elm", _signal_segment_on, it);
+   wd->insert_index = index;
+       ++wd->id;
+   _refresh_segment_ids(obj);
+
+       _update_list(obj);
+
+
+       if(animate && it->segment_id)
+   {
+               if(wd->ani_it == NULL)
+               {
+                       wd->ani_it = it;
+                       evas_object_resize(it->base, 1, wd->height);
+                       wd->ani = ecore_animator_add( _animator_animate_add_cb, obj );
+               }
+               else
+               {
+                       wd->queue = eina_list_append(wd->queue, it);
+               }
+   }
+   else
+      _state_value_set(obj);
+
+       evas_object_show( it->base);
+
+        if(index >= wd->id-1)
+          {
+               evas_object_box_append(wd->box,  it->base);
+          }
+          else
+          {
+               evas_object_box_insert_at(wd->box,  it->base, index);
+          }
+
+               evas_object_smart_calculate(wd->box);
+
+   return;
+}
+
+
+EAPI void
+elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if(!wd) return;
+
+   if(!item) return;
+
+   Elm_Segment_Item *it;
+   it = _item_search(obj, item);
+
+   if(!it)
+       return;
+   wd->del_index = it->segment_id;
+
+       if(animate && it->segment_id)
+       {
+               if(wd->ani_it == NULL)
+               {
+                       it->delete_me = EINA_TRUE;
+                       wd->ani_it = it;
+                       wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
+               }
+               else
+               {
+                       wd->queue = eina_list_append(wd->queue, it);
+               }
+       }
+       else
+       {
+               evas_object_box_remove(wd->box, it->base);
+               evas_object_smart_calculate(wd->box);
+               _item_free(obj, it);
+          _refresh_segment_ids(obj);
+               _state_value_set(obj);
+               _update_list(obj);
+       }
+       --wd->id;
+   return;
+}
+
+
+EAPI void
+elm_segment_control_delete_segment_at(Evas_Object *obj,  unsigned int index, Eina_Bool animate)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if(!wd) return;
+   Elm_Segment_Item *it, *it_rel;
+
+   it = _item_find(obj, index);
+
+   if(!it)
+       return;
+
+   wd->del_index = index;
+       --wd->id;
+       if(animate && it->segment_id)
+               {
+                       if(wd->ani_it == NULL)
+                       {
+                               wd->ani_it = it;
+                               it->delete_me = EINA_TRUE;
+                               wd->ani = ecore_animator_add( _animator_animate_del_cb, obj );
+                       }
+                       else
+                       {
+                               wd->queue = eina_list_append(wd->queue, it);
+                       }
+               }
+               else
+               {
+                       evas_object_box_remove(wd->box, it->base);
+                       evas_object_smart_calculate(wd->box);
+                       _item_free(obj, it);
+                  _refresh_segment_ids(obj);
+                       _state_value_set(obj);
+               }
+
+       _update_list(obj);
+   return;
+}
+
+
+
+EAPI const char *
+elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index)
+{
+       Elm_Segment_Item *it_rel;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if(!wd) return NULL;
+
+   it_rel = _item_find(obj, index);
+
+   if(it_rel)
+      return it_rel->label;
+
+   return NULL;
+}
+
+
+EAPI Evas_Object *
+elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index)
+{
+       Elm_Segment_Item *seg_rel;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if(!wd) return NULL;
+
+   seg_rel = _item_find(obj, index);
+
+   if(seg_rel)
+       return seg_rel->icon;
+
+   return NULL;
+}
+
+EAPI Elm_Segment_Item *
+elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+       if(!wd || !wd->seg_ctrl) return NULL;
+
+       Elm_Segment_Item *it;
+       Eina_List *l;
+
+       EINA_LIST_FOREACH(wd->seg_ctrl, l, it)
+       {
+               if(it->segment_id == wd->cur_seg_id)
+                       {
+                               * value = wd->cur_seg_id;
+                               return it;
+                       }
+       }
+       return NULL;
+}
+
+EAPI int
+elm_segment_control_get_segment_count(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if(!wd) return 0;
+
+   return wd->id;
+}