af052b104baa8754f864e5df51f769035deb2958
[profile/ivi/org.tizen.browser.git] / src / browser-extension / browser-picker-handler.cpp
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *    http://www.tizenopensource.org/license
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16
17 #include "browser-picker-handler.h"
18 #include "browser-view.h"
19
20 #include <ui-gadget.h>
21
22 Browser_Picker_Handler::Browser_Picker_Handler(Browser_View *browser_view)
23 :       m_browser_view(browser_view)
24         ,m_webview(NULL)
25         ,m_picker_ug(NULL)
26         ,m_picker_layout(NULL)
27 {
28         BROWSER_LOGD("[%s]", __func__);
29 }
30
31 Browser_Picker_Handler::~Browser_Picker_Handler(void)
32 {
33         BROWSER_LOGD("[%s]", __func__);
34         _destroy_options();
35
36         if (m_picker_layout) {
37                 elm_object_part_content_unset(m_picker_layout, "elm.swallow.picker");
38                 evas_object_del(m_picker_layout);
39         }
40
41         if (m_picker_ug) {
42                 ug_destroy(m_picker_ug);
43                 m_picker_ug = NULL;
44         }
45 }
46
47 void Browser_Picker_Handler::destroy_picker_layout(void)
48 {
49         BROWSER_LOGD("[%s]", __func__);
50         _destroy_options();
51
52         if (m_picker_layout) {
53                 elm_object_part_content_unset(m_picker_layout, "elm.swallow.picker");
54                 evas_object_del(m_picker_layout);
55         }
56
57         if (m_picker_ug) {
58                 ug_destroy(m_picker_ug);
59                 m_picker_ug = NULL;
60         }
61 }
62
63 void Browser_Picker_Handler::init(Evas_Object *webview)
64 {
65         BROWSER_LOGD("[%s]", __func__);
66         deinit();
67
68         m_webview = webview;
69         memset(&m_selected_info, 0x00, sizeof(selected_info));
70
71         Evas_Object *webkit = elm_webview_webkit_get(m_webview);
72         evas_object_smart_callback_add(webkit, "one,single,tap", __one_single_tap_cb, this);
73         evas_object_smart_callback_add(webkit, "inputmethod,changed", __input_method_changed_cb, this);
74 }
75
76 void Browser_Picker_Handler::deinit(void)
77 {
78         BROWSER_LOGD("[%s]", __func__);
79         if (m_webview) {
80                 Evas_Object *webkit = elm_webview_webkit_get(m_webview);
81
82                 _destroy_options();
83
84                 if (m_picker_layout) {
85                         elm_object_part_content_unset(m_picker_layout, "elm.swallow.picker");
86                         evas_object_del(m_picker_layout);
87                 }
88
89                 if (m_picker_ug) {
90                         ug_destroy(m_picker_ug);
91                         m_picker_ug = NULL;
92                 }
93
94                 evas_object_smart_callback_del(webkit, "one,single,tap", __one_single_tap_cb);
95                 evas_object_event_callback_del(m_win, EVAS_CALLBACK_RESIZE, __win_resize_cb);
96                 evas_object_smart_callback_del(webkit, "inputmethod,changed", __input_method_changed_cb);
97         }
98 }
99
100 void Browser_Picker_Handler::_destroy_options(void)
101 {
102         BROWSER_LOGD("[%s]", __func__);
103         for (int i = 0 ; i < m_selected_info.option_number ; i++) {
104                 if (m_selected_info.option_list[i]) {
105                         free(m_selected_info.option_list[i]);
106                         m_selected_info.option_list[i] = NULL;
107                 }
108         }
109
110         memset(&m_selected_info, 0x00, sizeof(selected_info));
111 }
112
113 Eina_Bool Browser_Picker_Handler::_show_picker(void)
114 {
115         BROWSER_LOGD("[%s]", __func__);
116
117         if (m_picker_ug) {
118                 ug_destroy(m_picker_ug);
119                 m_picker_ug = NULL;
120         }
121
122         bundle *b = NULL;
123         struct ug_cbs cbs = {0,};
124         b = bundle_create();
125         if (!b) {
126                 BROWSER_LOGE("bundle_create failed");
127                 return EINA_FALSE;
128         }
129
130         char bundle_buf[100] = {0, };
131         sprintf(bundle_buf, "%d", m_selected_info.option_number);
132         if (bundle_add(b, "Count", bundle_buf)) {
133                 BROWSER_LOGE("bundle_add failed");
134                 bundle_free(b);
135                 return EINA_FALSE;
136         }
137
138         char item_title[100] = {0, };
139         for (int i = 0 ; i < m_selected_info.option_number ; i++) {
140                 sprintf(item_title, "%d", i);
141                 if (bundle_add(b, item_title, m_selected_info.option_list[i])) {
142                         BROWSER_LOGE("bundle_add failed");
143                         bundle_free(b);
144                         return EINA_FALSE;
145                 }
146         }
147
148         cbs.layout_cb = __picker_layout_cb;
149         cbs.result_cb = __picker_result_cb;
150         cbs.destroy_cb = __picker_destroy_cb;
151         cbs.priv = (void *)this;
152
153         m_picker_ug = ug_create(NULL, "picker-efl", UG_MODE_FRAMEVIEW, b, &cbs);
154         if (!m_picker_ug) {
155                 BROWSER_LOGE("ug_create failed");
156                 return EINA_FALSE;
157         }
158         bundle_free(b);
159
160         Evas_Object *webkit = elm_webview_webkit_get(m_webview);
161         evas_object_smart_callback_call(webkit, "make,select,visible", (void*)(&m_selected_info.rect));
162
163         evas_object_event_callback_del(m_win, EVAS_CALLBACK_RESIZE, __win_resize_cb);
164         evas_object_event_callback_add(m_win, EVAS_CALLBACK_RESIZE, __win_resize_cb, this);
165
166         bundle *option_bundle = NULL;
167         option_bundle = bundle_create();
168         if (!option_bundle) {
169                 BROWSER_LOGE("bundle_create failed");
170                 return EINA_FALSE;
171         }
172
173         BROWSER_LOGD("prev=%d, next=%d", m_selected_info.is_prev, m_selected_info.is_next);
174         if (!m_selected_info.is_prev) {
175                 if (bundle_add(option_bundle, "PrevButton", "Disable")) {
176                         BROWSER_LOGE("bundle_add is failed.");
177                         bundle_free(option_bundle);
178                         return EINA_FALSE;
179                 }
180         }
181         if (!m_selected_info.is_next) {
182                 if (bundle_add(option_bundle, "NextButton", "Disable")) {
183                         BROWSER_LOGE("bundle_add is failed.");
184                         bundle_free(option_bundle);
185                         return EINA_FALSE;
186                 }
187         }
188         if (m_picker_ug) {
189                 if (ug_send_message(m_picker_ug, option_bundle))
190                         BROWSER_LOGE("ug_send_message is failed.\n");
191         }
192         bundle_free(option_bundle);
193
194         return EINA_TRUE;
195 }
196
197 void Browser_Picker_Handler::__win_resize_cb(void* data, Evas* evas, Evas_Object* obj, void* ev)
198 {
199         if (!data)
200                 return;
201
202         Browser_Picker_Handler *picker_handler = (Browser_Picker_Handler *)data;
203
204         int window_w = 0;
205         int window_h = 0;
206         evas_object_geometry_get(m_win, NULL, NULL, &window_w, &window_h);
207         BROWSER_LOGD("window w=%d, h=%d", window_w, window_h);
208         evas_object_resize(picker_handler->m_picker_layout, window_w, window_h);
209 }
210
211 void Browser_Picker_Handler::__picker_layout_cb(struct ui_gadget *ug, enum ug_mode mode, void *priv)
212 {
213         BROWSER_LOGD("[%s]", __func__);
214         if (!ug || !priv)
215                 return;
216
217         Browser_Picker_Handler *picker_handler = (Browser_Picker_Handler *)priv;
218
219         if (picker_handler->m_picker_layout) {
220                 elm_object_part_content_unset(picker_handler->m_picker_layout, "elm.swallow.picker");
221                 evas_object_del(picker_handler->m_picker_layout);
222         }
223
224         picker_handler->m_picker_layout = elm_layout_add(m_navi_bar);
225         if (!picker_handler->m_picker_layout) {
226                 BROWSER_LOGE("elm_layout_add");
227                 return;
228         }
229         elm_object_focus_allow_set(picker_handler->m_picker_layout, EINA_FALSE);
230
231         if (!elm_layout_file_set(picker_handler->m_picker_layout, BROWSER_EDJE_DIR"/browser-picker-layout.edj",
232                                                                                 "picker_layout")) {
233                 BROWSER_LOGE("elm_layout_file_set failed");
234                 return;
235         }
236         evas_object_size_hint_weight_set(picker_handler->m_picker_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
237
238         int window_w = 0;
239         int window_h = 0;
240         evas_object_geometry_get(m_win, NULL, NULL, &window_w, &window_h);
241
242         evas_object_resize(picker_handler->m_picker_layout, window_w, window_h);
243         evas_object_move(picker_handler->m_picker_layout, 0, 0);
244         evas_object_show(picker_handler->m_picker_layout);
245
246         Evas_Object *base = (Evas_Object *)ug_get_layout(ug);
247         if (!base) {
248                 BROWSER_LOGE("base is null");
249                 return;
250         }
251
252         switch (mode) {
253                 case UG_MODE_FRAMEVIEW:
254                         elm_object_part_content_set(picker_handler->m_picker_layout, "elm.swallow.picker", base);
255                         break;
256                 default:
257                         break;
258         }
259 }
260
261 Eina_Bool Browser_Picker_Handler::_move_to_next_node(Eina_Bool is_next_node)
262 {
263         BROWSER_LOGD("[%s]", __func__);
264
265         _destroy_options();
266
267         Evas_Object *webkit = elm_webview_webkit_get(m_webview);
268         if (is_next_node) {
269                 m_selected_info.option_list = ewk_view_dropdown_get_next_options(webkit,
270                                                         &m_selected_info.option_number,
271                                                         &m_selected_info.current_option_index,
272                                                         &m_selected_info.rect,
273                                                         &m_selected_info.is_prev,
274                                                         &m_selected_info.is_next);
275         } else {
276                 m_selected_info.option_list = ewk_view_dropdown_get_prev_options(webkit,
277                                                         &m_selected_info.option_number,
278                                                         &m_selected_info.current_option_index,
279                                                         &m_selected_info.rect,
280                                                         &m_selected_info.is_prev,
281                                                         &m_selected_info.is_next);
282         }
283
284         bundle *b = bundle_create();
285         if (!b) {
286                 BROWSER_LOGE("bundle_create failed");
287                 return EINA_FALSE;
288         }
289
290         if (bundle_add(b, "Command", "Refill")) {
291                 BROWSER_LOGE("bundle_add failed");
292                 bundle_free(b);
293                 return EINA_FALSE;
294         }
295         char bundle_buf[100] = {0, };
296         sprintf(bundle_buf, "%d", m_selected_info.option_number);
297         if (bundle_add(b, "Count", bundle_buf)) {
298                 BROWSER_LOGE("bundle_add failed");
299                 bundle_free(b);
300                 return EINA_FALSE;
301         }
302
303         BROWSER_LOGD("prev=%d, next=%d", m_selected_info.is_prev, m_selected_info.is_next);
304         if (!m_selected_info.is_prev) {
305                 if (bundle_add(b, "PrevButton", "Disable")) {
306                         BROWSER_LOGE("bundle_add is failed.");
307                         bundle_free(b);
308                         return EINA_FALSE;
309                 }
310         } else {
311                 if (bundle_add(b, "PrevButton", "Enable")) {
312                         BROWSER_LOGE("bundle_add is failed.");
313                         bundle_free(b);
314                         return EINA_FALSE;
315                 }
316         }
317
318         if (!m_selected_info.is_next) {
319                 if (bundle_add(b, "NextButton", "Disable")) {
320                         BROWSER_LOGE("bundle_add is failed.");
321                         bundle_free(b);
322                         return EINA_FALSE;
323                 }
324         } else {
325                 if (bundle_add(b, "NextButton", "Enable")) {
326                         BROWSER_LOGE("bundle_add is failed.");
327                         bundle_free(b);
328                         return EINA_FALSE;
329                 }
330         }
331
332         char item_title[100] = {0, };
333         for (int i = 0 ; i < m_selected_info.option_number ; i++) {
334                 sprintf(item_title, "%d", i);
335                 if (bundle_add(b, item_title, m_selected_info.option_list[i])) {
336                         BROWSER_LOGE("bundle_add failed");
337                         bundle_free(b);
338                         return EINA_FALSE;
339                 }
340         }
341
342         if (m_picker_ug) {
343                 if (ug_send_message(m_picker_ug, b))
344                         BROWSER_LOGE("ug_send_message is failed.\n");
345         }
346
347         bundle_free(b);
348
349         evas_object_smart_callback_call(webkit, "make,select,visible", (void*)(&m_selected_info.rect));
350 }
351
352 void Browser_Picker_Handler::__picker_result_cb(struct ui_gadget *ug, bundle *result, void *priv)
353 {
354         BROWSER_LOGD("[%s]", __func__);
355         if (!ug || !priv || !result)
356                 return;
357
358         Browser_Picker_Handler *picker_handler = (Browser_Picker_Handler *)priv;
359         const char *response = bundle_get_val(result, "Result");
360         if (response) {
361                 if (!strncmp(response, "Success", strlen("Success")))
362                         picker_handler->__picker_destroy_cb(ug, priv);
363                 else if (!strncmp(response, "Prev", strlen("Prev")))
364                         picker_handler->_move_to_next_node(EINA_FALSE);
365                 else if (!strncmp(response, "Next", strlen("Next")))
366                         picker_handler->_move_to_next_node(EINA_TRUE);
367         }
368
369         const char *index = bundle_get_val(result, "Index");
370         if (index) {
371                 Evas_Object *webkit = elm_webview_webkit_get(picker_handler->m_webview);
372                 if (atoi(index)) {
373                         if (!ewk_page_dropdown_set_current_index(webkit, atoi(index)))
374                                 BROWSER_LOGE("ewk_page_dropdown_set_current_index is failed.\n");
375                 }
376         }
377 }
378
379 void Browser_Picker_Handler::__picker_destroy_cb(struct ui_gadget *ug, void *priv)
380 {
381         BROWSER_LOGD("[%s]", __func__);
382         if (!ug || !priv)
383                 return;
384
385         Browser_Picker_Handler *picker_handler = (Browser_Picker_Handler *)priv;
386
387         if (ug_destroy(ug))
388                 BROWSER_LOGE("ug_destroy is failed.\n");
389
390         picker_handler->m_picker_ug = NULL;
391
392         elm_object_part_content_unset(picker_handler->m_picker_layout, "elm.swallow.picker");
393         evas_object_del(picker_handler->m_picker_layout);
394         picker_handler->m_picker_layout = NULL;
395 }
396
397 void Browser_Picker_Handler::__one_single_tap_cb(void *data, Evas_Object *obj, void *event_info)
398 {
399         BROWSER_LOGD("[%s]", __func__);
400         if (!data || !event_info)
401                 return;
402
403         Evas_Point *position = (Evas_Point *)event_info;
404         Browser_Picker_Handler *picker_handler = (Browser_Picker_Handler *)data;
405         Evas_Object *webkit = elm_webview_webkit_get(picker_handler->m_webview);
406         double zoom_rate = 1.0f;
407         int webview_y = 0;
408         evas_object_geometry_get(webkit, NULL, &webview_y, NULL, NULL);
409
410         picker_handler->_destroy_options();
411
412         if (ewk_view_zoom_cairo_scaling_get(webkit) == EINA_TRUE)
413                 zoom_rate = ewk_view_zoom_get(webkit);
414
415         picker_handler->m_selected_info.clicked_x = position->x / zoom_rate;
416         picker_handler->m_selected_info.clicked_y = (position->y - webview_y) / zoom_rate;
417
418         picker_handler->m_selected_info.option_list = ewk_page_dropdown_get_options(webkit,
419                                                 picker_handler->m_selected_info.clicked_x,
420                                                 picker_handler->m_selected_info.clicked_y,
421                                                 &picker_handler->m_selected_info.option_number,
422                                                 &picker_handler->m_selected_info.current_option_index,
423                                                 &picker_handler->m_selected_info.rect,
424                                                 &picker_handler->m_selected_info.is_prev,
425                                                 &picker_handler->m_selected_info.is_next);
426
427         if (picker_handler->m_selected_info.option_list) {
428                 if (!picker_handler->_show_picker())
429                         BROWSER_LOGE("_show_picker failed");
430         }
431 }
432
433 void Browser_Picker_Handler::__input_method_changed_cb(void *data, Evas_Object *obj, void *event_info)
434 {
435         if (!data)
436                 return;
437
438         Browser_Picker_Handler *picker_handler = (Browser_Picker_Handler *)data;
439         Evas_Object *webkit = elm_webview_webkit_get(picker_handler->m_webview);
440         int imh_type = ewk_view_imh_get(obj);
441         BROWSER_LOGD("imh_type = %d", imh_type);
442         if (imh_type == EWK_IMH_DATE) {
443                 const char *current_date = ewk_view_focused_input_element_value_get(webkit);
444                 BROWSER_LOGD("current_date=[%s]", current_date);
445
446                 if (!picker_handler->_show_calendar_picker(current_date, INPUT_TYPE_DATE))
447                         BROWSER_LOGE("_show_calendar_picker failed");
448
449                 if (current_date)
450                         free((char *)current_date);
451         } else if (imh_type == EWK_IMH_TIME) {
452                 /* To do. */
453         }
454 }
455
456 Eina_Bool Browser_Picker_Handler::_show_calendar_picker(const char *date, input_type type)
457 {
458         BROWSER_LOGD("date=[%s], type=%d", date, type);
459
460         if (m_picker_ug) {
461                 ug_destroy(m_picker_ug);
462                 m_picker_ug = NULL;
463         }
464
465         bundle *b = NULL;
466         struct ug_cbs cbs = {0,};
467         b = bundle_create();
468         if (!b) {
469                 BROWSER_LOGE("bundle_create failed");
470                 return EINA_FALSE;
471         }
472
473         if (bundle_add(b, "date", date)) {
474                 BROWSER_LOGE("bundle_add failed");
475                 bundle_free(b);
476                 return EINA_FALSE;
477         }
478
479         cbs.layout_cb = __picker_layout_cb;
480         cbs.destroy_cb = __picker_destroy_cb;
481         if (type == INPUT_TYPE_DATE)
482                 cbs.result_cb = __calendar_picker_date_result_cb;
483         cbs.priv = (void *)this;
484
485         m_picker_ug = ug_create(NULL, "calendar-picker-efl", UG_MODE_FRAMEVIEW, b, &cbs);
486         if (!m_picker_ug) {
487                 BROWSER_LOGE("ug_create failed");
488                 return EINA_FALSE;
489         }
490         bundle_free(b);
491
492         return EINA_TRUE;
493 }
494
495 void Browser_Picker_Handler::__calendar_picker_date_result_cb(struct ui_gadget *ug,
496                                                                 bundle *result, void *priv)
497 {
498         BROWSER_LOGD("[%s]", __func__);
499         if (!ug || !priv || !result)
500                 return;
501
502         Browser_Picker_Handler *picker_handler = (Browser_Picker_Handler *)priv;
503         const char *value = bundle_get_val(result, "Result");
504         if (value) {
505                 if (!strncmp(value, "Done", strlen("Done"))) {
506                         picker_handler->__picker_destroy_cb(ug, priv);
507                         return;
508                 }
509         }
510         const char *date = bundle_get_val(result, "Date");
511         if (date) {
512                 Evas_Object *webkit = elm_webview_webkit_get(picker_handler->m_webview);
513                 if (!ewk_view_focused_input_element_value_set(webkit, date))
514                         BROWSER_LOGE("ewk_view_focused_input_element_value_set failed");
515         }
516 }
517