diff --git a/legacy/elementary/data/objects/Makefile.am b/legacy/elementary/data/objects/Makefile.am index f8f37784c5..86593ca8a8 100644 --- a/legacy/elementary/data/objects/Makefile.am +++ b/legacy/elementary/data/objects/Makefile.am @@ -7,7 +7,7 @@ EDJE_CC_FLAGS += -id $(top_srcdir)/data/objects -fd $(top_srcdir)/data/objects filesdir = $(datadir)/elementary/objects -files_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 +files_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 EXTRA_DIST = \ test.edc \ @@ -16,6 +16,7 @@ test_prefs.edc \ test_prefs.epc \ multip.edc \ cursors.edc \ +combobox_multiple.edc \ font_preview.edc \ postit_ent.edc \ multibuttonentry.edc \ @@ -57,6 +58,11 @@ cursors.edj: Makefile $(EXTRA_DIST) $(top_srcdir)/data/objects/cursors.edc \ $(top_builddir)/data/objects/cursors.edj +combobox_multiple.edj: Makefile combobox_multiple.edc + $(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) \ + $(top_srcdir)/data/objects/combobox_multiple.edc \ + $(top_builddir)/data/objects/combobox_multiple.edj + font_preview.edj: Makefile $(EXTRA_DIST) $(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) \ $(top_srcdir)/data/objects/font_preview.edc \ diff --git a/legacy/elementary/data/objects/combobox_multiple.edc b/legacy/elementary/data/objects/combobox_multiple.edc new file mode 100644 index 0000000000..96543833ed --- /dev/null +++ b/legacy/elementary/data/objects/combobox_multiple.edc @@ -0,0 +1,61 @@ +collections { +group { + name: "combobox_multiple_test"; + parts{ + part { + name: "bg"; + type: RECT; + mouse_events: 1; + scale:1; + description { + state: "default" 0.0; + color: 0 0 0 0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + } + } + part{ + name: "top.left"; + type: RECT; + scale: 1; + description { + state: "default" 0.0; + min : 0 0; + fixed: 1 1; + rel1 { relative: 0.0 0.0; to: bg; } + rel2 { relative: 0.0 0.0; to: bg; } + align: 0.0 0.0; + color: 0 0 0 0; + } + } + part{ + name: "bottom.right"; + type: RECT; + scale: 1; + description { + state: "default" 0.0; + min : 0 0; + fixed: 1 1; + rel1 { relative: 1.0 1.0; to: bg; } + rel2 { relative: 1.0 1.0; to: bg; } + align: 1.0 1.0; + color: 0 0 0 0; + } + } + part { + name: "combobox"; + type: SWALLOW; + mouse_events: 1; + scale:1; + description { + state: "default" 0.0; + min : 0 0; + max : -1 300; + rel1 { relative: 0.0 1.0; to: top.left; } + rel2 { relative: 0.0 0.0; to: bottom.right; } + align: 0.0 0.0; + } + } + } +} +} diff --git a/legacy/elementary/src/bin/test.c b/legacy/elementary/src/bin/test.c index a3ae31d1b5..3bad1c6d2c 100644 --- a/legacy/elementary/src/bin/test.c +++ b/legacy/elementary/src/bin/test.c @@ -46,6 +46,7 @@ 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_combobox2(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); @@ -755,6 +756,7 @@ add_tests: 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, "Selectors", "Combobox Multiple Selection", test_combobox2); //------------------------------// ADD_TEST(NULL, "Cursors", "Cursor", test_cursor); diff --git a/legacy/elementary/src/bin/test_combobox.c b/legacy/elementary/src/bin/test_combobox.c index 720e3c6b23..baa6962cc3 100644 --- a/legacy/elementary/src/bin/test_combobox.c +++ b/legacy/elementary/src/bin/test_combobox.c @@ -52,6 +52,14 @@ gl_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUS return strdup(buf); } +static char * +gl2_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED) +{ + char buf[256]; + snprintf(buf, sizeof(buf), "%s", (char*)data); + return strdup(buf); +} + static Evas_Object *gl_content_get(void *data EINA_UNUSED, Evas_Object *obj, const char *part) { @@ -76,9 +84,9 @@ static Eina_Bool gl_state_get(void *data EINA_UNUSED, static Eina_Bool gl_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key) { + char buf[256]; // 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; @@ -94,6 +102,27 @@ _gl_filter_restart_cb(void *data EINA_UNUSED, elm_genlist_filter_set(obj, (void *)elm_object_text_get(obj)); } +static void +_gl2_filter_restart_cb(void *data EINA_UNUSED, + Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + elm_genlist_filter_set(obj, (void *)elm_object_text_get(elm_multibuttonentry_entry_get(obj))); +} + +static Eina_Bool +gl2_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key) +{ + char buf[256]; + // if the key is empty/NULL, return true for item + if (!strlen((char *)key)) return EINA_TRUE; + snprintf(buf, sizeof(buf), "%s", (char*)data); + if (!strncmp(buf, (char *)key, strlen((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, @@ -176,3 +205,74 @@ test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, evas_object_resize(win, 320, 500); evas_object_show(win); } + +static void +_combobox2_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); + if (elm_combobox_multiple_selection_get(obj)) + elm_multibuttonentry_item_append(obj, txt, NULL, NULL); + else + elm_object_text_set(obj, txt); + elm_combobox_hover_end(obj); +} +// Combobox with multiple selection +void +test_combobox2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *win, *combobox, *ly; + Elm_Genlist_Item_Class *itc; + char buf[128]; + 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"}; + win = elm_win_util_standard_add("combobox", "Combobox"); + elm_win_autodel_set(win, EINA_TRUE); + + ly = elm_layout_add(win); + snprintf(buf, sizeof(buf), "%s/objects/combobox_multiple.edj", elm_app_data_dir_get()); + elm_layout_file_set(ly, buf, "combobox_multiple_test"); + evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, ly); + evas_object_show(ly); + + itc = elm_genlist_item_class_new(); + itc->item_style = "default"; + itc->func.text_get = gl2_text_get; + itc->func.content_get = gl_content_get; + itc->func.state_get = gl_state_get; + itc->func.filter_get = gl2_filter_get; + itc->func.del = NULL; + + combobox = elm_combobox_add(win); + evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(combobox, "To:"); + elm_object_part_text_set(combobox, "guide", "Tap to add recipient"); + elm_combobox_multiple_selection_set(combobox, EINA_TRUE); + for (int i = 0; i < 300; i++) + elm_genlist_item_append(combobox, itc, (void *)email_address[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, "item,selected", + _combobox_item_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", + _combobox2_item_pressed_cb, NULL); + evas_object_smart_callback_add(combobox, "filter,done", + _gl_filter_finished_cb, NULL); + evas_object_smart_callback_add(combobox, "changed", + _gl2_filter_restart_cb, NULL); + elm_object_part_content_set(ly, "combobox", combobox); + evas_object_show(combobox); + + evas_object_resize(win, 640, 600); + evas_object_show(win); +} diff --git a/legacy/elementary/src/lib/elc_combobox.c b/legacy/elementary/src/lib/elc_combobox.c index 8f2b14110f..9719c13db1 100644 --- a/legacy/elementary/src/lib/elc_combobox.c +++ b/legacy/elementary/src/lib/elc_combobox.c @@ -150,7 +150,8 @@ _table_resize(void *data) 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(elm_object_part_content_get(data, "elm.swallow.content"), + 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); @@ -197,7 +198,13 @@ 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); + + if (!sd->multiple_selection) elm_object_focus_set(sd->entry, EINA_TRUE); + else + { + elm_genlist_item_bring_in(sd->item, ELM_GENLIST_ITEM_SCROLLTO_TOP); + elm_object_focus_set(sd->mbe, EINA_TRUE); + } eo_event_callback_call(data, ELM_COMBOBOX_EVENT_ITEM_SELECTED, event); } @@ -305,6 +312,107 @@ _elm_combobox_elm_button_admits_autorepeat_get(Eo *obj EINA_UNUSED, return EINA_FALSE; } +EOLIAN static Eina_Bool +_elm_combobox_multiple_selection_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd) +{ + return pd->multiple_selection; +} + +static Eina_Bool +_mbe_clicked_cb(void *data EINA_UNUSED, Eo *obj, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + //Unset the multibuttonentry to contracted mode of single line + elm_multibuttonentry_expanded_set(obj, EINA_TRUE); + return EINA_TRUE; +} + +static Eina_Bool +_mbe_focused_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + return EINA_TRUE; +} + +static Eina_Bool +_mbe_unfocused_cb(void *data EINA_UNUSED, Eo *obj, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + //Set the multibuttonentry to contracted mode of single line + elm_multibuttonentry_expanded_set(obj, EINA_FALSE); + return EINA_TRUE; +} + +static Eina_Bool +_mbe_item_added(void *data, Eo *obj EINA_UNUSED, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + ELM_COMBOBOX_DATA_GET(data, sd); + elm_genlist_filter_set(sd->genlist, NULL); + return EINA_TRUE; +} + +EO_CALLBACKS_ARRAY_DEFINE(mbe_callbacks, + { EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED, _mbe_clicked_cb }, + { ELM_WIDGET_EVENT_FOCUSED, _mbe_focused_cb }, + { ELM_WIDGET_EVENT_UNFOCUSED, _mbe_unfocused_cb }, + { ELM_MULTIBUTTONENTRY_EVENT_ITEM_ADDED , _mbe_item_added }); + +EO_CALLBACKS_ARRAY_DEFINE(entry_callbacks, + { ELM_ENTRY_EVENT_CHANGED_USER, _on_changed }, + { ELM_ENTRY_EVENT_ABORTED, _on_aborted }); + +EOLIAN static void +_elm_combobox_multiple_selection_set(Eo *obj, Elm_Combobox_Data *pd, + Eina_Bool enabled) +{ + Evas_Object* scr; + + pd->multiple_selection = enabled; + + if (enabled) + { + // This is multibuttonentry object that will take over the MBE call + eo_add(&pd->mbe,ELM_MULTIBUTTONENTRY_CLASS, obj); + evas_object_size_hint_weight_set(pd->mbe, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(pd->mbe, EVAS_HINT_FILL, EVAS_HINT_FILL); + eo_event_callback_array_add(elm_multibuttonentry_entry_get(pd->mbe), entry_callbacks(), obj); + eo_event_callback_array_add(pd->mbe, mbe_callbacks(), obj); + + pd->entry = elm_object_part_content_unset(obj, "elm.swallow.content"); + elm_object_text_set(pd->mbe, elm_object_part_text_get(pd->entry, NULL)); + elm_object_part_text_set(pd->mbe, "guide", elm_object_part_text_get(pd->entry, + "guide")); + evas_object_hide(pd->entry); + eo_composite_attach(obj, pd->mbe); + + scr = elm_scroller_add(obj); + elm_scroller_bounce_set(scr, EINA_FALSE, EINA_TRUE); + elm_scroller_policy_set(scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); + evas_object_size_hint_weight_set(scr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(scr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(scr); + elm_object_content_set(scr, pd->mbe); + elm_object_part_content_set(obj, "elm.swallow.content", scr); + elm_widget_can_focus_set(pd->genlist, EINA_FALSE); + } + else + { + scr = elm_object_part_content_unset(obj, "elm.swallow.content"); + elm_object_part_content_set(obj, "elm.swallow.content", pd->entry); + elm_object_text_set(pd->entry, elm_object_part_text_get(pd->mbe, NULL)); + elm_object_part_text_set(pd->entry, "guide", + elm_object_part_text_get(pd->mbe, "guide")); + elm_widget_can_focus_set(pd->genlist, EINA_TRUE); + elm_genlist_item_bring_in(pd->item, ELM_GENLIST_ITEM_SCROLLTO_NONE); + evas_object_hide(scr); + } +} + EAPI Evas_Object * elm_combobox_add(Evas_Object *parent) { @@ -336,7 +444,6 @@ _elm_combobox_eo_base_constructor(Eo *obj, Elm_Combobox_Data *sd) eo_add(&sd->hover, ELM_HOVER_CLASS, sd->hover_parent); elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE); elm_hover_target_set(sd->hover, obj); - elm_widget_sub_object_add(obj, sd->hover); snprintf(buf, sizeof(buf), "combobox_vertical/%s", elm_widget_style_get(obj)); elm_object_style_set(sd->hover, buf); @@ -382,8 +489,7 @@ _elm_combobox_eo_base_constructor(Eo *obj, Elm_Combobox_Data *sd) ELM_SCROLLER_POLICY_OFF); elm_entry_scrollable_set(entry, EINA_TRUE); elm_entry_single_line_set(entry, EINA_TRUE); - eo_event_callback_add(entry, ELM_ENTRY_EVENT_CHANGED_USER, _on_changed, obj); - eo_event_callback_add(entry, ELM_ENTRY_EVENT_ABORTED, _on_aborted, obj); + eo_event_callback_array_add(entry, entry_callbacks(), obj); evas_object_show(entry); eo_composite_attach(obj, gl); @@ -397,7 +503,11 @@ EOLIAN static void _elm_combobox_hover_begin(Eo *obj, Elm_Combobox_Data *sd) { if (!sd->hover) return; - elm_object_focus_set(sd->entry, EINA_TRUE); + + if (sd->multiple_selection) + elm_object_focus_set(sd->mbe, EINA_TRUE); + else elm_object_focus_set(sd->entry, EINA_TRUE); + _activate(obj); } @@ -514,13 +624,15 @@ 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); + if (pd->multiple_selection) elm_object_part_text_set(pd->mbe, part, label); + else 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) { + if (pd->multiple_selection) return elm_object_part_text_get(pd->mbe, part); return elm_object_part_text_get(pd->entry, part); } diff --git a/legacy/elementary/src/lib/elm_combobox.eo b/legacy/elementary/src/lib/elm_combobox.eo index 598a462b2c..4e711d41d9 100644 --- a/legacy/elementary/src/lib/elm_combobox.eo +++ b/legacy/elementary/src/lib/elm_combobox.eo @@ -1,6 +1,6 @@ class Elm.Combobox (Elm.Button, Evas.Selectable_Interface, Elm.Interface_Atspi_Widget_Action, - Elm.Entry, Elm.Genlist, Elm.Hover) + Elm.Entry, Elm.Genlist, Elm.Hover, Elm.Multibuttonentry) { eo_prefix: elm_obj_combobox; methods { @@ -16,6 +16,25 @@ class Elm.Combobox (Elm.Button, Evas.Selectable_Interface, return: bool; } } + @property multiple_selection { + get { + [[Returns whether the combobox allows multiple selection. + @since 1.18 + ]] + } + set { + [[Enables or disables multiple selection in combobox. + + Warning: This API should be set before any other API on + combobox, if you wish to avoid complications. + @since 1.18 + ]] + } + values { + enabled: bool; [[$true if multiple selection is enabled, + $false otherwise.]] + } + } hover_begin { [[This triggers the combobox popup from code, the same as if the user had clicked the button. diff --git a/legacy/elementary/src/lib/elm_widget_combobox.h b/legacy/elementary/src/lib/elm_widget_combobox.h index 205096a4c8..9d578c5997 100644 --- a/legacy/elementary/src/lib/elm_widget_combobox.h +++ b/legacy/elementary/src/lib/elm_widget_combobox.h @@ -33,6 +33,7 @@ struct _Elm_Combobox_Data Evas_Object *entry; Evas_Object *tbl; Evas_Object *spacer; + Evas_Object *mbe; Elm_Object_Item *item; const char *style; const char *best_location; @@ -40,6 +41,7 @@ struct _Elm_Combobox_Data int item_height; Eina_Bool expanded:1; Eina_Bool first_filter:1; + Eina_Bool multiple_selection:1; }; /**