Gengrid widget example

This application is a thorough exercise on the gengrid widget's API.

We place an Elementary gengrid widget on a window, with various knobs below its viewport, each one acting on it somehow.

The code's relevant part begins at the grid's creation. After instantiating it, we set its items sizes, so that we don't end with items one finger size wide, only. We're setting them to fat, 150 pixel wide ones, for this example. We give it some size hints, not to be discussed in this context and, than, we register a callback on one of its smart events – the one coming each time an item gets doubly clicked. There, we just print the item handle's value.

grid = elm_gengrid_add(win);
elm_gengrid_item_size_set(grid, 150, 150);
evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, grid);
evas_object_smart_callback_add(grid, "clicked,double", _double_click, NULL);
evas_object_smart_callback_add(grid, "longpressed", _long_pressed, NULL);
evas_object_show(grid);
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_gengrid_add
Evas_Object * elm_gengrid_add(Evas_Object *parent)
Add a new gengrid widget to the given parent Elementary (container) object.
Definition: elm_gengrid.c:4254
elm_gengrid_item_size_set
void elm_gengrid_item_size_set(Elm_Gengrid *obj, int w, int h)
Set the size for the items of a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:93
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_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
/* item double click callback */
static void
_double_click(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info)
{
printf("Double click on item with handle %p\n", event_info);
}
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

Before we actually start to deal with the items API, let's show some things items will be using throughout all the code. The first of them is a struct to be used as item data, for all of them:

typedef struct _Example_Item
{
const char *path;
} Example_Item;

That path will be used to index an image, to be swallowed into one of the item's icon spots. The images themselves are distributed with Elementary:

static const char *imgs[9] =
{
"panel_01.jpg",
"plant_01.jpg",
"rock_01.jpg",
"rock_02.jpg",
"sky_01.jpg",
"sky_02.jpg",
"sky_03.jpg",
"sky_04.jpg",
"wood_01.jpg",
};

We also have an (unique) gengrid item class we'll be using for items in the example:

static Elm_Gengrid_Item_Class *gic = NULL;
_Elm_Gen_Item_Class
Gengrid or Genlist item class definition.
Definition: elm_gen.h:109
gic->item_style = "default";
gic->func.text_get = _grid_label_get;
gic->func.content_get = _grid_content_get;
gic->func.state_get = _grid_state_get;
gic->func.del = _grid_del;
_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

As you see, our items will follow the default theme on gengrid items. For the label fetching code, we return a string composed of the item's image path:

/* label fetching callback */
static char *
_grid_label_get(void *data,
Evas_Object *obj EINA_UNUSED,
const char *part EINA_UNUSED)
{
const Example_Item *it = data;
char buf[256];
snprintf(buf, sizeof(buf), "Photo %s", it->path);
return strdup(buf);
}

For item icons, we'll be populating the item default theme's two icon spots, `"elm.swallow.icon"` and `"elm.swallow.end"`. The former will receive one of the images in our list (in the form of a background), while the latter will be a check widget. Note that we prevent the check to propagate click events, so that the user can toggle its state without messing with the respective item's selection in the grid:

/* icon fetching callback */
static Evas_Object *
_grid_content_get(void *data,
Evas_Object *obj,
const char *part)
{
const Example_Item *it = data;
if (!strcmp(part, "elm.swallow.icon"))
{
Evas_Object *icon = elm_bg_add(obj);
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(),
it->path);
elm_bg_file_set(icon, buf, NULL);
evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1,
1);
evas_object_show(icon);
return icon;
}
else if (!strcmp(part, "elm.swallow.end"))
{
Evas_Object *ck;
ck = elm_check_add(obj);
evas_object_propagate_events_set(ck, EINA_FALSE);
evas_object_show(ck);
return ck;
}
return NULL;
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_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:533
elm_app_data_dir_get
const char * elm_app_data_dir_get(void)
Get the application's run time data prefix directory, as set by elm_app_info_set() and the way (envir...
Definition: elm_main.c:586
elm_bg_file_set
Eina_Bool elm_bg_file_set(Eo *obj, const char *file, const char *group)
Sets the file (image or edje collection) to give life for the background.
Definition: efl_ui_bg.c:188
elm_bg_add
Evas_Object * elm_bg_add(Evas_Object *parent)
Adds a new background to the parent.
Definition: efl_ui_bg.c:304
elm_check_add
Evas_Object * elm_check_add(Evas_Object *parent)
Add a new Check object.
Definition: efl_ui_check.c:516
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_propagate_events_set
EVAS_API void evas_object_propagate_events_set(Efl_Canvas_Object *obj, Eina_Bool propagate)
Set whether events on a smart object's member should be propagated up to its parent.
Definition: efl_canvas_object_eo.legacy.c:63
}

