OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/browser/views/browser_actions_container.h" | 5 #include "chrome/browser/views/browser_actions_container.h" |
6 | 6 |
7 #include "app/gfx/canvas.h" | 7 #include "app/gfx/canvas.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/stl_util-inl.h" | 9 #include "base/stl_util-inl.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "chrome/browser/extensions/extension_browser_event_router.h" | 11 #include "chrome/browser/extensions/extension_browser_event_router.h" |
12 #include "chrome/browser/extensions/extensions_service.h" | 12 #include "chrome/browser/extensions/extensions_service.h" |
13 #include "chrome/browser/extensions/extension_tabs_module.h" | 13 #include "chrome/browser/extensions/extension_tabs_module.h" |
14 #include "chrome/browser/profile.h" | 14 #include "chrome/browser/profile.h" |
15 #include "chrome/browser/view_ids.h" | 15 #include "chrome/browser/view_ids.h" |
16 #include "chrome/browser/views/extensions/extension_popup.h" | 16 #include "chrome/browser/views/extensions/extension_popup.h" |
17 #include "chrome/browser/views/toolbar_view.h" | 17 #include "chrome/browser/views/toolbar_view.h" |
18 #include "chrome/common/extensions/extension_action.h" | 18 #include "chrome/common/extensions/extension_action.h" |
| 19 #include "chrome/common/extensions/extension_action2.h" |
19 #include "chrome/common/notification_source.h" | 20 #include "chrome/common/notification_source.h" |
20 #include "chrome/common/notification_type.h" | 21 #include "chrome/common/notification_type.h" |
21 #include "grit/app_resources.h" | 22 #include "grit/app_resources.h" |
22 #include "third_party/skia/include/core/SkBitmap.h" | 23 #include "third_party/skia/include/core/SkBitmap.h" |
23 #include "third_party/skia/include/core/SkTypeface.h" | 24 #include "third_party/skia/include/core/SkTypeface.h" |
24 #include "third_party/skia/include/effects/SkGradientShader.h" | 25 #include "third_party/skia/include/effects/SkGradientShader.h" |
25 #include "views/controls/button/text_button.h" | 26 #include "views/controls/button/text_button.h" |
26 | 27 |
27 // The size (both dimensions) of the buttons for page actions. | 28 // The size (both dimensions) of the buttons for page actions. |
28 static const int kButtonSize = 29; | 29 static const int kButtonSize = 29; |
29 | 30 |
30 // The padding between the browser actions and the omnibox/page menu. | 31 // The padding between the browser actions and the omnibox/page menu. |
31 static const int kHorizontalPadding = 4; | 32 static const int kHorizontalPadding = 4; |
32 | 33 |
33 // This is the same value from toolbar.cc. We position the browser actions | 34 // This is the same value from toolbar.cc. We position the browser actions |
34 // container flush with the edges of the toolbar as a special case so that we | 35 // container flush with the edges of the toolbar as a special case so that we |
35 // can draw the badge outside the visual bounds of the container. | 36 // can draw the badge outside the visual bounds of the container. |
36 static const int kControlVertOffset = 6; | 37 static const int kControlVertOffset = 6; |
37 | 38 |
38 // The maximum of the minimum number of browser actions present when there is | 39 // The maximum of the minimum number of browser actions present when there is |
39 // not enough space to fit all the browser actions in the toolbar. | 40 // not enough space to fit all the browser actions in the toolbar. |
40 static const int kMinimumNumberOfVisibleBrowserActions = 2; | 41 static const int kMinimumNumberOfVisibleBrowserActions = 2; |
41 | 42 |
42 | 43 |
43 //////////////////////////////////////////////////////////////////////////////// | 44 //////////////////////////////////////////////////////////////////////////////// |
44 // BrowserActionButton | 45 // BrowserActionButton |
45 | 46 |
46 BrowserActionButton::BrowserActionButton( | 47 BrowserActionButton::BrowserActionButton(Extension* extension, |
47 ExtensionAction* browser_action, Extension* extension, | 48 BrowserActionsContainer* panel) |
48 BrowserActionsContainer* panel) | |
49 : MenuButton(this, L"", NULL, false), | 49 : MenuButton(this, L"", NULL, false), |
50 browser_action_(browser_action), | 50 browser_action_(extension->browser_action()), |
51 browser_action_state_(extension->browser_action_state()), | 51 extension_(extension), |
52 tracker_(NULL), | 52 tracker_(NULL), |
53 panel_(panel) { | 53 panel_(panel) { |
54 set_alignment(TextButton::ALIGN_CENTER); | 54 set_alignment(TextButton::ALIGN_CENTER); |
55 | 55 |
56 // Load the images this view needs asynchronously on the file thread. We'll | 56 // No UpdateState() here because View heirarchy not setup yet. Our parent |
57 // get a call back into OnImageLoaded if the image loads successfully. If not, | 57 // should call UpdateState() after creation. |
58 // the ImageView will have no image and will not appear in the browser chrome. | |
59 if (!browser_action->icon_paths().empty()) { | |
60 const std::vector<std::string>& icon_paths = browser_action->icon_paths(); | |
61 browser_action_icons_.resize(icon_paths.size()); | |
62 tracker_ = new ImageLoadingTracker(this, icon_paths.size()); | |
63 for (std::vector<std::string>::const_iterator iter = icon_paths.begin(); | |
64 iter != icon_paths.end(); ++iter) { | |
65 tracker_->PostLoadImageTask( | |
66 extension->GetResource(*iter), | |
67 gfx::Size(Extension::kBrowserActionIconMaxSize, | |
68 Extension::kBrowserActionIconMaxSize)); | |
69 } | |
70 } | |
71 | 58 |
72 registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED, | 59 registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED, |
73 Source<ExtensionAction>(browser_action_)); | 60 Source<ExtensionAction2>(browser_action_)); |
74 } | 61 } |
75 | 62 |
76 BrowserActionButton::~BrowserActionButton() { | 63 BrowserActionButton::~BrowserActionButton() { |
77 if (tracker_) { | 64 if (tracker_) { |
78 tracker_->StopTrackingImageLoad(); | 65 tracker_->StopTrackingImageLoad(); |
79 tracker_ = NULL; // The tracker object will be deleted when we return. | 66 tracker_ = NULL; // The tracker object will be deleted when we return. |
80 } | 67 } |
81 } | 68 } |
82 | 69 |
83 gfx::Insets BrowserActionButton::GetInsets() const { | 70 gfx::Insets BrowserActionButton::GetInsets() const { |
84 static gfx::Insets zero_inset; | 71 static gfx::Insets zero_inset; |
85 return zero_inset; | 72 return zero_inset; |
86 } | 73 } |
87 | 74 |
88 void BrowserActionButton::ButtonPressed( | 75 void BrowserActionButton::ButtonPressed( |
89 views::Button* sender, const views::Event& event) { | 76 views::Button* sender, const views::Event& event) { |
90 panel_->OnBrowserActionExecuted(this); | 77 panel_->OnBrowserActionExecuted(this); |
91 } | 78 } |
92 | 79 |
93 void BrowserActionButton::OnImageLoaded(SkBitmap* image, size_t index) { | 80 void BrowserActionButton::LoadImage() { |
94 DCHECK(index < browser_action_icons_.size()); | 81 // Load the default image from the browser action asynchronously on the file |
95 browser_action_icons_[index] = image ? *image : SkBitmap(); | 82 // thread. We'll get a call back into OnImageLoaded if the image loads |
96 if (index == browser_action_icons_.size() - 1) { | 83 // successfully. |
97 OnStateUpdated(); | 84 std::string relative_path = browser_action()->GetDefaultIconPath(); |
98 tracker_ = NULL; // The tracker object will delete itself when we return. | 85 if (relative_path.empty()) |
99 } | 86 return; |
| 87 |
| 88 tracker_ = new ImageLoadingTracker(this, 1); |
| 89 tracker_->PostLoadImageTask( |
| 90 extension()->GetResource(relative_path), |
| 91 gfx::Size(Extension::kBrowserActionIconMaxSize, |
| 92 Extension::kBrowserActionIconMaxSize)); |
100 } | 93 } |
101 | 94 |
102 void BrowserActionButton::OnStateUpdated() { | 95 void BrowserActionButton::OnImageLoaded(SkBitmap* image, size_t index) { |
103 SkBitmap* image = browser_action_state_->icon(); | 96 SetIcon(*image); |
104 if (!image) { | 97 tracker_ = NULL; // The tracker object will delete itself when we return. |
105 if (static_cast<size_t>(browser_action_state_->icon_index()) < | |
106 browser_action_icons_.size()) { | |
107 image = &browser_action_icons_[browser_action_state_->icon_index()]; | |
108 } | |
109 } | |
110 | |
111 if (image) | |
112 SetIcon(*image); | |
113 | |
114 SetTooltipText(ASCIIToWide(browser_action_state_->title())); | |
115 panel_->OnBrowserActionVisibilityChanged(); | |
116 GetParent()->SchedulePaint(); | 98 GetParent()->SchedulePaint(); |
117 } | 99 } |
118 | 100 |
| 101 void BrowserActionButton::UpdateState() { |
| 102 int tab_id = panel_->GetCurrentTabId(); |
| 103 if (tab_id < 0) |
| 104 return; |
| 105 |
| 106 SkBitmap image = browser_action()->GetIcon(tab_id); |
| 107 if (image.isNull()) |
| 108 LoadImage(); |
| 109 else |
| 110 SetIcon(image); |
| 111 |
| 112 SetTooltipText(ASCIIToWide(browser_action()->GetTitle(tab_id))); |
| 113 GetParent()->SchedulePaint(); |
| 114 } |
| 115 |
119 void BrowserActionButton::Observe(NotificationType type, | 116 void BrowserActionButton::Observe(NotificationType type, |
120 const NotificationSource& source, | 117 const NotificationSource& source, |
121 const NotificationDetails& details) { | 118 const NotificationDetails& details) { |
122 if (type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED) { | 119 if (type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED) { |
123 OnStateUpdated(); | 120 UpdateState(); |
124 } else { | 121 } else { |
125 NOTREACHED() << L"Received unexpected notification"; | 122 NOTREACHED() << L"Received unexpected notification"; |
126 } | 123 } |
127 } | 124 } |
128 | 125 |
129 bool BrowserActionButton::IsPopup() { | 126 bool BrowserActionButton::IsPopup() { |
130 return browser_action_->is_popup(); | 127 return browser_action_->has_popup(); |
131 } | 128 } |
132 | 129 |
133 bool BrowserActionButton::Activate() { | 130 bool BrowserActionButton::Activate() { |
134 if (IsPopup()) { | 131 if (IsPopup()) { |
135 panel_->OnBrowserActionExecuted(this); | 132 panel_->OnBrowserActionExecuted(this); |
136 | 133 |
137 // TODO(erikkay): Run a nested modal loop while the mouse is down to | 134 // TODO(erikkay): Run a nested modal loop while the mouse is down to |
138 // enable menu-like drag-select behavior. | 135 // enable menu-like drag-select behavior. |
139 | 136 |
140 // The return value of this method is returned via OnMousePressed. | 137 // The return value of this method is returned via OnMousePressed. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 | 180 |
184 void BrowserActionButton::PopupDidHide() { | 181 void BrowserActionButton::PopupDidHide() { |
185 SetState(views::CustomButton::BS_NORMAL); | 182 SetState(views::CustomButton::BS_NORMAL); |
186 menu_visible_ = false; | 183 menu_visible_ = false; |
187 } | 184 } |
188 | 185 |
189 | 186 |
190 //////////////////////////////////////////////////////////////////////////////// | 187 //////////////////////////////////////////////////////////////////////////////// |
191 // BrowserActionView | 188 // BrowserActionView |
192 | 189 |
193 BrowserActionView::BrowserActionView(ExtensionAction* browser_action, | 190 BrowserActionView::BrowserActionView(Extension* extension, |
194 Extension* extension, | 191 BrowserActionsContainer* panel) |
195 BrowserActionsContainer* panel) { | 192 : panel_(panel) { |
196 button_ = new BrowserActionButton(browser_action, extension, panel); | 193 button_ = new BrowserActionButton(extension, panel); |
197 AddChildView(button_); | 194 AddChildView(button_); |
| 195 button_->UpdateState(); |
198 } | 196 } |
199 | 197 |
200 void BrowserActionView::Layout() { | 198 void BrowserActionView::Layout() { |
201 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize); | 199 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize); |
202 } | 200 } |
203 | 201 |
204 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) { | 202 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) { |
205 View::PaintChildren(canvas); | 203 View::PaintChildren(canvas); |
206 button_->browser_action_state()->PaintBadge(canvas, | 204 ExtensionAction2* action = button()->browser_action(); |
207 gfx::Rect(width(), height())); | 205 int tab_id = panel_->GetCurrentTabId(); |
| 206 if (tab_id < 0) |
| 207 return; |
| 208 |
| 209 ExtensionActionState::PaintBadge( |
| 210 canvas, gfx::Rect(width(), height()), |
| 211 action->GetBadgeText(tab_id), |
| 212 action->GetBadgeTextColor(tab_id), |
| 213 action->GetBadgeBackgroundColor(tab_id)); |
208 } | 214 } |
209 | 215 |
210 | 216 |
211 //////////////////////////////////////////////////////////////////////////////// | 217 //////////////////////////////////////////////////////////////////////////////// |
212 // BrowserActionsContainer | 218 // BrowserActionsContainer |
213 | 219 |
214 BrowserActionsContainer::BrowserActionsContainer( | 220 BrowserActionsContainer::BrowserActionsContainer( |
215 Profile* profile, ToolbarView* toolbar) | 221 Profile* profile, ToolbarView* toolbar) |
216 : profile_(profile), | 222 : profile_(profile), |
217 toolbar_(toolbar), | 223 toolbar_(toolbar), |
218 popup_(NULL), | 224 popup_(NULL), |
219 popup_button_(NULL), | 225 popup_button_(NULL), |
220 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { | 226 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { |
221 ExtensionsService* extension_service = profile->GetExtensionsService(); | 227 ExtensionsService* extension_service = profile->GetExtensionsService(); |
| 228 if (!extension_service) // The |extension_service| can be NULL in Incognito. |
| 229 return; |
| 230 |
222 registrar_.Add(this, NotificationType::EXTENSION_LOADED, | 231 registrar_.Add(this, NotificationType::EXTENSION_LOADED, |
223 Source<ExtensionsService>(extension_service)); | 232 Source<ExtensionsService>(extension_service)); |
224 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, | 233 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, |
225 Source<ExtensionsService>(extension_service)); | 234 Source<ExtensionsService>(extension_service)); |
226 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED, | 235 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED, |
227 Source<ExtensionsService>(extension_service)); | 236 Source<ExtensionsService>(extension_service)); |
228 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, | 237 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
229 Source<Profile>(profile_)); | 238 Source<Profile>(profile_)); |
230 | 239 |
231 RefreshBrowserActionViews(); | 240 for (size_t i = 0; i < extension_service->extensions()->size(); ++i) |
| 241 AddBrowserAction(extension_service->extensions()->at(i)); |
| 242 |
232 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR); | 243 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR); |
233 } | 244 } |
234 | 245 |
235 BrowserActionsContainer::~BrowserActionsContainer() { | 246 BrowserActionsContainer::~BrowserActionsContainer() { |
236 HidePopup(); | 247 HidePopup(); |
237 DeleteBrowserActionViews(); | 248 DeleteBrowserActionViews(); |
238 } | 249 } |
239 | 250 |
| 251 int BrowserActionsContainer::GetCurrentTabId() { |
| 252 TabContents* tab_contents = toolbar_->browser()->GetSelectedTabContents(); |
| 253 if (!tab_contents) |
| 254 return -1; |
| 255 |
| 256 return tab_contents->controller().session_id().id(); |
| 257 } |
| 258 |
240 void BrowserActionsContainer::RefreshBrowserActionViews() { | 259 void BrowserActionsContainer::RefreshBrowserActionViews() { |
241 ExtensionsService* extension_service = profile_->GetExtensionsService(); | 260 for (size_t i = 0; i < browser_action_views_.size(); ++i) |
242 if (!extension_service) // The |extension_service| can be NULL in Incognito. | 261 browser_action_views_[i]->button()->UpdateState(); |
| 262 } |
| 263 |
| 264 void BrowserActionsContainer::AddBrowserAction(Extension* extension) { |
| 265 #if defined(DEBUG) |
| 266 for (size_t i = 0; i < browser_action_views_.size(); ++i) { |
| 267 DCHECK(browser_action_views_[i]->button()->extension() != extension) << |
| 268 "Asked to add a browser action view for an extension that already " |
| 269 "exists."; |
| 270 } |
| 271 #endif |
| 272 if (!extension->browser_action()) |
243 return; | 273 return; |
244 | 274 |
245 // Get all browser actions, including those with popups. | 275 BrowserActionView* view = new BrowserActionView(extension, this); |
246 std::vector<ExtensionAction*> browser_actions; | 276 browser_action_views_.push_back(view); |
247 browser_actions = extension_service->GetBrowserActions(true); | 277 AddChildView(view); |
| 278 } |
248 | 279 |
249 DeleteBrowserActionViews(); | 280 void BrowserActionsContainer::RemoveBrowserAction(Extension* extension) { |
250 for (size_t i = 0; i < browser_actions.size(); ++i) { | 281 if (!extension->browser_action()) |
251 Extension* extension = extension_service->GetExtensionById( | 282 return; |
252 browser_actions[i]->extension_id()); | |
253 DCHECK(extension); | |
254 | 283 |
255 BrowserActionView* view = | 284 for (std::vector<BrowserActionView*>::iterator iter = |
256 new BrowserActionView(browser_actions[i], extension, this); | 285 browser_action_views_.begin(); iter != browser_action_views_.end(); |
257 browser_action_views_.push_back(view); | 286 ++iter) { |
258 AddChildView(view); | 287 if ((*iter)->button()->extension() == extension) { |
| 288 RemoveChildView(*iter); |
| 289 browser_action_views_.erase(iter); |
| 290 return; |
| 291 } |
259 } | 292 } |
| 293 |
| 294 NOTREACHED() << "Asked to remove a browser action view that doesn't exist."; |
260 } | 295 } |
261 | 296 |
262 void BrowserActionsContainer::DeleteBrowserActionViews() { | 297 void BrowserActionsContainer::DeleteBrowserActionViews() { |
263 if (!browser_action_views_.empty()) { | 298 if (!browser_action_views_.empty()) { |
264 for (size_t i = 0; i < browser_action_views_.size(); ++i) | 299 for (size_t i = 0; i < browser_action_views_.size(); ++i) |
265 RemoveChildView(browser_action_views_[i]); | 300 RemoveChildView(browser_action_views_[i]); |
266 STLDeleteContainerPointers(browser_action_views_.begin(), | 301 STLDeleteContainerPointers(browser_action_views_.begin(), |
267 browser_action_views_.end()); | 302 browser_action_views_.end()); |
268 browser_action_views_.clear(); | 303 browser_action_views_.clear(); |
269 } | 304 } |
(...skipping 24 matching lines...) Expand all Loading... |
294 } | 329 } |
295 } | 330 } |
296 | 331 |
297 void BrowserActionsContainer::TestExecuteBrowserAction(int index) { | 332 void BrowserActionsContainer::TestExecuteBrowserAction(int index) { |
298 BrowserActionButton* button = browser_action_views_[index]->button(); | 333 BrowserActionButton* button = browser_action_views_[index]->button(); |
299 OnBrowserActionExecuted(button); | 334 OnBrowserActionExecuted(button); |
300 } | 335 } |
301 | 336 |
302 void BrowserActionsContainer::OnBrowserActionExecuted( | 337 void BrowserActionsContainer::OnBrowserActionExecuted( |
303 BrowserActionButton* button) { | 338 BrowserActionButton* button) { |
304 const ExtensionAction& browser_action = button->browser_action(); | 339 ExtensionAction2* browser_action = button->browser_action(); |
305 | 340 |
306 // Popups just display. No notification to the extension. | 341 // Popups just display. No notification to the extension. |
307 // TODO(erikkay): should there be? | 342 // TODO(erikkay): should there be? |
308 if (button->IsPopup()) { | 343 if (button->IsPopup()) { |
309 // If we're showing the same popup, just hide it and return. | 344 // If we're showing the same popup, just hide it and return. |
310 bool same_showing = popup_ && button == popup_button_; | 345 bool same_showing = popup_ && button == popup_button_; |
311 | 346 |
312 // Always hide the current popup, even if it's not the same. | 347 // Always hide the current popup, even if it's not the same. |
313 // Only one popup should be visible at a time. | 348 // Only one popup should be visible at a time. |
314 HidePopup(); | 349 HidePopup(); |
315 | 350 |
316 if (same_showing) | 351 if (same_showing) |
317 return; | 352 return; |
318 | 353 |
319 gfx::Point origin; | 354 gfx::Point origin; |
320 View::ConvertPointToScreen(button, &origin); | 355 View::ConvertPointToScreen(button, &origin); |
321 gfx::Rect rect = button->bounds(); | 356 gfx::Rect rect = button->bounds(); |
322 rect.set_x(origin.x()); | 357 rect.set_x(origin.x()); |
323 rect.set_y(origin.y()); | 358 rect.set_y(origin.y()); |
324 popup_ = ExtensionPopup::Show(browser_action.popup_url(), | 359 popup_ = ExtensionPopup::Show(browser_action->popup_url(), |
325 toolbar_->browser(), | 360 toolbar_->browser(), |
326 rect); | 361 rect); |
327 popup_->set_delegate(this); | 362 popup_->set_delegate(this); |
328 popup_button_ = button; | 363 popup_button_ = button; |
329 popup_button_->PopupDidShow(); | 364 popup_button_->PopupDidShow(); |
330 return; | 365 return; |
331 } | 366 } |
332 | 367 |
333 // Otherwise, we send the action to the extension. | 368 // Otherwise, we send the action to the extension. |
334 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted( | 369 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted( |
335 profile_, browser_action.extension_id(), toolbar_->browser()); | 370 profile_, browser_action->extension_id(), toolbar_->browser()); |
336 } | 371 } |
337 | 372 |
338 gfx::Size BrowserActionsContainer::GetPreferredSize() { | 373 gfx::Size BrowserActionsContainer::GetPreferredSize() { |
339 if (browser_action_views_.empty()) | 374 if (browser_action_views_.empty()) |
340 return gfx::Size(0, 0); | 375 return gfx::Size(0, 0); |
341 int width = kHorizontalPadding * 2 + | 376 int width = kHorizontalPadding * 2 + |
342 browser_action_views_.size() * kButtonSize; | 377 browser_action_views_.size() * kButtonSize; |
343 return gfx::Size(width, kButtonSize); | 378 return gfx::Size(width, kButtonSize); |
344 } | 379 } |
345 | 380 |
346 void BrowserActionsContainer::Layout() { | 381 void BrowserActionsContainer::Layout() { |
347 for (size_t i = 0; i < browser_action_views_.size(); ++i) { | 382 for (size_t i = 0; i < browser_action_views_.size(); ++i) { |
348 BrowserActionView* view = browser_action_views_[i]; | 383 BrowserActionView* view = browser_action_views_[i]; |
349 int x = kHorizontalPadding + i * kButtonSize; | 384 int x = kHorizontalPadding + i * kButtonSize; |
350 if (x + kButtonSize <= width()) { | 385 if (x + kButtonSize <= width()) { |
351 view->SetBounds(x, 0, kButtonSize, height()); | 386 view->SetBounds(x, 0, kButtonSize, height()); |
352 view->SetVisible(true); | 387 view->SetVisible(true); |
353 } else { | 388 } else { |
354 view->SetVisible(false); | 389 view->SetVisible(false); |
355 } | 390 } |
356 } | 391 } |
357 } | 392 } |
358 | 393 |
359 void BrowserActionsContainer::Observe(NotificationType type, | 394 void BrowserActionsContainer::Observe(NotificationType type, |
360 const NotificationSource& source, | 395 const NotificationSource& source, |
361 const NotificationDetails& details) { | 396 const NotificationDetails& details) { |
362 if (type == NotificationType::EXTENSION_LOADED || | 397 switch (type.value) { |
363 type == NotificationType::EXTENSION_UNLOADED || | 398 case NotificationType::EXTENSION_LOADED: |
364 type == NotificationType::EXTENSION_UNLOADED_DISABLED) { | 399 AddBrowserAction(Details<Extension>(details).ptr()); |
365 RefreshBrowserActionViews(); | 400 OnBrowserActionVisibilityChanged(); |
| 401 break; |
366 | 402 |
367 // All these actions may change visibility of BrowserActions. | 403 case NotificationType::EXTENSION_UNLOADED: |
368 OnBrowserActionVisibilityChanged(); | 404 case NotificationType::EXTENSION_UNLOADED_DISABLED: |
369 } else if (type == NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE) { | 405 RemoveBrowserAction(Details<Extension>(details).ptr()); |
370 if (Details<ExtensionHost>(popup_->host()) != details) | 406 OnBrowserActionVisibilityChanged(); |
371 return; | 407 break; |
372 | 408 |
373 HidePopup(); | 409 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE: |
374 } else { | 410 if (Details<ExtensionHost>(popup_->host()) != details) |
375 NOTREACHED() << L"Received unexpected notification"; | 411 return; |
| 412 |
| 413 HidePopup(); |
| 414 |
| 415 default: |
| 416 NOTREACHED() << L"Unexpected notification"; |
376 } | 417 } |
377 } | 418 } |
378 | 419 |
379 void BrowserActionsContainer::BubbleBrowserWindowMoved(BrowserBubble* bubble) { | 420 void BrowserActionsContainer::BubbleBrowserWindowMoved(BrowserBubble* bubble) { |
380 } | 421 } |
381 | 422 |
382 void BrowserActionsContainer::BubbleBrowserWindowClosing( | 423 void BrowserActionsContainer::BubbleBrowserWindowClosing( |
383 BrowserBubble* bubble) { | 424 BrowserBubble* bubble) { |
384 HidePopup(); | 425 HidePopup(); |
385 } | 426 } |
(...skipping 22 matching lines...) Expand all Loading... |
408 std::min(static_cast<int>(browser_action_views_.size()), | 449 std::min(static_cast<int>(browser_action_views_.size()), |
409 kMinimumNumberOfVisibleBrowserActions) * kButtonSize; | 450 kMinimumNumberOfVisibleBrowserActions) * kButtonSize; |
410 | 451 |
411 // Even if available_width is <= 0, we still return at least the |min_width|. | 452 // Even if available_width is <= 0, we still return at least the |min_width|. |
412 if (available_width <= 0) | 453 if (available_width <= 0) |
413 return min_width; | 454 return min_width; |
414 | 455 |
415 return std::max(min_width, available_width - available_width % kButtonSize + | 456 return std::max(min_width, available_width - available_width % kButtonSize + |
416 kHorizontalPadding * 2); | 457 kHorizontalPadding * 2); |
417 } | 458 } |
OLD | NEW |