forked from enlightenment/www-content
Wiki pages genlist_tutorial created: set-up, modifications + image + code c
Coming soon page also added. Signed-off-by: Clément Bénier <clement.benier@openwide.fr> Signed-off-by: Pierre Le Magourou <pierre.lemagourou@openwide.fr> Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
parent
fb7b68ff8b
commit
27308035b3
|
@ -0,0 +1,139 @@
|
|||
#include <Elementary.h>
|
||||
|
||||
static char *
|
||||
_genlist_text_get_size(void *data, Evas_Object *obj , const char *part)
|
||||
{
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "Entry %d", (int)(uintptr_t)data);
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
static char *
|
||||
_genlist_text_get_nosize(void *data, Evas_Object *obj , const char *part)
|
||||
{
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "OHOHO %d", (int)(uintptr_t)data);
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_genlist_content_get_bg(void *data, Evas_Object *obj, const char *part)
|
||||
{
|
||||
int i = (int) (uintptr_t) data;
|
||||
|
||||
Evas_Object *bg = elm_bg_add(obj);
|
||||
elm_bg_color_set(bg, 255 * cos(i / (double) 10), 0, i % 255);
|
||||
|
||||
return bg;
|
||||
}
|
||||
|
||||
static void
|
||||
_tree_item_expand_request(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_item_class_update(it, data);
|
||||
|
||||
elm_genlist_item_expanded_set(it, EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_tree_item_contract_request(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_item_class_update(it, data);
|
||||
|
||||
elm_genlist_item_expanded_set(it, EINA_FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
_tree_item_expanded(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it_parent = (Elm_Object_Item*) event_info;
|
||||
int i_parent = (int)(uintptr_t)elm_object_item_data_get(it_parent);
|
||||
Elm_Object_Item *list = o;
|
||||
Elm_Genlist_Item_Class *itc = data;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
elm_genlist_item_append(list, itc,
|
||||
(void *)(uintptr_t) (i + i_parent),
|
||||
it_parent,
|
||||
ELM_GENLIST_ITEM_NONE,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_tree_item_contracted(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it_parent = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_subitems_clear(it_parent);
|
||||
}
|
||||
|
||||
EAPI_MAIN int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
Evas_Object *win;
|
||||
|
||||
win = elm_win_util_standard_add("Genlist", "Genlist Basic Tutorial");
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
||||
elm_win_autodel_set(win, EINA_TRUE);
|
||||
//win 400x400 px
|
||||
evas_object_resize(win, 400, 400);
|
||||
|
||||
Evas_Object *list;
|
||||
list = elm_genlist_add(win);
|
||||
evas_object_resize(list, 400, 400);
|
||||
|
||||
Elm_Genlist_Item_Class *_itc_child = elm_genlist_item_class_new();
|
||||
_itc_child->item_style = "default_style";
|
||||
_itc_child->func.text_get = _genlist_text_get_size;
|
||||
_itc_child->func.content_get = _genlist_content_get_bg;
|
||||
_itc_child->func.state_get = NULL;
|
||||
_itc_child->func.del = NULL;
|
||||
|
||||
Elm_Genlist_Item_Class *_itc_parent = elm_genlist_item_class_new();
|
||||
_itc_parent->item_style = "default_style";
|
||||
_itc_parent->func.text_get = _genlist_text_get_nosize;
|
||||
_itc_parent->func.content_get = _genlist_content_get_bg;
|
||||
_itc_parent->func.state_get = NULL;
|
||||
_itc_parent->func.del = NULL;
|
||||
|
||||
int i,j;
|
||||
Elm_Object_Item *it = NULL;
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
it = elm_genlist_item_append(list, _itc_parent,
|
||||
(void *)(uintptr_t) (10 * i),
|
||||
NULL,
|
||||
ELM_GENLIST_ITEM_TREE,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
|
||||
evas_object_smart_callback_add(list, "expand,request",
|
||||
_tree_item_expand_request, _itc_parent);
|
||||
evas_object_smart_callback_add(list, "expanded", _tree_item_expanded,
|
||||
_itc_child);
|
||||
|
||||
evas_object_smart_callback_add(list, "contract,request",
|
||||
_tree_item_contract_request, _itc_child);
|
||||
evas_object_smart_callback_add(list, "contracted", _tree_item_contracted,
|
||||
NULL);
|
||||
|
||||
evas_object_show(list);
|
||||
evas_object_show(win);
|
||||
elm_run();
|
||||
return 0;
|
||||
}
|
||||
ELM_MAIN()
|
|
@ -0,0 +1,96 @@
|
|||
#include <Elementary.h>
|
||||
|
||||
static char *
|
||||
_genlist_text_get(void *data, Evas_Object *obj , const char *part)
|
||||
{
|
||||
if (strcmp(part, "elm.text") == 0)
|
||||
{
|
||||
char *buf = malloc(16);
|
||||
snprintf(buf, 16, "Entry %d.", (int)(uintptr_t)data);
|
||||
|
||||
return buf;
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_genlist_content_get(void *data, Evas_Object *obj, const char *part)
|
||||
{
|
||||
int i = (int) (uintptr_t) data;
|
||||
|
||||
if (strcmp(part, "elm.swallow.icon") == 0)
|
||||
{
|
||||
Evas_Object *bg = elm_bg_add(obj);
|
||||
elm_bg_color_set(bg, 255 * cos(i / (double) 10), 0, i % 255);
|
||||
|
||||
return bg;
|
||||
}
|
||||
else if (strcmp(part, "elm.swallow.end") == 0)
|
||||
{
|
||||
Evas_Object *bg = elm_bg_add(obj);
|
||||
elm_bg_color_set(bg, 0, 255 * sin(i / (double) 10), i % 255);
|
||||
|
||||
return bg;
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_genlist_selected_cb(void *data, Evas_Object *obj, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_item_class_update(it, data);
|
||||
}
|
||||
|
||||
EAPI_MAIN int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
Evas_Object *win;
|
||||
|
||||
win = elm_win_util_standard_add("Genlist", "Genlist Basic Tutorial");
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
||||
elm_win_autodel_set(win, EINA_TRUE);
|
||||
//win 400x400 px
|
||||
evas_object_resize(win, 400, 400);
|
||||
|
||||
//GENLIST here
|
||||
Evas_Object *list;
|
||||
list = elm_genlist_add(win);
|
||||
|
||||
Elm_Genlist_Item_Class *_itc = elm_genlist_item_class_new();
|
||||
_itc->item_style = "default";
|
||||
_itc->func.text_get = _genlist_text_get;
|
||||
_itc->func.content_get = _genlist_content_get;
|
||||
_itc->func.state_get = NULL;
|
||||
_itc->func.del = NULL;
|
||||
|
||||
Elm_Genlist_Item_Class *_itc2 = elm_genlist_item_class_new();
|
||||
_itc2->item_style = "group_index";
|
||||
_itc2->func.text_get = _genlist_text_get;
|
||||
_itc2->func.content_get = _genlist_content_get;
|
||||
_itc2->func.state_get = NULL;
|
||||
_itc2->func.del = NULL;
|
||||
|
||||
int i=0;
|
||||
for (i=0; i<20; i++)
|
||||
{
|
||||
elm_genlist_item_append(list,
|
||||
_itc,
|
||||
(void *)(uintptr_t) i, // Item data
|
||||
NULL, // Parent item for trees, NULL if none
|
||||
ELM_GENLIST_ITEM_NONE, // Item type; this is the common one
|
||||
_genlist_selected_cb, // Callback on selection of the item
|
||||
_itc2 // Data for that callback function
|
||||
);
|
||||
}
|
||||
|
||||
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
elm_win_resize_object_add(win, list);
|
||||
evas_object_show(list);
|
||||
|
||||
evas_object_show(win);
|
||||
elm_run();
|
||||
return 0;
|
||||
}
|
||||
ELM_MAIN()
|
Binary file not shown.
After Width: | Height: | Size: 197 KiB |
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
|
@ -0,0 +1,6 @@
|
|||
~~Title: Coming Soon~~
|
||||
==== Coming soon! ====
|
||||
|
||||
:{{ coming_soon.jpg?direct&500 }}
|
||||
|
||||
|
|
@ -38,6 +38,7 @@ Go check the current available version of EFL on each distro/platform:
|
|||
=== Tutorials ===
|
||||
|
||||
* [[tutorial/basic_tutorial|Basic Tutorial]]
|
||||
* [[tutorial/genlist_tutorial|Genlist Tutorial]]
|
||||
|
||||
----
|
||||
|
||||
|
|
|
@ -0,0 +1,252 @@
|
|||
~~Title: Genlist Modifications~~
|
||||
==== Genlist Modifications ====
|
||||
|
||||
=== Choosing Another Item Style to Add or Remove Parts ===
|
||||
|
||||
As mentioned above, the number of parts to fill depends on the item style that
|
||||
is chosen when adding a new item. This is simply a matter of setting the right
|
||||
value when filling the ''Elm_Genlist_Item_Class'' struct:
|
||||
|
||||
<code c>
|
||||
itc->item_style = "default";
|
||||
</code>
|
||||
|
||||
The Genlist Widget lists all available item styles:
|
||||
* default
|
||||
* default_style - The text part is a textblock
|
||||
* double_label
|
||||
* icon_top_text_bottom
|
||||
* group_index
|
||||
* one_icon - Only 1 icon at left
|
||||
* end_icon - Only 1 icon at end/right
|
||||
* no_icon - No icon at end/right
|
||||
* full - Only 1 icon, elm.swallow.content, which consumes whole area of genlist item
|
||||
|
||||
|
||||
Further customization is achieved by modifying the theme as explained in the
|
||||
[[/coming_soon|Edje guide]].
|
||||
|
||||
In case the customization is only visual, it is good practice to keep the same
|
||||
item style names for new themes. This makes it possible to change theme and
|
||||
keep the code the same while also retaining the same overall item placement.
|
||||
|
||||
==== Using Item Modes ====
|
||||
|
||||
So far the genlist examples have all featured bare lists while the genlist
|
||||
widget is able to display trees or even a "group" mode where scrolling keeps
|
||||
the item at the top of the widget until another group comes and replaces it.
|
||||
|
||||
//**__Group Mode__**//
|
||||
|
||||
The group mode makes it possible to keep an element visible as long as one of
|
||||
its children is visible. This is most useful for "title" items.
|
||||
|
||||
Mark some elements as ''ELM_GENLIST_ITEM_GROUP'' and use the returned
|
||||
''Elm_Object_Item'' to establish the parent-children relationship when adding the
|
||||
children items.
|
||||
|
||||
Since there are two kind of items, create two item classes. Give them
|
||||
different styles and callback functions. The callback functions are visible in
|
||||
the example, they have no functionalities:
|
||||
|
||||
<code c>
|
||||
Elm_Genlist_Item_Class *_itc_child = elm_genlist_item_class_new();
|
||||
_itc->item_style = "default_style";
|
||||
_itc->func.text_get = _genlist_text_get_size;
|
||||
_itc->func.content_get = _genlist_content_get_bg;
|
||||
_itc->func.state_get = NULL;
|
||||
_itc->func.del = NULL;
|
||||
|
||||
Elm_Genlist_Item_Class *_itc_parent = elm_genlist_item_class_new();
|
||||
_itc2->item_style = "default_style";
|
||||
_itc2->func.text_get = _genlist_text_get_nosize;
|
||||
_itc2->func.content_get = _genlist_content_get_icon;
|
||||
_itc2->func.state_get = NULL;
|
||||
_itc2->func.del = NULL;
|
||||
</code>
|
||||
|
||||
Then add a group header and follow it with 10 children. This is repeated 10
|
||||
times.
|
||||
|
||||
The parent has type ''ELM_GENLIST_ITEM_GROUP'' while the children have type
|
||||
''ELM_GENLIST_ITEM_NONE''.
|
||||
|
||||
The other important point is that the value returned by
|
||||
''elm_genlist_item_append()'' is stored in it and then sent to the
|
||||
''elm_genlist_item_append()'' call that adds the children. This creates the
|
||||
parent-children relationship.
|
||||
|
||||
<code c>
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
it = elm_genlist_item_append(list, _itc_parent,
|
||||
(void *)(uintptr_t) (10 * i),
|
||||
NULL,
|
||||
ELM_GENLIST_ITEM_GROUP,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
for (j = 0; j < 10; j++)
|
||||
{
|
||||
elm_genlist_item_append(list, _itc_child,
|
||||
(void *)(uintptr_t) (10 * i + j),
|
||||
it, //parent item
|
||||
ELM_GENLIST_ITEM_NONE,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
//**__Tree Mode__**//
|
||||
|
||||
Like group mode, tree mode uses the parenting relationship with other items.
|
||||
Unlike group mode, the child elements are created on-demand when their parent
|
||||
is expanded and deleted when it is contracted. This is done by using smart
|
||||
callbacks: ''expand,request'', ''expanded'', ''contract,request'', and
|
||||
''contracted''. Like any smart callback, they are registered through
|
||||
''evas_object_smat_callback_add'' on the genlist object:
|
||||
|
||||
|
||||
<code c>
|
||||
evas_object_smart_callback_add(list, "expand,request",
|
||||
_tree_item_expand_request, _itc_parent);
|
||||
evas_object_smart_callback_add(list, "expanded", _tree_item_expanded,
|
||||
_itc_child);
|
||||
|
||||
evas_object_smart_callback_add(list, "contract,request",
|
||||
_tree_item_contract_request, _itc_child);
|
||||
evas_object_smart_callback_add(list, "contracted", _tree_item_contracted,
|
||||
NULL);
|
||||
</code>
|
||||
|
||||
The callbacks ''expand,request'' and ''contract,request'' do only one thing:
|
||||
decide whether the element is expanded or contracted. This is done by using
|
||||
''elm_genlist_item_expanded_set()'' function; if it changes the expansion
|
||||
status of the item, the next callback is called (either ''expanded'' or
|
||||
''contracted'' , depending on whether it was an ''expand,request'' or
|
||||
''contract,request'' event). A minimal implementation of these callbacks is
|
||||
therefore:
|
||||
|
||||
<code c>
|
||||
static void
|
||||
_tree_item_expand_request(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_item_class_update(it, data);
|
||||
|
||||
elm_genlist_item_expanded_set(it, EINA_TRUE);
|
||||
}
|
||||
</code>
|
||||
|
||||
<note>
|
||||
The example above has an extra line: the call to ''elm_genlist_item_item_class_update()''. It changes the item style and is explained in the [[/tutorial/genlist/modifications#Using_Other_APIs|Changing the item class of an item after its creation section]].^
|
||||
</note>
|
||||
|
||||
<code c>
|
||||
static void
|
||||
_tree_item_contract_request(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_item_class_update(it, data);
|
||||
|
||||
elm_genlist_item_expanded_set(it, EINA_FALSE);
|
||||
}
|
||||
</code>
|
||||
|
||||
As said above, once the genlist item status is set to ''expanded'', the
|
||||
expanded event is triggered and it is the duty of a callback for that event to
|
||||
populate the list with the item's children. This relies on the ''parent''
|
||||
parameter of functions like ''elm_genlist_item_append()'', like for the group
|
||||
mode.
|
||||
|
||||
The function below is a callback implementation for the ''expanded'' event. It
|
||||
adds items that are built similarly to previous items, the only change is the
|
||||
parent parameter which is not NULL. Conveniently, the
|
||||
parent''Elm_Object_Item'' and ''Elm_Genlist_Item_Class'' pointers that are passed to the
|
||||
''elm_genlist_item_append()'' function are given in the ''event_info'' and
|
||||
''data'' callback and need to be cast.
|
||||
|
||||
<code c>
|
||||
static void
|
||||
_tree_item_expanded(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it_parent = (Elm_Object_Item*) event_info;
|
||||
int i_parent = (int)(uintptr_t)elm_object_item_data_get(it_parent);
|
||||
Elm_Object_Item *list = o;
|
||||
Elm_Genlist_Item_Class *itc = data;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
elm_genlist_item_append(list, itc,
|
||||
(void *)(uintptr_t) (i + i_parent),
|
||||
it_parent,
|
||||
ELM_GENLIST_ITEM_NONE,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
The following code has the callback function for the ''contracted'' event. It
|
||||
imply calls ''elm_genlist_item_subitems_clear()'' to clear all children (including
|
||||
their own children if they have any) of the given item. Again, the item that
|
||||
is being contracted is available through the ''event_info'' parameter to the
|
||||
callback.
|
||||
|
||||
<code c>
|
||||
static void
|
||||
_tree_item_contracted(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it_parent = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_subitems_clear(it_parent);
|
||||
}
|
||||
</code>
|
||||
|
||||
//**__Mixing Group and Tree Modes__**//
|
||||
|
||||
A common UI design is to mix group and tree modes. It allows for a tree
|
||||
behavior while also keeping the group header item. The EFLs do not do any
|
||||
magic here and the way to get such a behavior is to create an item of type
|
||||
group, an item of type tree which parent is the group item. Then add the
|
||||
callbacks to populate the children of the tree item in the regular way.
|
||||
|
||||
=== Using Other APIs ===
|
||||
|
||||
//**__Homogeneous Item Size__**//
|
||||
|
||||
Because of the scroller, the actual height and/or width of the genlist must be
|
||||
computed. This means summing the sizes of all the items, the sizes must be
|
||||
computed. This obviously has a cost and slows down adding items to the
|
||||
genlist.
|
||||
|
||||
The ''elm_genlist_homogeneous_set()'' function alleviates this issue by
|
||||
assuming all the items are the same size as the first one of the list. It
|
||||
speeds up large insertions. However, it may lead to serious graphical issues
|
||||
if the items are not actually the same size. Use with care.
|
||||
|
||||
//**__Changing the Item Class of an Item After Its Creation__**//
|
||||
|
||||
Changing the item class of a widget is an easy way to change the appearance
|
||||
upon selection or others actions of the user. This is done by calling
|
||||
''elm_genlist_item_class_update()'' :
|
||||
|
||||
<code c>
|
||||
static void
|
||||
_tree_item_expand_request(void *data, Evas_Object *o, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it = (Elm_Object_Item*) event_info;
|
||||
|
||||
elm_genlist_item_item_class_update(it, data);
|
||||
|
||||
elm_genlist_item_expanded_set(it, EINA_TRUE);
|
||||
}
|
||||
</code>
|
||||
\\
|
||||
//**__The whole code__**// : {{/code_c/tutorial/genlist/modifications_genlist.c}}
|
|
@ -0,0 +1,229 @@
|
|||
~~Title: Genlist Set-up~~
|
||||
==== Genlist Set-up ====
|
||||
|
||||
=== Creating a Genlist ===
|
||||
|
||||
Call ''elm_genlist_add()'' to create a genlist. Then, new entries can be added.
|
||||
In this example, the basic windows is created first, then a genlist is added
|
||||
to it, and then 100 elements with text and a colored block on each side of
|
||||
it.
|
||||
|
||||
<code c>
|
||||
Evas_Object *list = elm_genlist_add(win);
|
||||
</code>
|
||||
|
||||
=== Adding New Entries ===
|
||||
|
||||
Before adding new entries, it is necessary to build a basic item class.
|
||||
|
||||
//**__Building a Basic Item Class__**//
|
||||
|
||||
When adding an item, genlist_item_{append, prepend, insert} function needs
|
||||
item class of the item. Given callback parameters are used at retrieving
|
||||
{text, content} of added item. Set as NULL if it's not used. If there's no
|
||||
available memory, return can be NULL.
|
||||
|
||||
The code for the minimal genlist item class is below:
|
||||
|
||||
<code c>
|
||||
Elm_Genlist_Item_Class *_itc = elm_genlist_item_class_new();
|
||||
_itc->item_style = "default";
|
||||
_itc->func.text_get = NULL;
|
||||
_itc->func.content_get = NULL;
|
||||
_itc->func.state_get = NULL;
|
||||
_itc->func.del = NULL;
|
||||
</code>
|
||||
|
||||
It creates a simple item class, sets the ''item_style'' to "default" and
|
||||
every other field to NULL. However, this leaves out the ''text_get'' and
|
||||
''content_get'' fields which are used to add text and an icon to the list
|
||||
entry. This is explained in another section.
|
||||
|
||||
//**__Adding the Element__**//
|
||||
|
||||
Once the genlist item class object is created, a new element is added to the
|
||||
list by calling ''elm_genlist_item_append()''.
|
||||
|
||||
<code c>
|
||||
elm_genlist_item_append(list,
|
||||
_itc,
|
||||
NULL, // Item data
|
||||
NULL, // Parent item for trees, NULL if none
|
||||
ELM_GENLIST_ITEM_NONE, // Item type; this is the common one
|
||||
NULL, // Callback on selection of the item
|
||||
NULL // Data for that callback function
|
||||
);
|
||||
</code>
|
||||
|
||||
With most parameters as NULL and ''_itc'' having most of its members NULL,
|
||||
too, the elements of that list are blank and will not trigger anything when
|
||||
selected.
|
||||
|
||||
//**__Text in the List Elements__**//
|
||||
|
||||
Use ''text_get'' field to add text in the items in the
|
||||
''Elm_Genlist_Item_Class'' structure.
|
||||
|
||||
<code c>
|
||||
_itc->func.text_get = text_get;
|
||||
</code>
|
||||
|
||||
These callbacks must have a prototype matching to the following:
|
||||
|
||||
<code c>
|
||||
char * text_get(void *data, Evas_Object *obj, const char *part);
|
||||
</code>
|
||||
|
||||
This callback returns a C string that is displayed in the part named after the
|
||||
''part'' parameter. This callback is called for each user-settable text part
|
||||
according to the current theme.
|
||||
|
||||
If you are not familiar with the concept of parts in the EFLs, read
|
||||
[[/coming_soon|the Write a Simple EDC File]] section.
|
||||
|
||||
<note>
|
||||
The value returned is freed by the EFLs: the value must be freshly-allocated, do not free it yourself and do not re-use it across list elements.
|
||||
</note>
|
||||
|
||||
For the default theme there is one part named ''elm.text''. A possible
|
||||
implementation of the ''text_get'' callback is therefore:
|
||||
|
||||
<code c>
|
||||
static char *
|
||||
_genlist_text_get(void *data, Evas_Object *obj, const char *part)
|
||||
{
|
||||
// Check this is text for the part we're expecting
|
||||
if (strcmp(part, "elm.text") == 0)
|
||||
{
|
||||
return strdup("Some text");
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
</code>
|
||||
|
||||
<note>
|
||||
The names and positions of parts depends on the item_style chosen when adding new items to the genlist. Setting a custom theme makes it possible to completely change genlists by adding and moving parts. The [[/coming_soon|Edje]] guide explains how to do that.
|
||||
</note>
|
||||
|
||||
It is possible to behave differently according to data
|
||||
that is given to the EFLs during the call to ''elm_genlist_item_append()'' in the
|
||||
''data'' parameter. For example, given an integer in that field through casting
|
||||
with ''(void *)(uintptr_t) i'', its value is got back using
|
||||
''(int)(uintptr_t)data'':
|
||||
|
||||
<code c>
|
||||
static char *
|
||||
_genlist_text_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
|
||||
{
|
||||
if (strcmp(part, "elm.text") == 0)
|
||||
{
|
||||
char *buf = malloc(16);
|
||||
snprintf(buf, 16, "Entry %d.", (int)(uintptr_t)data);
|
||||
|
||||
return buf;
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
</code>
|
||||
|
||||
//**__Evas_Object in the List Elements__**//
|
||||
|
||||
Icons are added in a similar fashion: there is a callback named
|
||||
''content_get'' which returns a pointer to an ''Evas_Object'' and is called
|
||||
for each part which contents can be set.
|
||||
|
||||
<code c>
|
||||
_itc->func.content_get = content_get;
|
||||
</code>
|
||||
|
||||
The prototype of the callback must match this one:
|
||||
|
||||
<code c>
|
||||
Evas_Object * content_get(void *data, Evas_Object *obj, const char *part);
|
||||
</code>
|
||||
|
||||
The only difference with the ''text_get'' callback is that it returns an
|
||||
''Evas_Object*'' rather than a ''char *''.
|
||||
|
||||
This leads to a fairly simple dummy implementation with colored rectangles in
|
||||
the parts that are to be set:
|
||||
|
||||
<code c>
|
||||
static Evas_Object *
|
||||
_genlist_content_get(void *data, Evas_Object *obj, const char *part)
|
||||
{
|
||||
int i = (int) (uintptr_t) data;
|
||||
|
||||
//the left part
|
||||
if (strcmp(part, "elm.swallow.icon") == 0)
|
||||
{
|
||||
Evas_Object *bg = elm_bg_add(obj);
|
||||
elm_bg_color_set(bg, 255 * cos(i / (double) 10), 0, i % 255);
|
||||
|
||||
return bg;
|
||||
}
|
||||
//the right part
|
||||
else if (strcmp(part, "elm.swallow.end") == 0)
|
||||
{
|
||||
Evas_Object *bg = elm_bg_add(obj);
|
||||
elm_bg_color_set(bg, 0, 255 * sin(i / (double) 10), i % 255);
|
||||
|
||||
return bg;
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
</code>
|
||||
|
||||
For the default theme, this displays a red rectangle on the left of each list
|
||||
item and a green one on their right.
|
||||
|
||||
//**__Event on Gentlist Items__**//
|
||||
|
||||
Genlist items triggers a callback when clicked. This callback is chosen when
|
||||
adding the new item (for example, when calling ''elm_genlist_item_append()''):
|
||||
|
||||
<code c>
|
||||
Elm_Genlist_Item_Class *_itc2 = elm_genlist_item_class_new();
|
||||
_itc2->item_style = "group_index";
|
||||
_itc2->func.text_get = _genlist_text_get;
|
||||
_itc2->func.content_get = _genlist_content_get;
|
||||
_itc2->func.state_get = NULL;
|
||||
_itc2->func.del = NULL;
|
||||
|
||||
elm_genlist_item_append(list,
|
||||
itc,
|
||||
NULL, // item data
|
||||
NULL, // parent item for trees, NULL if none
|
||||
ELM_GENLIST_ITEM_NONE, // item type, other values are used for trees
|
||||
_genlist_selected_cb, // callback on selection of the item
|
||||
_itc2 // data for that callback function
|
||||
);
|
||||
</code>
|
||||
|
||||
This callback adheres to the following prototype:
|
||||
|
||||
<code c>
|
||||
void _contact_selected_cb(void *data, Evas_Object *obj, void *event_info)
|
||||
</code>
|
||||
|
||||
The implementation below changes the item style of items when they are
|
||||
selected:
|
||||
|
||||
<code c>
|
||||
static void
|
||||
_genlist_selected_cb(void *data, Evas_Object *obj, void *event_info)
|
||||
{
|
||||
Elm_Object_Item *it = (Elm_Object_Item*) event_info;
|
||||
Elm_Genlist_Item_Class *itc2 = (Elm_Genlist_Item_Class *)data;
|
||||
te
|
||||
|
||||
//change to group index style
|
||||
elm_genlist_item_item_class_update(it, itc2);
|
||||
}
|
||||
</code>
|
||||
\\
|
||||
//**__The whole code__**// : {{/code_c/tutorial/genlist/set-up_genlist.c}}
|
||||
|
||||
==== Next Part ====
|
||||
|
||||
[[/tutorial/genlist/modifications|Modifications]]
|
|
@ -0,0 +1,43 @@
|
|||
~~Title: Genlist Tutorial~~
|
||||
==== Genlist Tutorial ====
|
||||
|
||||
This tutorial deals with Elementary genlist, a list widget for large sets of
|
||||
elements. Its API to populate entries reflects that as it uses callbacks.
|
||||
|
||||
Also keep in mind that the same widget handles both flat lists and trees and
|
||||
this is obviously seen in the API.
|
||||
|
||||
=== Initialize the Application ===
|
||||
|
||||
The code below shows a typical Elementary application that creates a window
|
||||
entitled "Genlist Basic Tutorial". The genlist goes inside.
|
||||
|
||||
<code c>
|
||||
#include <Elementary.h>
|
||||
|
||||
EAPI_MAIN int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
Evas_Object *win;
|
||||
|
||||
win = elm_win_util_standard_add("Genlist", "Genlist Basic Tutorial");
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
||||
elm_win_autodel_set(win, EINA_TRUE);
|
||||
//win 400x400 px
|
||||
evas_object_resize(win, 400, 400);
|
||||
|
||||
//GENLIST here
|
||||
|
||||
evas_object_show(win);
|
||||
elm_run();
|
||||
return 0;
|
||||
}
|
||||
ELM_MAIN()
|
||||
</code>
|
||||
|
||||
Genlist example :{{ :genlist.png?direct |list}}
|
||||
|
||||
=== Table of contents ===
|
||||
|
||||
* [[/tutorial/genlist/set-up|Set-up]] : {{/code_c/tutorial/genlist/set-up_genlist.c}}
|
||||
* [[/tutorial/genlist/modifications|Modifications]] : {{/code_c/tutorial/genlist/modifications_genlist.c}}
|
Loading…
Reference in New Issue