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