constrained_web_dialog_delegate_views.cc revision bb1529ce867d8845a77ec7cdf3e3003ef1771a40
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_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 "content/public/browser/web_contents_view.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;
29
30namespace {
31
32class ConstrainedWebDialogDelegateViews
33    : public ConstrainedWebDialogDelegateBase {
34 public:
35  ConstrainedWebDialogDelegateViews(
36      content::BrowserContext* browser_context,
37      WebDialogDelegate* delegate,
38      WebDialogWebContentsDelegate* tab_delegate,
39      views::WebView* view)
40      : ConstrainedWebDialogDelegateBase(
41            browser_context, delegate, tab_delegate),
42        view_(view),
43        window_(NULL) {}
44
45  virtual ~ConstrainedWebDialogDelegateViews() {}
46
47  // WebDialogWebContentsDelegate interface.
48  virtual void CloseContents(WebContents* source) OVERRIDE {
49    window_->Close();
50  }
51
52  // contents::WebContentsDelegate
53  virtual void HandleKeyboardEvent(
54      content::WebContents* source,
55      const content::NativeWebKeyboardEvent& event) OVERRIDE {
56    unhandled_keyboard_event_handler_.HandleKeyboardEvent(
57        event, view_->GetFocusManager());
58  }
59
60  // ConstrainedWebDialogDelegate
61  virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
62    return window_->GetNativeView();
63  }
64
65  void set_window(views::Widget* window) { window_ = window; }
66  views::Widget* window() const { return window_; }
67
68 private:
69  // Converts keyboard events on the WebContents to accelerators.
70  views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
71
72  views::WebView* view_;
73  views::Widget* window_;
74
75  DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
76};
77
78}  // namespace
79
80class ConstrainedWebDialogDelegateViewViews
81    : public views::WebView,
82      public ConstrainedWebDialogDelegate,
83      public views::WidgetDelegate {
84 public:
85  ConstrainedWebDialogDelegateViewViews(
86      content::BrowserContext* browser_context,
87      WebDialogDelegate* delegate,
88      WebDialogWebContentsDelegate* tab_delegate);
89  virtual ~ConstrainedWebDialogDelegateViewViews();
90
91  // ConstrainedWebDialogDelegate interface
92  virtual const WebDialogDelegate*
93      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  virtual void OnWidgetMove() OVERRIDE {
155    // We need to check the existence of the widget because when running on
156    // WinXP this could get executed before the widget is entirely created.
157    if (!GetWidget())
158      return;
159
160    if (!views::DialogDelegate::UseNewStyle()) {
161      GetWidget()->CenterWindow(
162          GetWidget()->non_client_view()->GetPreferredSize());
163    }
164    views::WidgetDelegate::OnWidgetMove();
165  }
166
167  // views::WebView overrides.
168  virtual bool AcceleratorPressed(
169      const ui::Accelerator& accelerator) OVERRIDE {
170    // Pressing ESC closes the dialog.
171    DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
172    impl_->window()->Close();
173    return true;
174  }
175  virtual gfx::Size GetPreferredSize() OVERRIDE {
176    gfx::Size size;
177    if (!impl_->closed_via_webui())
178      GetWebDialogDelegate()->GetDialogSize(&size);
179    return size;
180  }
181  virtual gfx::Size GetMinimumSize() OVERRIDE {
182    // Return an empty size so that we can be made smaller.
183    return gfx::Size();
184  }
185
186  void SetWindow(views::Widget* window) {
187    impl_->set_window(window);
188  }
189
190  views::Widget* GetWindow() {
191    return impl_->window();
192  }
193
194 private:
195  scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
196
197  DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
198};
199
200ConstrainedWebDialogDelegateViewViews::ConstrainedWebDialogDelegateViewViews(
201    content::BrowserContext* browser_context,
202    WebDialogDelegate* delegate,
203    WebDialogWebContentsDelegate* tab_delegate)
204    : views::WebView(browser_context),
205      impl_(new ConstrainedWebDialogDelegateViews(browser_context,
206                                                  delegate,
207                                                  tab_delegate,
208                                                  this)) {
209  SetWebContents(GetWebContents());
210
211  // Pressing ESC closes the dialog.
212  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
213}
214
215ConstrainedWebDialogDelegateViewViews::~ConstrainedWebDialogDelegateViewViews() {
216}
217
218ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
219    content::BrowserContext* browser_context,
220    WebDialogDelegate* delegate,
221    WebDialogWebContentsDelegate* tab_delegate,
222    content::WebContents* web_contents) {
223  ConstrainedWebDialogDelegateViewViews* constrained_delegate =
224      new ConstrainedWebDialogDelegateViewViews(
225          browser_context, delegate, tab_delegate);
226  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
227      WebContentsModalDialogManager::FromWebContents(web_contents);
228  views::Widget* window = CreateWebContentsModalDialogViews(
229      constrained_delegate,
230      web_contents->GetView()->GetNativeView(),
231      web_contents_modal_dialog_manager->delegate()->
232          GetWebContentsModalDialogHost());
233  web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());
234  constrained_delegate->SetWindow(window);
235  return constrained_delegate;
236}
237