OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/ui/toolbar/toolbar_actions_bar.h" | 5 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_delegate.h" | 28 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_delegate.h" |
29 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_observer.h" | 29 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_observer.h" |
30 #include "chrome/common/pref_names.h" | 30 #include "chrome/common/pref_names.h" |
31 #include "chrome/grit/theme_resources.h" | 31 #include "chrome/grit/theme_resources.h" |
32 #include "components/crx_file/id_util.h" | 32 #include "components/crx_file/id_util.h" |
33 #include "components/pref_registry/pref_registry_syncable.h" | 33 #include "components/pref_registry/pref_registry_syncable.h" |
34 #include "extensions/browser/extension_system.h" | 34 #include "extensions/browser/extension_system.h" |
35 #include "extensions/browser/extension_util.h" | 35 #include "extensions/browser/extension_util.h" |
36 #include "extensions/browser/runtime_data.h" | 36 #include "extensions/browser/runtime_data.h" |
37 #include "extensions/common/extension.h" | 37 #include "extensions/common/extension.h" |
38 #include "extensions/common/feature_switch.h" | |
39 #include "ui/base/resource/resource_bundle.h" | 38 #include "ui/base/resource/resource_bundle.h" |
40 #include "ui/gfx/image/image_skia.h" | 39 #include "ui/gfx/image/image_skia.h" |
41 | 40 |
42 namespace { | 41 namespace { |
43 | 42 |
44 using WeakToolbarActions = std::vector<ToolbarActionViewController*>; | 43 using WeakToolbarActions = std::vector<ToolbarActionViewController*>; |
45 | 44 |
46 enum DimensionType { WIDTH, HEIGHT }; | 45 enum DimensionType { WIDTH, HEIGHT }; |
47 | 46 |
48 // Takes a reference vector |reference| of length n, where n is less than or | 47 // Takes a reference vector |reference| of length n, where n is less than or |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // How long to wait until showing an extension message bubble. | 82 // How long to wait until showing an extension message bubble. |
84 int g_extension_bubble_appearance_wait_time_in_seconds = 5; | 83 int g_extension_bubble_appearance_wait_time_in_seconds = 5; |
85 | 84 |
86 } // namespace | 85 } // namespace |
87 | 86 |
88 // static | 87 // static |
89 bool ToolbarActionsBar::disable_animations_for_testing_ = false; | 88 bool ToolbarActionsBar::disable_animations_for_testing_ = false; |
90 | 89 |
91 ToolbarActionsBar::PlatformSettings::PlatformSettings() | 90 ToolbarActionsBar::PlatformSettings::PlatformSettings() |
92 : item_spacing(GetLayoutConstant(TOOLBAR_STANDARD_SPACING)), | 91 : item_spacing(GetLayoutConstant(TOOLBAR_STANDARD_SPACING)), |
93 icons_per_overflow_menu_row(1), | 92 icons_per_overflow_menu_row(1) {} |
94 chevron_enabled(!extensions::FeatureSwitch::extension_action_redesign()-> | |
95 IsEnabled()) { | |
96 } | |
97 | 93 |
98 ToolbarActionsBar::ToolbarActionsBar(ToolbarActionsBarDelegate* delegate, | 94 ToolbarActionsBar::ToolbarActionsBar(ToolbarActionsBarDelegate* delegate, |
99 Browser* browser, | 95 Browser* browser, |
100 ToolbarActionsBar* main_bar) | 96 ToolbarActionsBar* main_bar) |
101 : delegate_(delegate), | 97 : delegate_(delegate), |
102 browser_(browser), | 98 browser_(browser), |
103 model_(ToolbarActionsModel::Get(browser_->profile())), | 99 model_(ToolbarActionsModel::Get(browser_->profile())), |
104 main_bar_(main_bar), | 100 main_bar_(main_bar), |
105 platform_settings_(), | 101 platform_settings_(), |
106 popup_owner_(nullptr), | 102 popup_owner_(nullptr), |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 } | 256 } |
261 | 257 |
262 bool ToolbarActionsBar::NeedsOverflow() const { | 258 bool ToolbarActionsBar::NeedsOverflow() const { |
263 DCHECK(!in_overflow_mode()); | 259 DCHECK(!in_overflow_mode()); |
264 // We need an overflow view if either the end index is less than the number of | 260 // We need an overflow view if either the end index is less than the number of |
265 // icons, if a drag is in progress with the redesign turned on (since the | 261 // icons, if a drag is in progress with the redesign turned on (since the |
266 // user can drag an icon into the app menu), or if there is a non-sticky | 262 // user can drag an icon into the app menu), or if there is a non-sticky |
267 // popped out action (because the action will pop back into overflow when the | 263 // popped out action (because the action will pop back into overflow when the |
268 // menu opens). | 264 // menu opens). |
269 return GetEndIndexInBounds() != toolbar_actions_.size() || | 265 return GetEndIndexInBounds() != toolbar_actions_.size() || |
270 (is_drag_in_progress_ && !platform_settings_.chevron_enabled) || | 266 is_drag_in_progress_ || (popped_out_action_ && !is_popped_out_sticky_); |
271 (popped_out_action_ && !is_popped_out_sticky_); | |
272 } | 267 } |
273 | 268 |
274 gfx::Rect ToolbarActionsBar::GetFrameForIndex( | 269 gfx::Rect ToolbarActionsBar::GetFrameForIndex( |
275 size_t index) const { | 270 size_t index) const { |
276 size_t start_index = GetStartIndexInBounds(); | 271 size_t start_index = GetStartIndexInBounds(); |
277 | 272 |
278 // If the index is for an action that is before range we show (i.e., is for | 273 // If the index is for an action that is before range we show (i.e., is for |
279 // a button that's on the main bar, and this is the overflow), send back an | 274 // a button that's on the main bar, and this is the overflow), send back an |
280 // empty rect. | 275 // empty rect. |
281 if (index < start_index) | 276 if (index < start_index) |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 bool needs_redraw = !IsActionVisibleOnMainBar(controller); | 502 bool needs_redraw = !IsActionVisibleOnMainBar(controller); |
508 popped_out_action_ = controller; | 503 popped_out_action_ = controller; |
509 is_popped_out_sticky_ = is_sticky; | 504 is_popped_out_sticky_ = is_sticky; |
510 if (needs_redraw) { | 505 if (needs_redraw) { |
511 // We suppress animation for this draw, because we need the action to get | 506 // We suppress animation for this draw, because we need the action to get |
512 // into position immediately, since it's about to show its popup. | 507 // into position immediately, since it's about to show its popup. |
513 base::AutoReset<bool> layout_resetter(&suppress_animation_, false); | 508 base::AutoReset<bool> layout_resetter(&suppress_animation_, false); |
514 delegate_->Redraw(true); | 509 delegate_->Redraw(true); |
515 } | 510 } |
516 | 511 |
517 ResizeDelegate(gfx::Tween::LINEAR, false); | 512 ResizeDelegate(gfx::Tween::LINEAR); |
518 if (!delegate_->IsAnimating()) { | 513 if (!delegate_->IsAnimating()) { |
519 // Don't call the closure re-entrantly. | 514 // Don't call the closure re-entrantly. |
520 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); | 515 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); |
521 } else { | 516 } else { |
522 popped_out_closure_ = closure; | 517 popped_out_closure_ = closure; |
523 } | 518 } |
524 } | 519 } |
525 | 520 |
526 void ToolbarActionsBar::UndoPopOut() { | 521 void ToolbarActionsBar::UndoPopOut() { |
527 DCHECK(!in_overflow_mode()) << "Only the main bar can pop out actions."; | 522 DCHECK(!in_overflow_mode()) << "Only the main bar can pop out actions."; |
528 DCHECK(popped_out_action_); | 523 DCHECK(popped_out_action_); |
529 ToolbarActionViewController* controller = popped_out_action_; | 524 ToolbarActionViewController* controller = popped_out_action_; |
530 popped_out_action_ = nullptr; | 525 popped_out_action_ = nullptr; |
531 is_popped_out_sticky_ = false; | 526 is_popped_out_sticky_ = false; |
532 popped_out_closure_.Reset(); | 527 popped_out_closure_.Reset(); |
533 if (!IsActionVisibleOnMainBar(controller)) | 528 if (!IsActionVisibleOnMainBar(controller)) |
534 delegate_->Redraw(true); | 529 delegate_->Redraw(true); |
535 ResizeDelegate(gfx::Tween::LINEAR, false); | 530 ResizeDelegate(gfx::Tween::LINEAR); |
536 } | 531 } |
537 | 532 |
538 void ToolbarActionsBar::SetPopupOwner( | 533 void ToolbarActionsBar::SetPopupOwner( |
539 ToolbarActionViewController* popup_owner) { | 534 ToolbarActionViewController* popup_owner) { |
540 // We should never be setting a popup owner when one already exists, and | 535 // We should never be setting a popup owner when one already exists, and |
541 // never unsetting one when one wasn't set. | 536 // never unsetting one when one wasn't set. |
542 DCHECK((!popup_owner_ && popup_owner) || | 537 DCHECK((!popup_owner_ && popup_owner) || |
543 (popup_owner_ && !popup_owner)); | 538 (popup_owner_ && !popup_owner)); |
544 popup_owner_ = popup_owner; | 539 popup_owner_ = popup_owner; |
545 } | 540 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 int index) { | 621 int index) { |
627 CHECK(model_->actions_initialized()); | 622 CHECK(model_->actions_initialized()); |
628 CHECK(GetActionForId(item.id) == nullptr) | 623 CHECK(GetActionForId(item.id) == nullptr) |
629 << "Asked to add a toolbar action view for an action that already " | 624 << "Asked to add a toolbar action view for an action that already " |
630 "exists"; | 625 "exists"; |
631 | 626 |
632 toolbar_actions_.insert(toolbar_actions_.begin() + index, | 627 toolbar_actions_.insert(toolbar_actions_.begin() + index, |
633 model_->CreateActionForItem(browser_, this, item)); | 628 model_->CreateActionForItem(browser_, this, item)); |
634 delegate_->AddViewForAction(toolbar_actions_[index].get(), index); | 629 delegate_->AddViewForAction(toolbar_actions_[index].get(), index); |
635 | 630 |
636 // We may need to resize (e.g. to show the new icon, or the chevron). We don't | 631 // We may need to resize (e.g. to show the new icon). We don't need to check |
637 // need to check if an extension is upgrading here, because ResizeDelegate() | 632 // if an extension is upgrading here, because ResizeDelegate() checks to see |
638 // checks to see if the container is already the proper size, and because | 633 // if the container is already the proper size, and because if the action is |
639 // if the action is newly incognito enabled, even though it's a reload, it's | 634 // newly incognito enabled, even though it's a reload, it's a new extension to |
640 // a new extension to this toolbar. | 635 // this toolbar. |
641 // We suppress the chevron during animation because, if we're expanding to | 636 ResizeDelegate(gfx::Tween::LINEAR); |
642 // show a new icon, we don't want to have the chevron visible only for the | |
643 // duration of the animation. | |
644 ResizeDelegate(gfx::Tween::LINEAR, true); | |
645 } | 637 } |
646 | 638 |
647 void ToolbarActionsBar::OnToolbarActionRemoved(const std::string& action_id) { | 639 void ToolbarActionsBar::OnToolbarActionRemoved(const std::string& action_id) { |
648 ToolbarActions::iterator iter = toolbar_actions_.begin(); | 640 ToolbarActions::iterator iter = toolbar_actions_.begin(); |
649 while (iter != toolbar_actions_.end() && (*iter)->GetId() != action_id) | 641 while (iter != toolbar_actions_.end() && (*iter)->GetId() != action_id) |
650 ++iter; | 642 ++iter; |
651 | 643 |
652 if (iter == toolbar_actions_.end()) | 644 if (iter == toolbar_actions_.end()) |
653 return; | 645 return; |
654 | 646 |
(...skipping 19 matching lines...) Expand all Loading... |
674 !extensions::util::IsIncognitoEnabled(action_id, browser_->profile()))) { | 666 !extensions::util::IsIncognitoEnabled(action_id, browser_->profile()))) { |
675 if (toolbar_actions_.size() > model_->visible_icon_count()) { | 667 if (toolbar_actions_.size() > model_->visible_icon_count()) { |
676 // If we have more icons than we can show, then we must not be changing | 668 // If we have more icons than we can show, then we must not be changing |
677 // the container size (since we either removed an icon from the main | 669 // the container size (since we either removed an icon from the main |
678 // area and one from the overflow list will have shifted in, or we | 670 // area and one from the overflow list will have shifted in, or we |
679 // removed an entry directly from the overflow list). | 671 // removed an entry directly from the overflow list). |
680 delegate_->Redraw(false); | 672 delegate_->Redraw(false); |
681 } else { | 673 } else { |
682 // Either we went from overflow to no-overflow, or we shrunk the no- | 674 // Either we went from overflow to no-overflow, or we shrunk the no- |
683 // overflow container by 1. Either way the size changed, so animate. | 675 // overflow container by 1. Either way the size changed, so animate. |
684 ResizeDelegate(gfx::Tween::EASE_OUT, false); | 676 ResizeDelegate(gfx::Tween::EASE_OUT); |
685 } | 677 } |
686 } | 678 } |
687 } | 679 } |
688 | 680 |
689 void ToolbarActionsBar::OnToolbarActionMoved(const std::string& action_id, | 681 void ToolbarActionsBar::OnToolbarActionMoved(const std::string& action_id, |
690 int index) { | 682 int index) { |
691 DCHECK(index >= 0 && index < static_cast<int>(toolbar_actions_.size())); | 683 DCHECK(index >= 0 && index < static_cast<int>(toolbar_actions_.size())); |
692 // Unfortunately, |index| doesn't really mean a lot to us, because this | 684 // Unfortunately, |index| doesn't really mean a lot to us, because this |
693 // window's toolbar could be different (if actions are popped out). Just | 685 // window's toolbar could be different (if actions are popped out). Just |
694 // do a full reorder. | 686 // do a full reorder. |
695 ReorderActions(); | 687 ReorderActions(); |
696 } | 688 } |
697 | 689 |
698 void ToolbarActionsBar::OnToolbarActionUpdated(const std::string& action_id) { | 690 void ToolbarActionsBar::OnToolbarActionUpdated(const std::string& action_id) { |
699 ToolbarActionViewController* action = GetActionForId(action_id); | 691 ToolbarActionViewController* action = GetActionForId(action_id); |
700 // There might not be a view in cases where we are highlighting or if we | 692 // There might not be a view in cases where we are highlighting or if we |
701 // haven't fully initialized the actions. | 693 // haven't fully initialized the actions. |
702 if (action) | 694 if (action) |
703 action->UpdateState(); | 695 action->UpdateState(); |
704 } | 696 } |
705 | 697 |
706 void ToolbarActionsBar::OnToolbarVisibleCountChanged() { | 698 void ToolbarActionsBar::OnToolbarVisibleCountChanged() { |
707 ResizeDelegate(gfx::Tween::EASE_OUT, false); | 699 ResizeDelegate(gfx::Tween::EASE_OUT); |
708 } | 700 } |
709 | 701 |
710 void ToolbarActionsBar::ResizeDelegate(gfx::Tween::Type tween_type, | 702 void ToolbarActionsBar::ResizeDelegate(gfx::Tween::Type tween_type) { |
711 bool suppress_chevron) { | |
712 int desired_width = GetFullSize().width(); | 703 int desired_width = GetFullSize().width(); |
713 if (desired_width != | 704 if (desired_width != |
714 delegate_->GetWidth(ToolbarActionsBarDelegate::GET_WIDTH_CURRENT)) { | 705 delegate_->GetWidth(ToolbarActionsBarDelegate::GET_WIDTH_CURRENT)) { |
715 delegate_->ResizeAndAnimate(tween_type, desired_width); | 706 delegate_->ResizeAndAnimate(tween_type, desired_width); |
716 } else if (delegate_->IsAnimating()) { | 707 } else if (delegate_->IsAnimating()) { |
717 // It's possible that we're right where we're supposed to be in terms of | 708 // It's possible that we're right where we're supposed to be in terms of |
718 // width, but that we're also currently resizing. If this is the case, end | 709 // width, but that we're also currently resizing. If this is the case, end |
719 // the current animation with the current width. | 710 // the current animation with the current width. |
720 delegate_->StopAnimating(); | 711 delegate_->StopAnimating(); |
721 } else { | 712 } else { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 void ToolbarActionsBar::OnToolbarModelInitialized() { | 766 void ToolbarActionsBar::OnToolbarModelInitialized() { |
776 // We shouldn't have any actions before the model is initialized. | 767 // We shouldn't have any actions before the model is initialized. |
777 CHECK(toolbar_actions_.empty()); | 768 CHECK(toolbar_actions_.empty()); |
778 CreateActions(); | 769 CreateActions(); |
779 | 770 |
780 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/463337 is | 771 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/463337 is |
781 // fixed. | 772 // fixed. |
782 tracked_objects::ScopedTracker tracking_profile( | 773 tracked_objects::ScopedTracker tracking_profile( |
783 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 774 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
784 "ToolbarActionsBar::OnToolbarModelInitialized")); | 775 "ToolbarActionsBar::OnToolbarModelInitialized")); |
785 ResizeDelegate(gfx::Tween::EASE_OUT, false); | 776 ResizeDelegate(gfx::Tween::EASE_OUT); |
786 } | 777 } |
787 | 778 |
788 void ToolbarActionsBar::TabInsertedAt(TabStripModel* tab_strip_model, | 779 void ToolbarActionsBar::TabInsertedAt(TabStripModel* tab_strip_model, |
789 content::WebContents* contents, | 780 content::WebContents* contents, |
790 int index, | 781 int index, |
791 bool foreground) { | 782 bool foreground) { |
792 if (foreground) | 783 if (foreground) |
793 extensions::MaybeShowExtensionControlledNewTabPage(browser_, contents); | 784 extensions::MaybeShowExtensionControlledNewTabPage(browser_, contents); |
794 } | 785 } |
795 | 786 |
796 void ToolbarActionsBar::ReorderActions() { | 787 void ToolbarActionsBar::ReorderActions() { |
797 if (toolbar_actions_.empty()) | 788 if (toolbar_actions_.empty()) |
798 return; | 789 return; |
799 | 790 |
800 // First, reset the order to that of the model. | 791 // First, reset the order to that of the model. |
801 auto compare = [](ToolbarActionViewController* const& action, | 792 auto compare = [](ToolbarActionViewController* const& action, |
802 const ToolbarActionsModel::ToolbarItem& item) { | 793 const ToolbarActionsModel::ToolbarItem& item) { |
803 return action->GetId() == item.id; | 794 return action->GetId() == item.id; |
804 }; | 795 }; |
805 SortContainer(&toolbar_actions_, model_->toolbar_items(), compare); | 796 SortContainer(&toolbar_actions_, model_->toolbar_items(), compare); |
806 | 797 |
807 // Our visible browser actions may have changed - re-Layout() and check the | 798 // Our visible browser actions may have changed - re-Layout() and check the |
808 // size (if we aren't suppressing the layout). | 799 // size (if we aren't suppressing the layout). |
809 if (!suppress_layout_) { | 800 if (!suppress_layout_) { |
810 ResizeDelegate(gfx::Tween::EASE_OUT, false); | 801 ResizeDelegate(gfx::Tween::EASE_OUT); |
811 delegate_->Redraw(true); | 802 delegate_->Redraw(true); |
812 } | 803 } |
813 } | 804 } |
814 | 805 |
815 ToolbarActionViewController* ToolbarActionsBar::GetActionForId( | 806 ToolbarActionViewController* ToolbarActionsBar::GetActionForId( |
816 const std::string& action_id) { | 807 const std::string& action_id) { |
817 for (const auto& action : toolbar_actions_) { | 808 for (const auto& action : toolbar_actions_) { |
818 if (action->GetId() == action_id) | 809 if (action->GetId() == action_id) |
819 return action.get(); | 810 return action.get(); |
820 } | 811 } |
821 return nullptr; | 812 return nullptr; |
822 } | 813 } |
823 | 814 |
824 content::WebContents* ToolbarActionsBar::GetCurrentWebContents() { | 815 content::WebContents* ToolbarActionsBar::GetCurrentWebContents() { |
825 return browser_->tab_strip_model()->GetActiveWebContents(); | 816 return browser_->tab_strip_model()->GetActiveWebContents(); |
826 } | 817 } |
OLD | NEW |