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