elementary/index - Re: [E-devel] [Patch][elementary_test] test_index
[framework/uifw/elementary.git] / src / bin / test_index.c
1 #include <Elementary.h>
2 #include "test.h"
3 #ifdef HAVE_CONFIG_H
4 # include "elementary_config.h"
5 #endif
6 #ifndef ELM_LIB_QUICKLAUNCH
7 struct _Idx_Data_Type
8 {
9    Evas_Object *id;  /* Pointer to Index */
10    Elm_Object_Item *item; /* Item we use for search */
11 };
12 typedef struct _Idx_Data_Type Idx_Data_Type;
13
14 struct _api_data
15 {
16    unsigned int state;  /* What state we are testing       */
17    Idx_Data_Type dt;
18 };
19 typedef struct _api_data api_data;
20
21 struct _pagectrl_data
22 {
23    Evas_Object *index;
24    Evas_Object *sc;
25    Evas_Coord recent_x;
26    Evas_Coord page_width;
27    int page_cnt;
28    Eina_Bool drag_started : 1;
29    Eina_Bool changed : 1;
30 };
31 typedef struct _pagectrl_data pagectrl_data;
32
33 enum _api_state
34 {
35    INDEX_LEVEL_SET,
36    INDEX_ACTIVE_SET,
37    INDEX_APPEND_RELATIVE,
38    INDEX_PREPEND,
39    INDEX_ITEM_DEL,
40    INDEX_ITEM_FIND,
41    INDEX_HORIZONTAL,
42    INDEX_INDICATOR_DISABLED,
43    INDEX_CLEAR,
44    API_STATE_LAST
45 };
46 typedef enum _api_state api_state;
47
48 static void
49 set_api_state(api_data *api)
50 {
51    Idx_Data_Type *d = &api->dt;
52    switch(api->state)
53      { /* Put all api-changes under switch */
54       case INDEX_LEVEL_SET:
55          elm_index_autohide_disabled_set(d->id, EINA_TRUE);
56          elm_index_item_level_set(d->id, (elm_index_item_level_get(d->id) ? 0 : 1));
57          break;
58
59       case INDEX_ACTIVE_SET:
60          elm_index_autohide_disabled_set(d->id, EINA_FALSE);
61          break;
62
63       case INDEX_APPEND_RELATIVE:
64          elm_index_item_insert_after(d->id,
65                                      elm_index_item_find(d->id, d->item),
66                                      "W", NULL, d->item);
67          elm_index_item_insert_before(d->id,
68                                       elm_index_item_find(d->id, d->item),
69                                       "V", NULL, d->item);
70          break;
71
72       case INDEX_PREPEND:
73          elm_index_item_prepend(d->id, "D", NULL, d->item);
74          break;
75
76       case INDEX_ITEM_DEL:
77          elm_object_item_del(elm_index_item_find(d->id, d->item));
78          break;
79
80       case INDEX_ITEM_FIND:
81            {
82               Elm_Object_Item *i = elm_index_item_find(d->id, d->item);
83               if(i)
84                 {
85                    printf("Item Find - Found Item.\n");
86                    elm_object_item_del(i);
87                 }
88            }
89          break;
90
91       case INDEX_HORIZONTAL:
92          elm_index_horizontal_set(d->id, EINA_TRUE);
93          break;
94
95       case INDEX_INDICATOR_DISABLED:
96          elm_index_indicator_disabled_set(d->id, EINA_TRUE);
97          break;
98
99       case INDEX_CLEAR:
100          elm_index_item_clear(d->id);
101          break;
102
103       case API_STATE_LAST:
104          break;
105
106       default:
107          return;
108      }
109 }
110
111 static void
112 _api_bt_clicked(void *data, Evas_Object *obj, void *event_info __UNUSED__)
113 {  /* Will add here a SWITCH command containing code to modify test-object */
114    /* in accordance a->state value. */
115    api_data *a = data;
116    char str[128];
117
118    printf("clicked event on API Button: api_state=<%d>\n", a->state);
119    set_api_state(a);
120    a->state++;
121    sprintf(str, "Next API function (%u)", a->state);
122    elm_object_text_set(obj, str);
123    elm_object_disabled_set(obj, a->state == API_STATE_LAST);
124 }
125
126 static Elm_Genlist_Item_Class itci;
127 char *gli_text_get(void *data, Evas_Object *obj __UNUSED__, const char *part __UNUSED__)
128 {
129    char buf[256];
130    int j = (long)data;
131    snprintf(buf, sizeof(buf), "%c%c",
132             'A' + ((j >> 4) & 0xf),
133             'a' + ((j     ) & 0xf)
134             );
135    return strdup(buf);
136 }
137
138 void
139 _index_delay_changed_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
140 {
141    // called on a change but delayed in case multiple changes happen in a
142    // short timespan
143    elm_genlist_item_top_bring_in(elm_object_item_data_get(event_info));
144 }
145
146 void
147 _index_changed_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
148 {
149    // this is calld on every change, no matter how often
150    // elm_genlist_item_bring_in(event_info);
151 }
152
153 void
154 _index_selected_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
155 {
156    // called on final select
157    elm_genlist_item_top_bring_in(elm_object_item_data_get(event_info));
158 }
159
160 static void
161 _cleanup_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
162 {
163    free(data);
164 }
165
166 static void
167 id_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
168 {
169    printf("Current Index : %s\n", elm_index_item_letter_get((const Elm_Object_Item *)event_info));
170 }
171
172 void
173 test_index(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
174 {
175    Evas_Object *win, *bg, *bxx, *gl, *id, *bt;
176    Elm_Object_Item *glit;
177    int i, j;
178    api_data *api = calloc(1, sizeof(api_data));
179
180    win = elm_win_add(NULL, "index", ELM_WIN_BASIC);
181    elm_win_title_set(win, "Index");
182    elm_win_autodel_set(win, EINA_TRUE);
183    evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _cleanup_cb, api);
184
185    bg = elm_bg_add(win);
186    elm_win_resize_object_add(win, bg);
187    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
188    evas_object_show(bg);
189
190    bxx = elm_box_add(win);
191    elm_win_resize_object_add(win, bxx);
192    evas_object_size_hint_weight_set(bxx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
193    evas_object_show(bxx);
194
195    gl = elm_genlist_add(win);
196    evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
197    evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
198    evas_object_show(gl);
199
200    api->dt.id = id = elm_index_add(win);
201    evas_object_size_hint_weight_set(id, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
202    evas_object_size_hint_align_set(id, EVAS_HINT_FILL, EVAS_HINT_FILL);
203    elm_win_resize_object_add(win, id);
204
205    bt = elm_button_add(win);
206    elm_object_text_set(bt, "Next API function");
207    evas_object_smart_callback_add(bt, "clicked", _api_bt_clicked, (void *) api);
208    elm_box_pack_end(bxx, bt);
209    elm_object_disabled_set(bt, api->state == API_STATE_LAST);
210    evas_object_show(bt);
211
212    elm_box_pack_end(bxx, gl);
213
214    evas_object_show(id);
215
216    itci.item_style     = "default";
217    itci.func.text_get = gli_text_get;
218    itci.func.content_get  = NULL;
219    itci.func.state_get = NULL;
220    itci.func.del       = NULL;
221
222         Elm_Object_Item *it;
223    j = 0;
224    for (i = 0; i < 100; i++)
225      {
226         glit = elm_genlist_item_append(gl, &itci,
227                                        (void *)(long)j/* item data */,
228                                        NULL/* parent */,
229                                        ELM_GENLIST_ITEM_NONE,
230                                        NULL/* func */, NULL/* func data */);
231         if (!(j & 0xf))
232           {
233              char buf[32];
234
235              snprintf(buf, sizeof(buf), "%c", 'A' + ((j >> 4) & 0xf));
236                                  if (j == 96)
237              it = elm_index_item_append(id, buf, id_cb, glit);
238                                  else
239              elm_index_item_append(id, buf, id_cb, glit);
240              if (*buf == 'G')  /* Just init dt->item later used in API test */
241                api->dt.item = glit;
242           }
243         j += 2;
244      }
245    evas_object_smart_callback_add(id, "delay,changed", _index_delay_changed_cb, NULL);
246    evas_object_smart_callback_add(id, "changed", _index_changed_cb, NULL);
247    evas_object_smart_callback_add(id, "selected", _index_selected_cb, NULL);
248    elm_index_level_go(id, 0);
249         elm_index_item_selected_set(it, 1);
250    evas_object_resize(win, 320, 480);
251    evas_object_show(win);
252 }
253
254 /***********/
255
256 typedef struct _Test_Index2_Elements
257 {
258    Evas_Object *entry, *lst, *id;
259 } Test_Index2_Elements;
260
261 void
262 test_index2_del(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
263 {
264    /* FIXME it won't be called if elm_test main window is closed */
265    free(data);
266 }
267
268 int
269 test_index2_cmp(const void *data1, const void *data2)
270 {
271    const char *label1, *label2;
272    const Elm_Object_Item *li_it1 = data1;
273    const Elm_Object_Item *li_it2 = data2;
274
275    label1 = elm_object_item_text_get(li_it1);
276    label2 = elm_object_item_text_get(li_it2);
277
278    return strcasecmp(label1, label2);
279 }
280
281 int
282 test_index2_icmp(const void *data1, const void *data2)
283 {
284    const char *label1, *label2;
285    const Elm_Object_Item *index_it1 = data1;
286    const Elm_Object_Item *index_it2 = data2;
287
288    label1 = elm_index_item_letter_get(index_it1);
289    label2 = elm_index_item_letter_get(index_it2);
290
291    return strcasecmp(label1, label2);
292 }
293
294 void
295 test_index2_it_add(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
296 {
297    Test_Index2_Elements *gui = data;
298    Elm_Object_Item *list_it;
299    const char *label;
300    char letter[2];
301
302    label = elm_object_text_get(gui->entry);
303    snprintf(letter, sizeof(letter), "%c", label[0]);
304    list_it = elm_list_item_sorted_insert(gui->lst, label, NULL, NULL, NULL,
305                                          NULL, test_index2_cmp);
306    elm_index_item_sorted_insert(gui->id, letter, NULL, list_it, test_index2_icmp,
307                                 test_index2_cmp);
308    elm_list_go(gui->lst);
309    /* FIXME it's not showing the recently added item */
310    elm_list_item_show(list_it);
311 }
312
313 void
314 test_index2_it_del(void *data, Evas_Object *obj, void *event_info __UNUSED__)
315 {
316    Test_Index2_Elements *gui = data;
317    const char *label, *label_next;
318    Elm_Object_Item *list_it, *list_it_next;
319    Elm_Object_Item *iit;
320
321    list_it = elm_list_selected_item_get(obj);
322    list_it_next = elm_list_item_next(list_it);
323
324    if (!list_it_next)
325      {
326         iit = elm_index_item_find(gui->id, list_it);
327         if (iit) elm_object_item_del(iit);
328         elm_object_item_del(list_it);
329         return;
330      }
331
332    label = elm_object_item_text_get(list_it);
333    label_next = elm_object_item_text_get(list_it_next);
334
335    iit = elm_index_item_find(gui->id, list_it);
336    if (label[0] == label_next[0])
337      elm_object_item_data_set(iit, list_it_next);
338    else
339      elm_object_item_del(iit);
340
341    elm_object_item_del(list_it);
342 }
343
344 void
345 test_index2_id_changed(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
346 {
347    elm_list_item_show(elm_object_item_data_get(event_info));
348 }
349
350 void
351 test_index2(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
352 {
353    Evas_Object *win, *bg, *box, *bt;
354    Test_Index2_Elements *gui;
355
356    gui = malloc(sizeof(*gui));
357
358    win = elm_win_add(NULL, "sorted-index-list", ELM_WIN_BASIC);
359    elm_win_title_set(win, "Sorted Index and List");
360    evas_object_smart_callback_add(win, "delete,request", test_index2_del, gui);
361    elm_win_autodel_set(win, EINA_TRUE);
362
363    bg = elm_bg_add(win);
364    elm_win_resize_object_add(win, bg);
365    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
366    evas_object_show(bg);
367
368    box = elm_box_add(win);
369    evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
370    elm_win_resize_object_add(win, box);
371    evas_object_show(box);
372
373    gui->id = elm_index_add(win);
374    evas_object_size_hint_weight_set(gui->id, EVAS_HINT_EXPAND,
375                                     EVAS_HINT_EXPAND);
376    elm_win_resize_object_add(win, gui->id);
377    evas_object_smart_callback_add(gui->id, "delay,changed",
378                                   test_index2_id_changed, NULL);
379    evas_object_show(gui->id);
380
381    gui->entry = elm_entry_add(win);
382    elm_entry_scrollable_set(gui->entry, EINA_TRUE);
383    elm_object_text_set(gui->entry, "Label");
384    elm_entry_single_line_set(gui->entry, EINA_TRUE);
385    evas_object_size_hint_weight_set(gui->entry, EVAS_HINT_EXPAND, 0);
386    evas_object_size_hint_fill_set(gui->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
387    elm_box_pack_end(box, gui->entry);
388    evas_object_show(gui->entry);
389
390    bt = elm_button_add(win);
391    elm_object_text_set(bt, "Add");
392    evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0);
393    evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
394    elm_box_pack_end(box, bt);
395    evas_object_smart_callback_add(bt, "clicked", test_index2_it_add, gui);
396    evas_object_show(bt);
397
398    gui->lst = elm_list_add(win);
399    elm_box_pack_end(box, gui->lst);
400    evas_object_size_hint_weight_set(gui->lst, EVAS_HINT_EXPAND,
401                                     EVAS_HINT_EXPAND);
402    evas_object_size_hint_fill_set(gui->lst, EVAS_HINT_FILL, EVAS_HINT_FILL);
403    evas_object_smart_callback_add(gui->lst, "selected", test_index2_it_del,
404                                   gui);
405    elm_list_go(gui->lst);
406    evas_object_show(gui->lst);
407
408    evas_object_resize(win, 320, 480);
409    evas_object_show(win);
410 }
411
412
413 static void
414 _drag_start(void *data , Evas_Object *obj, void *event_info __UNUSED__)
415 {
416    pagectrl_data *page_data = data;
417    Evas_Coord x, y, w, h;
418    elm_scroller_region_get(obj, &x, &y, &w, &h);
419
420    page_data->recent_x = x;
421    page_data->drag_started = EINA_TRUE;
422 }
423
424 static void
425 _drag_stop(void *data , Evas_Object *obj, void *event_info __UNUSED__)
426 {
427    pagectrl_data *page_data = data;
428    Evas_Coord x, y, w, h;
429    elm_scroller_region_get(obj, &x, &y, &w, &h);
430
431    if ((page_data->recent_x == x) && (x != 0))
432      elm_object_scroll_hold_push(obj);
433 }
434
435 static void
436 _anim_start(void *data , Evas_Object *obj, void *event_info __UNUSED__)
437 {
438    pagectrl_data *page_data = data;
439    Evas_Coord x, y, w, h;
440    Elm_Object_Item *it;
441    int idx;
442    int threshold;
443    Evas_Coord max_page_x;
444
445    if (page_data->changed)
446      {
447         page_data->changed = EINA_FALSE;
448         return;
449      }
450
451    if (!page_data->drag_started) return;
452    max_page_x = (page_data->page_cnt - 1) * page_data->page_width;
453    elm_scroller_region_get(obj, &x, &y, &w, &h);
454    it = elm_index_selected_item_get(page_data->index, 0);
455    if (!it) return;
456    idx = (int) elm_object_item_data_get(it);
457    if (x < 0) x = 0;
458    if (x > max_page_x) x = max_page_x;
459
460    threshold = page_data->page_width * 0.2;
461    if (abs(page_data->recent_x - x) > threshold)
462      {
463         if (x > page_data->recent_x) idx++;
464         else if ((x < page_data->recent_x) && (idx > 0)) idx--;
465      }
466
467    if (idx > page_data->page_cnt) idx = page_data->page_cnt;
468
469    page_data->drag_started = EINA_FALSE;
470
471    elm_scroller_region_bring_in(obj, page_data->page_width * idx, 0, w, h);
472
473    it = elm_index_item_find(page_data->index, (void *) idx);
474 //   elm_index_item_selected_set(it, EINA_TRUE);
475 }
476
477 static void
478 _anim_stop(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
479 {
480    elm_object_scroll_hold_pop(obj);
481 }
482
483 static void
484 _index3_selected_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info)
485 {
486    Evas_Coord x, y, w, h;
487    Elm_Object_Item *it = event_info;
488    int idx = (int) elm_object_item_data_get(it);
489    pagectrl_data *page_data = data;
490
491    evas_object_geometry_get(page_data->sc, &x, &y, &w, &h);
492    page_data->changed = EINA_TRUE;
493
494    elm_scroller_region_bring_in(page_data->sc, page_data->page_width * idx, 0,
495                                 w, h);
496 }
497
498 void
499 test_index3(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
500 {
501    Evas_Object *win, *bg, *sc, *img, *id;
502    char buf[PATH_MAX];
503    api_data *api = calloc(1, sizeof(api_data));
504    pagectrl_data *page_data = calloc(1, sizeof(pagectrl_data));
505    Evas_Coord page_h;
506    int i;
507    Elm_Object_Item *it;
508    page_data->page_width = 480;
509    page_data->page_cnt = 3;
510
511    win = elm_win_add(NULL, "index", ELM_WIN_BASIC);
512    elm_win_title_set(win, "index - pagecontrol style");
513    elm_win_autodel_set(win, EINA_TRUE);
514    evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _cleanup_cb, api);
515
516    bg = elm_bg_add(win);
517    elm_win_resize_object_add(win, bg);
518    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
519    evas_object_show(bg);
520
521    img = elm_image_add(win);
522    snprintf(buf, sizeof(buf), "%s/images/horz_scrollbar.jpg", elm_app_data_dir_get());
523    elm_image_file_set(img, buf, NULL);
524    elm_image_resizable_set(img, EINA_TRUE, EINA_FALSE);
525    elm_image_object_size_get(img, NULL, &page_h);
526    evas_object_show(img);
527
528    page_data->sc = sc = elm_scroller_add(win);
529    evas_object_smart_callback_add(sc, "scroll,drag,start", _drag_start,
530                                   page_data);
531    evas_object_smart_callback_add(sc, "scroll,drag,stop", _drag_stop,
532                                   page_data);
533    evas_object_smart_callback_add(sc, "scroll,anim,start", _anim_start,
534                                   page_data);
535    evas_object_smart_callback_add(sc, "scroll,anim,stop", _anim_stop,
536                                   page_data);
537
538    elm_scroller_bounce_set(sc, EINA_FALSE, EINA_FALSE);
539    elm_scroller_policy_set(sc, ELM_SCROLLER_POLICY_OFF,
540                            ELM_SCROLLER_POLICY_OFF);
541    elm_scroller_page_size_set(sc, page_data->page_width, page_h);
542    elm_object_content_set(sc, img);
543    elm_object_scroll_lock_y_set(sc, EINA_TRUE);
544    elm_win_resize_object_add(win, sc);
545    evas_object_show(sc);
546
547    page_data->index = api->dt.id = id = elm_index_add(win);
548    elm_index_horizontal_set(id, EINA_TRUE);
549    elm_index_autohide_disabled_set(id, EINA_TRUE);
550    elm_object_style_set(id, "pagecontrol");
551
552    evas_object_smart_callback_add(id, "selected", _index3_selected_cb,
553                                   page_data);
554    evas_object_size_hint_weight_set(id, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
555    evas_object_size_hint_align_set(id, EVAS_HINT_FILL, EVAS_HINT_FILL);
556    evas_object_show(id);
557
558    for(i = 0; i < page_data->page_cnt; i++)
559      {
560         snprintf(buf, sizeof(buf), "%c", '1' + i);
561         if (i == 0)
562           it = elm_index_item_append(id, buf, NULL, (void *) i);
563         else
564           elm_index_item_append(id, buf, NULL, (void *) i);
565      }
566
567    elm_index_level_go(id, 0);
568    //elm_index_item_selected_set(it, EINA_TRUE);
569
570    elm_win_resize_object_add(win, id);
571    evas_object_resize(win, page_data->page_width, 585);
572    evas_object_show(win);
573 }
574
575
576 #endif