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>
This commit is contained in:
divyesh purohit 2016-01-04 15:22:46 -08:00 committed by Cedric BAIL
parent e6b686b493
commit 4a33cee27f
19 changed files with 1318 additions and 4 deletions

View File

@ -166,3 +166,4 @@ Subodh Kumar <s7158.kumar@samsung.com>
Kumar Navneet <k.navneet@samsung.com>
Godly T Alias <godly.talias@samsung.com> <godlytalias@yahoo.co.in>
Shashank Pandey <shashank.p@samsung.com> <shashank0990@gmail.com>
Divyesh Purohit <div.purohit@samsung.com> <purohit.div@gmail.com>

View File

@ -1,5 +1,5 @@
group "Elm_Config" struct {
value "config_version" int: 131078;
value "config_version" int: 131079;
value "engine" string: "";
value "vsync" uchar: 0;
value "thumbscroll_enable" uchar: 1;
@ -432,6 +432,53 @@ group "Elm_Config" struct {
}
}
}
group "Elm_Config_Bindings_Widget" struct {
value "name" string: "Elm_Combobox";
group "key_bindings" list {
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Return";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Enter";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "space";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Up";
value "action" string: "move";
value "params" string: "up";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Up";
value "action" string: "move";
value "params" string: "up";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Down";
value "action" string: "move";
value "params" string: "down";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Down";
value "action" string: "move";
value "params" string: "down";
}
}
}
group "Elm_Config_Bindings_Widget" struct {
value "name" string: "Elm_Multibuttonentry";
group "key_bindings" list {

View File

@ -1,5 +1,5 @@
group "Elm_Config" struct {
value "config_version" int: 131078;
value "config_version" int: 131079;
value "engine" string: "";
value "vsync" uchar: 0;
value "thumbscroll_enable" uchar: 1;
@ -436,6 +436,53 @@ group "Elm_Config" struct {
}
}
}
group "Elm_Config_Bindings_Widget" struct {
value "name" string: "Elm_Combobox";
group "key_bindings" list {
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Return";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Enter";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "space";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Up";
value "action" string: "move";
value "params" string: "up";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Up";
value "action" string: "move";
value "params" string: "up";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Down";
value "action" string: "move";
value "params" string: "down";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Down";
value "action" string: "move";
value "params" string: "down";
}
}
}
group "Elm_Config_Bindings_Widget" struct {
value "name" string: "Elm_Multibuttonentry";
group "key_bindings" list {

View File

@ -1,5 +1,5 @@
group "Elm_Config" struct {
value "config_version" int: 131078;
value "config_version" int: 131079;
value "engine" string: "";
value "vsync" uchar: 0;
value "thumbscroll_enable" uchar: 0;
@ -433,6 +433,53 @@ group "Elm_Config" struct {
}
}
}
group "Elm_Config_Bindings_Widget" struct {
value "name" string: "Elm_Combobox";
group "key_bindings" list {
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Return";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Enter";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "space";
value "action" string: "activate";
value "params" string: "return";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Up";
value "action" string: "move";
value "params" string: "up";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Up";
value "action" string: "move";
value "params" string: "up";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "Down";
value "action" string: "move";
value "params" string: "down";
}
group "Elm_Config_Binding_Key" struct {
value "context" int: 0;
value "key" string: "KP_Down";
value "action" string: "move";
value "params" string: "down";
}
}
}
group "Elm_Config_Bindings_Widget" struct {
value "name" string: "Elm_Multibuttonentry";
group "key_bindings" list {

View File

@ -1712,3 +1712,302 @@ group { name: "elm/button/base/hoversel_horizontal_entry/default";
}
}
/******************* SPINNER BUTTONS STYLES END **********************/
group { name: "elm/button/base/combobox_vertical/default";
alias: "elm/button/base/combobox_vertical/entry";
alias: "elm/button/base/combobox_horizontal/default";
alias: "elm/button/base/combobox_horizontal/entry";
images.image: "button_normal.png" COMP;
images.image: "button_clicked.png" COMP;
images.image: "vertical_separated_bar_glow.png" COMP;
parts {
image { "base"; nomouse;
desc { "default";
image.normal: "button_normal.png";
image.border: 4 4 3 5;
image.middle: SOLID;
rel1.offset: -1 0;
rel2.offset: 0 1;
fill.smooth: 0;
}
desc { "clicked";
inherit: "default";
image.normal: "button_clicked.png";
image.border: 5 5 4 6;
}
}
rect { "icon_clip";
desc { "default";
}
desc { "disabled";
inherit: "default";
color: 255 255 255 64;
}
}
rect { "event";
desc { "default";
color: 0 0 0 0;
}
desc { "disabled";
inherit: "default";
visible: 0;
}
}
swallow { "elm.swallow.content";
clip_to: "icon_clip";
desc { "default";
fixed: 0 0;
align: 0.5 0.5;
rel1.offset: 6 5;
rel1.to: "base";
rel2.relative: 0.0 1.0;
rel2.offset: -3 -8;
rel2.to: "select_line";
visible: 1;
}
}
image { "select_line"; nomouse;
desc { "default";
fixed: 1 1;
align: 1.0 0.5;
min: 15 10;
rel1.to: "base";
rel1.relative: 1.0 0.0;
rel1.offset: 1 -3;
rel2.to: "base";
rel2.offset: 1 0;
image.normal: "vertical_separated_bar_glow.png";
image.border: 7 7 7 7;
fill.smooth : 0;
}
desc { "clicked";
inherit: "default";
rel1.offset: 0 -2;
rel2.offset: 0 -1;
}
}
}
programs {
program {
signal: "mouse,down,1"; source: "event";
action: SIGNAL_EMIT "elm,action,press" "elm";
after: "button_click_anim";
}
program { name: "button_click_anim";
action: STATE_SET "clicked" 0.0;
target: "base";
target: "select_line";
}
program { name: "button_unclick";
signal: "mouse,up,1"; source: "event";
action: SIGNAL_EMIT "elm,action,unpress" "elm";
after: "button_unclick_anim";
}
program { name: "button_unclick_anim";
action: STATE_SET "default" 0.0;
target: "base";
target: "select_line";
}
program { name: "buttonactivate";
signal: "elm,anim,activate"; source: "elm";
action: STATE_SET "clicked" 0.0;
target: "base";
target: "select_line";
after: "button_unpressed_anim";
}
program { name: "button_unpressed_anim";
action: STATE_SET "default" 0.0;
in: 0.5 0.0;
target: "base";
target: "select_line";
}
program {
signal: "mouse,clicked,1"; source: "event";
action: SIGNAL_EMIT "elm,action,click" "elm";
}
program { name: "button_state_disabled";
signal: "elm,state,disabled"; source: "elm";
action: STATE_SET "disabled" 0.0;
target: "icon_clip";
target: "event";
}
program { name: "button_state_enabled";
signal: "elm,state,enabled"; source: "elm";
action: STATE_SET "default" 0.0;
target: "icon_clip";
target: "event";
}
}
}
group { name: "elm/button/base/combobox_vertical_entry/default";
alias: "elm/button/base/combobox_vertical_entry/entry";
images.image: "vgrad_med_dark.png" COMP;
images.image: "bevel_horiz_out.png" COMP;
images.image: "shadow_rounded_horiz.png" COMP;
images.image: "shine.png" COMP;
parts {
image { "shadow"; nomouse;
desc { "default";
fixed: 1 1;
image.normal: "shadow_rounded_horiz.png";
image.border: 0 0 9 9;
rel1.to: "base";
rel1.offset: 0 -4;
rel2.to: "base";
rel2.offset: -1 5;
fill.smooth: 0;
visible: 0;
}
desc { "clicked";
inherit: "default";
visible: 1;
}
}
image { "base"; nomouse;
desc { "default";
fixed: 1 1;
rel1.offset: -6 0;
image.normal: "vgrad_med_dark.png";
fill.smooth: 0;
TILED_HORIZ(120)
visible: 0;
}
desc { "clicked";
inherit: "default";
visible: 1;
}
}
rect { "icon_clip";
desc { "default";
}
desc { "disabled";
inherit: "default";
color: 255 255 255 64;
}
}
image { "bevel"; nomouse;
desc { "default";
fixed: 1 1;
image.normal: "bevel_horiz_out.png";
image.border: 0 0 2 2;
image.middle: 0;
fill.smooth: 0;
visible: 0;
}
desc { "clicked";
inherit: "default";
visible: 1;
}
}
image { "shine"; nomouse;
desc { "default";
fixed: 1 1;
rel1.to: "base";
rel1.offset: 0 -2;
rel2.to: "base";
rel2.relative: 1.0 0.0;
rel2.offset: -1 2;
image.normal: "shine.png";
visible: 0;
FIXED_SIZE(69, 5)
}
desc { "clicked";
inherit: "default";
visible: 1;
}
}
rect { name: "event";
desc { "default";
color: 0 0 0 0;
}
desc { "disabled";
inherit: "default";
visible: 0;
}
}
swallow { "elm.swallow.content"; nomouse;
clip_to: "icon_clip";
desc { "default";
fixed: 1 0;
align: 0.0 0.5;
rel1.offset: 6 5;
rel1.to: "base";
rel2.relative: 0.0 1.0;
rel2.offset: 6 -8;
rel2.to: "base";
visible: 0;
}
desc { "visible";
inherit: "default";
fixed: 1 0;
aspect: 1.0 1.0;
visible: 1;
}
desc { "icononly";
inherit: "default";
fixed: 0 0;
align: 0.5 0.5;
rel2.relative: 1.0 1.0;
rel2.offset: -7 -8;
visible: 1;
}
}
}
programs {
program {
signal: "mouse,down,1"; source: "event";
action: SIGNAL_EMIT "elm,action,press" "elm";
after: "button_click_anim";
}
program { name: "button_click_anim";
action: STATE_SET "clicked" 0.0;
target: "shadow";
target: "base";
target: "shine";
}
program { name: "button_unclick";
signal: "mouse,up,1"; source: "event";
action: SIGNAL_EMIT "elm,action,unpress" "elm";
after: "button_unclick_anim";
}
program { name: "button_unclick_anim";
action: STATE_SET "default" 0.0;
target: "shadow";
target: "base";
target: "shine";
}
program { name: "buttonactivate";
signal: "elm,anim,activate"; source: "elm";
action: STATE_SET "clicked" 0.0;
target: "shadow";
target: "base";
target: "shine";
after: "button_unpressed_anim";
}
program { name: "button_unpressed_anim";
action: STATE_SET "default" 0.0;
in: 0.5 0.0;
target: "shadow";
target: "base";
target: "shine";
}
program {
signal: "mouse,clicked,1"; source: "event";
action: SIGNAL_EMIT "elm,action,click" "elm";
}
program { name: "button_state_disabled";
signal: "elm,state,disabled"; source: "elm";
action: STATE_SET "disabled" 0.0;
target: "event";
target: "icon_clip";
}
program { name: "button_state_enabled";
signal: "elm,state,enabled"; source: "elm";
action: STATE_SET "default" 0.0;
target: "event";
target: "icon_clip";
}
}
}

View File

@ -439,6 +439,8 @@ group { name: "elm/hover/base/popout";
group { name: "elm/hover/base/hoversel_vertical/default";
alias: "elm/hover/base/hoversel_vertical/entry";
alias: "elm/hover/base/combobox_vertical/entry";
alias: "elm/hover/base/combobox_vertical/default";
images.image: "button_normal.png" COMP;
images.image: "vertical_separated_bar_glow.png" COMP;
data.item: "dismiss" "on";
@ -773,6 +775,8 @@ group { name: "elm/hover/base/hoversel_vertical/default";
group { name: "elm/hover/base/hoversel_horizontal/default";
alias: "elm/hover/base/hoversel_horizontal/entry";
alias: "elm/hover/base/combobox_horizontal/default";
alias: "elm/hover/base/combobox_horizontal/entry";
images.image: "button_normal.png" COMP;
data.item: "dismiss" "on";
// max_size limits the maximum size of expanded hoversel

View File

@ -43,6 +43,7 @@ test_clock.c \
test_cnp.c \
test_colorselector.c \
test_colorclass.c \
test_combobox.c \
test_config.c \
test_conform.c \
test_conform_indicator.c \

View File

@ -45,6 +45,7 @@ void test_clock(void *data, Evas_Object *obj, void *event_info);
void test_clock_edit(void *data, Evas_Object *obj, void *event_info);
void test_clock_edit2(void *data, Evas_Object *obj, void *event_info);
void test_clock_pause(void *data, Evas_Object *obj, void *event_info);
void test_combobox(void *data, Evas_Object *obj, void *event_info);
void test_check(void *data, Evas_Object *obj, void *event_info);
void test_check_toggle(void *data, Evas_Object *obj, void *event_info);
void test_radio(void *data, Evas_Object *obj, void *event_info);
@ -753,6 +754,7 @@ add_tests:
ADD_TEST(NULL, "Selectors", "FlipSelector", test_flipselector);
ADD_TEST(NULL, "Selectors", "DaySelector", test_dayselector);
ADD_TEST(NULL, "Selectors", "Main menu", test_main_menu);
ADD_TEST(NULL, "Selectors", "Combobox", test_combobox);
//------------------------------//
ADD_TEST(NULL, "Cursors", "Cursor", test_cursor);

View File

@ -0,0 +1,165 @@
#include "test.h"
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
static void
_combobox_clicked_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
printf("Hover button is clicked and 'clicked' callback is called.\n");
}
static void
_combobox_selected_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info)
{
const char *txt = elm_object_item_text_get(event_info);
printf("'selected' callback is called. (selected item : %s)\n", txt);
}
static void
_combobox_dismissed_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
printf("'dismissed' callback is called.\n");
}
static void
_combobox_expanded_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
printf("'expanded' callback is called.\n");
}
static void
_combobox_item_pressed_cb(void *data EINA_UNUSED, Evas_Object *obj,
void *event_info)
{
const char *txt = elm_object_item_text_get(event_info);
printf("'item,pressed' callback is called. (selected item : %s)\n", txt);
elm_object_text_set(obj, txt);
elm_combobox_hover_end(obj);
}
static char *
gl_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
{
char buf[256];
snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data);
return strdup(buf);
}
static Evas_Object *gl_content_get(void *data EINA_UNUSED, Evas_Object *obj,
const char *part)
{
char buf[PATH_MAX];
Evas_Object *ic = elm_icon_add(obj);
if (!strcmp(part, "elm.swallow.end"))
snprintf(buf, sizeof(buf), "%s/images/bubble.png", elm_app_data_dir_get());
else
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", elm_app_data_dir_get());
elm_image_file_set(ic, buf, NULL);
evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
return ic;
}
static Eina_Bool gl_state_get(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
const char *part EINA_UNUSED)
{
return EINA_FALSE;
}
static Eina_Bool
gl_filter_get(void *data, Evas_Object *obj EINA_UNUSED, void *key)
{
// if the key is empty/NULL, return true for item
if (!strlen((char *)key)) return EINA_TRUE;
char buf[256];
snprintf(buf, sizeof(buf), "Item # %i", (int)(uintptr_t)data);
if (strcasestr(buf, (char *)key))
return EINA_TRUE;
// Default case should return false (item fails filter hence will be hidden)
return EINA_FALSE;
}
static void
_gl_filter_finished_cb(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
printf("Filter finished\n");
}
void
test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Evas_Object *win, *bx, *combobox;
Elm_Genlist_Item_Class *itc;
win = elm_win_util_standard_add("combobox", "Combobox");
elm_win_autodel_set(win, EINA_TRUE);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bx);
evas_object_show(bx);
itc = elm_genlist_item_class_new();
itc->item_style = "default";
itc->func.text_get = gl_text_get;
itc->func.content_get = gl_content_get;
itc->func.state_get = gl_state_get;
itc->func.filter_get = gl_filter_get;
itc->func.del = NULL;
combobox = elm_combobox_add(win);
evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
elm_object_part_text_set(combobox, "guide", "A long list");
for (int i = 0; i < 1000; i++)
elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
NULL, ELM_GENLIST_ITEM_NONE, NULL,
(void*)(uintptr_t)(i * 10));
evas_object_smart_callback_add(combobox, "clicked",
_combobox_clicked_cb, NULL);
evas_object_smart_callback_add(combobox, "selected",
_combobox_selected_cb, NULL);
evas_object_smart_callback_add(combobox, "dismissed",
_combobox_dismissed_cb, NULL);
evas_object_smart_callback_add(combobox, "expanded",
_combobox_expanded_cb, NULL);
evas_object_smart_callback_add(combobox, "item,pressed",
_combobox_item_pressed_cb, NULL);
evas_object_smart_callback_add(combobox, "filter,done",
_gl_filter_finished_cb, NULL);
elm_box_pack_end(bx, combobox);
evas_object_show(combobox);
combobox = elm_combobox_add(win);
evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
elm_object_text_set(combobox, "Disabled Combobox");
for (int i = 0; i < 1000; i++)
elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
NULL, ELM_GENLIST_ITEM_NONE, NULL,
(void*)(uintptr_t)(i * 10));
evas_object_smart_callback_add(combobox, "clicked",
_combobox_clicked_cb, NULL);
evas_object_smart_callback_add(combobox, "selected",
_combobox_selected_cb, NULL);
evas_object_smart_callback_add(combobox, "dismissed",
_combobox_dismissed_cb, NULL);
evas_object_smart_callback_add(combobox, "expanded",
_combobox_expanded_cb, NULL);
evas_object_smart_callback_add(combobox, "filter,done",
_gl_filter_finished_cb, NULL);
elm_object_disabled_set(combobox, EINA_TRUE);
elm_box_pack_end(bx, combobox);
evas_object_show(combobox);
evas_object_resize(win, 320, 500);
evas_object_show(win);
}

