List - Items management

This code places an Elementary list widgets on a window, along with some buttons trigerring actions on it (though its API).

It covers most of elm_list_item functions.

On our `main` function, we are adding a default list with 3 items. We are only setting their labels (second parameter of function elm_list_item_append):

li = elm_list_add(win);
elm_list_add
Evas_Object * elm_list_add(Evas_Object *parent)
Add a new list widget to the given parent Elementary (container) object.
Definition: elm_list.c:2513
evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, li);
elm_list_item_append(li, "Item 0", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "Item 1", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "Item 2", NULL, NULL, NULL, NULL);
EVAS_HINT_EXPAND
#define EVAS_HINT_EXPAND
Use with evas_object_size_hint_weight_set(), evas_object_size_hint_weight_get(), evas_object_size_hin...
Definition: Evas_Common.h:297
EVAS_HINT_FILL
#define EVAS_HINT_FILL
Use with evas_object_size_hint_align_set(), evas_object_size_hint_align_get(), evas_object_size_hint_...
Definition: Evas_Common.h:298
elm_box_pack_end
void elm_box_pack_end(Elm_Box *obj, Efl_Canvas_Object *subobj)
Add an object at the end of the pack list.
Definition: elm_box_eo.legacy.c:57
elm_list_item_append
Elm_Widget_Item * elm_list_item_append(Elm_List *obj, const char *label, Efl_Canvas_Object *icon, Efl_Canvas_Object *end, Evas_Smart_Cb func, const void *data)
Append a new item to the list object.
Definition: elm_list_eo.legacy.c:129
evas_object_size_hint_weight_set
EVAS_API void evas_object_size_hint_weight_set(Evas_Object *obj, double x, double y)
Sets the hints for an object's weight.
Definition: evas_object_main.c:2638
evas_object_size_hint_align_set
EVAS_API void evas_object_size_hint_align_set(Evas_Object *obj, double x, double y)
Sets the hints for an object's alignment.
Definition: evas_object_main.c:2650

Next we are adding lots of buttons, each one for a callback function that will realize a task covering part of list items API. Lets check the first one:

bt = elm_button_add(win);
elm_button_add
Evas_Object * elm_button_add(Evas_Object *parent)
Add a new button to the parent's canvas.
Definition: efl_ui_button.c:459
elm_object_text_set(bt, "Prepend item");
evas_object_smart_callback_add(bt, "clicked", _prepend_cb, li);
elm_box_pack_end(hbx, bt);
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0);
evas_object_show(bt);
evas_object_show
EVAS_API void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1814
evas_object_smart_callback_add
EVAS_API void evas_object_smart_callback_add(Evas_Object *eo_obj, const char *event, Evas_Smart_Cb func, const void *data)
Add (register) a callback function to the smart event specified by event on the smart object obj.
Definition: evas_object_smart.c:1040

We are labeling the button with a task description with elm_object_text_set() and setting a callback function evas_object_smart_callback_add(). Each callback function will have the signature: `static void _task_cb(void *data, Evas_Object *obj, void *event_info)` with the function name varying for each task.

Now let's cover all of them.

Prepending an item:

_prepend_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition: eina_types.h:339
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition: Evas_Common.h:185
{
Elm_Object_Item *list_it;
Evas_Object *li = data;
char label[32];
snprintf(label, sizeof(label), "Item %i", counter++);
list_it = elm_list_item_prepend(li, label, NULL, NULL, NULL, NULL);
elm_list_go(li);
if (!list_it)
printf("Error adding item\n");
}
Elm_Object_Item
Eo Elm_Object_Item
An Elementary Object item handle.
Definition: elm_object_item.h:6
elm_list_go
void elm_list_go(Elm_List *obj)
Starts the list.
Definition: elm_list_eo.legacy.c:111
elm_list_item_prepend
Elm_Widget_Item * elm_list_item_prepend(Elm_List *obj, const char *label, Efl_Canvas_Object *icon, Efl_Canvas_Object *end, Evas_Smart_Cb func, const void *data)
Prepend a new item to the list object.
Definition: elm_list_eo.legacy.c:135

The item will be placed on the beginning of the list, i.e. it will be the first one.

The first parameter of elm_list_item_prepend() is the list object, that we are receiving as data on our callback function. The second one is a label, the string that will be placed in the center of our item. As we don't want icons or callback functions, we can send NULL as third, fourth, fifth and sixth parameters.

