cedric pushed a commit to branch master.

http://git.enlightenment.org/core/elementary.git/commit/?id=b4f8b8c0c66095730d4436db3987c3fad34aec95

commit b4f8b8c0c66095730d4436db3987c3fad34aec95
Author: divyesh purohit <div.puro...@samsung.com>
Date:   Mon Jan 4 15:22:46 2016 -0800

    combobox: add new widget.
    
    Summary:
    Combobox is a combinational widget of a drop-down list and single line 
entry.
    Based on the text entered in the entry, the list items are filtered 
accordingly.
    Signed-Off By: Cedric Bail <cedric.b...@free.fr>
    Signed-Off By: Divyesh Purohit <div.puro...@samsung.com>
    
    Test Plan: test_combobox.c is added to elementary test
    
    Reviewers: raster, shilpasingh, cedric, jpeg, stefan_schmidt
    
    Reviewed By: raster, shilpasingh, cedric
    
    Subscribers: SanghyeonLee, shashank0990, singh.amitesh, tasn, raster, seoz, 
poornima.srinivasan, rajeshps, govi
    
    Differential Revision: https://phab.enlightenment.org/D2537
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 AUTHORS                        |   1 +
 config/default/base.src.in     |  49 ++++-
 config/mobile/base.src.in      |  49 ++++-
 config/standard/base.src.in    |  49 ++++-
 data/themes/edc/elm/button.edc | 299 +++++++++++++++++++++++++++
 data/themes/edc/elm/hover.edc  |   4 +
 src/bin/Makefile.am            |   1 +
 src/bin/test.c                 |   2 +
 src/bin/test_combobox.c        | 165 +++++++++++++++
 src/lib/Elementary.h.in        |   1 +
 src/lib/Makefile.am            |   5 +
 src/lib/elc_combobox.c         | 458 +++++++++++++++++++++++++++++++++++++++++
 src/lib/elc_combobox.h         |  64 ++++++
 src/lib/elc_combobox_legacy.h  |  11 +
 src/lib/elm_authors.h          |   1 +
 src/lib/elm_combobox.eo        |  54 +++++
 src/lib/elm_config.c           |  27 +++
 src/lib/elm_priv.h             |   2 +-
 src/lib/elm_widget_combobox.h  |  80 +++++++
 19 files changed, 1318 insertions(+), 4 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 0e2457b..5ead385 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -166,3 +166,4 @@ Subodh Kumar <s7158.ku...@samsung.com>
 Kumar Navneet <k.navn...@samsung.com>
 Godly T Alias <godly.tal...@samsung.com> <godlytal...@yahoo.co.in>
 Shashank Pandey <shashan...@samsung.com> <shashank0...@gmail.com>