As the default gengrid item's theme does not have parts implementing item states, we'll be just returning false for every item state:

/* state fetching callback */
static Eina_Bool
_grid_state_get(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
const char *part EINA_UNUSED)
{
return EINA_FALSE;
}
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:527

Finally, the deletion callback on gengrid items takes care of freeing the item's label string and its data struct:

/* deletion callback */
static void
_grid_del(void *data,
Evas_Object *obj EINA_UNUSED)
{
Example_Item *it = data;
eina_stringshare_del(it->path);
free(it);
}
eina_stringshare_del
EINA_API void eina_stringshare_del(Eina_Stringshare *str)
Notes that the given string has lost an instance.
Definition: eina_stringshare.c:533

Let's move to item insertion/deletion knobs, them. They are four buttons, above the grid's viewport, namely

- "Append" (to append an item to the grid),
- "Prepend" (to prepend an item to the grid),
- "Insert before" (to insert an item before the selection, on the grid),
- "Insert after" (to insert an item after the selection, on the grid),
- "Clear" (to delete all items in the grid),
- "Bring in 1st" (to make the 1st item visible, by scrolling),
- "Show last" (to directly show the last item),

which are displaced and declared in that order. We're not dealing with the buttons' creation code (see a button example, for more details on it), but with their `"clicked"` registered callbacks. For all of them, the grid's handle is passed as `data`. The ones creating new items use a common code, which just gives a new `Example_Item` struct, with `path` filled with a random image in our images list:

/* new item with random path */
static Example_Item *
_item_new(void)
{
Example_Item *it;
it = malloc(sizeof(*it));
it->path = eina_stringshare_add(imgs[rand() % (sizeof(imgs) /
sizeof(imgs[0]))]);
return it;
}
eina_stringshare_add
EINA_API Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieves an instance of a string for use in a program.
Definition: eina_stringshare.c:606

Moreover, that ones will set a common function to be issued on the selection of the items. There, we print the item handle's value, along with the callback function data. The latter will be `NULL`, always, because it's what we pass when adding all icons. By using elm_object_item_data_get(), we can have the item data back and, with that, we're priting the item's path string. Finally, we exemplify elm_gengrid_item_pos_get(), printing the item's position in the grid:

/* item selection callback */
static void
_grid_sel(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info)
{
unsigned int x, y;
Example_Item *it = elm_object_item_data_get(event_info);
elm_gengrid_item_pos_get(event_info, &x, &y);
printf("Item [%p], with data [%p], path %s, at position (%u, %u),"
" has been selected\n", event_info, data, it->path, x, y);
}
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_gengrid_item_pos_get
void elm_gengrid_item_pos_get(const Elm_Object_Item *it, unsigned int *x, unsigned int *y)
Get a given gengrid item's position, relative to the whole gengrid's grid area.
Definition: elm_gengrid_item_eo.legacy.c:39

The appending button will exercise elm_gengrid_item_append(), simply:

/* append an item */
static void
_append_bt_clicked(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Evas_Object *grid = data;
Example_Item *it = _item_new();
elm_gengrid_item_append(grid, gic, it, _grid_sel, NULL);
}
elm_gengrid_item_append
Elm_Widget_Item * elm_gengrid_item_append(Elm_Gengrid *obj, const Elm_Gengrid_Item_Class *itc, const void *data, Evas_Smart_Cb func, const void *func_data)
Append a new item in a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:189

