Genlist - basic usage

This example creates a simple genlist with a small number of items and a callback that is called whenever an item is selected.

All the properties of this genlist are the default ones. The full code for this example can be seen at genlist_example_01.c.

For the simplest list that you plan to create, it's necessary to define some of the basic functions that are used for creating each list item, and associating them with the "item class" for that list. The item class is just an struct that contains pointers to the specific list item functions that are common to all the items of the list.

Let's show it by example. Our item class is declared globally and static as it will be the only item class that we need (we are just creating one list):

static Elm_Genlist_Item_Class *_itc = NULL;

This item class will be used for every item that we create. The only functions that we are going to set are `label_get` and `icon_get`. As the name suggests, they are used by the genlist to generate the label for the respective item, and to generate icon(s) to it too. Both the label and icon get functions can be called more than once for each item, with different `part` parameters, which represent where in the theme of the item that label or icon is going to be set.

The default theme for the genlist contains only one area for label, and two areas for icon ("elm.swallow.icon" and "elm.swallow.end"). Since we just want to set the first icon (that will be at the left side of the label), we compare the part name given with "elm.swallow.icon". Notice that the `label_get` function must return a strduped string, that will be freed later automatically by the list. Here's the code for `label_get` and `icon_get:`

static char *
_item_label_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 *
_item_content_get(void *data EINA_UNUSED, Evas_Object *obj, const char *part)
{
Evas_Object *ic = elm_icon_add(obj);
if (!strcmp(part, "elm.swallow.icon"))
elm_icon_standard_set(ic, "clock");
evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
return ic;
}
static void
EVAS_ASPECT_CONTROL_VERTICAL
@ EVAS_ASPECT_CONTROL_VERTICAL
Use all vertical container space to place an object, using the given aspect.
Definition Evas_Common.h:377
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition eina_types.h:339
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:876
elm_icon_add
Evas_Object * elm_icon_add(Evas_Object *parent)
Add a new icon object to the parent.
Definition elm_icon.c:604
evas_object_size_hint_aspect_set
EVAS_API void evas_object_size_hint_aspect_set(Evas_Object *obj, Evas_Aspect_Control aspect, Evas_Coord w, Evas_Coord h)
Sets the hints for an object's aspect ratio.
Definition evas_object_main.c:2581
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition Evas_Common.h:185

We will also provide a function that will be called whenever an item is selected in the genlist. However, this function is not part of the item class, it will be passed for each item being added to the genlist explicitly. Notice the similarity of the function signature with those used by `evas_object_smart_callback_add:`

_item_sel_cb(void *data, Evas_Object *obj, void *event_info)
{
printf("sel item data [%p] on genlist obj [%p], item pointer [%p]\n",
data, obj, event_info);
}

Now let's show the code used for really creating the list. Skipping boilerplate code used for creating a window and background, the first piece of code specific to our genlist example is setting the pointer functions of the item class to our above defined functions:

if (!_itc)
{
_itc = elm_genlist_item_class_new();
_itc->item_style = "default";
_itc->func.text_get = _item_label_get;
_itc->func.content_get = _item_content_get;
_itc->func.state_get = NULL;
_itc->func.del = NULL;
elm_genlist_item_class_new
Elm_Genlist_Item_Class * elm_genlist_item_class_new(void)
Create a new genlist item class in a given genlist widget.
Definition elm_genlist.c:8392
_Elm_Gen_Item_Class_Functions::state_get
Elm_Gen_Item_State_Get_Cb state_get
State fetching class function for genlist/gengrid item classes.
Definition elm_gen.h:101
_Elm_Gen_Item_Class_Functions::del
Elm_Gen_Item_Del_Cb del
Deletion class function for genlist/gengrid item classes.
Definition elm_gen.h:102
_Elm_Gen_Item_Class_Functions::content_get
Elm_Gen_Item_Content_Get_Cb content_get
Content fetching class function for genlist/gengrid item classes.
Definition elm_gen.h:100
_Elm_Gen_Item_Class_Functions::text_get
Elm_Gen_Item_Text_Get_Cb text_get
Text fetching class function for genlist/gengrid item classes.
Definition elm_gen.h:99
_Elm_Gen_Item_Class::func
Elm_Gen_Item_Class_Functions func
Set of callbacks.
Definition elm_gen.h:126
_Elm_Gen_Item_Class::item_style
const char * item_style
Name of the visual style to use for this item.
Definition elm_gen.h:118

Notice that we also choose to use the "default" style for our genlist items. Another interesting point is that `state_get` and `del` are set to `NULL`, since we don't need these functions now. `del` doesn't need to be used because we don't add any data that must be freed to our items, and `state_get` is also not used since all of our items are the same and don't need to have different states to be used for each item. Finally we create our list:

}
list = elm_genlist_add(win);
elm_genlist_add
Evas_Object * elm_genlist_add(Evas_Object *parent)
Add a new genlist widget to the given parent Elementary (container) object.
Definition elm_genlist.c:5998

Now we append several items to the list, and for all of them we need to give the list pointer, a pointer to the item class, the data that will be used with that item, a pointer to the parent of this item if it is in a group type list (this is not the case so we pass `NULL`), possible flags for this item, the callback for when the item is selected, and the data pointer that will be given to the selected callback.

for (i = 0; i < N_ITEMS; i++)
{
elm_genlist_item_append(list, _itc,
(void *)(uintptr_t)i, NULL,
ELM_GENLIST_ITEM_NONE,
_item_sel_cb, NULL);
}
elm_genlist_item_append
Elm_Widget_Item * elm_genlist_item_append(Elm_Genlist *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Widget_Item *parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
Append a new item in a given genlist widget.
Definition elm_genlist_eo.legacy.c:243
ELM_GENLIST_ITEM_NONE
@ ELM_GENLIST_ITEM_NONE
Simple item.
Definition elm_general.h:349

The rest of the code is also common to all the other examples, so it will be omitted here (look at the full source code link above if you need it).

You can try to play with this example, and see the selected callback being called whenever an item is clicked. It also already has some features enabled by default, like vertical bounce animation when reaching the end of the list, automatically visible/invisible scrollbar, etc. Look at the Genlist - list setup functions to see an example of setting these properties to the list.

The current example will look like this when running: