2f133b81820d33972a442661ba56b2e6bc921ea9
[platform/upstream/elementary.git] / src / lib / elm_scroller.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
7
8 #include <Elementary.h>
9
10 #include "elm_priv.h"
11 #include "elm_interface_scrollable.h"
12 #include "elm_widget_layout.h"
13 #include "elm_widget_scroller.h"
14
15 #define MY_CLASS ELM_SCROLLER_CLASS
16
17 #define MY_CLASS_NAME "Elm_Scroller"
18 #define MY_CLASS_NAME_LEGACY "elm_scroller"
19
20 #define ELM_PRIV_SCROLLER_SIGNALS(cmd) \
21    cmd(SIG_SCROLL, "scroll", "") \
22    cmd(SIG_SCROLL_LEFT, "scroll,left", "") \
23    cmd(SIG_SCROLL_RIGHT, "scroll,right", "") \
24    cmd(SIG_SCROLL_UP, "scroll,up", "") \
25    cmd(SIG_SCROLL_DOWN, "scroll,down", "") \
26    cmd(SIG_SCROLL_ANIM_START, "scroll,anim,start", "") \
27    cmd(SIG_SCROLL_ANIM_STOP, "scroll,anim,stop", "") \
28    cmd(SIG_SCROLL_DRAG_START, "scroll,drag,start", "") \
29    cmd(SIG_SCROLL_DRAG_STOP, "scroll,drag,stop", "") \
30    cmd(SIG_EDGE_LEFT, "edge,left", "") \
31    cmd(SIG_EDGE_RIGHT, "edge,right", "") \
32    cmd(SIG_EDGE_TOP, "edge,top", "") \
33    cmd(SIG_EDGE_BOTTOM, "edge,bottom", "") \
34    cmd(SIG_VBAR_DRAG, "vbar,drag", "") \
35    cmd(SIG_VBAR_PRESS, "vbar,press", "") \
36    cmd(SIG_VBAR_UNPRESS, "vbar,unpress", "") \
37    cmd(SIG_HBAR_DRAG, "hbar,drag", "") \
38    cmd(SIG_HBAR_PRESS, "hbar,press", "") \
39    cmd(SIG_HBAR_UNPRESS, "hbar,unpress", "") \
40    cmd(SIG_SCROLL_PAGE_CHANGE, "scroll,page,changed", "") \
41
42 ELM_PRIV_SCROLLER_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
43
44 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
45    ELM_PRIV_SCROLLER_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
46    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
47    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
48    {NULL, NULL}
49 };
50 #undef ELM_PRIV_SCROLLER_SIGNALS
51
52 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
53
54 static const Elm_Action key_actions[] = {
55    {"move", _key_action_move},
56    {NULL, NULL}
57 };
58
59 static void
60 _elm_scroller_proxy_set(Evas_Object *obj, Elm_Scroller_Data *sd, Evas_Object *proxy)
61 {
62    Evas_Coord h_pagesize, v_pagesize;
63    Evas_Coord cw, ch;
64    Evas_Object *content = sd->content;
65
66    if (!content) return;
67
68    eo_do(obj, elm_interface_scrollable_paging_get(NULL, NULL, &h_pagesize, &v_pagesize));
69    eo_do(obj, elm_interface_scrollable_content_size_get(&cw, &ch));
70    /* Since Proxy has the texture size limitation problem, we set a key value
71       for evas works in some hackish way to avoid this problem. This hackish
72       code should be removed once evas supports a mechanism like a virtual
73       texture. */
74    evas_object_image_fill_set(proxy, 0, 0, cw, ch);
75    evas_object_size_hint_min_set(proxy, h_pagesize, v_pagesize);
76    evas_object_image_source_clip_set(proxy, EINA_FALSE);
77    evas_object_image_source_set(proxy, content);
78    evas_object_show(proxy);
79 }
80
81 static Eina_Bool
82 _key_action_move(Evas_Object *obj, const char *params)
83 {
84    ELM_SCROLLER_DATA_GET(obj, sd);
85    const char *dir = params;
86    Evas_Coord x = 0;
87    Evas_Coord y = 0;
88    Evas_Coord c_x = 0;
89    Evas_Coord c_y = 0;
90    Evas_Coord v_x = 0;
91    Evas_Coord v_y = 0;
92    Evas_Coord v_w = 0;
93    Evas_Coord v_h = 0;
94    Evas_Coord max_x = 0;
95    Evas_Coord max_y = 0;
96    Evas_Coord page_x = 0;
97    Evas_Coord page_y = 0;
98    Evas_Coord step_x = 0;
99    Evas_Coord step_y = 0;
100    Evas_Object *current_focus = NULL;
101    Eina_List *can_focus_list = NULL;
102    Evas_Object *new_focus = NULL;
103    Elm_Object_Item *new_focus_item = NULL;
104    Evas_Coord f_x = 0;
105    Evas_Coord f_y = 0;
106    Evas_Coord f_w = 0;
107    Evas_Coord f_h = 0;
108
109    eo_do(obj,
110          elm_interface_scrollable_content_pos_get(&x, &y),
111          elm_interface_scrollable_step_size_get(&step_x, &step_y),
112          elm_interface_scrollable_page_size_get(&page_x, &page_y),
113          elm_interface_scrollable_content_viewport_geometry_get
114          (&v_x, &v_y, &v_w, &v_h));
115    evas_object_geometry_get(sd->content, &c_x, &c_y, &max_x, &max_y);
116
117    _elm_widget_focus_auto_show(obj);
118
119    current_focus = elm_widget_focused_object_get(obj);
120    evas_object_geometry_get(current_focus, &f_x, &f_y, &f_w, &f_h);
121    can_focus_list = elm_widget_can_focus_child_list_get(obj);
122
123    if ((current_focus == obj) ||
124        ((!ELM_RECTS_INTERSECT
125          (x, y, v_w, v_h, (f_x - c_x), (f_y - c_y), f_w, f_h)) &&
126         ((!strcmp(dir, "left") && (f_x > v_x)) ||
127         (!strcmp(dir, "right") && (f_x + f_w < v_x + v_w)) ||
128         (!strcmp(dir, "up") && (f_y > v_y)) ||
129         (!strcmp(dir, "down") && (f_y + f_h < v_y + v_h)))))
130      {
131         Eina_List *l;
132         Evas_Object *cur;
133         double weight = 0.0;
134
135         EINA_LIST_FOREACH(can_focus_list, l, cur)
136           {
137              double cur_weight = 0.0;
138
139              evas_object_geometry_get(cur, &f_x, &f_y, &f_w, &f_h);
140              if (ELM_RECTS_INTERSECT
141                  (x, y, v_w, v_h, (f_x - c_x), (f_y - c_y), f_w, f_h))
142                {
143                   if ((f_x - c_x) > x)
144                     cur_weight += ((f_x - c_x) - x) * ((f_x - c_x) - x);
145                   if ((f_y - c_y) > y)
146                     cur_weight += ((f_y - c_y) - y) * ((f_y - c_y) - y);
147                   if (cur_weight == 0.0)
148                     {
149                        elm_widget_focus_steal(cur, NULL);
150                        eina_list_free(can_focus_list);
151                        return EINA_TRUE;
152                     }
153                   cur_weight = 1.0 / cur_weight;
154                   if (cur_weight > weight)
155                     {
156                        new_focus = cur;
157                        weight = cur_weight;
158                     }
159                }
160           }
161         if (new_focus)
162           {
163              elm_widget_focus_steal(new_focus, NULL);
164              eina_list_free(can_focus_list);
165              return EINA_TRUE;
166           }
167      }
168    else
169      {
170         Eina_Bool r = EINA_FALSE;
171
172         if (!strcmp(dir, "left"))
173           r = elm_widget_focus_next_get(obj, ELM_FOCUS_LEFT, &new_focus, &new_focus_item);
174         else if (!strcmp(dir, "right"))
175           r = elm_widget_focus_next_get(obj, ELM_FOCUS_RIGHT, &new_focus, &new_focus_item);
176         else if (!strcmp(dir, "up"))
177           r = elm_widget_focus_next_get(obj, ELM_FOCUS_UP, &new_focus, &new_focus_item);
178         else if (!strcmp(dir, "down"))
179           r = elm_widget_focus_next_get(obj, ELM_FOCUS_DOWN, &new_focus, &new_focus_item);
180
181         if (r && new_focus)
182           {
183              elm_widget_focus_steal(new_focus, new_focus_item);
184              eina_list_free(can_focus_list);
185              return EINA_TRUE;
186           }
187      }
188
189    eina_list_free(can_focus_list);
190
191    if (!strcmp(dir, "left"))
192      {
193         if ((x <= 0) && (!sd->loop_h)) return EINA_FALSE;
194         x -= step_x;
195      }
196    else if (!strcmp(dir, "right"))
197      {
198         if ((x >= (max_x - v_w)) && (!sd->loop_h)) return EINA_FALSE;
199         x += step_x;
200      }
201    else if (!strcmp(dir, "up"))
202      {
203         if ((y <= 0) && (!sd->loop_v)) return EINA_FALSE;
204         y -= step_y;
205      }
206    else if (!strcmp(dir, "down"))
207      {
208         if ((y >= (max_y - v_h)) && (!sd->loop_v)) return EINA_FALSE;
209         y += step_y;
210      }
211    else if (!strcmp(dir, "first"))
212      {
213         y = 0;
214      }
215    else if (!strcmp(dir, "last"))
216      {
217         y = max_y - v_h;
218      }
219    else if (!strcmp(dir, "prior"))
220      {
221         if (page_y < 0)
222           y -= -(page_y * v_h) / 100;
223         else
224           y -= page_y;
225      }
226    else if (!strcmp(dir, "next"))
227      {
228         if (page_y < 0)
229           y += -(page_y * v_h) / 100;
230         else
231           y += page_y;
232      }
233    else return EINA_FALSE;
234
235    eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
236    return EINA_TRUE;
237 }
238
239 EOLIAN static Eina_Bool
240 _elm_scroller_elm_widget_event(Eo *obj, Elm_Scroller_Data *sd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
241 {
242    (void) src;
243    Evas_Event_Key_Down *ev = event_info;
244
245    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
246    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
247
248    if (!_elm_config_key_binding_call(obj, ev, key_actions))
249      return EINA_FALSE;
250
251    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
252    return EINA_TRUE;
253 }
254
255 EOLIAN static Eina_Bool
256 _elm_scroller_elm_widget_activate(Eo *obj, Elm_Scroller_Data *_pd EINA_UNUSED, Elm_Activate act)
257 {
258    Evas_Coord x = 0;
259    Evas_Coord y = 0;
260    Evas_Coord v_w = 0;
261    Evas_Coord v_h = 0;
262    Evas_Coord page_x = 0;
263    Evas_Coord page_y = 0;
264
265    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
266    if (act == ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
267
268    eo_do(obj,
269          elm_interface_scrollable_content_pos_get(&x, &y),
270          elm_interface_scrollable_page_size_get(&page_x, &page_y),
271          elm_interface_scrollable_content_viewport_geometry_get
272          (NULL, NULL, &v_w, &v_h));
273
274    if (act == ELM_ACTIVATE_UP)
275      {
276         if (page_y < 0)
277           y -= -(page_y * v_h) / 100;
278         else
279           y -= page_y;
280      }
281    else if (act == ELM_ACTIVATE_DOWN)
282      {
283         if (page_y < 0)
284           y += -(page_y * v_h) / 100;
285         else
286           y += page_y;
287      }
288    else if (act == ELM_ACTIVATE_LEFT)
289      {
290         if (page_x < 0)
291           x -= -(page_x * v_w) / 100;
292         else
293           x -= page_x;
294      }
295    else if (act == ELM_ACTIVATE_RIGHT)
296      {
297         if (page_x < 0)
298           x += -(page_x * v_w) / 100;
299         else
300           x += page_x;
301      }
302
303    eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
304
305    return EINA_TRUE;
306 }
307
308 EOLIAN static void
309 _elm_scroller_elm_layout_sizing_eval(Eo *obj, Elm_Scroller_Data *sd)
310 {
311    Evas_Coord vw = 0, vh = 0, minw = 0, minh = 0, maxw = 0, maxh = 0, w, h,
312               vmw, vmh;
313    Evas_Coord h_pagesize, v_pagesize;
314    double xw = 0.0, yw = 0.0;
315    int i;
316
317    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
318
319    if (sd->content)
320      {
321         evas_object_size_hint_min_get(sd->content, &minw, &minh);
322         evas_object_size_hint_max_get(sd->content, &maxw, &maxh);
323         evas_object_size_hint_weight_get(sd->content, &xw, &yw);
324      }
325
326    eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
327          (NULL, NULL, &vw, &vh));
328    if (xw > 0.0)
329      {
330         if ((minw > 0) && (vw < minw))
331           vw = minw;
332         else if ((maxw > 0) && (vw > maxw))
333           vw = maxw;
334      }
335    else if (minw > 0)
336      vw = minw;
337
338    if (yw > 0.0)
339      {
340         if ((minh > 0) && (vh < minh))
341           vh = minh;
342         else if ((maxh > 0) && (vh > maxh))
343           vh = maxh;
344      }
345    else if (minh > 0)
346      vh = minh;
347
348    if (sd->content) evas_object_resize(sd->content, vw, vh);
349    if (sd->contents) evas_object_resize(sd->contents, vw, vh);
350
351    for (i = 0 ; i < 3 ; i++)
352      {
353         if (!sd->proxy_content[i]) continue;
354         eo_do((Eo *)obj, elm_interface_scrollable_paging_get(NULL, NULL, &h_pagesize, &v_pagesize));
355         evas_object_image_fill_set(sd->proxy_content[i], 0, 0, vw, vh);
356         evas_object_size_hint_min_set(sd->proxy_content[i],
357                                       h_pagesize, v_pagesize);
358      }
359
360    w = -1;
361    h = -1;
362    vmw = vmh = 0;
363    edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
364
365    if (sd->min_w) w = vmw + minw;
366    if (sd->min_h) h = vmh + minh;
367
368    evas_object_size_hint_max_get(obj, &maxw, &maxh);
369    if ((maxw > 0) && (w > maxw)) w = maxw;
370    if ((maxh > 0) && (h > maxh)) h = maxh;
371
372    evas_object_size_hint_min_set(obj, w, h);
373 }
374
375 static void
376 _mirrored_set(Evas_Object *obj,
377               Eina_Bool mirrored)
378 {
379    eo_do(obj, elm_interface_scrollable_mirrored_set(mirrored));
380 }
381
382 EOLIAN static Elm_Theme_Apply
383 _elm_scroller_elm_widget_theme_apply(Eo *obj, Elm_Scroller_Data *sd EINA_UNUSED)
384 {
385    Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
386    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
387    if (!int_ret) return ELM_THEME_APPLY_FAILED;
388
389    _mirrored_set(obj, elm_widget_mirrored_get(obj));
390
391    elm_layout_sizing_eval(obj);
392
393    return int_ret;
394 }
395
396 EOLIAN static Eina_Bool
397 _elm_scroller_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Scroller_Data *_pd EINA_UNUSED)
398 {
399    return EINA_TRUE;
400 }
401
402 EOLIAN static Eina_Bool
403 _elm_scroller_elm_widget_focus_next(Eo *obj EINA_UNUSED, Elm_Scroller_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
404 {
405    Evas_Object *cur;
406
407    if (!sd->content) return EINA_FALSE;
408
409    cur = sd->content;
410
411    /* access */
412    if (_elm_config->access_mode)
413      {
414         if ((elm_widget_can_focus_get(cur)) ||
415             (elm_widget_child_can_focus_get(cur)))
416           {
417              return elm_widget_focus_next_get(cur, dir, next, next_item);
418           }
419
420         return EINA_FALSE;
421      }
422
423    /* Try focus cycle in subitem */
424    if ((elm_widget_can_focus_get(cur)) ||
425        (elm_widget_child_can_focus_get(cur)))
426      {
427         Eina_Bool ret = EINA_FALSE;
428         Evas_Coord x = 0, y = 0;
429         Evas_Coord v_w = 0, v_h = 0;
430         Evas_Coord c_x = 0, c_y = 0;
431         Evas_Coord f_x = 0, f_y = 0, f_w = 0, f_h = 0;
432         Evas_Coord l_x = 0, l_y = 0, l_w = 0, l_h = 0;
433         Evas_Coord step_x = 0, step_y = 0;
434
435         ret =  elm_widget_focus_next_get(cur, dir, next, next_item);
436
437         eo_do(obj,
438               elm_interface_scrollable_content_pos_get(&x, &y),
439               elm_interface_scrollable_step_size_get(&step_x, &step_y),
440               elm_interface_scrollable_content_viewport_geometry_get
441               (NULL, NULL, &v_w, &v_h));
442         evas_object_geometry_get(sd->content, &c_x, &c_y, NULL, NULL);
443         evas_object_geometry_get(*next, &f_x, &f_y, &f_w, &f_h);
444         l_x = f_x - c_x - step_x;
445         l_y = f_y - c_y - step_y;
446         l_w = f_w + (step_x * 2);
447         l_h = f_h + (step_y * 2);
448
449         if (!ret || ELM_RECTS_INTERSECT(x, y, v_w, v_h, l_x, l_y, l_w, l_h))
450           return ret;
451      }
452
453    if (!(elm_widget_can_focus_get(obj)) &&
454        !(elm_widget_can_focus_get(cur)))
455       return EINA_FALSE;
456
457    /* Return */
458    *next = (Evas_Object *)obj;
459
460    return !elm_widget_focus_get(obj);
461 }
462
463 EOLIAN static Eina_Bool
464 _elm_scroller_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Scroller_Data *_pd EINA_UNUSED)
465 {
466    return EINA_TRUE;
467 }
468
469 EOLIAN static Eina_Bool
470 _elm_scroller_elm_widget_focus_direction(Eo *obj, Elm_Scroller_Data *sd, const Evas_Object *base, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
471 {
472    Evas_Object *cur;
473
474    if (!sd->content) return EINA_FALSE;
475
476    cur = sd->content;
477
478    /* access */
479    if (_elm_config->access_mode)
480      {
481         if ((elm_widget_can_focus_get(cur)) ||
482             (elm_widget_child_can_focus_get(cur)))
483           {
484              return elm_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
485           }
486
487         return EINA_FALSE;
488      }
489
490    /* Try focus cycle in subitem */
491    if ((elm_widget_can_focus_get(cur)) ||
492        (elm_widget_child_can_focus_get(cur)))
493      {
494         Eina_Bool ret = EINA_FALSE;
495         Evas_Coord x = 0, y = 0;
496         Evas_Coord v_w = 0, v_h = 0;
497         Evas_Coord c_x = 0, c_y = 0;
498         Evas_Coord f_x = 0, f_y = 0, f_w = 0, f_h = 0;
499         Evas_Coord l_x = 0, l_y = 0, l_w = 0, l_h = 0;
500         Evas_Coord step_x = 0, step_y = 0;
501
502         ret = elm_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
503
504         eo_do(obj,
505               elm_interface_scrollable_content_pos_get(&x, &y),
506               elm_interface_scrollable_step_size_get(&step_x, &step_y),
507               elm_interface_scrollable_content_viewport_geometry_get
508               (NULL, NULL, &v_w, &v_h));
509         evas_object_geometry_get(sd->content, &c_x, &c_y, NULL, NULL);
510         evas_object_geometry_get(*direction, &f_x, &f_y, &f_w, &f_h);
511         l_x = f_x - c_x - step_x;
512         l_y = f_y - c_y - step_y;
513         l_w = f_w + (step_x * 2);
514         l_h = f_h + (step_y * 2);
515
516         if (!ret || ELM_RECTS_INTERSECT(x, y, v_w, v_h, l_x, l_y, l_w, l_h))
517           return ret;
518      }
519
520    /* Return */
521    *direction = (Evas_Object *)obj;
522
523    return !elm_widget_focus_get(obj);
524 }
525
526 static void
527 _show_region_hook(void *data,
528                   Evas_Object *content_obj)
529 {
530    Evas_Coord x, y, w, h;
531
532    elm_widget_show_region_get(content_obj, &x, &y, &w, &h);
533    eo_do(data, elm_interface_scrollable_content_region_show(x, y, w, h));
534 }
535
536 static void
537 _changed_size_hints_cb(void *data,
538                        Evas *e EINA_UNUSED,
539                        Evas_Object *obj EINA_UNUSED,
540                        void *event_info EINA_UNUSED)
541 {
542    elm_layout_sizing_eval(data);
543 }
544
545 EOLIAN static Eina_Bool
546 _elm_scroller_elm_widget_sub_object_del(Eo *obj, Elm_Scroller_Data *sd, Evas_Object *sobj)
547 {
548    Eina_Bool int_ret = EINA_FALSE;
549    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
550    if (!int_ret) return EINA_FALSE;
551
552    if (sobj == sd->content)
553      {
554         if (elm_widget_is(sobj))
555           elm_widget_on_show_region_hook_set(sd->content, NULL, NULL);
556
557         sd->content = NULL;
558      }
559
560    return EINA_TRUE;
561 }
562
563 static void
564 _resize_cb(void *data,
565            Evas *e EINA_UNUSED,
566            Evas_Object *obj EINA_UNUSED,
567            void *event_info EINA_UNUSED)
568 {
569    elm_layout_sizing_eval(data);
570 }
571
572 static void
573 _edge_left_cb(Evas_Object *obj,
574               void *data EINA_UNUSED)
575 {
576    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_EDGE_LEFT, NULL));
577 }
578
579 static void
580 _edge_right_cb(Evas_Object *obj,
581                void *data EINA_UNUSED)
582 {
583    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_EDGE_RIGHT, NULL));
584 }
585
586 static void
587 _edge_top_cb(Evas_Object *obj,
588              void *data EINA_UNUSED)
589 {
590    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_EDGE_TOP, NULL));
591 }
592
593 static void
594 _edge_bottom_cb(Evas_Object *obj,
595                 void *data EINA_UNUSED)
596 {
597    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_EDGE_BOTTOM, NULL));
598 }
599
600 static void
601 _scroll_cb(Evas_Object *obj,
602            void *data EINA_UNUSED)
603 {
604    eo_do(obj, eo_event_callback_call
605      (EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL, NULL));
606 }
607
608 static void
609 _scroll_left_cb(Evas_Object *obj,
610            void *data EINA_UNUSED)
611 {
612    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_SCROLL_LEFT, NULL));
613 }
614
615 static void
616 _scroll_right_cb(Evas_Object *obj,
617            void *data EINA_UNUSED)
618 {
619    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_SCROLL_RIGHT, NULL));
620 }
621
622 static void
623 _scroll_up_cb(Evas_Object *obj,
624            void *data EINA_UNUSED)
625 {
626    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_SCROLL_UP, NULL));
627 }
628
629 static void
630 _scroll_down_cb(Evas_Object *obj,
631            void *data EINA_UNUSED)
632 {
633    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_SCROLL_DOWN, NULL));
634 }
635
636 static void
637 _scroll_anim_start_cb(Evas_Object *obj,
638                       void *data EINA_UNUSED)
639 {
640    eo_do(obj, eo_event_callback_call
641      (EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_START, NULL));
642 }
643
644 static void
645 _scroll_anim_stop_cb(Evas_Object *obj,
646                      void *data EINA_UNUSED)
647 {
648    eo_do(obj, eo_event_callback_call
649      (EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_STOP, NULL));
650    //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
651    if (_elm_atspi_enabled())
652      {
653         elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
654      }
655    //
656 }
657
658 static void
659 _scroll_drag_start_cb(Evas_Object *obj,
660                       void *data EINA_UNUSED)
661 {
662    eo_do(obj, eo_event_callback_call
663      (EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_START, NULL));
664 }
665
666 static void
667 _scroll_drag_stop_cb(Evas_Object *obj,
668                      void *data EINA_UNUSED)
669 {
670    eo_do(obj, eo_event_callback_call
671      (EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_STOP, NULL));
672    //TIZEN_ONLY: Let the screen-reader know when drag ends
673    if (_elm_atspi_enabled())
674      {
675         elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
676      }
677    //
678 }
679
680 static void
681 _vbar_drag_cb(Evas_Object *obj,
682                 void *data EINA_UNUSED)
683 {
684    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_VBAR_DRAG, NULL));
685 }
686
687 static void
688 _vbar_press_cb(Evas_Object *obj,
689                 void *data EINA_UNUSED)
690 {
691    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_VBAR_PRESS, NULL));
692 }
693
694 static void
695 _vbar_unpress_cb(Evas_Object *obj,
696                 void *data EINA_UNUSED)
697 {
698    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_VBAR_UNPRESS, NULL));
699 }
700
701 static void
702 _hbar_drag_cb(Evas_Object *obj,
703                 void *data EINA_UNUSED)
704 {
705    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_HBAR_DRAG, NULL));
706 }
707
708 static void
709 _hbar_press_cb(Evas_Object *obj,
710                 void *data EINA_UNUSED)
711 {
712    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_HBAR_PRESS, NULL));
713 }
714
715 static void
716 _hbar_unpress_cb(Evas_Object *obj,
717                 void *data EINA_UNUSED)
718 {
719    eo_do(obj, eo_event_callback_call(ELM_SCROLLER_EVENT_HBAR_UNPRESS, NULL));
720 }
721
722 static void
723 _page_change_cb(Evas_Object *obj,
724                 void *data EINA_UNUSED)
725 {
726    eo_do(obj, eo_event_callback_call
727      (ELM_SCROLLER_EVENT_SCROLL_PAGE_CHANGED, NULL));
728 }
729
730 static void
731 _loop_content_set(Evas_Object *obj, Elm_Scroller_Data *sd, Evas_Object *content)
732 {
733    if (!sd->contents)
734      {
735         sd->contents = elm_layout_add(obj);
736         evas_object_smart_member_add(sd->contents, obj);
737         if (!elm_layout_theme_set(sd->contents, "scroller", "contents", elm_widget_style_get(obj)))
738           CRI("Failed to set layout!");
739
740         evas_object_size_hint_weight_set(sd->contents, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
741         evas_object_size_hint_align_set(sd->contents, EVAS_HINT_FILL, EVAS_HINT_FILL);
742
743         elm_widget_sub_object_add(obj, sd->contents);
744         elm_widget_on_show_region_hook_set(sd->contents, _show_region_hook, obj);
745      }
746    elm_object_part_content_set(sd->contents, "elm.swallow.content", content);
747    sd->content = content;
748
749    if (sd->loop_h)
750      {
751        if (!sd->proxy_content[0])
752           sd->proxy_content[0] =
753              evas_object_image_add(evas_object_evas_get(sd->contents));
754         _elm_scroller_proxy_set(obj, sd, sd->proxy_content[0]);
755         elm_object_part_content_set(sd->contents, "elm.swallow.content_r",
756                                     sd->proxy_content[0]);
757      }
758
759    if (sd->loop_v)
760      {
761         if (!sd->proxy_content[1])
762           sd->proxy_content[1] =
763              evas_object_image_add(evas_object_evas_get(sd->contents));
764         _elm_scroller_proxy_set(obj, sd, sd->proxy_content[1]);
765         elm_object_part_content_set(sd->contents, "elm.swallow.content_b",
766                                     sd->proxy_content[1]);
767      }
768
769    if (sd->loop_h && sd->loop_v)
770      {
771         if (!sd->proxy_content[2])
772           sd->proxy_content[2] =
773              evas_object_image_add(evas_object_evas_get(sd->contents));
774         _elm_scroller_proxy_set(obj, sd, sd->proxy_content[2]);
775         elm_object_part_content_set(sd->contents, "elm.swallow.content_rb",
776                                     sd->proxy_content[2]);
777      }
778 }
779
780 EOLIAN static Eina_Bool
781 _elm_scroller_elm_container_content_set(Eo *obj, Elm_Scroller_Data *sd, const char *part, Evas_Object *content)
782 {
783    if (part && strcmp(part, "default"))
784      {
785         Eina_Bool int_ret = EINA_FALSE;
786         eo_do_super(obj, MY_CLASS, int_ret = elm_obj_container_content_set(part, content));
787         return int_ret;
788      }
789
790    if (sd->content == content) return EINA_TRUE;
791
792    evas_object_del(sd->content);
793    sd->content = content;
794
795    if (content)
796      {
797         if (elm_widget_is(content))
798           elm_widget_on_show_region_hook_set(content, _show_region_hook, obj);
799         elm_widget_sub_object_add(obj, content);
800
801         if (sd->loop_h || sd->loop_v)
802           {
803              _loop_content_set(obj, sd, content);
804              if(sd->contents)
805                content = sd->contents;
806           }
807         eo_do(obj, elm_interface_scrollable_content_set(content));
808      }
809    else
810      {
811         int i;
812         for (i = 0; i < 3; i ++)
813           {
814              if (!sd->proxy_content[i]) continue;
815              evas_object_del(sd->proxy_content[i]);
816              sd->proxy_content[i] = NULL;
817           }
818      }
819
820    elm_layout_sizing_eval(obj);
821
822    return EINA_TRUE;
823 }
824
825 EOLIAN static Evas_Object*
826 _elm_scroller_elm_container_content_get(Eo *obj, Elm_Scroller_Data *sd, const char *part)
827 {
828    if (part && strcmp(part, "default"))
829      {
830         Evas_Object *ret = NULL;
831         eo_do_super(obj, MY_CLASS, ret = elm_obj_container_content_get(part));
832         return ret;
833      }
834
835    return sd->content;
836 }
837
838 EOLIAN static Evas_Object*
839 _elm_scroller_elm_container_content_unset(Eo *obj, Elm_Scroller_Data *sd, const char *part)
840 {
841    Evas_Object *ret = NULL;
842    if (part && strcmp(part, "default"))
843      {
844         eo_do_super(obj, MY_CLASS, ret = elm_obj_container_content_unset(part));
845         return ret;
846      }
847
848    if (!sd->content) return NULL;
849
850    ret = sd->content;
851    if (sd->loop_h || sd->loop_v)
852      _elm_widget_sub_object_redirect_to_top(obj, sd->contents);
853    else
854      _elm_widget_sub_object_redirect_to_top(obj, sd->content);
855    eo_do(obj, elm_interface_scrollable_content_set(NULL));
856    sd->content = NULL;
857
858    return ret;
859 }
860
861 static void
862 _elm_scroller_content_min_limit_cb(Evas_Object *obj,
863                                    Eina_Bool w,
864                                    Eina_Bool h)
865 {
866    ELM_SCROLLER_DATA_GET(obj, sd);
867
868    sd->min_w = !!w;
869    sd->min_h = !!h;
870
871    elm_layout_sizing_eval(obj);
872 }
873
874 static void
875 _elm_scroller_content_viewport_resize_cb(Evas_Object *obj,
876                                    Evas_Coord w EINA_UNUSED,
877                                    Evas_Coord h EINA_UNUSED)
878 {
879    elm_layout_sizing_eval(obj);
880 }
881
882 EOLIAN static void
883 _elm_scroller_evas_object_smart_add(Eo *obj, Elm_Scroller_Data *priv)
884 {
885    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
886    Evas_Coord minw, minh;
887
888    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
889    elm_widget_sub_object_parent_add(obj);
890    elm_widget_can_focus_set(obj, EINA_TRUE);
891
892    if (!elm_layout_theme_set
893        (obj, "scroller", "base", elm_widget_style_get(obj)))
894      CRI("Failed to set layout!");
895
896    priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
897    evas_object_smart_member_add(priv->hit_rect, obj);
898    elm_widget_sub_object_add(obj, priv->hit_rect);
899
900    evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
901    evas_object_show(priv->hit_rect);
902    evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
903
904    eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
905
906    evas_object_event_callback_add
907      (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints_cb, obj);
908
909    edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
910    evas_object_size_hint_min_set(obj, minw, minh);
911    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
912
913    _mirrored_set(obj, elm_widget_mirrored_get(obj));
914
915    eo_do(obj,
916          elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
917          elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
918          elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
919          elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
920          elm_interface_scrollable_scroll_cb_set(_scroll_cb),
921          elm_interface_scrollable_scroll_left_cb_set(_scroll_left_cb),
922          elm_interface_scrollable_scroll_right_cb_set(_scroll_right_cb),
923          elm_interface_scrollable_scroll_up_cb_set(_scroll_up_cb),
924          elm_interface_scrollable_scroll_down_cb_set(_scroll_down_cb),
925          elm_interface_scrollable_animate_start_cb_set(_scroll_anim_start_cb),
926          elm_interface_scrollable_animate_stop_cb_set(_scroll_anim_stop_cb),
927          elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
928          elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
929          elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
930          elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
931          elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
932          elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
933          elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
934          elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb),
935          elm_interface_scrollable_page_change_cb_set(_page_change_cb),
936          elm_interface_scrollable_content_min_limit_cb_set
937          (_elm_scroller_content_min_limit_cb),
938          elm_interface_scrollable_content_viewport_resize_cb_set
939          (_elm_scroller_content_viewport_resize_cb));
940 }
941
942 EOLIAN static void
943 _elm_scroller_evas_object_smart_move(Eo *obj, Elm_Scroller_Data *sd, Evas_Coord x, Evas_Coord y)
944 {
945    eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
946
947    evas_object_move(sd->hit_rect, x, y);
948 }
949
950 EOLIAN static void
951 _elm_scroller_evas_object_smart_resize(Eo *obj, Elm_Scroller_Data *sd, Evas_Coord w, Evas_Coord h)
952 {
953    eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
954
955    evas_object_resize(sd->hit_rect, w, h);
956 }
957
958 EOLIAN static void
959 _elm_scroller_evas_object_smart_member_add(Eo *obj, Elm_Scroller_Data *sd, Evas_Object *member)
960 {
961    eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
962
963    if (sd->hit_rect)
964      evas_object_raise(sd->hit_rect);
965 }
966
967 EAPI Evas_Object *
968 elm_scroller_add(Evas_Object *parent)
969 {
970    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
971    Evas_Object *obj = eo_add(MY_CLASS, parent);
972    return obj;
973 }
974
975 EOLIAN static Eo *
976 _elm_scroller_eo_base_constructor(Eo *obj, Elm_Scroller_Data *_pd EINA_UNUSED)
977 {
978    obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
979    eo_do(obj,
980          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
981          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
982          elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_SCROLL_PANE));
983
984    return obj;
985 }
986
987 /* deprecated */
988 EOLIAN static void
989 _elm_scroller_custom_widget_base_theme_set(Eo *obj, Elm_Scroller_Data *_pd EINA_UNUSED, const char *klass, const char *group)
990 {
991    ELM_LAYOUT_DATA_GET(obj, ld);
992
993    EINA_SAFETY_ON_NULL_RETURN(klass);
994    EINA_SAFETY_ON_NULL_RETURN(group);
995
996    if (eina_stringshare_replace(&(ld->klass), klass) ||
997        eina_stringshare_replace(&(ld->group), group))
998       eo_do(obj, elm_obj_widget_theme_apply());
999 }
1000
1001 EAPI void
1002 elm_scroller_content_min_limit(Evas_Object *obj,
1003                                Eina_Bool w,
1004                                Eina_Bool h)
1005 {
1006    ELM_SCROLLABLE_CHECK(obj);
1007
1008    eo_do(obj, elm_interface_scrollable_content_min_limit(w, h));
1009 }
1010
1011 EAPI void
1012 elm_scroller_region_show(Evas_Object *obj,
1013                          Evas_Coord x,
1014                          Evas_Coord y,
1015                          Evas_Coord w,
1016                          Evas_Coord h)
1017 {
1018    ELM_SCROLLABLE_CHECK(obj);
1019
1020    eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
1021 }
1022
1023 EAPI void
1024 elm_scroller_policy_set(Evas_Object *obj,
1025                         Elm_Scroller_Policy policy_h,
1026                         Elm_Scroller_Policy policy_v)
1027 {
1028    ELM_SCROLLABLE_CHECK(obj);
1029    eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
1030 }
1031
1032 EOLIAN static void
1033 _elm_scroller_elm_interface_scrollable_policy_set(Eo *obj, Elm_Scroller_Data *sd EINA_UNUSED, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
1034 {
1035    if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
1036        (policy_v >= ELM_SCROLLER_POLICY_LAST))
1037      return;
1038
1039    eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
1040 }
1041
1042 EAPI void
1043 elm_scroller_policy_get(const Evas_Object *obj,
1044                         Elm_Scroller_Policy *policy_h,
1045                         Elm_Scroller_Policy *policy_v)
1046 {
1047    ELM_SCROLLABLE_CHECK(obj);
1048
1049    eo_do((Eo *) obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
1050 }
1051
1052 EAPI void
1053 elm_scroller_single_direction_set(Evas_Object *obj,
1054                                   Elm_Scroller_Single_Direction single_dir)
1055 {
1056    ELM_SCROLLABLE_CHECK(obj);
1057    eo_do(obj, elm_interface_scrollable_single_direction_set(single_dir));
1058 }
1059
1060 EOLIAN static void
1061 _elm_scroller_elm_interface_scrollable_single_direction_set(Eo *obj, Elm_Scroller_Data *sd EINA_UNUSED, Elm_Scroller_Single_Direction single_dir)
1062 {
1063    if (single_dir >= ELM_SCROLLER_SINGLE_DIRECTION_LAST)
1064      return;
1065
1066    eo_do_super(obj, MY_CLASS,
1067                elm_interface_scrollable_single_direction_set(single_dir));
1068 }
1069
1070 EAPI Elm_Scroller_Single_Direction
1071 elm_scroller_single_direction_get(const Evas_Object *obj)
1072 {
1073    ELM_SCROLLABLE_CHECK(obj, ELM_SCROLLER_SINGLE_DIRECTION_NONE);
1074    Elm_Scroller_Single_Direction single_dir = ELM_SCROLLER_SINGLE_DIRECTION_NONE;
1075
1076    eo_do((Eo *) obj, single_dir = elm_interface_scrollable_single_direction_get());
1077    return single_dir;
1078 }
1079
1080 EOLIAN static Elm_Scroller_Single_Direction
1081 _elm_scroller_elm_interface_scrollable_single_direction_get(Eo *obj, Elm_Scroller_Data *sd EINA_UNUSED)
1082 {
1083    Elm_Scroller_Single_Direction ret = ELM_SCROLLER_SINGLE_DIRECTION_NONE;
1084    eo_do_super(obj, MY_CLASS,
1085                ret = elm_interface_scrollable_single_direction_get());
1086    return ret;
1087 }
1088
1089 EAPI void
1090 elm_scroller_region_get(const Evas_Object *obj,
1091                         Evas_Coord *x,
1092                         Evas_Coord *y,
1093                         Evas_Coord *w,
1094                         Evas_Coord *h)
1095 {
1096    ELM_SCROLLABLE_CHECK(obj);
1097    eo_do((Eo *) obj, elm_interface_scrollable_content_region_get(x, y, w, h));
1098 }
1099
1100 EAPI void
1101 elm_scroller_child_size_get(const Evas_Object *obj,
1102                             Evas_Coord *w,
1103                             Evas_Coord *h)
1104 {
1105    ELM_SCROLLABLE_CHECK(obj);
1106
1107    eo_do((Eo *) obj, elm_interface_scrollable_content_size_get(w, h));
1108 }
1109
1110 EAPI void
1111 elm_scroller_page_snap_set(Evas_Object *obj,
1112                              Eina_Bool page_snap_h,
1113                              Eina_Bool page_snap_v)
1114 {
1115    ELM_SCROLLABLE_CHECK(obj);
1116
1117    eo_do(obj, elm_interface_scrollable_page_snap_allow_set
1118          (page_snap_h, page_snap_v));
1119 }
1120
1121 EAPI void
1122 elm_scroller_page_snap_get(const Evas_Object *obj,
1123                              Eina_Bool *page_snap_h,
1124                              Eina_Bool *page_snap_v)
1125 {
1126    ELM_SCROLLABLE_CHECK(obj);
1127
1128    eo_do((Eo *) obj, elm_interface_scrollable_page_snap_allow_get
1129          (page_snap_h, page_snap_v));
1130 }
1131
1132 EAPI void
1133 elm_scroller_bounce_set(Evas_Object *obj,
1134                         Eina_Bool h_bounce,
1135                         Eina_Bool v_bounce)
1136 {
1137    ELM_SCROLLABLE_CHECK(obj);
1138
1139    eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
1140 }
1141
1142 EAPI void
1143 elm_scroller_bounce_get(const Evas_Object *obj,
1144                         Eina_Bool *h_bounce,
1145                         Eina_Bool *v_bounce)
1146 {
1147    ELM_SCROLLABLE_CHECK(obj);
1148
1149    eo_do((Eo *) obj, elm_interface_scrollable_bounce_allow_get(h_bounce, v_bounce));
1150 }
1151
1152 EAPI void
1153 elm_scroller_page_relative_set(Evas_Object *obj,
1154                                double h_pagerel,
1155                                double v_pagerel)
1156 {
1157    ELM_SCROLLABLE_CHECK(obj);
1158
1159    eo_do((Eo *)obj, elm_interface_scrollable_page_relative_set(h_pagerel, v_pagerel));
1160 }
1161
1162 EAPI void
1163 elm_scroller_page_relative_get(const Evas_Object *obj,
1164                                double *h_pagerel,
1165                                double *v_pagerel)
1166 {
1167    ELM_SCROLLABLE_CHECK(obj);
1168
1169    eo_do((Eo *)obj, elm_interface_scrollable_paging_get(h_pagerel, v_pagerel, NULL, NULL));
1170 }
1171
1172 EAPI void
1173 elm_scroller_page_size_set(Evas_Object *obj,
1174                            Evas_Coord h_pagesize,
1175                            Evas_Coord v_pagesize)
1176 {
1177    ELM_SCROLLABLE_CHECK(obj);
1178    eo_do(obj, elm_interface_scrollable_page_size_set(h_pagesize, v_pagesize));
1179 }
1180
1181 EOLIAN static void
1182 _elm_scroller_elm_interface_scrollable_page_size_set(Eo *obj, Elm_Scroller_Data *sd EINA_UNUSED, Evas_Coord h_pagesize, Evas_Coord v_pagesize)
1183 {
1184    double pagerel_h = 0.0, pagerel_v = 0.0;
1185
1186    eo_do(obj, elm_interface_scrollable_paging_get(&pagerel_h, &pagerel_v, NULL, NULL));
1187
1188    eo_do(obj, elm_interface_scrollable_paging_set(pagerel_h, pagerel_v, h_pagesize, v_pagesize));
1189 }
1190
1191 EAPI void
1192 elm_scroller_page_size_get(const Evas_Object *obj,
1193                            Evas_Coord *h_pagesize,
1194                            Evas_Coord *v_pagesize)
1195 {
1196    ELM_SCROLLABLE_CHECK(obj);
1197
1198    eo_do((Eo *)obj, elm_interface_scrollable_paging_get(NULL, NULL, h_pagesize, v_pagesize));
1199 }
1200
1201 EOLIAN static void
1202 _elm_scroller_page_scroll_limit_set(const Eo *obj, Elm_Scroller_Data *_pd EINA_UNUSED, int page_limit_h, int page_limit_v)
1203 {
1204    if (page_limit_h < 1)
1205      page_limit_h = 9999;
1206    if (page_limit_v < 1)
1207      page_limit_v = 9999;
1208
1209    eo_do(obj, elm_interface_scrollable_page_scroll_limit_set
1210          (page_limit_h, page_limit_v));
1211 }
1212
1213 EOLIAN static void
1214 _elm_scroller_page_scroll_limit_get(const Eo *obj, Elm_Scroller_Data *_pd EINA_UNUSED, int *page_limit_h, int *page_limit_v)
1215 {
1216    eo_do(obj, elm_interface_scrollable_page_scroll_limit_get
1217          (page_limit_h, page_limit_v));
1218 }
1219
1220 EAPI void
1221 elm_scroller_current_page_get(const Evas_Object *obj,
1222                               int *h_pagenumber,
1223                               int *v_pagenumber)
1224 {
1225    ELM_SCROLLABLE_CHECK(obj);
1226
1227    eo_do((Eo *) obj, elm_interface_scrollable_current_page_get(h_pagenumber, v_pagenumber));
1228 }
1229
1230 EAPI void
1231 elm_scroller_last_page_get(const Evas_Object *obj,
1232                            int *h_pagenumber,
1233                            int *v_pagenumber)
1234 {
1235    ELM_SCROLLABLE_CHECK(obj);
1236
1237    eo_do((Eo *) obj, elm_interface_scrollable_last_page_get(h_pagenumber, v_pagenumber));
1238 }
1239
1240 EAPI void
1241 elm_scroller_page_show(Evas_Object *obj,
1242                        int h_pagenumber,
1243                        int v_pagenumber)
1244 {
1245    ELM_SCROLLABLE_CHECK(obj);
1246
1247    eo_do(obj, elm_interface_scrollable_page_show(h_pagenumber, v_pagenumber));
1248 }
1249
1250 EAPI void
1251 elm_scroller_page_bring_in(Evas_Object *obj,
1252                            int h_pagenumber,
1253                            int v_pagenumber)
1254 {
1255    ELM_SCROLLABLE_CHECK(obj);
1256
1257    eo_do(obj, elm_interface_scrollable_page_bring_in(h_pagenumber, v_pagenumber));
1258 }
1259
1260 EAPI void
1261 elm_scroller_region_bring_in(Evas_Object *obj,
1262                              Evas_Coord x,
1263                              Evas_Coord y,
1264                              Evas_Coord w,
1265                              Evas_Coord h)
1266 {
1267    ELM_SCROLLABLE_CHECK(obj);
1268
1269    eo_do(obj, elm_interface_scrollable_region_bring_in(x, y, w, h));
1270 }
1271
1272 EAPI void
1273 elm_scroller_gravity_set(Evas_Object *obj,
1274                          double x,
1275                          double y)
1276 {
1277    ELM_SCROLLABLE_CHECK(obj);
1278
1279    eo_do(obj, elm_interface_scrollable_gravity_set(x, y));
1280 }
1281
1282 EAPI void
1283 elm_scroller_gravity_get(const Evas_Object *obj,
1284                          double *x,
1285                          double *y)
1286 {
1287    ELM_SCROLLABLE_CHECK(obj);
1288
1289    eo_do((Eo *) obj, elm_interface_scrollable_gravity_get(x, y));
1290 }
1291
1292 EAPI void
1293 elm_scroller_movement_block_set(Evas_Object *obj,
1294                                 Elm_Scroller_Movement_Block block)
1295 {
1296    ELM_SCROLLABLE_CHECK(obj);
1297
1298    eo_do(obj, elm_interface_scrollable_movement_block_set(block));
1299 }
1300
1301 EAPI Elm_Scroller_Movement_Block
1302 elm_scroller_movement_block_get(const Evas_Object *obj)
1303 {
1304    Elm_Scroller_Movement_Block block = ELM_SCROLLER_MOVEMENT_NO_BLOCK;
1305
1306    ELM_SCROLLABLE_CHECK(obj, ELM_SCROLLER_MOVEMENT_NO_BLOCK);
1307
1308    eo_do((Eo *) obj, block = elm_interface_scrollable_movement_block_get());
1309
1310    return block;
1311 }
1312
1313 EAPI void
1314 elm_scroller_step_size_set(Evas_Object *obj,
1315                            Evas_Coord x,
1316                            Evas_Coord y)
1317 {
1318    ELM_SCROLLABLE_CHECK(obj);
1319
1320    eo_do(obj, elm_interface_scrollable_step_size_set(x, y));
1321 }
1322
1323 EAPI void
1324 elm_scroller_step_size_get(const Evas_Object *obj,
1325                            Evas_Coord *x,
1326                            Evas_Coord *y)
1327 {
1328    ELM_SCROLLABLE_CHECK(obj);
1329
1330    eo_do((Eo *) obj, elm_interface_scrollable_step_size_get(x, y));
1331 }
1332
1333 EAPI void
1334 elm_scroller_loop_set(Evas_Object *obj,
1335                       Eina_Bool loop_h,
1336                       Eina_Bool loop_v)
1337 {
1338    ELM_SCROLLABLE_CHECK(obj);
1339    ELM_SCROLLER_DATA_GET(obj, sd);
1340
1341    int i;
1342
1343    if (sd->loop_h == loop_h && sd->loop_v == loop_v) return;
1344
1345    sd->loop_h = loop_h;
1346    sd->loop_v = loop_v;
1347
1348    eo_do(obj, elm_interface_scrollable_loop_set(loop_h, loop_v));
1349
1350    if (sd->content)
1351      {
1352         if (sd->loop_h || sd->loop_v)
1353           {
1354              eo_do(obj, elm_interface_scrollable_content_set(NULL));
1355              _loop_content_set(obj, sd, sd->content);
1356
1357              if (sd->contents)
1358                {
1359                   eo_do(obj, elm_interface_scrollable_content_set(sd->contents));
1360                   elm_widget_sub_object_add(obj, sd->contents);
1361                   elm_widget_on_show_region_hook_set(sd->contents, _show_region_hook, obj);
1362                }
1363           }
1364         else
1365           {
1366              for (i = 0 ; i < 3 ; i++)
1367                {
1368                   if (sd->proxy_content[i])
1369                     {
1370                        evas_object_del(sd->proxy_content[i]);
1371                        sd->proxy_content[i]= NULL;
1372                     }
1373                }
1374           }
1375      }
1376    elm_layout_sizing_eval(obj);
1377 }
1378
1379 EAPI void
1380 elm_scroller_loop_get(const Evas_Object *obj,
1381                       Eina_Bool *loop_h,
1382                       Eina_Bool *loop_v)
1383 {
1384    ELM_SCROLLABLE_CHECK(obj);
1385
1386    eo_do(obj, elm_interface_scrollable_loop_get(loop_h, loop_v));
1387 }
1388
1389 EAPI void
1390 elm_scroller_wheel_disabled_set(Evas_Object *obj, Eina_Bool disabled)
1391 {
1392    ELM_SCROLLABLE_CHECK(obj);
1393
1394    eo_do((Eo *)obj, elm_interface_scrollable_wheel_disabled_set(disabled));
1395 }
1396
1397 EAPI Eina_Bool
1398 elm_scroller_wheel_disabled_get(const Evas_Object *obj)
1399 {
1400    ELM_SCROLLABLE_CHECK(obj, EINA_FALSE);
1401
1402    Eina_Bool ret;
1403
1404    return eo_do_ret((Eo *) obj, ret, elm_interface_scrollable_wheel_disabled_get());
1405 }
1406
1407 EOLIAN static void
1408 _elm_scroller_propagate_events_set(Eo *obj, Elm_Scroller_Data *_pd EINA_UNUSED, Eina_Bool propagation)
1409 {
1410    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1411
1412    evas_object_propagate_events_set(wd->resize_obj, propagation);
1413 }
1414
1415 EOLIAN static Eina_Bool
1416 _elm_scroller_propagate_events_get(Eo *obj, Elm_Scroller_Data *_pd EINA_UNUSED)
1417 {
1418    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1419    return evas_object_propagate_events_get(wd->resize_obj);
1420 }
1421
1422 static void
1423 _elm_scroller_class_constructor(Eo_Class *klass)
1424 {
1425    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
1426 }
1427
1428 EOLIAN const Elm_Atspi_Action *
1429 _elm_scroller_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Scroller_Data *pd EINA_UNUSED)
1430 {
1431    static Elm_Atspi_Action atspi_actions[] = {
1432           { "move,prior", "move", "prior", _key_action_move},
1433           { "move,next", "move", "next", _key_action_move},
1434           { "move,left", "move", "left", _key_action_move},
1435           { "move,right", "move", "right", _key_action_move},
1436           { "move,up", "move", "up", _key_action_move},
1437           { "move,down", "move", "down", _key_action_move},
1438           { "move,first", "move", "first", _key_action_move},
1439           { "move,last", "move", "last", _key_action_move},
1440           { NULL, NULL, NULL, NULL }
1441    };
1442    return &atspi_actions[0];
1443 }
1444
1445 #include "elm_scroller.eo.c"