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/extensions/browser_action_button.h" | 5 #import "chrome/browser/ui/cocoa/extensions/browser_action_button.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 } // anonymous namespace | 43 } // anonymous namespace |
44 | 44 |
45 // A helper class to bridge the asynchronous Skia bitmap loading mechanism to | 45 // A helper class to bridge the asynchronous Skia bitmap loading mechanism to |
46 // the extension's button. | 46 // the extension's button. |
47 class ExtensionImageTrackerBridge : public content::NotificationObserver, | 47 class ExtensionImageTrackerBridge : public content::NotificationObserver, |
48 public ImageLoadingTracker::Observer { | 48 public ImageLoadingTracker::Observer { |
49 public: | 49 public: |
50 ExtensionImageTrackerBridge(BrowserActionButton* owner, | 50 ExtensionImageTrackerBridge(BrowserActionButton* owner, |
51 const Extension* extension) | 51 const Extension* extension) |
52 : owner_(owner), | 52 : owner_(owner), |
53 tracker_(this) { | 53 tracker_(this), |
54 extension_(extension) { | |
54 // The Browser Action API does not allow the default icon path to be | 55 // The Browser Action API does not allow the default icon path to be |
55 // changed at runtime, so we can load this now and cache it. | 56 // changed at runtime, so we can load this now and cache it. |
56 std::string path = extension->browser_action()->default_icon_path(); | 57 std::string path = extension->browser_action()->default_icon_path(); |
57 if (!path.empty()) { | 58 if (!path.empty()) { |
58 tracker_.LoadImage(extension, extension->GetResource(path), | 59 tracker_.LoadImage(extension, extension->GetResource(path), |
59 gfx::Size(Extension::kBrowserActionIconMaxSize, | 60 gfx::Size(Extension::kBrowserActionIconMaxSize, |
60 Extension::kBrowserActionIconMaxSize), | 61 Extension::kBrowserActionIconMaxSize), |
61 ImageLoadingTracker::DONT_CACHE); | 62 ImageLoadingTracker::DONT_CACHE); |
62 } else { | |
63 // Set the icon to be the default extensions icon. | |
64 SkBitmap bm = *ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
65 IDR_EXTENSIONS_FAVICON); | |
66 [owner_ setDefaultIcon:gfx::SkBitmapToNSImage(bm)]; | |
67 [owner_ updateState]; | |
Jeffrey Yasskin
2012/07/25 19:45:26
This updateState call is provided by the function
| |
68 } | 63 } |
69 registrar_.Add( | 64 registrar_.Add( |
70 this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED, | 65 this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED, |
71 content::Source<ExtensionAction>(extension->browser_action())); | 66 content::Source<ExtensionAction>(extension->browser_action())); |
72 } | 67 } |
73 | 68 |
74 ~ExtensionImageTrackerBridge() {} | 69 ~ExtensionImageTrackerBridge() {} |
75 | 70 |
71 const ExtensionAction::PathToIconCache& loaded_icons() const { | |
72 return loaded_icons_; | |
73 } | |
74 | |
76 // ImageLoadingTracker::Observer implementation. | 75 // ImageLoadingTracker::Observer implementation. |
77 void OnImageLoaded(const gfx::Image& image, | 76 void OnImageLoaded(const gfx::Image& image, |
78 const std::string& extension_id, | 77 const std::string& extension_id, |
79 int index) OVERRIDE { | 78 int index) OVERRIDE { |
80 if (!image.IsEmpty()) | 79 if (!image.IsEmpty()) |
81 [owner_ setDefaultIcon:image.ToNSImage()]; | 80 loaded_icons_[extension_->browser_action()->default_icon_path()] = image; |
82 [owner_ updateState]; | 81 [owner_ updateState]; |
83 } | 82 } |
84 | 83 |
85 // Overridden from content::NotificationObserver. | 84 // Overridden from content::NotificationObserver. |
86 void Observe(int type, | 85 void Observe(int type, |
87 const content::NotificationSource& source, | 86 const content::NotificationSource& source, |
88 const content::NotificationDetails& details) { | 87 const content::NotificationDetails& details) { |
89 if (type == chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED) | 88 if (type == chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED) |
90 [owner_ updateState]; | 89 [owner_ updateState]; |
91 else | 90 else |
92 NOTREACHED(); | 91 NOTREACHED(); |
93 } | 92 } |
94 | 93 |
95 private: | 94 private: |
96 // Weak. Owns us. | 95 // Weak. Owns us. |
97 BrowserActionButton* owner_; | 96 BrowserActionButton* owner_; |
98 | 97 |
99 // Loads the button's icons for us on the file thread. | 98 // Loads the button's icons for us on the file thread. |
100 ImageLoadingTracker tracker_; | 99 ImageLoadingTracker tracker_; |
101 | 100 |
101 // The extension whose images we're loading. | |
102 const Extension* const extension_; | |
not at google - send to devlin
2012/07/26 02:29:44
We only ever access extension_->browser_action(),
Jeffrey Yasskin
2012/07/26 21:11:47
Good point. Turned this into the browser action.
| |
103 | |
104 // Icons loaded from paths. Currently just the browser action's default icon. | |
105 ExtensionAction::PathToIconCache loaded_icons_; | |
106 | |
102 // Used for registering to receive notifications and automatic clean up. | 107 // Used for registering to receive notifications and automatic clean up. |
103 content::NotificationRegistrar registrar_; | 108 content::NotificationRegistrar registrar_; |
104 | 109 |
105 DISALLOW_COPY_AND_ASSIGN(ExtensionImageTrackerBridge); | 110 DISALLOW_COPY_AND_ASSIGN(ExtensionImageTrackerBridge); |
106 }; | 111 }; |
107 | 112 |
108 @interface BrowserActionCell (Internals) | 113 @interface BrowserActionCell (Internals) |
109 - (void)drawBadgeWithinFrame:(NSRect)frame; | 114 - (void)drawBadgeWithinFrame:(NSRect)frame; |
110 @end | 115 @end |
111 | 116 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 self, NSViewAnimationTargetKey, | 239 self, NSViewAnimationTargetKey, |
235 [NSValue valueWithRect:[self frame]], NSViewAnimationStartFrameKey, | 240 [NSValue valueWithRect:[self frame]], NSViewAnimationStartFrameKey, |
236 [NSValue valueWithRect:frameRect], NSViewAnimationEndFrameKey, | 241 [NSValue valueWithRect:frameRect], NSViewAnimationEndFrameKey, |
237 nil]; | 242 nil]; |
238 [moveAnimation_ setViewAnimations: | 243 [moveAnimation_ setViewAnimations: |
239 [NSArray arrayWithObject:animationDictionary]]; | 244 [NSArray arrayWithObject:animationDictionary]]; |
240 [moveAnimation_ startAnimation]; | 245 [moveAnimation_ startAnimation]; |
241 } | 246 } |
242 } | 247 } |
243 | 248 |
244 - (void)setDefaultIcon:(NSImage*)image { | |
245 defaultIcon_.reset([image retain]); | |
246 } | |
247 | |
248 - (void)setTabSpecificIcon:(NSImage*)image { | |
249 tabSpecificIcon_.reset([image retain]); | |
250 } | |
251 | |
252 - (void)updateState { | 249 - (void)updateState { |
253 if (tabId_ < 0) | 250 if (tabId_ < 0) |
254 return; | 251 return; |
255 | 252 |
256 std::string tooltip = extension_->browser_action()->GetTitle(tabId_); | 253 std::string tooltip = extension_->browser_action()->GetTitle(tabId_); |
257 if (tooltip.empty()) { | 254 if (tooltip.empty()) { |
258 [self setToolTip:nil]; | 255 [self setToolTip:nil]; |
259 } else { | 256 } else { |
260 [self setToolTip:base::SysUTF8ToNSString(tooltip)]; | 257 [self setToolTip:base::SysUTF8ToNSString(tooltip)]; |
261 } | 258 } |
262 | 259 |
263 SkBitmap image = extension_->browser_action()->GetIcon(tabId_); | 260 gfx::Image image = extension_->browser_action()->GetIcon( |
264 if (!image.isNull()) { | 261 tabId_, imageLoadingBridge_->loaded_icons()); |
265 [self setTabSpecificIcon:gfx::SkBitmapToNSImage(image)]; | 262 if (!image.IsEmpty()) { |
266 [self setImage:tabSpecificIcon_]; | 263 [self setImage:image.ToNSImage()]; |
not at google - send to devlin
2012/07/26 02:29:44
nit: no {}
Jeffrey Yasskin
2012/07/26 21:11:47
Done.
| |
267 } else if (defaultIcon_) { | |
268 [self setImage:defaultIcon_]; | |
269 } | 264 } |
270 | 265 |
271 [[self cell] setTabId:tabId_]; | 266 [[self cell] setTabId:tabId_]; |
272 | 267 |
273 bool enabled = extension_->browser_action()->GetIsVisible(tabId_); | 268 bool enabled = extension_->browser_action()->GetIsVisible(tabId_); |
274 [self setEnabled:enabled ? YES : NO]; | 269 [self setEnabled:enabled ? YES : NO]; |
275 | 270 |
276 [self setNeedsDisplay:YES]; | 271 [self setNeedsDisplay:YES]; |
277 } | 272 } |
278 | 273 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 } | 317 } |
323 | 318 |
324 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 319 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
325 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | 320 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
326 [super drawInteriorWithFrame:cellFrame inView:controlView]; | 321 [super drawInteriorWithFrame:cellFrame inView:controlView]; |
327 cellFrame.origin.y += kBrowserActionBadgeOriginYOffset; | 322 cellFrame.origin.y += kBrowserActionBadgeOriginYOffset; |
328 [self drawBadgeWithinFrame:cellFrame]; | 323 [self drawBadgeWithinFrame:cellFrame]; |
329 } | 324 } |
330 | 325 |
331 @end | 326 @end |
OLD | NEW |