summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordivyesh purohit <div.purohit@samsung.com>2016-03-10 14:24:50 -0800
committerCedric BAIL <cedric@osg.samsung.com>2016-03-10 14:50:59 -0800
commit015db15c626b9b06116fcc8f7ec61bbae3c6cc30 (patch)
tree59e8f97c580a7eb21865e0e613dc88593d6c8940
parent633d2557c8a79ceeb02f6064a47e205093685b2e (diff)
combobox: add Multiple selection feature
Summary: This patch focuses on Combobox widget customization, Multibuttonentry widget is used instead of entry for taking user input. The idea is to make the widget look like {F28112} {F28115} when the multiple_selection is set. To-DO: 1) Need to add scrollable interface to combobox when MBE is used (need some suggestions on it). 2) focus cycle is still buggy as genlist requires focus otherwise selected item will return NULL (sometimes) Signed-off-by: divyesh purohit <div.purohit@samsung.com> @feature Test Plan: Please run combobox multiple selection example from elementart_test. Reviewers: raster, shilpasingh, cedric Subscribers: govi, rajeshps Projects: #elementary Differential Revision: https://phab.enlightenment.org/D3570
-rw-r--r--data/objects/Makefile.am8
-rw-r--r--data/objects/combobox_multiple.edc61
-rw-r--r--src/bin/test.c2
-rw-r--r--src/bin/test_combobox.c102
-rw-r--r--src/lib/elc_combobox.c126
-rw-r--r--src/lib/elm_combobox.eo21
-rw-r--r--src/lib/elm_widget_combobox.h2
7 files changed, 312 insertions, 10 deletions
diff --git a/data/objects/Makefile.am b/data/objects/Makefile.am
index f8f37784c..86593ca8a 100644
--- a/data/objects/Makefile.am
+++ b/data/objects/Makefile.am
@@ -7,7 +7,7 @@ EDJE_CC_FLAGS += -id $(top_srcdir)/data/objects -fd $(top_srcdir)/data/objects
7 7
8filesdir = $(datadir)/elementary/objects 8filesdir = $(datadir)/elementary/objects
9 9
10files_DATA = test.edj test_external.edj multip.edj cursors.edj font_preview.edj postit_ent.edj multibuttonentry.edj test_prefs.edj test_prefs.epb test_focus_style.edj 10files_DATA = test.edj test_external.edj multip.edj cursors.edj combobox_multiple.edj font_preview.edj postit_ent.edj multibuttonentry.edj test_prefs.edj test_prefs.epb test_focus_style.edj
11 11
12EXTRA_DIST = \ 12EXTRA_DIST = \
13test.edc \ 13test.edc \
@@ -16,6 +16,7 @@ test_prefs.edc \
16test_prefs.epc \ 16test_prefs.epc \
17multip.edc \ 17multip.edc \
18cursors.edc \ 18cursors.edc \
19combobox_multiple.edc \
19font_preview.edc \ 20font_preview.edc \
20postit_ent.edc \ 21postit_ent.edc \
21multibuttonentry.edc \ 22multibuttonentry.edc \
@@ -57,6 +58,11 @@ cursors.edj: Makefile $(EXTRA_DIST)
57 $(top_srcdir)/data/objects/cursors.edc \ 58 $(top_srcdir)/data/objects/cursors.edc \
58 $(top_builddir)/data/objects/cursors.edj 59 $(top_builddir)/data/objects/cursors.edj
59 60
61combobox_multiple.edj: Makefile combobox_multiple.edc
62 $(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) \
63 $(top_srcdir)/data/objects/combobox_multiple.edc \
64 $(top_builddir)/data/objects/combobox_multiple.edj
65
60font_preview.edj: Makefile $(EXTRA_DIST) 66font_preview.edj: Makefile $(EXTRA_DIST)
61 $(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) \ 67 $(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) \
62 $(top_srcdir)/data/objects/font_preview.edc \ 68 $(top_srcdir)/data/objects/font_preview.edc \
diff --git a/data/objects/combobox_multiple.edc b/data/objects/combobox_multiple.edc
new file mode 100644
index 000000000..96543833e
--- /dev/null
+++ b/data/objects/combobox_multiple.edc
@@ -0,0 +1,61 @@
1collections {
2group {
3 name: "combobox_multiple_test";
4 parts{
5 part {
6 name: "bg";
7 type: RECT;
8 mouse_events: 1;
9 scale:1;
10 description {
11 state: "default" 0.0;
12 color: 0 0 0 0;
13 rel1.relative: 0.0 0.0;
14 rel2.relative: 1.0 1.0;
15 }
16 }
17 part{
18 name: "top.left";
19 type: RECT;
20 scale: 1;
21 description {
22 state: "default" 0.0;
23 min : 0 0;
24 fixed: 1 1;
25 rel1 { relative: 0.0 0.0; to: bg; }
26 rel2 { relative: 0.0 0.0; to: bg; }
27 align: 0.0 0.0;
28 color: 0 0 0 0;
29 }
30 }
31 part{
32 name: "bottom.right";
33 type: RECT;
34 scale: 1;
35 description {
36 state: "default" 0.0;
37 min : 0 0;
38 fixed: 1 1;
39 rel1 { relative: 1.0 1.0; to: bg; }
40 rel2 { relative: 1.0 1.0; to: bg; }
41 align: 1.0 1.0;
42 color: 0 0 0 0;
43 }
44 }
45 part {
46 name: "combobox";
47 type: SWALLOW;
48 mouse_events: 1;
49 scale:1;
50 description {
51 state: "default" 0.0;
52 min : 0 0;
53 max : -1 300;
54 rel1 { relative: 0.0 1.0; to: top.left; }
55 rel2 { relative: 0.0 0.0; to: bottom.right; }
56 align: 0.0 0.0;
57 }
58 }
59 }
60}
61}
diff --git a/src/bin/test.c b/src/bin/test.c
index a3ae31d1b..3bad1c6d2 100644
--- a/src/bin/test.c
+++ b/src/bin/test.c
@@ -46,6 +46,7 @@ void 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_combobox(void *data, Evas_Object *obj, void *event_info);
49void test_combobox2(void *data, Evas_Object *obj, void *event_info);
49void test_check(void *data, Evas_Object *obj, void *event_info); 50void test_check(void *data, Evas_Object *obj, void *event_info);
50void test_check_toggle(void *data, Evas_Object *obj, void *event_info); 51void test_check_toggle(void *data, Evas_Object *obj, void *event_info);
51void test_radio(void *data, Evas_Object *obj, void *event_info); 52void test_radio(void *data, Evas_Object *obj, void *event_info);
@@ -755,6 +756,7 @@ add_tests:
755 ADD_TEST(NULL, "Selectors", "DaySelector", test_dayselector); 756 ADD_TEST(NULL, "Selectors", "DaySelector", test_dayselector);
756 ADD_TEST(NULL, "Selectors", "Main menu", test_main_menu); 757 ADD_TEST(NULL, "Selectors", "Main menu", test_main_menu);
757 ADD_TEST(NULL, "Selectors", "Combobox", test_combobox); 758 ADD_TEST(NULL, "Selectors", "Combobox", test_combobox);
759 ADD_TEST(NULL, "Selectors", "Combobox Multiple Selection", test_combobox2);
758 760
759 //------------------------------// 761 //------------------------------//
760 ADD_TEST(NULL, "Cursors", "Cursor", test_cursor); 762 ADD_TEST(NULL, "Cursors", "Cursor", test_cursor);
diff --git a/src/bin/test_combobox.c b/src/bin/test_combobox.c
index 720e3c6b2..baa6962cc 100644
--- a/src/bin/test_combobox.c
+++ b/src/bin/test_combobox.c
@@ -52,6 +52,14 @@ gl_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUS
52 return strdup(buf); 52 return strdup(buf);
53} 53}
54 54
55static char *
56gl2_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
57{
58 char buf[256];
59 snprintf(buf, sizeof(buf), "%s", (char*)data);
60 return strdup(buf);
61}
62
55static Evas_Object *gl_content_get(void *data EINA_UNUSED, Evas_Object *obj, 63static Evas_Object *gl_content_get(void *data EINA_UNUSED, Evas_Object *obj,
56 const char *part) 64 const char *part)
57{ 65{
@@ -76,9 +84,9 @@ static Eina_Bool gl_state_get(void *data EINA_UNUSED,
76static Eina_Bool 84static Eina_Bool
77gl_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key) 85gl_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key)
78{ 86{
87 char buf[256];
79 // if the key is empty/NULL, return true for item 88 // if the key is empty/NULL, return true for item
80 if (!strlen((char *)key)) return EINA_TRUE; 89 if (!strlen((char *)key)) return EINA_TRUE;
81 char buf[256];
82 snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data); 90 snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data);
83 if (strcasestr(buf, (char *)key)) 91 if (strcasestr(buf, (char *)key))
84 return EINA_TRUE; 92 return EINA_TRUE;
@@ -95,6 +103,27 @@ _gl_filter_restart_cb(void *data EINA_UNUSED,
95} 103}
96 104
97static void 105static void
106_gl2_filter_restart_cb(void *data EINA_UNUSED,
107 Evas_Object *obj,
108 void *event_info EINA_UNUSED)
109{
110 elm_genlist_filter_set(obj, (void *)elm_object_text_get(elm_multibuttonentry_entry_get(obj)));
111}
112
113static Eina_Bool
114gl2_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key)
115{
116 char buf[256];
117 // if the key is empty/NULL, return true for item
118 if (!strlen((char *)key)) return EINA_TRUE;
119 snprintf(buf, sizeof(buf), "%s", (char*)data);
120 if (!strncmp(buf, (char *)key, strlen((char*)key)))
121 return EINA_TRUE;
122 // Default case should return false (item fails filter hence will be hidden)
123 return EINA_FALSE;
124}
125
126static void
98_gl_filter_finished_cb(void *data EINA_UNUSED, 127_gl_filter_finished_cb(void *data EINA_UNUSED,
99 Evas_Object *obj EINA_UNUSED, 128 Evas_Object *obj EINA_UNUSED,
100 void *event_info EINA_UNUSED) 129 void *event_info EINA_UNUSED)
@@ -176,3 +205,74 @@ test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
176 evas_object_resize(win, 320, 500); 205 evas_object_resize(win, 320, 500);
177 evas_object_show(win); 206 evas_object_show(win);
178} 207}
208
209static void
210_combobox2_item_pressed_cb(void *data EINA_UNUSED, Evas_Object *obj,
211 void *event_info)
212{
213 const char *txt = elm_object_item_text_get(event_info);
214 printf("'item,pressed' callback is called. (selected item : %s)\n", txt);
215 if (elm_combobox_multiple_selection_get(obj))
216 elm_multibuttonentry_item_append(obj, txt, NULL, NULL);
217 else
218 elm_object_text_set(obj, txt);
219 elm_combobox_hover_end(obj);
220}
221// Combobox with multiple selection
222void
223test_combobox2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
224 void *event_info EINA_UNUSED)
225{
226 Evas_Object *win, *combobox, *ly;
227 Elm_Genlist_Item_Class *itc;
228 char buf[128];
229 char* email_address[300] = {"augue.ut.lacus@Suspendisse.com","egestas.Aliquam.nec@Vivamusmolestiedapibus.edu","urna.et@purusNullam.co.uk","elit@Sedid.net","cursus@malesuadafringillaest.net","Lorem@Cras.org","risus@sedhendrerita.co.uk","auctor.nunc.nulla@utsemNulla.com","nunc.nulla@nonenim.org","egestas@egetipsum.co.uk","sed.tortor@tempusmauris.edu","rutrum@gravida.org","nunc@acsemut.com","lobortis.quam@eratvolutpatNulla.net","fames@ullamcorperDuisat.co.uk","pede.et.risus@necurna.edu","semper.cursus.Integer@justo.com","sem.molestie@orciPhasellusdapibus.com","quam.a@tinciduntvehicula.co.uk","ullamcorper.Duis@odioEtiam.com","enim.Sed.nulla@Etiamligulatortor.net","molestie.pharetra.nibh@velfaucibus.com","morbi@neceuismodin.com","egestas.hendrerit.neque@nequetellus.com","Etiam.gravida.molestie@purusDuis.org","metus.vitae@risus.net","tincidunt.tempus.risus@nonummyFusce.co.uk","Curabitur.ut.odio@in.com","rutrum@utnisi.ca","iaculis.nec@ultriciesdignissimlacus.ca","consectetuer.ipsum.nunc@Cumsociisnatoque.ca","non.arcu.Vivamus@ornare.com","arcu.Vestibulum@interdumligula.edu","sem.magna@urnasuscipit.ca","eu.euismod@urnaconvalliserat.net","Maecenas.mi.felis@mattisInteger.ca","magna.Suspendisse@Donecdignissimmagna.ca","cursus.Integer.mollis@fringillaeuismodenim.ca","tellus.eu@molestie.co.uk","metus.In@egestas.co.uk","Cum@nisl.com","Phasellus@atarcu.net","nec.quam.Curabitur@tortorInteger.org","condimentum.Donec@egetodioAliquam.edu","orci.luctus@magnatellus.co.uk","adipiscing@noncursusnon.co.uk","Sed.eget.lacus@Nullam.edu","felis.ullamcorper@ornare.co.uk","Nunc.quis.arcu@Proineget.edu","in@lobortis.co.uk","leo.Vivamus.nibh@seddui.com","eu.tellus.Phasellus@natoque.ca","ultrices.iaculis@Aliquam.net","purus.ac@feugiatLorem.net","tincidunt.neque@ut.net","odio.sagittis.semper@nibhdolornonummy.org","Sed@eunequepellentesque.com","elementum@sempererat.co.uk","Curae.Donec.tincidunt@neque.net","rhoncus@erat.edu","mauris.elit@Donec.ca","metus.vitae.velit@ad.edu","scelerisque.scelerisque@etmalesuadafames.net","velit.in@convallis.co.uk","ridiculus@laoreetlectusquis.org","tincidunt.orci.quis@musDonec.net","tempor@orciconsectetuereuismod.co.uk","Duis.sit@eratSednunc.com","elit.sed.consequat@nuncinterdum.edu","lorem@Pellentesqueultricies.org","ornare.placerat.orci@pretiumnequeMorbi.com","euismod.enim@primisinfaucibus.ca","a.scelerisque.sed@sapienCras.com","Aliquam@Vestibulum.net","nec@at.ca","quis.diam.luctus@atauctor.ca","nec@purusin.org","montes.nascetur.ridiculus@viverraMaecenas.co.uk","elementum@amet.edu","fringilla.cursus.purus@velarcuCurabitur.co.uk","et.rutrum@consectetuerrhoncus.edu","Aenean@maurissapiencursus.com","interdum@vehiculaaliquet.co.uk","orci.quis.lectus@facilisisfacilisis.org","et.netus.et@arcu.net","ipsum.porta.elit@sapienNunc.edu","libero.Morbi@ipsumCurabiturconsequat.ca","libero@sitamet.com","porta@penatibus.org","nec.enim.Nunc@egetmetusIn.edu","Nunc.sollicitudin.commodo@porttitorinterdum.org","Phasellus.at.augue@dolor.org","nec.ante@etlibero.com","diam@gravida.co.uk","laoreet@malesuada.co.uk","in.lobortis@blanditenim.edu","ante@ipsumnon.net","in@odio.org","Quisque.tincidunt@risus.co.uk","lacus.varius@Vestibulum.com","eu.eros.Nam@arcuNunc.org","pellentesque@Vivamuseuismodurna.org","Cum.sociis@eleifendCras.com","neque@vulputate.org","imperdiet.dictum.magna@risus.org","sagittis@enimcondimentum.edu","hendrerit@maurisMorbi.org","suscipit.nonummy@disparturientmontes.org","Vivamus.non.lorem@fermentummetusAenean.net","In.mi@maurisaliquam.com","est@massanonante.org","molestie@a.co.uk","sit@acturpis.org","diam@felisorci.edu","dolor.nonummy.ac@elitsedconsequat.co.uk","justo@Praesentinterdum.co.uk","Quisque.varius@enimMaurisquis.ca","nibh.enim.gravida@ut.ca","arcu.Vivamus@orciquis.co.uk","sociis@Sedeget.net","risus@egetvolutpatornare.com","vel.est.tempor@ipsum.net","ipsum@dolordapibusgravida.edu","sem.egestas@quamelementum.co.uk","ipsum@Duisatlacus.co.uk","facilisis.vitae@acturpisegestas.net","Nam@aliquetlobortis.net","ipsum.dolor.sit@nuncInat.net","gravida.sagittis@et.org","mauris@magnatellus.edu","sed@adipiscingenimmi.org","sed@ipsumportaelit.com","malesuada.vel.convallis@amet.net","Praesent.interdum@dictumeu.co.uk","nunc.In.at@ornare.co.uk","Phasellus.fermentum.convallis@ipsum.net","sed.libero.Proin@Aliquameratvolutpat.org","aliquet.libero@telluslorem.net","lectus.pede.ultrices@Maurisquisturpis.edu","blandit.at.nisi@ut.net","erat@convallisdolor.net","ante.Nunc.mauris@vehiculaetrutrum.ca","vel.quam@egestas.edu","non@justofaucibuslectus.co.uk","sem.ut.dolor@odioNaminterdum.org","et.ipsum@malesuada.net","non@Nulladignissim.com","ullamcorper.nisl@iaculisodio.com","neque.sed@necurna.ca","in.cursus.et@fermentumvelmauris.co.uk","magna.sed@eteuismodet.co.uk","a@Crasvehicula.com","tortor.Nunc.commodo@velmauris.net","dignissim.pharetra@Aeneaneuismodmauris.org","egestas.urna.justo@acorci.org","iaculis.enim.sit@maurisIntegersem.com","malesuada@imperdietnec.com","erat.volutpat.Nulla@ipsum.org","Aliquam@IntegerurnaVivamus.co.uk","Nunc.sollicitudin@ipsumCurabitur.net","nibh.enim@quam.co.uk","pede@quismassa.com","vel.nisl@fringillacursuspurus.co.uk","vel@auctorvelitAliquam.org","auctor.quis.tristique@fringillamilacinia.org","nisl.elementum@amagna.com","facilisis@feugiattelluslorem.co.uk","eleifend.Cras@Vestibulumante.net","Integer.eu.lacus@ipsumCurabiturconsequat.com","Donec.porttitor@Etiamvestibulummassa.ca","montes@auctorquistristique.net","Nunc.ullamcorper.velit@Vivamusnon.co.uk","dictum.cursus@sed.org","Aliquam.erat.volutpat@nonummyut.org","ac.mattis@ligulaNullamenim.net","id.sapien.Cras@Proin.ca","Phasellus.dolor@fermentumfermentum.edu","in@odio.edu","non.luctus@pedeNuncsed.com","per.conubia@euismodacfermentum.com","luctus.aliquet@venenatisvelfaucibus.ca","nulla.Cras@purusaccumsaninterdum.ca","aliquet.vel.vulputate@pedesagittis.edu","rutrum@pedeultrices.co.uk","Nullam.lobortis@hendrerit.ca","nonummy.ac.feugiat@Sedmalesuadaaugue.edu","nibh@ipsum.com","in.faucibus.orci@vehicula.com","odio.vel.est@in.edu","amet.ornare.lectus@Suspendisse.co.uk","Maecenas.malesuada.fringilla@at.co.uk","Aliquam@aceleifendvitae.org","Nullam.feugiat.placerat@massaQuisque.ca","urna@tempor.org","magnis.dis.parturient@arcuCurabitur.edu","erat.vel@In.ca","rutrum@Integervitae.ca","metus.In@odio.co.uk","nec.imperdiet@tellus.ca","dui.semper.et@at.org","sit.amet@quisarcu.org","ante@Donecsollicitudinadipiscing.edu","turpis.egestas.Aliquam@egestasnunc.edu","posuere@quismassaMauris.co.uk","Nulla.dignissim@nibhAliquamornare.com","facilisis.vitae.orci@estmaurisrhoncus.net","vitae.aliquet.nec@nostraper.co.uk","lorem@enimsitamet.co.uk","pellentesque@acipsum.org","pede.et.risus@nonvestibulum.org","sed@Nuncsollicitudin.com","erat@Maurisvestibulum.org","scelerisque@tortorNunc.org","metus@idsapien.org","dignissim@Duis.ca","Duis.at.lacus@egestaslaciniaSed.com","auctor.velit@dapibus.co.uk","Curae.Phasellus.ornare@eudolor.net","arcu@metusfacilisis.ca","laoreet@dictummagna.net","tristique.neque@auctorvitaealiquet.ca","nunc.interdum.feugiat@primisinfaucibus.edu","elit.pede.malesuada@quam.net","semper.et.lacinia@ornareliberoat.ca","magna.Praesent.interdum@elit.net","consequat@loremDonec.ca","Vivamus@nisiMauris.edu","feugiat.tellus@sociisnatoquepenatibus.co.uk","scelerisque.mollis.Phasellus@facilisis.edu","rhoncus.Proin@enimEtiam.com","amet.consectetuer.adipiscing@lacusNullatincidunt.edu","aliquet.lobortis.nisi@leo.com","magna@purus.org","a@etmalesuadafames.com","Nunc.commodo@vulputatenisisem.net","et.rutrum.non@imperdieteratnonummy.com","consectetuer@mauris.net","iaculis.lacus@Proinvelarcu.ca","tincidunt.Donec.vitae@habitant.net","et.ultrices@nequesed.org","Lorem.ipsum@nonante.edu","Vestibulum.ut@sed.co.uk","fermentum.arcu@Duis.com","Morbi.quis.urna@vulputate.org","Sed.eget@liberolacusvarius.net","amet.lorem@tincidunt.co.uk","morbi@Classaptenttaciti.com","nisl.Quisque.fringilla@ut.ca","Aenean.egestas.hendrerit@eleifendnec.co.uk","elit@odio.net","sodales.Mauris.blandit@fermentumfermentumarcu.com","massa.non@Nuncsollicitudin.com","quam@sit.co.uk","consectetuer@quispedePraesent.co.uk","erat.eget@aliquetPhasellusfermentum.ca","libero@convalliserat.net","dui@arcu.ca","Curabitur@ascelerisquesed.org","amet@sed.com","in.aliquet.lobortis@acipsum.net","Donec.non@feugiatnec.com","Suspendisse.dui.Fusce@musProin.com","congue@loremauctor.co.uk","magna@Morbi.com","sit@dolor.edu","Praesent.eu.nulla@parturientmontes.com","eu.dui.Cum@arcuvelquam.org","leo.elementum@aliquet.edu","aliquam@urna.org","congue@nonummy.ca","urna.Nullam@atauctor.ca","natoque.penatibus@id.co.uk","aliquam.arcu@risusQuisque.com","ultrices.iaculis@liberoet.com","mollis.Integer.tincidunt@auctorvelit.org","sit@mus.org","est.mollis@orci.net","gravida@eunullaat.co.uk","varius.ultrices@Intinciduntcongue.org","Duis.cursus@nuncnulla.org","eu.turpis@Cumsociis.com","metus.In@sapiencursusin.org","a.feugiat.tellus@velitjusto.co.uk","nibh.lacinia.orci@mifelis.org","tincidunt.neque.vitae@Sed.ca","convallis.est.vitae@Donec.org","mauris@semelit.co.uk","Nam.interdum@Morbiquis.ca","vel.arcu.Curabitur@ullamcorperDuisat.net","dolor@mauris.com","Suspendisse@ipsum.org","Vivamus@dui.edu","condimentum.eget.volutpat@lobortisultrices.ca","commodo@et.edu","ut.ipsum@MorbimetusVivamus.co.uk","ut@feugiatnecdiam.org","Nam@ultrices.co.uk","orci.Donec@turpis.org","semper.tellus@venenatislacus.com","elit.elit@arcuimperdietullamcorper.edu"};
230 win = elm_win_util_standard_add("combobox", "Combobox");
231 elm_win_autodel_set(win, EINA_TRUE);
232
233 ly = elm_layout_add(win);
234 snprintf(buf, sizeof(buf), "%s/objects/combobox_multiple.edj", elm_app_data_dir_get());
235 elm_layout_file_set(ly, buf, "combobox_multiple_test");
236 evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
237 elm_win_resize_object_add(win, ly);
238 evas_object_show(ly);
239
240 itc = elm_genlist_item_class_new();
241 itc->item_style = "default";
242 itc->func.text_get = gl2_text_get;
243 itc->func.content_get = gl_content_get;
244 itc->func.state_get = gl_state_get;
245 itc->func.filter_get = gl2_filter_get;
246 itc->func.del = NULL;
247
248 combobox = elm_combobox_add(win);
249 evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
250 evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, EVAS_HINT_FILL);
251 elm_object_text_set(combobox, "To:");
252 elm_object_part_text_set(combobox, "guide", "Tap to add recipient");
253 elm_combobox_multiple_selection_set(combobox, EINA_TRUE);
254 for (int i = 0; i < 300; i++)
255 elm_genlist_item_append(combobox, itc, (void *)email_address[i],
256 NULL, ELM_GENLIST_ITEM_NONE, NULL,
257 (void*)(uintptr_t)(i * 10));
258
259 evas_object_smart_callback_add(combobox, "clicked",
260 _combobox_clicked_cb, NULL);
261 evas_object_smart_callback_add(combobox, "item,selected",
262 _combobox_item_selected_cb, NULL);
263 evas_object_smart_callback_add(combobox, "dismissed",
264 _combobox_dismissed_cb, NULL);
265 evas_object_smart_callback_add(combobox, "expanded",
266 _combobox_expanded_cb, NULL);
267 evas_object_smart_callback_add(combobox, "item,pressed",
268 _combobox2_item_pressed_cb, NULL);
269 evas_object_smart_callback_add(combobox, "filter,done",
270 _gl_filter_finished_cb, NULL);
271 evas_object_smart_callback_add(combobox, "changed",
272 _gl2_filter_restart_cb, NULL);
273 elm_object_part_content_set(ly, "combobox", combobox);
274 evas_object_show(combobox);
275
276 evas_object_resize(win, 640, 600);
277 evas_object_show(win);
278}
diff --git a/src/lib/elc_combobox.c b/src/lib/elc_combobox.c
index 8f2b14110..9719c13db 100644
--- a/src/lib/elc_combobox.c
+++ b/src/lib/elc_combobox.c
@@ -150,7 +150,8 @@ _table_resize(void *data)
150 evas_object_geometry_get(elm_object_item_track(sd->item), NULL, NULL, 150 evas_object_geometry_get(elm_object_item_track(sd->item), NULL, NULL,
151 NULL, &h); 151 NULL, &h);
152 if (h) sd->item_height = h; 152 if (h) sd->item_height = h;
153 evas_object_geometry_get(sd->entry, NULL, NULL, &obj_w, NULL); 153 evas_object_geometry_get(elm_object_part_content_get(data, "elm.swallow.content"),
154 NULL, NULL, &obj_w, NULL);
154 evas_object_geometry_get(data, NULL, &obj_y, NULL, &obj_h); 155 evas_object_geometry_get(data, NULL, &obj_y, NULL, &obj_h);
155 evas_object_geometry_get(sd->hover_parent, NULL, NULL, &hover_parent_w, 156 evas_object_geometry_get(sd->hover_parent, NULL, NULL, &hover_parent_w,
156 &hover_parent_h); 157 &hover_parent_h);
@@ -197,7 +198,13 @@ static void
197_on_item_selected(void *data , Evas_Object *obj EINA_UNUSED, void *event) 198_on_item_selected(void *data , Evas_Object *obj EINA_UNUSED, void *event)
198{ 199{
199 ELM_COMBOBOX_DATA_GET(data, sd); 200 ELM_COMBOBOX_DATA_GET(data, sd);
200 elm_object_focus_set(sd->entry, EINA_TRUE); 201
202 if (!sd->multiple_selection) elm_object_focus_set(sd->entry, EINA_TRUE);
203 else
204 {
205 elm_genlist_item_bring_in(sd->item, ELM_GENLIST_ITEM_SCROLLTO_TOP);
206 elm_object_focus_set(sd->mbe, EINA_TRUE);
207 }
201 eo_event_callback_call(data, ELM_COMBOBOX_EVENT_ITEM_SELECTED, event); 208 eo_event_callback_call(data, ELM_COMBOBOX_EVENT_ITEM_SELECTED, event);
202} 209}
203 210
@@ -305,6 +312,107 @@ _elm_combobox_elm_button_admits_autorepeat_get(Eo *obj EINA_UNUSED,
305 return EINA_FALSE; 312 return EINA_FALSE;
306} 313}
307 314
315EOLIAN static Eina_Bool
316_elm_combobox_multiple_selection_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd)
317{
318 return pd->multiple_selection;
319}
320
321static Eina_Bool
322_mbe_clicked_cb(void *data EINA_UNUSED, Eo *obj,
323 const Eo_Event_Description *desc EINA_UNUSED,
324 void *event_info EINA_UNUSED)
325{
326 //Unset the multibuttonentry to contracted mode of single line
327 elm_multibuttonentry_expanded_set(obj, EINA_TRUE);
328 return EINA_TRUE;
329}
330
331static Eina_Bool
332_mbe_focused_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED,
333 const Eo_Event_Description *desc EINA_UNUSED,
334 void *event_info EINA_UNUSED)
335{
336 return EINA_TRUE;
337}
338
339static Eina_Bool
340_mbe_unfocused_cb(void *data EINA_UNUSED, Eo *obj,
341 const Eo_Event_Description *desc EINA_UNUSED,
342 void *event_info EINA_UNUSED)
343{
344 //Set the multibuttonentry to contracted mode of single line
345 elm_multibuttonentry_expanded_set(obj, EINA_FALSE);
346 return EINA_TRUE;
347}
348
349static Eina_Bool
350_mbe_item_added(void *data, Eo *obj EINA_UNUSED,
351 const Eo_Event_Description *desc EINA_UNUSED,
352 void *event_info EINA_UNUSED)
353{
354 ELM_COMBOBOX_DATA_GET(data, sd);
355 elm_genlist_filter_set(sd->genlist, NULL);
356 return EINA_TRUE;
357}
358
359EO_CALLBACKS_ARRAY_DEFINE(mbe_callbacks,
360 { EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED, _mbe_clicked_cb },
361 { ELM_WIDGET_EVENT_FOCUSED, _mbe_focused_cb },
362 { ELM_WIDGET_EVENT_UNFOCUSED, _mbe_unfocused_cb },
363 { ELM_MULTIBUTTONENTRY_EVENT_ITEM_ADDED , _mbe_item_added });
364
365EO_CALLBACKS_ARRAY_DEFINE(entry_callbacks,
366 { ELM_ENTRY_EVENT_CHANGED_USER, _on_changed },
367 { ELM_ENTRY_EVENT_ABORTED, _on_aborted });
368
369EOLIAN static void
370_elm_combobox_multiple_selection_set(Eo *obj, Elm_Combobox_Data *pd,
371 Eina_Bool enabled)
372{
373 Evas_Object* scr;
374
375 pd->multiple_selection = enabled;
376
377 if (enabled)
378 {
379 // This is multibuttonentry object that will take over the MBE call
380 eo_add(&pd->mbe,ELM_MULTIBUTTONENTRY_CLASS, obj);
381 evas_object_size_hint_weight_set(pd->mbe, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
382 evas_object_size_hint_align_set(pd->mbe, EVAS_HINT_FILL, EVAS_HINT_FILL);
383 eo_event_callback_array_add(elm_multibuttonentry_entry_get(pd->mbe), entry_callbacks(), obj);
384 eo_event_callback_array_add(pd->mbe, mbe_callbacks(), obj);
385
386 pd->entry = elm_object_part_content_unset(obj, "elm.swallow.content");
387 elm_object_text_set(pd->mbe, elm_object_part_text_get(pd->entry, NULL));
388 elm_object_part_text_set(pd->mbe, "guide", elm_object_part_text_get(pd->entry,
389 "guide"));
390 evas_object_hide(pd->entry);
391 eo_composite_attach(obj, pd->mbe);
392
393 scr = elm_scroller_add(obj);
394 elm_scroller_bounce_set(scr, EINA_FALSE, EINA_TRUE);
395 elm_scroller_policy_set(scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
396 evas_object_size_hint_weight_set(scr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
397 evas_object_size_hint_align_set(scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
398 evas_object_show(scr);
399 elm_object_content_set(scr, pd->mbe);
400 elm_object_part_content_set(obj, "elm.swallow.content", scr);
401 elm_widget_can_focus_set(pd->genlist, EINA_FALSE);
402 }
403 else
404 {
405 scr = elm_object_part_content_unset(obj, "elm.swallow.content");
406 elm_object_part_content_set(obj, "elm.swallow.content", pd->entry);
407 elm_object_text_set(pd->entry, elm_object_part_text_get(pd->mbe, NULL));
408 elm_object_part_text_set(pd->entry, "guide",
409 elm_object_part_text_get(pd->mbe, "guide"));
410 elm_widget_can_focus_set(pd->genlist, EINA_TRUE);
411 elm_genlist_item_bring_in(pd->item, ELM_GENLIST_ITEM_SCROLLTO_NONE);
412 evas_object_hide(scr);
413 }
414}
415
308EAPI Evas_Object * 416EAPI Evas_Object *
309elm_combobox_add(Evas_Object *parent) 417elm_combobox_add(Evas_Object *parent)
310{ 418{
@@ -336,7 +444,6 @@ _elm_combobox_eo_base_constructor(Eo *obj, Elm_Combobox_Data *sd)
336 eo_add(&sd->hover, ELM_HOVER_CLASS, sd->hover_parent); 444 eo_add(&sd->hover, ELM_HOVER_CLASS, sd->hover_parent);
337 elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE); 445 elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE);
338 elm_hover_target_set(sd->hover, obj); 446 elm_hover_target_set(sd->hover, obj);
339 elm_widget_sub_object_add(obj, sd->hover);
340 snprintf(buf, sizeof(buf), "combobox_vertical/%s", 447 snprintf(buf, sizeof(buf), "combobox_vertical/%s",
341 elm_widget_style_get(obj)); 448 elm_widget_style_get(obj));
342 elm_object_style_set(sd->hover, buf); 449 elm_object_style_set(sd->hover, buf);
@@ -382,8 +489,7 @@ _elm_combobox_eo_base_constructor(Eo *obj, Elm_Combobox_Data *sd)
382 ELM_SCROLLER_POLICY_OFF); 489 ELM_SCROLLER_POLICY_OFF);
383 elm_entry_scrollable_set(entry, EINA_TRUE); 490 elm_entry_scrollable_set(entry, EINA_TRUE);
384 elm_entry_single_line_set(entry, EINA_TRUE); 491 elm_entry_single_line_set(entry, EINA_TRUE);
385 eo_event_callback_add(entry, ELM_ENTRY_EVENT_CHANGED_USER, _on_changed, obj); 492 eo_event_callback_array_add(entry, entry_callbacks(), obj);
386 eo_event_callback_add(entry, ELM_ENTRY_EVENT_ABORTED, _on_aborted, obj);
387 evas_object_show(entry); 493 evas_object_show(entry);
388 494
389 eo_composite_attach(obj, gl); 495 eo_composite_attach(obj, gl);
@@ -397,7 +503,11 @@ EOLIAN static void
397_elm_combobox_hover_begin(Eo *obj, Elm_Combobox_Data *sd) 503_elm_combobox_hover_begin(Eo *obj, Elm_Combobox_Data *sd)
398{ 504{
399 if (!sd->hover) return; 505 if (!sd->hover) return;
400 elm_object_focus_set(sd->entry, EINA_TRUE); 506
507 if (sd->multiple_selection)
508 elm_object_focus_set(sd->mbe, EINA_TRUE);
509 else elm_object_focus_set(sd->entry, EINA_TRUE);
510
401 _activate(obj); 511 _activate(obj);
402} 512}
403 513
@@ -514,13 +624,15 @@ EOLIAN void
514_elm_combobox_elm_widget_part_text_set(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd, 624_elm_combobox_elm_widget_part_text_set(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd,
515 const char * part, const char *label) 625 const char * part, const char *label)
516{ 626{
517 elm_object_part_text_set(pd->entry, part, label); 627 if (pd->multiple_selection) elm_object_part_text_set(pd->mbe, part, label);
628 else elm_object_part_text_set(pd->entry, part, label);
518} 629}
519 630
520EOLIAN const char * 631EOLIAN const char *
521_elm_combobox_elm_widget_part_text_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd, 632_elm_combobox_elm_widget_part_text_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd,
522 const char * part) 633 const char * part)
523{ 634{
635 if (pd->multiple_selection) return elm_object_part_text_get(pd->mbe, part);
524 return elm_object_part_text_get(pd->entry, part); 636 return elm_object_part_text_get(pd->entry, part);
525} 637}
526 638
diff --git a/src/lib/elm_combobox.eo b/src/lib/elm_combobox.eo
index 598a462b2..4e711d41d 100644
--- a/src/lib/elm_combobox.eo
+++ b/src/lib/elm_combobox.eo
@@ -1,6 +1,6 @@
1class Elm.Combobox (Elm.Button, Evas.Selectable_Interface, 1class Elm.Combobox (Elm.Button, Evas.Selectable_Interface,
2 Elm.Interface_Atspi_Widget_Action, 2 Elm.Interface_Atspi_Widget_Action,
3 Elm.Entry, Elm.Genlist, Elm.Hover) 3 Elm.Entry, Elm.Genlist, Elm.Hover, Elm.Multibuttonentry)
4{ 4{
5 eo_prefix: elm_obj_combobox; 5 eo_prefix: elm_obj_combobox;
6 methods { 6 methods {
@@ -16,6 +16,25 @@ class Elm.Combobox (Elm.Button, Evas.Selectable_Interface,
16 return: bool; 16 return: bool;
17 } 17 }
18 } 18 }
19 @property multiple_selection {
20 get {
21 [[Returns whether the combobox allows multiple selection.
22 @since 1.18
23 ]]
24 }
25 set {
26 [[Enables or disables multiple selection in combobox.
27
28 Warning: This API should be set before any other API on
29 combobox, if you wish to avoid complications.
30 @since 1.18
31 ]]
32 }
33 values {
34 enabled: bool; [[$true if multiple selection is enabled,
35 $false otherwise.]]
36 }
37 }
19 hover_begin { 38 hover_begin {
20 [[This triggers the combobox popup from code, the same as if the user 39 [[This triggers the combobox popup from code, the same as if the user
21 had clicked the button. 40 had clicked the button.
diff --git a/src/lib/elm_widget_combobox.h b/src/lib/elm_widget_combobox.h
index 205096a4c..9d578c599 100644
--- a/src/lib/elm_widget_combobox.h
+++ b/src/lib/elm_widget_combobox.h
@@ -33,6 +33,7 @@ struct _Elm_Combobox_Data
33 Evas_Object *entry; 33 Evas_Object *entry;
34 Evas_Object *tbl; 34 Evas_Object *tbl;
35 Evas_Object *spacer; 35 Evas_Object *spacer;
36 Evas_Object *mbe;
36 Elm_Object_Item *item; 37 Elm_Object_Item *item;
37 const char *style; 38 const char *style;
38 const char *best_location; 39 const char *best_location;
@@ -40,6 +41,7 @@ struct _Elm_Combobox_Data
40 int item_height; 41 int item_height;
41 Eina_Bool expanded:1; 42 Eina_Bool expanded:1;
42 Eina_Bool first_filter:1; 43 Eina_Bool first_filter:1;
44 Eina_Bool multiple_selection:1;
43}; 45};
44 46
45/** 47/**