+Divyesh Purohit <div.puro...@samsung.com> <purohit....@gmail.com>
diff --git a/config/default/base.src.in b/config/default/base.src.in
index 7bf7713..e86f7d8 100644
--- a/config/default/base.src.in
+++ b/config/default/base.src.in
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131078;
+  value "config_version" int: 131079;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 1;
@@ -433,6 +433,53 @@ group "Elm_Config" struct {
         }
      }
      group "Elm_Config_Bindings_Widget" struct {
+        value "name" string: "Elm_Combobox";
+        group "key_bindings" list {
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Return";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Enter";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "space";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down";
+           }
+        }
+     }
+     group "Elm_Config_Bindings_Widget" struct {
         value "name" string: "Elm_Multibuttonentry";
         group "key_bindings" list {
            group "Elm_Config_Binding_Key" struct {
diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in
index 44bfd67..a588aa1 100644
--- a/config/mobile/base.src.in
+++ b/config/mobile/base.src.in
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131078;
+  value "config_version" int: 131079;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 1;
@@ -437,6 +437,53 @@ group "Elm_Config" struct {
         }
      }
      group "Elm_Config_Bindings_Widget" struct {
+        value "name" string: "Elm_Combobox";
+        group "key_bindings" list {
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Return";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Enter";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "space";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down";
+           }
+        }
+     }
+     group "Elm_Config_Bindings_Widget" struct {
         value "name" string: "Elm_Multibuttonentry";
         group "key_bindings" list {
            group "Elm_Config_Binding_Key" struct {
diff --git a/config/standard/base.src.in b/config/standard/base.src.in
index fd60d6a..745e577 100644
--- a/config/standard/base.src.in
+++ b/config/standard/base.src.in
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131078;
+  value "config_version" int: 131079;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 0;
@@ -434,6 +434,53 @@ group "Elm_Config" struct {
         }
      }
      group "Elm_Config_Bindings_Widget" struct {
+        value "name" string: "Elm_Combobox";
+        group "key_bindings" list {
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Return";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Enter";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "space";
+              value "action" string: "activate";
+              value "params" string: "return";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down";
+           }
+        }
+     }
+     group "Elm_Config_Bindings_Widget" struct {
         value "name" string: "Elm_Multibuttonentry";
         group "key_bindings" list {
            group "Elm_Config_Binding_Key" struct {
diff --git a/data/themes/edc/elm/button.edc b/data/themes/edc/elm/button.edc
index 2134d41..9dd9f61 100644
--- a/data/themes/edc/elm/button.edc
+++ b/data/themes/edc/elm/button.edc
@@ -1712,3 +1712,302 @@ group { name: 
"elm/button/base/hoversel_horizontal_entry/default";
       }
    }
 /******************* SPINNER BUTTONS STYLES END **********************/
+group { name: "elm/button/base/combobox_vertical/default";
+   alias: "elm/button/base/combobox_vertical/entry";
+   alias: "elm/button/base/combobox_horizontal/default";
+   alias: "elm/button/base/combobox_horizontal/entry";
+
+   images.image: "button_normal.png" COMP;
+   images.image: "button_clicked.png" COMP;
+   images.image: "vertical_separated_bar_glow.png" COMP;
+   parts {
+      image { "base"; nomouse;
+         desc { "default";
+            image.normal: "button_normal.png";
+            image.border: 4 4 3 5;
+            image.middle: SOLID;
+            rel1.offset: -1 0;
+            rel2.offset: 0 1;
+            fill.smooth: 0;
+         }
+         desc { "clicked";
+            inherit: "default";
+            image.normal: "button_clicked.png";
+            image.border: 5 5 4 6;
+         }
+      }
+      rect { "icon_clip";
+         desc { "default";
+         }
+         desc { "disabled";
+            inherit: "default";
+            color: 255 255 255 64;
+         }
+      }
+      rect { "event";
+         desc { "default";
+            color: 0 0 0 0;
+         }
+         desc { "disabled";
+            inherit: "default";
+            visible: 0;
+         }
+      }
+      swallow { "elm.swallow.content";
+         clip_to: "icon_clip";
+         desc { "default";
+            fixed: 0 0;
+            align: 0.5 0.5;
+            rel1.offset: 6 5;
+            rel1.to: "base";
+            rel2.relative: 0.0 1.0;
+            rel2.offset: -3 -8;
+            rel2.to: "select_line";
+            visible: 1;
+         }
+      }
+      image { "select_line"; nomouse;
+         desc { "default";
+            fixed: 1 1;
+            align: 1.0 0.5;
+            min: 15 10;
+            rel1.to: "base";
+            rel1.relative: 1.0 0.0;
+            rel1.offset: 1 -3;
+            rel2.to: "base";
+            rel2.offset: 1 0;
+            image.normal: "vertical_separated_bar_glow.png";
+            image.border: 7 7 7 7;
+            fill.smooth : 0;
+         }
+         desc { "clicked";
+            inherit: "default";
+            rel1.offset: 0 -2;
+            rel2.offset: 0 -1;
+         }
+      }
+   }
+   programs {
+      program {
+         signal: "mouse,down,1"; source: "event";
+         action: SIGNAL_EMIT "elm,action,press" "elm";
+         after: "button_click_anim";
+      }
+      program { name: "button_click_anim";
+         action: STATE_SET "clicked" 0.0;
+         target: "base";
+         target: "select_line";
+      }
+      program { name: "button_unclick";
+         signal: "mouse,up,1"; source: "event";
+         action: SIGNAL_EMIT "elm,action,unpress" "elm";
+         after: "button_unclick_anim";
+      }
+      program { name: "button_unclick_anim";
+         action: STATE_SET "default" 0.0;
+         target: "base";
+         target: "select_line";
+      }
+      program { name: "buttonactivate";
+         signal: "elm,anim,activate"; source: "elm";
+         action: STATE_SET "clicked" 0.0;
+         target: "base";
+         target: "select_line";
+         after: "button_unpressed_anim";
+      }
+      program { name: "button_unpressed_anim";
+         action: STATE_SET "default" 0.0;
+         in: 0.5 0.0;
+         target: "base";
+         target: "select_line";
+      }
+      program {
+         signal: "mouse,clicked,1"; source: "event";
+         action: SIGNAL_EMIT "elm,action,click" "elm";
+      }
+      program { name: "button_state_disabled";
+         signal: "elm,state,disabled"; source: "elm";
+         action: STATE_SET "disabled" 0.0;
+         target: "icon_clip";
+         target: "event";
+      }
+      program { name: "button_state_enabled";
+         signal: "elm,state,enabled"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "icon_clip";
+         target: "event";
+      }
+   }
+}
+
+group { name: "elm/button/base/combobox_vertical_entry/default";
+   alias: "elm/button/base/combobox_vertical_entry/entry";
+   images.image: "vgrad_med_dark.png" COMP;
+   images.image: "bevel_horiz_out.png" COMP;
+   images.image: "shadow_rounded_horiz.png" COMP;
+   images.image: "shine.png" COMP;
+
+   parts {
+      image { "shadow"; nomouse;
+         desc { "default";
+            fixed: 1 1;
+            image.normal: "shadow_rounded_horiz.png";
+            image.border: 0 0 9 9;
+            rel1.to: "base";
+            rel1.offset: 0 -4;
+            rel2.to: "base";
+            rel2.offset: -1 5;
+            fill.smooth: 0;
+            visible: 0;
+         }
+         desc { "clicked";
+            inherit: "default";
+            visible: 1;
+         }
+      }
+      image { "base"; nomouse;
+         desc { "default";
+            fixed: 1 1;
+            rel1.offset: -6 0;
+            image.normal: "vgrad_med_dark.png";
+            fill.smooth: 0;
+            TILED_HORIZ(120)
+            visible: 0;
+         }
+         desc { "clicked";
+            inherit: "default";
+            visible: 1;
+         }
+      }
+     rect { "icon_clip";
+         desc { "default";
+         }
+         desc { "disabled";
+            inherit: "default";
+            color: 255 255 255 64;
+         }
+      }
+      image { "bevel"; nomouse;
+         desc { "default";
+            fixed: 1 1;
+            image.normal: "bevel_horiz_out.png";
+            image.border: 0 0 2 2;
+            image.middle: 0;
+            fill.smooth: 0;
+            visible: 0;
+         }
+         desc { "clicked";
+            inherit: "default";
+            visible: 1;
+         }
+      }
+      image { "shine"; nomouse;
+         desc { "default";
+            fixed: 1 1;
+            rel1.to: "base";
+            rel1.offset: 0 -2;
+            rel2.to: "base";
+            rel2.relative: 1.0 0.0;
+            rel2.offset: -1 2;
+            image.normal: "shine.png";
+            visible: 0;
+            FIXED_SIZE(69, 5)
+         }
+         desc { "clicked";
+            inherit:  "default";
+            visible: 1;
+         }
+      }
+      rect { name: "event";
+         desc { "default";
+            color: 0 0 0 0;
+         }
+         desc { "disabled";
+            inherit: "default";
+            visible: 0;
+         }
+      }
+      swallow { "elm.swallow.content"; nomouse;
+         clip_to: "icon_clip";
+         desc { "default";
+            fixed: 1 0;
+            align: 0.0 0.5;
+            rel1.offset: 6 5;
+            rel1.to: "base";
+            rel2.relative: 0.0 1.0;
+            rel2.offset: 6 -8;
+            rel2.to: "base";
+            visible: 0;
+         }
+         desc { "visible";
+            inherit: "default";
+            fixed: 1 0;
+            aspect: 1.0 1.0;
+            visible: 1;
+         }
+         desc { "icononly";
+            inherit: "default";
+            fixed: 0 0;
+            align: 0.5 0.5;
+            rel2.relative: 1.0 1.0;
+            rel2.offset: -7 -8;
+            visible: 1;
+         }
+      }
+   }
+   programs {
+      program {
+         signal: "mouse,down,1"; source: "event";
+         action: SIGNAL_EMIT "elm,action,press" "elm";
+         after: "button_click_anim";
+      }
+      program { name: "button_click_anim";
+         action: STATE_SET "clicked" 0.0;
+         target: "shadow";
+         target: "base";
+         target: "shine";
+      }
+      program { name: "button_unclick";
+         signal: "mouse,up,1"; source: "event";
+         action: SIGNAL_EMIT "elm,action,unpress" "elm";
+         after: "button_unclick_anim";
+      }
+      program { name: "button_unclick_anim";
+         action: STATE_SET "default" 0.0;
+         target: "shadow";
+         target: "base";
+         target: "shine";
+      }
+      program { name: "buttonactivate";
+         signal: "elm,anim,activate"; source: "elm";
+         action: STATE_SET "clicked" 0.0;
+         target: "shadow";
+         target: "base";
+         target: "shine";
+         after: "button_unpressed_anim";
+      }
+      program { name: "button_unpressed_anim";
+         action: STATE_SET "default" 0.0;
+         in: 0.5 0.0;
+         target: "shadow";
+         target: "base";
+         target: "shine";
+      }
+      program {
+         signal: "mouse,clicked,1"; source: "event";
+         action: SIGNAL_EMIT "elm,action,click" "elm";
+      }
+      program { name:   "button_state_disabled";
+         signal: "elm,state,disabled"; source: "elm";
+         action: STATE_SET "disabled" 0.0;
+         target: "event";
+         target: "icon_clip";
+      }
+      program { name:   "button_state_enabled";
+         signal: "elm,state,enabled"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "event";
+         target: "icon_clip";
+      }
+   }
+}
diff --git a/data/themes/edc/elm/hover.edc b/data/themes/edc/elm/hover.edc
index 8a7ed49..75ea813 100644
--- a/data/themes/edc/elm/hover.edc
+++ b/data/themes/edc/elm/hover.edc
@@ -439,6 +439,8 @@ group { name: "elm/hover/base/popout";
 
 group { name: "elm/hover/base/hoversel_vertical/default";
    alias: "elm/hover/base/hoversel_vertical/entry";
+   alias: "elm/hover/base/combobox_vertical/entry";
+   alias: "elm/hover/base/combobox_vertical/default";
    images.image: "button_normal.png" COMP;
    images.image: "vertical_separated_bar_glow.png" COMP;
    data.item: "dismiss" "on";
@@ -773,6 +775,8 @@ group { name: "elm/hover/base/hoversel_vertical/default";
 
 group { name: "elm/hover/base/hoversel_horizontal/default";
    alias: "elm/hover/base/hoversel_horizontal/entry";
+   alias: "elm/hover/base/combobox_horizontal/default";
+   alias: "elm/hover/base/combobox_horizontal/entry";
    images.image: "button_normal.png" COMP;
    data.item: "dismiss" "on";
    // max_size limits the maximum size of expanded hoversel
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index b93374a..46db673 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -43,6 +43,7 @@ test_clock.c \
 test_cnp.c \
 test_colorselector.c \
 test_colorclass.c \
+test_combobox.c \
 test_config.c \
 test_conform.c \
 test_conform_indicator.c \
diff --git a/src/bin/test.c b/src/bin/test.c
index 53f419d..a3ae31d 100644
--- a/src/bin/test.c
+++ b/src/bin/test.c
@@ -45,6 +45,7 @@ void test_clock(void *data, Evas_Object *obj, void 
*event_info);
 void test_clock_edit(void *data, Evas_Object *obj, void *event_info);
 void test_clock_edit2(void *data, Evas_Object *obj, void *event_info);
 void test_clock_pause(void *data, Evas_Object *obj, void *event_info);
+void test_combobox(void *data, Evas_Object *obj, void *event_info);
 void test_check(void *data, Evas_Object *obj, void *event_info);
 void test_check_toggle(void *data, Evas_Object *obj, void *event_info);
 void test_radio(void *data, Evas_Object *obj, void *event_info);
@@ -753,6 +754,7 @@ add_tests:
    ADD_TEST(NULL, "Selectors", "FlipSelector", test_flipselector);
    ADD_TEST(NULL, "Selectors", "DaySelector", test_dayselector);
    ADD_TEST(NULL, "Selectors", "Main menu", test_main_menu);
+   ADD_TEST(NULL, "Selectors", "Combobox", test_combobox);
 
    //------------------------------//
    ADD_TEST(NULL, "Cursors", "Cursor", test_cursor);
diff --git a/src/bin/test_combobox.c b/src/bin/test_combobox.c
new file mode 100644
index 0000000..b5f1172
--- /dev/null
+++ b/src/bin/test_combobox.c
@@ -0,0 +1,165 @@
+#include "test.h"
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Elementary.h>
+
+static void
+_combobox_clicked_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                     void *event_info EINA_UNUSED)
+{
+   printf("Hover button is clicked and 'clicked' callback is called.\n");
+}
+
+static void
+_combobox_selected_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                      void *event_info)
+{
+   const char *txt = elm_object_item_text_get(event_info);
+   printf("'selected' callback is called. (selected item : %s)\n", txt);
+}
+
+static void
+_combobox_dismissed_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                       void *event_info EINA_UNUSED)
+{
+   printf("'dismissed' callback is called.\n");
+}
+
+static void
+_combobox_expanded_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                       void *event_info EINA_UNUSED)
+{
+   printf("'expanded' callback is called.\n");
+}
+
+static void
+_combobox_item_pressed_cb(void *data EINA_UNUSED, Evas_Object *obj,
+                      void *event_info)
+{
+   const char *txt = elm_object_item_text_get(event_info);
+   printf("'item,pressed' callback is called. (selected item : %s)\n", txt);
+   elm_object_text_set(obj, txt);
+   elm_combobox_hover_end(obj);
+}
+
+static char *
+gl_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part 
EINA_UNUSED)
+{
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data);
+   return strdup(buf);
+}
+
+static Evas_Object *gl_content_get(void *data EINA_UNUSED, Evas_Object *obj,
+                                    const char *part)
+{
+   char buf[PATH_MAX];
+   Evas_Object *ic = elm_icon_add(obj);
+   if (!strcmp(part, "elm.swallow.end"))
+     snprintf(buf, sizeof(buf), "%s/images/bubble.png", 
elm_app_data_dir_get());
+   else
+     snprintf(buf, sizeof(buf), "%s/images/logo_small.png", 
elm_app_data_dir_get());
+   elm_image_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   return ic;
+}
+
+static Eina_Bool gl_state_get(void *data EINA_UNUSED,
+                               Evas_Object *obj EINA_UNUSED,
+                               const char *part EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+gl_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key)
+{
+   // if the key is empty/NULL, return true for item
+   if (!strlen((char *)key)) return EINA_TRUE;
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data);
+   if (strcasestr(buf, (char *)key))
+     return EINA_TRUE;
+   // Default case should return false (item fails filter hence will be hidden)
+   return EINA_FALSE;
+}
+
+static void
+_gl_filter_finished_cb(void *data EINA_UNUSED,
+                       Evas_Object *obj EINA_UNUSED,
+                       void *event_info EINA_UNUSED)
+{
+   printf("Filter finished\n");
+}
+
+void
+test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+              void *event_info EINA_UNUSED)
+{
+   Evas_Object *win, *bx, *combobox;
+   Elm_Genlist_Item_Class *itc;
+   win = elm_win_util_standard_add("combobox", "Combobox");
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   itc = elm_genlist_item_class_new();
+   itc->item_style = "default";
+   itc->func.text_get = gl_text_get;
+   itc->func.content_get = gl_content_get;
+   itc->func.state_get = gl_state_get;
+   itc->func.filter_get = gl_filter_get;
+   itc->func.del = NULL;
+
+   combobox = elm_combobox_add(win);
+   evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
+   elm_object_part_text_set(combobox, "guide", "A long list");
+   for (int i = 0; i < 1000; i++)
+     elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
+                                   NULL, ELM_GENLIST_ITEM_NONE, NULL,
+                                   (void*)(uintptr_t)(i * 10));
+   evas_object_smart_callback_add(combobox, "clicked",
+                                  _combobox_clicked_cb, NULL);
+   evas_object_smart_callback_add(combobox, "selected",
+                                  _combobox_selected_cb, NULL);
+   evas_object_smart_callback_add(combobox, "dismissed",
+                                  _combobox_dismissed_cb, NULL);
+   evas_object_smart_callback_add(combobox, "expanded",
+                                  _combobox_expanded_cb, NULL);
+   evas_object_smart_callback_add(combobox, "item,pressed",
+                                  _combobox_item_pressed_cb, NULL);
+   evas_object_smart_callback_add(combobox, "filter,done",
+                                  _gl_filter_finished_cb, NULL);
+   elm_box_pack_end(bx, combobox);
+   evas_object_show(combobox);
+
+   combobox = elm_combobox_add(win);
+   evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
+   elm_object_text_set(combobox, "Disabled Combobox");
+   for (int i = 0; i < 1000; i++)
+     elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
+                                   NULL, ELM_GENLIST_ITEM_NONE, NULL,
+                                   (void*)(uintptr_t)(i * 10));
+   evas_object_smart_callback_add(combobox, "clicked",
+                                  _combobox_clicked_cb, NULL);
+   evas_object_smart_callback_add(combobox, "selected",
+                                  _combobox_selected_cb, NULL);
+   evas_object_smart_callback_add(combobox, "dismissed",
+                                  _combobox_dismissed_cb, NULL);
+   evas_object_smart_callback_add(combobox, "expanded",
+                                  _combobox_expanded_cb, NULL);
+   evas_object_smart_callback_add(combobox, "filter,done",
+                                  _gl_filter_finished_cb, NULL);
+   elm_object_disabled_set(combobox, EINA_TRUE);
+   elm_box_pack_end(bx, combobox);
+   evas_object_show(combobox);
+
+   evas_object_resize(win, 320, 500);
+   evas_object_show(win);
+}
diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in
index 1cd7c76..7dceefa 100644
--- a/src/lib/Elementary.h.in
+++ b/src/lib/Elementary.h.in
@@ -174,6 +174,7 @@ EAPI extern Elm_Version *elm_version;
 
 /* other includes */
 #include <elc_ctxpopup.h>
+#include <elc_combobox.h>
 #include <elm_dayselector.h>
 #include <elc_fileselector_button.h>
 #include <elc_fileselector_entry.h>
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 20f6521..40fb597 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -56,6 +56,7 @@ elm_widget_clock.h \
 elm_widget_colorselector.h \
 elm_widget_conform.h \
 elm_widget_container.h \
+elm_widget_combobox.h \
 elm_widget_ctxpopup.h \
 elm_widget_datetime.h \
 elm_widget_dayselector.h \
@@ -114,6 +115,8 @@ includesub_HEADERS = \
 elc_ctxpopup.h \
 elc_ctxpopup_eo.h \
 elc_ctxpopup_legacy.h \
+elc_combobox.h \
+elc_combobox_legacy.h \
 elc_fileselector.h \
 elc_fileselector_eo.h \
 elc_fileselector_legacy.h \
@@ -415,6 +418,7 @@ elm_clock.c \
 elm_cnp.c \
 elm_colorselector.c \
 elm_color_class.c \
+elc_combobox.c \
 elm_config.c \
 elm_conform.c \
 elm_container.c \
@@ -531,6 +535,7 @@ elm_calendar.eo \
 elm_check.eo \
 elm_clock.eo \
 elm_colorselector.eo \
+elm_combobox.eo \
 elm_conformant.eo \
 elm_container.eo \
 elm_ctxpopup.eo \
