
\begin{DoxyCodeInclude}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{//gcc -g genlist\_example\_05.c -o genlist\_example\_05 `pkg-config --cflags --libs elementary`}

\textcolor{preprocessor}{#include <Elementary.h>}

\textcolor{preprocessor}{#define N\_ITEMS 6}

\textcolor{keyword}{typedef} \textcolor{keyword}{struct }\_Node\_Data \{
     Eina\_List *children;
     \textcolor{keywordtype}{int} value;
     \textcolor{keywordtype}{int} level;
     Eina\_Bool favorite;
\} Node\_Data;

\textcolor{keyword}{static} Elm_Genlist_Item_Class *\_itc = NULL;
\textcolor{keyword}{static} Elm_Genlist_Item_Class *\_itp = NULL;
\textcolor{keyword}{static} Elm_Genlist_Item_Class *\_itfav = NULL;
\textcolor{keyword}{static} \textcolor{keywordtype}{int} nitems = 0;

\textcolor{keyword}{static} \textcolor{keywordtype}{char} *
\_item\_label\_get(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *part)
\{
   \textcolor{keywordtype}{char} buf[256] = \{0\};
   Node\_Data *d = data;

   \textcolor{keywordflow}{if} (!strcmp(part, \textcolor{stringliteral}{"elm.text"}))
     snprintf(buf, \textcolor{keyword}{sizeof}(buf), \textcolor{stringliteral}{"Item # %i (level %i)"}, d->value, d->level);

   \textcolor{keywordflow}{return} strdup(buf);
\}

\textcolor{keyword}{static} Evas\_Object *
\_item\_content\_get(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *part)
\{
   Evas\_Object *ic = elm_icon_add(obj);

   \textcolor{keywordflow}{if} (!strcmp(part, \textcolor{stringliteral}{"elm.swallow.icon"}))
     elm\_icon\_standard\_set(ic, \textcolor{stringliteral}{"file"});

   evas\_object\_size\_hint\_aspect\_set(ic, EVAS\_ASPECT\_CONTROL\_VERTICAL, 1, 1);
   \textcolor{keywordflow}{return} ic;
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_item\_sel\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keywordtype}{void} *event\_info)
\{
   printf(\textcolor{stringliteral}{"sel item data [%p] on genlist obj [%p], item pointer [%p]\(\backslash\)n"},
          data, obj, event\_info);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{char} *
\_parent\_label\_get(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *part)
\{
   \textcolor{keywordtype}{char} buf[256];
   Node\_Data *d = data;

   snprintf(buf, \textcolor{keyword}{sizeof}(buf), \textcolor{stringliteral}{"Group %d (%d items)"}, d->value / 7,
            eina\_list\_count(d->children));

   \textcolor{keywordflow}{return} strdup(buf);
\}

\textcolor{keyword}{static} Evas\_Object *
\_parent\_content\_get(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *part)
\{
   Evas\_Object *ic = elm_icon_add(obj);

   \textcolor{keywordflow}{if} (!strcmp(part, \textcolor{stringliteral}{"elm.swallow.icon"}))
     elm\_icon\_standard\_set(ic, \textcolor{stringliteral}{"folder"});

   evas\_object\_size\_hint\_aspect\_set(ic, EVAS\_ASPECT\_CONTROL\_VERTICAL, 1, 1);
   \textcolor{keywordflow}{return} ic;
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{char} *
\_favorite\_label\_get(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *part)
\{
   \textcolor{keywordtype}{char} buf[256] = \{0\};
   Node\_Data *d = data;

   \textcolor{keywordflow}{if} (!strcmp(part, \textcolor{stringliteral}{"elm.text"}))
     snprintf(buf, \textcolor{keyword}{sizeof}(buf), \textcolor{stringliteral}{"Favorite # %i"}, d->value);

   \textcolor{keywordflow}{return} strdup(buf);
\}

\textcolor{keyword}{static} Evas\_Object *
\_favorite\_content\_get(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *part)
\{
   Evas\_Object *ic = elm_icon_add(obj);

   \textcolor{keywordflow}{if} (!strcmp(part, \textcolor{stringliteral}{"elm.swallow.icon"}))
     elm\_icon\_standard\_set(ic, \textcolor{stringliteral}{"apps"});

   evas\_object\_size\_hint\_aspect\_set(ic, EVAS\_ASPECT\_CONTROL\_VERTICAL, 1, 1);
   \textcolor{keywordflow}{return} ic;
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_append\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{void} *event\_info)
\{
   Evas\_Object *list = data;
   Elm_Object_Item *glit, *parent = NULL;
   Node\_Data *pdata, *d = malloc(\textcolor{keyword}{sizeof}(*d));

   d->children = NULL;
   d->value = nitems++;
   d->favorite = EINA\_FALSE;

   glit = elm\_genlist\_selected\_item\_get(list);
   \textcolor{keywordflow}{if} (glit)
     parent = elm\_genlist\_item\_parent\_get(glit);

   \textcolor{keywordflow}{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);
     \}
   \textcolor{keywordflow}{else}
     d->level = 0;

   elm\_genlist\_item\_append(list, \_itc,
                           d, parent,
                           ELM\_GENLIST\_ITEM\_NONE,
                           \_item\_sel\_cb, NULL);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_favorite\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{void} *event\_info)
\{
   Evas\_Object *list = data;
   Elm_Object_Item *glit = elm\_genlist\_selected\_item\_get(list);

   \textcolor{keywordflow}{if} (!glit) \textcolor{keywordflow}{return};

   Node\_Data *d = elm_object_item_data_get(glit);
   d->favorite = !d->favorite;
   \textcolor{keywordflow}{if} (d->favorite)
     elm\_genlist\_item\_item\_class\_update(glit, \_itfav);
   \textcolor{keywordflow}{else}
     \{
        \textcolor{keywordflow}{if} (d->children)
          elm\_genlist\_item\_item\_class\_update(glit, \_itp);
        \textcolor{keywordflow}{else}
          elm\_genlist\_item\_item\_class\_update(glit, \_itc);
     \}

   elm\_genlist\_item\_update(glit);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_add\_child\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{void} *event\_info)
\{
   Evas\_Object *list = data;
   Elm_Object_Item *glit = elm\_genlist\_selected\_item\_get(list);
   Elm_Object_Item *glit\_prev, *glit\_parent;

   \textcolor{keywordflow}{if} (!glit) \textcolor{keywordflow}{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;

   \textcolor{comment}{// creating new item data}
   Node\_Data *ndata = malloc(\textcolor{keyword}{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);

   \textcolor{comment}{// Changing leaf item to parent item}
   \textcolor{keywordflow}{if} (change\_item)
     \{
        elm\_object\_item\_del(glit);

        \textcolor{keywordflow}{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);
        \textcolor{keywordflow}{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);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{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);

\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_clear\_list(Node\_Data *d)
\{
   Node\_Data *tmp;

   EINA\_LIST\_FREE(d->children, tmp)
      \_clear\_list(tmp);
   free(d);
\}

static \textcolor{keywordtype}{void}
\_del\_item\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{void} *event\_info)
\{
   Evas\_Object *list = data;
   Elm_Object_Item *glit = elm\_genlist\_selected\_item\_get(list);
   Elm_Object_Item *glit\_parent = NULL;

   \textcolor{keywordflow}{if} (!glit) \textcolor{keywordflow}{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);

   \textcolor{keywordflow}{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);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_expand\_request\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{void} *event\_info)
\{
   Elm_Object_Item *glit = event\_info;
   printf(\textcolor{stringliteral}{"expand request on item: %p\(\backslash\)n"}, event\_info);
   elm\_genlist\_item\_expanded\_set(glit, EINA\_TRUE);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_contract\_request\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{void} *event\_info)
\{
   Elm_Object_Item *glit = event\_info;
   printf(\textcolor{stringliteral}{"contract request on item: %p\(\backslash\)n"}, event\_info);
   elm\_genlist\_item\_expanded\_set(glit, EINA\_FALSE);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_expanded\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{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(\textcolor{stringliteral}{"expanding item: #%d from parent #%d\(\backslash\)n"}, it\_data->value, d->value);
        \textcolor{keywordflow}{if} (it\_data->favorite)
          ic = \_itfav;
        \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (it\_data->children)
          \{
             ic = \_itp;
             type = ELM\_GENLIST\_ITEM\_TREE;
          \}
        \textcolor{keywordflow}{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);
     \}
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_contracted\_cb(\textcolor{keywordtype}{void} *data, Evas\_Object *o, \textcolor{keywordtype}{void} *event\_info)
\{
   Elm_Object_Item *glit = event\_info;
   elm\_genlist\_item\_subitems\_clear(glit);
\}

\textcolor{keyword}{static} Evas\_Object *
\_button\_add(Evas\_Object *list, Evas\_Object *box, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *label, Evas\_Smart\_Cb cb)
\{
   Evas\_Object *bt;

   bt = elm_button_add(elm_object_parent_widget_get(list));
   elm\_object\_text\_set(bt, label);
   elm\_box\_pack\_end(box, bt);
   evas\_object\_show(bt);

   \textcolor{keywordflow}{if} (cb)
     evas\_object\_smart\_callback\_add(bt, \textcolor{stringliteral}{"clicked"}, cb, list);

   \textcolor{keywordflow}{return} bt;
\}

EAPI\_MAIN \textcolor{keywordtype}{int}
elm\_main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
   Evas\_Object *win, *box, *fbox;
   Evas\_Object *list;
   \textcolor{keywordtype}{int} i;

   win = elm_win_util_standard_add(\textcolor{stringliteral}{"genlist"}, \textcolor{stringliteral}{"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);

   \textcolor{keywordflow}{if} (!\_itc)
     \{
        \_itc = elm_genlist_item_class_new();
        \_itc->item\_style = \textcolor{stringliteral}{"default"};
        \_itc->func.text\_get = \_item\_label\_get;
        \_itc->func.content\_get = \_item\_content\_get;
        \_itc->func.state\_get = NULL;
        \_itc->func.del = NULL;
     \}

   \textcolor{keywordflow}{if} (!\_itp)
     \{
        \_itp = elm_genlist_item_class_new();
        \_itp->item\_style = \textcolor{stringliteral}{"default"};
        \_itp->func.text\_get = \_parent\_label\_get;
        \_itp->func.content\_get = \_parent\_content\_get;
        \_itp->func.state\_get = NULL;
        \_itp->func.del = NULL;
     \}

   \textcolor{keywordflow}{if} (!\_itfav)
     \{
        \_itfav = elm_genlist_item_class_new();
        \_itfav->item\_style = \textcolor{stringliteral}{"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, \textcolor{stringliteral}{"append item"}, \_append\_cb);
   \_button\_add(list, fbox, \textcolor{stringliteral}{"favorite"}, \_favorite\_cb);
   \_button\_add(list, fbox, \textcolor{stringliteral}{"add child"}, \_add\_child\_cb);
   \_button\_add(list, fbox, \textcolor{stringliteral}{"del item"}, \_del\_item\_cb);


   Node\_Data *pdata = NULL; \textcolor{comment}{// data for the parent of the group}
   Elm_Object_Item *glg = NULL;
   \textcolor{keywordflow}{for} (i = 0; i < N\_ITEMS; i++)
     \{
        Elm_Object_Item *gli = NULL;
        Node\_Data *data = malloc(\textcolor{keyword}{sizeof}(*data)); \textcolor{comment}{// data for this item}
        data->children = NULL;
        data->value = i;
        data->favorite = EINA\_FALSE;
        nitems++;

        printf(\textcolor{stringliteral}{"creating item: #%d\(\backslash\)n"}, data->value);
        \textcolor{keywordflow}{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;
          \}
        \textcolor{keywordflow}{else}
          \{
             gli = elm\_genlist\_item\_append(list, \_itc, data, glg,
                                           ELM\_GENLIST\_ITEM\_NONE,
                                           \_item\_sel\_cb, NULL);
             \textcolor{keywordflow}{if} (pdata)
               pdata->children = eina\_list\_append(pdata->children, data);
             data->level = 1;
          \}
     \}

   evas\_object\_smart\_callback\_add(list, \textcolor{stringliteral}{"expand,request"}, \_expand\_request\_cb, list);
   evas\_object\_smart\_callback\_add(list, \textcolor{stringliteral}{"contract,request"}, \_contract\_request\_cb, list);
   evas\_object\_smart\_callback\_add(list, \textcolor{stringliteral}{"expanded"}, \_expanded\_cb, list);
   evas\_object\_smart\_callback\_add(list, \textcolor{stringliteral}{"contracted"}, \_contracted\_cb, list);

   evas\_object\_resize(win, 420, 600);
   evas\_object\_show(win);

   elm_run();

   \textcolor{keywordflow}{return} 0;
\}
ELM_MAIN()
\end{DoxyCodeInclude}
 