[elm_webview]add bouncing feature
[framework/uifw/elementary.git] / src / lib / els_webview_container.c
1 /*
2  *
3  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
4  */
5 #include <Elementary.h>
6 #include "elm_priv.h"
7
8 #ifdef BOUNCING_SUPPORT
9
10 #define SMART_NAME "els_webview_container"
11 #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)))
12 #define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
13 typedef struct _Smart_Data Smart_Data;
14
15 struct _Smart_Data
16 {
17    Evas_Coord x, y, w, h;
18    Evas_Coord bx, by;
19    Evas_Object *smart_obj;
20    Evas_Object *child_obj;
21    Evas_Object *clip;
22 };
23
24 /* local subsystem functions */
25 static void _smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
26 static void _smart_child_resize_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
27
28 static void _smart_reconfigure(Smart_Data *sd);
29 static void _smart_add(Evas_Object *obj);
30 static void _smart_del(Evas_Object *obj);
31 static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
32 static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
33 static void _smart_show(Evas_Object *obj);
34 static void _smart_hide(Evas_Object *obj);
35 static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
36 static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
37 static void _smart_clip_unset(Evas_Object *obj);
38 static void _smart_init(void);
39
40 /* local subsystem globals */
41 static Evas_Smart *_smart = NULL;
42
43 /* externally accessible functions */
44 Evas_Object *
45 elm_smart_webview_container_add(Evas *evas)
46 {
47    _smart_init();
48    return evas_object_smart_add(evas, _smart);
49 }
50
51 void
52 _elm_smart_webview_container_child_set(Evas_Object *obj, Evas_Object *child)
53 {
54    API_ENTRY return;
55    if (child == sd->child_obj) return;
56    if (sd->child_obj)
57      {
58         evas_object_clip_unset(sd->child_obj);
59         evas_object_smart_member_del(sd->child_obj);
60         evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_FREE, _smart_child_del_hook, sd);
61         evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_RESIZE, _smart_child_resize_hook, sd);
62         sd->child_obj = NULL;
63      }
64    if (child)
65      {
66         int r, g, b, a;
67         sd->child_obj = child;
68         _elm_smart_webview_container_set(child, obj);
69         evas_object_clip_set(sd->child_obj, sd->clip); 
70         _smart_reconfigure(sd);
71      }
72    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
73 }
74
75 Eina_Bool
76 _elm_smart_webview_container_scroll_adjust(Evas_Object *obj, int *dx, int *dy)
77 {
78    API_ENTRY return;
79    Eina_Bool changed = EINA_FALSE;
80    printf(" [ WCSA ] %d , %d vs %d, %d\n", *dx, *dy, sd->bx, sd->by);
81
82    if (sd->bx != 0)
83      {
84         int xsum = sd->bx + *dx;
85         if ((*dx < 0 && sd->bx > 0 && xsum < 0) ||
86               (*dx > 0 && sd->bx < 0 && xsum > 0))
87           {
88              sd->bx = 0;
89              *dx = xsum;
90           }
91         else
92           {
93              sd->bx = xsum;
94              *dx = 0;
95           }
96      }
97    if (sd->by != 0)
98      {
99         int ysum = sd->by + *dy;
100         if ((*dy < 0 && sd->by > 0 && ysum < 0) ||
101               (*dy > 0 && sd->by < 0 && ysum > 0))
102           {
103              sd->by = 0;
104              *dx = ysum;
105           }
106         else
107           {
108              sd->by = ysum;
109              *dy = 0;
110           }
111      }
112 #if 0
113    if (sd->bx > 0 && *dx < 0)
114      {
115         sd->bx += *dx;
116         if (sd->bx < 0)
117           {
118              *dx = sd->bx;
119              sd->bx = 0;
120           }
121         else
122           *dx = 0;
123         changed = EINA_TRUE;
124      }
125    else if (sd->bx < 0 && *dx > 0)
126      {
127         sd->bx += *dx;
128         if (sd->bx > 0)
129           {
130              *dx = sd->bx;
131              sd->bx = 0;
132           }
133         else
134           *dx = 0;
135         changed = EINA_TRUE;
136      }
137    if (sd->by > 0 && *dy < 0)
138      {
139         sd->by += *dy;
140         if (sd->by < 0)
141           {
142              *dy = sd->by;
143              sd->by = 0;
144           }
145         else
146           *dy = 0;
147         changed = EINA_TRUE;
148      }
149    else if (sd->by < 0 && *dy > 0)
150      {
151         sd->by += *dy;
152         if (sd->by > 0)
153           {
154              *dy = sd->by;
155              sd->by = 0;
156           }
157         else
158           *dy = 0;
159         changed = EINA_TRUE;
160      }
161 #endif
162    printf(" [ WCSA(A) ] %d , %d vs %d, %d\n", *dx, *dy, sd->bx, sd->by);
163    return changed;
164 }
165
166 void
167 _elm_smart_webview_container_bounce_add(Evas_Object *obj, int dx, int dy)
168 {
169    API_ENTRY return;
170    sd->bx += dx;
171    sd->by += dy;
172    if (sd->bx != 0 || sd->by != 0)
173      _smart_reconfigure(sd);
174 }
175
176 void
177 _elm_smart_webview_container_mouse_up(Evas_Object *obj)
178 {
179    API_ENTRY return;
180    if (sd->bx != 0 || sd->by != 0)
181      {
182         sd->bx = 0;
183         sd->by = 0;
184         _smart_reconfigure(sd);
185      }
186 }
187
188 void
189 _elm_smart_webview_container_decelerated_flick_get(Evas_Object *obj, int *dx, int *dy)
190 {
191    API_ENTRY return;
192    if (sd->bx != 0) *dx /= 2;
193    if (sd->by != 0) *dy /= 2;
194 }
195
196 /* local subsystem functions */
197 static void
198 _smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
199 {
200    Smart_Data *sd;
201
202    sd = data;
203    sd->child_obj = NULL;
204    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
205 }
206
207 static void
208 _smart_child_resize_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
209 {
210    Smart_Data *sd;
211    Evas_Coord w, h;
212
213    sd = data;
214    evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h);
215    /*if ((w != sd->child_w) || (h != sd->child_h))
216      {
217         sd->child_w = w;
218         sd->child_h = h;
219         _smart_reconfigure(sd);
220      }
221      */
222    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
223 }
224
225 static void
226 _smart_reconfigure(Smart_Data *sd)
227 {
228    evas_object_move(sd->child_obj, sd->x - sd->bx, sd->y - sd->by);
229    //evas_object_move(sd->child_obj, sd->x, sd->y);
230 }
231
232 static void
233 _smart_add(Evas_Object *obj)
234 {
235    Smart_Data *sd;
236
237    sd = calloc(1, sizeof(Smart_Data));
238    if (!sd) return;
239    sd->smart_obj = obj;
240    sd->x = 0;
241    sd->y = 0;
242    sd->w = 0;
243    sd->h = 0;
244    sd->bx = 0;
245    sd->by = 0;
246    printf("#########################%s\n",__func__);
247    sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
248    evas_object_color_set(sd->clip, 255, 255, 255, 255);
249
250    evas_object_smart_data_set(obj, sd);
251 }
252
253 static void
254 _smart_del(Evas_Object *obj)
255 {
256    INTERNAL_ENTRY;
257    _elm_smart_pan_child_set(obj, NULL);
258    free(sd);
259 }
260
261 static void
262 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
263 {
264    INTERNAL_ENTRY;
265    sd->x = x;
266    sd->y = y;
267    printf("#########################%s\n",__func__);
268    printf("            %d %d\n", x, y);
269    evas_object_move(sd->clip, x, y);
270    _smart_reconfigure(sd);
271 }
272
273 static void
274 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
275 {
276    INTERNAL_ENTRY;
277    sd->w = w;
278    sd->h = h;
279    printf("#########################%s\n",__func__);
280    printf("            %d %d\n", w, h);
281    evas_object_resize(sd->clip, w, h);
282    _smart_reconfigure(sd);
283    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
284 }
285
286 static void
287 _smart_show(Evas_Object *obj)
288 {
289    INTERNAL_ENTRY;
290    printf("#########################%s(clip_show)\n",__func__);
291    evas_object_show(sd->clip);
292    // smart_obj? 
293    evas_object_show(sd->child_obj);
294 }
295
296 static void
297 _smart_hide(Evas_Object *obj)
298 {
299    INTERNAL_ENTRY;
300    evas_object_hide(sd->child_obj);
301 }
302
303 static void
304 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
305 {
306    printf("#########################%s\n",__func__);
307    INTERNAL_ENTRY;
308    evas_object_color_set(sd->child_obj, r, g, b, a);
309 }
310
311 static void
312 _smart_clip_set(Evas_Object *obj, Evas_Object *clip)
313 {
314    printf("#########################%s\n",__func__);
315    INTERNAL_ENTRY;
316    //evas_object_clip_set(sd->child_obj, clip);
317 }
318
319 static void
320 _smart_clip_unset(Evas_Object *obj)
321 {
322    printf("#########################%s\n",__func__);
323    INTERNAL_ENTRY;
324    evas_object_clip_unset(sd->child_obj);
325 }
326
327 static void
328 _smart_init(void)
329 {
330    if (_smart) return;
331      {
332         static const Evas_Smart_Class sc =
333           {
334              SMART_NAME,
335                EVAS_SMART_CLASS_VERSION,
336                _smart_add,
337                _smart_del,
338                _smart_move,
339                _smart_resize,
340                _smart_show,
341                _smart_hide,
342                _smart_color_set,
343                _smart_clip_set,
344                _smart_clip_unset,
345                NULL,
346                NULL,
347                NULL,
348                NULL,
349                NULL,
350                NULL,
351                NULL
352           };
353         _smart = evas_smart_class_new(&sc);
354      }
355 }
356 #endif