View File

@ -174,6 +174,7 @@ EAPI extern Elm_Version *elm_version;
/* other includes */
#include <elc_ctxpopup.h>
#include <elc_combobox.h>
#include <elm_dayselector.h>
#include <elc_fileselector_button.h>
#include <elc_fileselector_entry.h>

View File

@ -56,6 +56,7 @@ elm_widget_clock.h \
elm_widget_colorselector.h \
elm_widget_conform.h \
elm_widget_container.h \
elm_widget_combobox.h \
elm_widget_ctxpopup.h \
elm_widget_datetime.h \
elm_widget_dayselector.h \
@ -114,6 +115,8 @@ includesub_HEADERS = \
elc_ctxpopup.h \
elc_ctxpopup_eo.h \
elc_ctxpopup_legacy.h \
elc_combobox.h \
elc_combobox_legacy.h \
elc_fileselector.h \
elc_fileselector_eo.h \
elc_fileselector_legacy.h \
@ -415,6 +418,7 @@ elm_clock.c \
elm_cnp.c \
elm_colorselector.c \
elm_color_class.c \
elc_combobox.c \
elm_config.c \
elm_conform.c \
elm_container.c \
@ -531,6 +535,7 @@ elm_calendar.eo \
elm_check.eo \
elm_clock.eo \
elm_colorselector.eo \
elm_combobox.eo \
elm_conformant.eo \
elm_container.eo \
elm_ctxpopup.eo \

