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. | |
Peter Kasting
2014/10/02 21:49:56
Should we be doing this before we compare IconCoun
Devlin
2014/10/02 22:11:06
Nope. IconCountToWidth() will be the full width o
| |
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 if (!in_overflow_mode()) { |
918 | 917 // Highlighting only takes place on the main bar, so no need for it in |
919 const int kImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT); | 918 // overflow. |
Peter Kasting
2014/10/02 21:49:56
Nit: Put this comment above the conditional instea
Devlin
2014/10/02 22:11:06
Done.
| |
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_ && icons < static_cast<int>(browser_action_views_.size()); | |
Peter Kasting
2014/10/02 21:49:56
Nit: I think casting icons to size_t is probably b
Devlin
2014/10/02 22:11:06
Done.
| |
953 if (icons == 0 && !display_chevron) | |
955 return ToolbarView::kStandardSpacing; | 954 return ToolbarView::kStandardSpacing; |
956 int icons_size = | 955 int icons_size = icons == 0 ? 0 : ((icons * IconWidth(true)) - kItemSpacing); |
Peter Kasting
2014/10/02 21:49:56
Nit: Up to you, but I think the parens around the
Devlin
2014/10/02 22:11:06
Happy to defer to OWNER's preference. :) Done.
| |
957 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); | 956 int chevron_size = display_chevron ? |
958 int chevron_size = chevron_ && display_chevron ? | |
959 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; | 957 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; |
960 // In overflow mode, our padding is to use item spacing on either end (just so | 958 // 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 | 959 // we can see the drop indicator). Otherwise we use the standard toolbar |
962 // spacing. | 960 // spacing. |
963 // Note: These are actually the same thing, but, on the offchance one | 961 // Note: These are actually the same thing, but, on the offchance one |
964 // changes, let's get it right. | 962 // changes, let's get it right. |
965 int padding = | 963 int padding = |
966 2 * (in_overflow_mode() ? kItemSpacing : ToolbarView::kStandardSpacing); | 964 2 * (in_overflow_mode() ? kItemSpacing : ToolbarView::kStandardSpacing); |
967 return icons_size + chevron_size + padding; | 965 return icons_size + chevron_size + padding; |
968 } | 966 } |
969 | 967 |
970 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { | 968 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { |
971 // Check for widths large enough to show the entire icon set. | 969 // Check for widths large enough to show the entire icon set. |
972 if (pixels >= IconCountToWidth(-1, false)) | 970 if (pixels >= IconCountToWidth(-1)) |
973 return browser_action_views_.size(); | 971 return browser_action_views_.size(); |
974 | 972 |
975 // We reserve space for the padding on either side of the toolbar... | 973 // We reserve space for the padding on either side of the toolbar... |
976 int available_space = pixels - (ToolbarView::kStandardSpacing * 2); | 974 int available_space = pixels - (ToolbarView::kStandardSpacing * 2); |
977 // ... and, if the chevron is enabled, the chevron. | 975 // ... and, if the chevron is enabled, the chevron. |
978 if (chevron_) | 976 if (chevron_) |
979 available_space -= (chevron_->GetPreferredSize().width() + kChevronSpacing); | 977 available_space -= (chevron_->GetPreferredSize().width() + kChevronSpacing); |
980 | 978 |
981 // Now we add an extra between-item padding value so the space can be divided | 979 // Now we add an extra between-item padding value so the space can be divided |
982 // evenly by (size of icon with padding). | 980 // evenly by (size of icon with padding). |
983 return static_cast<size_t>( | 981 return static_cast<size_t>( |
984 std::max(0, available_space + kItemSpacing) / IconWidth(true)); | 982 std::max(0, available_space + kItemSpacing) / IconWidth(true)); |
985 } | 983 } |
986 | 984 |
987 int BrowserActionsContainer::MinimumNonemptyWidth() const { | 985 int BrowserActionsContainer::MinimumNonemptyWidth() const { |
988 if (!chevron_) | 986 if (!chevron_) |
989 return ToolbarView::kStandardSpacing; | 987 return ToolbarView::kStandardSpacing; |
990 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing + | 988 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing + |
991 chevron_->GetPreferredSize().width(); | 989 chevron_->GetPreferredSize().width(); |
992 } | 990 } |
993 | 991 |
994 void BrowserActionsContainer::Animate(gfx::Tween::Type tween_type, | 992 void BrowserActionsContainer::Animate(gfx::Tween::Type tween_type, |
995 size_t num_visible_icons) { | 993 size_t num_visible_icons) { |
996 int target_size = IconCountToWidth(num_visible_icons, | 994 int target_size = IconCountToWidth(num_visible_icons); |
997 num_visible_icons < browser_action_views_.size()); | |
998 if (resize_animation_ && !disable_animations_during_testing_) { | 995 if (resize_animation_ && !disable_animations_during_testing_) { |
999 // Animate! We have to set the animation_target_size_ after calling Reset(), | 996 // Animate! We have to set the animation_target_size_ after calling Reset(), |
1000 // because that could end up calling AnimationEnded which clears the value. | 997 // because that could end up calling AnimationEnded which clears the value. |
1001 resize_animation_->Reset(); | 998 resize_animation_->Reset(); |
1002 resize_animation_->SetTweenType(tween_type); | 999 resize_animation_->SetTweenType(tween_type); |
1003 animation_target_size_ = target_size; | 1000 animation_target_size_ = target_size; |
1004 resize_animation_->Show(); | 1001 resize_animation_->Show(); |
1005 } else { | 1002 } else { |
1006 animation_target_size_ = target_size; | 1003 animation_target_size_ = target_size; |
1007 AnimationEnded(resize_animation_.get()); | 1004 AnimationEnded(resize_animation_.get()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1045 if (initialized_ && profile_->IsOffTheRecord()) { | 1042 if (initialized_ && profile_->IsOffTheRecord()) { |
1046 main_displayed = in_overflow_mode() ? | 1043 main_displayed = in_overflow_mode() ? |
1047 main_container_->VisibleBrowserActionsAfterAnimation() : | 1044 main_container_->VisibleBrowserActionsAfterAnimation() : |
1048 VisibleBrowserActionsAfterAnimation(); | 1045 VisibleBrowserActionsAfterAnimation(); |
1049 } | 1046 } |
1050 | 1047 |
1051 // The overflow displays any (displayable) icons not shown by the main bar. | 1048 // The overflow displays any (displayable) icons not shown by the main bar. |
1052 return in_overflow_mode() ? | 1049 return in_overflow_mode() ? |
1053 displayable_icon_count - main_displayed : main_displayed; | 1050 displayable_icon_count - main_displayed : main_displayed; |
1054 } | 1051 } |
OLD | NEW |