constrained_web_dialog_delegate_views.cc revision f2477e01787aa58f445919b809d89e252beef54f
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 "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h"
6
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 "ui/gfx/size.h"
15#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
16#include "ui/views/controls/webview/webview.h"
17#include "ui/views/view.h"
18#include "ui/views/widget/widget.h"
19#include "ui/views/widget/widget_delegate.h"
20#include "ui/views/window/dialog_delegate.h"
21#include "ui/web_dialogs/web_dialog_delegate.h"
22#include "ui/web_dialogs/web_dialog_ui.h"
23
24using content::WebContents;
25using ui::WebDialogDelegate;
26using ui::WebDialogWebContentsDelegate;
27using web_modal::NativeWebContentsModalDialog;
28using web_modal::WebContentsModalDialogManager;
29using web_modal::WebContentsModalDialogManagerDelegate;
30
31namespace {
32
33class ConstrainedWebDialogDelegateViews
34    : public ConstrainedWebDialogDelegateBase {
35 public:
36  ConstrainedWebDialogDelegateViews(
37      content::BrowserContext* browser_context,
38      WebDialogDelegate* delegate,
39      WebDialogWebContentsDelegate* tab_delegate,
40      views::WebView* view)
41      : ConstrainedWebDialogDelegateBase(
42            browser_context, delegate, tab_delegate),
43        view_(view),
44        window_(NULL) {}
45
46  virtual ~ConstrainedWebDialogDelegateViews() {}
47
48  // WebDialogWebContentsDelegate interface.
49  virtual void CloseContents(WebContents* source) OVERRIDE {
50    window_->Close();
51  }
52
53  // contents::WebContentsDelegate
54  virtual void HandleKeyboardEvent(
55      content::WebContents* source,
56      const content::NativeWebKeyboardEvent& event) OVERRIDE {
57    unhandled_keyboard_event_handler_.HandleKeyboardEvent(
58        event, view_->GetFocusManager());
59  }
60
61  // ConstrainedWebDialogDelegate
62  virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
63    return window_->GetNativeView();
64  }
65
66  void set_window(views::Widget* window) { window_ = window; }
67  views::Widget* window() const { return window_; }
68
69 private:
70  // Converts keyboard events on the WebContents to accelerators.
71  views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
72
73  views::WebView* view_;
74  views::Widget* window_;
75
76  DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
77};
78
79}  // namespace
80
81class ConstrainedWebDialogDelegateViewViews
82    : public views::WebView,
83      public ConstrainedWebDialogDelegate,
84      public views::WidgetDelegate {
85 public:
86  ConstrainedWebDialogDelegateViewViews(
87      content::BrowserContext* browser_context,
88      WebDialogDelegate* delegate,
89      WebDialogWebContentsDelegate* tab_delegate);
90  virtual ~ConstrainedWebDialogDelegateViewViews();
91
92  // ConstrainedWebDialogDelegate interface
93  virtual const WebDialogDelegate* GetWebDialogDelegate() const OVERRIDE {
94    return impl_->GetWebDialogDelegate();
95  }
96  virtual WebDialogDelegate* GetWebDialogDelegate() OVERRIDE {
97    return impl_->GetWebDialogDelegate();
98  }
99  virtual void OnDialogCloseFromWebUI() OVERRIDE {
100    return impl_->OnDialogCloseFromWebUI();
101  }
102  virtual void ReleaseWebContentsOnDialogClose() OVERRIDE {
103    return impl_->ReleaseWebContentsOnDialogClose();
104  }
105  virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
106    return impl_->window()->GetNativeView();
107  }
108  virtual WebContents* GetWebContents() OVERRIDE {
109    return impl_->GetWebContents();
110  }
111
112  // views::WidgetDelegate interface.
113  virtual views::View* GetInitiallyFocusedView() OVERRIDE {
114    return this;
115  }
116  virtual void WindowClosing() OVERRIDE {
117    if (!impl_->closed_via_webui())
118      GetWebDialogDelegate()->OnDialogClosed(std::string());
119  }
120  virtual views::Widget* GetWidget() OVERRIDE {
121    return View::GetWidget();
122  }
123  virtual const views::Widget* GetWidget() const OVERRIDE {
124    return View::GetWidget();
125  }
126  virtual string16 GetWindowTitle() const OVERRIDE {
127    return impl_->closed_via_webui() ? string16() :
128        GetWebDialogDelegate()->GetDialogTitle();
129  }
130  virtual views::View* GetContentsView() OVERRIDE {
131    return this;
132  }
133  // TODO(wittman): Remove this override once we move to the new style frame
134  // view on all dialogs.
135  virtual views::NonClientFrameView* CreateNonClientFrameView(
136      views::Widget* widget) OVERRIDE {
137    return CreateConstrainedStyleNonClientFrameView(
138        widget,
139        GetWebContents()->GetBrowserContext());
140  }
141  virtual bool ShouldShowCloseButton() const OVERRIDE {
142    // No close button if the dialog doesn't want a title bar.
143    return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
144  }
145
146  virtual ui::ModalType GetModalType() const OVERRIDE {
147#if defined(USE_ASH)
148    return ui::MODAL_TYPE_CHILD;
149#else
150    return views::WidgetDelegate::GetModalType();
151#endif
152  }
153
154  // views::WebView overrides.
155  virtual bool AcceleratorPressed(
156      const ui::Accelerator& accelerator) OVERRIDE {
157    // Pressing ESC closes the dialog.
158    DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
159    impl_->window()->Close();
160    return true;
161  }
162  virtual gfx::Size GetPreferredSize() OVERRIDE {
163    gfx::Size size;
164    if (!impl_->closed_via_webui())
165      GetWebDialogDelegate()->GetDialogSize(&size);
166    return size;
167  }
168  virtual gfx::Size GetMinimumSize() OVERRIDE {
169    // Return an empty size so that we can be made smaller.
170    return gfx::Size();
171  }
172
173  void SetWindow(views::Widget* window) {
174    impl_->set_window(window);
175  }
176
177  views::Widget* GetWindow() {
178    return impl_->window();
179  }
180
181 private:
182  scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
183
184  DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
185};
186
187ConstrainedWebDialogDelegateViewViews::ConstrainedWebDialogDelegateViewViews(
188    content::BrowserContext* browser_context,
189    WebDialogDelegate* delegate,
190    WebDialogWebContentsDelegate* tab_delegate)
191    : views::WebView(browser_context),
192      impl_(new ConstrainedWebDialogDelegateViews(browser_context,
193                                                  delegate,
194                                                  tab_delegate,
195                                                  this)) {
196  SetWebContents(GetWebContents());
197
198  // Pressing ESC closes the dialog.
199  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
200}
201
202ConstrainedWebDialogDelegateViewViews::~ConstrainedWebDialogDelegateViewViews() {
203}
204
205ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
206    content::BrowserContext* browser_context,
207    WebDialogDelegate* delegate,
208    WebDialogWebContentsDelegate* tab_delegate,
209    content::WebContents* web_contents) {
210  ConstrainedWebDialogDelegateViewViews* constrained_delegate =
211      new ConstrainedWebDialogDelegateViewViews(
212          browser_context, delegate, tab_delegate);
213  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
214      WebContentsModalDialogManager::FromWebContents(web_contents);
215  WebContentsModalDialogManagerDelegate* modal_delegate =
216      web_contents_modal_dialog_manager->delegate();
217  DCHECK(modal_delegate);
218  views::Widget* window = views::Widget::CreateWindowAsFramelessChild(
219      constrained_delegate,
220      modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
221  web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());
222  constrained_delegate->SetWindow(window);
223  return constrained_delegate;
224}
225