Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: chrome/common/extensions/extension_action.cc

Issue 10905005: Change browser/page action default icon defined in manifest to support hidpi. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "chrome/common/extensions/extension_action.h" 5 #include "chrome/common/extensions/extension_action.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "chrome/common/badge_util.h" 12 #include "chrome/common/badge_util.h"
13 #include "chrome/common/extensions/extension_constants.h"
13 #include "googleurl/src/gurl.h" 14 #include "googleurl/src/gurl.h"
14 #include "grit/theme_resources.h" 15 #include "grit/theme_resources.h"
15 #include "grit/ui_resources.h" 16 #include "grit/ui_resources.h"
16 #include "third_party/skia/include/core/SkBitmap.h" 17 #include "third_party/skia/include/core/SkBitmap.h"
17 #include "third_party/skia/include/core/SkCanvas.h" 18 #include "third_party/skia/include/core/SkCanvas.h"
18 #include "third_party/skia/include/core/SkDevice.h" 19 #include "third_party/skia/include/core/SkDevice.h"
19 #include "third_party/skia/include/core/SkPaint.h" 20 #include "third_party/skia/include/core/SkPaint.h"
20 #include "third_party/skia/include/effects/SkGradientShader.h" 21 #include "third_party/skia/include/effects/SkGradientShader.h"
21 #include "ui/base/animation/animation_delegate.h" 22 #include "ui/base/animation/animation_delegate.h"
22 #include "ui/base/resource/resource_bundle.h" 23 #include "ui/base/resource/resource_bundle.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 const int kPadding = 2; 55 const int kPadding = 2;
55 // The padding between the top of the badge and the top of the text. 56 // The padding between the top of the badge and the top of the text.
56 const int kTopTextPadding = -1; 57 const int kTopTextPadding = -1;
57 #endif 58 #endif
58 59
59 const int kBadgeHeight = 11; 60 const int kBadgeHeight = 11;
60 const int kMaxTextWidth = 23; 61 const int kMaxTextWidth = 23;
61 // The minimum width for center-aligning the badge. 62 // The minimum width for center-aligning the badge.
62 const int kCenterAlignThreshold = 20; 63 const int kCenterAlignThreshold = 20;
63 64
65 void CopyExtensionIconSet(const ExtensionIconSet* from, ExtensionIconSet* to) {
Jeffrey Yasskin 2012/09/13 00:23:36 If we want this function, I suspect ExtensionIconS
tbarzic 2012/09/13 02:01:01 I don't think we want this functionality in produc
66 for (ExtensionIconSet::IconMap::const_iterator iter = from->map().begin();
67 iter != from->map().end();
68 ++iter) {
69 to->Add(iter->first, iter->second);
70 }
71 }
72
73 int GetDesiredIconSizeForActionType(ExtensionAction::Type type) {
74 switch (type) {
75 case ExtensionAction::TYPE_BROWSER:
76 case ExtensionAction::TYPE_PAGE:
77 return extension_misc::EXTENSION_ICON_ACTION;
78 case ExtensionAction::TYPE_SCRIPT_BADGE:
79 return extension_misc::EXTENSION_ICON_BITTY;
80 default:
81 NOTREACHED();
82 return 0;
83 }
84 }
85
86 gfx::ImageSkia GetIconFromIconSet(const ExtensionIconSet* icon_set,
Jeffrey Yasskin 2012/09/13 00:23:36 This function doesn't seem to pull its weight. I'd
tbarzic 2012/09/13 02:01:01 Done.
87 ExtensionIconFactoryDelegate* icon_factory,
88 ExtensionAction::Type type) {
89 if (!icon_set || !icon_factory)
90 return gfx::ImageSkia();
91
92 return icon_factory->GetIcon(icon_set, GetDesiredIconSizeForActionType(type));
93 }
94
64 class GetAttentionImageSource : public gfx::ImageSkiaSource { 95 class GetAttentionImageSource : public gfx::ImageSkiaSource {
65 public: 96 public:
66 explicit GetAttentionImageSource(const gfx::ImageSkia& icon) 97 explicit GetAttentionImageSource(const gfx::ImageSkia& icon)
67 : icon_(icon) {} 98 : icon_(icon) {}
68 99
69 // gfx::ImageSkiaSource overrides: 100 // gfx::ImageSkiaSource overrides:
70 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) 101 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor)
71 OVERRIDE { 102 OVERRIDE {
72 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale_factor); 103 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale_factor);
73 color_utils::HSL shift = {-1, 0, 0.5}; 104 color_utils::HSL shift = {-1, 0, 0.5};
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 new ExtensionAction(extension_id_, action_type_)); 278 new ExtensionAction(extension_id_, action_type_));
248 copy->popup_url_ = popup_url_; 279 copy->popup_url_ = popup_url_;
249 copy->title_ = title_; 280 copy->title_ = title_;
250 copy->icon_ = icon_; 281 copy->icon_ = icon_;
251 copy->icon_index_ = icon_index_; 282 copy->icon_index_ = icon_index_;
252 copy->badge_text_ = badge_text_; 283 copy->badge_text_ = badge_text_;
253 copy->badge_background_color_ = badge_background_color_; 284 copy->badge_background_color_ = badge_background_color_;
254 copy->badge_text_color_ = badge_text_color_; 285 copy->badge_text_color_ = badge_text_color_;
255 copy->appearance_ = appearance_; 286 copy->appearance_ = appearance_;
256 copy->icon_animation_ = icon_animation_; 287 copy->icon_animation_ = icon_animation_;
257 copy->default_icon_path_ = default_icon_path_;
258 copy->id_ = id_; 288 copy->id_ = id_;
259 copy->icon_paths_ = icon_paths_; 289
290 if (default_icon_.get()) {
291 scoped_ptr<ExtensionIconSet> default_icon(new ExtensionIconSet());
292 CopyExtensionIconSet(default_icon_.get(), default_icon.get());
293 copy->default_icon_ = default_icon.Pass();
294 }
295
296 for (size_t i = 0; i < page_action_icons_.size(); i++) {
297 scoped_ptr<ExtensionIconSet> page_action_icon(new ExtensionIconSet());
298 CopyExtensionIconSet(page_action_icons_[i], page_action_icon.get());
299 copy->AddPageActionIcon(page_action_icon.Pass());
300 }
301
260 return copy.Pass(); 302 return copy.Pass();
261 } 303 }
262 304
305 void ExtensionAction::AddPageActionIcon(scoped_ptr<ExtensionIconSet> icon_set) {
306 page_action_icons_.push_back(icon_set.release());
307 }
308
309 bool ExtensionAction::IsValidIconIndex(int index) const {
310 return index >= 0 && (static_cast<size_t>(index) < page_action_icons_.size());
311 }
312
263 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) { 313 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) {
264 // We store |url| even if it is empty, rather than removing a URL from the 314 // We store |url| even if it is empty, rather than removing a URL from the
265 // map. If an extension has a default popup, and removes it for a tab via 315 // map. If an extension has a default popup, and removes it for a tab via
266 // the API, we must remember that there is no popup for that specific tab. 316 // the API, we must remember that there is no popup for that specific tab.
267 // If we removed the tab's URL, GetPopupURL would incorrectly return the 317 // If we removed the tab's URL, GetPopupURL would incorrectly return the
268 // default URL. 318 // default URL.
269 SetValue(&popup_url_, tab_id, url); 319 SetValue(&popup_url_, tab_id, url);
270 } 320 }
271 321
272 bool ExtensionAction::HasPopup(int tab_id) const { 322 bool ExtensionAction::HasPopup(int tab_id) const {
273 return !GetPopupUrl(tab_id).is_empty(); 323 return !GetPopupUrl(tab_id).is_empty();
274 } 324 }
275 325
276 GURL ExtensionAction::GetPopupUrl(int tab_id) const { 326 GURL ExtensionAction::GetPopupUrl(int tab_id) const {
277 return GetValue(&popup_url_, tab_id); 327 return GetValue(&popup_url_, tab_id);
278 } 328 }
279 329
280 void ExtensionAction::CacheIcon(const std::string& path,
281 const gfx::Image& icon) {
282 if (!icon.IsEmpty())
283 path_to_icon_cache_.insert(std::make_pair(path, *icon.ToImageSkia()));
284 }
285
286 void ExtensionAction::SetIcon(int tab_id, const gfx::Image& image) { 330 void ExtensionAction::SetIcon(int tab_id, const gfx::Image& image) {
287 SetValue(&icon_, tab_id, image.AsImageSkia()); 331 SetValue(&icon_, tab_id, image.AsImageSkia());
288 } 332 }
289 333
290 gfx::Image ExtensionAction::GetIcon(int tab_id) const { 334 gfx::Image ExtensionAction::GetIcon(
335 int tab_id,
336 ExtensionIconFactoryDelegate* icon_factory) const {
291 // Check if a specific icon is set for this tab. 337 // Check if a specific icon is set for this tab.
292 gfx::ImageSkia icon = GetExplicitlySetIcon(tab_id); 338 gfx::ImageSkia icon = GetExplicitlySetIcon(tab_id);
293 if (icon.isNull()) { 339 if (icon.isNull()) {
294 // Need to find an icon from a path.
295 const std::string* path = NULL;
296 // Check if one of the elements of icon_path() was selected. 340 // Check if one of the elements of icon_path() was selected.
297 int icon_index = GetIconIndex(tab_id); 341 int icon_index = GetIconIndex(tab_id);
342 const ExtensionIconSet* icon_set = NULL;
298 if (icon_index >= 0) { 343 if (icon_index >= 0) {
299 path = &icon_paths()->at(icon_index); 344 icon_set = page_action_icons_[icon_index];
300 } else { 345 } else {
301 // Otherwise, use the default icon. 346 icon_set = default_icon_.get();
302 path = &default_icon_path();
303 } 347 }
304 348
305 std::map<std::string, gfx::ImageSkia>::const_iterator cached_icon = 349 icon = GetIconFromIconSet(icon_set, icon_factory, action_type());
306 path_to_icon_cache_.find(*path); 350
307 if (cached_icon != path_to_icon_cache_.end()) { 351 // Extension favicon is our last resort.
308 icon = cached_icon->second; 352 if (icon.isNull()) {
309 } else {
310 icon = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 353 icon = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
311 IDR_EXTENSIONS_FAVICON); 354 IDR_EXTENSIONS_FAVICON);
312 } 355 }
313 } 356 }
314 357
315 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION) 358 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION)
316 icon = gfx::ImageSkia(new GetAttentionImageSource(icon), icon.size()); 359 icon = gfx::ImageSkia(new GetAttentionImageSource(icon), icon.size());
317 360
318 return gfx::Image(ApplyIconAnimation(tab_id, icon)); 361 return gfx::Image(ApplyIconAnimation(tab_id, icon));
319 } 362 }
320 363
321 gfx::ImageSkia ExtensionAction::GetExplicitlySetIcon(int tab_id) const { 364 gfx::ImageSkia ExtensionAction::GetExplicitlySetIcon(int tab_id) const {
322 return GetValue(&icon_, tab_id); 365 return GetValue(&icon_, tab_id);
323 } 366 }
324 367
325 void ExtensionAction::SetIconIndex(int tab_id, int index) { 368 void ExtensionAction::SetIconIndex(int tab_id, int index) {
326 if (static_cast<size_t>(index) >= icon_paths_.size()) { 369 if (static_cast<size_t>(index) >= page_action_icons_.size()) {
327 NOTREACHED(); 370 NOTREACHED();
328 return; 371 return;
329 } 372 }
330 SetValue(&icon_index_, tab_id, index); 373 SetValue(&icon_index_, tab_id, index);
331 } 374 }
332 375
333 bool ExtensionAction::SetAppearance(int tab_id, Appearance new_appearance) { 376 bool ExtensionAction::SetAppearance(int tab_id, Appearance new_appearance) {
334 const Appearance old_appearance = GetValue(&appearance_, tab_id); 377 const Appearance old_appearance = GetValue(&appearance_, tab_id);
335 378
336 if (old_appearance == new_appearance) 379 if (old_appearance == new_appearance)
337 return false; 380 return false;
338 381
382 // Remeber icon width so it can be used for badge painting.
Jeffrey Yasskin 2012/09/13 00:23:36 This doesn't look like the width being rembered.
tbarzic 2012/09/13 02:01:01 Done.
339 SetValue(&appearance_, tab_id, new_appearance); 383 SetValue(&appearance_, tab_id, new_appearance);
340 384
341 // When showing a badge for the first time on a web page, fade it 385 // When showing a badge for the first time on a web page, fade it
342 // in. Other transitions happen instantly. 386 // in. Other transitions happen instantly.
343 if (old_appearance == INVISIBLE && tab_id != kDefaultTabId) { 387 if (old_appearance == INVISIBLE && tab_id != kDefaultTabId) {
344 RunIconAnimation(tab_id); 388 RunIconAnimation(tab_id);
345 } 389 }
346 390
347 return true; 391 return true;
348 } 392 }
(...skipping 12 matching lines...) Expand all
361 405
362 void ExtensionAction::PaintBadge(gfx::Canvas* canvas, 406 void ExtensionAction::PaintBadge(gfx::Canvas* canvas,
363 const gfx::Rect& bounds, 407 const gfx::Rect& bounds,
364 int tab_id) { 408 int tab_id) {
365 ExtensionAction::DoPaintBadge( 409 ExtensionAction::DoPaintBadge(
366 canvas, 410 canvas,
367 bounds, 411 bounds,
368 GetBadgeText(tab_id), 412 GetBadgeText(tab_id),
369 GetBadgeTextColor(tab_id), 413 GetBadgeTextColor(tab_id),
370 GetBadgeBackgroundColor(tab_id), 414 GetBadgeBackgroundColor(tab_id),
371 GetValue(&icon_, tab_id).size().width()); 415 GetIconWidth(tab_id));
372 } 416 }
373 417
374 gfx::ImageSkia ExtensionAction::GetIconWithBadge( 418 gfx::ImageSkia ExtensionAction::GetIconWithBadge(
375 const gfx::ImageSkia& icon, 419 const gfx::ImageSkia& icon,
376 int tab_id, 420 int tab_id,
377 const gfx::Size& spacing) const { 421 const gfx::Size& spacing) const {
378 if (tab_id < 0) 422 if (tab_id < 0)
379 return icon; 423 return icon;
380 424
381 return gfx::ImageSkia( 425 return gfx::ImageSkia(
382 new IconWithBadgeImageSource(icon, 426 new IconWithBadgeImageSource(icon,
383 spacing, 427 spacing,
384 GetBadgeText(tab_id), 428 GetBadgeText(tab_id),
385 GetBadgeTextColor(tab_id), 429 GetBadgeTextColor(tab_id),
386 GetBadgeBackgroundColor(tab_id)), 430 GetBadgeBackgroundColor(tab_id)),
387 icon.size()); 431 icon.size());
388 } 432 }
389 433
434 // Determines which icon would be returned by |GetIcon|, and returns its width.
435 int ExtensionAction:: GetIconWidth(int tab_id) const {
Jeffrey Yasskin 2012/09/13 00:23:36 No space between :: and the method name.
tbarzic 2012/09/13 02:01:01 Done.
436 // If icon has been set, return its width.
437 gfx::ImageSkia icon = GetValue(&icon_, tab_id);
438 if (!icon.isNull())
439 return icon.width();
440 // If page action icon has been set, or there is a default icon, the icon
441 // the icon width will be set depending on our action type.
Jeffrey Yasskin 2012/09/13 00:23:36 typo: "the icon the icon width"
tbarzic 2012/09/13 02:01:01 Done.
442 int icon_index = GetIconIndex(tab_id);
443 if (icon_index >= 0 || default_icon_.get())
444 return GetDesiredIconSizeForActionType(action_type());
445
446 // If no icon has been set and there is no default icon, we need favicon
447 // width.
448 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(
449 IDR_EXTENSIONS_FAVICON).ToImageSkia()->width();
450 }
451
390 // static 452 // static
391 void ExtensionAction::DoPaintBadge(gfx::Canvas* canvas, 453 void ExtensionAction::DoPaintBadge(gfx::Canvas* canvas,
392 const gfx::Rect& bounds, 454 const gfx::Rect& bounds,
393 const std::string& text, 455 const std::string& text,
394 const SkColor& text_color_in, 456 const SkColor& text_color_in,
395 const SkColor& background_color_in, 457 const SkColor& background_color_in,
396 int icon_width) { 458 int icon_width) {
397 if (text.empty()) 459 if (text.empty())
398 return; 460 return;
399 461
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 icon_animation->Start(); 577 icon_animation->Start();
516 // After the icon is finished fading in (plus some padding to handle random 578 // After the icon is finished fading in (plus some padding to handle random
517 // timer delays), destroy it. We use a delayed task so that the Animation is 579 // timer delays), destroy it. We use a delayed task so that the Animation is
518 // deleted even if it hasn't finished by the time the MessageLoop is 580 // deleted even if it hasn't finished by the time the MessageLoop is
519 // destroyed. 581 // destroyed.
520 MessageLoop::current()->PostDelayedTask( 582 MessageLoop::current()->PostDelayedTask(
521 FROM_HERE, 583 FROM_HERE,
522 base::Bind(&DestroyIconAnimation, base::Passed(icon_animation.Pass())), 584 base::Bind(&DestroyIconAnimation, base::Passed(icon_animation.Pass())),
523 base::TimeDelta::FromMilliseconds(kIconFadeInDurationMs * 2)); 585 base::TimeDelta::FromMilliseconds(kIconFadeInDurationMs * 2));
524 } 586 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698