Genlist - working with subitems

This is probably the most complex example of elementary Elm_Genlist.

We create a tree of items, using the subitems properties of the items, and keep it in memory to be able to expand/hide subitems of an item. The full source code can be found at genlist_example_05.c

The main point is the way that Genlist manages subitems. Clicking on an item's button to expand it won't really show its children. It will only generate the "expand,request" signal, and the expansion must be done manually.

In this example we want to be able to add items as subitems of another item. If an item has any child, it must be displayed using a parent class, otherwise it will use the normal item class.

It will be possible to delete items too. Once a tree is constructed (with subitems of subitems), and the user clicks on the first parent (root of the tree), the entire subtree must be hidden. However, just calling elm_genlist_item_expanded_set(item, EINA_FALSE) won't hide them. The only thing that happens is that the parent item will change its appearance to represent that it's contracted. And the signal "contracted" will be emitted from the genlist. Thus, we must call elm_genlist_item_subitems_clear() to delete all its subitems, but still keep a way to recreate them when expanding the parent again. That's why we are going to keep a node struct for each item, that will be the data of the item, with the following information:

typedef struct _Node_Data {
Eina_List *children;
int value;
int level;
Eina_Bool favorite;
} Node_Data;
Eina_List
struct _Eina_List Eina_List
Type for a generic double linked list.
Definition eina_list.h:304
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition eina_types.h:527

This `Node_Data` contains the value for the item, a number indicating its level under the tree, a list of children (to be able to expand it later) and a boolean indicating if it's a favorite item or not.

We use 3 different item classes in this example:

One for items that don't have children:

static int nitems = 0;
static char *
_item_label_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
{
char buf[256] = {0};
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
Node_Data *d = data;
if (!strcmp(part, "elm.text"))
snprintf(buf, sizeof(buf), "Item # %i (level %i)", d->value, d->level);
return strdup(buf);
}

One for items that have children:

static char *
_parent_label_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
{
char buf[256];
Node_Data *d = data;
snprintf(buf, sizeof(buf), "Group %d (%d items)", d->value / 7,
eina_list_count(d->children));
return strdup(buf);
}
static Evas_Object *
_parent_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, "folder");
evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
return ic;
}
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
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

And one for items that were favorited:

static char *
_favorite_label_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
{
char buf[256] = {0};
Node_Data *d = data;
if (!strcmp(part, "elm.text"))
snprintf(buf, sizeof(buf), "Favorite # %i", d->value);
return strdup(buf);
}

The favorite item class is there just to demonstrate the elm_genlist_item_item_class_update() function in action. It would be much simpler to implement the favorite behavior by just changing the icon inside the icon_get functions when the `favorite` boolean is activated.

Now we are going to declare the callbacks for the buttons that add, delete and change items.

First, a button for appending items to the list:

static Evas_Object *
_favorite_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, "apps");
evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
return ic;
}
static void
_append_cb(void *data, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *list = data;
Elm_Object_Item *glit, *parent = NULL;
Node_Data *pdata, *d = malloc(sizeof(*d));
d->children = NULL;
d->value = nitems++;
d->favorite = EINA_FALSE;
glit = elm_genlist_selected_item_get(list);
if (glit)
parent = elm_genlist_item_parent_get(glit);
if (parent)
{
d->level = elm_genlist_item_expanded_depth_get(parent) + 1;
pdata = elm_object_item_data_get(parent);
pdata->children = eina_list_append(pdata->children, d);
}
else
d->level = 0;
elm_genlist_item_append(list, _itc,
eina_list_append
EINA_API Eina_List * eina_list_append(Eina_List *list, const void *data)
Appends the given data to the given linked list.
Definition eina_list.c:584
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition eina_types.h:533
elm_object_item_data_get
void * elm_object_item_data_get(const Elm_Object_Item *it)
Get the data associated with an object item.
Definition efl_ui_widget.c:3796
Elm_Object_Item
Eo Elm_Object_Item
An Elementary Object item handle.
Definition elm_object_item.h:6
elm_genlist_selected_item_get
Elm_Widget_Item * elm_genlist_selected_item_get(const Elm_Genlist *obj)
Get the selected item in the genlist.
Definition elm_genlist_eo.legacy.c:153
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_parent_get
Elm_Widget_Item * elm_genlist_item_parent_get(const Elm_Genlist_Item *obj)
Get the parent item of the given item.
Definition elm_genlist_item_eo.legacy.c:15
elm_genlist_item_expanded_depth_get
int elm_genlist_item_expanded_depth_get(const Elm_Genlist_Item *obj)
Get the depth of expanded item.
Definition elm_genlist_item_eo.legacy.c:51
d, parent,
ELM_GENLIST_ITEM_NONE,
_item_sel_cb, NULL);
}
ELM_GENLIST_ITEM_NONE
@ ELM_GENLIST_ITEM_NONE
Simple item.
Definition elm_general.h:349