diff --git a/src/lib/elc_combobox.c b/src/lib/elc_combobox.c
new file mode 100644
index 0000000..7e5487f
--- /dev/null
+++ b/src/lib/elc_combobox.c
@@ -0,0 +1,458 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EO_BASE_BETA
+#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
+#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+#include "elm_widget_combobox.h"
+
+#define MY_CLASS ELM_COMBOBOX_CLASS
+
+#define MY_CLASS_NAME "Elm_Combobox"
+#define MY_CLASS_NAME_LEGACY "elm_combobox"
+
+static const char SIG_SELECTED[] = "selected";
+static const char SIG_DISMISSED[] = "dismissed";
+static const char SIG_EXPANDED[] = "expanded";
+static const char SIG_ITEM_PRESSED[] = "item,pressed";
+static const char SIG_FILTER_DONE[] = "filter,done";
+
+static const Evas_Smart_Cb_Description _smart_callbacks[] = {
+   {SIG_SELECTED, ""},
+   {SIG_DISMISSED, ""},
+   {SIG_EXPANDED, ""},
+   {SIG_ITEM_PRESSED, ""},
+   {SIG_FILTER_DONE, ""},
+   {"clicked", ""}, /**< handled by parent button class */
+   {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
+   {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
+   {NULL, NULL}
+};
+
+static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
+static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
+
+static const Elm_Action key_actions[] = {
+   {"activate", _key_action_activate},
+   {"move", _key_action_move},
+   {NULL, NULL}
+};
+
+EOLIAN static Eina_Bool
+_elm_combobox_elm_widget_translate(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
+{
+   eo_do_super(obj, MY_CLASS, elm_obj_widget_translate());
+   eo_do(sd->genlist, elm_obj_widget_translate());
+   eo_do(sd->entry, elm_obj_widget_translate());
+
+   if (sd->hover)
+     eo_do(sd->hover, elm_obj_widget_translate());
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_elm_combobox_elm_widget_theme_apply(Eo *obj, Elm_Combobox_Data *sd)
+{
+   const char *style;
+   Eina_Bool int_ret = EINA_FALSE;
+   Eina_Bool mirrored;
+   char buf[128];
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
+
+   style = elm_widget_style_get(obj);
+
+   snprintf(buf, sizeof(buf), "combobox_vertical/%s", style);
+
+   /* combobox's style has no extra bit for orientation but could have... */
+   eina_stringshare_replace(&(wd->style), buf);
+
+   eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
+   if (!int_ret) return EINA_FALSE;
+
+   mirrored = elm_widget_mirrored_get(obj);
+
+   if (sd->hover)
+     elm_widget_mirrored_set(sd->hover, mirrored);
+
+   elm_widget_mirrored_set(sd->genlist, mirrored);
+   elm_widget_mirrored_set(sd->entry, mirrored);
+
+   elm_combobox_hover_end(obj);
+
+   return EINA_TRUE;
+}
+
+static void
+_on_hover_clicked(void *data,
+                  Evas_Object *obj EINA_UNUSED,
+                  void *event_info EINA_UNUSED)
+{
+   elm_combobox_hover_end(data);
+}
+
+static void
+count_items_genlist(void *data)
+{
+   ELM_COMBOBOX_DATA_GET(data, sd);
+   Eina_Iterator *filter_iter;
+   int count = 0;
+   Elm_Object_Item *item;
+
+   filter_iter = elm_genlist_filter_iterator_new(sd->genlist);
+   if (!filter_iter) return;
+   EINA_ITERATOR_FOREACH(filter_iter, item)
+     if (item) count++;
+   sd->count = count;
+   eina_iterator_free(filter_iter);
+}
+
+static void
+_table_resize(void *data)
+{
+   ELM_COMBOBOX_DATA_GET(data, sd);
+   if (sd->count > 0)
+     {
+        int hover_parent_w, hover_parent_h, obj_h, obj_w, obj_y, win_y_offset;
+        int current_height, h;
+        sd->item = elm_genlist_first_item_get(sd->genlist);
+        elm_genlist_item_selected_set(sd->item, EINA_TRUE);
+        //FIXME:- the height of item is zero, sometimes.
+        evas_object_geometry_get(elm_object_item_track(sd->item), NULL, NULL,
+                                 NULL, &h);
+        if (h) sd->item_height = h;
+        evas_object_geometry_get(sd->entry, NULL, NULL, &obj_w, NULL);
+        evas_object_geometry_get(data, NULL, &obj_y, NULL, &obj_h);
+        evas_object_geometry_get(sd->hover_parent, NULL, NULL, &hover_parent_w,
+                                 &hover_parent_h);
+        current_height = sd->item_height * sd->count;
+        if (!strcmp(elm_hover_best_content_location_get(sd->hover,
+                                                       
ELM_HOVER_AXIS_VERTICAL),
+                                                       "bottom"))
+          win_y_offset = hover_parent_h - obj_y - obj_h;
+        else win_y_offset = obj_y;
+        if (current_height < win_y_offset)
+          evas_object_size_hint_min_set(sd->spacer, obj_w * 
elm_config_scale_get(),
+                                        current_height + (2 * 
elm_config_scale_get()));
+        else evas_object_size_hint_min_set(sd->spacer, obj_w * 
elm_config_scale_get(),
+                                           win_y_offset * 
elm_config_scale_get());
+     }
+}
+
+static void
+_activate(Evas_Object *obj)
+{
+   ELM_COMBOBOX_DATA_GET(obj, sd);
+   if (elm_widget_disabled_get(obj)) return;
+   sd->expanded = EINA_TRUE;
+   eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_EXPANDED, NULL));
+   _table_resize(obj);
+   evas_object_show(sd->hover);
+}
+
+static void
+_on_item_selected(void *data , Evas_Object *obj EINA_UNUSED, void *event)
+{
+   ELM_COMBOBOX_DATA_GET(data, sd);
+   elm_object_focus_set(sd->entry, EINA_TRUE);
+   eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_SELECTED, event));
+}
+
+static void
+_on_item_pressed(void *data , Evas_Object *obj EINA_UNUSED, void *event)
+{
+   eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_ITEM_PRESSED, event));
+}
+
+static Eina_Bool
+_gl_filter_finished_cb(void *data, Eo *obj EINA_UNUSED,
+                       const Eo_Event_Description *desc EINA_UNUSED, void 
*event)
+{
+   ELM_COMBOBOX_DATA_GET(data, sd);
+   eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_FILTER_DONE, event));
+   count_items_genlist(data);
+   if (sd->count > 0)
+     {
+        if (sd->expanded == EINA_TRUE)
+          elm_combobox_hover_end(data);
+        _activate(data);
+     }
+   else elm_combobox_hover_end(data);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_on_aborted(void *data, Eo *obj EINA_UNUSED,
+            const Eo_Event_Description *desc EINA_UNUSED, void *event_info 
EINA_UNUSED)
+{
+   ELM_COMBOBOX_DATA_GET(data, sd);
+   if (sd->expanded == EINA_TRUE) elm_combobox_hover_end(data);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_on_changed(void *data, Eo *obj EINA_UNUSED,
+            const Eo_Event_Description *desc EINA_UNUSED, void *event_info 
EINA_UNUSED)
+{
+   elm_combobox_hover_begin(data);
+   return EINA_TRUE;
+}
+
+static void
+_on_clicked(void *data,
+            Evas_Object *obj EINA_UNUSED,
+            void *event_info EINA_UNUSED)
+{
+   elm_combobox_hover_begin(data);
+}
+
+EOLIAN static void
+_elm_combobox_evas_object_smart_add(Eo *obj, Elm_Combobox_Data *sd EINA_UNUSED)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
+   elm_widget_sub_object_parent_add(obj);
+
+   elm_widget_mirrored_automatic_set(obj, EINA_FALSE);
+
+   evas_object_smart_callback_add(obj, "clicked", _on_clicked, obj);
+
+   //What are you doing here?
+   eo_do(obj, elm_obj_widget_theme_apply());
+}
+
+EOLIAN static void
+_elm_combobox_evas_object_smart_del(Eo *obj, Elm_Combobox_Data *sd)
+{
+   sd->hover_parent = NULL;
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
+}
+
+EOLIAN static void
+_elm_combobox_evas_object_smart_show(Eo *obj, Elm_Combobox_Data *sd)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_show());
+   if (sd->expanded) evas_object_show(sd->hover);
+}
+
+EOLIAN static void
+_elm_combobox_evas_object_smart_hide(Eo *obj, Elm_Combobox_Data *sd)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_hide());
+   if (sd->hover) evas_object_hide(sd->hover);
+}
+
+EOLIAN static Eina_Bool
+_elm_combobox_elm_button_admits_autorepeat_get(Eo *obj EINA_UNUSED,
+                                               Elm_Combobox_Data *sd 
EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+EAPI Evas_Object *
+elm_combobox_add(Evas_Object *parent)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
+   Evas_Object *obj = eo_add(MY_CLASS, parent);
+   return obj;
+}
+
+EOLIAN static Eo *
+_elm_combobox_eo_base_constructor(Eo *obj, Elm_Combobox_Data *sd)
+{
+   Evas_Object *gl;
+   Evas_Object *entry;
+   char buf[128];
+
+   eo_do_super(obj, MY_CLASS, eo_constructor());
+
+   eo_do(obj,
+         evas_obj_type_set(MY_CLASS_NAME_LEGACY),
+         evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
+         elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_GLASS_PANE));
+
+   //hover-parent
+   sd->hover_parent = elm_object_parent_widget_get(obj);
+
+   //hover
+   sd->hover = eo_add(ELM_HOVER_CLASS, sd->hover_parent);
+   elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE);
+   elm_hover_target_set(sd->hover, obj);
+
+   //table
+   sd->tbl = elm_table_add(obj);
+   evas_object_size_hint_weight_set(sd->tbl, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(sd->tbl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   //spacer
+   sd->spacer = 
evas_object_rectangle_add(evas_object_evas_get(sd->hover_parent));
+   evas_object_size_hint_weight_set(sd->spacer, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(sd->spacer, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_color_set(sd->spacer, 0, 0, 0, 0);
+   elm_table_pack(sd->tbl, sd->spacer, 0, 0, 1, 1);
+   evas_object_show(sd->tbl);
+
+   // This is the genlist object that will take over the genlist call
+   sd->genlist = gl = eo_add(ELM_GENLIST_CLASS, obj);
+   elm_widget_mirrored_automatic_set(gl, EINA_FALSE);
+   elm_widget_mirrored_set(gl, elm_widget_mirrored_get(obj));
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(gl, "selected", _on_item_selected, obj);
+   evas_object_smart_callback_add(gl, "pressed", _on_item_pressed, obj);
+   eo_do(gl, eo_event_callback_add(ELM_GENLIST_EVENT_FILTER_DONE,
+         _gl_filter_finished_cb, obj));
+   elm_genlist_homogeneous_set(gl, EINA_TRUE);
+   elm_table_pack(sd->tbl, gl, 0, 0, 1, 1);
+   evas_object_show(sd->genlist);
+
+   // This is the entry object that will take over the entry call
+   sd->entry = entry = eo_add(ELM_ENTRY_CLASS, obj);
+   elm_widget_mirrored_automatic_set(entry, EINA_FALSE);
+   elm_widget_mirrored_set(entry, elm_widget_mirrored_get(obj));
+   elm_scroller_policy_set(entry, ELM_SCROLLER_POLICY_OFF,
+                           ELM_SCROLLER_POLICY_OFF);
+   elm_entry_scrollable_set(entry, EINA_TRUE);
+   elm_entry_single_line_set(entry, EINA_TRUE);
+   eo_do(entry, eo_event_callback_add(ELM_ENTRY_EVENT_CHANGED_USER,
+         _on_changed, obj));
+   eo_do(entry, eo_event_callback_add(ELM_ENTRY_EVENT_ABORTED,
+         _on_aborted, obj));
+   evas_object_show(entry);
+
+   snprintf(buf, sizeof(buf), "combobox_vertical/%s", 
elm_widget_style_get(obj));
+   elm_object_style_set(sd->hover, buf);
+   evas_object_smart_callback_add(sd->hover, "clicked", _on_hover_clicked, 
obj);
+   elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get
+                               (sd->hover, ELM_HOVER_AXIS_VERTICAL), sd->tbl);
+   eo_do(obj,
+         eo_composite_attach(gl),
+         eo_composite_attach(entry));
+
+   elm_object_part_content_set(obj, "elm.swallow.content", entry);
+   return obj;
+}
+
+EOLIAN static void
+_elm_combobox_hover_begin(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
+{
+   if (!sd->hover) return;
+   elm_object_focus_set(sd->entry, EINA_TRUE);
+   elm_genlist_filter_set(sd->genlist, (void *)elm_object_text_get(sd->entry));
+}
+
+EOLIAN static void
+_elm_combobox_hover_end(Eo *obj, Elm_Combobox_Data *sd)
+{
+   if (!sd->hover) return;
+
+   sd->expanded = EINA_FALSE;
+   evas_object_hide(sd->hover);
+   eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_DISMISSED, NULL));
+}
+
+EOLIAN static Eina_Bool
+_elm_combobox_expanded_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
+{
+   return sd->expanded;
+}
+
+static Eina_Bool
+_key_action_move(Evas_Object *obj, const char *params)
+{
+   ELM_COMBOBOX_DATA_GET(obj, sd);
+   Elm_Object_Item *it = NULL;
+   const char *dir = params;
+   if (!sd->hover) return EINA_FALSE;
+
+   if (!strcmp(dir, "return"))
+     eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_CLICKED, NULL));
+   else if (!strcmp(dir, "up"))
+     {
+        it = sd->item;
+        it = elm_genlist_item_prev_get(it);
+        if (!it) sd->item = elm_genlist_last_item_get(sd->genlist);
+        else sd->item = it;
+        elm_genlist_item_selected_set(sd->item, EINA_TRUE);
+     }
+   else if (!strcmp(dir, "down"))
+     {
+        it = sd->item;
+        it = elm_genlist_item_next_get(it);
+        if (!it) sd->item = elm_genlist_first_item_get(sd->genlist);
+        else sd->item = it;
+        elm_genlist_item_selected_set(sd->item, EINA_TRUE);
+     }
+   else return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
+{
+   elm_combobox_hover_begin(obj);
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_elm_combobox_elm_widget_event(Eo *obj, Elm_Combobox_Data *sd,
+                               Evas_Object *src EINA_UNUSED,
+                               Evas_Callback_Type type, void *event_info)
+{
+   Evas_Event_Key_Down *ev = event_info;
+   if (!sd || !sd->hover) return EINA_FALSE;
+   if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
+   if (!_elm_config_key_binding_call(obj, MY_CLASS_NAME, ev, key_actions))
+     return EINA_FALSE;
+
+   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+   return EINA_TRUE;
+}
+
+static void
+_elm_combobox_class_constructor(Eo_Class *klass)
+{
+   evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+}
+
+EOLIAN const Elm_Atspi_Action *
+_elm_combobox_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj 
EINA_UNUSED,
+                                                                
Elm_Combobox_Data *pd
+                                                                EINA_UNUSED)
+{
+   static Elm_Atspi_Action atspi_actions[] = {
+      {"activate", "activate", "return", _key_action_activate},
+      {"move,up", "move", "up", _key_action_move},
+      {"move,down", "move", "down", _key_action_move},
+      {NULL, NULL, NULL, NULL}
+   };
+   return &atspi_actions[0];
+}
+
+EOLIAN void
+_elm_combobox_elm_widget_part_text_set(Eo *obj EINA_UNUSED, Elm_Combobox_Data 
*pd,
+                                       const char * part, const char *label)
+{
+   elm_object_part_text_set(pd->entry, part, label);
+}
+
+EOLIAN const char *
+_elm_combobox_elm_widget_part_text_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data 
*pd,
+                                       const char * part)
+{
+   return elm_object_part_text_get(pd->entry, part);
+}
+
+EOLIAN static void
+_elm_combobox_evas_object_smart_resize(Eo *obj, Elm_Combobox_Data *pd,
+                                       Evas_Coord w, Evas_Coord h)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
+   if (pd->count > 0) _table_resize(obj);
+}
+#include "elm_combobox.eo.c"
diff --git a/src/lib/elc_combobox.h b/src/lib/elc_combobox.h
new file mode 100644
index 0000000..80e1ae4
--- /dev/null
+++ b/src/lib/elc_combobox.h
@@ -0,0 +1,64 @@
+/**
+ * @defgroup Combobox Combobox
+ * @ingroup Elementary
+ *
+ * @image html combobox_inheritance_tree.png
+ * @image latex combobox_inheritance_tree.eps
+ *
+ * @image html img/widget/combobox/preview-00.png
+ * @image latex img/widget/combobox/preview-00.eps
+ *
+ * A combobox is a button displaying an entry that pops up a list of items
+ * (automatically choosing the direction to display). It is a convenience
+ * widget to avoid the need to do all the piecing together yourself. It is
+ * intended for manipulating a large number of items in the combobox menu.
+ *
+ * This widget inherits from the @ref Button, @ref Genlist and @ref Entry
+ * one, so that all the functions acting on it also work for combobox objects.
+ *
+ * This widget emits the following signals, besides the ones sent from
+ * @ref Button:
+ * - @c "clicked" - the user clicked the combobox button and popped up
+ *   the sel
+ * - @c "selected" - an item in the combobox list is selected. event_info
+ *   is the selected item
+ * - @c "dismissed" - the hover is dismissed
+ * - @c "expanded" - This is called on clicking combobox and 
elm_combobox_hover_begin().
+ * - @c "language,changed" - the program's language changed (since 1.9)
+ * - @c "item,focused" - When the combobox item has received focus. (since 
1.10)
+ * - @c "item,unfocused" - When the combobox item has lost focus. (since 1.10)
+ *
+ * Default content parts of the combobox widget that you can use for are:
+ * @li "icon" - An icon of the combobox
+ *
+ * Default text parts of the combobox widget that you can use for are:
+ * @li "default" - A label of the combobox
+ *
+ * Supported elm_object common APIs.
+ * @li @ref elm_object_disabled_set
+ * @li @ref elm_object_disabled_get
+ * @li @ref elm_object_part_text_set
+ * @li @ref elm_object_part_text_get
+ * @li @ref elm_object_part_content_set
+ * @li @ref elm_object_part_content_unset
+ *
+ * Supported elm_object_item common APIs.
+ * @li elm_object_item_del
+ * @li elm_object_item_part_text_get
+ * @li elm_object_item_signal_emit - this works only when the item is created.
+ * @li elm_object_item_style_set - this works only when the item is created.
+ * @li elm_object_item_style_get - this works only when the item is created.
+ *
+ * See @ref tutorial_combobox for an example.
+ * @{
+ */
+
+#ifdef EFL_EO_API_SUPPORT
+#include "elm_combobox.eo.h"
+#endif
+#ifndef EFL_NOLEGACY_API_SUPPORT
+#include "elc_combobox_legacy.h"
+#endif
+/**
+ * @}
+ */
diff --git a/src/lib/elc_combobox_legacy.h b/src/lib/elc_combobox_legacy.h
new file mode 100644
index 0000000..0719c78
--- /dev/null
+++ b/src/lib/elc_combobox_legacy.h
@@ -0,0 +1,11 @@
+/**
+ * @brief Add a new Combobox object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Combobox
+ */
+EAPI Evas_Object                 *elm_combobox_add(Evas_Object *parent);
+
+#include "elm_combobox.eo.legacy.h"
diff --git a/src/lib/elm_authors.h b/src/lib/elm_authors.h
index 71cc0f6..f3ff5db 100644
--- a/src/lib/elm_authors.h
+++ b/src/lib/elm_authors.h
@@ -163,6 +163,7 @@
  * @author Subodh Kumar <s7158.kumar@@samsung.com>
  * @author Kumar Navneet <k.navneet@@samsung.com>
  * @author Godly T Alias <godly.talias@@samsung.com>
