Elementary segment_control: Introduced new widget by Govindaraju and Prince.
authorseoz <seoz@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 7 Apr 2011 16:44:54 +0000 (16:44 +0000)
committerseoz <seoz@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 7 Apr 2011 16:44:54 +0000 (16:44 +0000)
Segment Control Widget is a horizontal control made of multiple segment items
together, each segment item is set to equal size, functioning similar to
discrete two state button. Only one segment item can be at selected state.

git-svn-id: https://svn.enlightenment.org/svn/e/trunk/elementary@58461 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

21 files changed:
AUTHORS
data/objects/test.edc
data/themes/default.edc
data/themes/seg_left_normal.png [new file with mode: 0644]
data/themes/seg_left_pressed.png [new file with mode: 0644]
data/themes/seg_left_selected.png [new file with mode: 0644]
data/themes/seg_middle_normal.png [new file with mode: 0644]
data/themes/seg_middle_pressed.png [new file with mode: 0644]
data/themes/seg_middle_selected.png [new file with mode: 0644]
data/themes/seg_right_normal.png [new file with mode: 0644]
data/themes/seg_right_pressed.png [new file with mode: 0644]
data/themes/seg_right_selected.png [new file with mode: 0644]
data/themes/seg_single_normal.png [new file with mode: 0644]
data/themes/seg_single_pressed.png [new file with mode: 0644]
data/themes/seg_single_selected.png [new file with mode: 0644]
src/bin/Makefile.am
src/bin/test.c
src/bin/test_segment_control.c [new file with mode: 0644]
src/lib/Elementary.h.in
src/lib/Makefile.am
src/lib/elm_segment_control.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index 25a2683..496ed8b 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -38,3 +38,5 @@ Tom Hacohen <tom@stosb.com>
 Aharon Hillel <a.hillel@partner.samsung.com>
 Jonathan Atton (Watchwolf) <jonathan.atton@gmail.com>
 Shinwoo Kim <kimcinoo@gmail.com>
+Govindaraju SM <govi.sm@samsung.com> <govism@gmail.com>
+Prince Kumar Dubey <prince.dubey@samsung.com> <prince.dubey@gmail.com>
index 8efdca8..c538d72 100644 (file)
@@ -611,6 +611,139 @@ collections {
          }
       }
    }
