| 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 #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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "chrome/common/badge_util.h" | 10 #include "chrome/common/badge_util.h" |
| 11 #include "googleurl/src/gurl.h" | 11 #include "googleurl/src/gurl.h" |
| 12 #include "grit/theme_resources.h" |
| 12 #include "grit/ui_resources.h" | 13 #include "grit/ui_resources.h" |
| 13 #include "third_party/skia/include/core/SkBitmap.h" | 14 #include "third_party/skia/include/core/SkBitmap.h" |
| 14 #include "third_party/skia/include/core/SkCanvas.h" | 15 #include "third_party/skia/include/core/SkCanvas.h" |
| 15 #include "third_party/skia/include/core/SkDevice.h" | 16 #include "third_party/skia/include/core/SkDevice.h" |
| 16 #include "third_party/skia/include/core/SkPaint.h" | 17 #include "third_party/skia/include/core/SkPaint.h" |
| 17 #include "third_party/skia/include/effects/SkGradientShader.h" | 18 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 18 #include "ui/base/animation/animation_delegate.h" | 19 #include "ui/base/animation/animation_delegate.h" |
| 19 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
| 20 #include "ui/gfx/canvas.h" | 21 #include "ui/gfx/canvas.h" |
| 21 #include "ui/gfx/rect.h" | 22 #include "ui/gfx/rect.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 45 // The padding between the top of the badge and the top of the text. | 46 // The padding between the top of the badge and the top of the text. |
| 46 const int kTopTextPadding = -1; | 47 const int kTopTextPadding = -1; |
| 47 #endif | 48 #endif |
| 48 | 49 |
| 49 const int kBadgeHeight = 11; | 50 const int kBadgeHeight = 11; |
| 50 const int kMaxTextWidth = 23; | 51 const int kMaxTextWidth = 23; |
| 51 // The minimum width for center-aligning the badge. | 52 // The minimum width for center-aligning the badge. |
| 52 const int kCenterAlignThreshold = 20; | 53 const int kCenterAlignThreshold = 20; |
| 53 | 54 |
| 54 | 55 |
| 56 int Width(const gfx::Image& image) { |
| 57 if (image.IsEmpty()) |
| 58 return 0; |
| 59 return image.ToSkBitmap()->width(); |
| 60 } |
| 61 |
| 55 } // namespace | 62 } // namespace |
| 56 | 63 |
| 57 // Wraps an IconAnimation and implements its ui::AnimationDelegate to erase the | 64 // Wraps an IconAnimation and implements its ui::AnimationDelegate to erase the |
| 58 // animation from a map when the animation ends or is cancelled, causing itself | 65 // animation from a map when the animation ends or is cancelled, causing itself |
| 59 // and its owned IconAnimation to be deleted. | 66 // and its owned IconAnimation to be deleted. |
| 60 class ExtensionAction::IconAnimationWrapper : public ui::AnimationDelegate { | 67 class ExtensionAction::IconAnimationWrapper : public ui::AnimationDelegate { |
| 61 public: | 68 public: |
| 62 IconAnimationWrapper(ExtensionAction* owner, int tab_id) | 69 IconAnimationWrapper(ExtensionAction* owner, int tab_id) |
| 63 : owner_(owner), | 70 : owner_(owner), |
| 64 tab_id_(tab_id), | 71 tab_id_(tab_id), |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 } | 190 } |
| 184 | 191 |
| 185 bool ExtensionAction::HasPopup(int tab_id) const { | 192 bool ExtensionAction::HasPopup(int tab_id) const { |
| 186 return !GetPopupUrl(tab_id).is_empty(); | 193 return !GetPopupUrl(tab_id).is_empty(); |
| 187 } | 194 } |
| 188 | 195 |
| 189 GURL ExtensionAction::GetPopupUrl(int tab_id) const { | 196 GURL ExtensionAction::GetPopupUrl(int tab_id) const { |
| 190 return GetValue(&popup_url_, tab_id); | 197 return GetValue(&popup_url_, tab_id); |
| 191 } | 198 } |
| 192 | 199 |
| 193 void ExtensionAction::SetIcon(int tab_id, const SkBitmap& bitmap) { | 200 void ExtensionAction::CacheIcon(const std::string& path, |
| 194 SetValue(&icon_, tab_id, bitmap); | 201 const gfx::Image& icon) { |
| 202 if (!icon.IsEmpty()) |
| 203 path_to_icon_cache_.insert(std::make_pair(path, icon)); |
| 195 } | 204 } |
| 196 | 205 |
| 197 SkBitmap ExtensionAction::GetIcon(int tab_id) const { | 206 void ExtensionAction::SetIcon(int tab_id, const SkBitmap& bitmap) { |
| 198 return GetValue(&icon_, tab_id); | 207 SetValue(&icon_, tab_id, gfx::Image(bitmap)); |
| 208 } |
| 209 |
| 210 gfx::Image ExtensionAction::GetIcon(int tab_id) const { |
| 211 // Check if a specific icon is set for this tab. |
| 212 gfx::Image icon = GetValue(&icon_, tab_id); |
| 213 if (icon.IsEmpty()) { |
| 214 // Need to find an icon from a path. |
| 215 const std::string* path = NULL; |
| 216 // Check if one of the elements of icon_path() was selected. |
| 217 int icon_index = GetIconIndex(tab_id); |
| 218 if (icon_index >= 0) { |
| 219 path = &icon_paths()->at(icon_index); |
| 220 } else { |
| 221 // Otherwise, use the default icon. |
| 222 path = &default_icon_path(); |
| 223 } |
| 224 |
| 225 std::map<std::string, gfx::Image>::const_iterator cached_icon = |
| 226 path_to_icon_cache_.find(*path); |
| 227 if (cached_icon != path_to_icon_cache_.end()) { |
| 228 icon = cached_icon->second; |
| 229 } else { |
| 230 icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| 231 IDR_EXTENSIONS_FAVICON); |
| 232 } |
| 233 } |
| 234 |
| 235 return ApplyIconAnimation(tab_id, icon); |
| 199 } | 236 } |
| 200 | 237 |
| 201 void ExtensionAction::SetIconIndex(int tab_id, int index) { | 238 void ExtensionAction::SetIconIndex(int tab_id, int index) { |
| 202 if (static_cast<size_t>(index) >= icon_paths_.size()) { | 239 if (static_cast<size_t>(index) >= icon_paths_.size()) { |
| 203 NOTREACHED(); | 240 NOTREACHED(); |
| 204 return; | 241 return; |
| 205 } | 242 } |
| 206 SetValue(&icon_index_, tab_id, index); | 243 SetValue(&icon_index_, tab_id, index); |
| 207 } | 244 } |
| 208 | 245 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 text_paint->setColor(text_color); | 278 text_paint->setColor(text_color); |
| 242 | 279 |
| 243 // Calculate text width. We clamp it to a max size. | 280 // Calculate text width. We clamp it to a max size. |
| 244 SkScalar text_width = text_paint->measureText(text.c_str(), text.size()); | 281 SkScalar text_width = text_paint->measureText(text.c_str(), text.size()); |
| 245 text_width = SkIntToScalar( | 282 text_width = SkIntToScalar( |
| 246 std::min(kMaxTextWidth, SkScalarFloor(text_width))); | 283 std::min(kMaxTextWidth, SkScalarFloor(text_width))); |
| 247 | 284 |
| 248 // Calculate badge size. It is clamped to a min width just because it looks | 285 // Calculate badge size. It is clamped to a min width just because it looks |
| 249 // silly if it is too skinny. | 286 // silly if it is too skinny. |
| 250 int badge_width = SkScalarFloor(text_width) + kPadding * 2; | 287 int badge_width = SkScalarFloor(text_width) + kPadding * 2; |
| 251 int icon_width = GetIcon(tab_id).width(); | 288 int icon_width = Width(GetValue(&icon_, tab_id)); |
| 252 // Force the pixel width of badge to be either odd (if the icon width is odd) | 289 // Force the pixel width of badge to be either odd (if the icon width is odd) |
| 253 // or even otherwise. If there is a mismatch you get http://crbug.com/26400. | 290 // or even otherwise. If there is a mismatch you get http://crbug.com/26400. |
| 254 if (icon_width != 0 && (badge_width % 2 != GetIcon(tab_id).width() % 2)) | 291 if (icon_width != 0 && (badge_width % 2 != icon_width % 2)) |
| 255 badge_width += 1; | 292 badge_width += 1; |
| 256 badge_width = std::max(kBadgeHeight, badge_width); | 293 badge_width = std::max(kBadgeHeight, badge_width); |
| 257 | 294 |
| 258 // Paint the badge background color in the right location. It is usually | 295 // Paint the badge background color in the right location. It is usually |
| 259 // right-aligned, but it can also be center-aligned if it is large. | 296 // right-aligned, but it can also be center-aligned if it is large. |
| 260 SkRect rect; | 297 SkRect rect; |
| 261 rect.fBottom = SkIntToScalar(bounds.bottom() - kBottomMargin); | 298 rect.fBottom = SkIntToScalar(bounds.bottom() - kBottomMargin); |
| 262 rect.fTop = rect.fBottom - SkIntToScalar(kBadgeHeight); | 299 rect.fTop = rect.fBottom - SkIntToScalar(kBadgeHeight); |
| 263 if (badge_width >= kCenterAlignThreshold) { | 300 if (badge_width >= kCenterAlignThreshold) { |
| 264 rect.fLeft = SkIntToScalar( | 301 rect.fLeft = SkIntToScalar( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 } | 345 } |
| 309 | 346 |
| 310 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation( | 347 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation( |
| 311 int tab_id) const { | 348 int tab_id) const { |
| 312 std::map<int, linked_ptr<IconAnimationWrapper> >::const_iterator it = | 349 std::map<int, linked_ptr<IconAnimationWrapper> >::const_iterator it = |
| 313 icon_animation_.find(tab_id); | 350 icon_animation_.find(tab_id); |
| 314 return (it != icon_animation_.end()) ? it->second->animation()->AsWeakPtr() | 351 return (it != icon_animation_.end()) ? it->second->animation()->AsWeakPtr() |
| 315 : base::WeakPtr<IconAnimation>(); | 352 : base::WeakPtr<IconAnimation>(); |
| 316 } | 353 } |
| 317 | 354 |
| 355 gfx::Image ExtensionAction::ApplyIconAnimation(int tab_id, |
| 356 const gfx::Image& orig) const { |
| 357 std::map<int, linked_ptr<IconAnimationWrapper> >::const_iterator it = |
| 358 icon_animation_.find(tab_id); |
| 359 if (it == icon_animation_.end()) |
| 360 return orig; |
| 361 return gfx::Image(it->second->animation()->Apply(*orig.ToSkBitmap())); |
| 362 } |
| 363 |
| 318 void ExtensionAction::RunIconAnimation(int tab_id) { | 364 void ExtensionAction::RunIconAnimation(int tab_id) { |
| 319 IconAnimationWrapper* icon_animation = | 365 IconAnimationWrapper* icon_animation = |
| 320 new IconAnimationWrapper(this, tab_id); | 366 new IconAnimationWrapper(this, tab_id); |
| 321 icon_animation_[tab_id] = make_linked_ptr(icon_animation); | 367 icon_animation_[tab_id] = make_linked_ptr(icon_animation); |
| 322 icon_animation->animation()->Start(); | 368 icon_animation->animation()->Start(); |
| 323 } | 369 } |
| OLD | NEW |