b1542f3d62242c93eb93660969bacbdebe00e2ae
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / ui / native_app_window_views.cc
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "xwalk/runtime/browser/ui/native_app_window_views.h"
6
7 #include "content/public/browser/notification_service.h"
8 #include "content/public/browser/web_contents.h"
9 #include "ui/gfx/screen.h"
10 #include "ui/views/controls/webview/webview.h"
11 #include "ui/views/widget/desktop_aura/desktop_screen.h"
12 #include "ui/views/widget/widget.h"
13 #include "xwalk/runtime/browser/ui/top_view_layout_views.h"
14 #include "xwalk/runtime/browser/ui/xwalk_views_delegate.h"
15 #include "xwalk/runtime/common/xwalk_notification_types.h"
16
17 #if defined(OS_WIN)
18 #include "ui/views/window/native_frame_view.h"
19 #endif
20
21 #if defined(OS_TIZEN)
22 #include "xwalk/runtime/browser/ui/native_app_window_tizen.h"
23 #endif
24
25 namespace xwalk {
26
27 NativeAppWindowViews::NativeAppWindowViews(
28     const NativeAppWindow::CreateParams& create_params)
29   : create_params_(create_params),
30     delegate_(create_params.delegate),
31     web_contents_(create_params.web_contents),
32     web_view_(NULL),
33     window_(NULL),
34     is_fullscreen_(false),
35     minimum_size_(create_params.minimum_size),
36     maximum_size_(create_params.maximum_size),
37     resizable_(create_params.resizable) {}
38
39 NativeAppWindowViews::~NativeAppWindowViews() {}
40
41 // Two-step initialization is needed here so that calls done by views::Widget to
42 // its delegate during views::Widget::Init() reach the correct implementation --
43 // e.g. ViewHierarchyChanged().
44 void NativeAppWindowViews::Initialize() {
45   CHECK(!window_);
46   window_ = new views::Widget;
47
48   views::Widget::InitParams params;
49   params.delegate = this;
50   params.remove_standard_frame = false;
51   params.use_system_default_icon = true;
52   params.show_state = create_params_.state;
53   params.parent = create_params_.parent;
54 #if defined(OS_TIZEN_MOBILE)
55   params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
56   // On Tizen apps are sized to the work area.
57   gfx::Rect bounds =
58       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
59   params.bounds = bounds;
60 #else
61   params.type = views::Widget::InitParams::TYPE_WINDOW;
62   params.bounds = create_params_.bounds;
63 #endif
64   params.net_wm_pid = create_params_.net_wm_pid;
65
66   window_->Init(params);
67
68 #if defined(OS_TIZEN_MOBILE)
69   // Set the bounds manually to avoid inset.
70   window_->SetBounds(bounds);
71 #elif !defined(USE_OZONE)
72   window_->CenterWindow(create_params_.bounds.size());
73 #endif
74
75   if (create_params_.state == ui::SHOW_STATE_FULLSCREEN)
76     SetFullscreen(true);
77
78   // TODO(hmin): Need to configure the maximum and minimum size of this window.
79   window_->AddObserver(this);
80 }
81
82 gfx::NativeWindow NativeAppWindowViews::GetNativeWindow() const {
83   return window_->GetNativeWindow();
84 }
85
86 void NativeAppWindowViews::UpdateIcon(const gfx::Image& icon) {
87   icon_ = icon;
88   window_->UpdateWindowIcon();
89 }
90
91 void NativeAppWindowViews::UpdateTitle(const base::string16& title) {
92   title_ = title;
93   window_->UpdateWindowTitle();
94 }
95
96 gfx::Rect NativeAppWindowViews::GetRestoredBounds() const {
97   return window_->GetRestoredBounds();
98 }
99
100 gfx::Rect NativeAppWindowViews::GetBounds() const {
101   return window_->GetWindowBoundsInScreen();
102 }
103
104 void NativeAppWindowViews::SetBounds(const gfx::Rect& bounds) {
105   window_->SetBounds(bounds);
106 }
107
108 void NativeAppWindowViews::Focus() {
109   // window_->Focus();
110 }
111
112 void NativeAppWindowViews::Show() {
113   window_->Show();
114 }
115
116 void NativeAppWindowViews::Hide() {
117   window_->Hide();
118 }
119
120 void NativeAppWindowViews::Maximize() {
121   window_->Maximize();
122 }
123
124 void NativeAppWindowViews::Minimize() {
125   window_->Minimize();
126 }
127
128 void NativeAppWindowViews::SetFullscreen(bool fullscreen) {
129   views::ViewsDelegate::views_delegate->SetShouldShowTitleBar(!fullscreen);
130
131   if (is_fullscreen_ == fullscreen)
132     return;
133   is_fullscreen_ = fullscreen;
134   window_->SetFullscreen(is_fullscreen_);
135
136   content::NotificationService::current()->Notify(
137       xwalk::NOTIFICATION_FULLSCREEN_CHANGED,
138       content::Source<NativeAppWindow>(this),
139       content::NotificationService::NoDetails());
140 }
141
142 void NativeAppWindowViews::Restore() {
143   window_->Restore();
144 }
145
146 void NativeAppWindowViews::FlashFrame(bool flash) {
147   window_->FlashFrame(flash);
148 }
149
150 void NativeAppWindowViews::Close() {
151   window_->Close();
152 }
153
154 bool NativeAppWindowViews::IsActive() const {
155   return window_->IsActive();
156 }
157
158 bool NativeAppWindowViews::IsMaximized() const {
159   return window_->IsMaximized();
160 }
161
162 bool NativeAppWindowViews::IsMinimized() const {
163   return window_->IsMinimized();
164 }
165
166 bool NativeAppWindowViews::IsFullscreen() const {
167   return is_fullscreen_;
168 }
169
170 TopViewLayout* NativeAppWindowViews::top_view_layout() {
171   return static_cast<TopViewLayout*>(GetLayoutManager());
172 }
173
174 ////////////////////////////////////////////////////////////
175 // WidgetDelegate implementation
176 ////////////////////////////////////////////////////////////
177 views::View* NativeAppWindowViews::GetInitiallyFocusedView() {
178   return web_view_;
179 }
180
181 views::View* NativeAppWindowViews::GetContentsView() {
182   return this;
183 }
184
185 views::Widget* NativeAppWindowViews::GetWidget() {
186   return window_;
187 }
188
189 const views::Widget* NativeAppWindowViews::GetWidget() const {
190   return window_;
191 }
192
193 base::string16 NativeAppWindowViews::GetWindowTitle() const {
194   return title_;
195 }
196
197 void NativeAppWindowViews::DeleteDelegate() {
198   window_->RemoveObserver(this);
199   delegate_->OnWindowDestroyed();
200   delete this;
201 }
202 gfx::ImageSkia NativeAppWindowViews::GetWindowAppIcon() {
203   return GetWindowIcon();
204 }
205
206 gfx::ImageSkia NativeAppWindowViews::GetWindowIcon() {
207   return *icon_.ToImageSkia();
208 }
209
210 bool NativeAppWindowViews::ShouldShowWindowTitle() const {
211   return true;
212 }
213
214 void NativeAppWindowViews::SaveWindowPlacement(const gfx::Rect& bounds,
215                                                ui::WindowShowState show_state) {
216   // TODO(hmin): views::WidgetDelegate::SaveWindowPlacement(bounds, show_state);
217 }
218
219 bool NativeAppWindowViews::GetSavedWindowPlacement(const views::Widget* widget,
220     gfx::Rect* bounds, ui::WindowShowState* show_state) const {
221   // TODO(hmin): Get the saved window placement.
222   return false;
223 }
224
225 bool NativeAppWindowViews::CanResize() const {
226   return resizable_ &&
227       (maximum_size_.IsEmpty() || minimum_size_ != maximum_size_);
228 }
229
230 bool NativeAppWindowViews::CanMaximize() const {
231   return resizable_ && maximum_size_.IsEmpty();
232 }
233
234 #if defined(OS_WIN)
235 views::NonClientFrameView* NativeAppWindowViews::CreateNonClientFrameView(
236     views::Widget* widget) {
237   return new views::NativeFrameView(widget);
238 }
239 #endif
240
241 ////////////////////////////////////////////////////////////
242 // views::View implementation
243 ////////////////////////////////////////////////////////////
244
245 void NativeAppWindowViews::ChildPreferredSizeChanged(views::View* child) {
246   // We only re-layout when the top view changes its preferred size (and notify
247   // us by calling its own function PreferredSizeChanged()). We don't react to
248   // changes in preferred size for the content view since we are currently
249   // setting its bounds to the maximum size available.
250   if (child == top_view_layout()->top_view())
251     Layout();
252 }
253
254 void NativeAppWindowViews::ViewHierarchyChanged(
255     const ViewHierarchyChangedDetails& details) {
256   if (details.is_add && details.child == this) {
257     TopViewLayout* layout = new TopViewLayout();
258     SetLayoutManager(layout);
259
260     web_view_ = new views::WebView(NULL);
261     web_view_->SetWebContents(web_contents_);
262     AddChildView(web_view_);
263     layout->set_content_view(web_view_);
264   }
265 }
266
267 void NativeAppWindowViews::OnFocus() {
268   web_view_->RequestFocus();
269 }
270
271 gfx::Size NativeAppWindowViews::GetMaximumSize() const {
272   return maximum_size_;
273 }
274
275 gfx::Size NativeAppWindowViews::GetMinimumSize() const {
276   return minimum_size_;
277 }
278
279 ////////////////////////////////////////////////////////////
280 // views::WidgetObserver implementation
281 ////////////////////////////////////////////////////////////
282 void NativeAppWindowViews::OnWidgetClosing(views::Widget* widget) {
283 }
284 void NativeAppWindowViews::OnWidgetCreated(views::Widget* widget) {
285 }
286 void NativeAppWindowViews::OnWidgetDestroying(views::Widget* widget) {
287 }
288 void NativeAppWindowViews::OnWidgetDestroyed(views::Widget* widget) {
289 }
290 void NativeAppWindowViews::OnWidgetBoundsChanged(views::Widget* widget,
291     const gfx::Rect& new_bounds) {
292 }
293
294 // static
295 NativeAppWindow* NativeAppWindow::Create(
296     const NativeAppWindow::CreateParams& create_params) {
297   NativeAppWindowViews* window;
298 #if defined(OS_TIZEN)
299   window = new NativeAppWindowTizen(create_params);
300 #else
301   window = new NativeAppWindowViews(create_params);
302 #endif
303   window->Initialize();
304   return window;
305 }
306
307 // static
308 void NativeAppWindow::Initialize() {
309   CHECK(!views::ViewsDelegate::views_delegate);
310   gfx::Screen::SetScreenInstance(
311       gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen());
312   views::ViewsDelegate::views_delegate = new XWalkViewsDelegate();
313 }
314
315 }  // namespace xwalk