If an item is selected, a new item will be appended to the same level of that item, but using the selected item's parent as its parent too. If no item is selected, the new item will be appended to the root of the tree.

Then the callback for marking an item as favorite:

static void
_favorite_cb(void *data, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *list = data;
Elm_Object_Item *glit = elm_genlist_selected_item_get(list);
if (!glit) return;
Node_Data *d = elm_object_item_data_get(glit);
d->favorite = !d->favorite;
if (d->favorite)
elm_genlist_item_item_class_update(glit, _itfav);
else
{
if (d->children)
elm_genlist_item_item_class_update(glit, _itp);
else
elm_genlist_item_item_class_update(glit, _itc);
}
elm_genlist_item_update(glit);
elm_genlist_item_update
void elm_genlist_item_update(Elm_Genlist_Item *obj)
Update all the contents of an item.
Definition elm_genlist_item_eo.legacy.c:159
elm_genlist_item_item_class_update
void elm_genlist_item_item_class_update(Elm_Genlist_Item *obj, const Elm_Genlist_Item_Class *itc)
Update the item class of an item.
Definition elm_genlist_item_eo.legacy.c:171
}

This callback is very simple, it just changes the item class of the selected item for the "favorite" one, or go back to the "item" or "parent" class depending on that item having children or not.

Now, the most complex operation (adding a child to an item):