The prepending, naturally, is analogous, but exercising elm_gengrid_item_prepend(), on its turn. The "Insert before" one will expect an item to be selected in the grid, so that it will insert a new item just before it:

/* "insert before" callback */
static void
_before_bt_clicked(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Example_Item *it;
Evas_Object *grid = data;
Elm_Object_Item *sel;
sel = elm_gengrid_selected_item_get(grid);
if (!sel)
return;
it = _item_new();
elm_gengrid_item_insert_before(grid, gic, it, sel, _grid_sel, NULL);
}
Elm_Object_Item
Eo Elm_Object_Item
An Elementary Object item handle.
Definition: elm_object_item.h:6
elm_gengrid_selected_item_get
Elm_Widget_Item * elm_gengrid_selected_item_get(const Elm_Gengrid *obj)
Get the selected item in a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:129
elm_gengrid_item_insert_before
Elm_Widget_Item * elm_gengrid_item_insert_before(Elm_Gengrid *obj, const Elm_Gengrid_Item_Class *itc, const void *data, Elm_Widget_Item *relative, Evas_Smart_Cb func, const void *func_data)
Insert an item before another in a gengrid widget.
Definition: elm_gengrid_eo.legacy.c:159

The "Insert after" is analogous, just using elm_gengrid_item_insert_after(), instead. The "Clear" button will, as expected, just issue elm_gengrid_clear():

/* delete items */
static void
_clear_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
elm_gengrid_clear(data);
printf("Clearing the grid!\n");
}
elm_gengrid_clear
void elm_gengrid_clear(Elm_Gengrid *obj)
Remove all items from a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:201

The "Bring in 1st" button is there exercise two gengrid functions – elm_gengrid_first_item_get() and elm_gengrid_item_bring_in(). With the former, we get a handle to the first item and, with the latter, you'll see that the widget animatedly scrolls its view until we can see that item:

/* bring in 1st item */
static void
_bring_1st_clicked(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Elm_Object_Item *gg_it = elm_gengrid_first_item_get(data);
if (!gg_it) return;
elm_gengrid_item_bring_in(gg_it, ELM_GENGRID_ITEM_SCROLLTO_IN);
}
elm_gengrid_first_item_get
Elm_Widget_Item * elm_gengrid_first_item_get(const Elm_Gengrid *obj)
Get the first item in a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:141
elm_gengrid_item_bring_in
void elm_gengrid_item_bring_in(Elm_Gengrid_Item *obj, Elm_Gengrid_Item_Scrollto_Type type)
Animatedly bring in, to the visible area of a gengrid, a given item on it.
Definition: elm_gengrid_item_eo.legacy.c:75
ELM_GENGRID_ITEM_SCROLLTO_IN
@ ELM_GENGRID_ITEM_SCROLLTO_IN
To the nearest viewport.
Definition: elm_general.h:397

The "Show last", in its turn, will use elm_gengrid_last_item_get() and elm_gengrid_item_show(). The latter differs from elm_gengrid_item_bring_in() in that it immediately replaces the contents of the grid's viewport with the region containing the item in question:

/* show last item */
static void
_show_last_clicked(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Elm_Object_Item *gg_it = elm_gengrid_last_item_get(data);
if (!gg_it) return;
elm_gengrid_item_show(gg_it, ELM_GENGRID_ITEM_SCROLLTO_IN);
}
elm_gengrid_last_item_get
Elm_Widget_Item * elm_gengrid_last_item_get(const Elm_Gengrid *obj)
Get the last item in a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:153
elm_gengrid_item_show
void elm_gengrid_item_show(Elm_Gengrid_Item *obj, Elm_Gengrid_Item_Scrollto_Type type)
Show the portion of a gengrid's internal grid containing a given item, immediately.
Definition: elm_gengrid_item_eo.legacy.c:69

To change the grid's cell (items) size, we've placed a spinner, which has the following `"changed"` smart callback:

