summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordivyesh purohit <div.purohit@samsung.com>2016-01-04 15:22:46 -0800
committerCedric BAIL <cedric@osg.samsung.com>2016-01-04 15:24:49 -0800
commitb4f8b8c0c66095730d4436db3987c3fad34aec95 (patch)
tree34f3e64220928f7c9732769f603044e1ebb9c4bc
parent8692c32417c61a5d3297f35687d44fc6ed1e1747 (diff)
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.bail@free.fr> Signed-Off By: Divyesh Purohit <div.purohit@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 <cedric@osg.samsung.com>
-rw-r--r--AUTHORS1
-rw-r--r--config/default/base.src.in49
-rw-r--r--config/mobile/base.src.in49
-rw-r--r--config/standard/base.src.in49
-rw-r--r--data/themes/edc/elm/button.edc299
-rw-r--r--data/themes/edc/elm/hover.edc4
-rw-r--r--src/bin/Makefile.am1
-rw-r--r--src/bin/test.c2
-rw-r--r--src/bin/test_combobox.c165
-rw-r--r--src/lib/Elementary.h.in1
-rw-r--r--src/lib/Makefile.am5
-rw-r--r--src/lib/elc_combobox.c458
-rw-r--r--src/lib/elc_combobox.h64
-rw-r--r--src/lib/elc_combobox_legacy.h11
-rw-r--r--src/lib/elm_authors.h1
-rw-r--r--src/lib/elm_combobox.eo54
-rw-r--r--src/lib/elm_config.c27
-rw-r--r--src/lib/elm_priv.h2
-rw-r--r--src/lib/elm_widget_combobox.h80
19 files changed, 1318 insertions, 4 deletions
diff --git a/AUTHORS b/AUTHORS
index 0e2457b0b..5ead385ae 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -166,3 +166,4 @@ Subodh Kumar <s7158.kumar@samsung.com>
166Kumar Navneet <k.navneet@samsung.com> 166Kumar Navneet <k.navneet@samsung.com>
167Godly T Alias <godly.talias@samsung.com> <godlytalias@yahoo.co.in> 167Godly T Alias <godly.talias@samsung.com> <godlytalias@yahoo.co.in>
168Shashank Pandey <shashank.p@samsung.com> <shashank0990@gmail.com> 168Shashank Pandey <shashank.p@samsung.com> <shashank0990@gmail.com>
169Divyesh Purohit <div.purohit@samsung.com> <purohit.div@gmail.com>
diff --git a/config/default/base.src.in b/config/default/base.src.in
index 7bf77132b..e86f7d8ee 100644
--- a/config/default/base.src.in
+++ b/config/default/base.src.in
@@ -1,5 +1,5 @@
1group "Elm_Config" struct { 1group "Elm_Config" struct {
2 value "config_version" int: 131078; 2 value "config_version" int: 131079;
3 value "engine" string: ""; 3 value "engine" string: "";
4 value "vsync" uchar: 0; 4 value "vsync" uchar: 0;
5 value "thumbscroll_enable" uchar: 1; 5 value "thumbscroll_enable" uchar: 1;
@@ -433,6 +433,53 @@ group "Elm_Config" struct {
433 } 433 }
434 } 434 }
435 group "Elm_Config_Bindings_Widget" struct { 435 group "Elm_Config_Bindings_Widget" struct {
436 value "name" string: "Elm_Combobox";
437 group "key_bindings" list {
438 group "Elm_Config_Binding_Key" struct {
439 value "context" int: 0;
440 value "key" string: "Return";
441 value "action" string: "activate";
442 value "params" string: "return";
443 }
444 group "Elm_Config_Binding_Key" struct {
445 value "context" int: 0;
446 value "key" string: "KP_Enter";
447 value "action" string: "activate";
448 value "params" string: "return";
449 }
450 group "Elm_Config_Binding_Key" struct {
451 value "context" int: 0;
452 value "key" string: "space";
453 value "action" string: "activate";
454 value "params" string: "return";
455 }
456 group "Elm_Config_Binding_Key" struct {
457 value "context" int: 0;
458 value "key" string: "Up";
459 value "action" string: "move";
460 value "params" string: "up";
461 }
462 group "Elm_Config_Binding_Key" struct {
463 value "context" int: 0;
464 value "key" string: "KP_Up";
465 value "action" string: "move";
466 value "params" string: "up";
467 }
468 group "Elm_Config_Binding_Key" struct {
469 value "context" int: 0;
470 value "key" string: "Down";
471 value "action" string: "move";
472 value "params" string: "down";
473 }
474 group "Elm_Config_Binding_Key" struct {
475 value "context" int: 0;
476 value "key" string: "KP_Down";
477 value "action" string: "move";
478 value "params" string: "down";
479 }
480 }
481 }
482 group "Elm_Config_Bindings_Widget" struct {
436 value "name" string: "Elm_Multibuttonentry"; 483 value "name" string: "Elm_Multibuttonentry";
437 group "key_bindings" list { 484 group "key_bindings" list {
438 group "Elm_Config_Binding_Key" struct { 485 group "Elm_Config_Binding_Key" struct {
diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in
index 44bfd6739..a588aa165 100644
--- a/config/mobile/base.src.in
+++ b/config/mobile/base.src.in
@@ -1,5 +1,5 @@
1group "Elm_Config" struct { 1group "Elm_Config" struct {
2 value "config_version" int: 131078; 2 value "config_version" int: 131079;
3 value "engine" string: ""; 3 value "engine" string: "";
4 value "vsync" uchar: 0; 4 value "vsync" uchar: 0;
5 value "thumbscroll_enable" uchar: 1; 5 value "thumbscroll_enable" uchar: 1;
@@ -437,6 +437,53 @@ group "Elm_Config" struct {
437 } 437 }
438 } 438 }
439 group "Elm_Config_Bindings_Widget" struct { 439 group "Elm_Config_Bindings_Widget" struct {
440 value "name" string: "Elm_Combobox";
441 group "key_bindings" list {
442 group "Elm_Config_Binding_Key" struct {
443 value "context" int: 0;
444 value "key" string: "Return";
445 value "action" string: "activate";
446 value "params" string: "return";
447 }
448 group "Elm_Config_Binding_Key" struct {
449 value "context" int: 0;
450 value "key" string: "KP_Enter";
451 value "action" string: "activate";
452 value "params" string: "return";
453 }
454 group "Elm_Config_Binding_Key" struct {
455 value "context" int: 0;
456 value "key" string: "space";
457 value "action" string: "activate";
458 value "params" string: "return";
459 }
460 group "Elm_Config_Binding_Key" struct {
461 value "context" int: 0;
462 value "key" string: "Up";
463 value "action" string: "move";
464 value "params" string: "up";
465 }
466 group "Elm_Config_Binding_Key" struct {
467 value "context" int: 0;
468 value "key" string: "KP_Up";
469 value "action" string: "move";
470 value "params" string: "up";
471 }
472 group "Elm_Config_Binding_Key" struct {
473 value "context" int: 0;
474 value "key" string: "Down";
475 value "action" string: "move";
476 value "params" string: "down";
477 }
478 group "Elm_Config_Binding_Key" struct {
479 value "context" int: 0;
480 value "key" string: "KP_Down";
481 value "action" string: "move";
482 value "params" string: "down";
483 }
484 }
485 }
486 group "Elm_Config_Bindings_Widget" struct {
440 value "name" string: "Elm_Multibuttonentry"; 487 value "name" string: "Elm_Multibuttonentry";
441 group "key_bindings" list { 488 group "key_bindings" list {
442 group "Elm_Config_Binding_Key" struct { 489 group "Elm_Config_Binding_Key" struct {
diff --git a/config/standard/base.src.in b/config/standard/base.src.in
index fd60d6a9c..745e5778e 100644
--- a/config/standard/base.src.in
+++ b/config/standard/base.src.in
@@ -1,5 +1,5 @@
1group "Elm_Config" struct { 1group "Elm_Config" struct {
2 value "config_version" int: 131078; 2 value "config_version" int: 131079;
3 value "engine" string: ""; 3 value "engine" string: "";
4 value "vsync" uchar: 0; 4 value "vsync" uchar: 0;
5 value "thumbscroll_enable" uchar: 0; 5 value "thumbscroll_enable" uchar: 0;
@@ -434,6 +434,53 @@ group "Elm_Config" struct {
434 } 434 }
435 } 435 }
436 group "Elm_Config_Bindings_Widget" struct { 436 group "Elm_Config_Bindings_Widget" struct {
437 value "name" string: "Elm_Combobox";
438 group "key_bindings" list {
439 group "Elm_Config_Binding_Key" struct {
440 value "context" int: 0;
441 value "key" string: "Return";
442 value "action" string: "activate";
443 value "params" string: "return";
444 }
445 group "Elm_Config_Binding_Key" struct {
446 value "context" int: 0;
447 value "key" string: "KP_Enter";
448 value "action" string: "activate";
449 value "params" string: "return";
450 }
451 group "Elm_Config_Binding_Key" struct {
452 value "context" int: 0;
453 value "key" string: "space";
454 value "action" string: "activate";
455 value "params" string: "return";
456 }
457 group "Elm_Config_Binding_Key" struct {
458 value "context" int: 0;
459 value "key" string: "Up";
460 value "action" string: "move";
461 value "params" string: "up";
462 }
463 group "Elm_Config_Binding_Key" struct {
464 value "context" int: 0;
465 value "key" string: "KP_Up";
466 value "action" string: "move";
467 value "params" string: "up";
468 }
469 group "Elm_Config_Binding_Key" struct {
470 value "context" int: 0;
471 value "key" string: "Down";
472 value "action" string: "move";
473 value "params" string: "down";
474 }
475 group "Elm_Config_Binding_Key" struct {
476 value "context" int: 0;
477 value "key" string: "KP_Down";
478 value "action" string: "move";
479 value "params" string: "down";
480 }
481 }
482 }
483 group "Elm_Config_Bindings_Widget" struct {
437 value "name" string: "Elm_Multibuttonentry"; 484 value "name" string: "Elm_Multibuttonentry";
438 group "key_bindings" list { 485 group "key_bindings" list {
439 group "Elm_Config_Binding_Key" struct { 486 group "Elm_Config_Binding_Key" struct {
diff --git a/data/themes/edc/elm/button.edc b/data/themes/edc/elm/button.edc
index 2134d41e3..9dd9f6186 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";
1712 } 1712 }
1713 } 1713 }
1714/******************* SPINNER BUTTONS STYLES END **********************/ 1714/******************* SPINNER BUTTONS STYLES END **********************/
1715group { name: "elm/button/base/combobox_vertical/default";
1716 alias: "elm/button/base/combobox_vertical/entry";
1717 alias: "elm/button/base/combobox_horizontal/default";
1718 alias: "elm/button/base/combobox_horizontal/entry";
1719
1720 images.image: "button_normal.png" COMP;
1721 images.image: "button_clicked.png" COMP;
1722 images.image: "vertical_separated_bar_glow.png" COMP;
1723 parts {
1724 image { "base"; nomouse;
1725 desc { "default";
1726 image.normal: "button_normal.png";
1727 image.border: 4 4 3 5;
1728 image.middle: SOLID;
1729 rel1.offset: -1 0;
1730 rel2.offset: 0 1;
1731 fill.smooth: 0;
1732 }
1733 desc { "clicked";
1734 inherit: "default";
1735 image.normal: "button_clicked.png";
1736 image.border: 5 5 4 6;
1737 }
1738 }
1739 rect { "icon_clip";
1740 desc { "default";
1741 }
1742 desc { "disabled";
1743 inherit: "default";
1744 color: 255 255 255 64;
1745 }
1746 }
1747 rect { "event";
1748 desc { "default";
1749 color: 0 0 0 0;
1750 }
1751 desc { "disabled";
1752 inherit: "default";
1753 visible: 0;
1754 }
1755 }
1756 swallow { "elm.swallow.content";
1757 clip_to: "icon_clip";
1758 desc { "default";
1759 fixed: 0 0;
1760 align: 0.5 0.5;
1761 rel1.offset: 6 5;
1762 rel1.to: "base";
1763 rel2.relative: 0.0 1.0;
1764 rel2.offset: -3 -8;
1765 rel2.to: "select_line";
1766 visible: 1;
1767 }
1768 }
1769 image { "select_line"; nomouse;
1770 desc { "default";
1771 fixed: 1 1;
1772 align: 1.0 0.5;
1773 min: 15 10;
1774 rel1.to: "base";
1775 rel1.relative: 1.0 0.0;
1776 rel1.offset: 1 -3;
1777 rel2.to: "base";
1778 rel2.offset: 1 0;
1779 image.normal: "vertical_separated_bar_glow.png";
1780 image.border: 7 7 7 7;
1781 fill.smooth : 0;
1782 }
1783 desc { "clicked";
1784 inherit: "default";
1785 rel1.offset: 0 -2;
1786 rel2.offset: 0 -1;
1787 }
1788 }
1789 }
1790 programs {
1791 program {
1792 signal: "mouse,down,1"; source: "event";
1793 action: SIGNAL_EMIT "elm,action,press" "elm";
1794 after: "button_click_anim";
1795 }
1796 program { name: "button_click_anim";
1797 action: STATE_SET "clicked" 0.0;
1798 target: "base";
1799 target: "select_line";
1800 }
1801 program { name: "button_unclick";
1802 signal: "mouse,up,1"; source: "event";
1803 action: SIGNAL_EMIT "elm,action,unpress" "elm";
1804 after: "button_unclick_anim";
1805 }
1806 program { name: "button_unclick_anim";
1807 action: STATE_SET "default" 0.0;
1808 target: "base";
1809 target: "select_line";
1810 }
1811 program { name: "buttonactivate";
1812 signal: "elm,anim,activate"; source: "elm";
1813 action: STATE_SET "clicked" 0.0;
1814 target: "base";
1815 target: "select_line";
1816 after: "button_unpressed_anim";
1817 }
1818 program { name: "button_unpressed_anim";
1819 action: STATE_SET "default" 0.0;
1820 in: 0.5 0.0;
1821 target: "base";
1822 target: "select_line";
1823 }
1824 program {
1825 signal: "mouse,clicked,1"; source: "event";
1826 action: SIGNAL_EMIT "elm,action,click" "elm";
1827 }
1828 program { name: "button_state_disabled";
1829 signal: "elm,state,disabled"; source: "elm";
1830 action: STATE_SET "disabled" 0.0;
1831 target: "icon_clip";
1832 target: "event";
1833 }
1834 program { name: "button_state_enabled";
1835 signal: "elm,state,enabled"; source: "elm";
1836 action: STATE_SET "default" 0.0;
1837 target: "icon_clip";
1838 target: "event";
1839 }
1840 }
1841}
1842
1843group { name: "elm/button/base/combobox_vertical_entry/default";
1844 alias: "elm/button/base/combobox_vertical_entry/entry";
1845 images.image: "vgrad_med_dark.png" COMP;
1846 images.image: "bevel_horiz_out.png" COMP;
1847 images.image: "shadow_rounded_horiz.png" COMP;
1848 images.image: "shine.png" COMP;
1849
1850 parts {
1851 image { "shadow"; nomouse;
1852 desc { "default";
1853 fixed: 1 1;
1854 image.normal: "shadow_rounded_horiz.png";
1855 image.border: 0 0 9 9;
1856 rel1.to: "base";
1857 rel1.offset: 0 -4;
1858 rel2.to: "base";
1859 rel2.offset: -1 5;
1860 fill.smooth: 0;
1861 visible: 0;
1862 }
1863 desc { "clicked";
1864 inherit: "default";
1865 visible: 1;
1866 }
1867 }
1868 image { "base"; nomouse;
1869 desc { "default";
1870 fixed: 1 1;
1871 rel1.offset: -6 0;
1872 image.normal: "vgrad_med_dark.png";
1873 fill.smooth: 0;
1874 TILED_HORIZ(120)
1875 visible: 0;
1876 }
1877 desc { "clicked";
1878 inherit: "default";
1879 visible: 1;
1880 }
1881 }
1882 rect { "icon_clip";
1883 desc { "default";
1884 }
1885 desc { "disabled";
1886 inherit: "default";
1887 color: 255 255 255 64;
1888 }
1889 }
1890 image { "bevel"; nomouse;
1891 desc { "default";
1892 fixed: 1 1;
1893 image.normal: "bevel_horiz_out.png";
1894 image.border: 0 0 2 2;
1895 image.middle: 0;
1896 fill.smooth: 0;
1897 visible: 0;
1898 }
1899 desc { "clicked";
1900 inherit: "default";
1901 visible: 1;
1902 }
1903 }
1904 image { "shine"; nomouse;
1905 desc { "default";
1906 fixed: 1 1;
1907 rel1.to: "base";
1908 rel1.offset: 0 -2;
1909 rel2.to: "base";
1910 rel2.relative: 1.0 0.0;
1911 rel2.offset: -1 2;
1912 image.normal: "shine.png";
1913 visible: 0;
1914 FIXED_SIZE(69, 5)
1915 }
1916 desc { "clicked";
1917 inherit: "default";
1918 visible: 1;
1919 }
1920 }
1921 rect { name: "event";
1922 desc { "default";
1923 color: 0 0 0 0;
1924 }
1925 desc { "disabled";
1926 inherit: "default";
1927 visible: 0;
1928 }
1929 }
1930 swallow { "elm.swallow.content"; nomouse;
1931 clip_to: "icon_clip";
1932 desc { "default";
1933 fixed: 1 0;
1934 align: 0.0 0.5;
1935 rel1.offset: 6 5;
1936 rel1.to: "base";
1937 rel2.relative: 0.0 1.0;
1938 rel2.offset: 6 -8;
1939 rel2.to: "base";
1940 visible: 0;
1941 }
1942 desc { "visible";
1943 inherit: "default";
1944 fixed: 1 0;
1945 aspect: 1.0 1.0;
1946 visible: 1;
1947 }
1948 desc { "icononly";
1949 inherit: "default";
1950 fixed: 0 0;
1951 align: 0.5 0.5;
1952 rel2.relative: 1.0 1.0;
1953 rel2.offset: -7 -8;
1954 visible: 1;
1955 }
1956 }
1957 }
1958 programs {
1959 program {
1960 signal: "mouse,down,1"; source: "event";
1961 action: SIGNAL_EMIT "elm,action,press" "elm";
1962 after: "button_click_anim";
1963 }
1964 program { name: "button_click_anim";
1965 action: STATE_SET "clicked" 0.0;
1966 target: "shadow";
1967 target: "base";
1968 target: "shine";
1969 }
1970 program { name: "button_unclick";
1971 signal: "mouse,up,1"; source: "event";
1972 action: SIGNAL_EMIT "elm,action,unpress" "elm";
1973 after: "button_unclick_anim";
1974 }
1975 program { name: "button_unclick_anim";
1976 action: STATE_SET "default" 0.0;
1977 target: "shadow";
1978 target: "base";
1979 target: "shine";
1980 }
1981 program { name: "buttonactivate";
1982 signal: "elm,anim,activate"; source: "elm";
1983 action: STATE_SET "clicked" 0.0;
1984 target: "shadow";
1985 target: "base";
1986 target: "shine";
1987 after: "button_unpressed_anim";
1988 }
1989 program { name: "button_unpressed_anim";
1990 action: STATE_SET "default" 0.0;
1991 in: 0.5 0.0;
1992 target: "shadow";
1993 target: "base";
1994 target: "shine";
1995 }
1996 program {
1997 signal: "mouse,clicked,1"; source: "event";
1998 action: SIGNAL_EMIT "elm,action,click" "elm";
1999 }
2000 program { name: "button_state_disabled";
2001 signal: "elm,state,disabled"; source: "elm";
2002 action: STATE_SET "disabled" 0.0;
2003 target: "event";
2004 target: "icon_clip";
2005 }
2006 program { name: "button_state_enabled";
2007 signal: "elm,state,enabled"; source: "elm";
2008 action: STATE_SET "default" 0.0;
2009 target: "event";
2010 target: "icon_clip";
2011 }
2012 }
2013}
diff --git a/data/themes/edc/elm/hover.edc b/data/themes/edc/elm/hover.edc
index 8a7ed497f..75ea8138c 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";
439 439
440group { name: "elm/hover/base/hoversel_vertical/default"; 440group { name: "elm/hover/base/hoversel_vertical/default";
441 alias: "elm/hover/base/hoversel_vertical/entry"; 441 alias: "elm/hover/base/hoversel_vertical/entry";
442 alias: "elm/hover/base/combobox_vertical/entry";
443 alias: "elm/hover/base/combobox_vertical/default";
442 images.image: "button_normal.png" COMP; 444 images.image: "button_normal.png" COMP;
443 images.image: "vertical_separated_bar_glow.png" COMP; 445 images.image: "vertical_separated_bar_glow.png" COMP;
444 data.item: "dismiss" "on"; 446 data.item: "dismiss" "on";
@@ -773,6 +775,8 @@ group { name: "elm/hover/base/hoversel_vertical/default";
773 775
774group { name: "elm/hover/base/hoversel_horizontal/default"; 776group { name: "elm/hover/base/hoversel_horizontal/default";
775 alias: "elm/hover/base/hoversel_horizontal/entry"; 777 alias: "elm/hover/base/hoversel_horizontal/entry";
778 alias: "elm/hover/base/combobox_horizontal/default";
779 alias: "elm/hover/base/combobox_horizontal/entry";
776 images.image: "button_normal.png" COMP; 780 images.image: "button_normal.png" COMP;
777 data.item: "dismiss" "on"; 781 data.item: "dismiss" "on";
778 // max_size limits the maximum size of expanded hoversel 782 // max_size limits the maximum size of expanded hoversel
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index b93374a11..46db673e5 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -43,6 +43,7 @@ test_clock.c \
43test_cnp.c \ 43test_cnp.c \
44test_colorselector.c \ 44test_colorselector.c \
45test_colorclass.c \ 45test_colorclass.c \
46test_combobox.c \
46test_config.c \ 47test_config.c \
47test_conform.c \ 48test_conform.c \
48test_conform_indicator.c \ 49test_conform_indicator.c \
diff --git a/src/bin/test.c b/src/bin/test.c
index 53f419d5b..a3ae31d1b 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);
45void test_clock_edit(void *data, Evas_Object *obj, void *event_info); 45void test_clock_edit(void *data, Evas_Object *obj, void *event_info);
46void test_clock_edit2(void *data, Evas_Object *obj, void *event_info); 46void test_clock_edit2(void *data, Evas_Object *obj, void *event_info);
47void test_clock_pause(void *data, Evas_Object *obj, void *event_info); 47void test_clock_pause(void *data, Evas_Object *obj, void *event_info);
48void test_combobox(void *data, Evas_Object *obj, void *event_info);
48void test_check(void *data, Evas_Object *obj, void *event_info); 49void test_check(void *data, Evas_Object *obj, void *event_info);
49void test_check_toggle(void *data, Evas_Object *obj, void *event_info); 50void test_check_toggle(void *data, Evas_Object *obj, void *event_info);
50void test_radio(void *data, Evas_Object *obj, void *event_info); 51void test_radio(void *data, Evas_Object *obj, void *event_info);
@@ -753,6 +754,7 @@ add_tests:
753 ADD_TEST(NULL, "Selectors", "FlipSelector", test_flipselector); 754 ADD_TEST(NULL, "Selectors", "FlipSelector", test_flipselector);
754 ADD_TEST(NULL, "Selectors", "DaySelector", test_dayselector); 755 ADD_TEST(NULL, "Selectors", "DaySelector", test_dayselector);
755 ADD_TEST(NULL, "Selectors", "Main menu", test_main_menu); 756 ADD_TEST(NULL, "Selectors", "Main menu", test_main_menu);
757 ADD_TEST(NULL, "Selectors", "Combobox", test_combobox);
756 758
757 //------------------------------// 759 //------------------------------//
758 ADD_TEST(NULL, "Cursors", "Cursor", test_cursor); 760 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 000000000..b5f11729c
--- /dev/null
+++ b/src/bin/test_combobox.c
@@ -0,0 +1,165 @@
1#include "test.h"
2#ifdef HAVE_CONFIG_H
3# include "elementary_config.h"
4#endif
5#include <Elementary.h>
6
7static void
8_combobox_clicked_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
9 void *event_info EINA_UNUSED)
10{
11 printf("Hover button is clicked and 'clicked' callback is called.\n");
12}
13
14static void
15_combobox_selected_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
16 void *event_info)
17{
18 const char *txt = elm_object_item_text_get(event_info);
19 printf("'selected' callback is called. (selected item : %s)\n", txt);
20}
21
22static void
23_combobox_dismissed_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
24 void *event_info EINA_UNUSED)
25{
26 printf("'dismissed' callback is called.\n");
27}
28
29static void
30_combobox_expanded_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
31 void *event_info EINA_UNUSED)
32{
33 printf("'expanded' callback is called.\n");
34}
35
36static void
37_combobox_item_pressed_cb(void *data EINA_UNUSED, Evas_Object *obj,
38 void *event_info)
39{
40 const char *txt = elm_object_item_text_get(event_info);
41 printf("'item,pressed' callback is called. (selected item : %s)\n", txt);
42 elm_object_text_set(obj, txt);
43 elm_combobox_hover_end(obj);
44}
45
46static char *
47gl_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
48{
49 char buf[256];
50 snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data);
51 return strdup(buf);
52}
53
54static Evas_Object *gl_content_get(void *data EINA_UNUSED, Evas_Object *obj,
55 const char *part)
56{
57 char buf[PATH_MAX];
58 Evas_Object *ic = elm_icon_add(obj);
59 if (!strcmp(part, "elm.swallow.end"))
60 snprintf(buf, sizeof(buf), "%s/images/bubble.png", elm_app_data_dir_get());
61 else
62 snprintf(buf, sizeof(buf), "%s/images/logo_small.png", elm_app_data_dir_get());
63 elm_image_file_set(ic, buf, NULL);
64 evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
65 return ic;
66}
67
68static Eina_Bool gl_state_get(void *data EINA_UNUSED,
69 Evas_Object *obj EINA_UNUSED,
70 const char *part EINA_UNUSED)
71{
72 return EINA_FALSE;
73}
74
75static Eina_Bool
76gl_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key)
77{
78 // if the key is empty/NULL, return true for item
79 if (!strlen((char *)key)) return EINA_TRUE;
80 char buf[256];
81 snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data);
82 if (strcasestr(buf, (char *)key))
83 return EINA_TRUE;
84 // Default case should return false (item fails filter hence will be hidden)
85 return EINA_FALSE;
86}
87
88static void
89_gl_filter_finished_cb(void *data EINA_UNUSED,
90 Evas_Object *obj EINA_UNUSED,
91 void *event_info EINA_UNUSED)
92{
93 printf("Filter finished\n");
94}
95
96void
97test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
98 void *event_info EINA_UNUSED)
99{
100 Evas_Object *win, *bx, *combobox;
101 Elm_Genlist_Item_Class *itc;
102 win = elm_win_util_standard_add("combobox", "Combobox");
103 elm_win_autodel_set(win, EINA_TRUE);
104
105 bx = elm_box_add(win);
106 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
107 elm_win_resize_object_add(win, bx);
108 evas_object_show(bx);
109
110 itc = elm_genlist_item_class_new();
111 itc->item_style = "default";
112 itc->func.text_get = gl_text_get;
113 itc->func.content_get = gl_content_get;
114 itc->func.state_get = gl_state_get;
115 itc->func.filter_get = gl_filter_get;
116 itc->func.del = NULL;
117
118 combobox = elm_combobox_add(win);
119 evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
120 evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
121 elm_object_part_text_set(combobox, "guide", "A long list");
122 for (int i = 0; i < 1000; i++)
123 elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
124 NULL, ELM_GENLIST_ITEM_NONE, NULL,
125 (void*)(uintptr_t)(i * 10));
126 evas_object_smart_callback_add(combobox, "clicked",
127 _combobox_clicked_cb, NULL);
128 evas_object_smart_callback_add(combobox, "selected",
129 _combobox_selected_cb, NULL);
130 evas_object_smart_callback_add(combobox, "dismissed",
131 _combobox_dismissed_cb, NULL);
132 evas_object_smart_callback_add(combobox, "expanded",
133 _combobox_expanded_cb, NULL);
134 evas_object_smart_callback_add(combobox, "item,pressed",
135 _combobox_item_pressed_cb, NULL);
136 evas_object_smart_callback_add(combobox, "filter,done",
137 _gl_filter_finished_cb, NULL);
138 elm_box_pack_end(bx, combobox);
139 evas_object_show(combobox);
140
141 combobox = elm_combobox_add(win);
142 evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
143 evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
144 elm_object_text_set(combobox, "Disabled Combobox");
145 for (int i = 0; i < 1000; i++)
146 elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
147 NULL, ELM_GENLIST_ITEM_NONE, NULL,
148 (void*)(uintptr_t)(i * 10));
149 evas_object_smart_callback_add(combobox, "clicked",
150 _combobox_clicked_cb, NULL);
151 evas_object_smart_callback_add(combobox, "selected",
152 _combobox_selected_cb, NULL);
153 evas_object_smart_callback_add(combobox, "dismissed",
154 _combobox_dismissed_cb, NULL);
155 evas_object_smart_callback_add(combobox, "expanded",
156 _combobox_expanded_cb, NULL);
157 evas_object_smart_callback_add(combobox, "filter,done",
158 _gl_filter_finished_cb, NULL);
159 elm_object_disabled_set(combobox, EINA_TRUE);
160 elm_box_pack_end(bx, combobox);
161 evas_object_show(combobox);
162
163 evas_object_resize(win, 320, 500);
164 evas_object_show(win);
165}
diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in
index 1cd7c7616..7dceefaca 100644
--- a/src/lib/Elementary.h.in
+++ b/src/lib/Elementary.h.in
@@ -174,6 +174,7 @@ EAPI extern Elm_Version *elm_version;
174 174
175/* other includes */ 175/* other includes */
176#include <elc_ctxpopup.h> 176#include <elc_ctxpopup.h>
177#include <elc_combobox.h>
177#include <elm_dayselector.h> 178#include <elm_dayselector.h>
178#include <elc_fileselector_button.h> 179#include <elc_fileselector_button.h>
179#include <elc_fileselector_entry.h> 180#include <elc_fileselector_entry.h>
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 20f6521b8..40fb59746 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -56,6 +56,7 @@ elm_widget_clock.h \
56elm_widget_colorselector.h \ 56elm_widget_colorselector.h \
57elm_widget_conform.h \ 57elm_widget_conform.h \
58elm_widget_container.h \ 58elm_widget_container.h \
59elm_widget_combobox.h \
59elm_widget_ctxpopup.h \ 60elm_widget_ctxpopup.h \
60elm_widget_datetime.h \ 61elm_widget_datetime.h \
61elm_widget_dayselector.h \ 62elm_widget_dayselector.h \
@@ -114,6 +115,8 @@ includesub_HEADERS = \
114elc_ctxpopup.h \ 115elc_ctxpopup.h \
115elc_ctxpopup_eo.h \ 116elc_ctxpopup_eo.h \
116elc_ctxpopup_legacy.h \ 117elc_ctxpopup_legacy.h \
118elc_combobox.h \
119elc_combobox_legacy.h \
117elc_fileselector.h \ 120elc_fileselector.h \
118elc_fileselector_eo.h \ 121elc_fileselector_eo.h \
119elc_fileselector_legacy.h \ 122elc_fileselector_legacy.h \
@@ -415,6 +418,7 @@ elm_clock.c \
415elm_cnp.c \ 418elm_cnp.c \
416elm_colorselector.c \ 419elm_colorselector.c \
417elm_color_class.c \ 420elm_color_class.c \
421elc_combobox.c \
418elm_config.c \ 422elm_config.c \
419elm_conform.c \ 423elm_conform.c \
420elm_container.c \ 424elm_container.c \
@@ -531,6 +535,7 @@ elm_calendar.eo \
531elm_check.eo \ 535elm_check.eo \
532elm_clock.eo \ 536elm_clock.eo \
533elm_colorselector.eo \ 537elm_colorselector.eo \
538elm_combobox.eo \
534elm_conformant.eo \ 539elm_conformant.eo \
535elm_container.eo \ 540elm_container.eo \
536elm_ctxpopup.eo \ 541elm_ctxpopup.eo \
diff --git a/src/lib/elc_combobox.c b/src/lib/elc_combobox.c
new file mode 100644
index 000000000..7e5487ffc
--- /dev/null
+++ b/src/lib/elc_combobox.c
@@ -0,0 +1,458 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EO_BASE_BETA
6#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
7#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
8
9#include <Elementary.h>
10#include "elm_priv.h"
11#include "elm_widget_combobox.h"
12
13#define MY_CLASS ELM_COMBOBOX_CLASS
14
15#define MY_CLASS_NAME "Elm_Combobox"
16#define MY_CLASS_NAME_LEGACY "elm_combobox"
17
18static const char SIG_SELECTED[] = "selected";
19static const char SIG_DISMISSED[] = "dismissed";
20static const char SIG_EXPANDED[] = "expanded";
21static const char SIG_ITEM_PRESSED[] = "item,pressed";
22static const char SIG_FILTER_DONE[] = "filter,done";
23
24static const Evas_Smart_Cb_Description _smart_callbacks[] = {
25 {SIG_SELECTED, ""},
26 {SIG_DISMISSED, ""},
27 {SIG_EXPANDED, ""},
28 {SIG_ITEM_PRESSED, ""},
29 {SIG_FILTER_DONE, ""},
30 {"clicked", ""}, /**< handled by parent button class */
31 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
32 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
33 {NULL, NULL}
34};
35
36static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
37static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
38
39static const Elm_Action key_actions[] = {
40 {"activate", _key_action_activate},
41 {"move", _key_action_move},
42 {NULL, NULL}
43};
44
45EOLIAN static Eina_Bool
46_elm_combobox_elm_widget_translate(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
47{
48 eo_do_super(obj, MY_CLASS, elm_obj_widget_translate());
49 eo_do(sd->genlist, elm_obj_widget_translate());
50 eo_do(sd->entry, elm_obj_widget_translate());
51
52 if (sd->hover)
53 eo_do(sd->hover, elm_obj_widget_translate());
54
55 return EINA_TRUE;
56}
57
58EOLIAN static Eina_Bool
59_elm_combobox_elm_widget_theme_apply(Eo *obj, Elm_Combobox_Data *sd)
60{
61 const char *style;
62 Eina_Bool int_ret = EINA_FALSE;
63 Eina_Bool mirrored;
64 char buf[128];
65
66 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
67
68 style = elm_widget_style_get(obj);
69
70 snprintf(buf, sizeof(buf), "combobox_vertical/%s", style);
71
72 /* combobox's style has no extra bit for orientation but could have... */
73 eina_stringshare_replace(&(wd->style), buf);
74
75 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
76 if (!int_ret) return EINA_FALSE;
77
78 mirrored = elm_widget_mirrored_get(obj);
79
80 if (sd->hover)
81 elm_widget_mirrored_set(sd->hover, mirrored);
82
83 elm_widget_mirrored_set(sd->genlist, mirrored);
84 elm_widget_mirrored_set(sd->entry, mirrored);
85
86 elm_combobox_hover_end(obj);
87
88 return EINA_TRUE;
89}
90
91static void
92_on_hover_clicked(void *data,
93 Evas_Object *obj EINA_UNUSED,
94 void *event_info EINA_UNUSED)
95{
96 elm_combobox_hover_end(data);
97}
98
99static void
100count_items_genlist(void *data)
101{
102 ELM_COMBOBOX_DATA_GET(data, sd);
103 Eina_Iterator *filter_iter;
104 int count = 0;
105 Elm_Object_Item *item;
106
107 filter_iter = elm_genlist_filter_iterator_new(sd->genlist);
108 if (!filter_iter) return;
109 EINA_ITERATOR_FOREACH(filter_iter, item)
110 if (item) count++;
111 sd->count = count;
112 eina_iterator_free(filter_iter);
113}
114
115static void
116_table_resize(void *data)
117{
118 ELM_COMBOBOX_DATA_GET(data, sd);
119 if (sd->count > 0)
120 {
121 int hover_parent_w, hover_parent_h, obj_h, obj_w, obj_y, win_y_offset;
122 int current_height, h;
123 sd->item = elm_genlist_first_item_get(sd->genlist);
124 elm_genlist_item_selected_set(sd->item, EINA_TRUE);
125 //FIXME:- the height of item is zero, sometimes.
126 evas_object_geometry_get(elm_object_item_track(sd->item), NULL, NULL,
127 NULL, &h);
128 if (h) sd->item_height = h;
129 evas_object_geometry_get(sd->entry, NULL, NULL, &obj_w, NULL);
130 evas_object_geometry_get(data, NULL, &obj_y, NULL, &obj_h);
131 evas_object_geometry_get(sd->hover_parent, NULL, NULL, &hover_parent_w,
132 &hover_parent_h);
133 current_height = sd->item_height * sd->count;
134 if (!strcmp(elm_hover_best_content_location_get(sd->hover,
135 ELM_HOVER_AXIS_VERTICAL),
136 "bottom"))
137 win_y_offset = hover_parent_h - obj_y - obj_h;
138 else win_y_offset = obj_y;
139 if (current_height < win_y_offset)
140 evas_object_size_hint_min_set(sd->spacer, obj_w * elm_config_scale_get(),
141 current_height + (2 * elm_config_scale_get()));
142 else evas_object_size_hint_min_set(sd->spacer, obj_w * elm_config_scale_get(),
143 win_y_offset * elm_config_scale_get());
144 }
145}
146
147static void
148_activate(Evas_Object *obj)
149{
150 ELM_COMBOBOX_DATA_GET(obj, sd);
151 if (elm_widget_disabled_get(obj)) return;
152 sd->expanded = EINA_TRUE;
153 eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_EXPANDED, NULL));
154 _table_resize(obj);
155 evas_object_show(sd->hover);
156}
157
158static void
159_on_item_selected(void *data , Evas_Object *obj EINA_UNUSED, void *event)
160{
161 ELM_COMBOBOX_DATA_GET(data, sd);
162 elm_object_focus_set(sd->entry, EINA_TRUE);
163 eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_SELECTED, event));
164}
165
166static void
167_on_item_pressed(void *data , Evas_Object *obj EINA_UNUSED, void *event)
168{
169 eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_ITEM_PRESSED, event));
170}
171
172static Eina_Bool
173_gl_filter_finished_cb(void *data, Eo *obj EINA_UNUSED,
174 const Eo_Event_Description *desc EINA_UNUSED, void *event)
175{
176 ELM_COMBOBOX_DATA_GET(data, sd);
177 eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_FILTER_DONE, event));
178 count_items_genlist(data);
179 if (sd->count > 0)
180 {
181 if (sd->expanded == EINA_TRUE)
182 elm_combobox_hover_end(data);
183 _activate(data);
184 }
185 else elm_combobox_hover_end(data);
186 return EINA_TRUE;
187}
188
189static Eina_Bool
190_on_aborted(void *data, Eo *obj EINA_UNUSED,
191 const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
192{
193 ELM_COMBOBOX_DATA_GET(data, sd);
194 if (sd->expanded == EINA_TRUE) elm_combobox_hover_end(data);
195 return EINA_TRUE;
196}
197
198static Eina_Bool
199_on_changed(void *data, Eo *obj EINA_UNUSED,
200 const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
201{
202 elm_combobox_hover_begin(data);
203 return EINA_TRUE;
204}
205
206static void
207_on_clicked(void *data,
208 Evas_Object *obj EINA_UNUSED,
209 void *event_info EINA_UNUSED)
210{
211 elm_combobox_hover_begin(data);
212}
213
214EOLIAN static void
215_elm_combobox_evas_object_smart_add(Eo *obj, Elm_Combobox_Data *sd EINA_UNUSED)
216{
217 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
218 elm_widget_sub_object_parent_add(obj);
219
220 elm_widget_mirrored_automatic_set(obj, EINA_FALSE);
221
222 evas_object_smart_callback_add(obj, "clicked", _on_clicked, obj);
223
224 //What are you doing here?
225 eo_do(obj, elm_obj_widget_theme_apply());
226}
227
228EOLIAN static void
229_elm_combobox_evas_object_smart_del(Eo *obj, Elm_Combobox_Data *sd)
230{
231 sd->hover_parent = NULL;
232 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
233}
234
235EOLIAN static void
236_elm_combobox_evas_object_smart_show(Eo *obj, Elm_Combobox_Data *sd)
237{
238 eo_do_super(obj, MY_CLASS, evas_obj_smart_show());
239 if (sd->expanded) evas_object_show(sd->hover);
240}
241
242EOLIAN static void
243_elm_combobox_evas_object_smart_hide(Eo *obj, Elm_Combobox_Data *sd)
244{
245 eo_do_super(obj, MY_CLASS, evas_obj_smart_hide());
246 if (sd->hover) evas_object_hide(sd->hover);
247}
248
249EOLIAN static Eina_Bool
250_elm_combobox_elm_button_admits_autorepeat_get(Eo *obj EINA_UNUSED,
251 Elm_Combobox_Data *sd EINA_UNUSED)
252{
253 return EINA_FALSE;
254}
255
256EAPI Evas_Object *
257elm_combobox_add(Evas_Object *parent)
258{
259 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
260 Evas_Object *obj = eo_add(MY_CLASS, parent);
261 return obj;
262}
263
264EOLIAN static Eo *
265_elm_combobox_eo_base_constructor(Eo *obj, Elm_Combobox_Data *sd)
266{
267 Evas_Object *gl;
268 Evas_Object *entry;
269 char buf[128];
270
271 eo_do_super(obj, MY_CLASS, eo_constructor());
272
273 eo_do(obj,
274 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
275 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
276 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_GLASS_PANE));
277
278 //hover-parent
279 sd->hover_parent = elm_object_parent_widget_get(obj);
280
281 //hover
282 sd->hover = eo_add(ELM_HOVER_CLASS, sd->hover_parent);
283 elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE);
284 elm_hover_target_set(sd->hover, obj);
285
286 //table
287 sd->tbl = elm_table_add(obj);
288 evas_object_size_hint_weight_set(sd->tbl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
289 evas_object_size_hint_align_set(sd->tbl, EVAS_HINT_FILL, EVAS_HINT_FILL);
290
291 //spacer
292 sd->spacer = evas_object_rectangle_add(evas_object_evas_get(sd->hover_parent));
293 evas_object_size_hint_weight_set(sd->spacer, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
294 evas_object_size_hint_align_set(sd->spacer, EVAS_HINT_FILL, EVAS_HINT_FILL);
295 evas_object_color_set(sd->spacer, 0, 0, 0, 0);
296 elm_table_pack(sd->tbl, sd->spacer, 0, 0, 1, 1);
297 evas_object_show(sd->tbl);
298
299 // This is the genlist object that will take over the genlist call
300 sd->genlist = gl = eo_add(ELM_GENLIST_CLASS, obj);
301 elm_widget_mirrored_automatic_set(gl, EINA_FALSE);
302 elm_widget_mirrored_set(gl, elm_widget_mirrored_get(obj));
303 evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
304 evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
305 evas_object_smart_callback_add(gl, "selected", _on_item_selected, obj);
306 evas_object_smart_callback_add(gl, "pressed", _on_item_pressed, obj);
307 eo_do(gl, eo_event_callback_add(ELM_GENLIST_EVENT_FILTER_DONE,
308 _gl_filter_finished_cb, obj));
309 elm_genlist_homogeneous_set(gl, EINA_TRUE);
310 elm_table_pack(sd->tbl, gl, 0, 0, 1, 1);
311 evas_object_show(sd->genlist);
312
313 // This is the entry object that will take over the entry call
314 sd->entry = entry = eo_add(ELM_ENTRY_CLASS, obj);
315 elm_widget_mirrored_automatic_set(entry, EINA_FALSE);
316 elm_widget_mirrored_set(entry, elm_widget_mirrored_get(obj));
317 elm_scroller_policy_set(entry, ELM_SCROLLER_POLICY_OFF,
318 ELM_SCROLLER_POLICY_OFF);
319 elm_entry_scrollable_set(entry, EINA_TRUE);
320 elm_entry_single_line_set(entry, EINA_TRUE);
321 eo_do(entry, eo_event_callback_add(ELM_ENTRY_EVENT_CHANGED_USER,
322 _on_changed, obj));
323 eo_do(entry, eo_event_callback_add(ELM_ENTRY_EVENT_ABORTED,
324 _on_aborted, obj));
325 evas_object_show(entry);
326
327 snprintf(buf, sizeof(buf), "combobox_vertical/%s", elm_widget_style_get(obj));
328 elm_object_style_set(sd->hover, buf);
329 evas_object_smart_callback_add(sd->hover, "clicked", _on_hover_clicked, obj);
330 elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get
331 (sd->hover, ELM_HOVER_AXIS_VERTICAL), sd->tbl);
332 eo_do(obj,
333 eo_composite_attach(gl),
334 eo_composite_attach(entry));
335
336 elm_object_part_content_set(obj, "elm.swallow.content", entry);
337 return obj;
338}
339
340EOLIAN static void
341_elm_combobox_hover_begin(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
342{
343 if (!sd->hover) return;
344 elm_object_focus_set(sd->entry, EINA_TRUE);
345 elm_genlist_filter_set(sd->genlist, (void *)elm_object_text_get(sd->entry));
346}
347
348EOLIAN static void
349_elm_combobox_hover_end(Eo *obj, Elm_Combobox_Data *sd)
350{
351 if (!sd->hover) return;
352
353 sd->expanded = EINA_FALSE;
354 evas_object_hide(sd->hover);
355 eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_DISMISSED, NULL));
356}
357
358EOLIAN static Eina_Bool
359_elm_combobox_expanded_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
360{
361 return sd->expanded;
362}
363
364static Eina_Bool
365_key_action_move(Evas_Object *obj, const char *params)
366{
367 ELM_COMBOBOX_DATA_GET(obj, sd);
368 Elm_Object_Item *it = NULL;
369 const char *dir = params;
370 if (!sd->hover) return EINA_FALSE;
371
372 if (!strcmp(dir, "return"))
373 eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_CLICKED, NULL));
374 else if (!strcmp(dir, "up"))
375 {
376 it = sd->item;
377 it = elm_genlist_item_prev_get(it);
378 if (!it) sd->item = elm_genlist_last_item_get(sd->genlist);
379 else sd->item = it;
380 elm_genlist_item_selected_set(sd->item, EINA_TRUE);
381 }
382 else if (!strcmp(dir, "down"))
383 {
384 it = sd->item;
385 it = elm_genlist_item_next_get(it);
386 if (!it) sd->item = elm_genlist_first_item_get(sd->genlist);
387 else sd->item = it;
388 elm_genlist_item_selected_set(sd->item, EINA_TRUE);
389 }
390 else return EINA_FALSE;
391 return EINA_TRUE;
392}
393
394static Eina_Bool
395_key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
396{
397 elm_combobox_hover_begin(obj);
398 return EINA_TRUE;
399}
400
401EOLIAN static Eina_Bool
402_elm_combobox_elm_widget_event(Eo *obj, Elm_Combobox_Data *sd,
403 Evas_Object *src EINA_UNUSED,
404 Evas_Callback_Type type, void *event_info)
405{
406 Evas_Event_Key_Down *ev = event_info;
407 if (!sd || !sd->hover) return EINA_FALSE;
408 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
409 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
410 if (!_elm_config_key_binding_call(obj, MY_CLASS_NAME, ev, key_actions))
411 return EINA_FALSE;
412
413 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
414 return EINA_TRUE;
415}
416
417static void
418_elm_combobox_class_constructor(Eo_Class *klass)
419{
420 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
421}
422
423EOLIAN const Elm_Atspi_Action *
424_elm_combobox_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED,
425 Elm_Combobox_Data *pd
426 EINA_UNUSED)
427{
428 static Elm_Atspi_Action atspi_actions[] = {
429 {"activate", "activate", "return", _key_action_activate},
430 {"move,up", "move", "up", _key_action_move},
431 {"move,down", "move", "down", _key_action_move},
432 {NULL, NULL, NULL, NULL}
433 };
434 return &atspi_actions[0];
435}
436
437EOLIAN void
438_elm_combobox_elm_widget_part_text_set(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd,
439 const char * part, const char *label)
440{
441 elm_object_part_text_set(pd->entry, part, label);
442}
443
444EOLIAN const char *
445_elm_combobox_elm_widget_part_text_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd,
446 const char * part)
447{
448 return elm_object_part_text_get(pd->entry, part);
449}
450
451EOLIAN static void
452_elm_combobox_evas_object_smart_resize(Eo *obj, Elm_Combobox_Data *pd,
453 Evas_Coord w, Evas_Coord h)
454{
455 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
456 if (pd->count > 0) _table_resize(obj);
457}
458#include "elm_combobox.eo.c"
diff --git a/src/lib/elc_combobox.h b/src/lib/elc_combobox.h
new file mode 100644
index 000000000..80e1ae42f
--- /dev/null
+++ b/src/lib/elc_combobox.h
@@ -0,0 +1,64 @@
1/**
2 * @defgroup Combobox Combobox
3 * @ingroup Elementary
4 *
5 * @image html combobox_inheritance_tree.png
6 * @image latex combobox_inheritance_tree.eps
7 *
8 * @image html img/widget/combobox/preview-00.png
9 * @image latex img/widget/combobox/preview-00.eps
10 *
11 * A combobox is a button displaying an entry that pops up a list of items
12 * (automatically choosing the direction to display). It is a convenience
13 * widget to avoid the need to do all the piecing together yourself. It is
14 * intended for manipulating a large number of items in the combobox menu.
15 *
16 * This widget inherits from the @ref Button, @ref Genlist and @ref Entry
17 * one, so that all the functions acting on it also work for combobox objects.
18 *
19 * This widget emits the following signals, besides the ones sent from
20 * @ref Button:
21 * - @c "clicked" - the user clicked the combobox button and popped up
22 * the sel
23 * - @c "selected" - an item in the combobox list is selected. event_info
24 * is the selected item
25 * - @c "dismissed" - the hover is dismissed
26 * - @c "expanded" - This is called on clicking combobox and elm_combobox_hover_begin().
27 * - @c "language,changed" - the program's language changed (since 1.9)
28 * - @c "item,focused" - When the combobox item has received focus. (since 1.10)
29 * - @c "item,unfocused" - When the combobox item has lost focus. (since 1.10)
30 *
31 * Default content parts of the combobox widget that you can use for are:
32 * @li "icon" - An icon of the combobox
33 *
34 * Default text parts of the combobox widget that you can use for are:
35 * @li "default" - A label of the combobox
36 *
37 * Supported elm_object common APIs.
38 * @li @ref elm_object_disabled_set
39 * @li @ref elm_object_disabled_get
40 * @li @ref elm_object_part_text_set
41 * @li @ref elm_object_part_text_get
42 * @li @ref elm_object_part_content_set
43 * @li @ref elm_object_part_content_unset
44 *
45 * Supported elm_object_item common APIs.
46 * @li elm_object_item_del
47 * @li elm_object_item_part_text_get
48 * @li elm_object_item_signal_emit - this works only when the item is created.
49 * @li elm_object_item_style_set - this works only when the item is created.
50 * @li elm_object_item_style_get - this works only when the item is created.
51 *
52 * See @ref tutorial_combobox for an example.
53 * @{
54 */
55
56#ifdef EFL_EO_API_SUPPORT
57#include "elm_combobox.eo.h"
58#endif
59#ifndef EFL_NOLEGACY_API_SUPPORT
60#include "elc_combobox_legacy.h"
61#endif
62/**
63 * @}
64 */
diff --git a/src/lib/elc_combobox_legacy.h b/src/lib/elc_combobox_legacy.h
new file mode 100644
index 000000000..0719c782b
--- /dev/null
+++ b/src/lib/elc_combobox_legacy.h
@@ -0,0 +1,11 @@
1/**
2 * @brief Add a new Combobox object
3 *
4 * @param parent The parent object
5 * @return The new object or NULL if it cannot be created
6 *
7 * @ingroup Combobox
8 */
9EAPI Evas_Object *elm_combobox_add(Evas_Object *parent);
10
11#include "elm_combobox.eo.legacy.h"
diff --git a/src/lib/elm_authors.h b/src/lib/elm_authors.h
index 71cc0f6c1..f3ff5dbde 100644
--- a/src/lib/elm_authors.h
+++ b/src/lib/elm_authors.h
@@ -163,6 +163,7 @@
163 * @author Subodh Kumar <s7158.kumar@@samsung.com> 163 * @author Subodh Kumar <s7158.kumar@@samsung.com>
164 * @author Kumar Navneet <k.navneet@@samsung.com> 164 * @author Kumar Navneet <k.navneet@@samsung.com>
165 * @author Godly T Alias <godly.talias@@samsung.com> 165 * @author Godly T Alias <godly.talias@@samsung.com>
166 * @author Divyesh Purohit <div.purohit@samsung.com> <purohit.div@gmail.com>
166 * 167 *
167 * Please contact <enlightenment-devel@lists.sourceforge.net> to get in 168 * Please contact <enlightenment-devel@lists.sourceforge.net> to get in
168 * contact with the developers and maintainers. 169 * 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 000000000..96cbb7ee3
--- /dev/null
+++ b/src/lib/elm_combobox.eo
@@ -0,0 +1,54 @@
1class Elm_Combobox (Elm.Button, Evas.Selectable_Interface,
2 Elm_Interface_Atspi_Widget_Action,
3 Elm.Entry, Elm.Genlist, Elm.Hover)
4{
5 eo_prefix: elm_obj_combobox;
6 methods {
7 @property expanded {
8 get {
9 [[Returns whether the combobox is expanded.
10
11 This will return EINA_TRUE if the combobox is expanded or
12 EINA_FALSE if it is not expanded.
13 ]]
14 return: bool;
15 }
16 }
17 hover_begin {
18 [[This triggers the combobox popup from code, the same as if the user
19 had clicked the button.
20 ]]
21 }
22 hover_end {
23 [[This dismisses the combobox popup as if the user had clicked
24 outside the hover.
25 ]]
26 }
27 }
28 implements {
29 class.constructor;
30 Eo.Base.constructor;
31 Evas.Object_Smart.hide;
32 Evas.Object_Smart.show;
33 Evas.Object_Smart.add;
34 Evas.Object_Smart.del;
35 Evas.Object_Smart.resize;
36 Elm.Widget.part_text.set;
37 Elm.Widget.part_text.get;
38 Elm.Widget.theme_apply;
39 Elm.Widget.translate;
40 Elm.Widget.event;
41 Elm.Button.admits_autorepeat.get;
42 Elm_Interface_Atspi_Widget_Action.elm_actions.get;
43 }
44 events {
45 selected;
46 dismissed;
47 expanded;
48 clicked;
49 item,pressed;
50 filter,done;
51 language,changed;
52 access,changed;
53 }
54}
diff --git a/src/lib/elm_config.c b/src/lib/elm_config.c
index 3496c6cf5..88595dc2b 100644
--- a/src/lib/elm_config.c
+++ b/src/lib/elm_config.c
@@ -1848,6 +1848,33 @@ _config_update(void)
1848 _elm_config->cursor_engine_only = 0; 1848 _elm_config->cursor_engine_only = 0;
1849 IFCFGEND 1849 IFCFGEND
1850 1850
1851 IFCFG(0x0007)
1852 Elm_Config_Bindings_Widget *wb, *twb = NULL;
1853 Eina_List *l;
1854
1855 EINA_LIST_FOREACH(tcfg->bindings, l, wb)
1856 {
1857 if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
1858 {
1859 twb = wb;
1860 break;
1861 }
1862 }
1863 if (twb)
1864 {
1865 EINA_LIST_FOREACH(_elm_config->bindings, l, wb)
1866 {
1867 if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
1868 {
1869 // simply swap bindngs for Elm_Combobox with system ones
1870 Eina_List *tmp = wb->key_bindings;
1871 wb->key_bindings = twb->key_bindings;
1872 twb->key_bindings = tmp;
1873 break;
1874 }
1875 }
1876 }
1877 IFCFGEND
1851 /** 1878 /**
1852 * Fix user config for current ELM_CONFIG_EPOCH here. 1879 * Fix user config for current ELM_CONFIG_EPOCH here.
1853 **/ 1880 **/
diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h
index 0c83e739d..f0dfd01da 100644
--- a/src/lib/elm_priv.h
+++ b/src/lib/elm_priv.h
@@ -134,7 +134,7 @@ struct _Elm_Theme
134 * the users config doesn't need to be wiped - simply new values need 134 * the users config doesn't need to be wiped - simply new values need
135 * to be put in 135 * to be put in
136 */ 136 */
137#define ELM_CONFIG_FILE_GENERATION 0x0006 137#define ELM_CONFIG_FILE_GENERATION 0x0007
138#define ELM_CONFIG_VERSION_EPOCH_OFFSET 16 138#define ELM_CONFIG_VERSION_EPOCH_OFFSET 16
139#define ELM_CONFIG_VERSION ((ELM_CONFIG_EPOCH << ELM_CONFIG_VERSION_EPOCH_OFFSET) | \ 139#define ELM_CONFIG_VERSION ((ELM_CONFIG_EPOCH << ELM_CONFIG_VERSION_EPOCH_OFFSET) | \
140 ELM_CONFIG_FILE_GENERATION) 140 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 000000000..80ffe25c7
--- /dev/null
+++ b/src/lib/elm_widget_combobox.h
@@ -0,0 +1,80 @@
1#ifndef ELM_WIDGET_COMBOBOX_H
2#define ELM_WIDGET_COMBOBOX_H
3
4#include "Elementary.h"
5
6/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
7 * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
8 * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
9 * IT AT RUNTIME.
10 */
11
12/**
13 * @addtogroup Widget
14 * @{
15 *
16 * @section elm-combobox-class The Elementary Combobox Class
17 *
18 * Elementary, besides having the @ref Combobox widget, exposes its
19 * foundation -- the Elementary Combobox Class -- in order to create other
20 * widgets which are a combobox with some more logic on top.
21 */
22
23/**
24 * Base button smart data extended with combobox instance data.
25 */
26typedef struct _Elm_Combobox_Data Elm_Combobox_Data;
27struct _Elm_Combobox_Data
28{
29 /* aggregates a hover */
30 Evas_Object *hover;
31 Evas_Object *hover_parent;
32 Evas_Object *genlist;
33 Evas_Object *entry;
34 Evas_Object *tbl;
35 Evas_Object *spacer;
36 Elm_Object_Item *item;
37 const char *style;
38 int count;
39 int item_height;
40 Eina_Bool expanded:1;
41};
42
43/**
44 * @}
45 */
46
47#define ELM_COMBOBOX_DATA_GET(o, sd) \
48 Elm_Combobox_Data * sd = eo_data_scope_get(o, ELM_COMBOBOX_CLASS)
49
50#define ELM_COMBOBOX_DATA_GET_OR_RETURN(o, ptr) \
51 ELM_COMBOBOX_DATA_GET(o, ptr); \
52 if (EINA_UNLIKELY(!ptr)) \
53 { \
54 CRI("No widget data for object %p (%s)", \
55 o, evas_object_type_get(o)); \
56 return; \
57 }
58
59#define ELM_COMBOBOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
60 ELM_COMBOBOX_DATA_GET(o, ptr); \
61 if (EINA_UNLIKELY(!ptr)) \
62 { \
63 CRI("No widget data for object %p (%s)", \
64 o, evas_object_type_get(o)); \
65 return val; \
66 }
67
68#define ELM_COMBOBOX_CHECK(obj) \
69 if (EINA_UNLIKELY(!eo_isa((obj), ELM_COMBOBOX_CLASS))) \
70 return
71
72#define ELM_COMBOBOX_ITEM_CHECK(it) \
73 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \
74 ELM_COMBOBOX_CHECK(it->base.widget);
75
76#define ELM_COMBOBOX_ITEM_CHECK_OR_RETURN(it, ...) \
77 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
78 ELM_COMBOBOX_CHECK(it->base.widget) __VA_ARGS__;
79
80#endif