OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h" | 5 #include "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include "base/mac/scoped_nsobject.h" | 9 #include "base/mac/scoped_nsobject.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi
ndow.h" | 11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi
ndow.h" |
12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" | 12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" |
13 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialo
g_sheet.h" | 13 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialo
g_sheet.h" |
14 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h" | |
15 #include "content/public/browser/render_view_host.h" | |
16 #include "content/public/browser/web_contents.h" | 14 #include "content/public/browser/web_contents.h" |
17 #include "content/public/browser/web_contents_observer.h" | |
18 #include "ui/base/cocoa/window_size_constants.h" | |
19 #include "ui/gfx/geometry/size.h" | 15 #include "ui/gfx/geometry/size.h" |
20 #include "ui/web_dialogs/web_dialog_delegate.h" | 16 #include "ui/web_dialogs/web_dialog_delegate.h" |
21 #include "ui/web_dialogs/web_dialog_ui.h" | 17 #include "ui/web_dialogs/web_dialog_ui.h" |
22 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h" | 18 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h" |
23 | 19 |
24 using content::WebContents; | 20 using content::WebContents; |
25 using ui::WebDialogDelegate; | 21 using ui::WebDialogDelegate; |
26 using ui::WebDialogWebContentsDelegate; | 22 using ui::WebDialogWebContentsDelegate; |
27 | 23 |
28 namespace { | 24 namespace { |
29 | 25 |
30 class ConstrainedWebDialogDelegateMac; | |
31 | |
32 // This class is to trigger a resize to the dialog window when | |
33 // ResizeDueToAutoResize() is invoked. | |
34 class WebDialogWebContentsDelegateMac | |
35 : public ui::WebDialogWebContentsDelegate { | |
36 public: | |
37 WebDialogWebContentsDelegateMac(content::BrowserContext* browser_context, | |
38 content::WebContentsObserver* observer, | |
39 ConstrainedWebDialogDelegateBase* delegate) | |
40 : ui::WebDialogWebContentsDelegate(browser_context, | |
41 new ChromeWebContentsHandler()), | |
42 observer_(observer), | |
43 delegate_(delegate) { | |
44 } | |
45 ~WebDialogWebContentsDelegateMac() override {} | |
46 | |
47 void ResizeDueToAutoResize(content::WebContents* source, | |
48 const gfx::Size& preferred_size) override { | |
49 if (!observer_->web_contents()) | |
50 return; | |
51 delegate_->ResizeToGivenSize(preferred_size); | |
52 } | |
53 | |
54 private: | |
55 // These members must outlive the instance. | |
56 content::WebContentsObserver* const observer_; | |
57 ConstrainedWebDialogDelegateBase* delegate_; | |
58 | |
59 DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateMac); | |
60 }; | |
61 | |
62 class ConstrainedWebDialogDelegateMac | 26 class ConstrainedWebDialogDelegateMac |
63 : public ConstrainedWebDialogDelegateBase { | 27 : public ConstrainedWebDialogDelegateBase { |
64 public: | 28 public: |
65 ConstrainedWebDialogDelegateMac( | 29 ConstrainedWebDialogDelegateMac( |
66 content::BrowserContext* browser_context, | 30 content::BrowserContext* browser_context, |
67 WebDialogDelegate* delegate, | 31 WebDialogDelegate* delegate) |
68 content::WebContentsObserver* observer) | 32 : ConstrainedWebDialogDelegateBase(browser_context, delegate, NULL) {} |
69 : ConstrainedWebDialogDelegateBase(browser_context, delegate, | |
70 new WebDialogWebContentsDelegateMac(browser_context, observer, | |
71 this)) {} | |
72 | 33 |
73 // WebDialogWebContentsDelegate interface. | 34 // WebDialogWebContentsDelegate interface. |
74 void CloseContents(WebContents* source) override { | 35 void CloseContents(WebContents* source) override { |
75 window_->CloseWebContentsModalDialog(); | 36 window_->CloseWebContentsModalDialog(); |
76 } | 37 } |
77 | 38 |
78 // ConstrainedWebDialogDelegateBase: | |
79 void ResizeToGivenSize(const gfx::Size size) override { | |
80 NSSize updated_preferred_size = NSMakeSize(size.width(), | |
81 size.height()); | |
82 [window_->sheet() resizeWithNewSize:updated_preferred_size]; | |
83 } | |
84 | |
85 void set_window(ConstrainedWindowMac* window) { window_ = window; } | 39 void set_window(ConstrainedWindowMac* window) { window_ = window; } |
86 ConstrainedWindowMac* window() const { return window_; } | 40 ConstrainedWindowMac* window() const { return window_; } |
87 | 41 |
88 private: | 42 private: |
89 // Weak, owned by ConstrainedWebDialogDelegateViewMac. | 43 // Weak, owned by ConstrainedWebDialogDelegateViewMac. |
90 ConstrainedWindowMac* window_; | 44 ConstrainedWindowMac* window_; |
91 | 45 |
92 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateMac); | 46 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateMac); |
93 }; | 47 }; |
94 | 48 |
95 } // namespace | 49 } // namespace |
96 | 50 |
97 class ConstrainedWebDialogDelegateViewMac : | 51 class ConstrainedWebDialogDelegateViewMac : |
98 public ConstrainedWindowMacDelegate, | 52 public ConstrainedWindowMacDelegate, |
99 public ConstrainedWebDialogDelegate, | 53 public ConstrainedWebDialogDelegate { |
100 public content::WebContentsObserver { | |
101 | 54 |
102 public: | 55 public: |
103 ConstrainedWebDialogDelegateViewMac( | 56 ConstrainedWebDialogDelegateViewMac( |
104 content::BrowserContext* browser_context, | 57 content::BrowserContext* browser_context, |
105 WebDialogDelegate* delegate, | 58 WebDialogDelegate* delegate, |
106 content::WebContents* web_contents, | 59 content::WebContents* web_contents); |
107 const gfx::Size& min_size, | |
108 const gfx::Size& max_size); | |
109 ~ConstrainedWebDialogDelegateViewMac() override {} | 60 ~ConstrainedWebDialogDelegateViewMac() override {} |
110 | 61 |
111 // ConstrainedWebDialogDelegate interface | 62 // ConstrainedWebDialogDelegate interface |
112 const WebDialogDelegate* GetWebDialogDelegate() const override { | 63 const WebDialogDelegate* GetWebDialogDelegate() const override { |
113 return impl_->GetWebDialogDelegate(); | 64 return impl_->GetWebDialogDelegate(); |
114 } | 65 } |
115 WebDialogDelegate* GetWebDialogDelegate() override { | 66 WebDialogDelegate* GetWebDialogDelegate() override { |
116 return impl_->GetWebDialogDelegate(); | 67 return impl_->GetWebDialogDelegate(); |
117 } | 68 } |
118 void OnDialogCloseFromWebUI() override { | 69 void OnDialogCloseFromWebUI() override { |
119 return impl_->OnDialogCloseFromWebUI(); | 70 return impl_->OnDialogCloseFromWebUI(); |
120 } | 71 } |
121 void ReleaseWebContentsOnDialogClose() override { | 72 void ReleaseWebContentsOnDialogClose() override { |
122 return impl_->ReleaseWebContentsOnDialogClose(); | 73 return impl_->ReleaseWebContentsOnDialogClose(); |
123 } | 74 } |
124 gfx::NativeWindow GetNativeDialog() override { return window_; } | 75 gfx::NativeWindow GetNativeDialog() override { return window_; } |
125 WebContents* GetWebContents() override { return impl_->GetWebContents(); } | 76 WebContents* GetWebContents() override { return impl_->GetWebContents(); } |
126 gfx::Size GetMinimumSize() const override { | 77 gfx::Size GetMinimumSize() const override { |
127 return min_size_; | 78 NOTIMPLEMENTED(); |
| 79 return gfx::Size(); |
128 } | 80 } |
129 gfx::Size GetMaximumSize() const override { | 81 gfx::Size GetMaximumSize() const override { |
130 return max_size_; | 82 NOTIMPLEMENTED(); |
| 83 return gfx::Size(); |
131 } | 84 } |
132 gfx::Size GetPreferredSize() const override { | 85 gfx::Size GetPreferredSize() const override { |
133 gfx::Size size; | 86 NOTIMPLEMENTED(); |
134 if (!impl_->closed_via_webui()) { | 87 return gfx::Size(); |
135 NSRect frame = [window_ frame]; | |
136 size = gfx::Size(frame.size.width, frame.size.height); | |
137 } | |
138 return size; | |
139 } | |
140 | |
141 // content::WebContentsObserver: | |
142 void RenderViewCreated(content::RenderViewHost* render_view_host) override { | |
143 if (IsDialogAutoResizable()) | |
144 EnableAutoResize(); | |
145 } | |
146 void RenderViewHostChanged(content::RenderViewHost* old_host, | |
147 content::RenderViewHost* new_host) override { | |
148 if (IsDialogAutoResizable()) | |
149 EnableAutoResize(); | |
150 } | |
151 void DocumentOnLoadCompletedInMainFrame() override { | |
152 if (!IsDialogAutoResizable()) | |
153 return; | |
154 | |
155 EnableAutoResize(); | |
156 if (GetWebContents()) | |
157 constrained_window_->ShowWebContentsModalDialog(); | |
158 } | 88 } |
159 | 89 |
160 // ConstrainedWindowMacDelegate interface | 90 // ConstrainedWindowMacDelegate interface |
161 void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override { | 91 void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override { |
162 if (!impl_->closed_via_webui()) | 92 if (!impl_->closed_via_webui()) |
163 GetWebDialogDelegate()->OnDialogClosed(""); | 93 GetWebDialogDelegate()->OnDialogClosed(""); |
164 delete this; | 94 delete this; |
165 } | 95 } |
166 | 96 |
167 private: | 97 private: |
168 void EnableAutoResize() { | |
169 if (!GetWebContents()) | |
170 return; | |
171 | |
172 content::RenderViewHost* render_view_host = | |
173 GetWebContents()->GetRenderViewHost(); | |
174 render_view_host->EnableAutoResize(min_size_, max_size_); | |
175 } | |
176 | |
177 // Whether or not the dialog is autoresizable is determined based on whether | |
178 // |max_size_| was specified. | |
179 bool IsDialogAutoResizable() { | |
180 return !max_size_.IsEmpty(); | |
181 } | |
182 | |
183 scoped_ptr<ConstrainedWebDialogDelegateMac> impl_; | 98 scoped_ptr<ConstrainedWebDialogDelegateMac> impl_; |
184 std::unique_ptr<ConstrainedWindowMac> constrained_window_; | 99 scoped_ptr<ConstrainedWindowMac> constrained_window_; |
185 base::scoped_nsobject<NSWindow> window_; | 100 base::scoped_nsobject<NSWindow> window_; |
186 | 101 |
187 // Minimum and maximum sizes to determine dialog bounds for auto-resizing. | |
188 const gfx::Size min_size_; | |
189 const gfx::Size max_size_; | |
190 | |
191 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewMac); | 102 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewMac); |
192 }; | 103 }; |
193 | 104 |
194 ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac( | 105 ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac( |
195 content::BrowserContext* browser_context, | 106 content::BrowserContext* browser_context, |
196 WebDialogDelegate* delegate, | 107 WebDialogDelegate* delegate, |
197 content::WebContents* web_contents, | 108 content::WebContents* web_contents) |
198 const gfx::Size& min_size, | 109 : impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate)) { |
199 const gfx::Size& max_size) | |
200 : content::WebContentsObserver(web_contents), | |
201 impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate, | |
202 this)), | |
203 min_size_(min_size), | |
204 max_size_(max_size) { | |
205 if (IsDialogAutoResizable()) | |
206 Observe(GetWebContents()); | |
207 | |
208 // Create a window to hold web_contents in the constrained sheet: | 110 // Create a window to hold web_contents in the constrained sheet: |
209 gfx::Size size; | 111 gfx::Size size; |
210 delegate->GetDialogSize(&size); | 112 delegate->GetDialogSize(&size); |
211 NSRect frame = NSMakeRect(0, 0, size.width(), size.height()); | 113 NSRect frame = NSMakeRect(0, 0, size.width(), size.height()); |
212 | 114 |
213 window_.reset([[ConstrainedWindowCustomWindow alloc] | 115 window_.reset( |
214 initWithContentRect:ui::kWindowSizeDeterminedLater]); | 116 [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]); |
215 [GetWebContents()->GetNativeView() setFrame:frame]; | 117 [GetWebContents()->GetNativeView() setFrame:frame]; |
216 [GetWebContents()->GetNativeView() setAutoresizingMask: | 118 [GetWebContents()->GetNativeView() setAutoresizingMask: |
217 NSViewWidthSizable|NSViewHeightSizable]; | 119 NSViewWidthSizable|NSViewHeightSizable]; |
218 [[window_ contentView] addSubview:GetWebContents()->GetNativeView()]; | 120 [[window_ contentView] addSubview:GetWebContents()->GetNativeView()]; |
219 | 121 |
220 base::scoped_nsobject<WebDialogConstrainedWindowSheet> sheet( | 122 base::scoped_nsobject<WebDialogConstrainedWindowSheet> sheet( |
221 [[WebDialogConstrainedWindowSheet alloc] initWithCustomWindow:window_ | 123 [[WebDialogConstrainedWindowSheet alloc] initWithCustomWindow:window_ |
222 webDialogDelegate:delegate]); | 124 webDialogDelegate:delegate]); |
223 | 125 constrained_window_.reset(new ConstrainedWindowMac( |
224 if (IsDialogAutoResizable()) { | 126 this, web_contents, sheet)); |
225 constrained_window_ = CreateWebModalDialogMac( | |
226 this, web_contents, sheet); | |
227 } else { | |
228 constrained_window_ = CreateAndShowWebModalDialogMac( | |
229 this, web_contents, sheet); | |
230 } | |
231 | 127 |
232 impl_->set_window(constrained_window_.get()); | 128 impl_->set_window(constrained_window_.get()); |
233 } | 129 } |
234 | 130 |
235 ConstrainedWebDialogDelegate* ShowConstrainedWebDialog( | 131 ConstrainedWebDialogDelegate* ShowConstrainedWebDialog( |
236 content::BrowserContext* browser_context, | 132 content::BrowserContext* browser_context, |
237 WebDialogDelegate* delegate, | 133 WebDialogDelegate* delegate, |
238 content::WebContents* web_contents) { | 134 content::WebContents* web_contents) { |
239 // Deleted when the dialog closes. | 135 // Deleted when the dialog closes. |
240 ConstrainedWebDialogDelegateViewMac* constrained_delegate = | 136 ConstrainedWebDialogDelegateViewMac* constrained_delegate = |
241 new ConstrainedWebDialogDelegateViewMac( | 137 new ConstrainedWebDialogDelegateViewMac( |
242 browser_context, delegate, web_contents, | 138 browser_context, delegate, web_contents); |
243 gfx::Size(), gfx::Size()); | |
244 return constrained_delegate; | 139 return constrained_delegate; |
245 } | 140 } |
246 | |
247 ConstrainedWebDialogDelegate* ShowConstrainedWebDialogWithAutoResize( | |
248 content::BrowserContext* browser_context, | |
249 WebDialogDelegate* delegate, | |
250 content::WebContents* web_contents, | |
251 const gfx::Size& min_size, | |
252 const gfx::Size& max_size) { | |
253 DCHECK(!min_size.IsEmpty()); | |
254 DCHECK(!max_size.IsEmpty()); | |
255 // Deleted when the dialog closes. | |
256 ConstrainedWebDialogDelegateViewMac* constrained_delegate = | |
257 new ConstrainedWebDialogDelegateViewMac( | |
258 browser_context, delegate, web_contents, | |
259 min_size, max_size); | |
260 return constrained_delegate; | |
261 } | |
OLD | NEW |