| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/views/toolbar/browser_actions_container.h" | 5 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "chrome/browser/extensions/extension_action_manager.h" | 9 #include "chrome/browser/extensions/extension_action_manager.h" |
| 10 #include "chrome/browser/extensions/extension_util.h" | 10 #include "chrome/browser/extensions/extension_util.h" |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 298 |
| 299 gfx::Size BrowserActionsContainer::GetPreferredSize() const { | 299 gfx::Size BrowserActionsContainer::GetPreferredSize() const { |
| 300 if (in_overflow_mode()) { | 300 if (in_overflow_mode()) { |
| 301 int icon_count = GetIconCount(); | 301 int icon_count = GetIconCount(); |
| 302 // In overflow, we always have a preferred size of a full row (even if we | 302 // In overflow, we always have a preferred size of a full row (even if we |
| 303 // don't use it), and always of at least one row. The parent may decide to | 303 // don't use it), and always of at least one row. The parent may decide to |
| 304 // show us even when empty, e.g. as a drag target for dragging in icons from | 304 // show us even when empty, e.g. as a drag target for dragging in icons from |
| 305 // the main container. | 305 // the main container. |
| 306 int row_count = | 306 int row_count = |
| 307 ((std::max(0, icon_count - 1)) / icons_per_overflow_menu_row_) + 1; | 307 ((std::max(0, icon_count - 1)) / icons_per_overflow_menu_row_) + 1; |
| 308 return gfx::Size( | 308 return gfx::Size(IconCountToWidth(icons_per_overflow_menu_row_), |
| 309 IconCountToWidth(icons_per_overflow_menu_row_, false), | 309 row_count * IconHeight()); |
| 310 row_count * IconHeight()); | |
| 311 } | 310 } |
| 312 | 311 |
| 313 // If there are no actions to show, then don't show the container at all. | 312 // If there are no actions to show, then don't show the container at all. |
| 314 if (browser_action_views_.empty()) | 313 if (browser_action_views_.empty()) |
| 315 return gfx::Size(); | 314 return gfx::Size(); |
| 316 | 315 |
| 317 // We calculate the size of the view by taking the current width and | 316 // We calculate the size of the view by taking the current width and |
| 318 // subtracting resize_amount_ (the latter represents how far the user is | 317 // subtracting resize_amount_ (the latter represents how far the user is |
| 319 // resizing the view or, if animating the snapping, how far to animate it). | 318 // resizing the view or, if animating the snapping, how far to animate it). |
| 320 // But we also clamp it to a minimum size and the maximum size, so that the | 319 // But we also clamp it to a minimum size and the maximum size, so that the |
| 321 // container can never shrink too far or take up more space than it needs. | 320 // container can never shrink too far or take up more space than it needs. |
| 322 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). | 321 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). |
| 323 int preferred_width = std::min( | 322 int preferred_width = std::min( |
| 324 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), | 323 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), |
| 325 IconCountToWidth(-1, false)); | 324 IconCountToWidth(-1)); |
| 326 return gfx::Size(preferred_width, IconHeight()); | 325 return gfx::Size(preferred_width, IconHeight()); |
| 327 } | 326 } |
| 328 | 327 |
| 329 int BrowserActionsContainer::GetHeightForWidth(int width) const { | 328 int BrowserActionsContainer::GetHeightForWidth(int width) const { |
| 330 if (in_overflow_mode()) | 329 if (in_overflow_mode()) |
| 331 icons_per_overflow_menu_row_ = (width - kItemSpacing) / IconWidth(true); | 330 icons_per_overflow_menu_row_ = (width - kItemSpacing) / IconWidth(true); |
| 332 return GetPreferredSize().height(); | 331 return GetPreferredSize().height(); |
| 333 } | 332 } |
| 334 | 333 |
| 335 gfx::Size BrowserActionsContainer::GetMinimumSize() const { | 334 gfx::Size BrowserActionsContainer::GetMinimumSize() const { |
| 336 int min_width = std::min(MinimumNonemptyWidth(), IconCountToWidth(-1, false)); | 335 int min_width = std::min(MinimumNonemptyWidth(), IconCountToWidth(-1)); |
| 337 return gfx::Size(min_width, IconHeight()); | 336 return gfx::Size(min_width, IconHeight()); |
| 338 } | 337 } |
| 339 | 338 |
| 340 void BrowserActionsContainer::Layout() { | 339 void BrowserActionsContainer::Layout() { |
| 341 if (browser_action_views_.empty()) { | 340 if (browser_action_views_.empty()) { |
| 342 SetVisible(false); | 341 SetVisible(false); |
| 343 return; | 342 return; |
| 344 } | 343 } |
| 345 | 344 |
| 346 SetVisible(true); | 345 SetVisible(true); |
| 347 if (resize_area_) | 346 if (resize_area_) |
| 348 resize_area_->SetBounds(0, 0, kItemSpacing, height()); | 347 resize_area_->SetBounds(0, 0, kItemSpacing, height()); |
| 349 | 348 |
| 350 // If the icons don't all fit, show the chevron (unless suppressed). | 349 // If the icons don't all fit, show the chevron (unless suppressed). |
| 351 int max_x = GetPreferredSize().width(); | 350 int max_x = GetPreferredSize().width(); |
| 352 if (IconCountToWidth(-1, false) > max_x && !suppress_chevron_ && chevron_) { | 351 if (IconCountToWidth(-1) > max_x && !suppress_chevron_ && chevron_) { |
| 353 chevron_->SetVisible(true); | 352 chevron_->SetVisible(true); |
| 354 gfx::Size chevron_size(chevron_->GetPreferredSize()); | 353 gfx::Size chevron_size(chevron_->GetPreferredSize()); |
| 355 max_x -= | 354 max_x -= chevron_size.width() + kChevronSpacing; |
| 356 ToolbarView::kStandardSpacing + chevron_size.width() + kChevronSpacing; | |
| 357 chevron_->SetBounds( | 355 chevron_->SetBounds( |
| 358 width() - ToolbarView::kStandardSpacing - chevron_size.width(), | 356 width() - ToolbarView::kStandardSpacing - chevron_size.width(), |
| 359 0, | 357 0, |
| 360 chevron_size.width(), | 358 chevron_size.width(), |
| 361 chevron_size.height()); | 359 chevron_size.height()); |
| 362 } else if (chevron_) { | 360 } else if (chevron_) { |
| 363 chevron_->SetVisible(false); | 361 chevron_->SetVisible(false); |
| 364 } | 362 } |
| 363 // Subtract off the trailing padding. |
| 364 max_x -= ToolbarView::kStandardSpacing; |
| 365 | 365 |
| 366 // Now draw the icons for the browser actions in the available space. | 366 // Now draw the icons for the browser actions in the available space. |
| 367 int icon_width = IconWidth(false); | 367 int icon_width = IconWidth(false); |
| 368 if (in_overflow_mode()) { | 368 if (in_overflow_mode()) { |
| 369 for (size_t i = 0; | 369 for (size_t i = 0; |
| 370 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { | 370 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { |
| 371 // Ensure that any browser actions shown in the main view are hidden in | 371 // Ensure that any browser actions shown in the main view are hidden in |
| 372 // the overflow view. | 372 // the overflow view. |
| 373 browser_action_views_[i]->SetVisible(false); | 373 browser_action_views_[i]->SetVisible(false); |
| 374 } | 374 } |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) { | 591 void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) { |
| 592 if (!done_resizing) { | 592 if (!done_resizing) { |
| 593 resize_amount_ = resize_amount; | 593 resize_amount_ = resize_amount; |
| 594 OnBrowserActionVisibilityChanged(); | 594 OnBrowserActionVisibilityChanged(); |
| 595 return; | 595 return; |
| 596 } | 596 } |
| 597 | 597 |
| 598 // Up until now we've only been modifying the resize_amount, but now it is | 598 // Up until now we've only been modifying the resize_amount, but now it is |
| 599 // time to set the container size to the size we have resized to, and then | 599 // time to set the container size to the size we have resized to, and then |
| 600 // animate to the nearest icon count size if necessary (which may be 0). | 600 // animate to the nearest icon count size if necessary (which may be 0). |
| 601 int max_width = IconCountToWidth(-1, false); | 601 int max_width = IconCountToWidth(-1); |
| 602 container_width_ = | 602 container_width_ = |
| 603 std::min(std::max(0, container_width_ - resize_amount), max_width); | 603 std::min(std::max(0, container_width_ - resize_amount), max_width); |
| 604 | 604 |
| 605 // Save off the desired number of visible icons. We do this now instead of at | 605 // Save off the desired number of visible icons. We do this now instead of at |
| 606 // the end of the animation so that even if the browser is shut down while | 606 // the end of the animation so that even if the browser is shut down while |
| 607 // animating, the right value will be restored on next run. | 607 // animating, the right value will be restored on next run. |
| 608 // NOTE: Don't save the icon count in incognito because there may be fewer | 608 // NOTE: Don't save the icon count in incognito because there may be fewer |
| 609 // icons in that mode. The result is that the container in a normal window is | 609 // icons in that mode. The result is that the container in a normal window is |
| 610 // always at least as wide as in an incognito window. | 610 // always at least as wide as in an incognito window. |
| 611 int visible_icons = WidthToIconCount(container_width_); | 611 int visible_icons = WidthToIconCount(container_width_); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 634 observers_, | 634 observers_, |
| 635 OnBrowserActionsContainerAnimationEnded()); | 635 OnBrowserActionsContainerAnimationEnded()); |
| 636 } | 636 } |
| 637 | 637 |
| 638 content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { | 638 content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { |
| 639 return browser_->tab_strip_model()->GetActiveWebContents(); | 639 return browser_->tab_strip_model()->GetActiveWebContents(); |
| 640 } | 640 } |
| 641 | 641 |
| 642 extensions::ActiveTabPermissionGranter* | 642 extensions::ActiveTabPermissionGranter* |
| 643 BrowserActionsContainer::GetActiveTabPermissionGranter() { | 643 BrowserActionsContainer::GetActiveTabPermissionGranter() { |
| 644 content::WebContents* web_contents = | 644 content::WebContents* web_contents = GetCurrentWebContents(); |
| 645 browser_->tab_strip_model()->GetActiveWebContents(); | |
| 646 if (!web_contents) | 645 if (!web_contents) |
| 647 return NULL; | 646 return NULL; |
| 648 return extensions::TabHelper::FromWebContents(web_contents)-> | 647 return extensions::TabHelper::FromWebContents(web_contents)-> |
| 649 active_tab_permission_granter(); | 648 active_tab_permission_granter(); |
| 650 } | 649 } |
| 651 | 650 |
| 652 ExtensionPopup* BrowserActionsContainer::TestGetPopup() { | 651 ExtensionPopup* BrowserActionsContainer::TestGetPopup() { |
| 653 return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL; | 652 return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL; |
| 654 } | 653 } |
| 655 | 654 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 CreateBrowserActionViews(); | 902 CreateBrowserActionViews(); |
| 904 Animate(gfx::Tween::LINEAR, GetIconCount()); | 903 Animate(gfx::Tween::LINEAR, GetIconCount()); |
| 905 } | 904 } |
| 906 | 905 |
| 907 Browser* BrowserActionsContainer::GetBrowser() { | 906 Browser* BrowserActionsContainer::GetBrowser() { |
| 908 return browser_; | 907 return browser_; |
| 909 } | 908 } |
| 910 | 909 |
| 911 void BrowserActionsContainer::LoadImages() { | 910 void BrowserActionsContainer::LoadImages() { |
| 912 ui::ThemeProvider* tp = GetThemeProvider(); | 911 ui::ThemeProvider* tp = GetThemeProvider(); |
| 913 if (!tp || !chevron_) | 912 if (tp && chevron_) { |
| 914 return; | 913 chevron_->SetImage(views::Button::STATE_NORMAL, |
| 915 | 914 *tp->GetImageSkiaNamed(IDR_BROWSER_ACTIONS_OVERFLOW)); |
| 916 chevron_->SetImage(views::Button::STATE_NORMAL, | 915 } |
| 917 *tp->GetImageSkiaNamed(IDR_BROWSER_ACTIONS_OVERFLOW)); | 916 // Highlighting only takes place on the main bar, so no need for it in |
| 918 | 917 // overflow. |
| 919 const int kImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT); | 918 if (!in_overflow_mode()) { |
| 920 highlight_painter_.reset(views::Painter::CreateImageGridPainter(kImages)); | 919 const int kImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT); |
| 920 highlight_painter_.reset(views::Painter::CreateImageGridPainter(kImages)); |
| 921 } |
| 921 } | 922 } |
| 922 | 923 |
| 923 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { | 924 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { |
| 924 SetVisible(!browser_action_views_.empty()); | 925 SetVisible(!browser_action_views_.empty()); |
| 925 if (owner_view_) { | 926 if (owner_view_) { |
| 926 owner_view_->Layout(); | 927 owner_view_->Layout(); |
| 927 owner_view_->SchedulePaint(); | 928 owner_view_->SchedulePaint(); |
| 928 } else { | 929 } else { |
| 929 // In overflow mode, we don't have an owner view, but we still have to | 930 // In overflow mode, we don't have an owner view, but we still have to |
| 930 // update ourselves. | 931 // update ourselves. |
| 931 Layout(); | 932 Layout(); |
| 932 SchedulePaint(); | 933 SchedulePaint(); |
| 933 } | 934 } |
| 934 } | 935 } |
| 935 | 936 |
| 936 int BrowserActionsContainer::GetPreferredWidth() { | 937 int BrowserActionsContainer::GetPreferredWidth() { |
| 937 size_t visible_actions = GetIconCount(); | 938 return IconCountToWidth(GetIconCount()); |
| 938 return IconCountToWidth( | |
| 939 visible_actions, | |
| 940 chevron_ && visible_actions < browser_action_views_.size()); | |
| 941 } | 939 } |
| 942 | 940 |
| 943 void BrowserActionsContainer::SetChevronVisibility() { | 941 void BrowserActionsContainer::SetChevronVisibility() { |
| 944 if (chevron_) { | 942 if (chevron_) { |
| 945 chevron_->SetVisible( | 943 chevron_->SetVisible( |
| 946 VisibleBrowserActionsAfterAnimation() < browser_action_views_.size()); | 944 VisibleBrowserActionsAfterAnimation() < browser_action_views_.size()); |
| 947 } | 945 } |
| 948 } | 946 } |
| 949 | 947 |
| 950 int BrowserActionsContainer::IconCountToWidth(int icons, | 948 int BrowserActionsContainer::IconCountToWidth(int icons) const { |
| 951 bool display_chevron) const { | |
| 952 if (icons < 0) | 949 if (icons < 0) |
| 953 icons = browser_action_views_.size(); | 950 icons = browser_action_views_.size(); |
| 954 if ((icons == 0) && !display_chevron) | 951 bool display_chevron = |
| 952 chevron_ && static_cast<size_t>(icons) < browser_action_views_.size(); |
| 953 if (icons == 0 && !display_chevron) |
| 955 return ToolbarView::kStandardSpacing; | 954 return ToolbarView::kStandardSpacing; |
| 956 int icons_size = | 955 int icons_size = |
| 957 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); | 956 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); |
| 958 int chevron_size = chevron_ && display_chevron ? | 957 int chevron_size = display_chevron ? |
| 959 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; | 958 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; |
| 960 // In overflow mode, our padding is to use item spacing on either end (just so | 959 // In overflow mode, our padding is to use item spacing on either end (just so |
| 961 // we can see the drop indicator). Otherwise we use the standard toolbar | 960 // we can see the drop indicator). Otherwise we use the standard toolbar |
| 962 // spacing. | 961 // spacing. |
| 963 // Note: These are actually the same thing, but, on the offchance one | 962 // Note: These are actually the same thing, but, on the offchance one |
| 964 // changes, let's get it right. | 963 // changes, let's get it right. |
| 965 int padding = | 964 int padding = |
| 966 2 * (in_overflow_mode() ? kItemSpacing : ToolbarView::kStandardSpacing); | 965 2 * (in_overflow_mode() ? kItemSpacing : ToolbarView::kStandardSpacing); |
| 967 return icons_size + chevron_size + padding; | 966 return icons_size + chevron_size + padding; |
| 968 } | 967 } |
| 969 | 968 |
| 970 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { | 969 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { |
| 971 // Check for widths large enough to show the entire icon set. | 970 // Check for widths large enough to show the entire icon set. |
| 972 if (pixels >= IconCountToWidth(-1, false)) | 971 if (pixels >= IconCountToWidth(-1)) |
| 973 return browser_action_views_.size(); | 972 return browser_action_views_.size(); |
| 974 | 973 |
| 975 // We reserve space for the padding on either side of the toolbar... | 974 // We reserve space for the padding on either side of the toolbar... |
| 976 int available_space = pixels - (ToolbarView::kStandardSpacing * 2); | 975 int available_space = pixels - (ToolbarView::kStandardSpacing * 2); |
| 977 // ... and, if the chevron is enabled, the chevron. | 976 // ... and, if the chevron is enabled, the chevron. |
| 978 if (chevron_) | 977 if (chevron_) |
| 979 available_space -= (chevron_->GetPreferredSize().width() + kChevronSpacing); | 978 available_space -= (chevron_->GetPreferredSize().width() + kChevronSpacing); |
| 980 | 979 |
| 981 // Now we add an extra between-item padding value so the space can be divided | 980 // Now we add an extra between-item padding value so the space can be divided |
| 982 // evenly by (size of icon with padding). | 981 // evenly by (size of icon with padding). |
| 983 return static_cast<size_t>( | 982 return static_cast<size_t>( |
| 984 std::max(0, available_space + kItemSpacing) / IconWidth(true)); | 983 std::max(0, available_space + kItemSpacing) / IconWidth(true)); |
| 985 } | 984 } |
| 986 | 985 |
| 987 int BrowserActionsContainer::MinimumNonemptyWidth() const { | 986 int BrowserActionsContainer::MinimumNonemptyWidth() const { |
| 988 if (!chevron_) | 987 if (!chevron_) |
| 989 return ToolbarView::kStandardSpacing; | 988 return ToolbarView::kStandardSpacing; |
| 990 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing + | 989 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing + |
| 991 chevron_->GetPreferredSize().width(); | 990 chevron_->GetPreferredSize().width(); |
| 992 } | 991 } |
| 993 | 992 |
| 994 void BrowserActionsContainer::Animate(gfx::Tween::Type tween_type, | 993 void BrowserActionsContainer::Animate(gfx::Tween::Type tween_type, |
| 995 size_t num_visible_icons) { | 994 size_t num_visible_icons) { |
| 996 int target_size = IconCountToWidth(num_visible_icons, | 995 int target_size = IconCountToWidth(num_visible_icons); |
| 997 num_visible_icons < browser_action_views_.size()); | |
| 998 if (resize_animation_ && !disable_animations_during_testing_) { | 996 if (resize_animation_ && !disable_animations_during_testing_) { |
| 999 // Animate! We have to set the animation_target_size_ after calling Reset(), | 997 // Animate! We have to set the animation_target_size_ after calling Reset(), |
| 1000 // because that could end up calling AnimationEnded which clears the value. | 998 // because that could end up calling AnimationEnded which clears the value. |
| 1001 resize_animation_->Reset(); | 999 resize_animation_->Reset(); |
| 1002 resize_animation_->SetTweenType(tween_type); | 1000 resize_animation_->SetTweenType(tween_type); |
| 1003 animation_target_size_ = target_size; | 1001 animation_target_size_ = target_size; |
| 1004 resize_animation_->Show(); | 1002 resize_animation_->Show(); |
| 1005 } else { | 1003 } else { |
| 1006 animation_target_size_ = target_size; | 1004 animation_target_size_ = target_size; |
| 1007 AnimationEnded(resize_animation_.get()); | 1005 AnimationEnded(resize_animation_.get()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 if (initialized_ && profile_->IsOffTheRecord()) { | 1043 if (initialized_ && profile_->IsOffTheRecord()) { |
| 1046 main_displayed = in_overflow_mode() ? | 1044 main_displayed = in_overflow_mode() ? |
| 1047 main_container_->VisibleBrowserActionsAfterAnimation() : | 1045 main_container_->VisibleBrowserActionsAfterAnimation() : |
| 1048 VisibleBrowserActionsAfterAnimation(); | 1046 VisibleBrowserActionsAfterAnimation(); |
| 1049 } | 1047 } |
| 1050 | 1048 |
| 1051 // The overflow displays any (displayable) icons not shown by the main bar. | 1049 // The overflow displays any (displayable) icons not shown by the main bar. |
| 1052 return in_overflow_mode() ? | 1050 return in_overflow_mode() ? |
| 1053 displayable_icon_count - main_displayed : main_displayed; | 1051 displayable_icon_count - main_displayed : main_displayed; |
| 1054 } | 1052 } |
| OLD | NEW |