Chromium Code Reviews| Index: chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
| diff --git a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
| index 2aab61a1e29ede1fa76753d8c9402f6260111456..b6a3a4f6a878d929ec9c3b83efc243ea07dcd60b 100644 |
| --- a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
| +++ b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
| @@ -12,8 +12,9 @@ |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| +#include "chrome/browser/ui/cocoa/constrained_window_mac.h" |
| #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" |
| -#import "chrome/browser/ui/cocoa/web_intent_bubble_controller.h" |
| +#import "chrome/browser/ui/cocoa/web_intent_sheet_controller.h" |
| #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" |
| #include "chrome/browser/ui/intents/web_intent_picker.h" |
| #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" |
| @@ -24,6 +25,49 @@ |
| using content::WebContents; |
| +namespace { |
| + |
| +// Since any delegates for constrained windows are tasked with deleting |
| +// themselves, and the WebIntentPicker needs to live longer than the |
| +// constrained window, we need this forwarding class. |
| +class ConstrainedPickerSheetDelegate : |
| + public ConstrainedWindowMacDelegateCustomSheet { |
| + public: |
| + ConstrainedPickerSheetDelegate( |
| + WebIntentPickerCocoa* picker, |
| + WebIntentPickerSheetController* sheet_controller); |
| + virtual ~ConstrainedPickerSheetDelegate() {} |
| + |
| + // ConstrainedWindowMacDelegateCustomSheet interface |
| + virtual void DeleteDelegate() OVERRIDE; |
| + |
| + private: |
| + WebIntentPickerCocoa* picker_; // Weak reference to picker |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ConstrainedPickerSheetDelegate); |
| +}; |
| + |
| +ConstrainedPickerSheetDelegate::ConstrainedPickerSheetDelegate( |
| + WebIntentPickerCocoa* picker, |
| + WebIntentPickerSheetController* sheet_controller) |
| + : picker_(picker) { |
| + init([sheet_controller window], sheet_controller, |
| + @selector(sheetDidEnd:returnCode:contextInfo:)); |
| + set_sheet([sheet_controller window]); |
|
Nico
2012/03/06 22:56:26
init() already sets the sheet, so this line should
groby-ooo-7-16
2012/03/07 00:50:42
Done.
|
| +} |
| + |
| +void ConstrainedPickerSheetDelegate::DeleteDelegate() { |
| + if (is_sheet_open()) |
| + [NSApp endSheet:sheet()]; |
| + |
| + if (picker_) |
| + picker_->OnCancelled(); |
| + |
| + delete this; |
| +} |
| + |
| +} // namespace |
| + |
| // static |
| WebIntentPicker* WebIntentPicker::Create(Browser* browser, |
| TabContentsWrapper* wrapper, |
| @@ -36,39 +80,32 @@ WebIntentPickerCocoa::WebIntentPickerCocoa() |
| : delegate_(NULL), |
| model_(NULL), |
| browser_(NULL), |
| - controller_(nil), |
| - weak_ptr_factory_(this), |
| + sheet_controller_(nil), |
| service_invoked(false) { |
| } |
| - |
| WebIntentPickerCocoa::WebIntentPickerCocoa(Browser* browser, |
| TabContentsWrapper* wrapper, |
| WebIntentPickerDelegate* delegate, |
| WebIntentPickerModel* model) |
| - : delegate_(delegate), |
| - model_(model), |
| - browser_(browser), |
| - controller_(nil), |
| - weak_ptr_factory_(this), |
| - service_invoked(false) { |
| + : delegate_(delegate), |
| + model_(model), |
| + browser_(browser), |
| + sheet_controller_(nil), |
| + service_invoked(false) { |
| model_->set_observer(this); |
| - DCHECK(browser); |
| DCHECK(delegate); |
| - NSWindow* parentWindow = browser->window()->GetNativeHandle(); |
| - |
| - // Compute the anchor point, relative to location bar. |
| - BrowserWindowController* controller = [parentWindow windowController]; |
| - LocationBarViewMac* locationBar = [controller locationBarBridge]; |
| - NSPoint anchor = locationBar->GetPageInfoBubblePoint(); |
| - anchor = [browser->window()->GetNativeHandle() convertBaseToScreen:anchor]; |
| - |
| - // The controller is deallocated when the window is closed, so no need to |
| - // worry about it here. |
| - [[WebIntentBubbleController alloc] initWithPicker:this |
| - parentWindow:parentWindow |
| - anchoredAt:anchor]; |
| + DCHECK(wrapper); |
| + |
| + sheet_controller_ = [ |
| + [WebIntentPickerSheetController alloc] initWithPicker:this]; |
| + |
| + // Deleted when ConstrainedPickerSheetDelegate::DeleteDelegate() runs. |
| + ConstrainedPickerSheetDelegate* constrained_delegate = |
| + new ConstrainedPickerSheetDelegate(this, sheet_controller_); |
| + |
| + window_ = new ConstrainedWindowMac(wrapper, constrained_delegate); |
| } |
| WebIntentPickerCocoa::~WebIntentPickerCocoa() { |
| @@ -76,50 +113,38 @@ WebIntentPickerCocoa::~WebIntentPickerCocoa() { |
| model_->set_observer(NULL); |
| } |
| +void WebIntentPickerCocoa::OnSheetDidEnd(NSWindow* sheet) { |
| + [sheet orderOut:sheet_controller_]; |
| + if (window_) |
| + window_->CloseConstrainedWindow(); |
| +} |
| + |
| void WebIntentPickerCocoa::Close() { |
| - DCHECK(controller_); |
| - [controller_ close]; |
| + DCHECK(sheet_controller_); |
| + [sheet_controller_ closeSheet]; |
| + |
| if (inline_disposition_tab_contents_.get()) |
| inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); |
| } |
| -void WebIntentPickerCocoa::PerformDelayedLayout() { |
| - // Check to see if a layout has already been scheduled. |
| - if (weak_ptr_factory_.HasWeakPtrs()) |
| - return; |
| - |
| - // Delay performing layout by a second so that all the animations from |
| - // InfoBubbleWindow and origin updates from BaseBubbleController finish, so |
| - // that we don't all race trying to change the frame's origin. |
| - // |
| - // Using MessageLoop is superior here to |-performSelector:| because it will |
| - // not retain its target; if the child outlives its parent, zombies get left |
| - // behind (http://crbug.com/59619). This will cancel the scheduled task if |
| - // the controller get destroyed before the message |
| - // can be delivered. |
| - MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| - base::Bind(&WebIntentPickerCocoa::PerformLayout, |
| - weak_ptr_factory_.GetWeakPtr()), |
| - 100 /* milliseconds */); |
| -} |
| - |
| void WebIntentPickerCocoa::PerformLayout() { |
| - DCHECK(controller_); |
| + DCHECK(sheet_controller_); |
| // If the window is animating closed when this is called, the |
| // animation could be holding the last reference to |controller_| |
| // (and thus |this|). Pin it until the task is completed. |
| - scoped_nsobject<WebIntentBubbleController> keep_alive([controller_ retain]); |
| - [controller_ performLayoutWithModel:model_]; |
| + scoped_nsobject<WebIntentPickerSheetController> |
| + keep_alive([sheet_controller_ retain]); |
| + [sheet_controller_ performLayoutWithModel:model_]; |
| } |
| void WebIntentPickerCocoa::OnModelChanged(WebIntentPickerModel* model) { |
| - PerformDelayedLayout(); |
| + PerformLayout(); |
| } |
| void WebIntentPickerCocoa::OnFaviconChanged(WebIntentPickerModel* model, |
| size_t index) { |
| // We don't handle individual icon changes - just redo the whole model. |
| - PerformDelayedLayout(); |
| + PerformLayout(); |
| } |
| void WebIntentPickerCocoa::OnExtensionIconChanged( |
| @@ -129,6 +154,7 @@ void WebIntentPickerCocoa::OnExtensionIconChanged( |
| } |
| void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) { |
| + DCHECK(browser_); |
| const WebIntentPickerModel::InstalledService& installed_service = |
| model->GetInstalledServiceAt(model->inline_disposition_index()); |
| @@ -148,9 +174,9 @@ void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) { |
| content::PAGE_TRANSITION_START_PAGE, |
| std::string()); |
| - [controller_ setInlineDispositionTabContents: |
| + [sheet_controller_ setInlineDispositionTabContents: |
| inline_disposition_tab_contents_.get()]; |
| - PerformDelayedLayout(); |
| + PerformLayout(); |
| } |
| void WebIntentPickerCocoa::OnCancelled() { |
| @@ -169,7 +195,3 @@ void WebIntentPickerCocoa::OnServiceChosen(size_t index) { |
| delegate_->OnServiceChosen(index, installed_service.disposition); |
| } |
| -void WebIntentPickerCocoa::set_controller( |
| - WebIntentBubbleController* controller) { |
| - controller_ = controller; |
| -} |