View File

@ -0,0 +1,458 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#define EO_BASE_BETA
#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_combobox.h"
#define MY_CLASS ELM_COMBOBOX_CLASS
#define MY_CLASS_NAME "Elm_Combobox"
#define MY_CLASS_NAME_LEGACY "elm_combobox"
static const char SIG_SELECTED[] = "selected";
static const char SIG_DISMISSED[] = "dismissed";
static const char SIG_EXPANDED[] = "expanded";
static const char SIG_ITEM_PRESSED[] = "item,pressed";
static const char SIG_FILTER_DONE[] = "filter,done";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_SELECTED, ""},
{SIG_DISMISSED, ""},
{SIG_EXPANDED, ""},
{SIG_ITEM_PRESSED, ""},
{SIG_FILTER_DONE, ""},
{"clicked", ""}, /**< handled by parent button class */
{SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
{SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
{NULL, NULL}
};
static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
static const Elm_Action key_actions[] = {
{"activate", _key_action_activate},
{"move", _key_action_move},
{NULL, NULL}
};
EOLIAN static Eina_Bool
_elm_combobox_elm_widget_translate(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
{
eo_do_super(obj, MY_CLASS, elm_obj_widget_translate());
eo_do(sd->genlist, elm_obj_widget_translate());
eo_do(sd->entry, elm_obj_widget_translate());
if (sd->hover)
eo_do(sd->hover, elm_obj_widget_translate());
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_combobox_elm_widget_theme_apply(Eo *obj, Elm_Combobox_Data *sd)
{
const char *style;
Eina_Bool int_ret = EINA_FALSE;
Eina_Bool mirrored;
char buf[128];
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
style = elm_widget_style_get(obj);
snprintf(buf, sizeof(buf), "combobox_vertical/%s", style);
/* combobox's style has no extra bit for orientation but could have... */
eina_stringshare_replace(&(wd->style), buf);
eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
if (!int_ret) return EINA_FALSE;
mirrored = elm_widget_mirrored_get(obj);
if (sd->hover)
elm_widget_mirrored_set(sd->hover, mirrored);
elm_widget_mirrored_set(sd->genlist, mirrored);
elm_widget_mirrored_set(sd->entry, mirrored);
elm_combobox_hover_end(obj);
return EINA_TRUE;
}
static void
_on_hover_clicked(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
elm_combobox_hover_end(data);
}
static void
count_items_genlist(void *data)
{
ELM_COMBOBOX_DATA_GET(data, sd);
Eina_Iterator *filter_iter;
int count = 0;
Elm_Object_Item *item;
filter_iter = elm_genlist_filter_iterator_new(sd->genlist);
if (!filter_iter) return;
EINA_ITERATOR_FOREACH(filter_iter, item)
if (item) count++;
sd->count = count;
eina_iterator_free(filter_iter);
}
static void
_table_resize(void *data)
{
ELM_COMBOBOX_DATA_GET(data, sd);
if (sd->count > 0)
{
int hover_parent_w, hover_parent_h, obj_h, obj_w, obj_y, win_y_offset;
int current_height, h;
sd->item = elm_genlist_first_item_get(sd->genlist);
elm_genlist_item_selected_set(sd->item, EINA_TRUE);
//FIXME:- the height of item is zero, sometimes.
evas_object_geometry_get(elm_object_item_track(sd->item), NULL, NULL,
NULL, &h);
if (h) sd->item_height = h;
evas_object_geometry_get(sd->entry, NULL, NULL, &obj_w, NULL);
evas_object_geometry_get(data, NULL, &obj_y, NULL, &obj_h);
evas_object_geometry_get(sd->hover_parent, NULL, NULL, &hover_parent_w,
&hover_parent_h);
current_height = sd->item_height * sd->count;
if (!strcmp(elm_hover_best_content_location_get(sd->hover,
ELM_HOVER_AXIS_VERTICAL),
"bottom"))
win_y_offset = hover_parent_h - obj_y - obj_h;
else win_y_offset = obj_y;
if (current_height < win_y_offset)
evas_object_size_hint_min_set(sd->spacer, obj_w * elm_config_scale_get(),
current_height + (2 * elm_config_scale_get()));
else evas_object_size_hint_min_set(sd->spacer, obj_w * elm_config_scale_get(),
win_y_offset * elm_config_scale_get());
}
}
static void
_activate(Evas_Object *obj)
{
ELM_COMBOBOX_DATA_GET(obj, sd);
if (elm_widget_disabled_get(obj)) return;
sd->expanded = EINA_TRUE;
eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_EXPANDED, NULL));
_table_resize(obj);
evas_object_show(sd->hover);
}
static void
_on_item_selected(void *data , Evas_Object *obj EINA_UNUSED, void *event)
{
ELM_COMBOBOX_DATA_GET(data, sd);
elm_object_focus_set(sd->entry, EINA_TRUE);
eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_SELECTED, event));
}
static void
_on_item_pressed(void *data , Evas_Object *obj EINA_UNUSED, void *event)
{
eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_ITEM_PRESSED, event));
}
static Eina_Bool
_gl_filter_finished_cb(void *data, Eo *obj EINA_UNUSED,
const Eo_Event_Description *desc EINA_UNUSED, void *event)
{
ELM_COMBOBOX_DATA_GET(data, sd);
eo_do(data, eo_event_callback_call(ELM_COMBOBOX_EVENT_FILTER_DONE, event));
count_items_genlist(data);
if (sd->count > 0)
{
if (sd->expanded == EINA_TRUE)
elm_combobox_hover_end(data);
_activate(data);
}
else elm_combobox_hover_end(data);
return EINA_TRUE;
}
static Eina_Bool
_on_aborted(void *data, Eo *obj EINA_UNUSED,
const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
{
ELM_COMBOBOX_DATA_GET(data, sd);
if (sd->expanded == EINA_TRUE) elm_combobox_hover_end(data);
return EINA_TRUE;
}
static Eina_Bool
_on_changed(void *data, Eo *obj EINA_UNUSED,
const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
{
elm_combobox_hover_begin(data);
return EINA_TRUE;
}
static void
_on_clicked(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
elm_combobox_hover_begin(data);
}
EOLIAN static void
_elm_combobox_evas_object_smart_add(Eo *obj, Elm_Combobox_Data *sd EINA_UNUSED)
{
eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
elm_widget_sub_object_parent_add(obj);
elm_widget_mirrored_automatic_set(obj, EINA_FALSE);
evas_object_smart_callback_add(obj, "clicked", _on_clicked, obj);
//What are you doing here?
eo_do(obj, elm_obj_widget_theme_apply());
}
EOLIAN static void
_elm_combobox_evas_object_smart_del(Eo *obj, Elm_Combobox_Data *sd)
{
sd->hover_parent = NULL;
eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
}
EOLIAN static void
_elm_combobox_evas_object_smart_show(Eo *obj, Elm_Combobox_Data *sd)
{
eo_do_super(obj, MY_CLASS, evas_obj_smart_show());
if (sd->expanded) evas_object_show(sd->hover);
}
EOLIAN static void
_elm_combobox_evas_object_smart_hide(Eo *obj, Elm_Combobox_Data *sd)
{
eo_do_super(obj, MY_CLASS, evas_obj_smart_hide());
if (sd->hover) evas_object_hide(sd->hover);
}
EOLIAN static Eina_Bool
_elm_combobox_elm_button_admits_autorepeat_get(Eo *obj EINA_UNUSED,
Elm_Combobox_Data *sd EINA_UNUSED)
{
return EINA_FALSE;
}
EAPI Evas_Object *
elm_combobox_add(Evas_Object *parent)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
Evas_Object *obj = eo_add(MY_CLASS, parent);
return obj;
}
EOLIAN static Eo *
_elm_combobox_eo_base_constructor(Eo *obj, Elm_Combobox_Data *sd)
{
Evas_Object *gl;
Evas_Object *entry;
char buf[128];
eo_do_super(obj, MY_CLASS, eo_constructor());
eo_do(obj,
evas_obj_type_set(MY_CLASS_NAME_LEGACY),
evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_GLASS_PANE));
//hover-parent
sd->hover_parent = elm_object_parent_widget_get(obj);
//hover
sd->hover = eo_add(ELM_HOVER_CLASS, sd->hover_parent);
elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE);
elm_hover_target_set(sd->hover, obj);
//table
sd->tbl = elm_table_add(obj);
evas_object_size_hint_weight_set(sd->tbl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sd->tbl, EVAS_HINT_FILL, EVAS_HINT_FILL);
//spacer
sd->spacer = evas_object_rectangle_add(evas_object_evas_get(sd->hover_parent));
evas_object_size_hint_weight_set(sd->spacer, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sd->spacer, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_color_set(sd->spacer, 0, 0, 0, 0);
elm_table_pack(sd->tbl, sd->spacer, 0, 0, 1, 1);
evas_object_show(sd->tbl);
// This is the genlist object that will take over the genlist call
sd->genlist = gl = eo_add(ELM_GENLIST_CLASS, obj);
elm_widget_mirrored_automatic_set(gl, EINA_FALSE);
elm_widget_mirrored_set(gl, elm_widget_mirrored_get(obj));
evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(gl, "selected", _on_item_selected, obj);
evas_object_smart_callback_add(gl, "pressed", _on_item_pressed, obj);
eo_do(gl, eo_event_callback_add(ELM_GENLIST_EVENT_FILTER_DONE,
_gl_filter_finished_cb, obj));
elm_genlist_homogeneous_set(gl, EINA_TRUE);
elm_table_pack(sd->tbl, gl, 0, 0, 1, 1);
evas_object_show(sd->genlist);
// This is the entry object that will take over the entry call
sd->entry = entry = eo_add(ELM_ENTRY_CLASS, obj);
elm_widget_mirrored_automatic_set(entry, EINA_FALSE);
elm_widget_mirrored_set(entry, elm_widget_mirrored_get(obj));
elm_scroller_policy_set(entry, ELM_SCROLLER_POLICY_OFF,
ELM_SCROLLER_POLICY_OFF);
elm_entry_scrollable_set(entry, EINA_TRUE);
elm_entry_single_line_set(entry, EINA_TRUE);
eo_do(entry, eo_event_callback_add(ELM_ENTRY_EVENT_CHANGED_USER,
_on_changed, obj));
eo_do(entry, eo_event_callback_add(ELM_ENTRY_EVENT_ABORTED,
_on_aborted, obj));
evas_object_show(entry);
snprintf(buf, sizeof(buf), "combobox_vertical/%s", elm_widget_style_get(obj));
elm_object_style_set(sd->hover, buf);
evas_object_smart_callback_add(sd->hover, "clicked", _on_hover_clicked, obj);
elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get
(sd->hover, ELM_HOVER_AXIS_VERTICAL), sd->tbl);
eo_do(obj,
eo_composite_attach(gl),
eo_composite_attach(entry));
elm_object_part_content_set(obj, "elm.swallow.content", entry);
return obj;
}
EOLIAN static void
_elm_combobox_hover_begin(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
{
if (!sd->hover) return;
elm_object_focus_set(sd->entry, EINA_TRUE);
elm_genlist_filter_set(sd->genlist, (void *)elm_object_text_get(sd->entry));
}
EOLIAN static void
_elm_combobox_hover_end(Eo *obj, Elm_Combobox_Data *sd)
{
if (!sd->hover) return;
sd->expanded = EINA_FALSE;
evas_object_hide(sd->hover);
eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_DISMISSED, NULL));
}
EOLIAN static Eina_Bool
_elm_combobox_expanded_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *sd)
{
return sd->expanded;
}
static Eina_Bool
_key_action_move(Evas_Object *obj, const char *params)
{
ELM_COMBOBOX_DATA_GET(obj, sd);
Elm_Object_Item *it = NULL;
const char *dir = params;
if (!sd->hover) return EINA_FALSE;
if (!strcmp(dir, "return"))
eo_do(obj, eo_event_callback_call(ELM_COMBOBOX_EVENT_CLICKED, NULL));
else if (!strcmp(dir, "up"))
{
it = sd->item;
it = elm_genlist_item_prev_get(it);
if (!it) sd->item = elm_genlist_last_item_get(sd->genlist);
else sd->item = it;
elm_genlist_item_selected_set(sd->item, EINA_TRUE);
}
else if (!strcmp(dir, "down"))
{
it = sd->item;
it = elm_genlist_item_next_get(it);
if (!it) sd->item = elm_genlist_first_item_get(sd->genlist);
else sd->item = it;
elm_genlist_item_selected_set(sd->item, EINA_TRUE);
}
else return EINA_FALSE;
return EINA_TRUE;
}
static Eina_Bool
_key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
{
elm_combobox_hover_begin(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_combobox_elm_widget_event(Eo *obj, Elm_Combobox_Data *sd,
Evas_Object *src EINA_UNUSED,
Evas_Callback_Type type, void *event_info)
{
Evas_Event_Key_Down *ev = event_info;
if (!sd || !sd->hover) return EINA_FALSE;
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
if (!_elm_config_key_binding_call(obj, MY_CLASS_NAME, ev, key_actions))
return EINA_FALSE;
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
static void
_elm_combobox_class_constructor(Eo_Class *klass)
{
evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
}
EOLIAN const Elm_Atspi_Action *
_elm_combobox_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED,
Elm_Combobox_Data *pd
EINA_UNUSED)
{
static Elm_Atspi_Action atspi_actions[] = {
{"activate", "activate", "return", _key_action_activate},
{"move,up", "move", "up", _key_action_move},
{"move,down", "move", "down", _key_action_move},
{NULL, NULL, NULL, NULL}
};
return &atspi_actions[0];
}
EOLIAN void
_elm_combobox_elm_widget_part_text_set(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd,
const char * part, const char *label)
{
elm_object_part_text_set(pd->entry, part, label);
}
EOLIAN const char *
_elm_combobox_elm_widget_part_text_get(Eo *obj EINA_UNUSED, Elm_Combobox_Data *pd,
const char * part)
{
return elm_object_part_text_get(pd->entry, part);
}
EOLIAN static void
_elm_combobox_evas_object_smart_resize(Eo *obj, Elm_Combobox_Data *pd,
Evas_Coord w, Evas_Coord h)
{
eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
if (pd->count > 0) _table_resize(obj);
}
#include "elm_combobox.eo.c"

View File

@ -0,0 +1,64 @@
/**
* @defgroup Combobox Combobox
* @ingroup Elementary
*
* @image html combobox_inheritance_tree.png
* @image latex combobox_inheritance_tree.eps
*
* @image html img/widget/combobox/preview-00.png
* @image latex img/widget/combobox/preview-00.eps
*
* A combobox is a button displaying an entry that pops up a list of items
* (automatically choosing the direction to display). It is a convenience
* widget to avoid the need to do all the piecing together yourself. It is
* intended for manipulating a large number of items in the combobox menu.
*
* This widget inherits from the @ref Button, @ref Genlist and @ref Entry
* one, so that all the functions acting on it also work for combobox objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Button:
* - @c "clicked" - the user clicked the combobox button and popped up
* the sel
* - @c "selected" - an item in the combobox list is selected. event_info
* is the selected item
* - @c "dismissed" - the hover is dismissed
* - @c "expanded" - This is called on clicking combobox and elm_combobox_hover_begin().
* - @c "language,changed" - the program's language changed (since 1.9)
* - @c "item,focused" - When the combobox item has received focus. (since 1.10)
* - @c "item,unfocused" - When the combobox item has lost focus. (since 1.10)
*
* Default content parts of the combobox widget that you can use for are:
* @li "icon" - An icon of the combobox
*
* Default text parts of the combobox widget that you can use for are:
* @li "default" - A label of the combobox
*
* Supported elm_object common APIs.
* @li @ref elm_object_disabled_set
* @li @ref elm_object_disabled_get
* @li @ref elm_object_part_text_set
* @li @ref elm_object_part_text_get
* @li @ref elm_object_part_content_set
* @li @ref elm_object_part_content_unset
*
* Supported elm_object_item common APIs.
* @li elm_object_item_del
* @li elm_object_item_part_text_get
* @li elm_object_item_signal_emit - this works only when the item is created.
* @li elm_object_item_style_set - this works only when the item is created.
* @li elm_object_item_style_get - this works only when the item is created.
*
* See @ref tutorial_combobox for an example.
* @{
*/
#ifdef EFL_EO_API_SUPPORT
#include "elm_combobox.eo.h"
#endif
#ifndef EFL_NOLEGACY_API_SUPPORT
#include "elc_combobox_legacy.h"
#endif
/**
* @}
*/

View File

@ -0,0 +1,11 @@
/**
* @brief Add a new Combobox object
*
* @param parent The parent object
* @return The new object or NULL if it cannot be created
*
* @ingroup Combobox
*/
EAPI Evas_Object *elm_combobox_add(Evas_Object *parent);
#include "elm_combobox.eo.legacy.h"

View File

@ -163,6 +163,7 @@
* @author Subodh Kumar <s7158.kumar@@samsung.com>
* @author Kumar Navneet <k.navneet@@samsung.com>
* @author Godly T Alias <godly.talias@@samsung.com>
* @author Divyesh Purohit <div.purohit@samsung.com> <purohit.div@gmail.com>
*
* Please contact <enlightenment-devel@lists.sourceforge.net> to get in
* contact with the developers and maintainers.

View File

@ -0,0 +1,54 @@
class Elm_Combobox (Elm.Button, Evas.Selectable_Interface,
Elm_Interface_Atspi_Widget_Action,
Elm.Entry, Elm.Genlist, Elm.Hover)
{
eo_prefix: elm_obj_combobox;
methods {
@property expanded {
get {
[[Returns whether the combobox is expanded.
This will return EINA_TRUE if the combobox is expanded or
EINA_FALSE if it is not expanded.
]]
return: bool;
}
}
hover_begin {
[[This triggers the combobox popup from code, the same as if the user
had clicked the button.
]]
}
hover_end {
[[This dismisses the combobox popup as if the user had clicked
outside the hover.
]]
}
}
implements {
class.constructor;
Eo.Base.constructor;
Evas.Object_Smart.hide;
Evas.Object_Smart.show;
Evas.Object_Smart.add;
Evas.Object_Smart.del;
Evas.Object_Smart.resize;
Elm.Widget.part_text.set;
Elm.Widget.part_text.get;
Elm.Widget.theme_apply;
Elm.Widget.translate;
Elm.Widget.event;
Elm.Button.admits_autorepeat.get;
Elm_Interface_Atspi_Widget_Action.elm_actions.get;
}
events {
selected;
dismissed;
expanded;
clicked;
item,pressed;
filter,done;
language,changed;
access,changed;
}
}

View File

@ -1848,6 +1848,33 @@ _config_update(void)
_elm_config->cursor_engine_only = 0;
IFCFGEND
IFCFG(0x0007)
Elm_Config_Bindings_Widget *wb, *twb = NULL;
Eina_List *l;
EINA_LIST_FOREACH(tcfg->bindings, l, wb)
{
if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
{
twb = wb;
break;
}
}
if (twb)
{
EINA_LIST_FOREACH(_elm_config->bindings, l, wb)
{
if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
{
// simply swap bindngs for Elm_Combobox with system ones
Eina_List *tmp = wb->key_bindings;
wb->key_bindings = twb->key_bindings;
twb->key_bindings = tmp;
break;
}
}
}
IFCFGEND
/**
* Fix user config for current ELM_CONFIG_EPOCH here.
**/

View File

@ -134,7 +134,7 @@ struct _Elm_Theme
* the users config doesn't need to be wiped - simply new values need
* to be put in
*/
#define ELM_CONFIG_FILE_GENERATION 0x0006
#define ELM_CONFIG_FILE_GENERATION 0x0007
#define ELM_CONFIG_VERSION_EPOCH_OFFSET 16
#define ELM_CONFIG_VERSION ((ELM_CONFIG_EPOCH << ELM_CONFIG_VERSION_EPOCH_OFFSET) | \
ELM_CONFIG_FILE_GENERATION)

View File

@ -0,0 +1,80 @@
#ifndef ELM_WIDGET_COMBOBOX_H
#define ELM_WIDGET_COMBOBOX_H
#include "Elementary.h"
/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
* CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
* FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
* IT AT RUNTIME.
*/
/**
* @addtogroup Widget
* @{
*
* @section elm-combobox-class The Elementary Combobox Class
*
* Elementary, besides having the @ref Combobox widget, exposes its
* foundation -- the Elementary Combobox Class -- in order to create other
* widgets which are a combobox with some more logic on top.
*/
/**
* Base button smart data extended with combobox instance data.
*/
typedef struct _Elm_Combobox_Data Elm_Combobox_Data;
struct _Elm_Combobox_Data
{
/* aggregates a hover */
Evas_Object *hover;
Evas_Object *hover_parent;
Evas_Object *genlist;
Evas_Object *entry;
Evas_Object *tbl;
Evas_Object *spacer;
Elm_Object_Item *item;
const char *style;
int count;
int item_height;
Eina_Bool expanded:1;
};
/**
* @}
*/
#define ELM_COMBOBOX_DATA_GET(o, sd) \
Elm_Combobox_Data * sd = eo_data_scope_get(o, ELM_COMBOBOX_CLASS)
#define ELM_COMBOBOX_DATA_GET_OR_RETURN(o, ptr) \
ELM_COMBOBOX_DATA_GET(o, ptr); \
if (EINA_UNLIKELY(!ptr)) \
{ \
CRI("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_COMBOBOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_COMBOBOX_DATA_GET(o, ptr); \
if (EINA_UNLIKELY(!ptr)) \
{ \
CRI("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_COMBOBOX_CHECK(obj) \
if (EINA_UNLIKELY(!eo_isa((obj), ELM_COMBOBOX_CLASS))) \
return
#define ELM_COMBOBOX_ITEM_CHECK(it) \
ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \
ELM_COMBOBOX_CHECK(it->base.widget);
#define ELM_COMBOBOX_ITEM_CHECK_OR_RETURN(it, ...) \
ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
ELM_COMBOBOX_CHECK(it->base.widget) __VA_ARGS__;
#endif