/* change items' size */
static void
_size_changed(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *grid = data;
int size = elm_spinner_value_get(obj);
elm_gengrid_item_size_set(grid, size, size);
}
elm_spinner_value_get
double elm_spinner_value_get(const Evas_Object *obj)
Control the value the spinner displays.
Definition: elm_spinner.c:1390

Experiment with it and see how the items are affected. The "Disable item" button will, as the name says, disable the currently selected item:

/* disable selected item */
static void
_toggle_disabled_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Elm_Object_Item *gg_it = elm_gengrid_selected_item_get(data);
if (!gg_it) return;
elm_gengrid_item_selected_set(gg_it, EINA_FALSE);
elm_object_item_disabled_set(gg_it, EINA_TRUE);
}
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539
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
elm_gengrid_item_selected_set
void elm_gengrid_item_selected_set(Elm_Gengrid_Item *obj, Eina_Bool selected)
Control whether a given gengrid item is selected or not.
Definition: elm_gengrid_item_eo.legacy.c:15

Note that we also make use of elm_gengrid_item_selected_set(), there, thus making the item unselected before we actually disable it.

To toggle between horizontal and vertical layouting modes on the grid, use the "Horizontal mode" check, which will call the respective API function on the grid:

/* change layouting mode */
static void
_horizontal_grid(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *grid = data;
elm_gengrid_horizontal_set(grid, elm_check_state_get(obj));
}
elm_check_state_get
Eina_Bool elm_check_state_get(const Evas_Object *obj)
Get the state of the check object.
Definition: efl_ui_check.c:381
elm_gengrid_horizontal_set
void elm_gengrid_horizontal_set(Elm_Gengrid *obj, Eina_Bool horizontal)
Set the direction in which a given gengrid widget will expand while placing its items.
Definition: elm_gengrid_eo.legacy.c:117

If you toggle the check right after that one, "Always select", you'll notice all subsequent clicks on the same grid item will still issue the selection callback on it, what is different from when it's not checked. This is the elm_gengrid_select_mode_set() behavior:

/* "always select" callback */
static void
_always_select_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *grid = data;
Eina_Bool always = elm_check_state_get(obj);
if (always)
elm_gengrid_select_mode_set(grid, ELM_OBJECT_SELECT_MODE_ALWAYS);
else
elm_gengrid_select_mode_set(grid, ELM_OBJECT_SELECT_MODE_DEFAULT);
printf("\"Always select\" mode for gengrid items is now %s\n",
always ? "on" : "off");
}
ELM_OBJECT_SELECT_MODE_DEFAULT
@ ELM_OBJECT_SELECT_MODE_DEFAULT
default select mode.
Definition: elm_general.h:34
ELM_OBJECT_SELECT_MODE_ALWAYS
@ ELM_OBJECT_SELECT_MODE_ALWAYS
always select mode.
Definition: elm_general.h:39
elm_gengrid_select_mode_set
void elm_gengrid_select_mode_set(Elm_Gengrid *obj, Elm_Object_Select_Mode mode)
Set the gengrid select mode.
Definition: elm_gengrid_eo.legacy.c:51

One more check follows, "Bouncing", which will turn on/off the bouncing animations on the grid, when one scrolls past its borders. Experiment with scrolling the grid to get the idea, having it turned on and off:

/* "bouncing mode" callback */
static void
_bouncing_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *grid = data;
Eina_Bool bounce = elm_check_state_get(obj);
elm_scroller_bounce_set(grid, bounce, bounce);
printf("Bouncing effect for gengrid is now %s\n",
bounce ? "on" : "off");
}
elm_scroller_bounce_set
void elm_scroller_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
Set bouncing behavior.
Definition: elm_scroller.c:1050

The next two checks will affect items selection on the grid. The first, "Multi-selection", will make it possible to select more the one item on the grid. Because it wouldn't make sense to fetch for an unique selected item on this case, we also disable two of the buttons, which insert items relatively, if multi-selection is on:

