OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/shell/shell.h" | 5 #include "content/shell/shell.h" |
6 | 6 |
| 7 #include "base/utf_string_conversions.h" |
| 8 #include "ui/aura/desktop/desktop_screen.h" |
| 9 #include "ui/aura/desktop/desktop_stacking_client.h" |
| 10 #include "ui/aura/display_manager.h" |
| 11 #include "ui/aura/env.h" |
| 12 #include "ui/aura/root_window.h" |
| 13 #include "ui/aura/window.h" |
| 14 #include "ui/aura/single_display_manager.h" |
| 15 #include "ui/base/accessibility/accessibility_types.h" |
| 16 #include "ui/base/clipboard/clipboard.h" |
| 17 #include "ui/base/resource/resource_bundle.h" |
| 18 #include "ui/gfx/screen.h" |
| 19 #include "ui/views/controls/button/text_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/view.h" |
| 26 #include "ui/views/views_delegate.h" |
| 27 #include "ui/views/widget/desktop_native_widget_helper_aura.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 #endif |
| 34 |
| 35 namespace views { |
| 36 // ViewDelegate implementation for aura content shell |
| 37 class ShellViewsDelegateAura : public ViewsDelegate { |
| 38 public: |
| 39 ShellViewsDelegateAura() |
| 40 : use_transparent_windows_(false) { |
| 41 DCHECK(!ViewsDelegate::views_delegate); |
| 42 ViewsDelegate::views_delegate = this; |
| 43 } |
| 44 |
| 45 virtual ~ShellViewsDelegateAura() { |
| 46 ViewsDelegate::views_delegate = NULL; |
| 47 } |
| 48 |
| 49 void SetUseTransparentWindows(bool transparent) { |
| 50 use_transparent_windows_ = transparent; |
| 51 } |
| 52 |
| 53 // Overridden from ViewsDelegate: |
| 54 virtual ui::Clipboard* GetClipboard() const OVERRIDE { |
| 55 if (!clipboard_.get()) { |
| 56 clipboard_.reset(new ui::Clipboard); |
| 57 } |
| 58 return clipboard_.get(); |
| 59 } |
| 60 |
| 61 virtual void SaveWindowPlacement(const Widget* window, |
| 62 const std::string& window_name, |
| 63 const gfx::Rect& bounds, |
| 64 ui::WindowShowState show_state) OVERRIDE { |
| 65 } |
| 66 |
| 67 virtual bool GetSavedWindowPlacement( |
| 68 const std::string& window_name, |
| 69 gfx::Rect* bounds, |
| 70 ui::WindowShowState* show_state) const OVERRIDE { |
| 71 return false; |
| 72 } |
| 73 |
| 74 virtual void NotifyAccessibilityEvent( |
| 75 View* view, ui::AccessibilityTypes::Event event_type) OVERRIDE {} |
| 76 |
| 77 virtual void NotifyMenuItemFocused(const string16& menu_name, |
| 78 const string16& menu_item_name, |
| 79 int item_index, |
| 80 int item_count, |
| 81 bool has_submenu) OVERRIDE {} |
| 82 #if defined(OS_WIN) |
| 83 virtual HICON GetDefaultWindowIcon() const OVERRIDE { |
| 84 return NULL; |
| 85 } |
| 86 #endif |
| 87 virtual NonClientFrameView* CreateDefaultNonClientFrameView( |
| 88 Widget* widget) OVERRIDE { |
| 89 return NULL; |
| 90 } |
| 91 virtual bool UseTransparentWindows() const OVERRIDE { |
| 92 return use_transparent_windows_; |
| 93 } |
| 94 virtual void AddRef() OVERRIDE {} |
| 95 virtual void ReleaseRef() OVERRIDE {} |
| 96 |
| 97 virtual int GetDispositionForEvent(int event_flags) OVERRIDE { |
| 98 return 0; |
| 99 } |
| 100 |
| 101 virtual views::NativeWidgetHelperAura* CreateNativeWidgetHelper( |
| 102 views::NativeWidgetAura* native_widget) OVERRIDE { |
| 103 return new views::DesktopNativeWidgetHelperAura(native_widget); |
| 104 } |
| 105 |
| 106 virtual content::WebContents* CreateWebContents( |
| 107 content::BrowserContext* browser_context, |
| 108 content::SiteInstance* site_instance) OVERRIDE { |
| 109 return NULL; |
| 110 } |
| 111 |
| 112 private: |
| 113 mutable scoped_ptr<ui::Clipboard> clipboard_; |
| 114 bool use_transparent_windows_; |
| 115 |
| 116 DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegateAura); |
| 117 }; |
| 118 |
| 119 // Maintain the UI controls and web view for content shell |
| 120 class ShellWindowDelegateView : public WidgetDelegateView, |
| 121 public TextfieldController, |
| 122 public ButtonListener { |
| 123 public: |
| 124 enum UIControl { |
| 125 BACK_BUTTON, |
| 126 FORWARD_BUTTON, |
| 127 STOP_BUTTON |
| 128 }; |
| 129 |
| 130 ShellWindowDelegateView(content::Shell* shell) |
| 131 : shell_(shell), |
| 132 toolbar_view_(new View), |
| 133 contents_view_(new View) { |
| 134 } |
| 135 virtual ~ShellWindowDelegateView() {} |
| 136 |
| 137 // Update the state of UI controls |
| 138 void SetAddressBarURL(const GURL& url) { |
| 139 url_entry_->SetText(ASCIIToUTF16(url.spec())); |
| 140 } |
| 141 void SetWebContents(content::WebContents* web_contents) { |
| 142 contents_view_->SetLayoutManager(new FillLayout()); |
| 143 web_view_ = new WebView(web_contents->GetBrowserContext()); |
| 144 web_view_->SetWebContents(web_contents); |
| 145 web_contents->Focus(); |
| 146 contents_view_->AddChildView(web_view_); |
| 147 Layout(); |
| 148 } |
| 149 void SetWindowTitle(const string16& title) { title_ = title; } |
| 150 void EnableUIControl(UIControl control, bool is_enabled) { |
| 151 if (control == BACK_BUTTON) { |
| 152 back_button_->SetState(is_enabled ? CustomButton::BS_NORMAL |
| 153 : CustomButton::BS_DISABLED); |
| 154 } else if (control == FORWARD_BUTTON) { |
| 155 forward_button_->SetState(is_enabled ? CustomButton::BS_NORMAL |
| 156 : CustomButton::BS_DISABLED); |
| 157 } else if (control == STOP_BUTTON) { |
| 158 stop_button_->SetState(is_enabled ? CustomButton::BS_NORMAL |
| 159 : CustomButton::BS_DISABLED); |
| 160 } |
| 161 } |
| 162 |
| 163 private: |
| 164 // Initialize the UI control contained in shell window |
| 165 void InitShellWindow() { |
| 166 set_background(Background::CreateStandardPanelBackground()); |
| 167 |
| 168 GridLayout* layout = new GridLayout(this); |
| 169 SetLayoutManager(layout); |
| 170 |
| 171 ColumnSet* column_set = layout->AddColumnSet(0); |
| 172 column_set->AddPaddingColumn(0, 2); |
| 173 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| 174 GridLayout::USE_PREF, 0, 0); |
| 175 column_set->AddPaddingColumn(0, 2); |
| 176 |
| 177 layout->AddPaddingRow(0, 2); |
| 178 |
| 179 // Add toolbar buttons and URL text field |
| 180 { |
| 181 layout->StartRow(0, 0); |
| 182 GridLayout* toolbar_layout = new GridLayout(toolbar_view_); |
| 183 toolbar_view_->SetLayoutManager(toolbar_layout); |
| 184 |
| 185 ColumnSet* toolbar_column_set = |
| 186 toolbar_layout->AddColumnSet(0); |
| 187 // Back button |
| 188 back_button_ = new NativeTextButton(this, ASCIIToUTF16("Back")); |
| 189 gfx::Size back_button_size = back_button_->GetPreferredSize(); |
| 190 toolbar_column_set->AddColumn(GridLayout::CENTER, |
| 191 GridLayout::CENTER, 0, |
| 192 GridLayout::FIXED, |
| 193 back_button_size.width(), |
| 194 back_button_size.width() / 2); |
| 195 // Forward button |
| 196 forward_button_ = new NativeTextButton(this, ASCIIToUTF16("Forward")); |
| 197 gfx::Size forward_button_size = forward_button_->GetPreferredSize(); |
| 198 toolbar_column_set->AddColumn(GridLayout::CENTER, |
| 199 GridLayout::CENTER, 0, |
| 200 GridLayout::FIXED, |
| 201 forward_button_size.width(), |
| 202 forward_button_size.width() / 2); |
| 203 // Refresh button |
| 204 refresh_button_ = new NativeTextButton(this, ASCIIToUTF16("Refresh")); |
| 205 gfx::Size refresh_button_size = refresh_button_->GetPreferredSize(); |
| 206 toolbar_column_set->AddColumn(GridLayout::CENTER, |
| 207 GridLayout::CENTER, 0, |
| 208 GridLayout::FIXED, |
| 209 refresh_button_size.width(), |
| 210 refresh_button_size.width() / 2); |
| 211 // Stop button |
| 212 stop_button_ = new NativeTextButton(this, ASCIIToUTF16("Stop")); |
| 213 gfx::Size stop_button_size = stop_button_->GetPreferredSize(); |
| 214 toolbar_column_set->AddColumn(GridLayout::CENTER, |
| 215 GridLayout::CENTER, 0, |
| 216 GridLayout::FIXED, |
| 217 stop_button_size.width(), |
| 218 stop_button_size.width() / 2); |
| 219 toolbar_column_set->AddPaddingColumn(0, 2); |
| 220 // URL entry |
| 221 url_entry_ = new Textfield(); |
| 222 url_entry_->SetController(this); |
| 223 toolbar_column_set->AddColumn(GridLayout::FILL, |
| 224 GridLayout::FILL, 1, |
| 225 GridLayout::USE_PREF, 0, 0); |
| 226 |
| 227 // Fill up the first row |
| 228 toolbar_layout->StartRow(0, 0); |
| 229 toolbar_layout->AddView(back_button_); |
| 230 toolbar_layout->AddView(forward_button_); |
| 231 toolbar_layout->AddView(refresh_button_); |
| 232 toolbar_layout->AddView(stop_button_); |
| 233 toolbar_layout->AddView(url_entry_); |
| 234 |
| 235 layout->AddView(toolbar_view_); |
| 236 } |
| 237 |
| 238 layout->AddPaddingRow(0, 5); |
| 239 |
| 240 // Add web contents view as the second row |
| 241 { |
| 242 layout->StartRow(1, 0); |
| 243 layout->AddView(contents_view_); |
| 244 } |
| 245 |
| 246 layout->AddPaddingRow(0, 5); |
| 247 } |
| 248 // Overriden from TextfieldController |
| 249 virtual void ContentsChanged(Textfield* sender, |
| 250 const string16& new_contents) OVERRIDE { |
| 251 } |
| 252 virtual bool HandleKeyEvent(Textfield* sender, |
| 253 const KeyEvent& key_event) OVERRIDE { |
| 254 if (sender == url_entry_ && key_event.key_code() == ui::VKEY_RETURN) { |
| 255 std::string text = UTF16ToUTF8(url_entry_->text()); |
| 256 GURL url(text); |
| 257 if (!url.has_scheme()) { |
| 258 url = GURL(std::string("http://") + std::string(text)); |
| 259 url_entry_->SetText(ASCIIToUTF16(url.spec())); |
| 260 } |
| 261 shell_->LoadURL(url); |
| 262 return true; |
| 263 } |
| 264 return false; |
| 265 } |
| 266 |
| 267 // Overriden from ButtonListener |
| 268 virtual void ButtonPressed(Button* sender, |
| 269 const Event& event) OVERRIDE { |
| 270 if (sender == back_button_) |
| 271 shell_->GoBackOrForward(-1); |
| 272 else if (sender == forward_button_) |
| 273 shell_->GoBackOrForward(1); |
| 274 else if (sender == refresh_button_) |
| 275 shell_->Reload(); |
| 276 else if (sender == stop_button_) |
| 277 shell_->Stop(); |
| 278 } |
| 279 |
| 280 // Overriden from WidgetDelegateView |
| 281 virtual bool CanResize() const OVERRIDE { return true; } |
| 282 virtual bool CanMaximize() const OVERRIDE { return true; } |
| 283 virtual string16 GetWindowTitle() const OVERRIDE { |
| 284 return title_; |
| 285 } |
| 286 virtual void WindowClosing() OVERRIDE { |
| 287 if (shell_) delete shell_; |
| 288 } |
| 289 virtual View* GetContentsView() OVERRIDE { return this; } |
| 290 |
| 291 // Overriden from View |
| 292 virtual void ViewHierarchyChanged(bool is_add, |
| 293 View* parent, |
| 294 View* child) OVERRIDE { |
| 295 if (is_add && child == this) { |
| 296 InitShellWindow(); |
| 297 } |
| 298 } |
| 299 |
| 300 private: |
| 301 // Hold a reference of Shell for deleting it when the window is closing |
| 302 content::Shell* shell_; |
| 303 |
| 304 // Window title |
| 305 string16 title_; |
| 306 |
| 307 // Toolbar view contains forward/backward/reload button and URL entry |
| 308 View* toolbar_view_; |
| 309 NativeTextButton* back_button_; |
| 310 NativeTextButton* forward_button_; |
| 311 NativeTextButton* refresh_button_; |
| 312 NativeTextButton* stop_button_; |
| 313 Textfield* url_entry_; |
| 314 |
| 315 // Contents view contains the web contents view |
| 316 View* contents_view_; |
| 317 WebView* web_view_; |
| 318 |
| 319 DISALLOW_COPY_AND_ASSIGN(ShellWindowDelegateView); |
| 320 }; |
| 321 |
| 322 } // namespace views |
| 323 |
7 namespace content { | 324 namespace content { |
8 | 325 |
| 326 using views::ShellWindowDelegateView; |
| 327 using views::ShellViewsDelegateAura; |
| 328 |
| 329 aura::client::StackingClient* Shell::stacking_client_ = NULL; |
| 330 views::ViewsDelegate* Shell::views_delegate_ = NULL; |
| 331 |
9 // static | 332 // static |
10 void Shell::PlatformInitialize() { | 333 void Shell::PlatformInitialize() { |
| 334 #if defined(OS_CHROMEOS) |
| 335 chromeos::DBusThreadManager::Initialize(); |
| 336 #endif |
| 337 aura::Env::GetInstance()->SetDisplayManager(new aura::SingleDisplayManager); |
| 338 stacking_client_ = new aura::DesktopStackingClient(); |
| 339 gfx::Screen::SetInstance(aura::CreateDesktopScreen()); |
| 340 views_delegate_ = new ShellViewsDelegateAura(); |
| 341 |
| 342 // Loading locale resources for Widget::CreateWindowWithBounds initialization |
| 343 // in which CustomFrameView requires the accessible name for buttons. |
| 344 ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources("en-US"); |
11 } | 345 } |
12 | 346 |
13 base::StringPiece Shell::PlatformResourceProvider(int key) { | 347 base::StringPiece Shell::PlatformResourceProvider(int key) { |
14 return base::StringPiece(); | 348 return base::StringPiece(); |
15 } | 349 } |
16 | 350 |
17 void Shell::PlatformExit() { | 351 void Shell::PlatformExit() { |
| 352 #if defined(OS_CHROMEOS) |
| 353 chromeos::DBusThreadManager::Shutdown(); |
| 354 #endif |
| 355 if (stacking_client_) |
| 356 delete stacking_client_; |
| 357 if (views_delegate_) |
| 358 delete views_delegate_; |
| 359 aura::Env::DeleteInstance(); |
18 } | 360 } |
19 | 361 |
20 void Shell::PlatformCleanUp() { | 362 void Shell::PlatformCleanUp() { |
21 } | 363 } |
22 | 364 |
23 void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { | 365 void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { |
| 366 ShellWindowDelegateView* delegate_view = |
| 367 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 368 if (control == BACK_BUTTON) { |
| 369 delegate_view->EnableUIControl(ShellWindowDelegateView::BACK_BUTTON, |
| 370 is_enabled); |
| 371 } else if (control == FORWARD_BUTTON) { |
| 372 delegate_view->EnableUIControl(ShellWindowDelegateView::FORWARD_BUTTON, |
| 373 is_enabled); |
| 374 } else if (control == STOP_BUTTON) { |
| 375 delegate_view->EnableUIControl(ShellWindowDelegateView::STOP_BUTTON, |
| 376 is_enabled); |
| 377 } |
24 } | 378 } |
25 | 379 |
26 void Shell::PlatformSetAddressBarURL(const GURL& url) { | 380 void Shell::PlatformSetAddressBarURL(const GURL& url) { |
| 381 ShellWindowDelegateView* delegate_view = |
| 382 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 383 delegate_view->SetAddressBarURL(url); |
27 } | 384 } |
28 | 385 |
29 void Shell::PlatformSetIsLoading(bool loading) { | 386 void Shell::PlatformSetIsLoading(bool loading) { |
30 } | 387 } |
31 | 388 |
32 void Shell::PlatformCreateWindow(int width, int height) { | 389 void Shell::PlatformCreateWindow(int width, int height) { |
| 390 window_widget_ = |
| 391 views::Widget::CreateWindowWithBounds(new ShellWindowDelegateView(this), |
| 392 gfx::Rect(0, 0, width, height)); |
| 393 window_ = window_widget_->GetNativeWindow(); |
| 394 window_widget_->Show(); |
33 } | 395 } |
34 | 396 |
35 void Shell::PlatformSetContents() { | 397 void Shell::PlatformSetContents() { |
| 398 ShellWindowDelegateView* delegate_view = |
| 399 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 400 delegate_view->SetWebContents(web_contents_.get()); |
36 } | 401 } |
37 | 402 |
38 void Shell::PlatformResizeSubViews() { | 403 void Shell::PlatformResizeSubViews() { |
39 } | 404 } |
40 | 405 |
41 void Shell::Close() { | 406 void Shell::Close() { |
| 407 window_widget_->Close(); |
42 } | 408 } |
43 | 409 |
44 void Shell::PlatformSetTitle(const string16& title) { | 410 void Shell::PlatformSetTitle(const string16& title) { |
| 411 ShellWindowDelegateView* delegate_view = |
| 412 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 413 delegate_view->SetWindowTitle(title); |
| 414 window_widget_->UpdateWindowTitle(); |
45 } | 415 } |
46 | 416 |
47 } // namespace content | 417 } // namespace content |
OLD | NEW |