Chromium Code Reviews| 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/theme_resources.h" |
| 13 #include "grit/ui_resources.h" | 13 #include "grit/ui_resources.h" |
| 14 #include "third_party/skia/include/core/SkBitmap.h" | 14 #include "third_party/skia/include/core/SkBitmap.h" |
| 15 #include "third_party/skia/include/core/SkCanvas.h" | 15 #include "third_party/skia/include/core/SkCanvas.h" |
| 16 #include "third_party/skia/include/core/SkDevice.h" | 16 #include "third_party/skia/include/core/SkDevice.h" |
| 17 #include "third_party/skia/include/core/SkPaint.h" | 17 #include "third_party/skia/include/core/SkPaint.h" |
| 18 #include "third_party/skia/include/effects/SkGradientShader.h" | 18 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 19 #include "ui/base/animation/animation_delegate.h" | 19 #include "ui/base/animation/animation_delegate.h" |
| 20 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
| 21 #include "ui/gfx/canvas.h" | 21 #include "ui/gfx/canvas.h" |
| 22 #include "ui/gfx/color_utils.h" | 22 #include "ui/gfx/color_utils.h" |
| 23 #include "ui/gfx/image/canvas_image_source.h" | |
| 24 #include "ui/gfx/image/image_skia.h" | |
| 25 #include "ui/gfx/image/image_skia_source.h" | |
| 23 #include "ui/gfx/rect.h" | 26 #include "ui/gfx/rect.h" |
| 27 #include "ui/gfx/size.h" | |
| 24 #include "ui/gfx/image/image_skia_source.h" | 28 #include "ui/gfx/image/image_skia_source.h" |
| 25 #include "ui/gfx/skbitmap_operations.h" | 29 #include "ui/gfx/skbitmap_operations.h" |
| 26 | 30 |
| 27 namespace { | 31 namespace { |
| 28 | 32 |
| 29 // Different platforms need slightly different constants to look good. | 33 // Different platforms need slightly different constants to look good. |
| 30 #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) | 34 #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) |
| 31 const float kTextSize = 9.0; | 35 const float kTextSize = 9.0; |
| 32 const int kBottomMargin = 0; | 36 const int kBottomMargin = 0; |
| 33 const int kPadding = 2; | 37 const int kPadding = 2; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 49 // The padding between the top of the badge and the top of the text. | 53 // The padding between the top of the badge and the top of the text. |
| 50 const int kTopTextPadding = -1; | 54 const int kTopTextPadding = -1; |
| 51 #endif | 55 #endif |
| 52 | 56 |
| 53 const int kBadgeHeight = 11; | 57 const int kBadgeHeight = 11; |
| 54 const int kMaxTextWidth = 23; | 58 const int kMaxTextWidth = 23; |
| 55 // The minimum width for center-aligning the badge. | 59 // The minimum width for center-aligning the badge. |
| 56 const int kCenterAlignThreshold = 20; | 60 const int kCenterAlignThreshold = 20; |
| 57 | 61 |
| 58 | 62 |
| 59 int Width(const gfx::Image& image) { | 63 int Width(const gfx::ImageSkia& image) { |
| 60 if (image.IsEmpty()) | 64 return image.size().width(); |
|
Jeffrey Yasskin
2012/08/09 21:39:04
Once this function is a single expression, it's pr
tbarzic
2012/08/10 06:24:08
Done.
| |
| 61 return 0; | |
| 62 return image.ToSkBitmap()->width(); | |
| 63 } | 65 } |
| 64 | 66 |
| 65 class GetAttentionImageSource : public gfx::ImageSkiaSource { | 67 class GetAttentionImageSource : public gfx::ImageSkiaSource { |
| 66 public: | 68 public: |
| 67 explicit GetAttentionImageSource(const gfx::Image& icon) | 69 explicit GetAttentionImageSource(const gfx::ImageSkia& icon) |
| 68 : icon_(*icon.ToImageSkia()) {} | 70 : icon_(icon) {} |
| 69 | 71 |
| 70 // gfx::ImageSkiaSource overrides: | 72 // gfx::ImageSkiaSource overrides: |
| 71 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) | 73 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) |
| 72 OVERRIDE { | 74 OVERRIDE { |
| 73 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale_factor); | 75 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale_factor); |
| 74 color_utils::HSL shift = {-1, 0, 0.5}; | 76 color_utils::HSL shift = {-1, 0, 0.5}; |
| 75 return gfx::ImageSkiaRep( | 77 return gfx::ImageSkiaRep( |
| 76 SkBitmapOperations::CreateHSLShiftedBitmap(icon_rep.sk_bitmap(), shift), | 78 SkBitmapOperations::CreateHSLShiftedBitmap(icon_rep.sk_bitmap(), shift), |
| 77 icon_rep.scale_factor()); | 79 icon_rep.scale_factor()); |
| 78 } | 80 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 108 Done(); | 110 Done(); |
| 109 } | 111 } |
| 110 | 112 |
| 111 void Done() { | 113 void Done() { |
| 112 delete this; | 114 delete this; |
| 113 } | 115 } |
| 114 | 116 |
| 115 IconAnimation animation_; | 117 IconAnimation animation_; |
| 116 }; | 118 }; |
| 117 | 119 |
| 120 // TODO(tbarzic): Merge AnimationIconImageSource and IconAnimation together. | |
| 121 // Source for painting animated skia image. | |
| 122 class ExtensionAction::AnimatedIconImageSource : public gfx::ImageSkiaSource { | |
| 123 public: | |
| 124 AnimatedIconImageSource(const gfx::ImageSkia& image, | |
| 125 IconAnimationWrapper* animation) | |
| 126 : image_(image), | |
| 127 animation_(animation->AsWeakPtr()) { | |
| 128 } | |
| 129 | |
| 130 private: | |
| 131 virtual ~AnimatedIconImageSource() {} | |
| 132 | |
| 133 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale) OVERRIDE { | |
| 134 gfx::ImageSkiaRep original_rep = image_.GetRepresentation(scale); | |
| 135 if (!animation_) | |
| 136 return original_rep; | |
| 137 | |
| 138 // Original representation's scale factor may be different from scale | |
|
Jeffrey Yasskin
2012/08/09 21:39:04
It would be nice if CanvasImageSource supported th
tbarzic
2012/08/10 06:24:08
yep.. TODO already added :)
| |
| 139 // factor passed to this method. We want to use the former (since we are | |
| 140 // using bitmap for that scale). | |
| 141 return gfx::ImageSkiaRep( | |
| 142 animation_->animation()->Apply(original_rep.sk_bitmap()), | |
| 143 original_rep.scale_factor()); | |
| 144 } | |
| 145 | |
| 146 gfx::ImageSkia image_; | |
| 147 base::WeakPtr<IconAnimationWrapper> animation_; | |
| 148 | |
| 149 DISALLOW_COPY_AND_ASSIGN(AnimatedIconImageSource); | |
| 150 }; | |
| 151 | |
| 152 // CanvasImageSource for creating browser action icon with a badge. | |
| 153 class ExtensionAction::IconWithBadgeImageSource | |
| 154 : public gfx::CanvasImageSource { | |
| 155 public: | |
| 156 IconWithBadgeImageSource(const gfx::ImageSkia& icon, | |
| 157 const gfx::Size& spacing, | |
| 158 const std::string& text, | |
| 159 const SkColor& text_color, | |
| 160 const SkColor& background_color) | |
| 161 : gfx::CanvasImageSource(icon.size(), false), | |
| 162 icon_(icon), | |
| 163 spacing_(spacing), | |
| 164 text_(text), | |
| 165 text_color_(text_color), | |
| 166 background_color_(background_color) { | |
| 167 } | |
| 168 | |
| 169 virtual ~IconWithBadgeImageSource() {} | |
| 170 | |
| 171 private: | |
| 172 virtual void Draw(gfx::Canvas* canvas) OVERRIDE { | |
| 173 canvas->DrawImageInt(icon_, 0, 0, SkPaint()); | |
| 174 | |
| 175 gfx::Rect bounds(size_.width() + spacing_.width(), | |
| 176 size_.height() + spacing_.height()); | |
| 177 | |
| 178 // Draw a badge on the provided browser action icon's canvas. | |
| 179 ExtensionAction::DoPaintBadge(canvas, bounds, text_, text_color_, | |
| 180 background_color_, size_.width()); | |
| 181 } | |
| 182 | |
| 183 // Browser action icon image. | |
| 184 gfx::ImageSkia icon_; | |
| 185 // Extra spacing for badge compared to icon bounds. | |
| 186 gfx::Size spacing_; | |
| 187 // Text to be displayed on the badge. | |
| 188 std::string text_; | |
| 189 // Color of badge text. | |
| 190 SkColor text_color_; | |
| 191 // Color of the badge. | |
| 192 SkColor background_color_; | |
| 193 | |
| 194 DISALLOW_COPY_AND_ASSIGN(IconWithBadgeImageSource); | |
| 195 }; | |
| 196 | |
| 197 | |
| 118 const int ExtensionAction::kDefaultTabId = -1; | 198 const int ExtensionAction::kDefaultTabId = -1; |
| 119 | 199 |
| 120 ExtensionAction::IconAnimation::IconAnimation( | 200 ExtensionAction::IconAnimation::IconAnimation( |
| 121 ui::AnimationDelegate* delegate) | 201 ui::AnimationDelegate* delegate) |
| 122 // 100ms animation at 50fps (so 5 animation frames in total). | 202 // 100ms animation at 50fps (so 5 animation frames in total). |
| 123 : ui::LinearAnimation(100, 50, delegate) {} | 203 : ui::LinearAnimation(100, 50, delegate) {} |
| 124 | 204 |
| 125 ExtensionAction::IconAnimation::~IconAnimation() {} | 205 ExtensionAction::IconAnimation::~IconAnimation() {} |
| 126 | 206 |
| 127 const SkBitmap& ExtensionAction::IconAnimation::Apply( | 207 const SkBitmap& ExtensionAction::IconAnimation::Apply( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 return !GetPopupUrl(tab_id).is_empty(); | 292 return !GetPopupUrl(tab_id).is_empty(); |
| 213 } | 293 } |
| 214 | 294 |
| 215 GURL ExtensionAction::GetPopupUrl(int tab_id) const { | 295 GURL ExtensionAction::GetPopupUrl(int tab_id) const { |
| 216 return GetValue(&popup_url_, tab_id); | 296 return GetValue(&popup_url_, tab_id); |
| 217 } | 297 } |
| 218 | 298 |
| 219 void ExtensionAction::CacheIcon(const std::string& path, | 299 void ExtensionAction::CacheIcon(const std::string& path, |
| 220 const gfx::Image& icon) { | 300 const gfx::Image& icon) { |
| 221 if (!icon.IsEmpty()) | 301 if (!icon.IsEmpty()) |
| 222 path_to_icon_cache_.insert(std::make_pair(path, icon)); | 302 path_to_icon_cache_.insert(std::make_pair(path, *icon.ToImageSkia())); |
| 223 } | 303 } |
| 224 | 304 |
| 225 void ExtensionAction::SetIcon(int tab_id, const SkBitmap& bitmap) { | 305 void ExtensionAction::SetIcon(int tab_id, const gfx::Image& image) { |
| 226 SetValue(&icon_, tab_id, gfx::Image(bitmap)); | 306 SetValue(&icon_, tab_id, *image.ToImageSkia()); |
| 227 } | 307 } |
| 228 | 308 |
| 229 gfx::Image ExtensionAction::GetIcon(int tab_id) const { | 309 gfx::Image ExtensionAction::GetIcon(int tab_id) const { |
| 230 // Check if a specific icon is set for this tab. | 310 // Check if a specific icon is set for this tab. |
| 231 gfx::Image icon = GetValue(&icon_, tab_id); | 311 gfx::ImageSkia icon = GetValue(&icon_, tab_id); |
| 232 if (icon.IsEmpty()) { | 312 if (icon.empty()) { |
| 233 // Need to find an icon from a path. | 313 // Need to find an icon from a path. |
| 234 const std::string* path = NULL; | 314 const std::string* path = NULL; |
| 235 // Check if one of the elements of icon_path() was selected. | 315 // Check if one of the elements of icon_path() was selected. |
| 236 int icon_index = GetIconIndex(tab_id); | 316 int icon_index = GetIconIndex(tab_id); |
| 237 if (icon_index >= 0) { | 317 if (icon_index >= 0) { |
| 238 path = &icon_paths()->at(icon_index); | 318 path = &icon_paths()->at(icon_index); |
| 239 } else { | 319 } else { |
| 240 // Otherwise, use the default icon. | 320 // Otherwise, use the default icon. |
| 241 path = &default_icon_path(); | 321 path = &default_icon_path(); |
| 242 } | 322 } |
| 243 | 323 |
| 244 std::map<std::string, gfx::Image>::const_iterator cached_icon = | 324 std::map<std::string, gfx::ImageSkia>::const_iterator cached_icon = |
| 245 path_to_icon_cache_.find(*path); | 325 path_to_icon_cache_.find(*path); |
| 246 if (cached_icon != path_to_icon_cache_.end()) { | 326 if (cached_icon != path_to_icon_cache_.end()) { |
| 247 icon = cached_icon->second; | 327 icon = cached_icon->second; |
| 248 } else { | 328 } else { |
| 249 icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | 329 icon = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 250 IDR_EXTENSIONS_FAVICON); | 330 IDR_EXTENSIONS_FAVICON); |
| 251 } | 331 } |
| 252 } | 332 } |
| 253 | 333 |
| 254 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION) { | 334 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION) |
| 255 icon = gfx::Image(gfx::ImageSkia(new GetAttentionImageSource(icon), | 335 icon = gfx::ImageSkia(new GetAttentionImageSource(icon), icon.size()); |
| 256 icon.ToImageSkia()->size())); | |
| 257 } | |
| 258 | 336 |
| 259 return ApplyIconAnimation(tab_id, icon); | 337 return gfx::Image(ApplyIconAnimation(tab_id, icon)); |
| 260 } | 338 } |
| 261 | 339 |
| 262 void ExtensionAction::SetIconIndex(int tab_id, int index) { | 340 void ExtensionAction::SetIconIndex(int tab_id, int index) { |
| 263 if (static_cast<size_t>(index) >= icon_paths_.size()) { | 341 if (static_cast<size_t>(index) >= icon_paths_.size()) { |
| 264 NOTREACHED(); | 342 NOTREACHED(); |
| 265 return; | 343 return; |
| 266 } | 344 } |
| 267 SetValue(&icon_index_, tab_id, index); | 345 SetValue(&icon_index_, tab_id, index); |
| 268 } | 346 } |
| 269 | 347 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 292 badge_text_.erase(tab_id); | 370 badge_text_.erase(tab_id); |
| 293 badge_text_color_.erase(tab_id); | 371 badge_text_color_.erase(tab_id); |
| 294 badge_background_color_.erase(tab_id); | 372 badge_background_color_.erase(tab_id); |
| 295 appearance_.erase(tab_id); | 373 appearance_.erase(tab_id); |
| 296 icon_animation_.erase(tab_id); | 374 icon_animation_.erase(tab_id); |
| 297 } | 375 } |
| 298 | 376 |
| 299 void ExtensionAction::PaintBadge(gfx::Canvas* canvas, | 377 void ExtensionAction::PaintBadge(gfx::Canvas* canvas, |
| 300 const gfx::Rect& bounds, | 378 const gfx::Rect& bounds, |
| 301 int tab_id) { | 379 int tab_id) { |
| 302 std::string text = GetBadgeText(tab_id); | 380 ExtensionAction::DoPaintBadge( |
| 381 canvas, | |
| 382 bounds, | |
| 383 GetBadgeText(tab_id), | |
| 384 GetBadgeTextColor(tab_id), | |
| 385 GetBadgeBackgroundColor(tab_id), | |
| 386 Width(GetValue(&icon_, tab_id))); | |
| 387 } | |
| 388 | |
| 389 gfx::ImageSkia ExtensionAction::GetIconWithBadge( | |
| 390 const gfx::ImageSkia& icon, | |
| 391 int tab_id, | |
| 392 const gfx::Size& spacing) const { | |
| 393 if (tab_id < 0) | |
| 394 return icon; | |
| 395 | |
| 396 return gfx::ImageSkia( | |
| 397 new IconWithBadgeImageSource(icon, | |
| 398 spacing, | |
| 399 GetBadgeText(tab_id), | |
| 400 GetBadgeTextColor(tab_id), | |
| 401 GetBadgeBackgroundColor(tab_id)), | |
| 402 icon.size()); | |
| 403 } | |
| 404 | |
| 405 // static | |
| 406 void ExtensionAction::DoPaintBadge(gfx::Canvas* canvas, | |
| 407 const gfx::Rect& bounds, | |
| 408 const std::string& text, | |
| 409 const SkColor& text_color_in, | |
| 410 const SkColor& background_color_in, | |
| 411 int icon_width) { | |
| 303 if (text.empty()) | 412 if (text.empty()) |
| 304 return; | 413 return; |
| 305 | 414 |
| 306 SkColor text_color = GetBadgeTextColor(tab_id); | 415 SkColor text_color = (SkColorGetA(text_color_in) == 0x00) ? |
|
Jeffrey Yasskin
2012/08/09 21:39:04
Interesting. I would probably have kept the if sta
tbarzic
2012/08/10 06:24:08
Done.
| |
| 307 SkColor background_color = GetBadgeBackgroundColor(tab_id); | 416 SK_ColorWHITE : text_color_in; |
| 308 | 417 |
| 309 if (SkColorGetA(text_color) == 0x00) | 418 SkColor background_color = (SkColorGetA(background_color_in) == 0x00) ? |
| 310 text_color = SK_ColorWHITE; | 419 SkColorSetARGB(255, 218, 0, 24) : background_color_in; |
| 311 | |
| 312 if (SkColorGetA(background_color) == 0x00) | |
| 313 background_color = SkColorSetARGB(255, 218, 0, 24); // Default badge color. | |
| 314 | 420 |
| 315 canvas->Save(); | 421 canvas->Save(); |
| 316 | 422 |
| 317 SkPaint* text_paint = badge_util::GetBadgeTextPaintSingleton(); | 423 SkPaint* text_paint = badge_util::GetBadgeTextPaintSingleton(); |
| 318 text_paint->setTextSize(SkFloatToScalar(kTextSize)); | 424 text_paint->setTextSize(SkFloatToScalar(kTextSize)); |
| 319 text_paint->setColor(text_color); | 425 text_paint->setColor(text_color); |
| 320 | 426 |
| 321 // Calculate text width. We clamp it to a max size. | 427 // Calculate text width. We clamp it to a max size. |
| 322 SkScalar text_width = text_paint->measureText(text.c_str(), text.size()); | 428 SkScalar sk_text_width = text_paint->measureText(text.c_str(), text.size()); |
| 323 text_width = SkIntToScalar( | 429 int text_width = std::min(kMaxTextWidth, SkScalarFloor(sk_text_width)); |
| 324 std::min(kMaxTextWidth, SkScalarFloor(text_width))); | |
| 325 | 430 |
| 326 // Calculate badge size. It is clamped to a min width just because it looks | 431 // Calculate badge size. It is clamped to a min width just because it looks |
| 327 // silly if it is too skinny. | 432 // silly if it is too skinny. |
| 328 int badge_width = SkScalarFloor(text_width) + kPadding * 2; | 433 int badge_width = text_width + kPadding * 2; |
| 329 int icon_width = Width(GetValue(&icon_, tab_id)); | |
| 330 // Force the pixel width of badge to be either odd (if the icon width is odd) | 434 // Force the pixel width of badge to be either odd (if the icon width is odd) |
| 331 // or even otherwise. If there is a mismatch you get http://crbug.com/26400. | 435 // or even otherwise. If there is a mismatch you get http://crbug.com/26400. |
| 332 if (icon_width != 0 && (badge_width % 2 != icon_width % 2)) | 436 if (icon_width != 0 && (badge_width % 2 != icon_width % 2)) |
| 333 badge_width += 1; | 437 badge_width += 1; |
| 334 badge_width = std::max(kBadgeHeight, badge_width); | 438 badge_width = std::max(kBadgeHeight, badge_width); |
| 335 | 439 |
| 336 // Paint the badge background color in the right location. It is usually | 440 // Paint the badge background color in the right location. It is usually |
| 337 // right-aligned, but it can also be center-aligned if it is large. | 441 // right-aligned, but it can also be center-aligned if it is large. |
| 338 SkRect rect; | 442 int rect_height = kBadgeHeight; |
| 339 rect.fBottom = SkIntToScalar(bounds.bottom() - kBottomMargin); | 443 int rect_y = bounds.bottom() - kBottomMargin - kBadgeHeight; |
| 340 rect.fTop = rect.fBottom - SkIntToScalar(kBadgeHeight); | 444 int rect_width = badge_width; |
| 341 if (badge_width >= kCenterAlignThreshold) { | 445 int rect_x = (badge_width >= kCenterAlignThreshold) ? |
| 342 rect.fLeft = SkIntToScalar( | 446 (bounds.x() + bounds.width()) / 2 - badge_width / 2 : |
| 343 SkScalarFloor(SkIntToScalar(bounds.x()) + | 447 bounds.right() - badge_width; |
| 344 SkIntToScalar(bounds.width()) / 2 - | 448 gfx::Rect rect(rect_x, rect_y, rect_width, rect_height); |
| 345 SkIntToScalar(badge_width) / 2)); | |
| 346 rect.fRight = rect.fLeft + SkIntToScalar(badge_width); | |
| 347 } else { | |
| 348 rect.fRight = SkIntToScalar(bounds.right()); | |
| 349 rect.fLeft = rect.fRight - badge_width; | |
| 350 } | |
| 351 | 449 |
| 352 SkPaint rect_paint; | 450 SkPaint rect_paint; |
| 353 rect_paint.setStyle(SkPaint::kFill_Style); | 451 rect_paint.setStyle(SkPaint::kFill_Style); |
| 354 rect_paint.setAntiAlias(true); | 452 rect_paint.setAntiAlias(true); |
| 355 rect_paint.setColor(background_color); | 453 rect_paint.setColor(background_color); |
| 356 canvas->sk_canvas()->drawRoundRect(rect, SkIntToScalar(2), | 454 canvas->DrawRoundRect(rect, 2, rect_paint); |
| 357 SkIntToScalar(2), rect_paint); | |
| 358 | 455 |
| 359 // Overlay the gradient. It is stretchy, so we do this in three parts. | 456 // Overlay the gradient. It is stretchy, so we do this in three parts. |
| 360 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 457 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 361 SkBitmap* gradient_left = rb.GetBitmapNamed(IDR_BROWSER_ACTION_BADGE_LEFT); | 458 gfx::ImageSkia* gradient_left = rb.GetImageSkiaNamed( |
| 362 SkBitmap* gradient_right = rb.GetBitmapNamed(IDR_BROWSER_ACTION_BADGE_RIGHT); | 459 IDR_BROWSER_ACTION_BADGE_LEFT); |
| 363 SkBitmap* gradient_center = rb.GetBitmapNamed( | 460 gfx::ImageSkia* gradient_right = rb.GetImageSkiaNamed( |
| 461 IDR_BROWSER_ACTION_BADGE_RIGHT); | |
| 462 gfx::ImageSkia* gradient_center = rb.GetImageSkiaNamed( | |
| 364 IDR_BROWSER_ACTION_BADGE_CENTER); | 463 IDR_BROWSER_ACTION_BADGE_CENTER); |
| 365 | 464 |
| 366 canvas->sk_canvas()->drawBitmap(*gradient_left, rect.fLeft, rect.fTop); | 465 canvas->DrawImageInt(*gradient_left, rect.x(), rect.y()); |
| 367 canvas->TileImageInt(*gradient_center, | 466 canvas->TileImageInt(*gradient_center, |
| 368 SkScalarFloor(rect.fLeft) + gradient_left->width(), | 467 rect.x() + gradient_left->width(), |
| 369 SkScalarFloor(rect.fTop), | 468 rect.y(), |
| 370 SkScalarFloor(rect.width()) - gradient_left->width() - | 469 rect.width() - gradient_left->width() - gradient_right->width(), |
| 371 gradient_right->width(), | 470 rect.height()); |
| 372 SkScalarFloor(rect.height())); | 471 canvas->DrawImageInt(*gradient_right, |
| 373 canvas->sk_canvas()->drawBitmap(*gradient_right, | 472 rect.right() - gradient_right->width(), rect.y()); |
| 374 rect.fRight - SkIntToScalar(gradient_right->width()), rect.fTop); | |
| 375 | 473 |
| 376 // Finally, draw the text centered within the badge. We set a clip in case the | 474 // Finally, draw the text centered within the badge. We set a clip in case the |
| 377 // text was too large. | 475 // text was too large. |
| 378 rect.fLeft += kPadding; | 476 rect.Inset(kPadding, 0); |
| 379 rect.fRight -= kPadding; | 477 canvas->ClipRect(rect); |
| 380 canvas->sk_canvas()->clipRect(rect); | |
| 381 canvas->sk_canvas()->drawText(text.c_str(), text.size(), | 478 canvas->sk_canvas()->drawText(text.c_str(), text.size(), |
| 382 rect.fLeft + (rect.width() - text_width) / 2, | 479 rect.x() + (rect.width() - text_width) / 2, |
| 383 rect.fTop + kTextSize + kTopTextPadding, | 480 rect.y() + kTextSize + kTopTextPadding, |
| 384 *text_paint); | 481 *text_paint); |
| 385 canvas->Restore(); | 482 canvas->Restore(); |
| 386 } | 483 } |
| 387 | 484 |
| 388 ExtensionAction::IconAnimationWrapper* ExtensionAction::GetIconAnimationWrapper( | 485 ExtensionAction::IconAnimationWrapper* ExtensionAction::GetIconAnimationWrapper( |
| 389 int tab_id) const { | 486 int tab_id) const { |
| 390 std::map<int, base::WeakPtr<IconAnimationWrapper> >::iterator it = | 487 std::map<int, base::WeakPtr<IconAnimationWrapper> >::iterator it = |
| 391 icon_animation_.find(tab_id); | 488 icon_animation_.find(tab_id); |
| 392 if (it == icon_animation_.end()) | 489 if (it == icon_animation_.end()) |
| 393 return NULL; | 490 return NULL; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 408 return NULL; | 505 return NULL; |
| 409 } | 506 } |
| 410 | 507 |
| 411 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation( | 508 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation( |
| 412 int tab_id) const { | 509 int tab_id) const { |
| 413 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id); | 510 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id); |
| 414 return wrapper ? wrapper->animation()->AsWeakPtr() | 511 return wrapper ? wrapper->animation()->AsWeakPtr() |
| 415 : base::WeakPtr<IconAnimation>(); | 512 : base::WeakPtr<IconAnimation>(); |
| 416 } | 513 } |
| 417 | 514 |
| 418 gfx::Image ExtensionAction::ApplyIconAnimation(int tab_id, | 515 gfx::ImageSkia ExtensionAction::ApplyIconAnimation( |
| 419 const gfx::Image& orig) const { | 516 int tab_id, |
| 420 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id); | 517 const gfx::ImageSkia& icon) const { |
| 421 if (wrapper == NULL) | 518 IconAnimationWrapper* animation_wrapper = GetIconAnimationWrapper(tab_id); |
| 422 return orig; | 519 if (animation_wrapper == NULL) |
| 423 return gfx::Image(wrapper->animation()->Apply(*orig.ToSkBitmap())); | 520 return icon; |
| 521 | |
| 522 return gfx::ImageSkia(new AnimatedIconImageSource(icon, animation_wrapper), | |
| 523 icon.size()); | |
| 424 } | 524 } |
| 425 | 525 |
| 426 void ExtensionAction::RunIconAnimation(int tab_id) { | 526 void ExtensionAction::RunIconAnimation(int tab_id) { |
| 427 IconAnimationWrapper* icon_animation = | 527 IconAnimationWrapper* icon_animation = |
| 428 new IconAnimationWrapper(); | 528 new IconAnimationWrapper(); |
| 429 icon_animation_[tab_id] = icon_animation->AsWeakPtr(); | 529 icon_animation_[tab_id] = icon_animation->AsWeakPtr(); |
| 430 icon_animation->animation()->Start(); | 530 icon_animation->animation()->Start(); |
| 431 } | 531 } |
| OLD | NEW |