[elm_webview]add bouncing feature
authorryuan choi <ryuan.choi@samsung.com>
Mon, 6 Sep 2010 07:39:24 +0000 (16:39 +0900)
committerryuan choi <ryuan.choi@samsung.com>
Mon, 6 Sep 2010 07:39:24 +0000 (16:39 +0900)
src/lib/Makefile.am
src/lib/elm_priv.h
src/lib/elm_webview.c
src/lib/els_webview.c
src/lib/els_webview.h
src/lib/els_webview_container.c [new file with mode: 0644]
src/lib/els_webview_container.h [new file with mode: 0644]

index 8076172..bed7ac8 100755 (executable)
@@ -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 =
index 0674da3..b5bce83 100644 (file)
@@ -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!
 // 
index fb664cc..6f37428 100644 (file)
@@ -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;
 }
index 8eec32d..0fa3bac 100644 (file)
@@ -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))
index adf6adf..6a4306e 100644 (file)
@@ -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 (file)
index 0000000..6ce3998
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ *
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#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 (file)
index 0000000..1195af0
--- /dev/null
@@ -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