2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "runtime/browser/native_window.h"
19 #include <Ecore_Wayland.h>
21 #include <EWebKit_internal.h>
24 #include "common/arraysize.h"
25 #include "common/logger.h"
30 const char* kEdjePath = "/usr/share/edje/xwalk/xwalk_tizen.edj";
31 const char* kWinowRotationEventKey = "wm,rotation,changed";
32 const char* kWinowFocusedEventKey = "focused";
33 const char* kWinowUnfocusedEventKey = "unfocused";
35 const int kPortraitNaturalAngle[] = {
36 0, // PORTRAIT_PRIMARY
37 180, // PORTRAIT_SECONDARY
38 270, // LANDSCAPE_PRIMARY
39 90, // LANDSCAPE_SECONDARY
43 const int kLandscapeNaturalAngle[] = {
44 270, // PORTRAIT_PRIMARY
45 90, // PORTRAIT_SECONDARY
46 0, // LANDSCAPE_PRIMARY
47 180, // LANDSCAPE_SECONDARY
52 NativeWindow::ScreenOrientation NativeAngleToOrientation(
53 int angle, NativeWindow::ScreenOrientation natural_orientation) {
55 natural_orientation == NativeWindow::ScreenOrientation::PORTRAIT_PRIMARY ?
56 kPortraitNaturalAngle :
57 kLandscapeNaturalAngle;
58 unsigned index = ARRAYSIZE(convert_table) - 1;
59 for (unsigned i = 0; i < ARRAYSIZE(convert_table); ++i) {
60 if (convert_table[i] == angle) {
65 return static_cast<NativeWindow::ScreenOrientation>(index);
71 NativeWindow::NativeWindow()
73 window_type_(Type::NORMAL),
75 currentViewModeFullScreen_(false),
86 NativeWindow::~NativeWindow() {
88 evas_object_del(window_);
91 void NativeWindow::Initialize() {
93 LOGGER(DEBUG) << "already initialized";
97 window_ = CreateWindowInternal();
98 elm_win_conformant_set(window_, EINA_TRUE);
100 ecore_wl_screen_size_get(&w, &h);
101 evas_object_resize(window_, w, h);
102 elm_win_size_base_set(window_, w, h);
103 elm_win_autodel_set(window_, EINA_TRUE);
104 evas_object_smart_callback_add(window_, "delete,request",
105 DidDeleteRequested, this);
106 evas_object_smart_callback_add(window_, "profile,changed",
107 DidProfileChanged, this);
109 #define EVAS_SIZE_EXPAND_FILL(obj) \
110 evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); \
111 evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
114 Evas_Object* bg = evas_object_rectangle_add(evas_object_evas_get(window_));
115 evas_object_color_set(bg, 0, 0, 0, 255);
116 EVAS_SIZE_EXPAND_FILL(bg);
117 elm_win_resize_object_add(window_, bg);
118 evas_object_render_op_set(bg, EVAS_RENDER_BLEND);
119 evas_object_show(bg);
122 Evas_Object* conformant = elm_conformant_add(window_);
123 EVAS_SIZE_EXPAND_FILL(conformant);
124 elm_win_resize_object_add(window_, conformant);
125 evas_object_show(conformant);
128 Evas_Object* top_layout = elm_layout_add(conformant);
129 elm_layout_file_set(top_layout, kEdjePath, "web-application");
130 EVAS_SIZE_EXPAND_FILL(top_layout);
131 elm_object_content_set(conformant, top_layout);
132 evas_object_show(top_layout);
133 #ifdef PROFILE_MOBILE
134 top_layout_ = top_layout;
138 Evas_Object* focus = elm_bg_add(top_layout);
139 evas_object_size_hint_align_set(focus, EVAS_HINT_FILL, EVAS_HINT_FILL);
140 evas_object_size_hint_weight_set(focus, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
141 elm_object_focus_allow_set(focus, EINA_TRUE);
142 elm_object_part_content_set(top_layout, "elm.swallow.content", focus);
143 EVAS_SIZE_EXPAND_FILL(focus);
144 elm_access_object_unregister(focus);
145 elm_atspi_accessible_role_set(focus, ELM_ATSPI_ROLE_FILLER);
146 evas_object_show(focus);
149 #ifdef PROFILE_MOBILE
151 Evas_Object *progressbar = elm_progressbar_add(top_layout);
152 EVAS_SIZE_EXPAND_FILL(progressbar);
153 elm_progressbar_unit_format_set(progressbar, "%1.1f%%");
154 elm_progressbar_horizontal_set(progressbar, EINA_TRUE);
155 elm_object_part_content_set(top_layout, "elm.swallow.progress", progressbar);
156 evas_object_show(progressbar);
157 progressbar_ = progressbar;
161 auto focus_callback = [](void* user_data,
164 NativeWindow* window = static_cast<NativeWindow*>(user_data);
165 window->DidFocusChanged(true);
167 auto unfocus_callback = [](void* user_data,
170 NativeWindow* window = static_cast<NativeWindow*>(user_data);
171 window->DidFocusChanged(false);
174 evas_object_smart_callback_add(focus,
175 kWinowFocusedEventKey,
178 evas_object_smart_callback_add(focus,
179 kWinowUnfocusedEventKey,
184 auto rotation_callback = [](void* user_data,
187 NativeWindow* window = static_cast<NativeWindow*>(user_data);
188 int degree = elm_win_rotation_get(obj);
189 window->DidRotation(degree);
191 evas_object_smart_callback_add(window_,
192 kWinowRotationEventKey,
197 natural_orientation_ = ScreenOrientation::LANDSCAPE_PRIMARY;
199 natural_orientation_ = ScreenOrientation::PORTRAIT_PRIMARY;
202 elm_win_indicator_mode_set(window_, ELM_WIN_INDICATOR_SHOW);
207 void NativeWindow::DidDeleteRequested(void* /*data*/,
208 Evas_Object* /*obj*/, void* /*event_info*/) {
209 LOGGER(DEBUG) << "didDeleteRequested";
213 void NativeWindow::DidProfileChanged(void* /*data*/,
214 Evas_Object* /*obj*/, void* /*event_info*/) {
215 LOGGER(DEBUG) << "didProfileChanged";
218 Evas_Object* NativeWindow::evas_object() const {
222 void NativeWindow::SetContent(Evas_Object* content) {
224 // If any object was already set as a content object in the same part,
225 // the previous object will be deleted automatically with this call.
226 // If the content is NULL, this call will just delete the previous object.
227 // If the If you wish to preserve it,
228 // issue elm_object_part_content_unset() on it first.
230 evas_object_show(content);
232 elm_object_part_content_unset(focus_, "elm.swallow.content"));
233 elm_object_part_content_set(focus_, "elm.swallow.content", content);
234 elm_object_focus_set(focus_, EINA_TRUE);
237 // attached webview was resized by evas_norender API
238 evas_norender(evas_object_evas_get(window_));
241 void NativeWindow::DidRotation(int degree) {
243 auto it = handler_table_.begin();
244 for ( ; it != handler_table_.end(); ++it) {
249 void NativeWindow::DidFocusChanged(bool got) {
250 if (content_ != NULL) {
251 ewk_view_focus_set(content_, got ? EINA_TRUE : EINA_FALSE);
255 int NativeWindow::AddRotationHandler(RotationHandler handler) {
256 int id = handler_id_++;
257 handler_table_[id] = handler;
261 void NativeWindow::RemoveRotationHandler(int id) {
262 handler_table_.erase(id);
265 NativeWindow::ScreenOrientation NativeWindow::orientation() const {
266 return NativeAngleToOrientation(rotation_, natural_orientation_);
269 void NativeWindow::SetRotationLock(int degree) {
271 rotation_ = degree % 360;
272 elm_win_wm_rotation_preferred_rotation_set(window_, rotation_);
275 void NativeWindow::SetRotationLock(ScreenOrientation orientation) {
276 auto& convert_table =
277 natural_orientation_ == ScreenOrientation::PORTRAIT_PRIMARY ?
278 kPortraitNaturalAngle :
279 kLandscapeNaturalAngle;
280 SetRotationLock(convert_table[static_cast<int>(orientation)]);
284 void NativeWindow::SetAutoRotation() {
285 elm_win_wm_rotation_preferred_rotation_set(window_, -1);
286 if (elm_win_wm_rotation_supported_get(window_)) {
287 const int rotation[4] = {0, 90, 180, 270};
288 elm_win_wm_rotation_available_rotations_set(window_, rotation, 4);
290 rotation_ = elm_win_rotation_get(window_);
293 void NativeWindow::SetCurrentViewModeFullScreen(bool mode) {
294 currentViewModeFullScreen_ = mode;
297 void NativeWindow::Show() {
298 evas_object_show(window_);
301 void NativeWindow::Active() {
302 elm_win_activate(window_);
305 void NativeWindow::InActive() {
306 elm_win_lower(window_);
309 void NativeWindow::FullScreen(bool enable) {
310 elm_win_indicator_opacity_set(window_,
311 (enable || currentViewModeFullScreen_) ? ELM_WIN_INDICATOR_TRANSPARENT : ELM_WIN_INDICATOR_OPAQUE);
314 #ifdef MANUAL_ROTATE_FEATURE_SUPPORT
315 void NativeWindow::EnableManualRotation(bool enable) {
316 LOGGER(DEBUG) << "set manual rotation : " << (enable ? "enabled" : "disabled");
317 elm_win_wm_rotation_manual_rotation_done_set(window_, enable ? EINA_TRUE : EINA_FALSE);
320 void NativeWindow::ManualRotationDone() {
321 if (EINA_TRUE == elm_win_wm_rotation_manual_rotation_done_get(window_)) {
322 elm_win_wm_rotation_manual_rotation_done(window_);
325 #endif // MANUAL_ROTATE_FEATURE_SUPPORT
327 #ifdef PROFILE_MOBILE
328 void NativeWindow::SignalEmit(const char* emission,
329 const char* source) {
330 elm_object_signal_emit(top_layout_, emission, source);
333 void NativeWindow::UpdateProgress(double value) {
334 elm_progressbar_value_set(progressbar_, ELM_SCALE_SIZE(value));
338 } // namespace runtime