Appending an item:

_add_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *list_it;
Evas_Object *li = data;
char label[32];
snprintf(label, sizeof(label), "Item %i", counter++);
list_it = elm_list_item_append(li, label, NULL, NULL, NULL, NULL);
elm_list_go(li);
if (!list_it)
printf("Error adding item\n");
}

Items included with append will be inserted inserted after the last one.

Appending an item with icon:

_add_ic_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *list_it;
Evas_Object *ic, *li = data;
char label[32];
snprintf(label, sizeof(label), "Item %i", counter++);
ic = elm_icon_add(li);
elm_icon_standard_set(ic, "home");
elm_image_resizable_set(ic, EINA_FALSE, EINA_FALSE);
list_it = elm_list_item_append(li, label, ic, NULL, NULL, NULL);
elm_list_go(li);
if (!list_it)
printf("Error adding item with icon\n");
}
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:533
elm_icon_add
Evas_Object * elm_icon_add(Evas_Object *parent)
Add a new icon object to the parent.
Definition: elm_icon.c:613
elm_icon_standard_set
Eina_Bool elm_icon_standard_set(Evas_Object *obj, const char *name)
Set the icon by icon standards names.
Definition: elm_icon.c:885
elm_image_resizable_set
void elm_image_resizable_set(Evas_Object *obj, Eina_Bool up, Eina_Bool down)
Control if the object is (up/down) resizable.
Definition: efl_ui_image.c:2656

If an icon is required, you can pass it as third parameter on our elm_list_item_append() function. It will be place on the left side of item's label. If an icon is wanted on the right side, it should be passed as fourth parameter.

For more details about how to create icons, look for elm_icon examples Icon example.

Appending an item with callback function for selected:

_sel_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Elm_Object_Item *list_it = event_info;
printf("Selected label: %s\n", elm_object_item_text_get(list_it));
}
static void
_add_func_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *list_it;
Evas_Object *li = data;
char label[32];
snprintf(label, sizeof(label), "Item %i", counter++);
list_it = elm_list_item_append(li, label, NULL, NULL, _sel_cb, NULL);
elm_list_go(li);
if (!list_it)
printf("Error adding item\n");
}

To set a callback function that will be called every time an item is selected, i.e., everytime the list stops with this item in center position, just pass the function as fifth parameter.

Appending an item with callback function for selected with data:

_sel_data_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
char *content = data;
Elm_Object_Item *list_it = event_info;
printf("Selected label: %s with data: %s\n",
elm_object_item_text_get(list_it), content);
}
static void
_free_data(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
free(data);
}
static void
_add_data_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *list_it;
Evas_Object *li = data;
char label[32];
char *content = malloc(sizeof(char) * 32);
snprintf(content, 32, "Item content %i", counter);
snprintf(label, sizeof(label), "Item %i", counter++);
list_it = elm_list_item_append(li, label, NULL, NULL, _sel_data_cb, content);
elm_list_go(li);
if (!list_it)
{
printf("Error adding item\n");
return;
}
elm_object_item_del_cb_set(list_it, _free_data);
}
elm_object_item_del_cb_set
void elm_object_item_del_cb_set(Elm_Widget_Item *obj, Evas_Smart_Cb del_cb)
Set the function to be called when an item from the widget is freed.
Definition: elm_widget_item_eo.legacy.c:231

If the callback function request an extra data, it can be attached to our item passing a pointer for data as sixth parameter. Our function _sel_data_cb will receive it as `void *data` .

If you want to free this data, or handle that the way you need when the item is deleted, set a callback function for that, with elm_object_item_del_cb_set().

As you can see we check if `it` is not `NULL` after appending it. If an error happens, we won't try to set a function for it.

Deleting an item:

_del_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item;
Evas_Object *li = data;
selected_item = elm_list_selected_item_get(li);
elm_object_item_del(selected_item);
elm_list_go(li);
}
elm_object_item_del
void elm_object_item_del(Eo *obj)
Delete the given item.
Definition: elm_main.c:2017
elm_list_selected_item_get
Elm_Widget_Item * elm_list_selected_item_get(const Elm_List *obj)
Get the selected item.
Definition: elm_list_eo.legacy.c:75

To delete an item we simple need to call elm_object_item_del() with a pointer for such item.

If you need, you can get selected item with elm_list_selected_item_get(), that will return a pointer for it.

