1 // Copyright (c) 2009 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/cocoa/constrained_window_mac.h" 6 7 #import "chrome/browser/ui/cocoa/browser_window_controller.h" 8 #include "content/browser/tab_contents/tab_contents.h" 9 #include "content/browser/tab_contents/tab_contents_view.h" 10 #import "third_party/GTM/AppKit/GTMWindowSheetController.h" 11 12 ConstrainedWindowMacDelegateSystemSheet:: 13 ConstrainedWindowMacDelegateSystemSheet(id delegate, SEL didEndSelector) 14 : systemSheet_(nil), 15 delegate_([delegate retain]), 16 didEndSelector_(didEndSelector) {} 17 18 ConstrainedWindowMacDelegateSystemSheet:: 19 ~ConstrainedWindowMacDelegateSystemSheet() {} 20 21 void ConstrainedWindowMacDelegateSystemSheet::set_sheet(id sheet) { 22 systemSheet_.reset([sheet retain]); 23 } 24 25 NSArray* ConstrainedWindowMacDelegateSystemSheet::GetSheetParameters( 26 id delegate, 27 SEL didEndSelector) { 28 return [NSArray arrayWithObjects: 29 [NSNull null], // window, must be [NSNull null] 30 delegate, 31 [NSValue valueWithPointer:didEndSelector], 32 [NSValue valueWithPointer:NULL], // context info for didEndSelector_. 33 nil]; 34 } 35 36 void ConstrainedWindowMacDelegateSystemSheet::RunSheet( 37 GTMWindowSheetController* sheetController, 38 NSView* view) { 39 NSArray* params = GetSheetParameters(delegate_.get(), didEndSelector_); 40 [sheetController beginSystemSheet:systemSheet_ 41 modalForView:view 42 withParameters:params]; 43 } 44 45 ConstrainedWindowMacDelegateCustomSheet:: 46 ConstrainedWindowMacDelegateCustomSheet() 47 : customSheet_(nil), 48 delegate_(nil), 49 didEndSelector_(NULL) {} 50 51 ConstrainedWindowMacDelegateCustomSheet:: 52 ConstrainedWindowMacDelegateCustomSheet(id delegate, SEL didEndSelector) 53 : customSheet_(nil), 54 delegate_([delegate retain]), 55 didEndSelector_(didEndSelector) {} 56 57 ConstrainedWindowMacDelegateCustomSheet:: 58 ~ConstrainedWindowMacDelegateCustomSheet() {} 59 60 void ConstrainedWindowMacDelegateCustomSheet::init(NSWindow* sheet, 61 id delegate, 62 SEL didEndSelector) { 63 DCHECK(!delegate_.get()); 64 DCHECK(!didEndSelector_); 65 customSheet_.reset([sheet retain]); 66 delegate_.reset([delegate retain]); 67 didEndSelector_ = didEndSelector; 68 DCHECK(delegate_.get()); 69 DCHECK(didEndSelector_); 70 } 71 72 void ConstrainedWindowMacDelegateCustomSheet::set_sheet(NSWindow* sheet) { 73 customSheet_.reset([sheet retain]); 74 } 75 76 void ConstrainedWindowMacDelegateCustomSheet::RunSheet( 77 GTMWindowSheetController* sheetController, 78 NSView* view) { 79 [sheetController beginSheet:customSheet_.get() 80 modalForView:view 81 modalDelegate:delegate_.get() 82 didEndSelector:didEndSelector_ 83 contextInfo:NULL]; 84 } 85 86 // static 87 ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog( 88 TabContents* parent, 89 ConstrainedWindowMacDelegate* delegate) { 90 return new ConstrainedWindowMac(parent, delegate); 91 } 92 93 ConstrainedWindowMac::ConstrainedWindowMac( 94 TabContents* owner, ConstrainedWindowMacDelegate* delegate) 95 : owner_(owner), 96 delegate_(delegate), 97 controller_(nil), 98 should_be_visible_(false) { 99 DCHECK(owner); 100 DCHECK(delegate); 101 } 102 103 ConstrainedWindowMac::~ConstrainedWindowMac() {} 104 105 void ConstrainedWindowMac::ShowConstrainedWindow() { 106 should_be_visible_ = true; 107 // The TabContents only has a native window if it is currently visible. In 108 // this case, open the sheet now. Else, Realize() will be called later, when 109 // our tab becomes visible. 110 NSWindow* browserWindow = owner_->view()->GetTopLevelNativeWindow(); 111 NSWindowController* controller = [browserWindow windowController]; 112 if (controller != nil) { 113 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); 114 BrowserWindowController* browser_controller = 115 static_cast<BrowserWindowController*>(controller); 116 if ([browser_controller canAttachConstrainedWindow]) 117 Realize(browser_controller); 118 } 119 } 120 121 void ConstrainedWindowMac::CloseConstrainedWindow() { 122 // Note: controller_ can be `nil` here if the sheet was never realized. That's 123 // ok. 124 [controller_ removeConstrainedWindow:this]; 125 delegate_->DeleteDelegate(); 126 owner_->WillClose(this); 127 128 delete this; 129 } 130 131 void ConstrainedWindowMac::Realize(BrowserWindowController* controller) { 132 if (!should_be_visible_) 133 return; 134 135 if (controller_ != nil) { 136 DCHECK(controller_ == controller); 137 return; 138 } 139 DCHECK(controller != nil); 140 141 // Remember the controller we're adding ourselves to, so that we can later 142 // remove us from it. 143 controller_ = controller; 144 [controller_ attachConstrainedWindow:this]; 145 delegate_->set_sheet_open(true); 146 } 147