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

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

Issue 10559054: Animate the script badges. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: rebase, fix thing i accidentally deleted in the last rebase Created 8 years, 5 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
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/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/ui_resources.h" 12 #include "grit/ui_resources.h"
13 #include "third_party/skia/include/core/SkBitmap.h" 13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "third_party/skia/include/core/SkDevice.h"
16 #include "third_party/skia/include/core/SkPaint.h"
14 #include "third_party/skia/include/effects/SkGradientShader.h" 17 #include "third_party/skia/include/effects/SkGradientShader.h"
18 #include "ui/base/animation/animation_delegate.h"
15 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/gfx/canvas.h" 20 #include "ui/gfx/canvas.h"
17 #include "ui/gfx/rect.h" 21 #include "ui/gfx/rect.h"
18 22
19 namespace { 23 namespace {
20 24
21 // Different platforms need slightly different constants to look good. 25 // Different platforms need slightly different constants to look good.
22 #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) 26 #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)
23 const float kTextSize = 9.0; 27 const float kTextSize = 9.0;
24 const int kBottomMargin = 0; 28 const int kBottomMargin = 0;
(...skipping 18 matching lines...) Expand all
43 #endif 47 #endif
44 48
45 const int kBadgeHeight = 11; 49 const int kBadgeHeight = 11;
46 const int kMaxTextWidth = 23; 50 const int kMaxTextWidth = 23;
47 // The minimum width for center-aligning the badge. 51 // The minimum width for center-aligning the badge.
48 const int kCenterAlignThreshold = 20; 52 const int kCenterAlignThreshold = 20;
49 53
50 54
51 } // namespace 55 } // namespace
52 56
57 // 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
59 // and its owned IconAnimation to be deleted.
60 class ExtensionAction::IconAnimationWrapper : public ui::AnimationDelegate {
61 public:
62 IconAnimationWrapper(ExtensionAction* owner, int tab_id)
63 : owner_(owner),
64 tab_id_(tab_id),
65 ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) {}
66
67 virtual ~IconAnimationWrapper() {}
68
69 IconAnimation* animation() {
70 return &animation_;
71 }
72
73 private:
74 virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE {
75 Done();
76 }
77
78 virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE {
79 Done();
80 }
81
82 void Done() {
83 owner_->icon_animation_.erase(tab_id_);
84 // this will now have been deleted.
85 }
86
87 ExtensionAction* owner_;
88 int tab_id_;
89 IconAnimation animation_;
90 };
91
53 const int ExtensionAction::kDefaultTabId = -1; 92 const int ExtensionAction::kDefaultTabId = -1;
54 93
94 ExtensionAction::IconAnimation::IconAnimation(
95 ui::AnimationDelegate* delegate)
96 // 100ms animation at 50fps (so 5 animation frames in total).
97 : ui::LinearAnimation(100, 50, delegate) {}
98
99 ExtensionAction::IconAnimation::~IconAnimation() {}
100
101 const SkBitmap& ExtensionAction::IconAnimation::Apply(
102 const SkBitmap& icon) const {
103 DCHECK_GT(icon.width(), 0);
104 DCHECK_GT(icon.height(), 0);
105
106 if (!device_.get() ||
107 (device_->width() != icon.width()) ||
108 (device_->height() != icon.height())) {
109 device_.reset(new SkDevice(
110 SkBitmap::kARGB_8888_Config, icon.width(), icon.height(), true));
111 }
112
113 SkCanvas canvas(device_.get());
114 canvas.clear(SK_ColorWHITE);
115 SkPaint paint;
116 paint.setAlpha(CurrentValueBetween(0, 255));
117 canvas.drawBitmap(icon, 0, 0, &paint);
118 return device_->accessBitmap(false);
119 }
120
121 void ExtensionAction::IconAnimation::AddObserver(
122 ExtensionAction::IconAnimation::Observer* observer) {
123 observers_.AddObserver(observer);
124 }
125
126 void ExtensionAction::IconAnimation::RemoveObserver(
127 ExtensionAction::IconAnimation::Observer* observer) {
128 observers_.RemoveObserver(observer);
129 }
130
131 void ExtensionAction::IconAnimation::AnimateToState(double state) {
132 FOR_EACH_OBSERVER(Observer, observers_, OnIconChanged(*this));
133 }
134
135 ExtensionAction::IconAnimation::ScopedObserver::ScopedObserver(
136 const base::WeakPtr<IconAnimation>& icon_animation,
137 Observer* observer)
138 : icon_animation_(icon_animation),
139 observer_(observer) {
140 if (icon_animation.get())
141 icon_animation->AddObserver(observer);
142 }
143
144 ExtensionAction::IconAnimation::ScopedObserver::~ScopedObserver() {
145 if (icon_animation_.get())
146 icon_animation_->RemoveObserver(observer_);
147 }
148
55 ExtensionAction::ExtensionAction(const std::string& extension_id, 149 ExtensionAction::ExtensionAction(const std::string& extension_id,
56 Type action_type) 150 Type action_type)
57 : extension_id_(extension_id), 151 : extension_id_(extension_id),
58 action_type_(action_type) { 152 action_type_(action_type) {
59 } 153 }
60 154
61 ExtensionAction::~ExtensionAction() { 155 ExtensionAction::~ExtensionAction() {
62 } 156 }
63 157
158 scoped_ptr<ExtensionAction> ExtensionAction::CopyForTest() const {
159 scoped_ptr<ExtensionAction> copy(
160 new ExtensionAction(extension_id_, action_type_));
161 copy->popup_url_ = popup_url_;
162 copy->title_ = title_;
163 copy->icon_ = icon_;
164 copy->icon_index_ = icon_index_;
165 copy->badge_text_ = badge_text_;
166 copy->badge_background_color_ = badge_background_color_;
167 copy->badge_text_color_ = badge_text_color_;
168 copy->visible_ = visible_;
169 copy->icon_animation_ = icon_animation_;
170 copy->default_icon_path_ = default_icon_path_;
171 copy->id_ = id_;
172 copy->icon_paths_ = icon_paths_;
173 return copy.Pass();
174 }
175
64 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) { 176 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) {
65 // We store |url| even if it is empty, rather than removing a URL from the 177 // We store |url| even if it is empty, rather than removing a URL from the
66 // map. If an extension has a default popup, and removes it for a tab via 178 // map. If an extension has a default popup, and removes it for a tab via
67 // the API, we must remember that there is no popup for that specific tab. 179 // the API, we must remember that there is no popup for that specific tab.
68 // If we removed the tab's URL, GetPopupURL would incorrectly return the 180 // If we removed the tab's URL, GetPopupURL would incorrectly return the
69 // default URL. 181 // default URL.
70 SetValue(&popup_url_, tab_id, url); 182 SetValue(&popup_url_, tab_id, url);
71 } 183 }
72 184
73 bool ExtensionAction::HasPopup(int tab_id) const { 185 bool ExtensionAction::HasPopup(int tab_id) const {
(...skipping 14 matching lines...) Expand all
88 200
89 void ExtensionAction::SetIconIndex(int tab_id, int index) { 201 void ExtensionAction::SetIconIndex(int tab_id, int index) {
90 if (static_cast<size_t>(index) >= icon_paths_.size()) { 202 if (static_cast<size_t>(index) >= icon_paths_.size()) {
91 NOTREACHED(); 203 NOTREACHED();
92 return; 204 return;
93 } 205 }
94 SetValue(&icon_index_, tab_id, index); 206 SetValue(&icon_index_, tab_id, index);
95 } 207 }
96 208
97 void ExtensionAction::ClearAllValuesForTab(int tab_id) { 209 void ExtensionAction::ClearAllValuesForTab(int tab_id) {
210 popup_url_.erase(tab_id);
98 title_.erase(tab_id); 211 title_.erase(tab_id);
99 icon_.erase(tab_id); 212 icon_.erase(tab_id);
100 icon_index_.erase(tab_id); 213 icon_index_.erase(tab_id);
101 badge_text_.erase(tab_id); 214 badge_text_.erase(tab_id);
102 badge_text_color_.erase(tab_id); 215 badge_text_color_.erase(tab_id);
103 badge_background_color_.erase(tab_id); 216 badge_background_color_.erase(tab_id);
104 visible_.erase(tab_id); 217 visible_.erase(tab_id);
105 popup_url_.erase(tab_id); 218 icon_animation_.erase(tab_id);
106 } 219 }
107 220
108 void ExtensionAction::PaintBadge(gfx::Canvas* canvas, 221 void ExtensionAction::PaintBadge(gfx::Canvas* canvas,
109 const gfx::Rect& bounds, 222 const gfx::Rect& bounds,
110 int tab_id) { 223 int tab_id) {
111 std::string text = GetBadgeText(tab_id); 224 std::string text = GetBadgeText(tab_id);
112 if (text.empty()) 225 if (text.empty())
113 return; 226 return;
114 227
115 SkColor text_color = GetBadgeTextColor(tab_id); 228 SkColor text_color = GetBadgeTextColor(tab_id);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 // text was too large. 299 // text was too large.
187 rect.fLeft += kPadding; 300 rect.fLeft += kPadding;
188 rect.fRight -= kPadding; 301 rect.fRight -= kPadding;
189 canvas->sk_canvas()->clipRect(rect); 302 canvas->sk_canvas()->clipRect(rect);
190 canvas->sk_canvas()->drawText(text.c_str(), text.size(), 303 canvas->sk_canvas()->drawText(text.c_str(), text.size(),
191 rect.fLeft + (rect.width() - text_width) / 2, 304 rect.fLeft + (rect.width() - text_width) / 2,
192 rect.fTop + kTextSize + kTopTextPadding, 305 rect.fTop + kTextSize + kTopTextPadding,
193 *text_paint); 306 *text_paint);
194 canvas->Restore(); 307 canvas->Restore();
195 } 308 }
309
310 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation(
311 int tab_id) const {
312 std::map<int, linked_ptr<IconAnimationWrapper> >::const_iterator it =
313 icon_animation_.find(tab_id);
314 return (it != icon_animation_.end()) ? it->second->animation()->AsWeakPtr()
315 : base::WeakPtr<IconAnimation>();
316 }
317
318 void ExtensionAction::RunIconAnimation(int tab_id) {
319 IconAnimationWrapper* icon_animation =
320 new IconAnimationWrapper(this, tab_id);
321 icon_animation_[tab_id] = make_linked_ptr(icon_animation);
322 icon_animation->animation()->Start();
323 }
OLDNEW
« no previous file with comments | « chrome/common/extensions/extension_action.h ('k') | chrome/common/extensions/extension_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698