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.
5 #include "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/ui/views/constrained_window_views.h"
9 #include "components/web_modal/web_contents_modal_dialog_host.h"
10 #include "components/web_modal/web_contents_modal_dialog_manager.h"
11 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
12 #include "content/public/browser/native_web_keyboard_event.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/browser/web_contents_view.h"
15 #include "ui/gfx/size.h"
16 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
17 #include "ui/views/controls/webview/webview.h"
18 #include "ui/views/view.h"
19 #include "ui/views/widget/widget.h"
20 #include "ui/views/widget/widget_delegate.h"
21 #include "ui/views/window/dialog_delegate.h"
22 #include "ui/web_dialogs/web_dialog_delegate.h"
23 #include "ui/web_dialogs/web_dialog_ui.h"
25 using content::WebContents;
26 using ui::WebDialogDelegate;
27 using ui::WebDialogWebContentsDelegate;
28 using web_modal::NativeWebContentsModalDialog;
29 using web_modal::WebContentsModalDialogManager;
30 using web_modal::WebContentsModalDialogManagerDelegate;
34 class ConstrainedWebDialogDelegateViews
35 : public ConstrainedWebDialogDelegateBase {
37 ConstrainedWebDialogDelegateViews(
38 content::BrowserContext* browser_context,
39 WebDialogDelegate* delegate,
40 WebDialogWebContentsDelegate* tab_delegate,
42 : ConstrainedWebDialogDelegateBase(
43 browser_context, delegate, tab_delegate),
47 virtual ~ConstrainedWebDialogDelegateViews() {}
49 // WebDialogWebContentsDelegate interface.
50 virtual void CloseContents(WebContents* source) OVERRIDE {
54 // contents::WebContentsDelegate
55 virtual void HandleKeyboardEvent(
56 content::WebContents* source,
57 const content::NativeWebKeyboardEvent& event) OVERRIDE {
58 unhandled_keyboard_event_handler_.HandleKeyboardEvent(
59 event, view_->GetFocusManager());
62 // ConstrainedWebDialogDelegate
63 virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
64 return window_->GetNativeView();
67 void set_window(views::Widget* window) { window_ = window; }
68 views::Widget* window() const { return window_; }
71 // Converts keyboard events on the WebContents to accelerators.
72 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
74 views::WebView* view_;
75 views::Widget* window_;
77 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
82 class ConstrainedWebDialogDelegateViewViews
83 : public views::WebView,
84 public ConstrainedWebDialogDelegate,
85 public views::WidgetDelegate {
87 ConstrainedWebDialogDelegateViewViews(
88 content::BrowserContext* browser_context,
89 WebDialogDelegate* delegate,
90 WebDialogWebContentsDelegate* tab_delegate);
91 virtual ~ConstrainedWebDialogDelegateViewViews();
93 // ConstrainedWebDialogDelegate interface
94 virtual const WebDialogDelegate*
95 GetWebDialogDelegate() const OVERRIDE {
96 return impl_->GetWebDialogDelegate();
98 virtual WebDialogDelegate* GetWebDialogDelegate() OVERRIDE {
99 return impl_->GetWebDialogDelegate();
101 virtual void OnDialogCloseFromWebUI() OVERRIDE {
102 return impl_->OnDialogCloseFromWebUI();
104 virtual void ReleaseWebContentsOnDialogClose() OVERRIDE {
105 return impl_->ReleaseWebContentsOnDialogClose();
107 virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
108 return impl_->window()->GetNativeView();
110 virtual WebContents* GetWebContents() OVERRIDE {
111 return impl_->GetWebContents();
114 // views::WidgetDelegate interface.
115 virtual views::View* GetInitiallyFocusedView() OVERRIDE {
118 virtual void WindowClosing() OVERRIDE {
119 if (!impl_->closed_via_webui())
120 GetWebDialogDelegate()->OnDialogClosed(std::string());
122 virtual views::Widget* GetWidget() OVERRIDE {
123 return View::GetWidget();
125 virtual const views::Widget* GetWidget() const OVERRIDE {
126 return View::GetWidget();
128 virtual string16 GetWindowTitle() const OVERRIDE {
129 return impl_->closed_via_webui() ? string16() :
130 GetWebDialogDelegate()->GetDialogTitle();
132 virtual views::View* GetContentsView() OVERRIDE {
135 // TODO(wittman): Remove this override once we move to the new style frame
136 // view on all dialogs.
137 virtual views::NonClientFrameView* CreateNonClientFrameView(
138 views::Widget* widget) OVERRIDE {
139 return CreateConstrainedStyleNonClientFrameView(
141 GetWebContents()->GetBrowserContext());
143 virtual bool ShouldShowCloseButton() const OVERRIDE {
144 // No close button if the dialog doesn't want a title bar.
145 return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
148 virtual ui::ModalType GetModalType() const OVERRIDE {
150 return ui::MODAL_TYPE_CHILD;
152 return views::WidgetDelegate::GetModalType();
156 virtual void OnWidgetMove() OVERRIDE {
157 // We need to check the existence of the widget because when running on
158 // WinXP this could get executed before the widget is entirely created.
162 if (!views::DialogDelegate::UseNewStyle()) {
163 GetWidget()->CenterWindow(
164 GetWidget()->non_client_view()->GetPreferredSize());
166 views::WidgetDelegate::OnWidgetMove();
169 // views::WebView overrides.
170 virtual bool AcceleratorPressed(
171 const ui::Accelerator& accelerator) OVERRIDE {
172 // Pressing ESC closes the dialog.
173 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
174 impl_->window()->Close();
177 virtual gfx::Size GetPreferredSize() OVERRIDE {
179 if (!impl_->closed_via_webui())
180 GetWebDialogDelegate()->GetDialogSize(&size);
183 virtual gfx::Size GetMinimumSize() OVERRIDE {
184 // Return an empty size so that we can be made smaller.
188 void SetWindow(views::Widget* window) {
189 impl_->set_window(window);
192 views::Widget* GetWindow() {
193 return impl_->window();
197 scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
199 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
202 ConstrainedWebDialogDelegateViewViews::ConstrainedWebDialogDelegateViewViews(
203 content::BrowserContext* browser_context,
204 WebDialogDelegate* delegate,
205 WebDialogWebContentsDelegate* tab_delegate)
206 : views::WebView(browser_context),
207 impl_(new ConstrainedWebDialogDelegateViews(browser_context,
211 SetWebContents(GetWebContents());
213 // Pressing ESC closes the dialog.
214 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
217 ConstrainedWebDialogDelegateViewViews::~ConstrainedWebDialogDelegateViewViews() {
220 ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
221 content::BrowserContext* browser_context,
222 WebDialogDelegate* delegate,
223 WebDialogWebContentsDelegate* tab_delegate,
224 content::WebContents* web_contents) {
225 ConstrainedWebDialogDelegateViewViews* constrained_delegate =
226 new ConstrainedWebDialogDelegateViewViews(
227 browser_context, delegate, tab_delegate);
228 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
229 WebContentsModalDialogManager::FromWebContents(web_contents);
230 WebContentsModalDialogManagerDelegate* modal_delegate =
231 web_contents_modal_dialog_manager->delegate();
232 DCHECK(modal_delegate);
233 views::Widget* window = views::Widget::CreateWindowAsFramelessChild(
234 constrained_delegate,
235 web_contents->GetView()->GetNativeView(),
236 modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
237 web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());
238 constrained_delegate->SetWindow(window);
239 return constrained_delegate;