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

Side by Side Diff: chrome/browser/views/browser_actions_container.cc

Issue 553084: re-try r37061 with fix for browser tests... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/views/browser_actions_container.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "app/slide_animation.h" 9 #include "app/slide_animation.h"
10 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 278
279 //////////////////////////////////////////////////////////////////////////////// 279 ////////////////////////////////////////////////////////////////////////////////
280 // BrowserActionsContainer 280 // BrowserActionsContainer
281 281
282 BrowserActionsContainer::BrowserActionsContainer( 282 BrowserActionsContainer::BrowserActionsContainer(
283 Profile* profile, ToolbarView* toolbar) 283 Profile* profile, ToolbarView* toolbar)
284 : profile_(profile), 284 : profile_(profile),
285 toolbar_(toolbar), 285 toolbar_(toolbar),
286 popup_(NULL), 286 popup_(NULL),
287 popup_button_(NULL), 287 popup_button_(NULL),
288 model_(NULL),
288 resize_gripper_(NULL), 289 resize_gripper_(NULL),
289 chevron_(NULL), 290 chevron_(NULL),
290 suppress_chevron_(false), 291 suppress_chevron_(false),
291 resize_amount_(0), 292 resize_amount_(0),
292 animation_target_size_(0), 293 animation_target_size_(0),
293 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { 294 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
295 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR);
296
294 ExtensionsService* extension_service = profile->GetExtensionsService(); 297 ExtensionsService* extension_service = profile->GetExtensionsService();
295 if (!extension_service) // The |extension_service| can be NULL in Incognito. 298 if (!extension_service) // The |extension_service| can be NULL in Incognito.
296 return; 299 return;
297 300
298 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
299 Source<Profile>(profile_));
300 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
301 Source<Profile>(profile_));
302 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
303 Source<Profile>(profile_));
304 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, 301 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
305 Source<Profile>(profile_)); 302 Source<Profile>(profile_));
306 303
304 model_ = extension_service->toolbar_model();
305 model_->AddObserver(this);
306
307 resize_animation_.reset(new SlideAnimation(this)); 307 resize_animation_.reset(new SlideAnimation(this));
308
309 resize_gripper_ = new views::ResizeGripper(this); 308 resize_gripper_ = new views::ResizeGripper(this);
310 resize_gripper_->SetVisible(false); 309 resize_gripper_->SetVisible(false);
311 AddChildView(resize_gripper_); 310 AddChildView(resize_gripper_);
312 311
313 // TODO(glen): Come up with a new bitmap for the chevron. 312 // TODO(glen): Come up with a new bitmap for the chevron.
314 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 313 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
315 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS); 314 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS);
316 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false); 315 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false);
317 chevron_->SetVisible(false); 316 chevron_->SetVisible(false);
318 chevron_->SetIcon(*chevron_image); 317 chevron_->SetIcon(*chevron_image);
319 // Chevron contains >> that should point left in LTR locales. 318 // Chevron contains >> that should point left in LTR locales.
320 chevron_->EnableCanvasFlippingForRTLUI(true); 319 chevron_->EnableCanvasFlippingForRTLUI(true);
321 AddChildView(chevron_); 320 AddChildView(chevron_);
322 321
323 int predefined_width = 322 int predefined_width =
324 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth); 323 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth);
325 container_size_ = gfx::Size(predefined_width, kButtonSize); 324 container_size_ = gfx::Size(predefined_width, kButtonSize);
326
327 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR);
328 } 325 }
329 326
330 BrowserActionsContainer::~BrowserActionsContainer() { 327 BrowserActionsContainer::~BrowserActionsContainer() {
328 if (model_)
329 model_->RemoveObserver(this);
331 CloseOverflowMenu(); 330 CloseOverflowMenu();
332 HidePopup(); 331 HidePopup();
333 DeleteBrowserActionViews(); 332 DeleteBrowserActionViews();
334 } 333 }
335 334
336 // Static. 335 // Static.
337 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) { 336 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) {
338 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0); 337 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0);
339 } 338 }
340 339
(...skipping 15 matching lines...) Expand all
356 } 355 }
357 356
358 return NULL; 357 return NULL;
359 } 358 }
360 359
361 void BrowserActionsContainer::RefreshBrowserActionViews() { 360 void BrowserActionsContainer::RefreshBrowserActionViews() {
362 for (size_t i = 0; i < browser_action_views_.size(); ++i) 361 for (size_t i = 0; i < browser_action_views_.size(); ++i)
363 browser_action_views_[i]->button()->UpdateState(); 362 browser_action_views_[i]->button()->UpdateState();
364 } 363 }
365 364
366 void BrowserActionsContainer::AddBrowserAction(Extension* extension) {
367 #if defined(DEBUG)
368 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
369 DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
370 "Asked to add a browser action view for an extension that already "
371 "exists.";
372 }
373 #endif
374 if (!extension->browser_action())
375 return;
376
377 // Before we change anything, determine the number of visible browser actions.
378 size_t visible_actions = VisibleBrowserActions();
379
380 // Add the new browser action to the vector and the view hierarchy.
381 BrowserActionView* view = new BrowserActionView(extension, this);
382 browser_action_views_.push_back(view);
383 AddChildView(view);
384
385 // For details on why we do the following see the class comments in the
386 // header.
387
388 // Determine if we need to increase (we only do that if the container was
389 // showing all icons before the addition of this icon). We use -1 because
390 // we don't want to count the view that we just added.
391 if (visible_actions < browser_action_views_.size() - 1) {
392 // Some icons were hidden, don't increase the size of the container.
393 OnBrowserActionVisibilityChanged();
394 } else {
395 // Container was at max, increase the size of it by one icon.
396 animation_target_size_ = IconCountToWidth(visible_actions + 1);
397
398 // We don't want the chevron to appear while we animate. See documentation
399 // in the header for why we do this.
400 suppress_chevron_ = !chevron_->IsVisible();
401
402 // Animate!
403 resize_animation_->Reset();
404 resize_animation_->SetTweenType(SlideAnimation::NONE);
405 resize_animation_->Show();
406 }
407 }
408
409 void BrowserActionsContainer::RemoveBrowserAction(Extension* extension) {
410 if (!extension->browser_action())
411 return;
412
413 if (popup_ && popup_->host()->extension() == extension) {
414 HidePopup();
415 }
416
417 // Before we change anything, determine the number of visible browser actions.
418 int visible_actions = VisibleBrowserActions();
419
420 for (std::vector<BrowserActionView*>::iterator iter =
421 browser_action_views_.begin(); iter != browser_action_views_.end();
422 ++iter) {
423 if ((*iter)->button()->extension() == extension) {
424 RemoveChildView(*iter);
425 delete *iter;
426 browser_action_views_.erase(iter);
427
428 // For details on why we do the following see the class comments in the
429 // header.
430
431 // Calculate the target size we'll animate to (end state). This might be
432 // the same size (if the icon we are removing is in the overflow bucket
433 // and there are other icons there). We don't decrement visible_actions
434 // because we want the container to stay the same size (clamping will take
435 // care of shrinking the container if there aren't enough icons to show).
436 animation_target_size_ =
437 ClampToNearestIconCount(IconCountToWidth(visible_actions));
438
439 // Animate!
440 resize_animation_->Reset();
441 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT);
442 resize_animation_->Show();
443 return;
444 }
445 }
446 }
447
448 void BrowserActionsContainer::CloseOverflowMenu() { 365 void BrowserActionsContainer::CloseOverflowMenu() {
449 // Close the overflow menu if open (and the context menu off of that). 366 // Close the overflow menu if open (and the context menu off of that).
450 if (overflow_menu_.get()) 367 if (overflow_menu_.get())
451 overflow_menu_->CancelMenu(); 368 overflow_menu_->CancelMenu();
452 } 369 }
453 370
454 void BrowserActionsContainer::DeleteBrowserActionViews() { 371 void BrowserActionsContainer::DeleteBrowserActionViews() {
455 if (!browser_action_views_.empty()) { 372 if (!browser_action_views_.empty()) {
456 for (size_t i = 0; i < browser_action_views_.size(); ++i) 373 for (size_t i = 0; i < browser_action_views_.size(); ++i)
457 RemoveChildView(browser_action_views_[i]); 374 RemoveChildView(browser_action_views_[i]);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 DetachableToolbarView::PaintVerticalDivider( 547 DetachableToolbarView::PaintVerticalDivider(
631 canvas, x, height(), kDividerVerticalPadding, 548 canvas, x, height(), kDividerVerticalPadding,
632 DetachableToolbarView::kEdgeDividerColor, 549 DetachableToolbarView::kEdgeDividerColor,
633 DetachableToolbarView::kMiddleDividerColor, 550 DetachableToolbarView::kMiddleDividerColor,
634 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); 551 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR));
635 } 552 }
636 553
637 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add, 554 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add,
638 views::View* parent, 555 views::View* parent,
639 views::View* child) { 556 views::View* child) {
557 // No extensions (e.g., incognito).
558 if (!model_)
559 return;
560
640 if (is_add && child == this) { 561 if (is_add && child == this) {
562 // Initial toolbar button creation and placement in the widget hierarchy.
641 // We do this here instead of in the constructor because AddBrowserAction 563 // We do this here instead of in the constructor because AddBrowserAction
642 // calls Layout on the Toolbar, which needs this object to be constructed 564 // calls Layout on the Toolbar, which needs this object to be constructed
643 // before its Layout function is called. 565 // before its Layout function is called.
644 ExtensionsService* extension_service = profile_->GetExtensionsService(); 566 for (ExtensionList::iterator iter = model_->begin();
645 if (!extension_service) 567 iter != model_->end(); ++iter) {
646 return; // The |extension_service| can be NULL in Incognito. 568 BrowserActionView* view = new BrowserActionView(*iter, this);
647 for (size_t i = 0; i < extension_service->extensions()->size(); ++i) 569 browser_action_views_.push_back(view);
648 AddBrowserAction(extension_service->extensions()->at(i)); 570 AddChildView(view);
571 }
649 } 572 }
650 } 573 }
651 574
652 void BrowserActionsContainer::Observe(NotificationType type, 575 void BrowserActionsContainer::Observe(NotificationType type,
653 const NotificationSource& source, 576 const NotificationSource& source,
654 const NotificationDetails& details) { 577 const NotificationDetails& details) {
655 switch (type.value) { 578 switch (type.value) {
656 case NotificationType::EXTENSION_LOADED:
657 CloseOverflowMenu();
658 AddBrowserAction(Details<Extension>(details).ptr());
659 OnBrowserActionVisibilityChanged();
660 break;
661
662 case NotificationType::EXTENSION_UNLOADED:
663 case NotificationType::EXTENSION_UNLOADED_DISABLED:
664 CloseOverflowMenu();
665 RemoveBrowserAction(Details<Extension>(details).ptr());
666 OnBrowserActionVisibilityChanged();
667 break;
668
669 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE: 579 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE:
670 // If we aren't the host of the popup, then disregard the notification. 580 // If we aren't the host of the popup, then disregard the notification.
671 if (!popup_ || Details<ExtensionHost>(popup_->host()) != details) 581 if (!popup_ || Details<ExtensionHost>(popup_->host()) != details)
672 return; 582 return;
673 583
674 HidePopup(); 584 HidePopup();
675 break; 585 break;
676 586
677 default: 587 default:
678 NOTREACHED() << "Unexpected notification"; 588 NOTREACHED() << "Unexpected notification";
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 } else { 668 } else {
759 // A negative |pixels| count indicates caller wants to know the max width 669 // A negative |pixels| count indicates caller wants to know the max width
760 // that fits all icons; 670 // that fits all icons;
761 icon_count = browser_action_views_.size(); 671 icon_count = browser_action_views_.size();
762 } 672 }
763 673
764 int returning = extras + (icon_count * icon_width); 674 int returning = extras + (icon_count * icon_width);
765 return returning; 675 return returning;
766 } 676 }
767 677
678 void BrowserActionsContainer::BrowserActionAdded(Extension* extension,
679 int index) {
680 #if defined(DEBUG)
681 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
682 DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
683 "Asked to add a browser action view for an extension that already "
684 "exists.";
685 }
686 #endif
687
688 CloseOverflowMenu();
689
690 // Before we change anything, determine the number of visible browser actions.
691 size_t visible_actions = VisibleBrowserActions();
692
693 // Add the new browser action to the vector and the view hierarchy.
694 BrowserActionView* view = new BrowserActionView(extension, this);
695 browser_action_views_.push_back(view);
696 AddChildView(index, view);
697
698 // For details on why we do the following see the class comments in the
699 // header.
700
701 // Determine if we need to increase (we only do that if the container was
702 // showing all icons before the addition of this icon). We use -1 because
703 // we don't want to count the view that we just added.
704 if (visible_actions < browser_action_views_.size() - 1) {
705 // Some icons were hidden, don't increase the size of the container.
706 OnBrowserActionVisibilityChanged();
707 } else {
708 // Container was at max, increase the size of it by one icon.
709 animation_target_size_ = IconCountToWidth(visible_actions + 1);
710
711 // We don't want the chevron to appear while we animate. See documentation
712 // in the header for why we do this.
713 suppress_chevron_ = !chevron_->IsVisible();
714
715 // Animate!
716 resize_animation_->Reset();
717 resize_animation_->SetTweenType(SlideAnimation::NONE);
718 resize_animation_->Show();
719 }
720 }
721
722 void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) {
723 CloseOverflowMenu();
724
725 if (popup_ && popup_->host()->extension() == extension)
726 HidePopup();
727
728 // Before we change anything, determine the number of visible browser actions.
729 size_t visible_actions = VisibleBrowserActions();
730
731 for (std::vector<BrowserActionView*>::iterator iter =
732 browser_action_views_.begin(); iter != browser_action_views_.end();
733 ++iter) {
734 if ((*iter)->button()->extension() == extension) {
735 RemoveChildView(*iter);
736 delete *iter;
737 browser_action_views_.erase(iter);
738
739 // For details on why we do the following see the class comments in the
740 // header.
741
742 // Calculate the target size we'll animate to (end state). This might be
743 // the same size (if the icon we are removing is in the overflow bucket
744 // and there are other icons there). We don't decrement visible_actions
745 // because we want the container to stay the same size (clamping will take
746 // care of shrinking the container if there aren't enough icons to show).
747 animation_target_size_ =
748 ClampToNearestIconCount(IconCountToWidth(visible_actions));
749
750 // Animate!
751 resize_animation_->Reset();
752 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT);
753 resize_animation_->Show();
754 return;
755 }
756 }
757 }
758
768 int BrowserActionsContainer::WidthOfNonIconArea() const { 759 int BrowserActionsContainer::WidthOfNonIconArea() const {
769 int chevron_size = (chevron_->IsVisible()) ? 760 int chevron_size = (chevron_->IsVisible()) ?
770 chevron_->GetPreferredSize().width() : 0; 761 chevron_->GetPreferredSize().width() : 0;
771 return resize_gripper_->GetPreferredSize().width() + kHorizontalPadding + 762 return resize_gripper_->GetPreferredSize().width() + kHorizontalPadding +
772 chevron_size + kChevronRightMargin + kDividerHorizontalMargin; 763 chevron_size + kChevronRightMargin + kDividerHorizontalMargin;
773 } 764 }
774 765
775 int BrowserActionsContainer::IconCountToWidth(int icons) const { 766 int BrowserActionsContainer::IconCountToWidth(int icons) const {
776 DCHECK(icons >= 0); 767 DCHECK(icons >= 0);
777 if (icons == 0) 768 if (icons == 0)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 void BrowserActionsContainer::AnimationEnded(const Animation* animation) { 826 void BrowserActionsContainer::AnimationEnded(const Animation* animation) {
836 container_size_.set_width(animation_target_size_); 827 container_size_.set_width(animation_target_size_);
837 animation_target_size_ = 0; 828 animation_target_size_ = 0;
838 resize_amount_ = 0; 829 resize_amount_ = 0;
839 OnBrowserActionVisibilityChanged(); 830 OnBrowserActionVisibilityChanged();
840 suppress_chevron_ = false; 831 suppress_chevron_ = false;
841 832
842 profile_->GetPrefs()->SetInteger(prefs::kBrowserActionContainerWidth, 833 profile_->GetPrefs()->SetInteger(prefs::kBrowserActionContainerWidth,
843 container_size_.width()); 834 container_size_.width());
844 } 835 }
OLDNEW
« no previous file with comments | « chrome/browser/views/browser_actions_container.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698