EFL migration revision 67547
[framework/uifw/elementary.git] / tests / src / lib / elm_gen.c
1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
3 #include "elm_priv.h"
4 #include "els_scroller.h"
5 #include "elm_gen.h"
6
7 /* TEMPORARY */
8 #undef ELM_CHECK_WIDTYPE
9 #define ELM_CHECK_WIDTYPE(obj, widtype) \
10    if ((!obj) || (!elm_gen_type_check((obj), __func__))) return
11 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
12 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...)                \
13    ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
14    ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
15
16 static const char *_gengrid = NULL;
17 static const char *_genlist = NULL;
18
19 struct _Widget_Data
20 {
21    Eina_Inlist_Sorted_State *state;
22    Evas_Object      *obj;
23    Evas_Object      *scr; /* a smart scroller object which is used internally in genlist */
24    Evas_Object      *pan_smart; /* "elm_genlist_pan" evas smart object. this is an extern pan of smart scroller(scr). */
25    Eina_List        *selected;
26    Eina_List        *group_items;
27    Eina_Inlist      *items; /* inlist of all items */
28    Elm_Gen_Item     *reorder_it; /* item currently being repositioned */
29    Elm_Gen_Item     *last_selected_item;
30    Pan              *pan; /* pan_smart object's smart data */
31    Ecore_Job        *calc_job;
32    int               walking;
33    int               item_width, item_height;
34    int               group_item_width, group_item_height;
35    int               minw, minh;
36    long              count;
37    Evas_Coord        pan_x, pan_y;
38    Eina_Bool         reorder_mode : 1;
39    Eina_Bool         on_hold : 1;
40    Eina_Bool         multi : 1;
41    Eina_Bool         no_select : 1;
42    Eina_Bool         wasselected : 1;
43    Eina_Bool         always_select : 1;
44    Eina_Bool         clear_me : 1;
45    Eina_Bool         h_bounce : 1;
46    Eina_Bool         v_bounce : 1;
47    Ecore_Cb          del_cb, calc_cb, sizing_cb;
48    Ecore_Cb          clear_cb;
49 };
50
51 static const char SIG_ACTIVATED[] = "activated";
52 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
53 static const char SIG_SELECTED[] = "selected";
54 static const char SIG_UNSELECTED[] = "unselected";
55 static const char SIG_EXPANDED[] = "expanded";
56 static const char SIG_CONTRACTED[] = "contracted";
57 static const char SIG_EXPAND_REQUEST[] = "expand,request";
58 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
59 static const char SIG_REALIZED[] = "realized";
60 static const char SIG_UNREALIZED[] = "unrealized";
61 static const char SIG_DRAG_START_UP[] = "drag,start,up";
62 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
63 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
64 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
65 static const char SIG_DRAG_STOP[] = "drag,stop";
66 static const char SIG_DRAG[] = "drag";
67 static const char SIG_LONGPRESSED[] = "longpressed";
68 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
69 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
70 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
71 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
72 static const char SIG_SCROLL_EDGE_TOP[] = "scroll,edge,top"; // TODO : remove this
73 static const char SIG_SCROLL_EDGE_BOTTOM[] = "scroll,edge,bottom"; // TODO : remove this
74 static const char SIG_SCROLL_EDGE_LEFT[] = "scroll,edge,left"; // TODO : remove this
75 static const char SIG_SCROLL_EDGE_RIGHT[] = "scroll,edge,right"; // TODO : remove this
76 static const char SIG_EDGE_TOP[] = "edge,top";
77 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
78 static const char SIG_EDGE_LEFT[] = "edge,left";
79 static const char SIG_EDGE_RIGHT[] = "edge,right";
80 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
81 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
82 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
83 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
84 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
85 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
86 static const char SIG_SWIPE[] = "swipe";
87 static const char SIG_MOVED[] = "moved";
88
89 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
90 Eina_Bool
91 elm_gen_type_check(const Evas_Object *obj,
92                    const char        *func)
93 {
94    const char *provided, *expected = "(unknown)";
95    static int abort_on_warn = -1;
96    provided = elm_widget_type_get(obj);
97    if (!_genlist) _genlist = eina_stringshare_add("genlist");
98    if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
99    if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
100      return EINA_TRUE;
101    if ((!provided) || (!provided[0]))
102      {
103         provided = evas_object_type_get(obj);
104         if ((!provided) || (!provided[0]))
105           provided = "(unknown)";
106      }
107    ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
108    if (abort_on_warn == -1)
109      {
110         if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
111         else abort_on_warn = 0;
112      }
113    if (abort_on_warn == 1) abort();
114    return EINA_FALSE;
115 }
116
117 static const char *
118 _item_text_hook(Elm_Gen_Item *it, const char *part)
119 {
120    if (!it->itc->func.text_get) return NULL;
121    return edje_object_part_text_get(VIEW(it), part);
122 }
123
124 static Evas_Object *
125 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
126 {
127    return edje_object_part_swallow_get(VIEW(it), part);
128 }
129
130 static void
131 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
132 {
133    edje_object_part_swallow(VIEW(it), part, content);
134 }
135
136 static Evas_Object *
137 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
138 {
139    Evas_Object *obj;
140
141    obj = edje_object_part_swallow_get(VIEW(it), part);
142    if (!obj) return NULL;
143    edje_object_part_unswallow(VIEW(it), obj);
144    return obj;
145 }
146
147 #if 0
148 static Eina_Bool
149 _deselect_all_items(Widget_Data *wd)
150 {
151    if (!wd->selected) return EINA_FALSE;
152    while (wd->selected)
153      elm_gengrid_item_selected_set(wd->selected->data, EINA_FALSE);
154
155    return EINA_TRUE;
156 }
157
158 static Eina_Bool
159 _item_multi_select_left(Widget_Data *wd)
160 {
161    if (!wd->selected) return EINA_FALSE;
162
163    Elm_Gengrid_Item *prev = elm_gengrid_item_prev_get(wd->last_selected_item);
164    if (!prev) return EINA_TRUE;
165    if (elm_gengrid_item_selected_get(prev))
166      {
167         elm_gengrid_item_selected_set(wd->last_selected_item, EINA_FALSE);
168         wd->last_selected_item = prev;
169         elm_gengrid_item_show(wd->last_selected_item);
170      }
171    else
172      {
173         elm_gengrid_item_selected_set(prev, EINA_TRUE);
174         elm_gengrid_item_show(prev);
175      }
176
177    return EINA_TRUE;
178 }
179
180 static Eina_Bool
181 _item_multi_select_right(Widget_Data *wd)
182 {
183    if (!wd->selected) return EINA_FALSE;
184
185    Elm_Gengrid_Item *next = elm_gengrid_item_next_get(wd->last_selected_item);
186    if (!next) return EINA_TRUE;
187    if (elm_gengrid_item_selected_get(next))
188      {
189         elm_gengrid_item_selected_set(wd->last_selected_item, EINA_FALSE);
190         wd->last_selected_item = next;
191         elm_gengrid_item_show(wd->last_selected_item);
192      }
193    else
194      {
195         elm_gengrid_item_selected_set(next, EINA_TRUE);
196         elm_gengrid_item_show(next);
197      }
198
199    return EINA_TRUE;
200 }
201
202 static Eina_Bool
203 _item_multi_select_up(Widget_Data *wd)
204 {
205    unsigned int i;
206    Eina_Bool r = EINA_TRUE;
207
208    if (!wd->selected) return EINA_FALSE;
209
210    for (i = 0; (r) && (i < wd->nmax); i++)
211      r &= _item_multi_select_left(wd);
212
213    return r;
214 }
215
216 static Eina_Bool
217 _item_multi_select_down(Widget_Data *wd)
218 {
219    unsigned int i;
220    Eina_Bool r = EINA_TRUE;
221
222    if (!wd->selected) return EINA_FALSE;
223
224    for (i = 0; (r) && (i < wd->nmax); i++)
225      r &= _item_multi_select_right(wd);
226
227    return r;
228 }
229
230 static Eina_Bool
231 _item_single_select_up(Widget_Data *wd)
232 {
233    unsigned int i;
234
235    Elm_Gengrid_Item *prev;
236
237    if (!wd->selected)
238      {
239         prev = ELM_GENGRID_ITEM_FROM_INLIST(wd->items->last);
240         while ((prev) && (prev->delete_me))
241           prev = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
242         elm_gengrid_item_selected_set(prev, EINA_TRUE);
243         elm_gengrid_item_show(prev);
244         return EINA_TRUE;
245      }
246    else prev = elm_gengrid_item_prev_get(wd->last_selected_item);
247
248    if (!prev) return EINA_FALSE;
249
250    for (i = 1; i < wd->nmax; i++)
251      {
252         Elm_Gengrid_Item *tmp = elm_gengrid_item_prev_get(prev);
253         if (!tmp) return EINA_FALSE;
254         prev = tmp;
255      }
256
257    _deselect_all_items(wd);
258
259    elm_gengrid_item_selected_set(prev, EINA_TRUE);
260    elm_gengrid_item_show(prev);
261    return EINA_TRUE;
262 }
263
264 static Eina_Bool
265 _item_single_select_down(Widget_Data *wd)
266 {
267    unsigned int i;
268
269    Elm_Gengrid_Item *next;
270
271    if (!wd->selected)
272      {
273         next = ELM_GENGRID_ITEM_FROM_INLIST(wd->items);
274         while ((next) && (next->delete_me))
275           next = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
276         elm_gengrid_item_selected_set(next, EINA_TRUE);
277         elm_gengrid_item_show(next);
278         return EINA_TRUE;
279      }
280    else next = elm_gengrid_item_next_get(wd->last_selected_item);
281
282    if (!next) return EINA_FALSE;
283
284    for (i = 1; i < wd->nmax; i++)
285      {
286         Elm_Gengrid_Item *tmp = elm_gengrid_item_next_get(next);
287         if (!tmp) return EINA_FALSE;
288         next = tmp;
289      }
290
291    _deselect_all_items(wd);
292
293    elm_gengrid_item_selected_set(next, EINA_TRUE);
294    elm_gengrid_item_show(next);
295    return EINA_TRUE;
296 }
297
298 static Eina_Bool
299 _item_single_select_left(Widget_Data *wd)
300 {
301    Elm_Gengrid_Item *prev;
302    if (!wd->selected)
303      {
304         prev = ELM_GENGRID_ITEM_FROM_INLIST(wd->items->last);
305         while ((prev) && (prev->delete_me))
306           prev = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
307      }
308    else prev = elm_gengrid_item_prev_get(wd->last_selected_item);
309
310    if (!prev) return EINA_FALSE;
311
312    _deselect_all_items(wd);
313
314    elm_gengrid_item_selected_set(prev, EINA_TRUE);
315    elm_gengrid_item_show(prev);
316    return EINA_TRUE;
317 }
318
319 static Eina_Bool
320 _item_single_select_right(Widget_Data *wd)
321 {
322    Elm_Gengrid_Item *next;
323    if (!wd->selected)
324      {
325         next = ELM_GENGRID_ITEM_FROM_INLIST(wd->items);
326         while ((next) && (next->delete_me))
327           next = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
328      }
329    else next = elm_gengrid_item_next_get(wd->last_selected_item);
330
331    if (!next) return EINA_FALSE;
332
333    _deselect_all_items(wd);
334
335    elm_gengrid_item_selected_set(next, EINA_TRUE);
336    elm_gengrid_item_show(next);
337    return EINA_TRUE;
338 }
339 #endif
340
341
342 static void
343 _item_select(Elm_Gen_Item *it)
344 {
345    if ((it->wd->no_select) || (it->delete_me) || (it->mode_set)) return;
346    if (!it->selected)
347      {
348         it->selected = EINA_TRUE;
349         it->wd->selected = eina_list_append(it->wd->selected, it);
350      }
351    else if (!it->wd->always_select) return;
352
353    evas_object_ref(WIDGET(it));
354    it->walking++;
355    it->wd->walking++;
356    if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
357    if (!it->delete_me)
358      evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
359    it->walking--;
360    it->wd->walking--;
361    evas_object_unref(WIDGET(it));
362    if ((it->wd->clear_me) && (!it->wd->walking))
363      elm_gen_clear(WIDGET(it));
364    else
365      {
366         if ((!it->walking) && (it->delete_me))
367           {
368              if (!it->relcount) it->del_cb(it);
369           }
370         else
371           it->wd->last_selected_item = it;
372      }
373 }
374 /******************************************************************************/
375 void
376 elm_gen_item_unrealize(Elm_Gen_Item *it,
377                        Eina_Bool     calc)
378 {
379    Evas_Object *content;
380
381    if (!it->realized) return;
382    if (it->wd->reorder_it == it) return;
383    evas_event_freeze(evas_object_evas_get(WIDGET(it)));
384    if (!calc)
385      evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
386    if (it->long_timer)
387      {
388         ecore_timer_del(it->long_timer);
389         it->long_timer = NULL;
390      }
391
392    elm_widget_stringlist_free(it->labels);
393    it->labels = NULL;
394    elm_widget_stringlist_free(it->contents);
395    it->contents = NULL;
396    elm_widget_stringlist_free(it->states);
397    it->states = NULL;
398
399    EINA_LIST_FREE(it->content_objs, content)
400      evas_object_del(content);
401
402    it->unrealize_cb(it);
403
404    it->realized = EINA_FALSE;
405    it->want_unrealize = EINA_FALSE;
406    evas_event_thaw(evas_object_evas_get(WIDGET(it)));
407    evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
408 }
409
410 void
411 elm_gen_item_del_notserious(Elm_Gen_Item *it)
412 {
413    elm_widget_item_pre_notify_del(it);
414    it->delete_me = EINA_TRUE;
415    if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
416
417    if (it->itc->func.del)
418      it->itc->func.del((void *)it->base.data, WIDGET(it));
419 }
420
421 void
422 elm_gen_item_del_serious(Elm_Gen_Item *it)
423 {
424    elm_gen_item_del_notserious(it);
425    it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
426    if (it->tooltip.del_cb)
427      it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
428    it->wd->walking -= it->walking;
429    if (it->long_timer) ecore_timer_del(it->long_timer);
430    if (it->group)
431      it->wd->group_items = eina_list_remove(it->wd->group_items, it);
432
433    if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
434    it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
435    free(it->item);
436    it->item = NULL;
437    elm_widget_item_del(it);
438 }
439
440 Elm_Gen_Item *
441 elm_gen_item_new(Widget_Data              *wd,
442                  const Elm_Gen_Item_Class *itc,
443                  const void               *data,
444                  Elm_Gen_Item             *parent,
445                  Evas_Smart_Cb             func,
446                  const void               *func_data)
447 {
448    Elm_Gen_Item *it;
449
450    it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
451    if (!it) return NULL;
452    it->wd = wd;
453    it->itc = itc;
454    it->base.data = data;
455    it->parent = parent;
456    it->func.func = func;
457    it->func.data = func_data;
458    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
459    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
460    elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
461    /* TEMPORARY */
462    it->sel_cb = (Ecore_Cb)_item_select;
463
464    elm_widget_item_text_get_hook_set(it, _item_text_hook);
465    return it;
466 }
467 /******************************************************************************/
468
469 EAPI void
470 elm_gen_item_selected_set(Elm_Gen_Item *it,
471                           Eina_Bool     selected)
472 {
473    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
474    Widget_Data *wd = it->wd;
475    if (!wd) return;
476    if ((it->delete_me) || (it->disabled)) return;
477    selected = !!selected;
478    if (it->selected == selected) return;
479
480    if (selected)
481      {
482         if (!wd->multi)
483           {
484              while (wd->selected)
485                {
486                   if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
487                   it->unsel_cb(wd->selected->data);
488                }
489           }
490         it->highlight_cb(it);
491         _item_select(it);
492         return;
493      }
494    if (it->unhighlight_cb) it->unhighlight_cb(it);
495    it->unsel_cb(it);
496 }
497
498 EAPI void
499 elm_gen_clear(Evas_Object *obj)
500 {
501    ELM_CHECK_WIDTYPE(obj, widtype);
502    Widget_Data *wd = elm_widget_data_get(obj);
503    if (!wd) return;
504
505    if (wd->state)
506      {
507         eina_inlist_sorted_state_free(wd->state);
508         wd->state = NULL;
509      }
510
511    if (wd->walking > 0)
512      {
513         Elm_Gen_Item *it;
514         wd->clear_me = 1;
515         EINA_INLIST_FOREACH(wd->items, it)
516            it->delete_me = 1;
517         return;
518      }
519    evas_event_freeze(evas_object_evas_get(wd->obj));
520    while (wd->items)
521      {
522         Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
523         it->del_cb(it);
524      }
525    wd->clear_me = 0;
526    if (wd->calc_job)
527      {
528         ecore_job_del(wd->calc_job);
529         wd->calc_job = NULL;
530      }
531    if (wd->selected) wd->selected = eina_list_free(wd->selected);
532    if (wd->clear_cb) wd->clear_cb(wd);
533    wd->pan_x = 0;
534    wd->pan_y = 0;
535    wd->minw = 0;
536    wd->minh = 0;
537    wd->count = 0;
538    if (wd->pan_smart)
539      {
540         evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
541         evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
542      }
543    if (wd->sizing_cb) wd->sizing_cb(wd->obj);
544    elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
545    evas_event_thaw(evas_object_evas_get(wd->obj));
546    evas_event_thaw_eval(evas_object_evas_get(wd->obj));
547 }
548
549 EAPI Eina_Bool
550 elm_gen_item_selected_get(const Elm_Gen_Item *it)
551 {
552    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
553    return it->selected;
554 }
555
556 EAPI void
557 elm_gen_always_select_mode_set(Evas_Object *obj,
558                                    Eina_Bool    always_select)
559 {
560    ELM_CHECK_WIDTYPE(obj, widtype);
561    Widget_Data *wd = elm_widget_data_get(obj);
562    if (!wd) return;
563    wd->always_select = always_select;
564 }
565
566 EAPI Eina_Bool
567 elm_gen_always_select_mode_get(const Evas_Object *obj)
568 {
569    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
570    Widget_Data *wd = elm_widget_data_get(obj);
571    if (!wd) return EINA_FALSE;
572    return wd->always_select;
573 }
574
575 EAPI void
576 elm_gen_no_select_mode_set(Evas_Object *obj,
577                                Eina_Bool    no_select)
578 {
579    ELM_CHECK_WIDTYPE(obj, widtype);
580    Widget_Data *wd = elm_widget_data_get(obj);
581    if (!wd) return;
582    wd->no_select = no_select;
583 }
584
585 EAPI Eina_Bool
586 elm_gen_no_select_mode_get(const Evas_Object *obj)
587 {
588    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
589    Widget_Data *wd = elm_widget_data_get(obj);
590    if (!wd) return EINA_FALSE;
591    return wd->no_select;
592 }
593
594 EAPI void
595 elm_gen_bounce_set(Evas_Object *obj,
596                        Eina_Bool    h_bounce,
597                        Eina_Bool    v_bounce)
598 {
599    ELM_CHECK_WIDTYPE(obj, widtype);
600    Widget_Data *wd = elm_widget_data_get(obj);
601    if (!wd) return;
602    elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
603    wd->h_bounce = h_bounce;
604    wd->v_bounce = v_bounce;
605 }
606
607 EAPI void
608 elm_gen_bounce_get(const Evas_Object *obj,
609                        Eina_Bool         *h_bounce,
610                        Eina_Bool         *v_bounce)
611 {
612    ELM_CHECK_WIDTYPE(obj, widtype);
613    Widget_Data *wd = elm_widget_data_get(obj);
614    if (!wd) return;
615    if (h_bounce) *h_bounce = wd->h_bounce;
616    if (v_bounce) *v_bounce = wd->v_bounce;
617 }
618
619 EAPI void
620 elm_gen_page_relative_set(Evas_Object *obj,
621                               double       h_pagerel,
622                               double       v_pagerel)
623 {
624    Evas_Coord pagesize_h;
625    Evas_Coord pagesize_v;
626
627    ELM_CHECK_WIDTYPE(obj, widtype);
628    Widget_Data *wd = elm_widget_data_get(obj);
629    if (!wd) return;
630
631    elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
632    elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
633                                  pagesize_v);
634 }
635
636 EAPI void
637 elm_gen_page_relative_get(const Evas_Object *obj, double *h_pagerel, double *v_pagerel)
638 {
639    ELM_CHECK_WIDTYPE(obj, widtype);
640    Widget_Data *wd = elm_widget_data_get(obj);
641    if (!wd) return;
642
643    elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
644 }
645
646 EAPI void
647 elm_gen_page_size_set(Evas_Object *obj,
648                           Evas_Coord   h_pagesize,
649                           Evas_Coord   v_pagesize)
650 {
651    double pagerel_h;
652    double pagerel_v;
653
654    ELM_CHECK_WIDTYPE(obj, widtype);
655    Widget_Data *wd = elm_widget_data_get(obj);
656    if (!wd) return;
657    elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
658    elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
659                                  v_pagesize);
660 }
661
662 EAPI void
663 elm_gen_current_page_get(const Evas_Object *obj, int *h_pagenumber, int *v_pagenumber)
664 {
665    ELM_CHECK_WIDTYPE(obj, widtype);
666    Widget_Data *wd = elm_widget_data_get(obj);
667    if (!wd) return;
668    if (wd->scr)
669      elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
670 }
671
672 EAPI void
673 elm_gen_last_page_get(const Evas_Object *obj, int *h_pagenumber, int *v_pagenumber)
674 {
675    ELM_CHECK_WIDTYPE(obj, widtype);
676    Widget_Data *wd = elm_widget_data_get(obj);
677    if (!wd) return;
678    if (wd->scr)
679      elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
680 }
681
682 EAPI void
683 elm_gen_page_show(const Evas_Object *obj, int h_pagenumber, int v_pagenumber)
684 {
685    ELM_CHECK_WIDTYPE(obj, widtype);
686    Widget_Data *wd = elm_widget_data_get(obj);
687    if (!wd) return;
688    if (wd->scr)
689      elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
690 }
691
692 EAPI void
693 elm_gen_page_bring_in(const Evas_Object *obj, int h_pagenumber, int v_pagenumber)
694 {
695    ELM_CHECK_WIDTYPE(obj, widtype);
696    Widget_Data *wd = elm_widget_data_get(obj);
697    if (!wd) return;
698    if (wd->scr)
699      elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
700 }
701
702 EAPI Elm_Gen_Item *
703 elm_gen_first_item_get(const Evas_Object *obj)
704 {
705    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
706    Widget_Data *wd = elm_widget_data_get(obj);
707    if (!wd) return NULL;
708    if (!wd->items) return NULL;
709    Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
710    while ((it) && (it->delete_me))
711      it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
712    return it;
713 }
714
715 EAPI Elm_Gen_Item *
716 elm_gen_last_item_get(const Evas_Object *obj)
717 {
718    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
719    Widget_Data *wd = elm_widget_data_get(obj);
720    if (!wd) return NULL;
721    if (!wd->items) return NULL;
722    Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
723    while ((it) && (it->delete_me))
724      it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
725    return it;
726 }
727
728 EAPI Elm_Gen_Item *
729 elm_gen_item_next_get(const Elm_Gen_Item *it)
730 {
731    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
732    while (it)
733      {
734         it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
735         if ((it) && (!it->delete_me)) break;
736      }
737    return (Elm_Gen_Item *)it;
738 }
739
740 EAPI Elm_Gen_Item *
741 elm_gen_item_prev_get(const Elm_Gen_Item *it)
742 {
743    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
744    while (it)
745      {
746         it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
747         if ((it) && (!it->delete_me)) break;
748      }
749    return (Elm_Gen_Item *)it;
750 }
751
752 EAPI Evas_Object *
753 elm_gen_item_widget_get(const Elm_Gen_Item *it)
754 {
755    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
756    return WIDGET(it);
757 }