constrained_web_dialog_delegate_views.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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
44  virtual ~ConstrainedWebDialogDelegateViews() {}
45
46  // WebDialogWebContentsDelegate interface.
47  virtual void CloseContents(WebContents* source) OVERRIDE {
48    window_->Close();
49  }
50
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());
57  }
58
59  // ConstrainedWebDialogDelegate
60  virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
61    return window_->GetNativeView();
62  }
63
64  void set_window(views::Widget* window) { window_ = window; }
65  views::Widget* window() const { return window_; }
66
67 private:
68  // Converts keyboard events on the WebContents to accelerators.
69  views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
70
71  views::WebView* view_;
72  views::Widget* window_;
73
74  DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
75};
76
77}  // namespace
78
79class ConstrainedWebDialogDelegateViewViews
80    : public views::WebView,
81      public ConstrainedWebDialogDelegate,
82      public views::WidgetDelegate {
83 public:
84  ConstrainedWebDialogDelegateViewViews(
85      content::BrowserContext* browser_context,
86      WebDialogDelegate* delegate,
87      WebDialogWebContentsDelegate* tab_delegate);
88  virtual ~ConstrainedWebDialogDelegateViewViews();
89
90  // ConstrainedWebDialogDelegate interface
91  virtual const WebDialogDelegate*
92      GetWebDialogDelegate() const OVERRIDE {
93    return impl_->GetWebDialogDelegate();
94  }
95  virtual WebDialogDelegate* GetWebDialogDelegate() OVERRIDE {
96    return impl_->GetWebDialogDelegate();
97  }
98  virtual void OnDialogCloseFromWebUI() OVERRIDE {
99    return impl_->OnDialogCloseFromWebUI();
100  }
101  virtual void ReleaseWebContentsOnDialogClose() OVERRIDE {
102    return impl_->ReleaseWebContentsOnDialogClose();
103  }
104  virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
105    return impl_->window()->GetNativeView();
106  }
107  virtual WebContents* GetWebContents() OVERRIDE {
108    return impl_->GetWebContents();
109  }
110
111  // views::WidgetDelegate interface.
112  virtual views::View* GetInitiallyFocusedView() OVERRIDE {
113    return this;
114  }
115  virtual void WindowClosing() OVERRIDE {
116    if (!impl_->closed_via_webui())
117      GetWebDialogDelegate()->OnDialogClosed(std::string());
118  }
119  virtual views::Widget* GetWidget() OVERRIDE {
120    return View::GetWidget();
121  }
122  virtual const views::Widget* GetWidget() const OVERRIDE {
123    return View::GetWidget();
124  }
125  virtual string16 GetWindowTitle() const OVERRIDE {
126    return impl_->closed_via_webui() ? string16() :
127        GetWebDialogDelegate()->GetDialogTitle();
128  }
129  virtual views::View* GetContentsView() OVERRIDE {
130    return this;
131  }
132  // TODO(wittman): Remove this override once we move to the new style frame
133  // view on all dialogs.
134  virtual views::NonClientFrameView* CreateNonClientFrameView(
135      views::Widget* widget) OVERRIDE {
136    return CreateConstrainedStyleNonClientFrameView(
137        widget,
138        GetWebContents()->GetBrowserContext());
139  }
140  virtual bool ShouldShowCloseButton() const OVERRIDE {
141    // No close button if the dialog doesn't want a title bar.
142    return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
143  }
144
145  virtual ui::ModalType GetModalType() const OVERRIDE {
146#if defined(USE_ASH)
147    return ui::MODAL_TYPE_CHILD;
148#else
149    return views::WidgetDelegate::GetModalType();
150#endif
151  }
152
153  virtual void OnWidgetMove() OVERRIDE {
154    // We need to check the existence of the widget because when running on
155    // WinXP this could get executed before the widget is entirely created.
156    if (!GetWidget())
157      return;
158
159    if (!views::DialogDelegate::UseNewStyle()) {
160      GetWidget()->CenterWindow(
161          GetWidget()->non_client_view()->GetPreferredSize());
162    }
163    views::WidgetDelegate::OnWidgetMove();
164  }
165
166  // views::WebView overrides.
167  virtual bool AcceleratorPressed(
168      const ui::Accelerator& accelerator) OVERRIDE {
169    // Pressing ESC closes the dialog.
170    DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
171    impl_->window()->Close();
172    return true;
173  }
174  virtual gfx::Size GetPreferredSize() OVERRIDE {
175    gfx::Size size;
176    if (!impl_->closed_via_webui())
177      GetWebDialogDelegate()->GetDialogSize(&size);
178    return size;
179  }
180  virtual gfx::Size GetMinimumSize() OVERRIDE {
181    // Return an empty size so that we can be made smaller.
182    return gfx::Size();
183  }
184
185  void SetWindow(views::Widget* window) {
186    impl_->set_window(window);
187  }
188
189  views::Widget* GetWindow() {
190    return impl_->window();
191  }
192
193 private:
194  scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
195
196  DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
197};
198
199ConstrainedWebDialogDelegateViewViews::ConstrainedWebDialogDelegateViewViews(
200    content::BrowserContext* browser_context,
201    WebDialogDelegate* delegate,
202    WebDialogWebContentsDelegate* tab_delegate)
203    : views::WebView(browser_context),
204      impl_(new ConstrainedWebDialogDelegateViews(browser_context,
205                                                  delegate,
206                                                  tab_delegate,
207                                                  this)) {
208  SetWebContents(GetWebContents());
209
210  // Pressing ESC closes the dialog.
211  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
212}
213
214ConstrainedWebDialogDelegateViewViews::~ConstrainedWebDialogDelegateViewViews() {
215}
216
217ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
218    content::BrowserContext* browser_context,
219    WebDialogDelegate* delegate,
220    WebDialogWebContentsDelegate* tab_delegate,
221    content::WebContents* web_contents) {
222  ConstrainedWebDialogDelegateViewViews* constrained_delegate =
223      new ConstrainedWebDialogDelegateViewViews(
224          browser_context, delegate, tab_delegate);
225  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
226      WebContentsModalDialogManager::FromWebContents(web_contents);
227  views::Widget* window = CreateWebContentsModalDialogViews(
228      constrained_delegate,
229      web_contents->GetView()->GetNativeView(),
230      web_contents_modal_dialog_manager->delegate()->
231          GetWebContentsModalDialogHost());
232  web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());
233  constrained_delegate->SetWindow(window);
234  return constrained_delegate;
235}
236