+ * @author Divyesh Purohit <div.puro...@samsung.com> <purohit....@gmail.com>
  *
  * Please contact <enlightenment-de...@lists.sourceforge.net> to get in
  * contact with the developers and maintainers.
diff --git a/src/lib/elm_combobox.eo b/src/lib/elm_combobox.eo
new file mode 100644
index 0000000..96cbb7e
--- /dev/null
+++ b/src/lib/elm_combobox.eo
@@ -0,0 +1,54 @@
+class Elm_Combobox (Elm.Button, Evas.Selectable_Interface,
+                    Elm_Interface_Atspi_Widget_Action,
+                    Elm.Entry, Elm.Genlist, Elm.Hover)
+{
+   eo_prefix: elm_obj_combobox;
+   methods {
+      @property expanded {
+         get {
+            [[Returns whether the combobox is expanded.
+
+            This will return EINA_TRUE if the combobox is expanded or
+            EINA_FALSE if it is not expanded.
+            ]]
+            return: bool;
+         }
+      }
+      hover_begin {
+         [[This triggers the combobox popup from code, the same as if the user
+         had clicked the button.
+         ]]
+      }
+      hover_end {
+         [[This dismisses the combobox popup as if the user had clicked
+         outside the hover.
+         ]]
+      }
+   }
+   implements {
+      class.constructor;
+      Eo.Base.constructor;
+      Evas.Object_Smart.hide;
+      Evas.Object_Smart.show;
+      Evas.Object_Smart.add;
+      Evas.Object_Smart.del;
+      Evas.Object_Smart.resize;
+      Elm.Widget.part_text.set;
+      Elm.Widget.part_text.get;
+      Elm.Widget.theme_apply;
+      Elm.Widget.translate;
+      Elm.Widget.event;
+      Elm.Button.admits_autorepeat.get;
+      Elm_Interface_Atspi_Widget_Action.elm_actions.get;
+   }
+   events {
+      selected;
+      dismissed;
+      expanded;
+      clicked;
+      item,pressed;
+      filter,done;
+      language,changed;
+      access,changed;
+   }
+}
diff --git a/src/lib/elm_config.c b/src/lib/elm_config.c
index 3496c6c..88595dc 100644
--- a/src/lib/elm_config.c
+++ b/src/lib/elm_config.c
@@ -1848,6 +1848,33 @@ _config_update(void)
    _elm_config->cursor_engine_only = 0;
    IFCFGEND
 
