diff options
author | Jaeun Choi <jaeun12.choi@samsung.com> | 2017-06-14 23:44:05 +0900 |
---|---|---|
committer | Jaeun Choi <jaeun12.choi@samsung.com> | 2017-06-15 16:02:38 +0900 |
commit | 72a8fd60ca0aa2415db0db301cb90a849f9492e9 (patch) | |
tree | b716edc418995583aa5e1a4ee377e189d1de2f87 | |
parent | 7a66fdc7847395c23b13195d19b35f49fb9b2634 (diff) | |
download | efl-devs/eunue/scrollable.tar.gz |
efl_ui_scroll_manager: take the first step to breaking the inheritance of elm_interface_scrollabledevs/eunue/scrollable
the final goal is to implement efl_ui_scroll_manager without using elm_interface_scrollable API.
to complete this job, i first broke the features down into several parts:
basic scroll, scroll bar, scroll blocking, edge effect, key input handling, etc.
this commit implements basic scroll feature at a low level.
-rw-r--r-- | src/lib/elementary/efl_ui_scroll_manager.c | 221 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_widget_scroll_manager.h | 22 |
2 files changed, 229 insertions, 14 deletions
diff --git a/src/lib/elementary/efl_ui_scroll_manager.c b/src/lib/elementary/efl_ui_scroll_manager.c index c237ef6f8b..25ae1fdaa5 100644 --- a/src/lib/elementary/efl_ui_scroll_manager.c +++ b/src/lib/elementary/efl_ui_scroll_manager.c @@ -9,6 +9,10 @@ #define MY_CLASS EFL_UI_SCROLL_MANAGER_CLASS #define MY_CLASS_NAME "Efl_Ui_Scroll_Manager" +#define MY_SCROLLABLE_INTERFACE ELM_INTERFACE_SCROLLABLE_MIXIN +#define MY_PAN_CLASS ELM_PAN_CLASS +#define LEGACY 0 + EOLIAN static void _efl_ui_scroll_manager_scrollbar_mode_set(Eo *obj, @@ -16,7 +20,10 @@ _efl_ui_scroll_manager_scrollbar_mode_set(Eo *obj, Efl_Ui_Scrollbar_Mode hmode, Efl_Ui_Scrollbar_Mode vmode) { +#if LEGACY elm_interface_scrollable_policy_set(obj, hmode, vmode); +#else +#endif } EOLIAN static Efl_Ui_Focus_Manager* @@ -39,7 +46,7 @@ _efl_ui_scroll_manager_efl_gfx_size_set(Eo *obj EINA_UNUSED, Evas_Coord w, Evas_Coord h) { - efl_gfx_size_set(sd->hit_rect, w, h); + efl_gfx_size_set(sd->event_obj, w, h); } EOLIAN static void @@ -48,19 +55,168 @@ _efl_ui_scroll_manager_efl_gfx_position_set(Eo *obj EINA_UNUSED, Evas_Coord x, Evas_Coord y) { - efl_gfx_position_set(sd->hit_rect, x, y); + efl_gfx_position_set(sd->event_obj, x, y); } +#if LEGACY static void -_resize_cb(Evas_Object *obj, Evas_Coord w EINA_UNUSED, Evas_Coord h EINA_UNUSED) +_viewport_resize_cb(Evas_Object *obj, Evas_Coord w EINA_UNUSED, Evas_Coord h EINA_UNUSED) { Evas_Coord minw, minh; Efl_Ui_Scroll_Manager_Data *sd = efl_data_scope_get(obj, EFL_UI_SCROLL_MANAGER_CLASS); - efl_gfx_size_hint_combined_min_get(sd->content, &minw, &minh); - efl_gfx_size_set(sd->content, minw, minh); + efl_gfx_size_hint_combined_min_get(sd->content.obj, &minw, &minh); + efl_gfx_size_set(sd->content.obj, minw, minh); +} +#else +static void +_edje_object_resize_cb(void *data, + Evas *e EINA_UNUSED, + Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + Efl_Ui_Scroll_Manager_Data *sd = data; + Evas_Coord w, h; + efl_gfx_size_get(obj, &w, &h); + + sd->edje_obj.w = w; + sd->edje_obj.h = h; +} + +static void +_edje_object_move_cb(void *data, + Evas *e EINA_UNUSED, + Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + Efl_Ui_Scroll_Manager_Data *sd = data; + Evas_Coord x, y; + efl_gfx_position_get(obj, &x, &y); + + sd->edje_obj.x = x; + sd->edje_obj.y = y; +} + +static void +_mouse_down_cb(void *data, + Evas *e, + Evas_Object *obj, + void *event_info) +{ + Efl_Ui_Scroll_Manager_Data *sd = data; + Evas_Event_Mouse_Down *ev = event_info; + + sd->down.on = EINA_TRUE; + sd->down.x = ev->canvas.x; + sd->down.y = ev->canvas.y; + + sd->prev_x = sd->down.x; + sd->prev_y = sd->down.y; +} + +static void +_mouse_move_cb(void *data, + Evas *e, + Evas_Object *obj, + void *event_info) +{ + Efl_Ui_Scroll_Manager_Data *sd = data; + Evas_Event_Mouse_Move *ev = event_info; + Evas_Coord cur_x, cur_y, dx, dy, x, y; + + if (!sd->down.on) return; + + cur_x = ev->cur.canvas.x; + cur_y = ev->cur.canvas.y; + dx = cur_x - sd->prev_x; + dy = cur_y - sd->prev_y; + + elm_obj_pan_pos_get(sd->pan_obj, &x, &y); + elm_obj_pan_pos_set(sd->pan_obj, (x - dx), (y - dy)); + + sd->prev_x = cur_x; + sd->prev_y = cur_y; +} + +static void +_mouse_up_cb(void *data, + Evas *e, + Evas_Object *obj, + void *event_info) +{ + Efl_Ui_Scroll_Manager_Data *sd = data; + Evas_Event_Mouse_Up *ev = event_info; + + sd->down.on = EINA_FALSE; +} + +static void +_edje_object_cb_add(Efl_Ui_Scroll_Manager_Data *sd) +{ + evas_object_event_callback_add + (sd->edje_obj.obj, EVAS_CALLBACK_RESIZE, _edje_object_resize_cb, sd); + evas_object_event_callback_add + (sd->edje_obj.obj, EVAS_CALLBACK_MOVE, _edje_object_move_cb, sd); +} + +static void +_edje_object_cb_del(Efl_Ui_Scroll_Manager_Data *sd) +{ + evas_object_event_callback_del_full + (sd->edje_obj.obj, EVAS_CALLBACK_RESIZE, _edje_object_resize_cb, sd); + evas_object_event_callback_del_full + (sd->edje_obj.obj, EVAS_CALLBACK_MOVE, _edje_object_move_cb, sd); +} + +static void +_event_object_cb_add(Efl_Ui_Scroll_Manager_Data *sd) +{ + evas_object_event_callback_add + (sd->event_obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, sd); + evas_object_event_callback_add + (sd->event_obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb, sd); + evas_object_event_callback_add + (sd->event_obj, EVAS_CALLBACK_MOUSE_UP, _mouse_up_cb, sd); } +static void +_event_object_cb_del(Efl_Ui_Scroll_Manager_Data *sd) +{ + evas_object_event_callback_del_full + (sd->event_obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, sd); + evas_object_event_callback_del_full + (sd->event_obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb, sd); + evas_object_event_callback_del_full + (sd->event_obj, EVAS_CALLBACK_MOUSE_UP, _mouse_up_cb, sd); +} + +static void +_pan_object_change_cb(void *data, const Efl_Event *event EINA_UNUSED) +{ + Efl_Ui_Scroll_Manager_Data *sd = data; + Evas_Coord w, h; + + elm_obj_pan_content_size_get(sd->pan_obj, &w, &h); + sd->content.w = w; + sd->content.h = h; + evas_object_size_hint_min_set(sd->edje_obj.obj, sd->content.w, sd->content.h); +} + +static void +_pan_object_resize_cb(void *data, + Evas *e EINA_UNUSED, + Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Efl_Ui_Scroll_Manager_Data *sd = data; + Evas_Coord minw, minh; + + edje_object_calc_force(sd->edje_obj.obj); + efl_gfx_size_hint_combined_min_get(sd->content.obj, &minw, &minh); + efl_gfx_size_set(sd->content.obj, minw, minh); +} +#endif + EOLIAN static void _efl_ui_scroll_manager_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Scroll_Manager_Data *sd) @@ -68,15 +224,38 @@ _efl_ui_scroll_manager_efl_canvas_group_group_add(Eo *obj, sd->parent = efl_parent_get(obj); ELM_WIDGET_DATA_GET_OR_RETURN(sd->parent, wd); +#if LEGACY efl_canvas_group_add(efl_super(obj, MY_CLASS)); - sd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj)); - efl_gfx_color_set(sd->hit_rect, 0, 0, 0, 0); - efl_gfx_visible_set(sd->hit_rect, EINA_TRUE); + sd->event_obj = evas_object_rectangle_add(evas_object_evas_get(obj)); + efl_gfx_color_set(sd->event_obj, 0, 0, 0, 0); + efl_gfx_visible_set(sd->event_obj, EINA_TRUE); - elm_interface_scrollable_objects_set(obj, wd->resize_obj, sd->hit_rect); + elm_interface_scrollable_objects_set(obj, wd->resize_obj, sd->event_obj); - elm_interface_scrollable_content_viewport_resize_cb_set(obj, _resize_cb); + elm_interface_scrollable_content_viewport_resize_cb_set(obj, _viewport_resize_cb); +#else + efl_canvas_group_add(efl_super(obj, MY_SCROLLABLE_INTERFACE)); + + sd->edje_obj.x = 0; + sd->edje_obj.y = 0; + sd->edje_obj.w = 0; + sd->edje_obj.h = 0; + + if (sd->edje_obj.obj) _edje_object_cb_del(sd); + sd->edje_obj.obj = wd->resize_obj; + + _edje_object_cb_add(sd); + + if (sd->event_obj) _event_object_cb_del(sd); + + sd->event_obj = evas_object_rectangle_add(evas_object_evas_get(obj)); + efl_gfx_color_set(sd->event_obj, 0, 0, 0, 0); + efl_gfx_visible_set(sd->event_obj, EINA_TRUE); + efl_canvas_object_repeat_events_set(sd->event_obj, EINA_TRUE); + + _event_object_cb_add(sd); +#endif } EOLIAN static void @@ -84,11 +263,29 @@ _efl_ui_scroll_manager_content_set(Eo *obj, Efl_Ui_Scroll_Manager_Data *sd, Evas_Object *content) { - if (sd->content == content) return; + Evas_Coord w, h; + if (sd->content.obj == content) return; - sd->content = content; + sd->content.obj = content; efl_canvas_group_member_add(obj, content); +#if LEGACY elm_interface_scrollable_content_set(obj, content); +#else + if (!sd->pan_obj) + { + sd->pan_obj = efl_add(MY_PAN_CLASS, evas_object_evas_get(obj)); + efl_event_callback_add(sd->pan_obj, ELM_PAN_EVENT_CHANGED, + _pan_object_change_cb, sd); + evas_object_event_callback_add(sd->pan_obj, EVAS_CALLBACK_RESIZE, + _pan_object_resize_cb, sd); + edje_object_part_swallow(sd->edje_obj.obj, "elm.swallow.content", + sd->pan_obj); + } + elm_obj_pan_content_set(sd->pan_obj, content); + elm_obj_pan_content_size_get(sd->pan_obj, &w, &h); + sd->content.w = w; + sd->content.h = h; +#endif } EOLIAN static Eo * diff --git a/src/lib/elementary/efl_ui_widget_scroll_manager.h b/src/lib/elementary/efl_ui_widget_scroll_manager.h index 231ba05744..070cb5e75d 100644 --- a/src/lib/elementary/efl_ui_widget_scroll_manager.h +++ b/src/lib/elementary/efl_ui_widget_scroll_manager.h @@ -5,10 +5,28 @@ typedef struct _Efl_Ui_Scroll_Manager_Data { + Evas_Coord prev_x, prev_y; + + struct { + Evas_Object *obj; + Evas_Coord x, y, w, h; + } edje_obj; + + struct { + Evas_Object *obj; + Evas_Coord w, h; + } content; + + struct { + Evas_Coord x, y; //mouse cursor + Evas_Coord cx, cy; //content position + Eina_Bool on : 1; + } down; + Eo *parent; - Evas_Object *hit_rect; - Evas_Object *content; + Evas_Object *event_obj; + Evas_Object *pan_obj; } Efl_Ui_Scroll_Manager_Data; |