Index: trunk/src/content/shell/browser/shell_aura.cc |
=================================================================== |
--- trunk/src/content/shell/browser/shell_aura.cc (revision 229520) |
+++ trunk/src/content/shell/browser/shell_aura.cc (working copy) |
@@ -4,157 +4,317 @@ |
#include "content/shell/browser/shell.h" |
+#include "base/command_line.h" |
+#include "base/strings/utf_string_conversions.h" |
#include "content/public/browser/web_contents.h" |
#include "content/public/browser/web_contents_view.h" |
-#include "content/shell/browser/shell_aura.h" |
-#include "ui/aura/client/aura_constants.h" |
-#include "ui/aura/client/default_activation_client.h" |
-#include "ui/aura/client/default_capture_client.h" |
#include "ui/aura/env.h" |
-#include "ui/aura/focus_manager.h" |
-#include "ui/aura/layout_manager.h" |
#include "ui/aura/root_window.h" |
-#include "ui/aura/test/test_screen.h" |
#include "ui/aura/window.h" |
-#include "ui/base/ime/input_method.h" |
-#include "ui/base/ime/input_method_delegate.h" |
-#include "ui/base/ime/input_method_factory.h" |
+#include "ui/base/accessibility/accessibility_types.h" |
+#include "ui/base/clipboard/clipboard.h" |
+#include "ui/base/resource/resource_bundle.h" |
+#include "ui/events/event.h" |
#include "ui/gfx/screen.h" |
+#include "ui/views/controls/button/label_button.h" |
+#include "ui/views/controls/textfield/textfield.h" |
+#include "ui/views/controls/textfield/textfield_controller.h" |
+#include "ui/views/controls/webview/webview.h" |
+#include "ui/views/layout/fill_layout.h" |
+#include "ui/views/layout/grid_layout.h" |
+#include "ui/views/test/desktop_test_views_delegate.h" |
+#include "ui/views/view.h" |
+#include "ui/views/widget/desktop_aura/desktop_screen.h" |
+#include "ui/views/widget/widget.h" |
+#include "ui/views/widget/widget_delegate.h" |
+#if defined(OS_CHROMEOS) |
+#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "ui/aura/test/test_screen.h" |
+#include "ui/shell/minimal_shell.h" |
+#endif |
+ |
+#if defined(OS_WIN) |
+#include <fcntl.h> |
+#include <io.h> |
+#endif |
+ |
namespace content { |
namespace { |
- |
-class FillLayout : public aura::LayoutManager { |
+// ViewDelegate implementation for aura content shell |
+class ShellViewsDelegateAura : public views::DesktopTestViewsDelegate { |
public: |
- explicit FillLayout(aura::RootWindow* root) |
- : root_(root) { |
+ ShellViewsDelegateAura() : use_transparent_windows_(false) { |
} |
- virtual ~FillLayout() {} |
- |
- private: |
- // aura::LayoutManager: |
- virtual void OnWindowResized() OVERRIDE { |
+ virtual ~ShellViewsDelegateAura() { |
} |
- virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { |
- child->SetBounds(gfx::Rect(root_->GetHostSize())); |
+ void SetUseTransparentWindows(bool transparent) { |
+ use_transparent_windows_ = transparent; |
} |
- virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE { |
+ // Overridden from views::TestViewsDelegate: |
+ virtual bool UseTransparentWindows() const OVERRIDE { |
+ return use_transparent_windows_; |
} |
- virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE { |
- } |
+ private: |
+ bool use_transparent_windows_; |
- virtual void OnChildWindowVisibilityChanged(aura::Window* child, |
- bool visible) OVERRIDE { |
+ DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegateAura); |
+}; |
+ |
+// Maintain the UI controls and web view for content shell |
+class ShellWindowDelegateView : public views::WidgetDelegateView, |
+ public views::TextfieldController, |
+ public views::ButtonListener { |
+ public: |
+ enum UIControl { |
+ BACK_BUTTON, |
+ FORWARD_BUTTON, |
+ STOP_BUTTON |
+ }; |
+ |
+ ShellWindowDelegateView(Shell* shell) |
+ : shell_(shell), |
+ toolbar_view_(new View), |
+ contents_view_(new View) { |
} |
+ virtual ~ShellWindowDelegateView() {} |
- virtual void SetChildBounds(aura::Window* child, |
- const gfx::Rect& requested_bounds) OVERRIDE { |
- SetChildBoundsDirect(child, requested_bounds); |
+ // Update the state of UI controls |
+ void SetAddressBarURL(const GURL& url) { |
+ url_entry_->SetText(ASCIIToUTF16(url.spec())); |
} |
+ void SetWebContents(WebContents* web_contents) { |
+ contents_view_->SetLayoutManager(new views::FillLayout()); |
+ web_view_ = new views::WebView(web_contents->GetBrowserContext()); |
+ web_view_->SetWebContents(web_contents); |
+ web_contents->GetView()->Focus(); |
+ contents_view_->AddChildView(web_view_); |
+ Layout(); |
+ } |
+ void SetWindowTitle(const string16& title) { title_ = title; } |
+ void EnableUIControl(UIControl control, bool is_enabled) { |
+ if (control == BACK_BUTTON) { |
+ back_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL |
+ : views::CustomButton::STATE_DISABLED); |
+ } else if (control == FORWARD_BUTTON) { |
+ forward_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL |
+ : views::CustomButton::STATE_DISABLED); |
+ } else if (control == STOP_BUTTON) { |
+ stop_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL |
+ : views::CustomButton::STATE_DISABLED); |
+ } |
+ } |
- aura::RootWindow* root_; |
+ private: |
+ // Initialize the UI control contained in shell window |
+ void InitShellWindow() { |
+ set_background(views::Background::CreateStandardPanelBackground()); |
- DISALLOW_COPY_AND_ASSIGN(FillLayout); |
-}; |
+ views::GridLayout* layout = new views::GridLayout(this); |
+ SetLayoutManager(layout); |
-class MinimalInputEventFilter : public ui::internal::InputMethodDelegate, |
- public ui::EventHandler { |
- public: |
- explicit MinimalInputEventFilter(aura::RootWindow* root) |
- : root_(root), |
- input_method_(ui::CreateInputMethod(this, NULL)) { |
- input_method_->Init(true); |
- root_->AddPreTargetHandler(this); |
- root_->SetProperty(aura::client::kRootWindowInputMethodKey, |
- input_method_.get()); |
- } |
+ views::ColumnSet* column_set = layout->AddColumnSet(0); |
+ column_set->AddPaddingColumn(0, 2); |
+ column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, |
+ views::GridLayout::USE_PREF, 0, 0); |
+ column_set->AddPaddingColumn(0, 2); |
- virtual ~MinimalInputEventFilter() { |
- root_->RemovePreTargetHandler(this); |
- root_->SetProperty(aura::client::kRootWindowInputMethodKey, |
- static_cast<ui::InputMethod*>(NULL)); |
- } |
+ layout->AddPaddingRow(0, 2); |
- private: |
- // ui::EventHandler: |
- virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { |
- const ui::EventType type = event->type(); |
- if (type == ui::ET_TRANSLATED_KEY_PRESS || |
- type == ui::ET_TRANSLATED_KEY_RELEASE) { |
- // The |event| is already handled by this object, change the type of the |
- // event to ui::ET_KEY_* and pass it to the next filter. |
- static_cast<ui::TranslatedKeyEvent*>(event)->ConvertToKeyEvent(); |
- } else { |
- bool handled = false; |
- if (event->HasNativeEvent()) |
- handled = input_method_->DispatchKeyEvent(event->native_event()); |
- else |
- handled = input_method_->DispatchFabricatedKeyEvent(*event); |
- if (handled) |
- event->StopPropagation(); |
+ // Add toolbar buttons and URL text field |
+ { |
+ layout->StartRow(0, 0); |
+ views::GridLayout* toolbar_layout = new views::GridLayout(toolbar_view_); |
+ toolbar_view_->SetLayoutManager(toolbar_layout); |
+ |
+ views::ColumnSet* toolbar_column_set = |
+ toolbar_layout->AddColumnSet(0); |
+ // Back button |
+ back_button_ = new views::LabelButton(this, ASCIIToUTF16("Back")); |
+ back_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
+ gfx::Size back_button_size = back_button_->GetPreferredSize(); |
+ toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
+ views::GridLayout::CENTER, 0, |
+ views::GridLayout::FIXED, |
+ back_button_size.width(), |
+ back_button_size.width() / 2); |
+ // Forward button |
+ forward_button_ = new views::LabelButton(this, ASCIIToUTF16("Forward")); |
+ forward_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
+ gfx::Size forward_button_size = forward_button_->GetPreferredSize(); |
+ toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
+ views::GridLayout::CENTER, 0, |
+ views::GridLayout::FIXED, |
+ forward_button_size.width(), |
+ forward_button_size.width() / 2); |
+ // Refresh button |
+ refresh_button_ = new views::LabelButton(this, ASCIIToUTF16("Refresh")); |
+ refresh_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
+ gfx::Size refresh_button_size = refresh_button_->GetPreferredSize(); |
+ toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
+ views::GridLayout::CENTER, 0, |
+ views::GridLayout::FIXED, |
+ refresh_button_size.width(), |
+ refresh_button_size.width() / 2); |
+ // Stop button |
+ stop_button_ = new views::LabelButton(this, ASCIIToUTF16("Stop")); |
+ stop_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
+ gfx::Size stop_button_size = stop_button_->GetPreferredSize(); |
+ toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
+ views::GridLayout::CENTER, 0, |
+ views::GridLayout::FIXED, |
+ stop_button_size.width(), |
+ stop_button_size.width() / 2); |
+ toolbar_column_set->AddPaddingColumn(0, 2); |
+ // URL entry |
+ url_entry_ = new views::Textfield(); |
+ url_entry_->SetController(this); |
+ toolbar_column_set->AddColumn(views::GridLayout::FILL, |
+ views::GridLayout::FILL, 1, |
+ views::GridLayout::USE_PREF, 0, 0); |
+ |
+ // Fill up the first row |
+ toolbar_layout->StartRow(0, 0); |
+ toolbar_layout->AddView(back_button_); |
+ toolbar_layout->AddView(forward_button_); |
+ toolbar_layout->AddView(refresh_button_); |
+ toolbar_layout->AddView(stop_button_); |
+ toolbar_layout->AddView(url_entry_); |
+ |
+ layout->AddView(toolbar_view_); |
} |
+ |
+ layout->AddPaddingRow(0, 5); |
+ |
+ // Add web contents view as the second row |
+ { |
+ layout->StartRow(1, 0); |
+ layout->AddView(contents_view_); |
+ } |
+ |
+ layout->AddPaddingRow(0, 5); |
} |
+ // Overridden from TextfieldController |
+ virtual void ContentsChanged(views::Textfield* sender, |
+ const string16& new_contents) OVERRIDE { |
+ } |
+ virtual bool HandleKeyEvent(views::Textfield* sender, |
+ const ui::KeyEvent& key_event) OVERRIDE { |
+ if (sender == url_entry_ && key_event.key_code() == ui::VKEY_RETURN) { |
+ std::string text = UTF16ToUTF8(url_entry_->text()); |
+ GURL url(text); |
+ if (!url.has_scheme()) { |
+ url = GURL(std::string("http://") + std::string(text)); |
+ url_entry_->SetText(ASCIIToUTF16(url.spec())); |
+ } |
+ shell_->LoadURL(url); |
+ return true; |
+ } |
+ return false; |
+ } |
- // ui::InputMethodDelegate: |
- virtual bool DispatchKeyEventPostIME( |
- const base::NativeEvent& event) OVERRIDE { |
- ui::TranslatedKeyEvent aura_event(event, false /* is_char */); |
- return root_->AsRootWindowHostDelegate()->OnHostKeyEvent( |
- &aura_event); |
+ // Overridden from ButtonListener |
+ virtual void ButtonPressed(views::Button* sender, |
+ const ui::Event& event) OVERRIDE { |
+ if (sender == back_button_) |
+ shell_->GoBackOrForward(-1); |
+ else if (sender == forward_button_) |
+ shell_->GoBackOrForward(1); |
+ else if (sender == refresh_button_) |
+ shell_->Reload(); |
+ else if (sender == stop_button_) |
+ shell_->Stop(); |
} |
- virtual bool DispatchFabricatedKeyEventPostIME(ui::EventType type, |
- ui::KeyboardCode key_code, |
- int flags) OVERRIDE { |
- ui::TranslatedKeyEvent aura_event(type == ui::ET_KEY_PRESSED, key_code, |
- flags); |
- return root_->AsRootWindowHostDelegate()->OnHostKeyEvent( |
- &aura_event); |
+ // Overridden from WidgetDelegateView |
+ virtual bool CanResize() const OVERRIDE { return true; } |
+ virtual bool CanMaximize() const OVERRIDE { return true; } |
+ virtual string16 GetWindowTitle() const OVERRIDE { |
+ return title_; |
} |
+ virtual void WindowClosing() OVERRIDE { |
+ if (shell_) { |
+ delete shell_; |
+ shell_ = NULL; |
+ } |
+ } |
+ virtual View* GetContentsView() OVERRIDE { return this; } |
- aura::RootWindow* root_; |
- scoped_ptr<ui::InputMethod> input_method_; |
+ // Overridden from View |
+ virtual void ViewHierarchyChanged( |
+ const ViewHierarchyChangedDetails& details) OVERRIDE { |
+ if (details.is_add && details.child == this) { |
+ InitShellWindow(); |
+ } |
+ } |
- DISALLOW_COPY_AND_ASSIGN(MinimalInputEventFilter); |
-}; |
+ private: |
+ // Hold a reference of Shell for deleting it when the window is closing |
+ Shell* shell_; |
-} |
+ // Window title |
+ string16 title_; |
-ShellAuraPlatformData::ShellAuraPlatformData() { |
-} |
+ // Toolbar view contains forward/backward/reload button and URL entry |
+ View* toolbar_view_; |
+ views::LabelButton* back_button_; |
+ views::LabelButton* forward_button_; |
+ views::LabelButton* refresh_button_; |
+ views::LabelButton* stop_button_; |
+ views::Textfield* url_entry_; |
-ShellAuraPlatformData::~ShellAuraPlatformData() { |
-} |
+ // Contents view contains the web contents view |
+ View* contents_view_; |
+ views::WebView* web_view_; |
-void ShellAuraPlatformData::CreateWindow(int width, int height) { |
- aura::TestScreen* screen = aura::TestScreen::Create(); |
- gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen); |
- root_window_.reset(screen->CreateRootWindowForPrimaryDisplay()); |
- root_window_->SetHostSize(gfx::Size(width, height)); |
- root_window_->ShowRootWindow(); |
- root_window_->SetLayoutManager(new FillLayout(root_window_.get())); |
+ DISALLOW_COPY_AND_ASSIGN(ShellWindowDelegateView); |
+}; |
- focus_client_.reset(new aura::FocusManager()); |
- aura::client::SetFocusClient(root_window_.get(), focus_client_.get()); |
+} // namespace |
- activation_client_.reset( |
- new aura::client::DefaultActivationClient(root_window_.get())); |
- capture_client_.reset( |
- new aura::client::DefaultCaptureClient(root_window_.get())); |
- ime_filter_.reset(new MinimalInputEventFilter(root_window_.get())); |
-} |
+#if defined(OS_CHROMEOS) |
+shell::MinimalShell* Shell::minimal_shell_ = NULL; |
+#endif |
+views::ViewsDelegate* Shell::views_delegate_ = NULL; |
// static |
void Shell::PlatformInitialize(const gfx::Size& default_window_size) { |
- aura::Env::CreateInstance(); |
+#if defined(OS_WIN) |
+ _setmode(_fileno(stdout), _O_BINARY); |
+ _setmode(_fileno(stderr), _O_BINARY); |
+#endif |
+#if defined(OS_CHROMEOS) |
+ chromeos::DBusThreadManager::Initialize(); |
+ gfx::Screen::SetScreenInstance( |
+ gfx::SCREEN_TYPE_NATIVE, aura::TestScreen::Create()); |
+ minimal_shell_ = new shell::MinimalShell(default_window_size); |
+#else |
+ gfx::Screen::SetScreenInstance( |
+ gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen()); |
+#endif |
+ views_delegate_ = new ShellViewsDelegateAura(); |
} |
void Shell::PlatformExit() { |
+ std::vector<Shell*> windows = windows_; |
+ for (std::vector<Shell*>::iterator it = windows.begin(); |
+ it != windows.end(); ++it) { |
+ (*it)->window_widget_->Close(); |
+ } |
+#if defined(OS_CHROMEOS) |
+ if (minimal_shell_) |
+ delete minimal_shell_; |
+#endif |
+ if (views_delegate_) |
+ delete views_delegate_; |
+#if defined(OS_CHROMEOS) |
+ chromeos::DBusThreadManager::Shutdown(); |
+#endif |
aura::Env::DeleteInstance(); |
} |
@@ -162,31 +322,67 @@ |
} |
void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { |
+ ShellWindowDelegateView* delegate_view = |
+ static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
+ if (control == BACK_BUTTON) { |
+ delegate_view->EnableUIControl(ShellWindowDelegateView::BACK_BUTTON, |
+ is_enabled); |
+ } else if (control == FORWARD_BUTTON) { |
+ delegate_view->EnableUIControl(ShellWindowDelegateView::FORWARD_BUTTON, |
+ is_enabled); |
+ } else if (control == STOP_BUTTON) { |
+ delegate_view->EnableUIControl(ShellWindowDelegateView::STOP_BUTTON, |
+ is_enabled); |
+ } |
} |
void Shell::PlatformSetAddressBarURL(const GURL& url) { |
+ ShellWindowDelegateView* delegate_view = |
+ static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
+ delegate_view->SetAddressBarURL(url); |
} |
void Shell::PlatformSetIsLoading(bool loading) { |
} |
void Shell::PlatformCreateWindow(int width, int height) { |
- platform_.reset(new ShellAuraPlatformData()); |
- platform_->CreateWindow(width, height); |
+#if defined(OS_CHROMEOS) |
+ window_widget_ = |
+ views::Widget::CreateWindowWithContextAndBounds( |
+ new ShellWindowDelegateView(this), |
+ minimal_shell_->GetDefaultParent(NULL, NULL, gfx::Rect()), |
+ gfx::Rect(0, 0, width, height)); |
+#else |
+ window_widget_ = |
+ views::Widget::CreateWindowWithBounds(new ShellWindowDelegateView(this), |
+ gfx::Rect(0, 0, width, height)); |
+#endif |
+ |
+ window_ = window_widget_->GetNativeWindow(); |
+ // Call ShowRootWindow on RootWindow created by MinimalShell without |
+ // which XWindow owned by RootWindow doesn't get mapped. |
+ window_->GetRootWindow()->ShowRootWindow(); |
+ window_widget_->Show(); |
} |
void Shell::PlatformSetContents() { |
- platform_->window()->AddChild(web_contents_->GetView()->GetNativeView()); |
- web_contents_->GetView()->GetNativeView()->Show(); |
+ ShellWindowDelegateView* delegate_view = |
+ static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
+ delegate_view->SetWebContents(web_contents_.get()); |
} |
void Shell::PlatformResizeSubViews() { |
} |
void Shell::Close() { |
+ window_widget_->CloseNow(); |
} |
void Shell::PlatformSetTitle(const string16& title) { |
+ ShellWindowDelegateView* delegate_view = |
+ static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
+ delegate_view->SetWindowTitle(title); |
+ window_widget_->UpdateWindowTitle(); |
} |
} // namespace content |