+   IFCFG(0x0007)
+   Elm_Config_Bindings_Widget *wb, *twb = NULL;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(tcfg->bindings, l, wb)
+     {
+        if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
+          {
+             twb = wb;
+             break;
+          }
+     }
+   if (twb)
+     {
+        EINA_LIST_FOREACH(_elm_config->bindings, l, wb)
+           {
+              if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
+                {
+                   // simply swap bindngs for Elm_Combobox with system ones
+                   Eina_List *tmp = wb->key_bindings;
+                   wb->key_bindings = twb->key_bindings;
+                   twb->key_bindings = tmp;
+                   break;
+                }
+           }
+     }
+   IFCFGEND
    /**
     * Fix user config for current ELM_CONFIG_EPOCH here.
     **/
diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h
index 0c83e73..f0dfd01 100644
--- a/src/lib/elm_priv.h
+++ b/src/lib/elm_priv.h
@@ -134,7 +134,7 @@ struct _Elm_Theme
  * the users config doesn't need to be wiped - simply new values need
  * to be put in
  */
-#define ELM_CONFIG_FILE_GENERATION 0x0006
+#define ELM_CONFIG_FILE_GENERATION 0x0007
 #define ELM_CONFIG_VERSION_EPOCH_OFFSET 16
 #define ELM_CONFIG_VERSION         ((ELM_CONFIG_EPOCH << 