/* multi-selection callback */
static void
_multi_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *grid = data;
Eina_Bool multi = elm_check_state_get(obj);
elm_gengrid_multi_select_set(grid, multi);
printf("Multi-selection for gengrid is now %s\n",
multi ? "on" : "off");
elm_object_disabled_set(before_bt, multi);
elm_object_disabled_set(after_bt, multi);
if (!multi)
{
Elm_Object_Item *gg_it;
const Eina_List *selected = elm_gengrid_selected_items_get(grid), *l;
EINA_LIST_FOREACH(selected, l, gg_it)
elm_gengrid_item_selected_set(gg_it, EINA_FALSE);
}
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_disabled_set
void elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled)
Set the disabled state of an Elementary object.
Definition: elm_main.c:1613
elm_gengrid_multi_select_set
void elm_gengrid_multi_select_set(Elm_Gengrid *obj, Eina_Bool multi)
Enable or disable multi-selection in a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:27
elm_gengrid_selected_items_get
const Eina_List * elm_gengrid_selected_items_get(const Elm_Gengrid *obj)
Get a list of selected items in a given gengrid.
Definition: elm_gengrid_eo.legacy.c:147
_Eina_List
Type for a generic double linked list.
Definition: eina_list.h:318

Note that we also unselect all items in the grid, when returning from multi-selection mode, making use of elm_gengrid_item_selected_set().

The second check acting on selection, "No selection", is just what its name depicts – no selection will be allowed anymore, on the grid, while it's on. Check it out for yourself, interacting with the program:

/* no selection callback */
static void
_no_sel_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *grid = data;
Eina_Bool no_sel = elm_check_state_get(obj);
if (no_sel)
elm_gengrid_select_mode_set(grid, ELM_OBJECT_SELECT_MODE_NONE);
else
elm_gengrid_select_mode_set(grid, ELM_OBJECT_SELECT_MODE_DEFAULT);
printf("Selection for gengrid items is now %s\n",
no_sel ? "disabled" : "enabled");
}
ELM_OBJECT_SELECT_MODE_NONE
@ ELM_OBJECT_SELECT_MODE_NONE
no select mode.
Definition: elm_general.h:43

We have, finally, one more line of knobs, now sliders, to change the grids behavior. The two first will change the horizontal alignment of the whole actual grid of items within the gengrid's viewport:

/* items grid horizontal alignment change */
static void
_h_align_change_cb(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
double v_align;
double val = elm_slider_value_get(obj);
elm_gengrid_align_get(data, NULL, &v_align);
printf("Setting horizontal alignment to %f\n", val);
elm_gengrid_align_set(data, val, v_align);
}
elm_gengrid_align_get
void elm_gengrid_align_get(const Elm_Gengrid *obj, double *align_x, double *align_y)
Get the items grid's alignment values within a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:9
elm_gengrid_align_set
void elm_gengrid_align_set(Elm_Gengrid *obj, double align_x, double align_y)
Set the items grid's alignment within a given gengrid widget.
Definition: elm_gengrid_eo.legacy.c:3
elm_slider_value_get
double elm_slider_value_get(const Evas_Object *obj)
Get the value displayed by the slider.
Definition: elm_slider.c:1534

Naturally, the vertical counterpart just issues elm_gengrid_align_set() changing the second alignment component, instead.

The last slider will change the grid's page size, relative to its own one. Try to change those values and, one manner of observing the paging behavior, is to scroll softly and release the mouse button, with different page sizes, at different grid positions, while having lots of items in it – you'll see it snapping to page boundaries differenty, for each configuration:

/* page relative size change */
static void
_page_change_cb(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
double val = elm_slider_value_get(obj);
elm_scroller_page_relative_set(data, val, val);
printf("Setting grid page's relative size to %f\n", val);
}
elm_scroller_page_relative_set
void elm_scroller_page_relative_set(Evas_Object *obj, double h_pagerel, double v_pagerel)
Set scroll page size relative to viewport size.
Definition: elm_scroller.c:1070

This is how the example program's window looks like:

Note that it starts with three items which we included at will:

_append_bt_clicked(grid, NULL, NULL);
_append_bt_clicked(grid, NULL, NULL);
_append_bt_clicked(grid, NULL, NULL);

See the full source code for this example.