notification window
[platform/framework/web/crosswalk-tizen.git] / runtime / browser / native_window.cc
1 /*
2  * Copyright (c) 2015 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 #include "runtime/browser/native_window.h"
18
19 #include <Ecore_Wayland.h>
20 #include <cstdint>
21
22 #include "common/logger.h"
23
24 namespace runtime {
25
26 namespace {
27   const char* kEdjePath = "/usr/share/edje/xwalk/xwalk_tizen.edj";
28   const char* kWinowRotationEventKey = "wm,rotation,changed";
29 }  // namespace
30
31
32 NativeWindow::NativeWindow()
33     : window_(NULL),
34       window_type_(Type::NORMAL),
35       initialized_(false),
36       layout_(NULL),
37       content_(NULL),
38       rotation_(0),
39       handler_id_(0) {
40 }
41
42 NativeWindow::~NativeWindow() {
43   if (window_)
44     evas_object_del(window_);
45 }
46
47 void NativeWindow::Initialize() {
48   if (initialized_) {
49     LOGGER(DEBUG) << "already initialized";
50     return;
51   }
52   // window
53   window_ = CreateWindowInternal();
54   elm_win_conformant_set(window_, EINA_TRUE);
55   int w, h;
56   ecore_wl_screen_size_get(&w, &h);
57   evas_object_resize(window_, w, h);
58   elm_win_autodel_set(window_, EINA_TRUE);
59   evas_object_smart_callback_add(window_, "delete,request",
60                                  DidDeleteRequested, this);
61   evas_object_smart_callback_add(window_, "profile,changed",
62                                  DidProfileChanged, this);
63
64   #define EVAS_SIZE_EXPAND_FILL(obj) \
65     evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); \
66     evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
67
68   // background
69   Evas_Object* bg = evas_object_rectangle_add(evas_object_evas_get(window_));
70   evas_object_color_set(bg, 0, 0, 0, 255);
71   EVAS_SIZE_EXPAND_FILL(bg);
72   elm_win_resize_object_add(window_, bg);
73   evas_object_render_op_set(bg, EVAS_RENDER_BLEND);
74   evas_object_show(bg);
75
76   // conformant
77   Evas_Object* conformant = elm_conformant_add(window_);
78   EVAS_SIZE_EXPAND_FILL(conformant);
79   elm_win_resize_object_add(window_, conformant);
80   evas_object_show(conformant);
81
82   // top layout
83   Evas_Object* top_layout = elm_layout_add(conformant);
84   elm_layout_file_set(top_layout, kEdjePath, "web-application");
85   EVAS_SIZE_EXPAND_FILL(top_layout);
86   elm_object_content_set(conformant, top_layout);
87   evas_object_show(top_layout);
88   layout_ = top_layout;
89
90   // Rotation
91   auto rotation_callback = [](void* user_data,
92                               Evas_Object* obj,
93                               void*) -> void {
94       NativeWindow* window = static_cast<NativeWindow*>(user_data);
95       int degree = elm_win_rotation_get(obj);
96       window->DidRotation(degree);
97   };
98   evas_object_smart_callback_add(window_,
99                                  kWinowRotationEventKey,
100                                  rotation_callback,
101                                  this);
102
103   if (w > h) {
104     natural_orientation_ = ScreenOrientation::LANDSCAPE_PRIMARY;
105   } else {
106     natural_orientation_ = ScreenOrientation::PORTRAIT_PRIMARY;
107   }
108
109   initialized_ = true;
110 }
111
112 void NativeWindow::DidDeleteRequested(void* /*data*/,
113     Evas_Object* /*obj*/, void* /*event_info*/) {
114   LOGGER(DEBUG) << "didDeleteRequested";
115   elm_exit();
116 }
117
118 void NativeWindow::DidProfileChanged(void* /*data*/,
119     Evas_Object* /*obj*/, void* /*event_info*/) {
120   LOGGER(DEBUG) << "didProfileChanged";
121 }
122
123 Evas_Object* NativeWindow::evas_object() const {
124   return window_;
125 }
126
127 void NativeWindow::SetContent(Evas_Object* content) {
128   // Remarks
129   // If any object was already set as a content object in the same part,
130   // the previous object will be deleted automatically with this call.
131   // If the content is NULL, this call will just delete the previous object.
132   // If the If you wish to preserve it,
133   // issue elm_object_part_content_unset() on it first.
134
135   evas_object_show(content);
136
137   // Hide unseted evas object to avoid focus and event callback problem.
138   evas_object_hide(
139     elm_object_part_content_unset(layout_, "elm.swallow.content"));
140   elm_object_part_content_set(layout_, "elm.swallow.content", content);
141   content_ = content;
142
143   // attached webview was resized by evas_norender API
144   evas_norender(evas_object_evas_get(window_));
145 }
146
147 void NativeWindow::DidRotation(int degree) {
148   rotation_ = degree;
149   auto it = handler_table_.begin();
150   for ( ; it != handler_table_.end(); ++it) {
151     it->second(degree);
152   }
153 }
154
155 int NativeWindow::AddRotationHandler(RotationHandler handler) {
156   int id = handler_id_++;
157   handler_table_[id] = handler;
158   return id;
159 }
160
161 void NativeWindow::RemoveRotationHandler(int id) {
162   handler_table_.erase(id);
163 }
164
165 void NativeWindow::SetRotationLock(int degree) {
166   if (degree != -1)
167     rotation_ = degree % 360;
168   elm_win_wm_rotation_preferred_rotation_set(window_, rotation_);
169 }
170
171 void NativeWindow::SetRotationLock(ScreenOrientation orientation) {
172   int portrait_natural_angle[] = {
173     0,  // PORTRAIT_PRIMARY
174     180,  // PORTRAIT_SECONDARY
175     270,  // LANDSCAPE_PRIMARY
176     90,  // LANDSCAPE_SECONDARY
177     0,  // NATURAL
178     -1  // ANY
179   };
180   int landscape_natural_angle[] = {
181     270,  // PORTRAIT_PRIMARY
182     90,  // PORTRAIT_SECONDARY
183     0,  // LANDSCAPE_PRIMARY
184     180,  // LANDSCAPE_SECONDARY
185     0,  // NATURAL
186     -1,  // ANY
187   };
188   auto& convert_table =
189       natural_orientation_ == ScreenOrientation::PORTRAIT_PRIMARY ?
190           portrait_natural_angle :
191           landscape_natural_angle;
192   SetRotationLock(convert_table[static_cast<int>(orientation)]);
193 }
194
195
196 void NativeWindow::SetAutoRotation() {
197   elm_win_wm_rotation_preferred_rotation_set(window_, -1);
198   if (elm_win_wm_rotation_supported_get(window_)) {
199     const int rotation[4] = {0, 90, 180, 270};
200     elm_win_wm_rotation_available_rotations_set(window_, rotation, 4);
201   }
202   rotation_ = elm_win_rotation_get(window_);
203 }
204
205 void NativeWindow::Show() {
206   evas_object_show(window_);
207 }
208
209 void NativeWindow::Active() {
210   elm_win_activate(window_);
211 }
212
213 void NativeWindow::InActive() {
214   elm_win_lower(window_);
215 }
216
217 void NativeWindow::FullScreen(bool enable) {
218   elm_win_indicator_opacity_set(window_,
219       enable ? ELM_WIN_INDICATOR_TRANSPARENT : ELM_WIN_INDICATOR_OPAQUE);
220 }
221
222 }  // namespace runtime