ELM_CONFIG_VERSION_EPOCH_OFFSET) | \
                                     ELM_CONFIG_FILE_GENERATION)
diff --git a/src/lib/elm_widget_combobox.h b/src/lib/elm_widget_combobox.h
new file mode 100644
index 0000000..80ffe25
--- /dev/null
+++ b/src/lib/elm_widget_combobox.h
@@ -0,0 +1,80 @@
+#ifndef ELM_WIDGET_COMBOBOX_H
+#define ELM_WIDGET_COMBOBOX_H
+
+#include "Elementary.h"
+
+/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
+ * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
+ * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
+ * IT AT RUNTIME.
+ */
+
+/**
+ * @addtogroup Widget
+ * @{
+ *
+ * @section elm-combobox-class The Elementary Combobox Class
+ *
+ * Elementary, besides having the @ref Combobox widget, exposes its
+ * foundation -- the Elementary Combobox Class -- in order to create other
+ * widgets which are a combobox with some more logic on top.
+ */
+
+/**
+ * Base button smart data extended with combobox instance data.
+ */
+typedef struct _Elm_Combobox_Data Elm_Combobox_Data;
+struct _Elm_Combobox_Data
+{
+   /* aggregates a hover */
+   Evas_Object          *hover;
+   Evas_Object          *hover_parent;
+   Evas_Object          *genlist;
+   Evas_Object          *entry;
+   Evas_Object          *tbl;
+   Evas_Object          *spacer;
+   Elm_Object_Item      *item;
+   const char           *style;
+   int                   count;
+   int                   item_height;
+   Eina_Bool             expanded:1;
+};
+
+/**
+ * @}
+ */
+
+#define ELM_COMBOBOX_DATA_GET(o, sd) \
+  Elm_Combobox_Data * sd = eo_data_scope_get(o, ELM_COMBOBOX_CLASS)
+
+#define ELM_COMBOBOX_DATA_GET_OR_RETURN(o, ptr)      \
+  ELM_COMBOBOX_DATA_GET(o, ptr);                     \
+  if (EINA_UNLIKELY(!ptr))                           \
+    {                                                \
+       CRI("No widget data for object %p (%s)",      \
+           o, evas_object_type_get(o));              \
+       return;                                       \
+    }
+
+#define ELM_COMBOBOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+  ELM_COMBOBOX_DATA_GET(o, ptr);                         \
+  if (EINA_UNLIKELY(!ptr))                               \
+    {                                                    \
+       CRI("No widget data for object %p (%s)",          \
+           o, evas_object_type_get(o));                  \
+       return val;                                       \
+    }
+
+#define ELM_COMBOBOX_CHECK(obj)                              \
+  if (EINA_UNLIKELY(!eo_isa((obj), ELM_COMBOBOX_CLASS))) \
+    return
+
+#define ELM_COMBOBOX_ITEM_CHECK(it)                         \
+  ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \
+  ELM_COMBOBOX_CHECK(it->base.widget);
+
+#define ELM_COMBOBOX_ITEM_CHECK_OR_RETURN(it, ...)                     \
+  ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
+  ELM_COMBOBOX_CHECK(it->base.widget) __VA_ARGS__;
+
+#endif

-- 


Reply via email to