| 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 |