Merge pull request #49 from szulak/fix_lib_name
[platform/framework/web/crosswalk-tizen.git] / runtime / browser / splash_screen.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/splash_screen.h"
18
19 #include <algorithm>
20 #include <map>
21 #include <string>
22
23 #include <Ecore_Wayland.h>
24 #include <Evas_Legacy.h>
25
26 #include "common/logger.h"
27 #include "runtime/browser/native_window.h"
28 #include "wgt_manifest_handlers/splash_screen_handler.h"
29
30 using ScreenOrientation = runtime::NativeWindow::ScreenOrientation;
31
32 namespace {
33
34 enum class BorderOption { REPEAT = 1, STRETCH, ROUND };
35
36 wgt::parse::ScreenOrientation ChooseOrientation(
37     const std::map<wgt::parse::ScreenOrientation,
38     wgt::parse::SplashScreenData>& splash_map,
39     ScreenOrientation screen_orientation) {
40   auto orientation_pair = splash_map.end();
41
42   if (screen_orientation ==
43       runtime::NativeWindow::ScreenOrientation::PORTRAIT_PRIMARY) {
44      orientation_pair =
45          splash_map.find(wgt::parse::ScreenOrientation::PORTRAIT);
46   } else {
47     orientation_pair =
48         splash_map.find(wgt::parse::ScreenOrientation::LANDSCAPE);
49   }
50   if (orientation_pair == splash_map.end())
51         orientation_pair = splash_map.find(wgt::parse::ScreenOrientation::AUTO);
52
53   if (orientation_pair != splash_map.end()) return orientation_pair->first;
54   return wgt::parse::ScreenOrientation::NONE;
55 }
56
57 bool ParseImageBorder(const std::vector<std::string>& borders,
58                       std::vector<int>* border_values,
59                       std::vector<BorderOption>* border_options) {
60   std::map<std::string, BorderOption> scaling_string;
61   scaling_string["repeat"] = BorderOption::REPEAT;
62   scaling_string["stretch"] = BorderOption::STRETCH;
63   scaling_string["round"] = BorderOption::ROUND;
64
65   for (const auto& border : borders) {
66     std::string::size_type px_index = border.find("px");
67     if (px_index != std::string::npos) {
68       std::string border_value(border.begin(), border.begin() + px_index);
69       border_values->push_back(std::atoi(border_value.c_str()));
70     }
71     for (const auto& border_string_val : scaling_string) {
72       std::string::size_type index = border.find(border_string_val.first);
73       if (index != std::string::npos) {
74         border_options->push_back(border_string_val.second);
75       }
76     }
77   }
78
79   LOGGER(DEBUG) << "Image border values:";
80   for (const auto& border_value : *border_values) {
81     LOGGER(DEBUG) << border_value;
82   }
83   LOGGER(DEBUG) << "Image border scaling values:";
84   for (const auto& border_option : *border_options) {
85     LOGGER(DEBUG) << static_cast<int>(border_option);
86   }
87
88   return !border_values->empty() && !border_options->empty();
89 }
90
91 }  // namespace
92
93 namespace runtime {
94
95 SplashScreen::SplashScreen(
96     runtime::NativeWindow* window,
97     std::shared_ptr<const wgt::parse::SplashScreenInfo> ss_info,
98     const std::string& app_path)
99     : ss_info_(ss_info),
100       window_(window),
101       image_(nullptr),
102       background_(nullptr),
103       background_image_(nullptr),
104       is_active_(false) {
105   LOGGER(DEBUG) << "start of create splash screen";
106   if (ss_info == nullptr) return;
107   auto splash_map = ss_info->splash_screen_data();
108   auto used_orientation =
109       ChooseOrientation(splash_map, window->natural_orientation());
110   if (used_orientation == wgt::parse::ScreenOrientation::NONE) return;
111
112   auto dimensions = GetDimensions();
113
114   SetBackground(splash_map[used_orientation], window->evas_object(),
115                      dimensions, app_path);
116   SetImage(splash_map[used_orientation], window->evas_object(),
117                      dimensions, app_path);
118   is_active_ = true;
119 }
120
121
122 void SplashScreen::HideSplashScreen(HideReason reason) {
123   if (!is_active_) return;
124   if (reason == HideReason::RENDERED &&
125       ss_info_->ready_when() != wgt::parse::ReadyWhen::FIRSTPAINT) {
126     return;
127   }
128   if (reason == HideReason::LOADFINISHED &&
129       ss_info_->ready_when() != wgt::parse::ReadyWhen::COMPLETE) {
130     return;
131   }
132   if (reason == HideReason::CUSTOM &&
133       ss_info_->ready_when() != wgt::parse::ReadyWhen::CUSTOM) {
134     return;
135   }
136
137   evas_object_hide(background_);
138   evas_object_hide(image_);
139   evas_object_del(background_);
140   evas_object_del(image_);
141   background_ = nullptr;
142   image_ = nullptr;
143   is_active_ = false;
144 }
145
146 std::pair<int, int> SplashScreen::GetDimensions() {
147   int w, h;
148   ecore_wl_screen_size_get(&w, &h);
149   evas_object_resize(background_, w, h);
150   return std::make_pair(w, h);
151 }
152
153 void SplashScreen::SetBackground(
154     const wgt::parse::SplashScreenData& splash_data, Evas_Object* parent,
155     const SplashScreenBound& bound, const std::string& app_path) {
156   background_ = elm_bg_add(parent);
157   if (!background_) return;
158   evas_object_resize(background_, bound.first, bound.second);
159
160   if (splash_data.background_color != nullptr) {
161     elm_bg_color_set(background_,
162                      splash_data.background_color->red,
163                      splash_data.background_color->green,
164                      splash_data.background_color->blue);
165   }
166
167   std::vector<int> border_values;
168   std::vector<BorderOption> border_options;
169
170   if (!splash_data.background_image.empty() &&
171       ParseImageBorder(
172           splash_data.image_border, &border_values, &border_options)) {
173     const std::string& background_image_path =
174         splash_data.background_image.front();
175
176     background_image_ = elm_image_add(background_);
177     evas_object_image_file_set(background_image_,
178                                (app_path + background_image_path).c_str(),
179                                NULL);
180     elm_image_aspect_fixed_set(background_image_, 0);
181     evas_object_image_border_center_fill_set(background_image_,
182                                              EVAS_BORDER_FILL_DEFAULT);
183
184     evas_object_resize(background_image_, bound.first, bound.second);
185
186     int border_l, border_r, border_t, border_b;
187     switch (border_values.size()) {
188       case 1:
189         border_l = border_r = border_t = border_b = -border_values[0];
190         break;
191       case 2:
192         border_t = border_b =  border_values[0];
193         border_l = border_r =  border_values[1];
194         break;
195       case 4:
196         border_t = border_values[0];
197         border_r = border_values[1];
198         border_b = border_values[2];
199         border_l = border_values[3];
200         break;
201       default:
202         border_l = border_r = border_t = border_b = 0;
203     }
204     evas_object_image_border_set(background_image_,
205                                  border_l,
206                                  border_r,
207                                  border_t,
208                                  border_b);
209     // TODO(a.szulakiewi): add scaling of horizontal and vertical borders
210   }
211
212   evas_object_show(background_);
213   evas_object_show(background_image_);
214 }
215
216 void SplashScreen::SetImage(
217     const wgt::parse::SplashScreenData& splash_data, Evas_Object* parent,
218     const SplashScreenBound& bound, const std::string& app_path) {
219   if (!background_) return;
220   image_ = elm_image_add(background_);
221   if (!image_) return;
222
223   const std::string& image_path = splash_data.image.front();
224   elm_image_file_set(image_, (app_path + image_path).c_str(), NULL);
225   evas_object_resize(image_, bound.first, bound.second);
226   evas_object_show(image_);
227 }
228 }  // namespace runtime