From 70636ca20f399ac15bb81b16d1c4ad24b451fbf9 Mon Sep 17 00:00:00 2001 From: ryuan choi Date: Mon, 6 Sep 2010 16:39:24 +0900 Subject: [PATCH] [elm_webview]add bouncing feature --- src/lib/Makefile.am | 3 +- src/lib/elm_priv.h | 1 + src/lib/elm_webview.c | 26 ++- src/lib/els_webview.c | 42 +++++ src/lib/els_webview.h | 6 + src/lib/els_webview_container.c | 356 ++++++++++++++++++++++++++++++++++++++++ src/lib/els_webview_container.h | 11 ++ 7 files changed, 442 insertions(+), 3 deletions(-) create mode 100644 src/lib/els_webview_container.c create mode 100644 src/lib/els_webview_container.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 8076172..bed7ac8 100755 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -151,7 +151,8 @@ els_icon.c \ els_icon.h \ els_touch.c \ els_touch.h \ -els_webview.c +els_webview.c \ +els_webview_container.c libelementary_la_CFLAGS = diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h index 0674da3..b5bce83 100644 --- a/src/lib/elm_priv.h +++ b/src/lib/elm_priv.h @@ -20,6 +20,7 @@ #include "els_hor_scroller.h" #include "els_touch.h" #include "els_webview.h" +#include "els_webview_container.h" // FIXME: totally disorganised. clean this up! // diff --git a/src/lib/elm_webview.c b/src/lib/elm_webview.c index fb664cc..6f37428 100644 --- a/src/lib/elm_webview.c +++ b/src/lib/elm_webview.c @@ -15,6 +15,9 @@ typedef struct _Widget_Data Widget_Data; struct _Widget_Data { +#ifdef BOUNCING_SUPPORT + Evas_Object *container; +#endif Evas_Object *webkit; }; @@ -47,10 +50,20 @@ _del_hook(Evas_Object *obj) static void _sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord w, h; evas_object_geometry_get(obj, NULL, NULL, &w, &h); printf("sizing eval : %d, %d\n", w, h); - //evas_object_resize(obj, w, h); +#ifdef BOUNCING_SUPPORT + evas_object_resize(wd->container, w, h); +#endif + evas_object_resize(wd->webkit, w, h); +} + +static void +_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + _sizing_eval(data); } static void @@ -99,12 +112,21 @@ elm_webview_add(Evas_Object *parent, Eina_Bool tiled) elm_widget_del_hook_set(obj, _del_hook); wd->webkit = _elm_smart_webview_add(e, tiled); +#ifdef BOUNCING_SUPPORT + wd->container = elm_smart_webview_container_add(e); + _elm_smart_webview_container_child_set(wd->container, wd->webkit); + _elm_smart_webview_container_set(wd->webkit, wd->container); +#endif _elm_smart_webview_widget_set(wd->webkit, obj); - //TODO:evas_object_box_layout_set(wd->box, _layout, wd, NULL); evas_object_event_callback_add(wd->webkit, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); +#ifdef BOUNCING_SUPPORT + elm_widget_resize_object_set(obj, wd->container); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj); +#else elm_widget_resize_object_set(obj, wd->webkit); +#endif evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); return obj; } diff --git a/src/lib/els_webview.c b/src/lib/els_webview.c index 8eec32d..0fa3bac 100644 --- a/src/lib/els_webview.c +++ b/src/lib/els_webview.c @@ -84,6 +84,9 @@ struct _Smart_Data { Ewk_View_Smart_Data base; //default data Evas_Object* widget; +#ifdef BOUNCING_SUPPORT + Evas_Object* container; +#endif Ecore_Job *move_calc_job; Ecore_Job *resize_calc_job; Eina_Hash* mime_func_hash; @@ -94,6 +97,7 @@ struct _Smart_Data { unsigned char events_feed : 1; unsigned char auto_fitting : 1; unsigned char mouse_clicked : 1; + unsigned char on_flick : 1; /* ewk functions */ void (*ewk_view_theme_set)(Evas_Object *, const char *); @@ -568,6 +572,15 @@ _elm_smart_webview_default_layout_width_set(Evas_Object *obj, int width) sd->layout.default_w = width; } +#ifdef BOUNCING_SUPPORT +void +_elm_smart_webview_container_set(Evas_Object *obj, Evas_Object *container) +{ + API_ENTRY return; + sd->container = container; +} +#endif + int _flush_and_pre_render(void *data) { @@ -1637,6 +1650,7 @@ _smart_cb_mouse_up(void* data, Evas_Object* webview, void* ev) Smart_Data* sd = (Smart_Data *)data; if (!sd) return; if (sd->events_feed == EINA_TRUE) return; + sd->on_flick = EINA_TRUE; Evas_Point* point = (Evas_Point*)ev; DBG(" argument : (%d, %d)\n", point->x, point->y); @@ -1771,6 +1785,7 @@ _smart_cb_pan_start(void* data, Evas_Object* webview, void* ev) sd->pan_s = *point; sd->on_panning = EINA_TRUE; + sd->on_flick = EINA_FALSE; if (sd->use_text_selection == EINA_TRUE && sd->text_selection_on == EINA_TRUE) { @@ -1890,6 +1905,19 @@ _smart_cb_pan_by(void* data, Evas_Object* webview, void* ev) if (locked) return; #endif +#ifdef BOUNCING_SUPPORT + printf(":::::::: %s\n", __func__); + _elm_smart_webview_container_scroll_adjust(sd->container, &dx, &dy); + if (dx == 0 && dy == 0) + { + sd->pan_s = *point; + _elm_smart_webview_container_bounce_add(sd->container, 0, 0); + if (sd->on_flick) + _elm_smart_touch_reset(sd->touch_obj); + return; + } +#endif + if (!sd->ewk_view_frame_main_get) sd->ewk_view_frame_main_get = (Evas_Object *(*)(const Evas_Object *))dlsym(ewk_handle, "ewk_view_frame_main_get"); if (!sd->ewk_frame_scroll_add) @@ -1906,6 +1934,17 @@ _smart_cb_pan_by(void* data, Evas_Object* webview, void* ev) if (sd->use_text_selection == EINA_TRUE && sd->text_selection_on == EINA_TRUE) _text_selection_move_by(sd, old_x - new_x, old_y - new_y); +#ifdef BOUNCING_SUPPORT + int bx, by; + bx = old_x + dx - new_x; + by = old_y + dy - new_y; + if (sd->on_flick && (bx != 0 || by != 0)) + { + _elm_smart_webview_container_decelerated_flick_get(sd->container, &bx, &by); + } + _elm_smart_webview_container_bounce_add(sd->container, bx, by); +#endif + #if 0 // comment out below code until it is completed if (!sd->bounce_horiz && (dx && elm_widget_drag_lock_x_get(sd->widget) && (old_x == new_x))) @@ -1968,6 +2007,9 @@ _smart_cb_pan_stop(void* data, Evas_Object* webview, void* ev) _directional_pre_render(webview, (sd->mouse_down_copy.canvas.x - point->x), (sd->mouse_down_copy.canvas.y - point->y)); } +#ifdef BOUNCING_SUPPORT + _elm_smart_webview_container_mouse_up(sd->container); +#endif #if 0 // comment out below code until it is completed if (!sd->bounce_horiz && elm_widget_drag_lock_x_get(sd->widget)) diff --git a/src/lib/els_webview.h b/src/lib/els_webview.h index adf6adf..6a4306e 100644 --- a/src/lib/els_webview.h +++ b/src/lib/els_webview.h @@ -1,6 +1,12 @@ +//FIXME: need to remove +//#define BOUNCING_SUPPORT + Evas_Object* _elm_smart_webview_add(Evas *evas, Eina_Bool tiled); void _elm_smart_webview_events_feed_set(Evas_Object* obj, Eina_Bool feed); Eina_Bool _elm_smart_webview_events_feed_get(Evas_Object* obj); void _elm_smart_webview_bounce_allow_set(Evas_Object* obj, Eina_Bool horiz, Eina_Bool vert); void _elm_smart_webview_mime_callback_set(Evas_Object* obj, const char *mime, Elm_WebView_Mime_Cb func); void _elm_smart_webview_default_layout_width_set(Evas_Object *obj, int width); +#ifdef BOUNCING_SUPPORT +void _elm_smart_webview_container_set(Evas_Object *obj, Evas_Object *container); +#endif diff --git a/src/lib/els_webview_container.c b/src/lib/els_webview_container.c new file mode 100644 index 0000000..6ce3998 --- /dev/null +++ b/src/lib/els_webview_container.c @@ -0,0 +1,356 @@ +/* + * + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include +#include "elm_priv.h" + +#ifdef BOUNCING_SUPPORT + +#define SMART_NAME "els_webview_container" +#define API_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME))) +#define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; +typedef struct _Smart_Data Smart_Data; + +struct _Smart_Data +{ + Evas_Coord x, y, w, h; + Evas_Coord bx, by; + Evas_Object *smart_obj; + Evas_Object *child_obj; + Evas_Object *clip; +}; + +/* local subsystem functions */ +static void _smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _smart_child_resize_hook(void *data, Evas *e, Evas_Object *obj, void *event_info); + +static void _smart_reconfigure(Smart_Data *sd); +static void _smart_add(Evas_Object *obj); +static void _smart_del(Evas_Object *obj); +static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h); +static void _smart_show(Evas_Object *obj); +static void _smart_hide(Evas_Object *obj); +static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a); +static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip); +static void _smart_clip_unset(Evas_Object *obj); +static void _smart_init(void); + +/* local subsystem globals */ +static Evas_Smart *_smart = NULL; + +/* externally accessible functions */ +Evas_Object * +elm_smart_webview_container_add(Evas *evas) +{ + _smart_init(); + return evas_object_smart_add(evas, _smart); +} + +void +_elm_smart_webview_container_child_set(Evas_Object *obj, Evas_Object *child) +{ + API_ENTRY return; + if (child == sd->child_obj) return; + if (sd->child_obj) + { + evas_object_clip_unset(sd->child_obj); + evas_object_smart_member_del(sd->child_obj); + evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_FREE, _smart_child_del_hook, sd); + evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_RESIZE, _smart_child_resize_hook, sd); + sd->child_obj = NULL; + } + if (child) + { + int r, g, b, a; + sd->child_obj = child; + _elm_smart_webview_container_set(child, obj); + evas_object_clip_set(sd->child_obj, sd->clip); + _smart_reconfigure(sd); + } + evas_object_smart_callback_call(sd->smart_obj, "changed", NULL); +} + +Eina_Bool +_elm_smart_webview_container_scroll_adjust(Evas_Object *obj, int *dx, int *dy) +{ + API_ENTRY return; + Eina_Bool changed = EINA_FALSE; + printf(" [ WCSA ] %d , %d vs %d, %d\n", *dx, *dy, sd->bx, sd->by); + + if (sd->bx != 0) + { + int xsum = sd->bx + *dx; + if ((*dx < 0 && sd->bx > 0 && xsum < 0) || + (*dx > 0 && sd->bx < 0 && xsum > 0)) + { + sd->bx = 0; + *dx = xsum; + } + else + { + sd->bx = xsum; + *dx = 0; + } + } + if (sd->by != 0) + { + int ysum = sd->by + *dy; + if ((*dy < 0 && sd->by > 0 && ysum < 0) || + (*dy > 0 && sd->by < 0 && ysum > 0)) + { + sd->by = 0; + *dx = ysum; + } + else + { + sd->by = ysum; + *dy = 0; + } + } +#if 0 + if (sd->bx > 0 && *dx < 0) + { + sd->bx += *dx; + if (sd->bx < 0) + { + *dx = sd->bx; + sd->bx = 0; + } + else + *dx = 0; + changed = EINA_TRUE; + } + else if (sd->bx < 0 && *dx > 0) + { + sd->bx += *dx; + if (sd->bx > 0) + { + *dx = sd->bx; + sd->bx = 0; + } + else + *dx = 0; + changed = EINA_TRUE; + } + if (sd->by > 0 && *dy < 0) + { + sd->by += *dy; + if (sd->by < 0) + { + *dy = sd->by; + sd->by = 0; + } + else + *dy = 0; + changed = EINA_TRUE; + } + else if (sd->by < 0 && *dy > 0) + { + sd->by += *dy; + if (sd->by > 0) + { + *dy = sd->by; + sd->by = 0; + } + else + *dy = 0; + changed = EINA_TRUE; + } +#endif + printf(" [ WCSA(A) ] %d , %d vs %d, %d\n", *dx, *dy, sd->bx, sd->by); + return changed; +} + +void +_elm_smart_webview_container_bounce_add(Evas_Object *obj, int dx, int dy) +{ + API_ENTRY return; + sd->bx += dx; + sd->by += dy; + if (sd->bx != 0 || sd->by != 0) + _smart_reconfigure(sd); +} + +void +_elm_smart_webview_container_mouse_up(Evas_Object *obj) +{ + API_ENTRY return; + if (sd->bx != 0 || sd->by != 0) + { + sd->bx = 0; + sd->by = 0; + _smart_reconfigure(sd); + } +} + +void +_elm_smart_webview_container_decelerated_flick_get(Evas_Object *obj, int *dx, int *dy) +{ + API_ENTRY return; + if (sd->bx != 0) *dx /= 2; + if (sd->by != 0) *dy /= 2; +} + +/* local subsystem functions */ +static void +_smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Smart_Data *sd; + + sd = data; + sd->child_obj = NULL; + evas_object_smart_callback_call(sd->smart_obj, "changed", NULL); +} + +static void +_smart_child_resize_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Smart_Data *sd; + Evas_Coord w, h; + + sd = data; + evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h); + /*if ((w != sd->child_w) || (h != sd->child_h)) + { + sd->child_w = w; + sd->child_h = h; + _smart_reconfigure(sd); + } + */ + evas_object_smart_callback_call(sd->smart_obj, "changed", NULL); +} + +static void +_smart_reconfigure(Smart_Data *sd) +{ + evas_object_move(sd->child_obj, sd->x - sd->bx, sd->y - sd->by); + //evas_object_move(sd->child_obj, sd->x, sd->y); +} + +static void +_smart_add(Evas_Object *obj) +{ + Smart_Data *sd; + + sd = calloc(1, sizeof(Smart_Data)); + if (!sd) return; + sd->smart_obj = obj; + sd->x = 0; + sd->y = 0; + sd->w = 0; + sd->h = 0; + sd->bx = 0; + sd->by = 0; + printf("#########################%s\n",__func__); + sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_color_set(sd->clip, 255, 255, 255, 255); + + evas_object_smart_data_set(obj, sd); +} + +static void +_smart_del(Evas_Object *obj) +{ + INTERNAL_ENTRY; + _elm_smart_pan_child_set(obj, NULL); + free(sd); +} + +static void +_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + INTERNAL_ENTRY; + sd->x = x; + sd->y = y; + printf("#########################%s\n",__func__); + printf(" %d %d\n", x, y); + evas_object_move(sd->clip, x, y); + _smart_reconfigure(sd); +} + +static void +_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + INTERNAL_ENTRY; + sd->w = w; + sd->h = h; + printf("#########################%s\n",__func__); + printf(" %d %d\n", w, h); + evas_object_resize(sd->clip, w, h); + _smart_reconfigure(sd); + evas_object_smart_callback_call(sd->smart_obj, "changed", NULL); +} + +static void +_smart_show(Evas_Object *obj) +{ + INTERNAL_ENTRY; + printf("#########################%s(clip_show)\n",__func__); + evas_object_show(sd->clip); + // smart_obj? + evas_object_show(sd->child_obj); +} + +static void +_smart_hide(Evas_Object *obj) +{ + INTERNAL_ENTRY; + evas_object_hide(sd->child_obj); +} + +static void +_smart_color_set(Evas_Object *obj, int r, int g, int b, int a) +{ + printf("#########################%s\n",__func__); + INTERNAL_ENTRY; + evas_object_color_set(sd->child_obj, r, g, b, a); +} + +static void +_smart_clip_set(Evas_Object *obj, Evas_Object *clip) +{ + printf("#########################%s\n",__func__); + INTERNAL_ENTRY; + //evas_object_clip_set(sd->child_obj, clip); +} + +static void +_smart_clip_unset(Evas_Object *obj) +{ + printf("#########################%s\n",__func__); + INTERNAL_ENTRY; + evas_object_clip_unset(sd->child_obj); +} + +static void +_smart_init(void) +{ + if (_smart) return; + { + static const Evas_Smart_Class sc = + { + SMART_NAME, + EVAS_SMART_CLASS_VERSION, + _smart_add, + _smart_del, + _smart_move, + _smart_resize, + _smart_show, + _smart_hide, + _smart_color_set, + _smart_clip_set, + _smart_clip_unset, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + }; + _smart = evas_smart_class_new(&sc); + } +} +#endif diff --git a/src/lib/els_webview_container.h b/src/lib/els_webview_container.h new file mode 100644 index 0000000..1195af0 --- /dev/null +++ b/src/lib/els_webview_container.h @@ -0,0 +1,11 @@ +//FIXME need to remove include and macro +#include "els_webview.h" + +#ifdef BOUNCING_SUPPORT +Evas_Object * elm_smart_webview_container_add(Evas *evas); +void _elm_smart_webview_container_child_set(Evas_Object *obj, Evas_Object *child); +void _elm_smart_webview_container_bounce_add(Evas_Object *obj, int dx, int dy); +void _elm_smart_webview_container_mouse_up(Evas_Object *obj); +void _elm_smart_webview_container_decelerated_flick_get(Evas_Object *obj, int *dx, int *dy); +Eina_Bool _elm_smart_webview_container_scroll_adjust(Evas_Object *obj, int *dx, int *dy); +#endif -- 2.7.4