Profiling points updated, script fixed
[platform/framework/web/wrt.git] / src / wrt-client / window_data.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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  * @file        window_data.cpp
18  * @author      Jaroslaw Osmanski (j.osmanski@samsung.com)
19  * @version     1.0
20  * @brief       Window data class implementation
21  */
22 #include "window_data.h"
23
24 #include <ui-gadget.h>
25 #include <dpl/log/log.h>
26
27 namespace {
28 char const* const PLATFORM_EDJ_PATH = "/usr/share/edje/wrt/Platform.edj";
29 char const* const DAEMON_EDJ_PATH = "/usr/share/edje/wrt/Daemon.edj";
30 char const* const THEME_EDJ_PATH = "/usr/share/edje/wrt/wrt_theme.edj";
31 char const* const ELM_STATE_SHOW_CONTENT = "elm,state,show,content";
32 char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
33 char const* const ELM_SWALLOW_TOOLBAR = "elm.swallow.toolbar";
34 char const* const ELM_RECT_HIDDENOPTION = "elm.rect.hiddenOption";
35
36 const char *EDJE_SHOW_TOOLBAR_SIGNAL = "show,toolbar,signal";
37 const char *EDJE_HIDE_TOOLBAR_SIGNAL = "hide,toolbar,signal";
38 const char *EDJE_SHOW_HIDDENOPTION_SIGNAL = "show,hiddenOption,signal";
39 const char *EDJE_HIDE_HIDDENOPTION_SIGNAL = "hide,hiddenOption,signal";
40
41 char const* const ELM = "elm";
42 char const* const LAYOUT = "layout";
43 char const* const APPLICATION = "application";
44 char const* const INDICATOR = "indicator";
45 char const* const NOINDICATOR = "noindicator";
46 char const* const INTERNAL_LAYOUT = "internal_layout";
47 char const* const FLOATBACKWARD_BUTTON_STYLE = "wrt/backward";
48 } // anonymous namespace
49
50 WindowData::WindowData(unsigned long pid, bool manualInit) :
51     m_debugMode(false),
52     m_win(NULL),
53     m_naviBackButton(NULL),
54     m_toolbarTimer(NULL)
55 {
56     m_win = createWindow(pid);
57
58     if (!manualInit)
59     {
60         init();
61     }
62 }
63
64 WindowData::~WindowData()
65 {
66     LogDebug("");
67     evas_object_del(m_win);
68 }
69
70 void WindowData::init()
71 {
72     Assert(m_win != NULL && "m_win is null");
73
74     // import button theme
75     elm_theme_overlay_add(NULL, THEME_EDJ_PATH);
76
77     m_conformant = createConformant(m_win);
78     evas_object_show(m_conformant);
79     m_platform_layout = createPlatformLayout(m_conformant);
80     evas_object_show(m_platform_layout);
81     m_navigation = createNavigationBar(m_platform_layout);
82     evas_object_show(m_navigation);
83     m_user_layout = createUserLayout(m_navigation);
84     evas_object_show(m_user_layout);
85
86 }
87
88 void WindowData::setEvasObjectForLayout(Evas_Object* evas_object)
89 {
90     elm_object_content_set(m_conformant, evas_object);
91 }
92
93 void WindowData::unsetEvasObjectForLayout()
94 {
95     elm_object_content_unset(m_conformant);
96 }
97
98 void WindowData::toggleIndicator(bool fullscreen)
99 {
100     LogDebug(__PRETTY_FUNCTION__);
101     if (fullscreen) {
102         elm_win_indicator_mode_set(m_win, ELM_WIN_INDICATOR_HIDE);
103     }
104     else {
105         elm_win_indicator_mode_set(m_win, ELM_WIN_INDICATOR_SHOW);
106     }
107
108 }
109
110 void WindowData::setViewMode(
111         bool fullscreen,
112         CtxMenuItems ctxMenuItems)
113 {
114     LogDebug("setViewMode");
115     LogDebug("fullscreen: " << fullscreen );
116
117     m_fullscreen = fullscreen;
118
119     toggleIndicator(m_fullscreen);
120
121     m_ctxMenuItems = ctxMenuItems;
122
123     if(m_debugMode) {
124         showHiddenOption(m_user_layout);
125         createToolbar(m_ctxMenuItems);
126     }
127 }
128
129 void WindowData::createToolbar(CtxMenuItems ctxMenuItems)
130 {
131     Elm_Object_Item *toolbarIt;
132     Evas_Object *toolbarButton;
133     Evas_Object *toolbar;
134     char buf[100];
135
136     toolbar = elm_toolbar_add(m_user_layout);
137     if (!toolbar)
138         return;
139
140     elm_object_style_set(toolbar, "naviframe");
141     elm_object_part_content_set(m_user_layout,
142             ELM_SWALLOW_TOOLBAR,
143             toolbar);
144
145     std::list<CtxMenuItem>::iterator itor;
146     for (itor = ctxMenuItems.begin(); itor != ctxMenuItems.end(); ++itor) {
147         toolbarButton = elm_button_add(toolbar);
148         if (!toolbarButton)
149             return;
150
151         evas_object_size_hint_align_set(toolbarButton,
152                 EVAS_HINT_FILL,
153                 EVAS_HINT_FILL);
154         evas_object_size_hint_weight_set(toolbarButton,
155                 EVAS_HINT_EXPAND,
156                 EVAS_HINT_EXPAND);
157
158         Evas_Object *ic = elm_icon_add(toolbar);
159
160         // (*itor).icon.c_str() guarantied not to have format specifiers
161         snprintf(buf, sizeof(buf), (*itor).icon.c_str());
162
163         elm_icon_file_set(ic, buf, NULL);
164         evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
165         elm_icon_resizable_set(ic, EINA_TRUE, EINA_TRUE);
166         elm_object_part_content_set(toolbarButton, "icon", ic);
167
168         evas_object_smart_callback_add(toolbarButton,
169                 "clicked",
170                 (*itor).callback,
171                 (*itor).data);
172         toolbarIt = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
173         elm_object_item_part_content_set(toolbarIt, "object", toolbarButton);
174
175         //for margin button between buttons
176         toolbarButton = elm_button_add(toolbar);
177         if (!toolbarButton)
178             return;
179         evas_object_color_set(
180                 toolbarButton,
181                 255,
182                 255,
183                 255,
184                 0);
185         toolbarIt = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
186         elm_object_item_part_content_set(toolbarIt, "object", toolbarButton);
187     }
188
189     optionheaderClose = TRUE;
190
191     elm_object_part_content_set(m_user_layout,
192             ELM_SWALLOW_TOOLBAR,
193             toolbar);
194 }
195
196 void WindowData::showToolbar()
197 {
198     emitSignalForUserLayout(EDJE_SHOW_TOOLBAR_SIGNAL, "");
199     m_toolbarTimer = ecore_timer_add(10.0, hideToolbarCallback, this);
200 }
201
202 void WindowData::hideToolbar()
203 {
204     emitSignalForUserLayout(EDJE_HIDE_TOOLBAR_SIGNAL, "");
205     if(m_toolbarTimer) {
206         ecore_timer_del(m_toolbarTimer);
207         m_toolbarTimer = NULL;
208     }
209 }
210
211 Evas_Object* WindowData::createWindow(unsigned long pid)
212 {
213     ADD_PROFILING_POINT("elm_win_add", "start");
214     Evas_Object* window = elm_win_add(NULL, "wrt-widget", ELM_WIN_BASIC);
215     ADD_PROFILING_POINT("elm_win_add", "stop");
216     ecore_x_window_prop_property_set(
217         elm_win_xwindow_get(window),
218         ECORE_X_ATOM_NET_WM_PID,
219         ECORE_X_ATOM_CARDINAL, 32, &pid, 1);
220     elm_win_title_set(window, "wrt-widget");
221     elm_win_conformant_set(window, EINA_TRUE);
222     int w, h;
223     ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
224     evas_object_resize(window, w, h);
225
226     evas_object_smart_callback_add(window,
227             "profile,changed",
228             winProfileChangedCallback,
229             this);
230     return window;
231 }
232
233 Evas_Object* WindowData::createConformant(Evas_Object* parent)
234 {
235     Assert(parent != NULL && "Parent is null");
236     Evas_Object* conformant = elm_conformant_add(parent);
237
238     evas_object_size_hint_weight_set(
239             conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
240     evas_object_size_hint_align_set(conformant, EVAS_HINT_FILL, EVAS_HINT_FILL);
241     elm_win_resize_object_add(parent, conformant);
242     return conformant;
243 }
244
245 Evas_Object* WindowData::createPlatformLayout(Evas_Object* parent)
246 {
247     Evas_Object*  platform_layout = elm_layout_add(parent);
248
249     ADD_PROFILING_POINT("elm_layout_theme_set", "start");
250     elm_layout_file_set(platform_layout, PLATFORM_EDJ_PATH, "platformlayout");
251     ADD_PROFILING_POINT("elm_layout_theme_set", "stop");
252
253     evas_object_size_hint_align_set(platform_layout,
254             EVAS_HINT_FILL,
255             EVAS_HINT_FILL);
256     evas_object_size_hint_weight_set(platform_layout,
257             EVAS_HINT_EXPAND,
258             EVAS_HINT_EXPAND);
259
260     elm_object_content_set(parent, platform_layout);
261     edje_object_signal_emit(
262             elm_layout_edje_get(platform_layout), ELM_STATE_SHOW_CONTENT, ELM);
263     return platform_layout;
264 }
265
266 Evas_Object* WindowData::createNavigationBar(Evas_Object* parent)
267 {
268     Assert(parent != NULL && "Parent for naviframe is null");
269     Evas_Object* navigation = elm_naviframe_add(parent);
270
271     evas_object_size_hint_align_set(navigation,
272             EVAS_HINT_FILL,
273             EVAS_HINT_FILL);
274     evas_object_size_hint_weight_set(navigation,
275             EVAS_HINT_EXPAND,
276             EVAS_HINT_EXPAND);
277     elm_object_part_content_set(parent, ELM_SWALLOW_CONTENT, navigation);
278     //elm_object_content_set(parent, navigation);
279     return navigation;
280 }
281
282 Evas_Object* WindowData::createUserLayout(Evas_Object* parent)
283 {
284     Assert(parent != NULL && "Parent for User Layout is null");
285     Evas_Object* layout = elm_layout_add(parent);
286     elm_layout_file_set(layout, DAEMON_EDJ_PATH, "client");
287     evas_object_size_hint_weight_set(
288             layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
289     evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
290
291     ADD_PROFILING_POINT("elm_naviframe_item_push", "start");
292     Elm_Object_Item* naviIt = elm_naviframe_item_push(
293         /* Evas_Object *obj */
294         parent,
295         /* const char *title_label  */
296         "",
297         /* Evas_Object *prev_btn */
298         NULL,
299         /* Evas_Object *next_btn */
300         NULL,
301         /* Evas_Object *content */
302         layout,
303         /* const char *item_style */
304         NULL);
305     ADD_PROFILING_POINT("elm_naviframe_item_push", "stop");
306
307     elm_naviframe_item_title_visible_set(naviIt, EINA_FALSE);
308
309     return layout;
310 }
311
312 void WindowData::showHiddenOption(Evas_Object* parent)
313 {
314     Assert(parent != NULL && "Parent for Hiden Option");
315
316     emitSignalForUserLayout(EDJE_SHOW_HIDDENOPTION_SIGNAL, "");
317
318     edje_object_signal_callback_add(elm_layout_edje_get(parent),
319             "mouse,clicked,1",
320             "elm.rect.hiddenOption",
321             controlHiddenOptionCallback,
322             this);
323 }
324
325 void WindowData::hideHiddenOption(Evas_Object* parent)
326 {
327     Assert(parent != NULL && "Parent for Hiden Option");
328
329     emitSignalForUserLayout(EDJE_HIDE_HIDDENOPTION_SIGNAL, "");
330
331     edje_object_signal_callback_del(elm_layout_edje_get(parent),
332             "mouse,clicked,1",
333             "elm.rect.hiddenOption",
334             controlHiddenOptionCallback);
335 }
336
337 void WindowData::initFullViewMode ()
338 {
339     hideToolbar();
340     showHiddenOption(m_user_layout);
341 }
342
343 Evas_Object * WindowData::setDesktopIcon()
344 {
345     // set window icon
346     Evas_Object *icon = evas_object_image_add(evas_object_evas_get(m_win));
347     evas_object_image_file_set(icon,
348             "/opt/share/icons/default/small/com.samsung.elm-demo-slp.png",
349             NULL);
350     elm_win_icon_object_set(m_win, icon);
351
352     return icon;
353 }
354
355 void WindowData::addNaviBackButtonCallback(
356         const char* event,
357         CallbackType callback,
358         const void* data)
359 {
360     Assert(m_naviBackButton != NULL && "m_naviBackButton is null");
361     evas_object_smart_callback_add(m_naviBackButton, event, callback, data);
362 }
363
364 void* WindowData::delNaviBackButtonCallback(
365         const char* event,
366         CallbackType callBack)
367 {
368     Assert(m_naviBackButton != NULL && "m_naviBackButton is null");
369     return evas_object_smart_callback_del(m_naviBackButton, event, callBack);
370 }
371
372 void WindowData::userlayoutCallbackAdd(
373         const Evas_Callback_Type event,
374         EvasCallbackType callback,
375         const void* data)
376 {
377     Assert(m_user_layout != NULL && "m_user_layout is null");
378     evas_object_event_callback_add(m_user_layout, event, callback, data);
379 }
380
381 void* WindowData::userlayoutCallbackDel(
382         const Evas_Callback_Type event,
383         EvasCallbackType callBack)
384 {
385     Assert(m_user_layout != NULL && "m_user_layout is null");
386     return evas_object_event_callback_del(m_user_layout, event, callBack);
387 }
388
389 void WindowData::emitSignalForUserLayout(
390         const char* emission, const char* source)
391 {
392     LogInfo("emitSignalForUserLayout called");
393     Assert(m_user_layout != NULL && "m_user_layout is null");
394     Assert(emission != NULL && "emission is null");
395     Assert(source != NULL && "source is null");
396
397     edje_object_signal_emit(
398             elm_layout_edje_get(m_user_layout), emission, source);
399 }
400
401 void WindowData::moreButtonCallback(void *data,
402         Evas_Object */*obj*/,
403         void */*event_info*/)
404 {
405     WindowData* This = static_cast<WindowData*>(data);
406     Elm_Object_Item *naviIt = elm_naviframe_top_item_get(This->m_navigation);
407
408     if (This->optionheaderClose)
409         elm_object_item_signal_emit(naviIt, "elm,state,optionheader,open", "");
410     else
411         elm_object_item_signal_emit(naviIt, "elm,state,optionheader,close", "");
412
413     This->optionheaderClose = !This->optionheaderClose;
414 }
415
416
417 void WindowData::changeViewModeCallback(void *data,
418         Evas_Object */*obj*/,
419         void */*event_info*/)
420 {
421     WindowData* This = static_cast<WindowData*>(data);
422     Elm_Object_Item *naviIt = elm_naviframe_top_item_get(This->m_navigation);
423
424     if(elm_naviframe_item_title_visible_get(naviIt)) {
425         This->showHiddenOption(This->m_user_layout);
426
427     } else {
428         This ->hideToolbar();
429     }
430 }
431
432 void WindowData::controlHiddenOptionCallback(void *data,
433         Evas_Object * /*obj*/,
434         const char * /*emission*/,
435         const char * /*source*/)
436 {
437     LogDebug("controlHiddenOptionCallback");
438     WindowData* This = static_cast<WindowData *>(data);
439     const char* state = edje_object_part_state_get(
440             elm_layout_edje_get(This->m_user_layout), "elm.swallow.toolbar",
441             NULL);
442
443     if (state && !strncmp(state, "default", strlen("default"))) {
444         This->showToolbar();
445         This->hideHiddenOption(This->m_user_layout);
446     } else {
447         This->initFullViewMode();
448     }
449 }
450
451 Eina_Bool WindowData::hideToolbarCallback(void *data)
452 {
453     WindowData *This = static_cast<WindowData *>(data);
454
455     This->initFullViewMode();
456     return TRUE;
457 }
458
459 void WindowData::toggleFullscreen(bool fullscreen)
460 {
461     LogDebug(__PRETTY_FUNCTION__);
462
463     static bool alreadyFullscreen = false;
464
465     if (alreadyFullscreen == fullscreen) {
466         // window is in fullscreen mode and fullscreen mode is requested, or
467         // window is not in fullscreen and a request is made to exit fullscreen
468         // In these two situations we don't have to do anything here.
469         return;
470     }
471
472     if (m_indicator) //If indicator is shown by default, toggle it.
473         toggleIndicator(!fullscreen);
474
475     alreadyFullscreen = !alreadyFullscreen;
476 }
477
478 void WindowData::winProfileChangedCallback(void *data,
479                                            Evas_Object* /*obj*/,
480                                            void* /*eventInfo*/)
481 {
482     LogDebug("winProfileChangedCallback");
483     if (data == NULL) {
484         return;
485     }
486     WindowData* This = static_cast<WindowData *>(data);
487     const char *profile = elm_config_profile_get();
488
489     if (!strcmp(profile, "desktop")) {
490         elm_win_indicator_mode_set(This->m_win, ELM_WIN_INDICATOR_HIDE);
491         if (!This->m_icon)
492             This->m_icon = This->setDesktopIcon();
493     }
494     else
495         elm_win_indicator_mode_set(This->m_win, ELM_WIN_INDICATOR_SHOW);
496 }
497