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