static void
_add_child_cb(void *data, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *list = data;
Elm_Object_Item *glit = elm_genlist_selected_item_get(list);
Elm_Object_Item *glit_prev, *glit_parent;
if (!glit) return;
Node_Data *d = elm_object_item_data_get(glit);
glit_prev = elm_genlist_item_prev_get(glit);
glit_parent = elm_genlist_item_parent_get(glit);
Eina_Bool change_item = !d->children;
// creating new item data
Node_Data *ndata = malloc(sizeof(*ndata));
ndata->value = nitems++;
ndata->children = NULL;
ndata->favorite = EINA_FALSE;
ndata->level = elm_genlist_item_expanded_depth_get(glit) + 1;
d->children = eina_list_append(d->children, ndata);
// Changing leaf item to parent item
if (change_item)
{
elm_object_item_del(glit);
if (glit_prev != glit_parent)
glit = elm_genlist_item_insert_after(list, _itp, d, glit_parent,
glit_prev,
ELM_GENLIST_ITEM_TREE,
_item_sel_cb, NULL);
else
glit = elm_genlist_item_prepend(list, _itp, d, glit_parent,
ELM_GENLIST_ITEM_TREE,
_item_sel_cb, NULL);
elm_genlist_item_expanded_set(glit, EINA_FALSE);
elm_genlist_item_selected_set(glit, EINA_TRUE);
}
else if (elm_genlist_item_expanded_get(glit))
{
elm_genlist_item_append(list, _itc, ndata, glit,
ELM_GENLIST_ITEM_NONE, _item_sel_cb, NULL);
}
elm_genlist_item_update(glit);
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
elm_object_item_del
void elm_object_item_del(Eo *obj)
Delete the given item.
Definition elm_main.c:2017
elm_genlist_item_prepend
Elm_Widget_Item * elm_genlist_item_prepend(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)
Prepend a new item in a given genlist widget.
Definition elm_genlist_eo.legacy.c:231
elm_genlist_item_insert_after
Elm_Widget_Item * elm_genlist_item_insert_after(Elm_Genlist *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Widget_Item *parent, Elm_Widget_Item *after_it, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
Insert an item after another in a genlist widget.
Definition elm_genlist_eo.legacy.c:195
elm_genlist_item_expanded_set
void elm_genlist_item_expanded_set(Elm_Genlist_Item *obj, Eina_Bool expanded)
Sets the expanded state of an item.
Definition elm_genlist_item_eo.legacy.c:39
elm_genlist_item_expanded_get
Eina_Bool elm_genlist_item_expanded_get(const Elm_Genlist_Item *obj)
Get the expanded state of an item.
Definition elm_genlist_item_eo.legacy.c:45
elm_genlist_item_prev_get
Elm_Widget_Item * elm_genlist_item_prev_get(const Elm_Genlist_Item *obj)
Get the previous item in a genlist widget's internal list of items, given a handle to one of those it...
Definition elm_genlist_item_eo.legacy.c:3
elm_genlist_item_selected_set
void elm_genlist_item_selected_set(Elm_Genlist_Item *obj, Eina_Bool selected)
Set whether a given genlist item is selected or not.
Definition elm_genlist_item_eo.legacy.c:27
ELM_GENLIST_ITEM_TREE
@ ELM_GENLIST_ITEM_TREE
This may be expanded and have child items.
Definition elm_general.h:350
}

This function gets the data of the selected item, create a new data (for the item being added), and appends it to the children list of the selected item.

Then we must check if the selected item (let's call it `item1` now) to which the new item (called `item2` from now on) was already a parent item too (using the parent item class) or just a normal item (using the default item class). In the first case, we just have to append the item to the end of the `item1` children list.

However, if the `item1` didn't have any child previously, we have to change it to a parent item now. It would be easy to just change its item class to the parent type, but there's no way to change the item flags and make it be of the type ELM_GENLIST_ITEM_TREE. Thus, we have to delete it and create a new item, and add this new item to the same position that the deleted one was. That's the reason of the checks inside the bigger `if`.

After adding the item to the newly converted parent, we set it to not expanded (since we don't want to show the added item immediately) and select it again, since the original item was deleted and no item is selected at the moment.

Finally, let's show the callback for deleting items:

static void
_clear_list(Node_Data *d)
{
Node_Data *tmp;
EINA_LIST_FREE(d->children, tmp)
_clear_list(tmp);
free(d);
}
static void
_del_item_cb(void *data, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *list = data;
Elm_Object_Item *glit = elm_genlist_selected_item_get(list);
Elm_Object_Item *glit_parent = NULL;
if (!glit) return;
Node_Data *pdata, *d = elm_object_item_data_get(glit);
glit_parent = elm_genlist_item_parent_get(glit);
elm_genlist_item_subitems_clear(glit);
elm_object_item_del(glit);
if (glit_parent)
{
pdata = elm_object_item_data_get(glit_parent);
pdata->children = eina_list_remove(pdata->children, d);
}
_clear_list(d);
elm_genlist_item_update(glit_parent);
eina_list_remove
EINA_API Eina_List * eina_list_remove(Eina_List *list, const void *data)
Removes the first instance of the specified data from the given list.
Definition eina_list.c:773
EINA_LIST_FREE
#define EINA_LIST_FREE(list, data)
Definition for the macro to remove each list node while having access to each node's data.
Definition eina_list.h:1629
elm_genlist_item_subitems_clear
void elm_genlist_item_subitems_clear(Elm_Genlist_Item *obj)
Remove all sub-items (children) of the given item.
Definition elm_genlist_item_eo.legacy.c:123
}

Since we have an iternal list representing each element of our tree, once we delete an item we have to go deleting each child of that item, in our internal list. That's why we have the function `_clear_list`, which recursively goes freeing all the item data.

This is necessary because only when we really want to delete the item is when we need to delete the item data. When we are just contracting the item, we need to hide the children by deleting them, but keeping the item data.

Now there are two callbacks that will be called whenever the user clicks on the expand/contract icon of the item. They will just request to items to be contracted or expanded:

static void
_expand_request_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
{
Elm_Object_Item *glit = event_info;
printf("expand request on item: %p\n", event_info);
elm_genlist_item_expanded_set(glit, EINA_TRUE);
}
static void
_contract_request_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
{
Elm_Object_Item *glit = event_info;
printf("contract request on item: %p\n", event_info);
elm_genlist_item_expanded_set(glit, EINA_FALSE);
}

When the elm_genlist_item_expanded_set() function is called with `EINA_TRUE`, the `_expanded_cb` will be called. And when this happens, the subtree of that item must be recreated again. This is done using the internal list stored as item data for each item. The function code follows:

static void
_expanded_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
{
Eina_List *l;
Elm_Object_Item *glit = event_info;
Node_Data *it_data, *d = elm_object_item_data_get(glit);
Evas_Object *list = elm_object_item_widget_get(glit);
Elm_Genlist_Item_Class *ic;
EINA_LIST_FOREACH(d->children, l, it_data)
{
Elm_Object_Item *nitem;
Elm_Genlist_Item_Type type = ELM_GENLIST_ITEM_NONE;
printf("expanding item: #%d from parent #%d\n", it_data->value, d->value);
if (it_data->favorite)
ic = _itfav;
else if (it_data->children)
{
ic = _itp;
type = ELM_GENLIST_ITEM_TREE;
}
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_object_item_widget_get
Efl_Canvas_Object * elm_object_item_widget_get(const Elm_Widget_Item *obj)
Get the widget object's handle which contains a given item.
Definition elm_widget_item_eo.legacy.c:135
Elm_Genlist_Item_Type
Elm_Genlist_Item_Type
Defines if the item is of any special type (has subitems or it's the index of a group),...
Definition elm_general.h:348

Each appended item is set to contracted, so we don't have to deal with checking if the item was contracted or expanded before its parent being contracted. It could be easily implemented, though, by adding a flag expanded inside the item data.

Now, the `_contracted_cb`, which is much simpler:

else
ic = _itc;
nitem = elm_genlist_item_append(list, ic, it_data, glit,
type, _item_sel_cb, NULL);
elm_genlist_item_expanded_set(nitem, EINA_FALSE);
}

We just have to call elm_genlist_item_subitems_clear(), that will take care of deleting every item, and keep the item data still stored (since we don't have any del function set on any of our item classes).

Finally, the code inside `elm_main` is very similar to the other examples:

elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
Evas_Object *win, *box, *fbox;
Evas_Object *list;
int i;
win = elm_win_util_standard_add("genlist", "Genlist");
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
elm_win_autodel_set(win, EINA_TRUE);
box = elm_box_add(win);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, box);
evas_object_show(box);
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;
}
if (!_itp)
{
_itp = elm_genlist_item_class_new();
_itp->item_style = "default";
_itp->func.text_get = _parent_label_get;
_itp->func.content_get = _parent_content_get;
_itp->func.state_get = NULL;
_itp->func.del = NULL;
}
if (!_itfav)
{
_itfav = elm_genlist_item_class_new();
_itfav->item_style = "default";
_itfav->func.text_get = _favorite_label_get;
_itfav->func.content_get = _favorite_content_get;
_itfav->func.state_get = NULL;
_itfav->func.del = NULL;
}
list = elm_genlist_add(win);
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, list);
evas_object_show(list);
fbox = elm_box_add(win);
elm_box_layout_set(fbox, evas_object_box_layout_flow_horizontal,
NULL, NULL);
evas_object_size_hint_weight_set(fbox, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(fbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, fbox);
evas_object_show(fbox);
_button_add(list, fbox, "append item", _append_cb);
_button_add(list, fbox, "favorite", _favorite_cb);
_button_add(list, fbox, "add child", _add_child_cb);
_button_add(list, fbox, "del item", _del_item_cb);
Node_Data *pdata = NULL; // data for the parent of the group
Elm_Object_Item *glg = NULL;
for (i = 0; i < N_ITEMS; i++)
{
Elm_Object_Item *gli = NULL;
Node_Data *data = malloc(sizeof(*data)); // data for this item
data->children = NULL;
data->value = i;
data->favorite = EINA_FALSE;
nitems++;
printf("creating item: #%d\n", data->value);
if (i % 3 == 0)
{
glg = gli = elm_genlist_item_append(list, _itp, data, NULL,
ELM_GENLIST_ITEM_TREE,
_item_sel_cb, NULL);
elm_genlist_item_expanded_set(glg, EINA_TRUE);
pdata = data;
data->level = 0;
}
else
{
gli = elm_genlist_item_append(list, _itc, data, glg,
ELM_GENLIST_ITEM_NONE,
_item_sel_cb, NULL);
if (pdata)
pdata->children = eina_list_append(pdata->children, data);
data->level = 1;
}
}
evas_object_smart_callback_add(list, "expand,request", _expand_request_cb, list);
evas_object_smart_callback_add(list, "contract,request", _contract_request_cb, list);
evas_object_smart_callback_add(list, "expanded", _expanded_cb, list);
evas_object_smart_callback_add(list, "contracted", _contracted_cb, list);
evas_object_resize(win, 420, 600);
evas_object_show(win);
elm_run();
return 0;
}
ELM_MAIN()
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_add
Evas_Object * elm_box_add(Evas_Object *parent)
Add a new box to the parent.
Definition elm_box.c:363
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_box_layout_set
void elm_box_layout_set(Eo *obj, Evas_Object_Box_Layout cb, const void *data, Ecore_Cb free_data)
Set the layout defining function to be used by the box.
Definition elm_box.c:502
ELM_MAIN
#define ELM_MAIN()
macro to be used after the elm_main() function
Definition elm_general.h:556
elm_policy_set
Eina_Bool elm_policy_set(unsigned int policy, int value)
Set a new policy's value (for a given policy group/identifier).
Definition elm_main.c:1380
elm_run
void elm_run(void)
Run Elementary's main loop.
Definition elm_main.c:1357
ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
@ ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
quit when the application's last window is closed
Definition elm_general.h:248
ELM_POLICY_QUIT
@ ELM_POLICY_QUIT
under which circumstances the application should quit automatically.
Definition elm_general.h:227
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
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_win_util_standard_add
Evas_Object * elm_win_util_standard_add(const char *name, const char *title)
Adds a window object with standard setup.
Definition efl_ui_win.c:9587
elm_win_resize_object_add
void elm_win_resize_object_add(Eo *obj, Evas_Object *subobj)
Add subobj as a resize object of window obj.
Definition efl_ui_win.c:9002
elm_win_autodel_set
void elm_win_autodel_set(Eo *obj, Eina_Bool autodel)
Set the window's autodel state.
Definition efl_ui_win.c:6199
evas_object_box_layout_flow_horizontal
EVAS_API void evas_object_box_layout_flow_horizontal(Evas_Box *obj, Evas_Object_Box_Data *priv, void *data)
Layout function which sets the box o to a flow horizontal box.
Definition evas_box_eo.legacy.c:159
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_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
evas_object_resize
EVAS_API void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Changes the size of the given Evas object.
Definition evas_object_main.c:1236
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

The example will look like this when running: