OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. 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 "content/shell/shell.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "content/public/browser/web_contents.h" | |
10 #include "content/public/browser/web_contents_view.h" | |
11 #include "ui/aura/env.h" | |
12 #include "ui/aura/root_window.h" | |
13 #include "ui/aura/window.h" | |
14 #include "ui/base/accessibility/accessibility_types.h" | |
15 #include "ui/base/clipboard/clipboard.h" | |
16 #include "ui/base/events/event.h" | |
17 #include "ui/base/resource/resource_bundle.h" | |
18 #include "ui/gfx/screen.h" | |
19 #include "ui/views/controls/button/label_button.h" | |
20 #include "ui/views/controls/textfield/textfield.h" | |
21 #include "ui/views/controls/textfield/textfield_controller.h" | |
22 #include "ui/views/controls/webview/webview.h" | |
23 #include "ui/views/layout/fill_layout.h" | |
24 #include "ui/views/layout/grid_layout.h" | |
25 #include "ui/views/test/desktop_test_views_delegate.h" | |
26 #include "ui/views/view.h" | |
27 #include "ui/views/widget/desktop_aura/desktop_screen.h" | |
28 #include "ui/views/widget/widget.h" | |
29 #include "ui/views/widget/widget_delegate.h" | |
30 | |
31 #if defined(OS_CHROMEOS) | |
32 #include "chromeos/dbus/dbus_thread_manager.h" | |
33 #include "content/shell/minimal_shell.h" | |
34 #include "ui/aura/test/test_screen.h" | |
35 #endif | |
36 | |
37 namespace content { | |
38 | |
39 namespace { | |
40 // ViewDelegate implementation for aura content shell | |
41 class ShellViewsDelegateAura : public views::DesktopTestViewsDelegate { | |
42 public: | |
43 ShellViewsDelegateAura() : use_transparent_windows_(false) { | |
44 } | |
45 | |
46 virtual ~ShellViewsDelegateAura() { | |
47 } | |
48 | |
49 void SetUseTransparentWindows(bool transparent) { | |
50 use_transparent_windows_ = transparent; | |
51 } | |
52 | |
53 // Overridden from views::TestViewsDelegate: | |
54 virtual bool UseTransparentWindows() const OVERRIDE { | |
55 return use_transparent_windows_; | |
56 } | |
57 | |
58 private: | |
59 bool use_transparent_windows_; | |
60 | |
61 DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegateAura); | |
62 }; | |
63 | |
64 // Maintain the UI controls and web view for content shell | |
65 class ShellWindowDelegateView : public views::WidgetDelegateView, | |
66 public views::TextfieldController, | |
67 public views::ButtonListener { | |
68 public: | |
69 enum UIControl { | |
70 BACK_BUTTON, | |
71 FORWARD_BUTTON, | |
72 STOP_BUTTON | |
73 }; | |
74 | |
75 ShellWindowDelegateView(Shell* shell) | |
76 : shell_(shell), | |
77 toolbar_view_(new View), | |
78 contents_view_(new View) { | |
79 } | |
80 virtual ~ShellWindowDelegateView() {} | |
81 | |
82 // Update the state of UI controls | |
83 void SetAddressBarURL(const GURL& url) { | |
84 url_entry_->SetText(ASCIIToUTF16(url.spec())); | |
85 } | |
86 void SetWebContents(WebContents* web_contents) { | |
87 contents_view_->SetLayoutManager(new views::FillLayout()); | |
88 web_view_ = new views::WebView(web_contents->GetBrowserContext()); | |
89 web_view_->SetWebContents(web_contents); | |
90 web_contents->GetView()->Focus(); | |
91 contents_view_->AddChildView(web_view_); | |
92 Layout(); | |
93 } | |
94 void SetWindowTitle(const string16& title) { title_ = title; } | |
95 void EnableUIControl(UIControl control, bool is_enabled) { | |
96 if (control == BACK_BUTTON) { | |
97 back_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL | |
98 : views::CustomButton::STATE_DISABLED); | |
99 } else if (control == FORWARD_BUTTON) { | |
100 forward_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL | |
101 : views::CustomButton::STATE_DISABLED); | |
102 } else if (control == STOP_BUTTON) { | |
103 stop_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL | |
104 : views::CustomButton::STATE_DISABLED); | |
105 } | |
106 } | |
107 | |
108 private: | |
109 // Initialize the UI control contained in shell window | |
110 void InitShellWindow() { | |
111 set_background(views::Background::CreateStandardPanelBackground()); | |
112 | |
113 views::GridLayout* layout = new views::GridLayout(this); | |
114 SetLayoutManager(layout); | |
115 | |
116 views::ColumnSet* column_set = layout->AddColumnSet(0); | |
117 column_set->AddPaddingColumn(0, 2); | |
118 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, | |
119 views::GridLayout::USE_PREF, 0, 0); | |
120 column_set->AddPaddingColumn(0, 2); | |
121 | |
122 layout->AddPaddingRow(0, 2); | |
123 | |
124 // Add toolbar buttons and URL text field | |
125 { | |
126 layout->StartRow(0, 0); | |
127 views::GridLayout* toolbar_layout = new views::GridLayout(toolbar_view_); | |
128 toolbar_view_->SetLayoutManager(toolbar_layout); | |
129 | |
130 views::ColumnSet* toolbar_column_set = | |
131 toolbar_layout->AddColumnSet(0); | |
132 // Back button | |
133 back_button_ = new views::LabelButton(this, ASCIIToUTF16("Back")); | |
134 back_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | |
135 gfx::Size back_button_size = back_button_->GetPreferredSize(); | |
136 toolbar_column_set->AddColumn(views::GridLayout::CENTER, | |
137 views::GridLayout::CENTER, 0, | |
138 views::GridLayout::FIXED, | |
139 back_button_size.width(), | |
140 back_button_size.width() / 2); | |
141 // Forward button | |
142 forward_button_ = new views::LabelButton(this, ASCIIToUTF16("Forward")); | |
143 forward_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | |
144 gfx::Size forward_button_size = forward_button_->GetPreferredSize(); | |
145 toolbar_column_set->AddColumn(views::GridLayout::CENTER, | |
146 views::GridLayout::CENTER, 0, | |
147 views::GridLayout::FIXED, | |
148 forward_button_size.width(), | |
149 forward_button_size.width() / 2); | |
150 // Refresh button | |
151 refresh_button_ = new views::LabelButton(this, ASCIIToUTF16("Refresh")); | |
152 refresh_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | |
153 gfx::Size refresh_button_size = refresh_button_->GetPreferredSize(); | |
154 toolbar_column_set->AddColumn(views::GridLayout::CENTER, | |
155 views::GridLayout::CENTER, 0, | |
156 views::GridLayout::FIXED, | |
157 refresh_button_size.width(), | |
158 refresh_button_size.width() / 2); | |
159 // Stop button | |
160 stop_button_ = new views::LabelButton(this, ASCIIToUTF16("Stop")); | |
161 stop_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | |
162 gfx::Size stop_button_size = stop_button_->GetPreferredSize(); | |
163 toolbar_column_set->AddColumn(views::GridLayout::CENTER, | |
164 views::GridLayout::CENTER, 0, | |
165 views::GridLayout::FIXED, | |
166 stop_button_size.width(), | |
167 stop_button_size.width() / 2); | |
168 toolbar_column_set->AddPaddingColumn(0, 2); | |
169 // URL entry | |
170 url_entry_ = new views::Textfield(); | |
171 url_entry_->SetController(this); | |
172 toolbar_column_set->AddColumn(views::GridLayout::FILL, | |
173 views::GridLayout::FILL, 1, | |
174 views::GridLayout::USE_PREF, 0, 0); | |
175 | |
176 // Fill up the first row | |
177 toolbar_layout->StartRow(0, 0); | |
178 toolbar_layout->AddView(back_button_); | |
179 toolbar_layout->AddView(forward_button_); | |
180 toolbar_layout->AddView(refresh_button_); | |
181 toolbar_layout->AddView(stop_button_); | |
182 toolbar_layout->AddView(url_entry_); | |
183 | |
184 layout->AddView(toolbar_view_); | |
185 } | |
186 | |
187 layout->AddPaddingRow(0, 5); | |
188 | |
189 // Add web contents view as the second row | |
190 { | |
191 layout->StartRow(1, 0); | |
192 layout->AddView(contents_view_); | |
193 } | |
194 | |
195 layout->AddPaddingRow(0, 5); | |
196 } | |
197 // Overridden from TextfieldController | |
198 virtual void ContentsChanged(views::Textfield* sender, | |
199 const string16& new_contents) OVERRIDE { | |
200 } | |
201 virtual bool HandleKeyEvent(views::Textfield* sender, | |
202 const ui::KeyEvent& key_event) OVERRIDE { | |
203 if (sender == url_entry_ && key_event.key_code() == ui::VKEY_RETURN) { | |
204 std::string text = UTF16ToUTF8(url_entry_->text()); | |
205 GURL url(text); | |
206 if (!url.has_scheme()) { | |
207 url = GURL(std::string("http://") + std::string(text)); | |
208 url_entry_->SetText(ASCIIToUTF16(url.spec())); | |
209 } | |
210 shell_->LoadURL(url); | |
211 return true; | |
212 } | |
213 return false; | |
214 } | |
215 | |
216 // Overridden from ButtonListener | |
217 virtual void ButtonPressed(views::Button* sender, | |
218 const ui::Event& event) OVERRIDE { | |
219 if (sender == back_button_) | |
220 shell_->GoBackOrForward(-1); | |
221 else if (sender == forward_button_) | |
222 shell_->GoBackOrForward(1); | |
223 else if (sender == refresh_button_) | |
224 shell_->Reload(); | |
225 else if (sender == stop_button_) | |
226 shell_->Stop(); | |
227 } | |
228 | |
229 // Overridden from WidgetDelegateView | |
230 virtual bool CanResize() const OVERRIDE { return true; } | |
231 virtual bool CanMaximize() const OVERRIDE { return true; } | |
232 virtual string16 GetWindowTitle() const OVERRIDE { | |
233 return title_; | |
234 } | |
235 virtual void WindowClosing() OVERRIDE { | |
236 if (shell_) { | |
237 delete shell_; | |
238 shell_ = NULL; | |
239 } | |
240 } | |
241 virtual View* GetContentsView() OVERRIDE { return this; } | |
242 | |
243 // Overridden from View | |
244 virtual void ViewHierarchyChanged( | |
245 const ViewHierarchyChangedDetails& details) OVERRIDE { | |
246 if (details.is_add && details.child == this) { | |
247 InitShellWindow(); | |
248 } | |
249 } | |
250 | |
251 private: | |
252 // Hold a reference of Shell for deleting it when the window is closing | |
253 Shell* shell_; | |
254 | |
255 // Window title | |
256 string16 title_; | |
257 | |
258 // Toolbar view contains forward/backward/reload button and URL entry | |
259 View* toolbar_view_; | |
260 views::LabelButton* back_button_; | |
261 views::LabelButton* forward_button_; | |
262 views::LabelButton* refresh_button_; | |
263 views::LabelButton* stop_button_; | |
264 views::Textfield* url_entry_; | |
265 | |
266 // Contents view contains the web contents view | |
267 View* contents_view_; | |
268 views::WebView* web_view_; | |
269 | |
270 DISALLOW_COPY_AND_ASSIGN(ShellWindowDelegateView); | |
271 }; | |
272 | |
273 } // namespace | |
274 | |
275 #if defined(OS_CHROMEOS) | |
276 MinimalShell* Shell::minimal_shell_ = NULL; | |
277 #endif | |
278 views::ViewsDelegate* Shell::views_delegate_ = NULL; | |
279 | |
280 // static | |
281 void Shell::PlatformInitialize(const gfx::Size& default_window_size) { | |
282 #if defined(OS_CHROMEOS) | |
283 chromeos::DBusThreadManager::Initialize(); | |
284 gfx::Screen::SetScreenInstance( | |
285 gfx::SCREEN_TYPE_NATIVE, aura::TestScreen::Create()); | |
286 minimal_shell_ = new content::MinimalShell(default_window_size); | |
287 #else | |
288 gfx::Screen::SetScreenInstance( | |
289 gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen()); | |
290 #endif | |
291 views_delegate_ = new ShellViewsDelegateAura(); | |
292 } | |
293 | |
294 void Shell::PlatformExit() { | |
295 #if defined(OS_CHROMEOS) | |
296 if (minimal_shell_) | |
297 delete minimal_shell_; | |
298 #endif | |
299 if (views_delegate_) | |
300 delete views_delegate_; | |
301 #if defined(OS_CHROMEOS) | |
302 chromeos::DBusThreadManager::Shutdown(); | |
303 #endif | |
304 aura::Env::DeleteInstance(); | |
305 } | |
306 | |
307 void Shell::PlatformCleanUp() { | |
308 } | |
309 | |
310 void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { | |
311 ShellWindowDelegateView* delegate_view = | |
312 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); | |
313 if (control == BACK_BUTTON) { | |
314 delegate_view->EnableUIControl(ShellWindowDelegateView::BACK_BUTTON, | |
315 is_enabled); | |
316 } else if (control == FORWARD_BUTTON) { | |
317 delegate_view->EnableUIControl(ShellWindowDelegateView::FORWARD_BUTTON, | |
318 is_enabled); | |
319 } else if (control == STOP_BUTTON) { | |
320 delegate_view->EnableUIControl(ShellWindowDelegateView::STOP_BUTTON, | |
321 is_enabled); | |
322 } | |
323 } | |
324 | |
325 void Shell::PlatformSetAddressBarURL(const GURL& url) { | |
326 ShellWindowDelegateView* delegate_view = | |
327 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); | |
328 delegate_view->SetAddressBarURL(url); | |
329 } | |
330 | |
331 void Shell::PlatformSetIsLoading(bool loading) { | |
332 } | |
333 | |
334 void Shell::PlatformCreateWindow(int width, int height) { | |
335 #if defined(OS_CHROMEOS) | |
336 window_widget_ = | |
337 views::Widget::CreateWindowWithContextAndBounds( | |
338 new ShellWindowDelegateView(this), | |
339 minimal_shell_->GetDefaultParent(NULL, NULL, gfx::Rect()), | |
340 gfx::Rect(0, 0, width, height)); | |
341 #else | |
342 window_widget_ = | |
343 views::Widget::CreateWindowWithBounds(new ShellWindowDelegateView(this), | |
344 gfx::Rect(0, 0, width, height)); | |
345 #endif | |
346 | |
347 window_ = window_widget_->GetNativeWindow(); | |
348 // Call ShowRootWindow on RootWindow created by MinimalShell without | |
349 // which XWindow owned by RootWindow doesn't get mapped. | |
350 window_->GetRootWindow()->ShowRootWindow(); | |
351 window_widget_->Show(); | |
352 } | |
353 | |
354 void Shell::PlatformSetContents() { | |
355 ShellWindowDelegateView* delegate_view = | |
356 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); | |
357 delegate_view->SetWebContents(web_contents_.get()); | |
358 } | |
359 | |
360 void Shell::PlatformResizeSubViews() { | |
361 } | |
362 | |
363 void Shell::Close() { | |
364 window_widget_->Close(); | |
365 } | |
366 | |
367 void Shell::PlatformSetTitle(const string16& title) { | |
368 ShellWindowDelegateView* delegate_view = | |
369 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); | |
370 delegate_view->SetWindowTitle(title); | |
371 window_widget_->UpdateWindowTitle(); | |
372 } | |
373 | |
374 } // namespace content | |
OLD | NEW |