+      group { name: "segment_test";
+      parts{
+         part {
+            name: "bg";
+            type: RECT;
+            scale: 1; //allow scaling
+            description {
+            state: "default" 0.0;
+            visible: 0;
+            min: 480 400;
+            color:  0 0 0 0;
+            }
+         }
+         part { name: "top_padding";
+            type: RECT;
+            scale: 1; //allow scaling
+            description {
+               state: "default" 0.0;
+               visible: 0;
+               min : 250 30; //minimum size for gap filler
+               fixed: 0 1;
+               rel1 { relative: 0 0; }
+               rel2 { relative: 1 0; }
+               color:  0 0 0 0;
+               align: 0 0;
+            }
+         }
+         part { name: "segment1";
+            type: SWALLOW;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               fixed: 1 1;
+               rel1 { relative: 0.0 1.0; to_x: "bg"; to_y: "top_padding"; }
+               rel2 { relative: 1.0 0.25; to: "bg"; }
+               align: 0.5 0.0;
+            }
+         }
+         part { name: "segment1_bottom_padding";
+            type: RECT;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               visible: 0;
+               min : 250 10;
+               max : 250 10;
+               fixed: 1 1;
+               align: 0.5 0;
+               rel1 { relative: 0 1.0; to_y: "segment1"; }
+               rel2 { relative: 1 1.0; to_y: "segment1"; }
+               color: 0 255 0 0;
+            }
+         }
+         part { name: "segment2";
+            type: SWALLOW;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               fixed: 1 1;
+               rel1 { relative: 0.1 1.0; to_x: "bg"; to_y: "segment1_bottom_padding"; }
+               rel2 { relative: 0.9 160/400; to: "bg"; }
+               align: 0.5 0.0;
+            }
+         }
+         part { name: "segment2_bottom_padding";
+            type: RECT;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               visible: 0;
+               min : 250 10;
+               max : 250 10;
+               fixed: 1 1;
+               align: 0.5 0;
+               rel1 { relative: 0 1.0; to_y: "segment2"; }
+               rel2 { relative: 1 1.0; to_y: "segment2"; }
+               color: 0 255 0 0;
+            }
+         }
+         part { name: "segment3";
+            type: SWALLOW;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               fixed: 1 1;
+               rel1 { relative: 0.2 1.0; to_x: "bg"; to_y: "segment2_bottom_padding"; }
+               rel2 { relative: 0.8 0.6; to: "bg"; }
+               align: 0.5 0.0;
+            }
+         }
+         part { name: "segment3_bottom_padding";
+            type: RECT;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               visible: 0;
+               min : 250 10;
+               max : 250 10;
+               fixed: 1 1;
+               align: 0.5 0;
+               rel1 { relative: 0 1.0; to_y: "segment3"; }
+               rel2 { relative: 1 1.0; to_y: "segment3"; }
+               color: 0 255 0 0;
+            }
+         }
+         part { name: "segment4";
+            type: SWALLOW;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               fixed: 1 1;
+               rel1 { relative: 0.3 1.0; to_x: "bg"; to_y: "segment3_bottom_padding"; }
+               rel2 { relative: 0.7 340/400; to: "bg"; }
+               align: 0.5 0.0;
+            }
+         }
+         part { name: "btn1_bottom_padding";
+            type: RECT;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               visible: 0;
+               min : 250 100;
+               max : 250 100;
+               fixed: 1 1;
+               align: 0.5 0;
+               rel1 { relative: 0 1.0; to_y: "segment4"; }
+               rel2 { relative: 1 1.0; to_y: "segment4"; }
+               color: 0 255 0 0;
+            }
+         }
+       }
+   }
    group { name: "bg_overlay";
       images {
         image: "clo.png" LOSSY 60;
index 497018e..2599027 100644 (file)
@@ -36048,6 +36048,637 @@ collections {
       }
    }
 
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/segment_control/base/default";
+#define SEGMENT_TYPE_SINGLE 1
+#define SEGMENT_TYPE_LEFT 2
+#define SEGMENT_TYPE_MIDDLE 3
+#define SEGMENT_TYPE_RIGHT 4
+#define SEGMENT_STATE_NORMAL 1
+#define SEGMENT_STATE_PRESSED 2
+#define SEGMENT_STATE_SELECTED 3
+#define SEGMENT_STATUS_ENABLED 0
+#define SEGMENT_STATUS_DISABLED 1
+      parts {
+         part { name: "bg";
+            type: RECT;
+            mouse_events: 0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+               min: 100 40;
+            }
+         }
+      }
+   }
+   group { name: "elm/segment_control/item/default";
+      data.item: "label.wrap.part" "label.bg";
+      styles {
+         style { name: "seg_text_style_normal";
+            base: "font=Sans font_size=16 style=shadow \
+            shadow_color=#2924224d \
+            align=center \
+            color=#ffffffff wrap=char text_class=label";
+            tag:  "br" "\n";
+            tag:  "hilight" "+ font=Sans:style=Bold";
+            tag:  "tab" "\t";
+         }
+         style { name: "seg_text_style_selected";
+            base: "font=Sans:style=Bold font_size=16 style=shadow \
+            shadow_color=#aaaaaa4d \
+            align=center \
+            color=#111111ff wrap=char text_class=label";
+            tag:  "br" "\n";
+            tag:  "hilight" "+ font=Sans:style=Bold";
+            tag:  "b" "+ font=Sans:style=Bold";
+            tag:  "tab" "\t";
+         }
+         style { name: "seg_text_style_disabled";
+            base: "font=Sans:style=Medium font_size=16 style=shadow \
+            shadow_color=#2924224d \
+            align=center color=#2924224d \
+            wrap=char text_class=label";
+            tag:  "br" "\n";
+            tag:  "hilight" "+ font=Sans:style=Bold";
+            tag:  "b" "+ font=Sans:style=Bold";
+            tag:  "tab" "\t";
+         }
+      }
+      images {
+         image: "seg_single_pressed.png" COMP;
+         image: "seg_single_selected.png" COMP;
+         image: "seg_single_normal.png" COMP;
+
+         image: "seg_left_pressed.png" COMP;
+         image: "seg_left_selected.png" COMP;
+         image: "seg_left_normal.png" COMP;
+
+         image: "seg_middle_pressed.png" COMP;
+         image: "seg_middle_selected.png" COMP;
+         image: "seg_middle_normal.png" COMP;
+
+         image: "seg_right_pressed.png" COMP;
+         image: "seg_right_selected.png" COMP;
+         image: "seg_right_normal.png" COMP;
+      }
+      parts {
+         part { name: "segment";
+            mouse_events: 1;
+            scale: 1;
+            description { state: "default" 0.0;
+               min: 1 1;
+               visible: 0;
+               image {
+                  normal: "seg_single_normal.png";
+                  border: 7 7 7 7;
+                  border_scale: 1;
+                  middle: 1;
+               }
+            }
+            description { state: "default_single" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_single_normal.png";
+                  border: 7 7 7 7;
+               }
+            }
+            description { state: "default_left" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+               normal: "seg_left_normal.png";
+                  border:  6 1 7 7;
+               }
+            }
+            description { state: "default_right" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_right_normal.png";
+                  border: 1 6 7 7;
+               }
+            }
+            description { state: "default_middle" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_middle_normal.png";
+                  border: 2 2 2 2;
+               }
+            }
+            description { state: "pressed_single" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_single_pressed.png";
+                  border: 7 7 7 7;
+               }
+            }
+            description { state: "pressed_left" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_left_pressed.png";
+                  border:  6 1 7 7;
+               }
+            }
+            description { state: "pressed_right" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_right_pressed.png";
+                  border: 1 6 7 7;
+               }
+            }
+            description { state: "pressed_middle" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_middle_pressed.png";
+                  border: 1 1 2 2;
+               }
+            }
+            description { state: "selected_single" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_single_selected.png";
+                  border: 7 7 7 7;
+               }
+            }
+            description { state: "selected_left" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_left_selected.png";
+                  border:  6 3 7 7;
+               }
+            }
+            description { state: "selected_right" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_right_selected.png";
+                  border: 3 6 7 7;
+               }
+            }
+            description { state: "selected_middle" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_middle_selected.png";
+                  border: 3 3 3 3;
+               }
+            }
+         }
+         part { name: "padding_left";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               align: 0.0 0.0;
+               rel1.relative: 0.0 0.0;
+               rel2.relative: 0.0 1.0;
+               min: 2 2;
+               max: 2 2;
+               fixed: 1 0;
+               color: 0 0 0 0;
+            }
+         }
+         part { name: "padding_right";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               align: 1.0 0.0;
+               rel1.relative: 1.0 0.0;
+               rel2.relative: 1.0 1.0;
+               min: 2 2;
+               max: 2 2;
+               fixed: 1 0;
+               color: 0 0 0 0;
+            }
+         }
+         part { name: "padding_top";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               align: 0.0 0.0;
+               rel1.relative: 0.0 0.0;
+               rel2.relative: 1.0 0.0;
+               min: 2 2;
+               max: 2 2;
+               fixed: 0 1;
+               color: 0 0 0 0;
+            }
+         }
+         part { name: "padding_bottom";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               align: 1.0 1.0;
+               rel1.relative: 0.0 1.0;
+               rel2.relative: 1.0 1.0;
+               min: 2 2;
+               max: 2 2;
+               fixed: 0 1;
+               color: 0 0 0 0;
+            }
+         }
+         part { name: "icon.bg";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 1;
+               fixed: 1 0;
+               rel1 {
+                  to_x: "padding_left";
+                  to_y: "padding_top";
+                  relative: 1.0 1.0;
+               }
+               rel2 {
+                  to: "elm.swallow.icon";
+                  relative: 1.0 1.0;
+               }
+               align: 0.0 0.5;
+               color: 0 0 0 0;
+            }
+         }
+         part { name: "padding_icon_text";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0; //when only icon or no icon is there
+               align: 0.0 0.0;
+               rel1 {
+                  to: "icon.bg";
+                  relative: 1.0 0.0;
+               }
+               rel2 {
+                  to: "icon.bg";
+                  relative: 1.0 1.0;
+               }
+               fixed: 1 0;
+               min: 0 0;
+               color: 0 0 0 0;
+            }
+            description { state: "icononly" 0.0;
+               inherit: "default" 0.0;
+            }
+            description { state: "visible" 0.0; //when icon is visible
+               inherit: "default" 0.0;
+               min: 2 0;
+            }
+         }
+         part { name: "elm.swallow.icon";
+            type: SWALLOW;
+            scale: 1;
+            description { state: "default" 0.0;
+               visible: 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "padding_left";
+                  to_y: "padding_top";
+                  relative: 1.0 1.0;
+               }
+               rel2 {
+                  to_y: "padding_bottom";
+                  relative: 0.0 0.0;
+               }
+               fixed: 1 0;
+               aspect: 1.0 1.0;
+               aspect_preference: BOTH;
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               rel2 {
+                  to_y: "padding_bottom";
+                  relative: 0.3 0.0;
+               }
+            }
+            description { state: "icononly" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               rel2 {
+                  to_x: "padding_right";
+                  to_y: "padding_bottom";
+                  relative: 0.0 0.0;
+               }
+               align: 0.5 0.5;
+            }
+         }
+         part { name: "elm.text";
+            type: TEXT;
+            mouse_events: 0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               visible: 0;
+               fixed: 1 1;
+               min: 1 1;
+               rel1 {
+                  to_x: "padding_icon_text";
+                  relative: 1.0 1.0;
+               }
+               rel2 {
+                  to_x: "padding_right";
+                  relative: 0.0 0.0;
+               }
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+               text {
+                  font: "Sans";
+                  ellipsis: 0.0;
+                  fit: 1 1;
+                  size: 24;
+                  size_range: 8 36;
+                  min: 0 1;
+               }
+            }
+            description { state: "normal" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+            }
+            description { state: "pressed" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 0 0 0 255;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 50 50 50 255;
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 200 200 200 255;
+            }
+         }
+         part { name: "disabler";
+            repeat_events: 0;
+            scale: 1;
+            description { state: "default" 0.0;
+               visible: 0;
+               fixed: 1 1;
+               min: 1 1;
+               align: 0.0 0.5;
+               rel1 { relative: 0.0 0.0; to: "segment";}
+               rel2 { relative: 1.0 1.0; to: "segment";}
+               color: 255 255 255 150;
+            }
+            description { state: "disabled_single" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_single_normal.png";
+                  border: 7 7 7 7;
+               }
+            }
+            description { state: "disabled_left" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_left_normal.png";
+                  border:  6 1 7 7;
+               }
+            }
+            description { state: "disabled_right" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_right_normal.png";
+                  border: 1 6 7 7;
+               }
+            }
+            description { state: "disabled_middle" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               image {
+                  normal: "seg_middle_normal.png";
+                  border: 2 2 2 2;
+               }
+            }
+         }
+      }
+      programs {
+         script {
+            public seg_type; // Single, Left, Middle, Right.
+            public seg_state; // Normal/Default, Pressed, Selected.
+            public seg_status;// Enabled/Default, Disabled
+
+            public update_state() {
+               new type, state, disabled;
+               type = get_int(seg_type);
+               state = get_int(seg_state);
+               disabled = get_int(seg_status);
+
+               if(state == SEGMENT_STATE_NORMAL)
+                 {
+                    if(type == SEGMENT_TYPE_SINGLE)
+                      set_state(PART:"segment", "default_single", 0.0);
+                    else if(type == SEGMENT_TYPE_LEFT)
+                      set_state(PART:"segment", "default_left", 0.0);
+                    else if(type == SEGMENT_TYPE_MIDDLE)
+                      set_state(PART:"segment", "default_middle", 0.0);
+                    else if(type == SEGMENT_TYPE_RIGHT)
+                      set_state(PART:"segment", "default_right", 0.0);
+                    set_state(PART:"elm.text", "normal", 0.0);
+                 }
+               else if(state == SEGMENT_STATE_PRESSED)
+                 {
+                    if(type == SEGMENT_TYPE_SINGLE)
+                      set_state(PART:"segment", "pressed_single", 0.0);
+                    else if(type == SEGMENT_TYPE_LEFT)
+                      set_state(PART:"segment", "pressed_left", 0.0);
+                    else if(type == SEGMENT_TYPE_MIDDLE)
+                      set_state(PART:"segment", "pressed_middle", 0.0);
+                    else if(type == SEGMENT_TYPE_RIGHT)
+                      set_state(PART:"segment", "pressed_right", 0.0);
+                    set_state(PART:"elm.text", "pressed", 0.0);
+                 }
+               else if(state == SEGMENT_STATE_SELECTED)
+                 {
+                    if(type == SEGMENT_TYPE_SINGLE)
+                      set_state(PART:"segment", "selected_single", 0.0);
+                    else if(type == SEGMENT_TYPE_LEFT)
+                      set_state(PART:"segment", "selected_left", 0.0);
+                    else if(type == SEGMENT_TYPE_MIDDLE)
+                      set_state(PART:"segment", "selected_middle", 0.0);
+                    else if(type == SEGMENT_TYPE_RIGHT)
+                      set_state(PART:"segment", "selected_right", 0.0);
+                    set_state(PART:"elm.text", "selected", 0.0);
+                 }
+               if(disabled == SEGMENT_STATUS_DISABLED)
+                 {
+                    if(type == SEGMENT_TYPE_SINGLE)
+                      set_state(PART:"disabler", "disabled_single", 0.0);
+                    else if(type == SEGMENT_TYPE_LEFT)
+                      set_state(PART:"disabler", "disabled_left", 0.0);
+                    else if(type == SEGMENT_TYPE_MIDDLE)
+                      set_state(PART:"disabler", "disabled_middle", 0.0);
+                    else if(type == SEGMENT_TYPE_RIGHT)
+                      set_state(PART:"disabler", "disabled_right", 0.0);
+                    set_state(PART:"elm.text", "disabled", 0.0);
+                 }
+            }
+         }
+         program {
+            name: "segment_type_s";
+            signal: "elm,type,segment,single";
+            source: "elm";
+            script {
+               set_int(seg_type, SEGMENT_TYPE_SINGLE);
+               update_state();
+            }
+         }
+         program {
+            name: "segment_type_l";
+            signal: "elm,type,segment,left";
+            source: "elm";
+            script {
+               set_int(seg_type, SEGMENT_TYPE_LEFT);
+               update_state();
+            }
+         }
+         program {
+            name: "segment_type_m";
+            signal: "elm,type,segment,middle";
+            source: "elm";
+            script {
+               set_int(seg_type, SEGMENT_TYPE_MIDDLE);
+               update_state();
+            }
+         }
+         program {
+            name: "segment_type_r";
+            signal: "elm,type,segment,right";
+            source: "elm";
+            script {
+               set_int(seg_type, SEGMENT_TYPE_RIGHT);
+               update_state();
+            }
+         }
+         program {
+            name: "normal_segment";
+            signal: "elm,state,segment,normal";
+            source: "elm";
+            script {
+               set_int(seg_state, SEGMENT_STATE_NORMAL);
+               update_state();
+            }
+         }
+         program {
+            name: "pressed_segment";
+            signal: "elm,state,segment,pressed";
+            source: "elm";
+            script {
+               set_int(seg_state, SEGMENT_STATE_PRESSED);
+               update_state();
+            }
+         }
+         program {
+            name: "selected_segment";
+            signal: "elm,state,segment,selected";
+            source: "elm";
+            script {
+               set_int(seg_state, SEGMENT_STATE_SELECTED);
+               update_state();
+            }
+         }
+         program { name: "disable_segment";
+            signal: "elm,state,disabled";
+            source: "elm";
+            script {
+               set_int(seg_status, SEGMENT_STATUS_DISABLED);
+               update_state();
+            }
+         }
+         program { name: "enable_segment";
+            signal: "elm,state,enabled";
+            source: "elm";
+            script {
+               set_int(seg_status, SEGMENT_STATUS_ENABLED);
+               update_state();
+            }
+         }
+         program { name: "text_show";
+            signal: "elm,state,text,visible";
+            source: "elm";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.swallow.icon", st, 30, vl);
+               if (!strcmp(st, "icononly"))
+                 {
+                    set_state(PART:"elm.swallow.icon", "visible", 0.0);
+                    set_state(PART:"padding_icon_text", "visible", 0.0);
+                 }
+               get_state(PART:"elm.text", st, 30, vl);
+               if (!strcmp(st, "selected"))
+                  set_state(PART:"elm.text", "selected", 0.0);
+               else
+                  set_state(PART:"elm.text", "normal", 0.0);
+            }
+         }
+         program { name: "text_hide";
+            signal: "elm,state,text,hidden";
+            source: "elm";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.swallow.icon", st, 30, vl);
+               if (!strcmp(st, "visible"))
+                 {
+                    set_state(PART:"elm.swallow.icon", "icononly", 0.0);
+                    set_state(PART:"padding_icon_text", "icononly", 0.0);
+                 }
+               set_state(PART:"elm.text", "default", 0.0);
+            }
+         }
+         program { name: "icon_show";
+            signal: "elm,state,icon,visible";
+            source: "elm";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.text", st, 30, vl);
+               if ((!strcmp(st, "normal")) || (!strcmp(st, "selected")))
+                 {
+                    set_state(PART:"elm.swallow.icon", "visible", 0.0);
+                    set_state(PART:"padding_icon_text", "visible", 0.0);
+                 }
+               else
+                 {
+                    set_state(PART:"elm.swallow.icon", "icononly", 0.0);
+                    set_state(PART:"padding_icon_text", "icononly", 0.0);
+                 }
+            }
+         }
+         program { name: "icon_hide";
+            signal: "elm,state,icon,hidden";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.swallow.icon";
+         }
+      }
+#undef SEGMENT_TYPE_SINGLE
+#undef SEGMENT_TYPE_LEFT
+#undef SEGMENT_TYPE_MIDDLE
+#undef SEGMENT_TYPE_RIGHT
+#undef SEGMENT_STATE_NORMAL
+#undef SEGMENT_STATE_PRESSED
+#undef SEGMENT_STATE_SELECTED
+#undef SEGMENT_STATUS_ENABLED
+#undef SEGMENT_STATUS_DISABLED
+   }
+
    /* a simple title layout, with a label and two icons */
    group { name: "elm/layout/application/titlebar";
       images {
diff --git a/data/themes/seg_left_normal.png b/data/themes/seg_left_normal.png
new file mode 100644 (file)
index 0000000..703c363
Binary files /dev/null and b/data/themes/seg_left_normal.png differ
diff --git a/data/themes/seg_left_pressed.png b/data/themes/seg_left_pressed.png
new file mode 100644 (file)
index 0000000..347c607
Binary files /dev/null and b/data/themes/seg_left_pressed.png differ
diff --git a/data/themes/seg_left_selected.png b/data/themes/seg_left_selected.png
new file mode 100644 (file)
index 0000000..c2e1546
Binary files /dev/null and b/data/themes/seg_left_selected.png differ
diff --git a/data/themes/seg_middle_normal.png b/data/themes/seg_middle_normal.png
new file mode 100644 (file)
index 0000000..4bd183a
Binary files /dev/null and b/data/themes/seg_middle_normal.png differ
diff --git a/data/themes/seg_middle_pressed.png b/data/themes/seg_middle_pressed.png
new file mode 100644 (file)
index 0000000..79fbe0f
Binary files /dev/null and b/data/themes/seg_middle_pressed.png differ
diff --git a/data/themes/seg_middle_selected.png b/data/themes/seg_middle_selected.png
new file mode 100644 (file)
index 0000000..368d95f
Binary files /dev/null and b/data/themes/seg_middle_selected.png differ
diff --git a/data/themes/seg_right_normal.png b/data/themes/seg_right_normal.png
new file mode 100644 (file)
index 0000000..3d719f8
Binary files /dev/null and b/data/themes/seg_right_normal.png differ
diff --git a/data/themes/seg_right_pressed.png b/data/themes/seg_right_pressed.png
new file mode 100644 (file)
index 0000000..e93ae20
Binary files /dev/null and b/data/themes/seg_right_pressed.png differ
diff --git a/data/themes/seg_right_selected.png b/data/themes/seg_right_selected.png
new file mode 100644 (file)
index 0000000..6037721
Binary files /dev/null and b/data/themes/seg_right_selected.png differ
diff --git a/data/themes/seg_single_normal.png b/data/themes/seg_single_normal.png
new file mode 100644 (file)
index 0000000..e619e27
Binary files /dev/null and b/data/themes/seg_single_normal.png differ
diff --git a/data/themes/seg_single_pressed.png b/data/themes/seg_single_pressed.png
new file mode 100644 (file)
index 0000000..ff90a24
Binary files /dev/null and b/data/themes/seg_single_pressed.png differ
diff --git a/data/themes/seg_single_selected.png b/data/themes/seg_single_selected.png
new file mode 100644 (file)
index 0000000..116ce68
Binary files /dev/null and b/data/themes/seg_single_selected.png differ
index cd124a7..b3bb98e 100644 (file)
@@ -94,6 +94,7 @@ test_diskselector.c \
 test_colorselector.c \
 test_ctxpopup.c \
 test_bubble.c \
+test_segment_control.c \
 test_store.c
 
 elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la \
index 78577ee..1b8e2b3 100644 (file)
@@ -120,6 +120,7 @@ void test_diskselector(void *data, Evas_Object *obj, void *event_info);
 void test_colorselector(void *data, Evas_Object *obj, void *event_info);
 void test_ctxpopup(void *data, Evas_Object *obj, void *event_info);
 void test_bubble(void *data, Evas_Object *obj, void *event_info);
+void test_segment_control(void *data, Evas_Object *obj, void *event_info);
 void test_store(void *data, Evas_Object *obj, void *event_info);
 
 struct elm_test
@@ -373,6 +374,7 @@ my_win_main(char *autorun)
    ADD_TEST("Color Selector", test_colorselector);
    ADD_TEST("Ctxpopup", test_ctxpopup);
    ADD_TEST("Bubble", test_bubble);
+   ADD_TEST("Segment Control", test_segment_control);
    ADD_TEST("Store", test_store);
 #undef ADD_TEST
 
diff --git a/src/bin/test_segment_control.c b/src/bin/test_segment_control.c
new file mode 100644 (file)
index 0000000..4a45fb8
--- /dev/null
@@ -0,0 +1,105 @@
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#ifndef ELM_LIB_QUICKLAUNCH
+
+void
+test_segment_control(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *win, *bg, *ic, *ic1, *ic2, *ic3, *ic4, *ic5;
+   Elm_Segment_Item *it1, *it2, *it3, *it4, *it5;
+
+   Evas_Object * in_layout;
+   Evas_Object *segment1, *segment2, *segment3, *segment4;
+   char buf[PATH_MAX];
+   char buf1[PATH_MAX];
+   char buf2[PATH_MAX];
+   char buf3[PATH_MAX];
+   char buf4[PATH_MAX];
+   char buf5[PATH_MAX];
+   char buf6[PATH_MAX];
+
+   win = elm_win_add(NULL, "segmentcontrol", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Segment Control");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   in_layout = elm_layout_add( win );
+   elm_win_resize_object_add(win, in_layout);
+   snprintf(buf, sizeof(buf), "%s/objects/test.edj", PACKAGE_DATA_DIR);
+   elm_layout_file_set(in_layout, buf, "segment_test");
+   evas_object_size_hint_weight_set(in_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+   ic = elm_icon_add(in_layout);
+   snprintf(buf1, sizeof(buf1), "%s/images/logo.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf1, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+
+   ic1 = elm_icon_add(in_layout);
+   snprintf(buf2, sizeof(buf2), "%s/images/logo.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic1, buf2, NULL);
+   evas_object_size_hint_aspect_set(ic1, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+
+   segment1 = elm_segment_control_add(win);
+   it1 = elm_segment_control_item_add(segment1, NULL, "Only Text");
+   it2 = elm_segment_control_item_add(segment1, ic, NULL);
+   elm_segment_control_item_selected_set(it2, EINA_TRUE);
+   it3 = elm_segment_control_item_add(segment1, ic1, "Text_Icon_test");
+   it4 = elm_segment_control_item_add(segment1, NULL, "Seg4");
+   it5 = elm_segment_control_item_add(segment1, NULL, "Seg5");
+
+   segment2 = elm_segment_control_add(win);
+   it1 = elm_segment_control_item_add(segment2, NULL, "SegmentItem");
+   it2 = elm_segment_control_item_add(segment2, NULL, "SegmentItem");
+   elm_segment_control_item_selected_set(it2, EINA_TRUE);
+   it3 = elm_segment_control_item_add(segment2, NULL, "SegmentControlItem");
+   it4 = elm_segment_control_item_add(segment2, NULL, "SegmentItem");
+
+   ic2 = elm_icon_add(in_layout);
+   snprintf(buf3, sizeof(buf3), "%s/images/logo.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic2, buf3, NULL);
+   evas_object_size_hint_aspect_set(ic2, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+
+   ic3 = elm_icon_add(in_layout);
+   snprintf(buf4, sizeof(buf4), "%s/images/logo.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic3, buf4, NULL);
+   evas_object_size_hint_aspect_set(ic3, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+
+   ic4 = elm_icon_add(in_layout);
+   snprintf(buf5, sizeof(buf5), "%s/images/logo.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic4, buf5, NULL);
+   evas_object_size_hint_aspect_set(ic4, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+
+   segment3 = elm_segment_control_add(win);
+   it1 = elm_segment_control_item_add(segment3, ic2, NULL);
+   it2 = elm_segment_control_item_add(segment3, ic3, NULL);
+   elm_segment_control_item_selected_set(it2, EINA_TRUE);
+   it3 = elm_segment_control_item_add(segment3, ic4, NULL);
+
+   ic5 = elm_icon_add(in_layout);
+   snprintf(buf6, sizeof(buf6), "%s/images/logo.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic5, buf6, NULL);
+   evas_object_size_hint_aspect_set(ic5, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+
+   segment4 = elm_segment_control_add(win);
+   it1 = elm_segment_control_item_add(segment4, NULL, "Disabled");
+   it2 = elm_segment_control_item_add(segment4, ic5, "Disabled");
+   elm_segment_control_item_selected_set(it2, EINA_TRUE);
+   it3 = elm_segment_control_item_add(segment4, NULL, "Disabled");
+   elm_object_disabled_set(segment4, EINA_TRUE);
+
+   elm_layout_content_set(in_layout, "segment1", segment1);
+   elm_layout_content_set(in_layout, "segment2", segment2);
+   elm_layout_content_set(in_layout, "segment3", segment3);
+   elm_layout_content_set(in_layout, "segment4", segment4);
+
+   evas_object_show(in_layout);
+
+   evas_object_show(win);
+}
+#endif
index 72722f7..89c12b6 100644 (file)
@@ -2780,6 +2780,24 @@ extern "C" {
   EAPI const Elm_Store        *elm_store_item_store_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
   EAPI const Elm_Genlist_Item *elm_store_item_genlist_item_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
 
+   /* SegmentControl */
+   typedef struct _Elm_Segment_Item Elm_Segment_Item;
+   EAPI Evas_Object      *elm_segment_control_add(Evas_Object *parent) EINA_ARG_NONNULL(1);
+   EAPI Elm_Segment_Item *elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon, const char *label) EINA_ARG_NONNULL(1);
+   EAPI Elm_Segment_Item *elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon, const char *label, int index) EINA_ARG_NONNULL(1);
+   EAPI void              elm_segment_control_item_del(Elm_Segment_Item *it) EINA_ARG_NONNULL(1);
+   EAPI void              elm_segment_control_item_del_at(Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
+   EAPI int               elm_segment_control_item_count_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI Elm_Segment_Item *elm_segment_control_item_get(const Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
+   EAPI const char       *elm_segment_control_item_label_get(const Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
+   EAPI void              elm_segment_control_item_label_set(Elm_Segment_Item* it, const char* label) EINA_ARG_NONNULL(1);
+   EAPI Evas_Object      *elm_segment_control_item_icon_get(const Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
+   EAPI void              elm_segment_control_item_icon_set(Elm_Segment_Item *it, Evas_Object *icon) EINA_ARG_NONNULL(1);
+   EAPI int               elm_segment_control_item_index_get(const Elm_Segment_Item *it) EINA_ARG_NONNULL(1);
+   EAPI Evas_Object      *elm_segment_control_item_object_get(const Elm_Segment_Item *it) EINA_ARG_NONNULL(1);
+   EAPI Elm_Segment_Item *elm_segment_control_item_selected_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void              elm_segment_control_item_selected_set(Elm_Segment_Item *it, Eina_Bool select) EINA_ARG_NONNULL(1);
+
 #ifdef __cplusplus
 }
 #endif
index 5708e56..0d0ac23 100644 (file)
@@ -94,6 +94,7 @@ elm_calendar.c \
 elm_flipselector.c \
 elm_diskselector.c \
 elm_colorselector.c \
+elm_segment_control.c \
 \
 elc_anchorblock.c \
 elc_anchorview.c \
diff --git a/src/lib/elm_segment_control.c b/src/lib/elm_segment_control.c
new file mode 100644 (file)
index 0000000..809b38d
--- /dev/null
@@ -0,0 +1,849 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup SegmentControl SegmentControl
+ *
+ * SegmentControl Widget is a horizontal control made of multiple segment items,
+ * each segment item functioning similar to discrete two state button. A segment
+ * control groups the the items together and provides compact single button with
+ * multiple equal size segments. Segment item size is determined by base widget
+ * size and the number of items added.
+ * Only one Segment item can be at selected state. A segment item can display
+ * combination of Text and any Evas_Object like Images or other widget.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * "changed" -when the user clicks on a segment item which is not previously
+ *            selected and get selected. The event_info parameter is the
+ *            segment item index.
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *obj;
+   Evas_Object *base;
+   Eina_List *seg_items;
+   int item_count;
+   Elm_Segment_Item *selected_item;
+   int item_width;
+};
+
+struct _Elm_Segment_Item
+{
+   Elm_Widget_Item base;
+   Evas_Object *icon;
+   const char *label;
+   int seg_index;
+};
+
+static const char *widtype = NULL;
+static void _sizing_eval(Evas_Object *obj);
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _item_free(Elm_Segment_Item *it);
+static void _segment_off(Elm_Segment_Item *it);
+static void _segment_on(Elm_Segment_Item *it);
+static void _position_items(Widget_Data *wd);
+static void _on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj
+                            __UNUSED__, void *event_info __UNUSED__);
+static void _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj
+                      __UNUSED__, void *event_info __UNUSED__);
+static void _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj
+                        __UNUSED__, void *event_info __UNUSED__);
+static void _swallow_item_objects(Elm_Segment_Item *it);
+static void _update_list(Widget_Data *wd);
+static Elm_Segment_Item * _item_find(const Evas_Object *obj, int index);
+static Elm_Segment_Item* _item_new(Evas_Object *obj, Evas_Object *icon,
+                                   const char *label);
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd;
+   Evas_Coord minw = -1, minh = -1;
+   Evas_Coord w, h;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh);
+
+   evas_object_size_hint_min_get(obj, &w, &h);
+   if (w > minw) minw = w;
+   if (h > minh) minh = h;
+   evas_object_size_hint_min_set(obj, minw, minh);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Elm_Segment_Item *it;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   EINA_LIST_FREE(wd->seg_items, it) _item_free(it);
+
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Eina_List *l;
+   Eina_Bool rtl;
+   Elm_Segment_Item *it;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   _elm_widget_mirrored_reload(obj);
+   rtl = elm_widget_mirrored_get(obj);
+   edje_object_mirrored_set(wd->base, rtl);
+
+   _elm_theme_object_set(obj, wd->base, "segment_control", "base",
+                         elm_widget_style_get(obj));
+   edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base)
+                         *_elm_config->scale);
+
+   EINA_LIST_FOREACH(wd->seg_items, l, it)
+     {
+        _elm_theme_object_set(obj, it->base.view, "segment_control",
+                              "item", elm_widget_style_get(obj));
+        edje_object_scale_set(it->base.view, elm_widget_scale_get(it->base.view)
+                              *_elm_config->scale);
+        edje_object_mirrored_set(it->base.view, rtl);
+     }
+
+   _update_list(wd);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _update_list(wd);
+}
+
+// TODO:  Elm_widget elm_widget_focus_list_next_get  supports only Elm_widget list,
+// Not the Elm_Widget_item. Focus switching with in widget not supported until
+// it is supported in elm_widget
+#if 0
+static void *
+_elm_list_data_get(const Eina_List *list)
+{
+   Elm_Segment_Item *it = eina_list_data_get(list);
+
+   if (it) return NULL;
+
+   edje_object_signal_emit(it->base.view, "elm,state,segment,selected", "elm");
+   return it->base.view;
+}
+
+static Eina_Bool
+_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir,
+                 Evas_Object **next)
+{
+   static int count=0;
+   Widget_Data *;
+   const Eina_List *items;
+   void *(*list_data_get) (const Eina_List *list);
+
+   wd = elm_widget_data_get(obj);
+   if ((!wd)) return EINA_FALSE;
+
+   /* Focus chain */
+   /* TODO: Change this to use other chain */
+   if ((items = elm_widget_focus_custom_chain_get(obj)))
+     list_data_get = eina_list_data_get;
+   else
+     {
+        items = wd->seg_items;
+        list_data_get = _elm_list_data_get;
+        if (!items) return EINA_FALSE;
+     }
+   return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
+}
+#endif
+
+static void
+_item_free(Elm_Segment_Item *it)
+{
+   Widget_Data *wd;
+
+   if (!it) return;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+
+   if (wd->selected_item == it) wd->selected_item = NULL;
+   if (wd->seg_items) wd->seg_items = eina_list_remove(wd->seg_items, it);
+
+   elm_widget_item_pre_notify_del(it);
+
+   if (it->icon) evas_object_del(it->icon);
+   if (it->label) eina_stringshare_del(it->label);
+
+   elm_widget_item_del(it);
+}
+
+static void
+_segment_off(Elm_Segment_Item *it)
+{
+   Widget_Data *wd;
+
+   if (!it) return;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+
+   edje_object_signal_emit(it->base.view, "elm,state,segment,normal", "elm");
+
+   if (wd->selected_item == it) wd->selected_item = NULL;
+}
+
+static void
+_segment_on(Elm_Segment_Item *it)
+{
+   Widget_Data *wd;
+
+   if (!it) return;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+   if (it == wd->selected_item) return;
+
+   if (wd->selected_item) _segment_off(wd->selected_item);
+
+   edje_object_signal_emit(it->base.view, "elm,state,segment,selected", "elm");
+
+   wd->selected_item = it;
+   evas_object_smart_callback_call(wd->obj, "changed", (void*) it->seg_index);
+}
+
+static void
+_position_items(Widget_Data *wd)
+{
+   Eina_List *l;
+   Elm_Segment_Item *it;
+   Eina_Bool rtl;
+   int bx, by, bw, bh, pos;
+
+   wd->item_count = eina_list_count(wd->seg_items);
+   if (wd->item_count <= 0) return;
+
+   evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh);
+   wd->item_width = bw / wd->item_count;
+   rtl = elm_widget_mirrored_get(wd->obj);
+
+   if (rtl)
+     pos = bx + bw - wd->item_width;
+   else
+     pos = bx;
+
+   EINA_LIST_FOREACH(wd->seg_items, l, it)
+     {
+        evas_object_move(it->base.view, pos, by);
+        evas_object_resize(it->base.view, wd->item_width, bh);
+        if (rtl)
+          pos -= wd->item_width;
+        else
+          pos += wd->item_width;
+     }
+   _sizing_eval(wd->obj);
+}
+
+static void
+_on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
+                void *event_info __UNUSED__)
+{
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   _position_items(wd);
+
+}
+
+static void
+_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
+          void *event_info)
+{
+   Widget_Data *wd;
+   Elm_Segment_Item *it;
+   Evas_Event_Mouse_Up *ev;
+   Evas_Coord x, y, w, h;
+
+   it = data;
+   if (!it) return;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+
+   if (elm_widget_disabled_get(wd->obj)) return;
+
+   if (it == wd->selected_item) return;
+
+   ev = event_info;
+   evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
+
+   if ((ev->output.x >= x) && (ev->output.x <= (x + w)) && (ev->output.y >= y)
+       && (ev->output.y <= (y + h)))
+     _segment_on(it);
+   else
+     edje_object_signal_emit(it->base.view, "elm,state,segment,normal", "elm");
+}
+
+static void
+_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
+            void *event_info __UNUSED__)
+{
+   Widget_Data *wd;
+   Elm_Segment_Item *it;
+
+   it = data;
+   if (!it) return;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+
+   if (elm_widget_disabled_get(wd->obj)) return;
+
+   if (it == wd->selected_item) return;
+
+   edje_object_signal_emit(it->base.view, "elm,state,segment,pressed", "elm");
+}
+
+static void
+_swallow_item_objects(Elm_Segment_Item *it)
+{
+   if (!it) return;
+
+   if (it->icon)
+     {
+        edje_object_part_swallow(it->base.view, "elm.swallow.icon", it->icon);
+        edje_object_signal_emit(it->base.view, "elm,state,icon,visible", "elm");
+     }
+   else
+     edje_object_signal_emit(it->base.view, "elm,state,icon,hidden", "elm");
+
+   if (it->label)
+     edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
+   edje_object_message_signal_process(it->base.view);
+}
+
+static void
+_update_list(Widget_Data *wd)
+{
+   Eina_List *l;
+   Elm_Segment_Item *it;
+   Eina_Bool rtl;
+   int index = 0;
+
+   _position_items(wd);
+
+   if (wd->item_count == 1)
+     {
+        it = eina_list_nth(wd->seg_items, 0);
+        it->seg_index = 0;
+
+        //Set the segment type
+        edje_object_signal_emit(it->base.view,
+                                "elm,type,segment,single", "elm");
+
+        //Set the segment state
+        if (wd->selected_item == it)
+          edje_object_signal_emit(it->base.view,
+                                  "elm,state,segment,selected", "elm");
+        else
+          edje_object_signal_emit(it->base.view,
+                                  "elm,state,segment,normal", "elm");
+
+        if (elm_widget_disabled_get(wd->obj))
+          edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm");
+
+        _swallow_item_objects(it);
+        return;
+     }
+
+   rtl = elm_widget_mirrored_get(wd->obj);
+   EINA_LIST_FOREACH(wd->seg_items, l, it)
+     {
+        it->seg_index = index;
+
+        //Set the segment type
+        if (index == 0)
+          {
+             if (rtl)
+               edje_object_signal_emit(it->base.view,
+                                       "elm,type,segment,right", "elm");
+             else
+               edje_object_signal_emit(it->base.view,
+                                       "elm,type,segment,left", "elm");
+          }
+        else if (index == (wd->item_count - 1))
+          {
+             if (rtl)
+               edje_object_signal_emit(it->base.view,
+                                       "elm,type,segment,left", "elm");
+             else
+               edje_object_signal_emit(it->base.view,
+                                       "elm,type,segment,right", "elm");
+          }
+        else
+          edje_object_signal_emit(it->base.view,
+                                  "elm,type,segment,middle", "elm");
+
+        //Set the segment state
+        if (wd->selected_item == it)
+          edje_object_signal_emit(it->base.view,
+                                  "elm,state,segment,selected", "elm");
+        else
+          edje_object_signal_emit(it->base.view,
+                                  "elm,state,segment,normal", "elm");
+
+        if (elm_widget_disabled_get(wd->obj))
+          edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm");
+
+        _swallow_item_objects(it);
+        index++;
+     }
+}
+
+static Elm_Segment_Item *
+_item_find(const Evas_Object *obj, int index)
+{
+   Widget_Data *wd;
+   Elm_Segment_Item *it;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   it = eina_list_nth(wd->seg_items, index);
+   return it;
+}
+
+static Elm_Segment_Item*
+_item_new(Evas_Object *obj, Evas_Object *icon, const char *label)
+{
+   Elm_Segment_Item *it;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   it = elm_widget_item_new(obj, Elm_Segment_Item);
+   if (!it) return NULL;
+   elm_widget_item_data_set(it, wd);
+
+   it->base.view = edje_object_add(evas_object_evas_get(obj));
+   edje_object_scale_set(it->base.view, elm_widget_scale_get(it->base.view)
+                         *_elm_config->scale);
+   evas_object_smart_member_add(it->base.view, obj);
+   elm_widget_sub_object_add(obj, it->base.view);
+   _elm_theme_object_set(obj, it->base.view, "segment_control", "item",
+                         elm_object_style_get(obj));
+   edje_object_mirrored_set(it->base.view,
+                            elm_widget_mirrored_get(it->base.widget));
+
+   if (label)
+     eina_stringshare_replace(&it->label, label);
+   if (it->label)
+     edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
+   edje_object_message_signal_process(it->base.view);
+   edje_object_part_text_set(it->base.view, "elm.text", label);
+
+   it->icon = icon;
+   if (it->icon) elm_widget_sub_object_add(it->base.view, it->icon);
+   evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _mouse_down, it);
+   evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_UP,
+                                  _mouse_up, it);
+   evas_object_show(it->base.view);
+
+   return it;
+}
+
+/**
+ * Create new SegmentControl.
+ * @param [in] parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup SegmentControl
+ */
+EAPI Evas_Object *
+elm_segment_control_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
+
+   ELM_SET_WIDTYPE(widtype, "segment_control");
+   elm_widget_type_set(obj, "segment_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);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+
+   // TODO: Focus switch support to Elm_widget_Item not supported yet.
+#if 0
+   elm_widget_focus_next_hook_set(obj, _focus_next_hook);
+#endif
+
+   wd->obj = obj;
+
+   wd->base = edje_object_add(e);
+   edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base)
+                         *_elm_config->scale);
+   _elm_theme_object_set(obj, wd->base, "segment_control", "base", "default");
+   elm_widget_resize_object_set(obj, wd->base);
+
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
+                                  _on_move_resize, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
+                                  _on_move_resize, obj);
+   return obj;
+}
+
+/**
+ * Add new segment item to SegmentControl.
+ * @param [in] obj The SegmentControl object
+ * @param [in] icon Any Objects like icon, Label, layout etc
+ * @param [in] label The label for added segment item.
+ *             Note that, NULL is different from empty string "".
+ * @return The new segment item or NULL if it cannot be created
+ *
+ * @ingroup SegmentControl
+ */
+EAPI Elm_Segment_Item *
+elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon,
+                             const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Elm_Segment_Item *it;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   it = _item_new(obj, icon, label);
+   if (!it) return NULL;
+
+   wd->seg_items = eina_list_append(wd->seg_items, it);
+   _update_list(wd);
+
+   return it;
+}
+
+/**
+ * Insert a new segment item to SegmentControl.
+ * @param [in] obj The SegmentControl object
+ * @param [in] icon Any Objects like icon, Label, layout etc
+ * @param [in] label The label for added segment item.
+ *        Note that, NULL is different from empty string "".
+ * @param [in] index Segment item location. Value should be between 0 and
+ *        Existing total item count( @see elm_segment_control_item_count_get() )
+ * @return The new segment item or NULL if it cannot be created
+ *
+ * @ingroup SegmentControl
+ */
+EAPI Elm_Segment_Item *
+elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon,
+                                   const char *label, int index)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Elm_Segment_Item *it, *it_rel;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   if (index < 0) index = 0;
+
+   it = _item_new(obj, icon, label);
+   if (!it) return NULL;
+
+   it_rel = _item_find(obj, index);
+   if (it_rel)
+     wd->seg_items = eina_list_prepend_relative(wd->seg_items, it, it_rel);
+   else
+     wd->seg_items = eina_list_append(wd->seg_items, it);
+
+   _update_list(wd);
+   return it;
+}
+
+/**
+ * Delete a segment item from SegmentControl
+ * @param [in] obj The SegmentControl object
+ * @param [in] it The segment item to be deleted
+ *
+ * @ingroup SegmentControl
+ */
+EAPI void
+elm_segment_control_item_del(Elm_Segment_Item *it)
+{
+   ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
+   Widget_Data *wd;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+
+   _item_free(it);
+   _update_list(wd);
+}
+
+/**
+ * Delete a segment item of given index from SegmentControl
+ * @param [in] obj The SegmentControl object
+ * @param [in] index The position at which segment item to be deleted.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI void
+elm_segment_control_item_del_at(Evas_Object *obj, int index)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Elm_Segment_Item *it;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   it = _item_find(obj, index);
+   if (!it) return;
+   _item_free(it);
+   _update_list(wd);
+}
+
+/**
+ * Get the label of a segment item.
+ * @param [in] obj The SegmentControl object
+ * @param [in] index The index of the segment item
+ * @return The label of the segment item
+ *
+ * @ingroup SegmentControl
+ */
+EAPI const char*
+elm_segment_control_item_label_get(const Evas_Object *obj, int index)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Elm_Segment_Item *it;
+
+   it = _item_find(obj, index);
+   if (it) return it->label;
+
+   return NULL;
+}
+
+/**
+ * Set the label of a segment item.
+ * @param [in] it The SegmentControl Item
+ * @param [in] label New label text.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI void
+elm_segment_control_item_label_set(Elm_Segment_Item* it, const char* label)
+{
+   ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
+   Widget_Data *wd;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+
+   eina_stringshare_replace(&it->label, label);
+   if (it->label)
+     edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
+   edje_object_message_signal_process(it->base.view);
+   //label can be NULL also.
+   edje_object_part_text_set(it->base.view, "elm.text", it->label);
+}
+
+/**
+ * Get the icon of a segment item of SegmentControl
+ * @param [in] obj The SegmentControl object
+ * @param [in] index The index of the segment item
+ * @return The icon object.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI Evas_Object *
+elm_segment_control_item_icon_get(const Evas_Object *obj, int index)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Elm_Segment_Item *it;
+
+   it = _item_find(obj, index);
+   if (it) return it->icon;
+
+   return NULL;
+}
+
+/**
+ * Set the Icon to the segment item
+ * @param [in] it The SegmentControl Item
+ * @param [in] icon Objects like Layout, Icon, Label etc...
+ *
+ * @ingroup SegmentControl
+ */
+EAPI void
+elm_segment_control_item_icon_set(Elm_Segment_Item *it, Evas_Object *icon)
+{
+   ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
+
+   //Remove the existing icon
+   if (it->icon)
+     {
+        edje_object_part_unswallow(it->base.view, it->icon);
+        evas_object_del(it->icon);
+        it->icon = NULL;
+     }
+
+   it->icon = icon;
+   if (it->icon)
+     {
+        elm_widget_sub_object_add(it->base.view, it->icon);
+        edje_object_part_swallow(it->base.view, "elm.swallow.icon", it->icon);
+        edje_object_signal_emit(it->base.view, "elm,state,icon,visible", "elm");
+     }
+   else
+     edje_object_signal_emit(it->base.view, "elm,state,icon,hidden", "elm");
+}
+
+/**
+ * Get the Segment items count from SegmentControl
+ * @param [in] obj The SegmentControl object
+ * @return Segment items count.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI int
+elm_segment_control_item_count_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+
+   return eina_list_count(wd->seg_items);
+}
+
+/**
+ * Get the base object of segment item.
+ * @param [in] it The Segment item
+ * @return obj The base object of the segment item.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI Evas_Object*
+elm_segment_control_item_object_get(const Elm_Segment_Item *it)
+{
+   ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
+
+   return it->base.view;
+}
+
+/**
+ * Get the selected segment item in the SegmentControl
+ * @param [in] obj The SegmentControl object
+ * @return Selected Segment Item. NULL if none of segment item is selected.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI Elm_Segment_Item*
+elm_segment_control_item_selected_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   return wd->selected_item;
+}
+
+/**
+ * Select/unselect a particular segment item of SegmentControl
+ * @param [in] it The Segment item that is to be selected or unselected.
+ * @param [in] select Passing EINA_TRUE will select the segment item and
+ *             EINA_FALSE will unselect.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI void
+elm_segment_control_item_selected_set(Elm_Segment_Item *it, Eina_Bool select)
+{
+   ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
+   Widget_Data *wd;
+
+   wd = elm_widget_item_data_get(it);
+   if (!wd) return;
+
+   if (it == wd->selected_item)
+     {
+        //already in selected state.
+        if (select) return;
+
+        //unselect case
+        _segment_off(it);
+     }
+   else if (select)
+     _segment_on(it);
+
+   return;
+}
+
+/**
+ * Get the Segment Item from the specified Index.
+ * @param [in] obj The Segment Control object.
+ * @param [in] index The index of the segment item.
+ * @return The Segment item.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI Elm_Segment_Item *
+elm_segment_control_item_get(const Evas_Object *obj, int index)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Elm_Segment_Item *it;
+
+   it = _item_find(obj, index);
+
+   return it;
+}
+
+/**
+ * Get the index of a Segment item in the SegmentControl
+ * @param [in] it The Segment Item.
+ * @return Segment Item index.
+ *
+ * @ingroup SegmentControl
+ */
+EAPI int
+elm_segment_control_item_index_get(const Elm_Segment_Item *it)
+{
+   ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, -1);
+
+   return it->seg_index;
+}