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