}
}
+//TIZEN_ONLY(20171102): add scroll functions for Universal-Switch scroll's functionality
+typedef struct scroll_timer_data {
+ Ecore_Timer *timer;
+ Eo *obj;
+ int step, start_pos, vertical;
+ double step_calc_time;
+ double end_time;
+} scroll_timer_data;
+static scroll_timer_data scroll_info;
+
+static double _scroll_timer_data_calculate(int *pos, int start_pos, int step, int size, int view,
+ double now, double step_calc_time)
+{
+ *pos = start_pos + step * (now - step_calc_time);
+
+ double timeToFinish = 0;
+
+ if (step > 0)
+ {
+ if (*pos + view > size)
+ {
+ *pos = size - view;
+ if (*pos < 0) *pos = 0;
+ }
+ else
+ {
+ timeToFinish = ((double)size - (*pos + view)) / step;
+ }
+ }
+ else if (step < 0)
+ {
+ if (*pos < 0)
+ {
+ *pos = 0;
+ }
+ else
+ {
+ timeToFinish = ((double)*pos) / -step;
+ }
+ }
+
+ if (timeToFinish < 0) timeToFinish = 0;
+
+ return timeToFinish;
+}
+
+static double _scroll_timer_data_update(double now, Eina_Bool force_reset)
+{
+ if (!scroll_info.obj) {
+ return 0;
+ }
+ int size_w, size_h, view_w, view_h, pos_x, pos_y;
+ eo_do(scroll_info.obj,
+ elm_interface_scrollable_content_pos_get(&pos_x, &pos_y),
+ elm_interface_scrollable_content_size_get(&size_w, &size_h),
+ elm_interface_scrollable_content_viewport_geometry_get(NULL, NULL, &view_w, &view_h));
+
+ double timeToFinish = 0;
+ if (scroll_info.vertical)
+ {
+ timeToFinish = _scroll_timer_data_calculate(&pos_y, scroll_info.start_pos, scroll_info.step,
+ size_h, view_h, now, scroll_info.step_calc_time);
+ if (force_reset) scroll_info.start_pos = pos_y;
+ }
+ else
+ {
+ timeToFinish = _scroll_timer_data_calculate(&pos_x, scroll_info.start_pos, scroll_info.step,
+ size_w, view_w, now, scroll_info.step_calc_time);
+ if (force_reset) scroll_info.start_pos = pos_x;
+ }
+ if (force_reset) scroll_info.step_calc_time = now;
+ eo_do(scroll_info.obj, elm_interface_scrollable_content_pos_set(pos_x, pos_y, EINA_TRUE));
+ return timeToFinish;
+}
+
+static Eina_Bool scroll_timer_cb(void *data)
+{
+ double now = ecore_time_get();
+ if (now >= scroll_info.end_time || _scroll_timer_data_update(now, EINA_FALSE) == 0)
+ {
+ scroll_info.timer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+EOLIAN static double
+_elm_interface_scrollable_content_scroll_auto(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroll_Direction direction, unsigned int ustep)
+{
+ double remainingTime = 0;
+
+ int step = (int)ustep;
+ if (step == 0)
+ {
+ remainingTime = 0;
+ if (scroll_info.timer)
+ {
+ ecore_timer_del(scroll_info.timer);
+ scroll_info.timer = NULL;
+ }
+ }
+ else
+ {
+ double now = ecore_time_get();
+ scroll_info.end_time = now + 1.0f;
+ scroll_info.vertical = direction == ELM_SCROLL_DIRECTION_UP || direction == ELM_SCROLL_DIRECTION_DOWN;
+
+ if (direction == ELM_SCROLL_DIRECTION_UP || direction == ELM_SCROLL_DIRECTION_LEFT) step = -step;
+
+ if (!scroll_info.timer || scroll_info.obj != obj)
+ {
+ scroll_info.obj = obj;
+ scroll_info.step_calc_time = now;
+ scroll_info.step = step;
+
+ if (scroll_info.vertical)
+ eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &scroll_info.start_pos));
+ else
+ eo_do(obj, elm_interface_scrollable_content_pos_get(&scroll_info.start_pos, NULL));
+ remainingTime = _scroll_timer_data_update(now, EINA_FALSE);
+ }
+ else
+ {
+ remainingTime = _scroll_timer_data_update(now, EINA_TRUE);
+ scroll_info.step = step;
+ }
+ // TODO: remove move by timer and some sort of animator object to animate scrolling
+ if (!scroll_info.timer) scroll_info.timer = ecore_timer_add(0.04f, scroll_timer_cb, NULL);
+ }
+ return remainingTime;
+}
+
+static void _scroll_page_calculate(int *pos, int size, int view, int positive_direction)
+{
+ if (positive_direction)
+ {
+ *pos += view;
+ if (*pos + view > size)
+ {
+ *pos = size - view;
+ if (*pos < 0) *pos = 0;
+ }
+ }
+ else
+ {
+ *pos -= view;
+ if (*pos < 0) *pos = 0;
+ }
+}
+
+EOLIAN static void
+_elm_interface_scrollable_content_scroll_page(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroll_Direction direction)
+{
+ int size_w, size_h, view_w, view_h, pos_x, pos_y;
+ eo_do(obj,
+ elm_interface_scrollable_content_pos_get(&pos_x, &pos_y),
+ elm_interface_scrollable_content_size_get(&size_w, &size_h),
+ elm_interface_scrollable_content_viewport_geometry_get(NULL, NULL, &view_w, &view_h));
+
+ if (direction == ELM_SCROLL_DIRECTION_DOWN || direction == ELM_SCROLL_DIRECTION_UP)
+ _scroll_page_calculate(&pos_y, size_h, view_h, direction == ELM_SCROLL_DIRECTION_DOWN);
+ else
+ _scroll_page_calculate(&pos_x, size_w, view_w, direction == ELM_SCROLL_DIRECTION_RIGHT);
+
+ eo_do(obj, elm_interface_scrollable_region_bring_in(pos_x, pos_y, size_w, size_h));
+}
+
+EOLIAN static void
+_elm_interface_scrollable_content_scroll_to_end(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroll_Direction direction)
+{
+ int size_w, size_h, view_w, view_h, pos_x, pos_y;
+ eo_do(obj,
+ elm_interface_scrollable_content_pos_get(&pos_x, &pos_y),
+ elm_interface_scrollable_content_size_get(&size_w, &size_h),
+ elm_interface_scrollable_content_viewport_geometry_get(NULL, NULL, &view_w, &view_h));
+
+ if (direction == ELM_SCROLL_DIRECTION_DOWN)
+ {
+ pos_y = size_h - view_h;
+ if (pos_y < 0) pos_y = 0;
+ }
+ else if (direction == ELM_SCROLL_DIRECTION_RIGHT)
+ {
+ pos_x = size_w - view_w;
+ if (pos_x < 0) pos_x = 0;
+ }
+ else if (direction == ELM_SCROLL_DIRECTION_LEFT)
+ {
+ pos_x = 0;
+ }
+ else if (direction == ELM_SCROLL_DIRECTION_UP)
+ {
+ pos_y = 0;
+ }
+
+ eo_do(obj, elm_interface_scrollable_region_bring_in(pos_x, pos_y, size_w, size_h));
+}
+//
+
EOLIAN static void
_elm_interface_scrollable_content_pos_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
{