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