Unselecting an item:

_unselect_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item;
Evas_Object *li = data;
selected_item = elm_list_selected_item_get(li);
elm_list_item_selected_set(selected_item, EINA_FALSE);
}

To select an item, you should call elm_list_item_selected_set() passing `EINA_TRUE`, and to unselect it, `EINA_FALSE`.

Printing all items:

_print_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
const Eina_List *l, *items;
Elm_Object_Item *list_it;
Evas_Object *li = data;
items = elm_list_items_get(li);
EINA_LIST_FOREACH(items, l, list_it)
printf("%s\n", elm_object_item_text_get(list_it));
}
EINA_LIST_FOREACH
#define EINA_LIST_FOREACH(list, l, _data)
Definition for the macro to iterate over a list.
Definition: eina_list.h:1415
elm_list_items_get
const Eina_List * elm_list_items_get(const Elm_List *obj)
Get a list of all the list items.
Definition: elm_list_eo.legacy.c:81
_Eina_List
Type for a generic double linked list.
Definition: eina_list.h:318

Clearing the list:

_clear_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *li = data;
elm_list_clear(li);
}
elm_list_clear
void elm_list_clear(Elm_List *obj)
Remove all list's items.
Definition: elm_list_eo.legacy.c:141

Selecting the next item:

_select_next_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item, *next_item;
Evas_Object *li = data;
selected_item = elm_list_selected_item_get(li);
if (!selected_item) return;
next_item = elm_list_item_next(selected_item);
if (next_item)
elm_list_item_selected_set(next_item, EINA_TRUE);
}
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539

Inserting after an item:

_insert_after_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item, *list_it;
Evas_Object *li = data;
char label[32];
selected_item = elm_list_selected_item_get(li);
if (!selected_item) return;
snprintf(label, sizeof(label), "Item %i", counter++);
list_it = elm_list_item_insert_after(li, selected_item, label, NULL, NULL,
NULL, NULL);
elm_list_go(li);
if (!list_it)
printf("Error adding item\n");
}
elm_list_item_insert_after
Elm_Widget_Item * elm_list_item_insert_after(Elm_List *obj, Elm_Widget_Item *after, const char *label, Efl_Canvas_Object *icon, Efl_Canvas_Object *end, Evas_Smart_Cb func, const void *data)
Insert a new item into the list object after item after.
Definition: elm_list_eo.legacy.c:117

Selecting the previous item:

_select_prev_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item, *prev_item;
Evas_Object *li = data;
selected_item = elm_list_selected_item_get(li);
if (!selected_item) return;
prev_item = elm_list_item_prev(selected_item);
if (prev_item)
elm_list_item_selected_set(prev_item, EINA_TRUE);
}

Inserting before an item:

_insert_before_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item, *list_it;
Evas_Object *li = data;
char label[32];
selected_item = elm_list_selected_item_get(li);
if (!selected_item) return;
snprintf(label, sizeof(label), "Item %i", counter++);
list_it = elm_list_item_insert_before(li, selected_item, label, NULL, NULL,
NULL, NULL);
elm_list_go(li);
if (!list_it)
printf("Error adding item\n");
}
elm_list_item_insert_before
Elm_Widget_Item * elm_list_item_insert_before(Elm_List *obj, Elm_Widget_Item *before, const char *label, Efl_Canvas_Object *icon, Efl_Canvas_Object *end, Evas_Smart_Cb func, const void *data)
Insert a new item into the list object before item before.
Definition: elm_list_eo.legacy.c:105

If a separator is required, just set an item as such:

_set_separator_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item;
Evas_Object *li = data;
selected_item = elm_list_selected_item_get(li);
if (!selected_item) return;
elm_list_item_separator_set(selected_item, EINA_TRUE);
elm_list_go(li);
}

Also an item can be disabled, and the user won't be allowed to (un)select it:

_disable_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Object_Item *selected_item;
Evas_Object *li = data;
selected_item = elm_list_selected_item_get(li);
if (!selected_item) return;
elm_object_item_disabled_set(selected_item, EINA_TRUE);
}
elm_object_item_disabled_set
void elm_object_item_disabled_set(Elm_Widget_Item *obj, Eina_Bool disable)
Control the disabled state of a widget item.
Definition: elm_widget_item_eo.legacy.c:111

See the full list_example_03.c code, whose window should look like this picture: