236242aa6db77c185d859522620513f3898fbadc
[framework/uifw/elementary.git] / src / examples / genlist_example_05.c
1 //Compile with:
2 //gcc -g `pkg-config --cflags --libs elementary` genlist_example_04.c -o genlist_example_04
3
4 #include <Elementary.h>
5 #ifdef HAVE_CONFIG_H
6 # include "elementary_config.h"
7 #else
8 # define __UNUSED__
9 #endif
10
11 #define N_ITEMS 6
12
13 typedef struct _Node_Data {
14      Eina_List *children;
15      int value;
16      int level;
17      Eina_Bool favorite;
18 } Node_Data;
19
20 static Elm_Genlist_Item_Class *_itc = NULL;
21 static Elm_Genlist_Item_Class *_itp = NULL;
22 static Elm_Genlist_Item_Class *_itfav = NULL;
23 static int nitems = 0;
24
25 static char *
26 _item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
27 {
28    char buf[256];
29    Node_Data *d = data;
30
31    if (!strcmp(part, "elm.text"))
32      snprintf(buf, sizeof(buf), "Item # %i (level %i)", d->value, d->level);
33
34    return strdup(buf);
35 }
36
37 static Evas_Object *
38 _item_content_get(void *data __UNUSED__, Evas_Object *obj, const char *part)
39 {
40    Evas_Object *ic = elm_icon_add(obj);
41
42    if (!strcmp(part, "elm.swallow.icon"))
43      elm_icon_standard_set(ic, "file");
44
45    evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
46    return ic;
47 }
48
49 static void
50 _item_sel_cb(void *data, Evas_Object *obj, void *event_info)
51 {
52    printf("sel item data [%p] on genlist obj [%p], item pointer [%p]\n",
53           data, obj, event_info);
54 }
55
56 static char *
57 _parent_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part __UNUSED__)
58 {
59    char buf[256];
60    Node_Data *d = data;
61
62    snprintf(buf, sizeof(buf), "Group %d (%d items)", d->value / 7,
63             eina_list_count(d->children));
64
65    return strdup(buf);
66 }
67
68 static Evas_Object *
69 _parent_content_get(void *data __UNUSED__, Evas_Object *obj, const char *part __UNUSED__)
70 {
71    Evas_Object *ic = elm_icon_add(obj);
72
73    if (!strcmp(part, "elm.swallow.icon"))
74      elm_icon_standard_set(ic, "folder");
75
76    evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
77    return ic;
78 }
79
80 static char *
81 _favorite_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
82 {
83    char buf[256];
84    Node_Data *d = data;
85
86    if (!strcmp(part, "elm.text"))
87      snprintf(buf, sizeof(buf), "Favorite # %i", d->value);
88
89    return strdup(buf);
90 }
91
92 static Evas_Object *
93 _favorite_content_get(void *data __UNUSED__, Evas_Object *obj, const char *part)
94 {
95    Evas_Object *ic = elm_icon_add(obj);
96
97    if (!strcmp(part, "elm.swallow.icon"))
98      elm_icon_standard_set(ic, "apps");
99
100    evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
101    return ic;
102 }
103
104 static void
105 _append_cb(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
106 {
107    Evas_Object *list = data;
108    Elm_Object_Item *glit, *parent = NULL;
109    Node_Data *pdata, *d = malloc(sizeof(*d));
110
111    d->children = NULL;
112    d->value = nitems++;
113    d->favorite = EINA_FALSE;
114
115    glit = elm_genlist_selected_item_get(list);
116    if (glit)
117      parent = elm_genlist_item_parent_get(glit);
118
119    if (parent)
120      {
121         d->level = elm_genlist_item_expanded_depth_get(parent) + 1;
122         pdata = elm_object_item_data_get(parent);
123         pdata->children = eina_list_append(pdata->children, d);
124      }
125    else
126      d->level = 0;
127
128    elm_genlist_item_append(list, _itc,
129                            d, parent,
130                            ELM_GENLIST_ITEM_NONE,
131                            _item_sel_cb, NULL);
132 }
133
134 static void
135 _favorite_cb(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
136 {
137    Evas_Object *list = data;
138    Elm_Object_Item *glit = elm_genlist_selected_item_get(list);
139
140    if (!glit) return;
141
142    Node_Data *d = elm_object_item_data_get(glit);
143    d->favorite = !d->favorite;
144    if (d->favorite)
145      elm_genlist_item_item_class_update(glit, _itfav);
146    else
147      {
148         if (d->children)
149           elm_genlist_item_item_class_update(glit, _itp);
150         else
151           elm_genlist_item_item_class_update(glit, _itc);
152      }
153
154    elm_genlist_item_update(glit);
155 }
156
157 static void
158 _add_child_cb(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
159 {
160    Evas_Object *list = data;
161    Elm_Object_Item *glit = elm_genlist_selected_item_get(list);
162    Elm_Object_Item *glit_prev, *glit_parent;
163
164    if (!glit) return;
165
166    Node_Data *d = elm_object_item_data_get(glit);
167    glit_prev = elm_genlist_item_prev_get(glit);
168    glit_parent = elm_genlist_item_parent_get(glit);
169
170    Eina_Bool change_item = !d->children;
171
172    // creating new item data
173    Node_Data *ndata = malloc(sizeof(*ndata));
174    ndata->value = nitems++;
175    ndata->children = NULL;
176    ndata->favorite = EINA_FALSE;
177    ndata->level = elm_genlist_item_expanded_depth_get(glit) + 1;
178    d->children = eina_list_append(d->children, ndata);
179
180    // Changing leaf item to parent item
181    if (change_item)
182      {
183         elm_object_item_del(glit);
184
185         if (glit_prev != glit_parent)
186           glit = elm_genlist_item_insert_after(list, _itp, d, glit_parent,
187                                                glit_prev,
188                                                ELM_GENLIST_ITEM_SUBITEMS,
189                                                _item_sel_cb, NULL);
190         else
191           glit = elm_genlist_item_prepend(list, _itp, d, glit_parent,
192                                           ELM_GENLIST_ITEM_SUBITEMS,
193                                           _item_sel_cb, NULL);
194         elm_genlist_item_expanded_set(glit, EINA_FALSE);
195         elm_genlist_item_selected_set(glit, EINA_TRUE);
196      }
197    else if (elm_genlist_item_expanded_get(glit))
198      {
199         elm_genlist_item_append(list, _itc, ndata, glit,
200                                 ELM_GENLIST_ITEM_NONE, _item_sel_cb, NULL);
201      }
202
203    elm_genlist_item_update(glit);
204
205 }
206
207 static void
208 _clear_list(Node_Data *d)
209 {
210    Node_Data *tmp;
211
212    EINA_LIST_FREE(d->children, tmp)
213       _clear_list(tmp);
214    free(d);
215 }
216
217 static void
218 _del_item_cb(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
219 {
220    Evas_Object *list = data;
221    Elm_Object_Item *glit = elm_genlist_selected_item_get(list);
222    Elm_Object_Item *glit_parent = NULL;
223
224    if (!glit) return;
225
226    Node_Data *pdata, *d = elm_object_item_data_get(glit);
227    glit_parent = elm_genlist_item_parent_get(glit);
228    elm_genlist_item_subitems_clear(glit);
229    elm_object_item_del(glit);
230
231    _clear_list(d);
232
233    if (!glit_parent) return;
234
235    pdata = elm_object_item_data_get(glit_parent);
236    pdata->children = eina_list_remove(pdata->children, d);
237    elm_genlist_item_update(glit_parent);
238 }
239
240 static void
241 _expand_request_cb(void *data __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
242 {
243    Elm_Object_Item *glit = event_info;
244    printf("expand request on item: %p\n", event_info);
245    elm_genlist_item_expanded_set(glit, EINA_TRUE);
246 }
247
248 static void
249 _contract_request_cb(void *data __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
250 {
251    Elm_Object_Item *glit = event_info;
252    printf("contract request on item: %p\n", event_info);
253    elm_genlist_item_expanded_set(glit, EINA_FALSE);
254 }
255
256 static void
257 _expanded_cb(void *data __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
258 {
259    Eina_List *l;
260    Elm_Object_Item *glit = event_info;
261    Node_Data *it_data, *d = elm_object_item_data_get(glit);
262    Evas_Object *list = elm_object_item_widget_get(glit);
263
264    Elm_Genlist_Item_Class *ic;
265
266    EINA_LIST_FOREACH(d->children, l, it_data)
267      {
268         Elm_Object_Item *nitem;
269         Elm_Genlist_Item_Type type = ELM_GENLIST_ITEM_NONE;
270         printf("expanding item: #%d from parent #%d\n", it_data->value, d->value);
271         if (it_data->favorite)
272           ic = _itfav;
273         else if (it_data->children)
274           {
275              ic = _itp;
276              type = ELM_GENLIST_ITEM_SUBITEMS;
277           }
278         else
279           ic = _itc;
280
281         nitem = elm_genlist_item_append(list, ic, it_data, glit,
282                                         type, _item_sel_cb, NULL);
283         elm_genlist_item_expanded_set(nitem, EINA_FALSE);
284      }
285 }
286
287 static void
288 _contracted_cb(void *data __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
289 {
290    Elm_Object_Item *glit = event_info;
291    elm_genlist_item_subitems_clear(glit);
292 }
293
294 static Evas_Object *
295 _button_add(Evas_Object *list, Evas_Object *box, const char *label, Evas_Smart_Cb cb)
296 {
297    Evas_Object *bt;
298
299    bt = elm_button_add(elm_object_parent_widget_get(list));
300    elm_object_text_set(bt, label);
301    elm_box_pack_end(box, bt);
302    evas_object_show(bt);
303
304    if (cb)
305      evas_object_smart_callback_add(bt, "clicked", cb, list);
306
307    return bt;
308 }
309
310 int
311 elm_main(int argc __UNUSED__, char **argv __UNUSED__)
312 {
313    Evas_Object *win, *bg, *box, *fbox;
314    Evas_Object *list;
315    int i;
316
317    win = elm_win_add(NULL, "icon", ELM_WIN_BASIC);
318    elm_win_title_set(win, "Icon");
319    elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
320    elm_win_autodel_set(win, EINA_TRUE);
321
322    bg = elm_bg_add(win);
323    elm_bg_color_set(bg, 255,255 ,255);
324    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
325    elm_win_resize_object_add(win, bg);
326    evas_object_show(bg);
327
328    box = elm_box_add(win);
329    evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
330    evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
331    elm_win_resize_object_add(win, box);
332    evas_object_show(box);
333
334    if (!_itc)
335      {
336         _itc = elm_genlist_item_class_new();
337         _itc->item_style = "default";
338         _itc->func.text_get = _item_label_get;
339         _itc->func.content_get = _item_content_get;
340         _itc->func.state_get = NULL;
341         _itc->func.del = NULL;
342      }
343    
344    if (!_itp)
345      {
346         _itp = elm_genlist_item_class_new();
347         _itp->item_style = "default";
348         _itp->func.text_get = _parent_label_get;
349         _itp->func.content_get = _parent_content_get;
350         _itp->func.state_get = NULL;
351         _itp->func.del = NULL;
352      }
353    
354    if (!_itfav)
355      {
356         _itfav = elm_genlist_item_class_new();
357         _itfav->item_style = "default";
358         _itfav->func.text_get = _favorite_label_get;
359         _itfav->func.content_get = _favorite_content_get;
360         _itfav->func.state_get = NULL;
361         _itfav->func.del = NULL;
362      }
363
364    list = elm_genlist_add(win);
365
366    evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
367    evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
368    elm_box_pack_end(box, list);
369    evas_object_show(list);
370
371    fbox = elm_box_add(win);
372    elm_box_layout_set(fbox, evas_object_box_layout_flow_horizontal,
373                       NULL, NULL);
374    evas_object_size_hint_weight_set(fbox, EVAS_HINT_EXPAND, 0);
375    evas_object_size_hint_align_set(fbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
376    elm_box_pack_end(box, fbox);
377    evas_object_show(fbox);
378
379    _button_add(list, fbox, "append item", _append_cb);
380    _button_add(list, fbox, "favorite", _favorite_cb);
381    _button_add(list, fbox, "add child", _add_child_cb);
382    _button_add(list, fbox, "del item", _del_item_cb);
383
384    for (i = 0; i < N_ITEMS; i++)
385      {
386         Elm_Object_Item *gli, *glg;
387         Node_Data *data = malloc(sizeof(*data)); // data for this item
388         data->children = NULL;
389         data->value = i;
390         data->favorite = EINA_FALSE;
391         nitems++;
392
393         Node_Data *pdata; // data for the parent of the group
394
395         printf("creating item: #%d\n", data->value);
396         if (i % 3 == 0)
397           {
398              glg = gli = elm_genlist_item_append(list, _itp, data, NULL,
399                                                  ELM_GENLIST_ITEM_SUBITEMS,
400                                                  _item_sel_cb, NULL);
401              elm_genlist_item_expanded_set(glg, EINA_TRUE);
402              pdata = data;
403              data->level = 0;
404           }
405         else
406           {
407              gli = elm_genlist_item_append(list, _itc, data, glg,
408                                            ELM_GENLIST_ITEM_NONE,
409                                            _item_sel_cb, NULL);
410              pdata->children = eina_list_append(pdata->children, data);
411              data->level = 1;
412           }
413      }
414
415    evas_object_smart_callback_add(list, "expand,request", _expand_request_cb, list);
416    evas_object_smart_callback_add(list, "contract,request", _contract_request_cb, list);
417    evas_object_smart_callback_add(list, "expanded", _expanded_cb, list);
418    evas_object_smart_callback_add(list, "contracted", _contracted_cb, list);
419
420    evas_object_size_hint_min_set(bg, 160, 160);
421    evas_object_size_hint_max_set(bg, 640, 800);
422    evas_object_resize(win, 420, 600);
423    evas_object_show(win);
424
425    elm_run();
426
427    return 0;
428 }
429
430 ELM_MAIN()