Genlist - list setup functions

This example is very similar to the Genlist - basic usage, but it fetch most of the properties of the genlist and displays them on startup (thus getting the default value for them) and then set them to some other values, to show how to use that API.

The full source code is at genlist_example_02.c.

Considering that the base code for instantiating a genlist was already described in the previous example, we are going to focus on the new code.

Just a small difference for the `_item_label_get` function, we are going to store the time that this function was called. This is the "realized" time, the time when the visual representation of this item was created. This is the code for the `label_get` function:

static char *
_item_label_get(void *data, Evas_Object *obj, const char *part)
{
time_t t = (time_t)ecore_time_unix_get();
char buf[256];
int i = (int)(long)data;
if (i % 2)
{
int n;
snprintf(buf, sizeof(buf), "Very Long Item # %i - realized at %s", i, ctime(&t));
n = strlen(buf);
buf[n - 1] = '\0';
}
else
snprintf(buf, sizeof(buf), "short item # %i", i);
return strdup(buf);

Now let's go to the list creation and setup. First, just after creating the list, we get most of the default properties from it, and print them on the console:

list = elm_genlist_add(win);
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;
}
Eina_Bool hbounce, vbounce, always, no_sel;
Elm_Scroller_Policy hp, vp;
Elm_Object_Select_Mode sel_mode;
always = no_sel = EINA_FALSE;
sel_mode = elm_genlist_select_mode_get(list);
if (sel_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)
always = EINA_TRUE;
else if (sel_mode == ELM_OBJECT_SELECT_MODE_NONE)
no_sel = EINA_TRUE;
printf("default values:\n");
printf("always select: %d\n", always);
elm_scroller_bounce_get(list, &hbounce, &vbounce);
printf("bounce - horizontal: %d, vertical: %d\n", hbounce, vbounce);
printf("homogeneous: %d\n", elm_genlist_homogeneous_get(list));
printf("horizontal mode: %d\n", elm_genlist_mode_get(list));
printf("longpress timeout: %0.3f\n",
elm_genlist_longpress_timeout_get(list));
printf("multi selection: %d\n", elm_genlist_multi_select_get(list));
printf("no selection mode: %d\n", no_sel);
elm_scroller_policy_get(list, &hp, &vp);
printf("scroller policy - horizontal: %d, vertical: %d\n", hp, vp);
printf("block count: %d\n", elm_genlist_block_count_get(list));
printf("\n");

We are going to change some of the properties of our list.

There's no need to call the selected callback at every click, just when the selected item changes, thus we call elm_genlist_select_mode_set() with ELM_OBJECT_SELECT_MODE_ALWAYS.

For this list we don't want bounce animations at all, so we set both the horizontal bounce and the vertical bounce to false with elm_genlist_bounce_set().

We also want our list to compress items if they are wider than the list width (thus we call elm_genlist_mode_set(obj, ELM_LIST_COMPRESS).

The items have different width, so they are not homogeneous: elm_genlist_homogeneous_set() is set to false.

Since the compress mode is active, the call to elm_genlist_mode_set() doesn't make difference, but the current option would make the list to have at least the width of the largest item.

This list will support multiple selection, so we call elm_genlist_multi_select_set() on it.

The option elm_genlist_mode_set() would allow text block to wrap lines if the Edje part is configured with "text.min: 0 1", for example. But since we are compressing the elements to the width of the list, this option wouldn't take any effect.

We want the vertical scrollbar to be always displayed, and the orizontal one to never be displayed, and set this with elm_genlist_scroller_policy_set().

The timeout to consider a longpress is set to half of a second with elm_genlist_longpress_timeout_set().

We also change the block count to a smaller value, but that should have not impact on performance since the number of visible items is too small. We just increase the granularity of the block count (setting it to have at most 4 items).

elm_scroller_bounce_set(list, EINA_FALSE, EINA_FALSE);
elm_genlist_homogeneous_set(list, EINA_FALSE);
elm_genlist_mode_set(list, ELM_LIST_LIMIT);
elm_genlist_multi_select_set(list, EINA_TRUE);
elm_genlist_select_mode_set(list, ELM_OBJECT_SELECT_MODE_DEFAULT);
elm_scroller_policy_set(list, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_ON);
elm_genlist_longpress_timeout_set(list, 0.5);
elm_genlist_block_count_set(list, 16);

Now let's add elements to the list:

for (i = 0; i < N_ITEMS; i++)
{
elm_genlist_item_append(list, _itc,
(void *)(long)i, NULL,
ELM_GENLIST_ITEM_NONE,
_item_sel_cb, NULL);
}

It's exactly the same as the previous example. The difference is on the behavior of the list, if you try to scroll, select items and so.

In this example we also need two buttons. One of them, when clicked, will display several status info about the current selection, the "realized" items, the item in the middle of the screen, and the current mode and active item of that mode for the genlist.

The other button will ask the genlist to "realize" again the items already "realized", so their respective label_get and icon_get functions will be called again.

These are the callbacks for both of these buttons:

static void
_show_status_cb(void *data, Evas_Object *o, void *event_info)
{
Evas_Object *list = data;
Evas_Coord x, y, w, h, mx, my;
Elm_Object_Item *glit = elm_genlist_selected_item_get(list);
const Eina_List *selected, *l, *realized;
printf("\nfirst selected item: %p\n", glit);
selected = elm_genlist_selected_items_get(list);
printf("all selected items (%d): ", eina_list_count(selected));
EINA_LIST_FOREACH(selected, l, glit)
printf("%p ", glit);
printf("\n");
realized = elm_genlist_realized_items_get(list);
printf("realized items (%d): ", eina_list_count(realized));
EINA_LIST_FOREACH(realized, l, glit)
printf("%p ", glit);
printf("\n");
printf("genlist mode: %d\n", elm_genlist_decorate_mode_get(list));
printf("mode item: %p\n", elm_genlist_decorated_item_get(list));
evas_object_geometry_get(list, &x, &y, &w, &h);
mx = w / 2 + x;
my = h / 2 + y;
glit = elm_genlist_at_xy_item_get(list, mx, my, NULL);
printf("item in the middle of the screen: %p\n", glit);
}
static void
_realize_cb(void *data, Evas_Object *o, void *event_info)
{
Evas_Object *list = data;
elm_genlist_realized_items_update(list);
}

Try to scroll, select some items and click on the "Show status" button. You'll notice that not all items of the list are "realized", thus consuming just a small amount of memory. The selected items are listed in the order that they were selected, and the current selected item printed using elm_genlist_selected_item_get() is the first selected item of the multiple selection.

Now resize the window so that you can see the "realized time" of some items. This is the time of when the label_get function was called. If you click on the "Realize" button, all the already realized items will be rebuilt, so the time will be updated for all of them.

The current example will look like this when running: