c7fa33173261c1b6734ce5cd5ccf26f4ed093751
[profile/tv/apps/web/browser.git] / services / ZoomUI / ZoomUI.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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
18 #include <Elementary.h>
19 #include <boost/concept_check.hpp>
20 #include <vector>
21 #include <AbstractMainWindow.h>
22
23 #include "ZoomUI.h"
24 #include "BrowserLogger.h"
25 #include "ServiceManager.h"
26
27 #define DX 50
28 #define iDX -50
29
30 namespace tizen_browser{
31 namespace base_ui{
32
33 EXPORT_SERVICE(ZoomUI, "org.tizen.browser.zoomui")
34
35 ZoomUI::ZoomUI()
36     : m_layout(nullptr)
37     , m_zoom_slider(nullptr)
38     , m_nav_layout(nullptr)
39     , m_current_translation_x(0)
40     , m_current_translation_y(0)
41 {
42     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
43     m_edjFilePath = EDJE_DIR;
44     m_edjFilePath.append("ZoomUI/ZoomUI.edj");
45     elm_theme_extension_add(nullptr, m_edjFilePath.c_str());
46 }
47
48 ZoomUI::~ZoomUI() {}
49
50 void ZoomUI::init(Evas_Object* parent)
51 {
52     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
53     M_ASSERT(parent);
54     m_parent = parent;
55 }
56
57 Evas_Object* ZoomUI::getContent()
58 {
59     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
60     M_ASSERT(m_parent);
61     if(!m_layout)
62         createLayout(m_parent);
63     return m_layout;
64 }
65
66 void ZoomUI::showUI()
67 {
68     evas_object_show(m_layout);
69     evas_object_show(m_zoom_menu);
70     evas_object_show(m_zoom_slider);
71     m_keyDownHandler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_down_cb, this);
72     m_keyUpHandler = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_up_cb, this);
73     int zoomFactor = *(getZoom());
74     elm_slider_value_set(m_zoom_slider, calculateSliderValue(zoomFactor));
75 }
76
77 void ZoomUI::hideUI()
78 {
79     evas_object_hide(m_zoom_slider);
80     evas_object_hide(m_nav_layout);
81     evas_object_hide(m_zoom_menu);
82     evas_object_hide(m_layout);
83     ecore_event_handler_del(m_keyDownHandler);
84     ecore_event_handler_del(m_keyUpHandler);
85 }
86
87 void ZoomUI::show(Evas_Object* parent)
88 {
89     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
90     init(parent);
91     if (!m_layout)
92         createLayout(parent);
93     showUI();
94     elm_object_focus_set(m_zoom_slider, EINA_TRUE);
95 }
96
97 void ZoomUI::showNavigation()
98 {
99     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
100     M_ASSERT(m_nav_layout);
101     int zoomFactor = *(getZoom());
102     if (zoomFactor > ZOOM_DEFAULT)
103         evas_object_show(m_nav_layout);
104 }
105
106 void ZoomUI::createLayout(Evas_Object *parent)
107 {
108     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
109
110     m_layout = elm_layout_add(parent);
111     elm_layout_file_set(m_layout, m_edjFilePath.c_str(), "zoom-layout");
112     evas_object_size_hint_weight_set(m_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
113     evas_object_size_hint_align_set(m_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
114     createZoomSlider();
115     createNavigationButtons();
116 }
117
118 void ZoomUI::createZoomSlider()
119 {
120     m_zoom_menu = elm_layout_add(m_layout);
121     elm_layout_file_set(m_zoom_menu, m_edjFilePath.c_str(), "zoom-menu");
122     evas_object_size_hint_weight_set(m_zoom_menu, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
123     evas_object_size_hint_align_set(m_zoom_menu, EVAS_HINT_FILL, EVAS_HINT_FILL);
124
125     m_zoom_slider = elm_slider_add(m_zoom_menu);
126     evas_object_size_hint_weight_set(m_zoom_slider, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
127     evas_object_size_hint_align_set(m_zoom_slider, EVAS_HINT_FILL, EVAS_HINT_FILL);
128     evas_object_smart_callback_add(m_zoom_slider, "changed", _zoom_slider_changed, this);
129     elm_object_style_set(m_zoom_slider, "default");
130     elm_slider_horizontal_set(m_zoom_slider, EINA_TRUE);
131     elm_slider_min_max_set(m_zoom_slider, 1, 6);
132     elm_slider_step_set(m_zoom_slider, 0.2);
133     int zoomFactor = *(getZoom());
134     elm_slider_value_set(m_zoom_slider, calculateSliderValue(zoomFactor));
135     elm_slider_indicator_show_set(m_zoom_slider, EINA_FALSE);
136
137     elm_object_part_content_set(m_zoom_menu, "slider_swallow", m_zoom_slider);
138     evas_object_event_callback_add(m_zoom_slider, EVAS_CALLBACK_KEY_DOWN, _zoom_value_confirmed, this);
139 }
140
141 void ZoomUI::createNavigationButtons()
142 {
143     m_nav_layout = elm_layout_add(m_layout);
144     elm_layout_file_set(m_nav_layout, m_edjFilePath.c_str(), "nav-layout");
145     evas_object_size_hint_weight_set(m_nav_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
146     evas_object_size_hint_align_set(m_nav_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
147
148     m_leftArrow = elm_icon_add(m_nav_layout);
149     setImageFile(m_leftArrow, LEFT, false);
150     evas_object_smart_callback_add(m_leftArrow, "clicked", _left_button_clicked, this);
151     evas_object_event_callback_add(m_leftArrow, EVAS_CALLBACK_MOUSE_IN, _cb_focus_in_left_button, this);
152     evas_object_event_callback_add(m_leftArrow, EVAS_CALLBACK_MOUSE_OUT, _cb_focus_out_left_button, this);
153     elm_object_part_content_set(m_nav_layout, "left_button", m_leftArrow);
154
155     m_rightArrow = elm_icon_add(m_nav_layout);
156     setImageFile(m_rightArrow, RIGHT, false);
157     evas_object_smart_callback_add(m_rightArrow, "clicked", _right_button_clicked, this);
158     evas_object_event_callback_add(m_rightArrow, EVAS_CALLBACK_MOUSE_IN, _cb_focus_in_right_button, this);
159     evas_object_event_callback_add(m_rightArrow, EVAS_CALLBACK_MOUSE_OUT, _cb_focus_out_right_button, this);
160     elm_object_part_content_set(m_nav_layout, "right_button", m_rightArrow);
161
162     m_downArrow = elm_icon_add(m_nav_layout);
163     setImageFile(m_downArrow, DOWN, false);
164     evas_object_smart_callback_add(m_downArrow, "clicked", _down_button_clicked, this);
165     evas_object_event_callback_add(m_downArrow, EVAS_CALLBACK_MOUSE_IN, _cb_focus_in_down_button, this);
166     evas_object_event_callback_add(m_downArrow, EVAS_CALLBACK_MOUSE_OUT, _cb_focus_out_down_button, this);
167     elm_object_part_content_set(m_nav_layout, "down_button", m_downArrow);
168
169     m_upArrow = elm_icon_add(m_nav_layout);
170     setImageFile(m_upArrow, UP, false);
171     evas_object_smart_callback_add(m_upArrow, "clicked", _up_button_clicked, this);
172     evas_object_event_callback_add(m_upArrow, EVAS_CALLBACK_MOUSE_IN, _cb_focus_in_up_button, this);
173     evas_object_event_callback_add(m_upArrow, EVAS_CALLBACK_MOUSE_OUT, _cb_focus_out_up_button, this);
174     elm_object_part_content_set(m_nav_layout, "up_button", m_upArrow);
175 }
176
177 void ZoomUI::clearItems()
178 {
179     evas_object_del(m_layout);
180     setZoom(ZOOM_DEFAULT);
181 }
182
183 void ZoomUI::setImageFile(Evas_Object* obj, int direction, bool focused)
184 {
185     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
186     switch (direction) {
187         case LEFT:  elm_image_file_set(obj, m_edjFilePath.c_str(), focused ? "ic_zoom_indicator_left_foc.png" : "ic_zoom_indicator_left_nor.png");
188                     break;
189         case RIGHT: elm_image_file_set(obj, m_edjFilePath.c_str(), focused ? "ic_zoom_indicator_right_foc.png" : "ic_zoom_indicator_right_nor.png");
190                     break;
191         case DOWN:  elm_image_file_set(obj, m_edjFilePath.c_str(), focused ? "ic_zoom_indicator_down_foc.png" : "ic_zoom_indicator_down_nor.png");
192                     break;
193         case UP:    elm_image_file_set(obj, m_edjFilePath.c_str(), focused ? "ic_zoom_indicator_up_foc.png" : "ic_zoom_indicator_up_nor.png");
194                     break;
195         default:    BROWSER_LOGD("[%s:%d] Warning: Unhandled button", __PRETTY_FUNCTION__, __LINE__);
196                     break;
197     }
198 }
199
200 void ZoomUI::_zoom_slider_changed(void *data, Evas_Object *obj, void*)
201 {
202     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
203     if(data && obj) {
204         int val = elm_slider_value_get(obj);
205         int zoomLevel = ZOOM_DEFAULT;    
206         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
207
208         switch (val) {
209             case 1: zoomLevel = ZOOM_50;
210                     break;
211             case 2: zoomLevel = ZOOM_75;
212                     break;
213             case 3: zoomLevel = ZOOM_DEFAULT;
214                     break;
215             case 4: zoomLevel = ZOOM_150;
216                     break;
217             case 5: zoomLevel = ZOOM_200;
218                     break;
219             case 6: zoomLevel = ZOOM_300;
220                     break;
221             default:BROWSER_LOGD("[%s:%d] Warning: Unhandled zoom level", __PRETTY_FUNCTION__, __LINE__);
222                     break;
223         }
224         zoomUI->setZoom(zoomLevel);
225     }
226 }
227
228 void ZoomUI::_zoom_value_confirmed(void* data, Evas*, Evas_Object*, void* event_info)
229 {
230     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
231     Evas_Event_Key_Down* ev = static_cast<Evas_Event_Key_Down*>(event_info);
232
233     if (!data || !ev || !ev->keyname)
234         return;
235
236     ZoomUI* self = static_cast<ZoomUI*>(data);
237     if (std::string(ev->keyname) == "Return") {
238         int val = (int)elm_slider_value_get(self->m_zoom_slider);
239         BROWSER_LOGD("[%s:%d] val: %d", __PRETTY_FUNCTION__, __LINE__, val);
240         if (val > 3) {
241             BROWSER_LOGD("[%s:%d] value is greater than 3", __PRETTY_FUNCTION__, __LINE__);
242             evas_object_show(self->m_nav_layout);
243         } else {
244             BROWSER_LOGD("[%s:%d] value is smaller or equal to 3", __PRETTY_FUNCTION__, __LINE__);
245             evas_object_hide(self->m_nav_layout);
246         }
247         evas_object_hide(self->m_zoom_menu);
248     }
249 }
250
251 Eina_Bool ZoomUI::_key_down_cb(void* data, int, void* event_info)
252 {
253     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
254     Ecore_Event_Key* ev = static_cast<Ecore_Event_Key*>(event_info);
255
256     if (!data || !ev || !ev->keyname)
257         return EINA_FALSE;
258
259     ZoomUI* self = static_cast<ZoomUI*>(data);
260     if (std::string(ev->keyname) == "Left") {
261         _left_button_clicked(data, self->m_leftArrow, event_info);
262         _cb_focus_in_left_button(data, nullptr, self->m_leftArrow, event_info);
263     } else if (std::string(ev->keyname) == "Right") {
264         _right_button_clicked(data, self->m_rightArrow, event_info);
265         _cb_focus_in_right_button(data, nullptr, self->m_rightArrow, event_info);
266     } else if (std::string(ev->keyname) == "Up") {
267         _up_button_clicked(data, self->m_upArrow, event_info);
268         _cb_focus_in_up_button(data, nullptr, self->m_upArrow, event_info);
269     } else if (std::string(ev->keyname) == "Down") {
270         _down_button_clicked(data, self->m_downArrow, event_info);
271         _cb_focus_in_down_button(data, nullptr, self->m_downArrow, event_info);
272     } else
273         return EINA_FALSE;
274
275     return EINA_TRUE;
276 }
277
278 Eina_Bool ZoomUI::_key_up_cb(void* data, int, void* event_info)
279 {
280     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
281     Ecore_Event_Key* ev = static_cast<Ecore_Event_Key*>(event_info);
282
283     if (!data || !ev || !ev->keyname)
284         return EINA_FALSE;
285
286     ZoomUI* self = static_cast<ZoomUI*>(data);
287     if (std::string(ev->keyname) == "Left") {
288         _cb_focus_out_left_button(data, nullptr, self->m_leftArrow, event_info);
289     } else if (std::string(ev->keyname) == "Right") {
290         _cb_focus_out_right_button(data, nullptr, self->m_rightArrow, event_info);
291     } else if (std::string(ev->keyname) == "Up") {
292         _cb_focus_out_up_button(data, nullptr, self->m_upArrow, event_info);
293     } else if (std::string(ev->keyname) == "Down") {
294         _cb_focus_out_down_button(data, nullptr, self->m_downArrow, event_info);
295     } else
296         return EINA_FALSE;
297
298     return EINA_TRUE;
299 }
300
301 void ZoomUI::_left_button_clicked(void * data, Evas_Object * obj, void*)
302 {
303     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
304     if (data && obj) {
305         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
306         zoomUI->scrollView(iDX, 0);
307     }
308 }
309
310 void ZoomUI::_right_button_clicked(void * data, Evas_Object * obj, void*)
311 {
312     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
313     if (data && obj) {
314         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
315         zoomUI->scrollView(DX, 0);
316     }
317 }
318
319 void ZoomUI::_up_button_clicked(void * data, Evas_Object * obj, void*)
320 {
321     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
322     if (data && obj) {
323         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
324         zoomUI->scrollView(0, iDX);
325     }
326 }
327
328 void ZoomUI::_down_button_clicked(void * data, Evas_Object * obj, void*)
329 {
330     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
331     if (data && obj) {
332         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
333         zoomUI->scrollView(0, DX);
334     }
335 }
336
337 void ZoomUI::_cb_focus_in_left_button(void * data, Evas *, Evas_Object *obj, void *)
338 {
339     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
340     if (data && obj) {
341         elm_object_focus_set(obj, EINA_TRUE);
342         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
343         zoomUI->setImageFile(obj, LEFT, true);
344     }
345 }
346
347 void ZoomUI::_cb_focus_out_left_button(void * data, Evas *, Evas_Object *obj, void *)
348 {
349     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
350     if (data && obj) {
351         elm_object_focus_set(obj, EINA_FALSE);
352         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
353         zoomUI->setImageFile(obj, LEFT, false);
354     }
355 }
356
357 void ZoomUI::_cb_focus_in_right_button(void * data, Evas *, Evas_Object *obj, void *)
358 {
359     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
360     if (data && obj) {
361         elm_object_focus_set(obj, EINA_TRUE);
362         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
363         zoomUI->setImageFile(obj, RIGHT, true);
364     }
365 }
366
367 void ZoomUI::_cb_focus_out_right_button(void * data, Evas *, Evas_Object *obj, void *)
368 {
369     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
370     if (data && obj) {
371         elm_object_focus_set(obj, EINA_FALSE);
372         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
373         zoomUI->setImageFile(obj, RIGHT, false);
374     }
375 }
376
377 void ZoomUI::_cb_focus_in_up_button(void * data, Evas *, Evas_Object *obj, void *)
378 {
379     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
380     if (data && obj) {
381         elm_object_focus_set(obj, EINA_TRUE);
382         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
383         zoomUI->setImageFile(obj, UP, true);
384     }
385 }
386
387 void ZoomUI::_cb_focus_out_up_button(void * data, Evas *, Evas_Object *obj, void *)
388 {
389     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
390     if (data && obj) {
391         elm_object_focus_set(obj, EINA_FALSE);
392         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
393         zoomUI->setImageFile(obj, UP, false);
394     }
395 }
396
397 void ZoomUI::_cb_focus_in_down_button(void * data, Evas *, Evas_Object *obj, void *)
398 {
399     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
400     if (data && obj) {
401         elm_object_focus_set(obj, EINA_TRUE);
402         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
403         zoomUI->setImageFile(obj, DOWN, true);
404     }
405 }
406
407 void ZoomUI::_cb_focus_out_down_button(void * data, Evas *, Evas_Object *obj, void *)
408 {
409     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
410     if (data && obj) {
411         elm_object_focus_set(obj, EINA_FALSE);
412         ZoomUI *zoomUI = static_cast<ZoomUI*>(data);
413         zoomUI->setImageFile(obj, DOWN, false);
414     }
415 }
416
417 int ZoomUI::calculateSliderValue(int zoom)
418 {
419     BROWSER_LOGD("[%s:%d] zoom factor: %d", __PRETTY_FUNCTION__, __LINE__, zoom);
420     int rv = 1; //for zoom < ZOOM_75
421     if (zoom >= ZOOM_300)
422         rv = 6;
423     else if (zoom >= ZOOM_200)
424         rv = 5;
425     else if (zoom >= ZOOM_150)
426         rv = 4;
427     else if (zoom >= ZOOM_100)
428         rv = 3;
429     else if (zoom >= ZOOM_75)
430         rv = 2;
431
432     return rv;
433 }
434
435
436 }
437 }