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