Index: chrome/common/extensions/extension_action.cc |
diff --git a/chrome/common/extensions/extension_action.cc b/chrome/common/extensions/extension_action.cc |
index 9df8905772c436650aa306670ca0f61cf2110778..a489aaf0257f6115a27e4ebd3a22a32e0fe90819 100644 |
--- a/chrome/common/extensions/extension_action.cc |
+++ b/chrome/common/extensions/extension_action.cc |
@@ -11,7 +11,11 @@ |
#include "googleurl/src/gurl.h" |
#include "grit/ui_resources.h" |
#include "third_party/skia/include/core/SkBitmap.h" |
+#include "third_party/skia/include/core/SkCanvas.h" |
+#include "third_party/skia/include/core/SkDevice.h" |
+#include "third_party/skia/include/core/SkPaint.h" |
#include "third_party/skia/include/effects/SkGradientShader.h" |
+#include "ui/base/animation/animation_delegate.h" |
#include "ui/base/resource/resource_bundle.h" |
#include "ui/gfx/canvas.h" |
#include "ui/gfx/rect.h" |
@@ -52,6 +56,47 @@ const int kCenterAlignThreshold = 20; |
const int ExtensionAction::kDefaultTabId = -1; |
+ExtensionAction::IconAnimation::IconAnimation( |
+ ui::AnimationDelegate* delegate) |
+ // 100ms animation at 50fps (so 5 animation frames in total). |
+ : ui::LinearAnimation(100, 50, delegate) {} |
+ |
+ExtensionAction::IconAnimation::~IconAnimation() {} |
+ |
+const SkBitmap& ExtensionAction::IconAnimation::Apply( |
+ const SkBitmap& icon) const { |
+ DCHECK_GT(icon.width(), 0); |
+ DCHECK_GT(icon.height(), 0); |
+ |
+ if (!device_.get() || |
+ (device_->width() != icon.width()) || |
+ (device_->height() != icon.height())) { |
+ device_.reset(new SkDevice( |
+ SkBitmap::kARGB_8888_Config, icon.width(), icon.height(), true)); |
+ } |
+ |
+ SkCanvas canvas(device_.get()); |
+ canvas.clear(SK_ColorWHITE); |
+ SkPaint paint; |
+ paint.setAlpha(CurrentValueBetween(0, 255)); |
+ canvas.drawBitmap(icon, 0, 0, &paint); |
+ return device_->accessBitmap(false); |
+} |
+ |
+void ExtensionAction::IconAnimation::AddObserver( |
+ ExtensionAction::IconAnimation::Observer* observer) { |
+ observers_.AddObserver(observer); |
+} |
+ |
+void ExtensionAction::IconAnimation::RemoveObserver( |
+ ExtensionAction::IconAnimation::Observer* observer) { |
+ observers_.RemoveObserver(observer); |
+} |
+ |
+void ExtensionAction::IconAnimation::AnimateToState(double state) { |
+ FOR_EACH_OBSERVER(Observer, observers_, OnIconChanged(*this)); |
+} |
+ |
ExtensionAction::ExtensionAction(const std::string& extension_id, |
Type action_type) |
: extension_id_(extension_id), |
@@ -95,6 +140,7 @@ void ExtensionAction::SetIconIndex(int tab_id, int index) { |
} |
void ExtensionAction::ClearAllValuesForTab(int tab_id) { |
+ popup_url_.erase(tab_id); |
title_.erase(tab_id); |
icon_.erase(tab_id); |
icon_index_.erase(tab_id); |
@@ -102,7 +148,7 @@ void ExtensionAction::ClearAllValuesForTab(int tab_id) { |
badge_text_color_.erase(tab_id); |
badge_background_color_.erase(tab_id); |
visible_.erase(tab_id); |
- popup_url_.erase(tab_id); |
+ icon_animation_.erase(tab_id); |
} |
void ExtensionAction::PaintBadge(gfx::Canvas* canvas, |
@@ -193,3 +239,53 @@ void ExtensionAction::PaintBadge(gfx::Canvas* canvas, |
*text_paint); |
canvas->Restore(); |
} |
+ |
+// Wraps an IconAnimation and implements its ui::AnimationDelegate to erase the |
+// animation from a map when the animation ends or is cancelled, causing itself |
+// and its owned IconAnimation to be deleted. |
+class ExtensionAction::IconAnimationWrapper : public ui::AnimationDelegate { |
+ public: |
+ IconAnimationWrapper(ExtensionAction* owner, int tab_id) |
+ : owner_(owner), |
+ tab_id_(tab_id), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) {} |
+ |
+ virtual ~IconAnimationWrapper() {} |
+ |
+ IconAnimation* animation() { |
+ return &animation_; |
+ } |
+ |
+ private: |
+ virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE { |
+ Done(); |
+ } |
+ |
+ virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE { |
+ Done(); |
+ } |
+ |
+ void Done() { |
+ owner_->icon_animation_.erase(tab_id_); |
+ // this will now have been deleted. |
+ } |
+ |
+ ExtensionAction* owner_; |
+ int tab_id_; |
+ IconAnimation animation_; |
+}; |
+ |
+base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation( |
Yoyo Zhou
2012/06/26 18:38:15
nit: Group ExtensionAnimation functions together i
not at google - send to devlin
2012/06/27 06:26:54
I don't understand what this means; they are group
Yoyo Zhou
2012/06/27 06:28:25
Between ExtensionAction::PaintBadge and ExtensionA
|
+ int tab_id) const { |
+ std::map<int, linked_ptr<IconAnimationWrapper> >::const_iterator it = |
+ icon_animation_.find(tab_id); |
+ return (it != icon_animation_.end()) ? it->second->animation()->AsWeakPtr() |
+ : base::WeakPtr<IconAnimation>(); |
+} |
+ |
+void ExtensionAction::RunIconAnimation(int tab_id) { |
+ IconAnimationWrapper* icon_animation = |
+ new IconAnimationWrapper(this, tab_id); |
+ icon_animation_[tab_id] = make_linked_ptr(icon_animation); |
+ icon_animation->animation()->Start(); |
+} |