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 #import "chrome/browser/ui/cocoa/infobars/extension_infobar_controller.h" | 5 #import "chrome/browser/ui/cocoa/infobars/extension_infobar_controller.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "chrome/browser/extensions/extension_infobar_delegate.h" | 9 #include "chrome/browser/extensions/extension_infobar_delegate.h" |
10 #include "chrome/browser/extensions/extension_view_host.h" | 10 #include "chrome/browser/extensions/extension_view_host.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 - (CGFloat)clampedExtensionViewHeight; | 45 - (CGFloat)clampedExtensionViewHeight; |
46 // Adjusts the width of the extension's hosted view to match the window's width | 46 // Adjusts the width of the extension's hosted view to match the window's width |
47 // and sets the proper height for it as well. | 47 // and sets the proper height for it as well. |
48 - (void)adjustExtensionViewSize; | 48 - (void)adjustExtensionViewSize; |
49 // Sets the image to be used in the button on the left side of the infobar. | 49 // Sets the image to be used in the button on the left side of the infobar. |
50 - (void)setButtonImage:(NSImage*)image; | 50 - (void)setButtonImage:(NSImage*)image; |
51 @end | 51 @end |
52 | 52 |
53 // A helper class to bridge the asynchronous Skia bitmap loading mechanism to | 53 // A helper class to bridge the asynchronous Skia bitmap loading mechanism to |
54 // the extension's button. | 54 // the extension's button. |
55 class InfobarBridge { | 55 class InfobarBridge : public ExtensionInfoBarDelegate::DelegateObserver { |
56 public: | 56 public: |
57 explicit InfobarBridge(ExtensionInfoBarController* owner) | 57 explicit InfobarBridge(ExtensionInfoBarController* owner) |
58 : owner_(owner), | 58 : owner_(owner), |
59 delegate_([owner delegate]->AsExtensionInfoBarDelegate()), | 59 delegate_([owner delegate]->AsExtensionInfoBarDelegate()), |
60 weak_ptr_factory_(this) { | 60 weak_ptr_factory_(this) { |
| 61 delegate_->set_observer(this); |
61 LoadIcon(); | 62 LoadIcon(); |
62 } | 63 } |
63 | 64 |
| 65 virtual ~InfobarBridge() { |
| 66 if (delegate_) |
| 67 delegate_->set_observer(NULL); |
| 68 } |
| 69 |
64 // Load the Extension's icon image. | 70 // Load the Extension's icon image. |
65 void LoadIcon() { | 71 void LoadIcon() { |
66 const extensions::Extension* extension = delegate_->extension_view_host()-> | 72 const extensions::Extension* extension = delegate_->extension_view_host()-> |
67 extension(); | 73 extension(); |
68 extensions::ExtensionResource icon_resource = | 74 extensions::ExtensionResource icon_resource = |
69 extensions::IconsInfo::GetIconResource( | 75 extensions::IconsInfo::GetIconResource( |
70 extension, | 76 extension, |
71 extension_misc::EXTENSION_ICON_BITTY, | 77 extension_misc::EXTENSION_ICON_BITTY, |
72 ExtensionIconSet::MATCH_EXACTLY); | 78 ExtensionIconSet::MATCH_EXACTLY); |
73 extensions::ImageLoader* loader = extensions::ImageLoader::Get( | 79 extensions::ImageLoader* loader = extensions::ImageLoader::Get( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 0, 0, icon->width(), icon->height(), | 112 0, 0, icon->width(), icon->height(), |
107 0, 0, image_size, image_size, | 113 0, 0, image_size, image_size, |
108 false); | 114 false); |
109 canvas->DrawImageInt(*drop_image, | 115 canvas->DrawImageInt(*drop_image, |
110 image_size + kDropArrowLeftMarginPx, | 116 image_size + kDropArrowLeftMarginPx, |
111 image_size / 2); | 117 image_size / 2); |
112 [owner_ setButtonImage:gfx::SkBitmapToNSImage( | 118 [owner_ setButtonImage:gfx::SkBitmapToNSImage( |
113 canvas->ExtractImageRep().sk_bitmap())]; | 119 canvas->ExtractImageRep().sk_bitmap())]; |
114 } | 120 } |
115 | 121 |
| 122 // Overridden from ExtensionInfoBarDelegate::DelegateObserver: |
| 123 virtual void OnDelegateDeleted() OVERRIDE { |
| 124 delegate_ = NULL; |
| 125 } |
| 126 |
116 private: | 127 private: |
117 // Weak. Owns us. | 128 // Weak. Owns us. |
118 ExtensionInfoBarController* owner_; | 129 ExtensionInfoBarController* owner_; |
119 | 130 |
120 // Weak. | 131 // Weak. |
121 ExtensionInfoBarDelegate* delegate_; | 132 ExtensionInfoBarDelegate* delegate_; |
122 | 133 |
123 base::WeakPtrFactory<InfobarBridge> weak_ptr_factory_; | 134 base::WeakPtrFactory<InfobarBridge> weak_ptr_factory_; |
124 | 135 |
125 DISALLOW_COPY_AND_ASSIGN(InfobarBridge); | 136 DISALLOW_COPY_AND_ASSIGN(InfobarBridge); |
126 }; | 137 }; |
127 | 138 |
128 | 139 |
129 @implementation ExtensionInfoBarController | 140 @implementation ExtensionInfoBarController |
130 | 141 |
131 - (id)initWithInfoBar:(InfoBarCocoa*)infobar { | 142 - (id)initWithInfoBar:(InfoBarCocoa*)infobar |
| 143 window:(NSWindow*)window { |
132 if ((self = [super initWithInfoBar:infobar])) { | 144 if ((self = [super initWithInfoBar:infobar])) { |
| 145 window_ = window; |
133 dropdownButton_.reset([[MenuButton alloc] init]); | 146 dropdownButton_.reset([[MenuButton alloc] init]); |
134 [dropdownButton_ setOpenMenuOnClick:YES]; | 147 [dropdownButton_ setOpenMenuOnClick:YES]; |
135 | 148 |
| 149 extensions::ExtensionViewHost* extensionViewHost = |
| 150 [self delegate]->AsExtensionInfoBarDelegate()->extension_view_host(); |
| 151 Browser* browser = chrome::FindBrowserWithWebContents( |
| 152 [self infobar]->OwnerCocoa()->web_contents()); |
| 153 contextMenuController_.reset([[ExtensionActionContextMenuController alloc] |
| 154 initWithExtension:extensionViewHost->extension() |
| 155 browser:browser |
| 156 extensionAction:NULL]); |
| 157 |
136 base::scoped_nsobject<NSMenu> contextMenu( | 158 base::scoped_nsobject<NSMenu> contextMenu( |
137 [[NSMenu alloc] initWithTitle:@""]); | 159 [[NSMenu alloc] initWithTitle:@""]); |
138 [contextMenu setDelegate:self]; | 160 [contextMenu setDelegate:self]; |
139 // See menu_button.h for documentation on why this is needed. | 161 // See menu_button.h for documentation on why this is needed. |
140 [contextMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; | 162 [contextMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; |
141 [dropdownButton_ setAttachedMenu:contextMenu]; | 163 [dropdownButton_ setAttachedMenu:contextMenu]; |
142 | 164 |
143 bridge_.reset(new InfobarBridge(self)); | 165 bridge_.reset(new InfobarBridge(self)); |
144 } | 166 } |
145 return self; | 167 return self; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 // the parent infobar view matches the height of the extension's native view. | 217 // the parent infobar view matches the height of the extension's native view. |
196 [[NSNotificationCenter defaultCenter] | 218 [[NSNotificationCenter defaultCenter] |
197 addObserver:self | 219 addObserver:self |
198 selector:@selector(extensionViewFrameChanged) | 220 selector:@selector(extensionViewFrameChanged) |
199 name:NSViewFrameDidChangeNotification | 221 name:NSViewFrameDidChangeNotification |
200 object:extensionView_]; | 222 object:extensionView_]; |
201 | 223 |
202 [[NSNotificationCenter defaultCenter] | 224 [[NSNotificationCenter defaultCenter] |
203 addObserver:self | 225 addObserver:self |
204 selector:@selector(adjustExtensionViewSize) | 226 selector:@selector(adjustExtensionViewSize) |
205 name:NSViewFrameDidChangeNotification | 227 name:NSWindowDidResizeNotification |
206 object:[self view]]; | 228 object:window_]; |
207 } | |
208 | |
209 - (void)infobarWillHide { | |
210 [[dropdownButton_ menu] cancelTracking]; | |
211 [super infobarWillHide]; | |
212 } | 229 } |
213 | 230 |
214 - (void)infobarWillClose { | 231 - (void)infobarWillClose { |
215 [self disablePopUpMenu:[dropdownButton_ menu]]; | 232 [self disablePopUpMenu:[dropdownButton_ menu]]; |
216 [super infobarWillClose]; | 233 [super infobarWillClose]; |
217 } | 234 } |
218 | 235 |
219 - (void)extensionViewFrameChanged { | 236 - (void)extensionViewFrameChanged { |
220 [self adjustExtensionViewSize]; | 237 [self adjustExtensionViewSize]; |
221 [self infobar]->SetBarTargetHeight([self clampedExtensionViewHeight]); | 238 [self infobar]->SetBarTargetHeight([self clampedExtensionViewHeight]); |
222 } | 239 } |
223 | 240 |
224 - (CGFloat)clampedExtensionViewHeight { | 241 - (CGFloat)clampedExtensionViewHeight { |
225 CGFloat height = [self delegate]->AsExtensionInfoBarDelegate()->height(); | 242 CGFloat height = [self delegate]->AsExtensionInfoBarDelegate()->height(); |
226 return std::max(kToolbarMinHeightPx, std::min(height, kToolbarMaxHeightPx)); | 243 return std::max(kToolbarMinHeightPx, std::min(height, kToolbarMaxHeightPx)); |
227 } | 244 } |
228 | 245 |
229 - (void)adjustExtensionViewSize { | 246 - (void)adjustExtensionViewSize { |
230 [extensionView_ setPostsFrameChangedNotifications:NO]; | 247 [extensionView_ setPostsFrameChangedNotifications:NO]; |
231 NSSize extensionViewSize = [extensionView_ frame].size; | 248 NSSize extensionViewSize = [extensionView_ frame].size; |
232 extensionViewSize.width = NSWidth([[self view] frame]); | 249 extensionViewSize.width = NSWidth([window_ frame]); |
233 extensionViewSize.height = [self clampedExtensionViewHeight]; | 250 extensionViewSize.height = [self clampedExtensionViewHeight]; |
234 [extensionView_ setFrameSize:extensionViewSize]; | 251 [extensionView_ setFrameSize:extensionViewSize]; |
235 [extensionView_ setPostsFrameChangedNotifications:YES]; | 252 [extensionView_ setPostsFrameChangedNotifications:YES]; |
236 } | 253 } |
237 | 254 |
238 - (void)setButtonImage:(NSImage*)image { | 255 - (void)setButtonImage:(NSImage*)image { |
239 [dropdownButton_ setImage:image]; | 256 [dropdownButton_ setImage:image]; |
240 } | 257 } |
241 | 258 |
242 - (void)menuNeedsUpdate:(NSMenu*)menu { | 259 - (void)menuNeedsUpdate:(NSMenu*)menu { |
243 DCHECK([self isOwned]); | |
244 | |
245 if (!contextMenuController_) { | |
246 extensions::ExtensionViewHost* extensionViewHost = | |
247 [self delegate]->AsExtensionInfoBarDelegate()->extension_view_host(); | |
248 Browser* browser = chrome::FindBrowserWithWebContents( | |
249 [self infobar]->OwnerCocoa()->web_contents()); | |
250 contextMenuController_.reset([[ExtensionActionContextMenuController alloc] | |
251 initWithExtension:extensionViewHost->extension() | |
252 browser:browser | |
253 extensionAction:NULL]); | |
254 } | |
255 | |
256 [menu removeAllItems]; | 260 [menu removeAllItems]; |
257 [contextMenuController_ populateMenu:menu]; | 261 [contextMenuController_ populateMenu:menu]; |
258 } | 262 } |
259 | 263 |
260 @end | 264 @end |
261 | 265 |
262 // static | 266 InfoBar* ExtensionInfoBarDelegate::CreateInfoBar(InfoBarService* owner) { |
263 scoped_ptr<InfoBar> ExtensionInfoBarDelegate::CreateInfoBar( | 267 scoped_ptr<InfoBarCocoa> infobar(new InfoBarCocoa(owner, this)); |
264 scoped_ptr<ExtensionInfoBarDelegate> delegate) { | 268 NSWindow* window = |
265 scoped_ptr<InfoBarCocoa> infobar( | 269 [(NSView*)owner->web_contents()->GetView()->GetContentNativeView() |
266 new InfoBarCocoa(delegate.PassAs<InfoBarDelegate>())); | 270 window]; |
267 base::scoped_nsobject<ExtensionInfoBarController> controller( | 271 base::scoped_nsobject<ExtensionInfoBarController> controller( |
268 [[ExtensionInfoBarController alloc] initWithInfoBar:infobar.get()]); | 272 [[ExtensionInfoBarController alloc] initWithInfoBar:infobar.get() |
| 273 window:window]); |
269 infobar->set_controller(controller); | 274 infobar->set_controller(controller); |
270 return infobar.PassAs<InfoBar>(); | 275 return infobar.release(); |
271 } | 276 } |
OLD | NEW |