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 "components/web_modal/web_contents_modal_dialog_host.h"
9 #include "components/web_modal/web_contents_modal_dialog_manager.h"
10 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
11 #include "content/public/browser/native_web_keyboard_event.h"
12 #include "content/public/browser/web_contents.h"
13 #include "ui/gfx/size.h"
14 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
15 #include "ui/views/controls/webview/webview.h"
16 #include "ui/views/view.h"
17 #include "ui/views/widget/widget.h"
18 #include "ui/views/widget/widget_delegate.h"
19 #include "ui/views/window/dialog_delegate.h"
20 #include "ui/web_dialogs/web_dialog_delegate.h"
21 #include "ui/web_dialogs/web_dialog_ui.h"
23 using content::WebContents
;
24 using ui::WebDialogDelegate
;
25 using ui::WebDialogWebContentsDelegate
;
26 using web_modal::NativeWebContentsModalDialog
;
27 using web_modal::WebContentsModalDialogManager
;
28 using web_modal::WebContentsModalDialogManagerDelegate
;
32 class ConstrainedWebDialogDelegateViews
33 : public ConstrainedWebDialogDelegateBase
{
35 ConstrainedWebDialogDelegateViews(content::BrowserContext
* browser_context
,
36 WebDialogDelegate
* delegate
,
37 WebDialogWebContentsDelegate
* tab_delegate
,
39 : ConstrainedWebDialogDelegateBase(
40 browser_context
, delegate
, tab_delegate
),
44 virtual ~ConstrainedWebDialogDelegateViews() {}
46 // WebDialogWebContentsDelegate interface.
47 virtual void CloseContents(WebContents
* source
) OVERRIDE
{
51 // contents::WebContentsDelegate
52 virtual void HandleKeyboardEvent(
53 content::WebContents
* source
,
54 const content::NativeWebKeyboardEvent
& event
) OVERRIDE
{
55 unhandled_keyboard_event_handler_
.HandleKeyboardEvent(
56 event
, view_
->GetFocusManager());
59 // ConstrainedWebDialogDelegate
60 virtual NativeWebContentsModalDialog
GetNativeDialog() OVERRIDE
{
61 return window_
->GetNativeView();
64 void set_window(views::Widget
* window
) { window_
= window
; }
65 views::Widget
* window() const { return window_
; }
68 // Converts keyboard events on the WebContents to accelerators.
69 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_
;
71 views::WebView
* view_
;
72 views::Widget
* window_
;
74 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews
);
79 class ConstrainedWebDialogDelegateViewViews
80 : public views::WebView
,
81 public ConstrainedWebDialogDelegate
,
82 public views::WidgetDelegate
{
84 ConstrainedWebDialogDelegateViewViews(
85 content::BrowserContext
* browser_context
,
86 WebDialogDelegate
* delegate
,
87 WebDialogWebContentsDelegate
* tab_delegate
);
88 virtual ~ConstrainedWebDialogDelegateViewViews();
90 // ConstrainedWebDialogDelegate interface
91 virtual const WebDialogDelegate
* GetWebDialogDelegate() const OVERRIDE
{
92 return impl_
->GetWebDialogDelegate();
94 virtual WebDialogDelegate
* GetWebDialogDelegate() OVERRIDE
{
95 return impl_
->GetWebDialogDelegate();
97 virtual void OnDialogCloseFromWebUI() OVERRIDE
{
98 return impl_
->OnDialogCloseFromWebUI();
100 virtual void ReleaseWebContentsOnDialogClose() OVERRIDE
{
101 return impl_
->ReleaseWebContentsOnDialogClose();
103 virtual NativeWebContentsModalDialog
GetNativeDialog() OVERRIDE
{
104 return impl_
->window()->GetNativeView();
106 virtual WebContents
* GetWebContents() OVERRIDE
{
107 return impl_
->GetWebContents();
110 // views::WidgetDelegate interface.
111 virtual views::View
* GetInitiallyFocusedView() OVERRIDE
{
114 virtual void WindowClosing() OVERRIDE
{
115 if (!impl_
->closed_via_webui())
116 GetWebDialogDelegate()->OnDialogClosed(std::string());
118 virtual views::Widget
* GetWidget() OVERRIDE
{
119 return View::GetWidget();
121 virtual const views::Widget
* GetWidget() const OVERRIDE
{
122 return View::GetWidget();
124 virtual base::string16
GetWindowTitle() const OVERRIDE
{
125 return impl_
->closed_via_webui() ? base::string16() :
126 GetWebDialogDelegate()->GetDialogTitle();
128 virtual views::View
* GetContentsView() OVERRIDE
{
131 virtual views::NonClientFrameView
* CreateNonClientFrameView(
132 views::Widget
* widget
) OVERRIDE
{
133 return views::DialogDelegate::CreateDialogFrameView(widget
);
135 virtual bool ShouldShowCloseButton() const OVERRIDE
{
136 // No close button if the dialog doesn't want a title bar.
137 return impl_
->GetWebDialogDelegate()->ShouldShowDialogTitle();
140 virtual ui::ModalType
GetModalType() const OVERRIDE
{
142 return ui::MODAL_TYPE_CHILD
;
144 return views::WidgetDelegate::GetModalType();
148 // views::WebView overrides.
149 virtual bool AcceleratorPressed(
150 const ui::Accelerator
& accelerator
) OVERRIDE
{
151 // Pressing ESC closes the dialog.
152 DCHECK_EQ(ui::VKEY_ESCAPE
, accelerator
.key_code());
153 impl_
->window()->Close();
156 virtual gfx::Size
GetPreferredSize() const OVERRIDE
{
158 if (!impl_
->closed_via_webui())
159 GetWebDialogDelegate()->GetDialogSize(&size
);
162 virtual gfx::Size
GetMinimumSize() const OVERRIDE
{
163 // Return an empty size so that we can be made smaller.
167 void SetWindow(views::Widget
* window
) {
168 impl_
->set_window(window
);
171 views::Widget
* GetWindow() {
172 return impl_
->window();
176 scoped_ptr
<ConstrainedWebDialogDelegateViews
> impl_
;
178 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews
);
181 ConstrainedWebDialogDelegateViewViews::ConstrainedWebDialogDelegateViewViews(
182 content::BrowserContext
* browser_context
,
183 WebDialogDelegate
* delegate
,
184 WebDialogWebContentsDelegate
* tab_delegate
)
185 : views::WebView(browser_context
),
186 impl_(new ConstrainedWebDialogDelegateViews(browser_context
,
190 SetWebContents(GetWebContents());
192 // Pressing ESC closes the dialog.
193 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE
, ui::EF_NONE
));
196 ConstrainedWebDialogDelegateViewViews::
197 ~ConstrainedWebDialogDelegateViewViews() {
200 ConstrainedWebDialogDelegate
* CreateConstrainedWebDialog(
201 content::BrowserContext
* browser_context
,
202 WebDialogDelegate
* delegate
,
203 WebDialogWebContentsDelegate
* tab_delegate
,
204 content::WebContents
* web_contents
) {
205 ConstrainedWebDialogDelegateViewViews
* constrained_delegate
=
206 new ConstrainedWebDialogDelegateViewViews(
207 browser_context
, delegate
, tab_delegate
);
208 WebContentsModalDialogManager
* web_contents_modal_dialog_manager
=
209 WebContentsModalDialogManager::FromWebContents(web_contents
);
210 WebContentsModalDialogManagerDelegate
* modal_delegate
=
211 web_contents_modal_dialog_manager
->delegate();
212 DCHECK(modal_delegate
);
213 views::Widget
* window
= views::Widget::CreateWindowAsFramelessChild(
214 constrained_delegate
,
215 modal_delegate
->GetWebContentsModalDialogHost()->GetHostView());
216 web_contents_modal_dialog_manager
->ShowModalDialog(
217 window
->GetNativeView());
218 constrained_delegate
->SetWindow(window
);
219 return constrained_delegate
;