| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/tabs/tab.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
| 11 #include "base/profiler/scoped_tracker.h" | 11 #include "base/profiler/scoped_tracker.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "chrome/browser/themes/theme_properties.h" | 13 #include "chrome/browser/themes/theme_properties.h" |
| 14 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
| 15 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" | 15 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" |
| 16 #include "chrome/browser/ui/tabs/tab_utils.h" | 16 #include "chrome/browser/ui/tabs/tab_utils.h" |
| 17 #include "chrome/browser/ui/view_ids.h" | 17 #include "chrome/browser/ui/view_ids.h" |
| 18 #include "chrome/browser/ui/views/layout_constants.h" |
| 18 #include "chrome/browser/ui/views/tabs/media_indicator_button.h" | 19 #include "chrome/browser/ui/views/tabs/media_indicator_button.h" |
| 19 #include "chrome/browser/ui/views/tabs/tab_controller.h" | 20 #include "chrome/browser/ui/views/tabs/tab_controller.h" |
| 20 #include "chrome/browser/ui/views/theme_image_mapper.h" | 21 #include "chrome/browser/ui/views/theme_image_mapper.h" |
| 21 #include "chrome/browser/ui/views/touch_uma/touch_uma.h" | 22 #include "chrome/browser/ui/views/touch_uma/touch_uma.h" |
| 22 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
| 23 #include "chrome/grit/generated_resources.h" | 24 #include "chrome/grit/generated_resources.h" |
| 24 #include "content/public/browser/user_metrics.h" | 25 #include "content/public/browser/user_metrics.h" |
| 25 #include "grit/theme_resources.h" | 26 #include "grit/theme_resources.h" |
| 26 #include "third_party/skia/include/effects/SkGradientShader.h" | 27 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 27 #include "ui/accessibility/ax_view_state.h" | 28 #include "ui/accessibility/ax_view_state.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 50 #include "ui/views/window/non_client_view.h" | 51 #include "ui/views/window/non_client_view.h" |
| 51 | 52 |
| 52 #if defined(USE_AURA) | 53 #if defined(USE_AURA) |
| 53 #include "ui/aura/env.h" | 54 #include "ui/aura/env.h" |
| 54 #endif | 55 #endif |
| 55 | 56 |
| 56 using base::UserMetricsAction; | 57 using base::UserMetricsAction; |
| 57 | 58 |
| 58 namespace { | 59 namespace { |
| 59 | 60 |
| 60 // Padding around the "content" of a tab, occupied by the tab border graphics. | |
| 61 const int kLeftPadding = 20; | |
| 62 const int kTopPadding = 4; | |
| 63 const int kRightPadding = 20; | |
| 64 const int kBottomPadding = 2; | |
| 65 | |
| 66 // Height of the shadow at the top of the tab image assets. | 61 // Height of the shadow at the top of the tab image assets. |
| 67 const int kDropShadowHeight = 4; | 62 const int kDropShadowHeight = 4; |
| 68 | 63 |
| 69 // How long the pulse throb takes. | 64 // How long the pulse throb takes. |
| 70 const int kPulseDurationMs = 200; | 65 const int kPulseDurationMs = 200; |
| 71 | 66 |
| 72 // Width of touch tabs. | 67 // Width of touch tabs. |
| 73 const int kTouchWidth = 120; | 68 const int kTouchWidth = 120; |
| 74 | 69 |
| 75 const int kToolbarOverlap = 1; | 70 const int kToolbarOverlap = 1; |
| 76 const int kExtraLeftPaddingToBalanceCloseButtonPadding = 2; | 71 const int kExtraLeftPaddingToBalanceCloseButtonPadding = 2; |
| 77 const int kFaviconTitleSpacing = 4; | |
| 78 const int kAfterTitleSpacing = 3; | 72 const int kAfterTitleSpacing = 3; |
| 79 const int kCloseButtonRightPaddingOverlap = 3; | |
| 80 const int kStandardTitleWidth = 175; | |
| 81 | |
| 82 // Width of the content inside a pinned tab. | |
| 83 int kPinnedTabContentWidth = 25; | |
| 84 | 73 |
| 85 // When a non-pinned tab becomes a pinned tab the width of the tab animates. If | 74 // When a non-pinned tab becomes a pinned tab the width of the tab animates. If |
| 86 // the width of a pinned tab is at least kPinnedTabExtraWidthToRenderAsNormal | 75 // the width of a pinned tab is at least kPinnedTabExtraWidthToRenderAsNormal |
| 87 // larger than the desired pinned tab width then the tab is rendered as a normal | 76 // larger than the desired pinned tab width then the tab is rendered as a normal |
| 88 // tab. This is done to avoid having the title immediately disappear when | 77 // tab. This is done to avoid having the title immediately disappear when |
| 89 // transitioning a tab from normal to pinned tab. | 78 // transitioning a tab from normal to pinned tab. |
| 90 const int kPinnedTabExtraWidthToRenderAsNormal = 30; | 79 const int kPinnedTabExtraWidthToRenderAsNormal = 30; |
| 91 | 80 |
| 92 // How opaque to make the hover state (out of 1). | 81 // How opaque to make the hover state (out of 1). |
| 93 const double kHoverOpacity = 0.33; | 82 const double kHoverOpacity = 0.33; |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 const int close_button_left = showing_close_button_ ? | 600 const int close_button_left = showing_close_button_ ? |
| 612 close_button_->x() : width(); | 601 close_button_->x() : width(); |
| 613 return std::min(indicator_left, close_button_left); | 602 return std::min(indicator_left, close_button_left); |
| 614 } | 603 } |
| 615 | 604 |
| 616 gfx::Size Tab::GetMinimumUnselectedSize() { | 605 gfx::Size Tab::GetMinimumUnselectedSize() { |
| 617 // Since we use images, the real minimum height of the image is | 606 // Since we use images, the real minimum height of the image is |
| 618 // defined most accurately by the height of the end cap images. | 607 // defined most accurately by the height of the end cap images. |
| 619 InitTabResources(); | 608 InitTabResources(); |
| 620 int height = tab_active_.image_l->height(); | 609 int height = tab_active_.image_l->height(); |
| 621 return gfx::Size(kLeftPadding + kRightPadding, height); | 610 return gfx::Size(GetLayoutInsets(TAB).width(), height); |
| 622 } | 611 } |
| 623 | 612 |
| 624 // static | 613 // static |
| 625 gfx::Size Tab::GetMinimumSelectedSize() { | 614 gfx::Size Tab::GetMinimumSelectedSize() { |
| 626 gfx::Size minimum_size = GetMinimumUnselectedSize(); | 615 gfx::Size minimum_size = GetMinimumUnselectedSize(); |
| 627 minimum_size.Enlarge(gfx::kFaviconSize, 0); | 616 minimum_size.Enlarge(gfx::kFaviconSize, 0); |
| 628 return minimum_size; | 617 return minimum_size; |
| 629 } | 618 } |
| 630 | 619 |
| 631 // static | 620 // static |
| 632 gfx::Size Tab::GetStandardSize() { | 621 gfx::Size Tab::GetStandardSize() { |
| 633 gfx::Size standard_size = GetMinimumUnselectedSize(); | 622 gfx::Size standard_size = GetMinimumUnselectedSize(); |
| 634 standard_size.Enlarge(kFaviconTitleSpacing + kStandardTitleWidth, 0); | 623 const int title_spacing = GetLayoutConstant(TAB_FAVICON_TITLE_SPACING); |
| 624 const int title_width = GetLayoutConstant(TAB_MAXIMUM_TITLE_WIDTH); |
| 625 standard_size.Enlarge(title_spacing + title_width, 0); |
| 635 return standard_size; | 626 return standard_size; |
| 636 } | 627 } |
| 637 | 628 |
| 638 // static | 629 // static |
| 639 int Tab::GetTouchWidth() { | 630 int Tab::GetTouchWidth() { |
| 640 return kTouchWidth; | 631 return kTouchWidth; |
| 641 } | 632 } |
| 642 | 633 |
| 643 // static | 634 // static |
| 644 int Tab::GetPinnedWidth() { | 635 int Tab::GetPinnedWidth() { |
| 645 return GetMinimumUnselectedSize().width() + kPinnedTabContentWidth; | 636 return GetMinimumUnselectedSize().width() + |
| 637 GetLayoutConstant(TAB_PINNED_CONTENT_WIDTH); |
| 646 } | 638 } |
| 647 | 639 |
| 648 // static | 640 // static |
| 649 int Tab::GetImmersiveHeight() { | 641 int Tab::GetImmersiveHeight() { |
| 650 return kImmersiveTabHeight; | 642 return kImmersiveTabHeight; |
| 651 } | 643 } |
| 652 | 644 |
| 653 //////////////////////////////////////////////////////////////////////////////// | 645 //////////////////////////////////////////////////////////////////////////////// |
| 654 // Tab, AnimationDelegate overrides: | 646 // Tab, AnimationDelegate overrides: |
| 655 | 647 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 | 748 |
| 757 if (!clip.IsEmpty()) | 749 if (!clip.IsEmpty()) |
| 758 canvas->Restore(); | 750 canvas->Restore(); |
| 759 } | 751 } |
| 760 | 752 |
| 761 void Tab::Layout() { | 753 void Tab::Layout() { |
| 762 gfx::Rect lb = GetContentsBounds(); | 754 gfx::Rect lb = GetContentsBounds(); |
| 763 if (lb.IsEmpty()) | 755 if (lb.IsEmpty()) |
| 764 return; | 756 return; |
| 765 | 757 |
| 766 lb.Inset(kLeftPadding, kTopPadding, kRightPadding, kBottomPadding); | 758 lb.Inset(GetLayoutInsets(TAB)); |
| 767 showing_icon_ = ShouldShowIcon(); | 759 showing_icon_ = ShouldShowIcon(); |
| 768 // See comments in IconCapacity(). | 760 // See comments in IconCapacity(). |
| 769 const int extra_padding = | 761 const int extra_padding = |
| 770 (controller_->ShouldHideCloseButtonForInactiveTabs() || | 762 (controller_->ShouldHideCloseButtonForInactiveTabs() || |
| 771 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding; | 763 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding; |
| 772 const int start = lb.x() + extra_padding; | 764 const int start = lb.x() + extra_padding; |
| 773 favicon_bounds_.SetRect(start, lb.y(), 0, 0); | 765 favicon_bounds_.SetRect(start, lb.y(), 0, 0); |
| 774 if (showing_icon_) { | 766 if (showing_icon_) { |
| 775 favicon_bounds_.set_size(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize)); | 767 favicon_bounds_.set_size(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize)); |
| 776 favicon_bounds_.set_y(lb.y() + (lb.height() - gfx::kFaviconSize + 1) / 2); | 768 favicon_bounds_.set_y(lb.y() + (lb.height() - gfx::kFaviconSize + 1) / 2); |
| 777 MaybeAdjustLeftForPinnedTab(&favicon_bounds_); | 769 MaybeAdjustLeftForPinnedTab(&favicon_bounds_); |
| 778 } | 770 } |
| 779 | 771 |
| 780 showing_close_button_ = ShouldShowCloseBox(); | 772 showing_close_button_ = ShouldShowCloseBox(); |
| 781 if (showing_close_button_) { | 773 if (showing_close_button_) { |
| 782 // If the ratio of the close button size to tab width exceeds the maximum. | 774 // If the ratio of the close button size to tab width exceeds the maximum. |
| 783 // The close button should be as large as possible so that there is a larger | 775 // The close button should be as large as possible so that there is a larger |
| 784 // hit-target for touch events. So the close button bounds extends to the | 776 // hit-target for touch events. So the close button bounds extends to the |
| 785 // edges of the tab. However, the larger hit-target should be active only | 777 // edges of the tab. However, the larger hit-target should be active only |
| 786 // for mouse events, and the close-image should show up in the right place. | 778 // for mouse events, and the close-image should show up in the right place. |
| 787 // So a border is added to the button with necessary padding. The close | 779 // So a border is added to the button with necessary padding. The close |
| 788 // button (BaseTab::TabCloseButton) makes sure the padding is a hit-target | 780 // button (BaseTab::TabCloseButton) makes sure the padding is a hit-target |
| 789 // only for touch events. | 781 // only for touch events. |
| 790 close_button_->SetBorder(views::Border::NullBorder()); | 782 close_button_->SetBorder(views::Border::NullBorder()); |
| 791 const gfx::Size close_button_size(close_button_->GetPreferredSize()); | 783 const gfx::Size close_button_size(close_button_->GetPreferredSize()); |
| 792 const int top = lb.y() + (lb.height() - close_button_size.height() + 1) / 2; | 784 const int top = lb.y() + (lb.height() - close_button_size.height() + 1) / 2; |
| 793 const int left = kAfterTitleSpacing; | 785 const int left = kAfterTitleSpacing; |
| 794 const int close_button_end = lb.right() + kCloseButtonRightPaddingOverlap; | 786 const int close_button_end = lb.right() + |
| 787 GetLayoutConstant(TAB_CLOSE_BUTTON_TRAILING_PADDING_OVERLAP); |
| 795 close_button_->SetPosition( | 788 close_button_->SetPosition( |
| 796 gfx::Point(close_button_end - close_button_size.width() - left, 0)); | 789 gfx::Point(close_button_end - close_button_size.width() - left, 0)); |
| 797 const int bottom = height() - close_button_size.height() - top; | 790 const int bottom = height() - close_button_size.height() - top; |
| 798 const int right = width() - close_button_end; | 791 const int right = width() - close_button_end; |
| 799 close_button_->SetBorder( | 792 close_button_->SetBorder( |
| 800 views::Border::CreateEmptyBorder(top, left, bottom, right)); | 793 views::Border::CreateEmptyBorder(top, left, bottom, right)); |
| 801 close_button_->SizeToPreferredSize(); | 794 close_button_->SizeToPreferredSize(); |
| 802 } | 795 } |
| 803 close_button_->SetVisible(showing_close_button_); | 796 close_button_->SetVisible(showing_close_button_); |
| 804 | 797 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 816 MaybeAdjustLeftForPinnedTab(&bounds); | 809 MaybeAdjustLeftForPinnedTab(&bounds); |
| 817 button->SetBoundsRect(bounds); | 810 button->SetBoundsRect(bounds); |
| 818 button->SetVisible(true); | 811 button->SetVisible(true); |
| 819 } else if (media_indicator_button_) { | 812 } else if (media_indicator_button_) { |
| 820 media_indicator_button_->SetVisible(false); | 813 media_indicator_button_->SetVisible(false); |
| 821 } | 814 } |
| 822 | 815 |
| 823 // Size the title to fill the remaining width and use all available height. | 816 // Size the title to fill the remaining width and use all available height. |
| 824 const bool show_title = ShouldRenderAsNormalTab(); | 817 const bool show_title = ShouldRenderAsNormalTab(); |
| 825 if (show_title) { | 818 if (show_title) { |
| 819 const int title_spacing = GetLayoutConstant(TAB_FAVICON_TITLE_SPACING); |
| 826 int title_left = showing_icon_ ? | 820 int title_left = showing_icon_ ? |
| 827 (favicon_bounds_.right() + kFaviconTitleSpacing) : start; | 821 (favicon_bounds_.right() + title_spacing) : start; |
| 828 int title_width = lb.right() - title_left; | 822 int title_width = lb.right() - title_left; |
| 829 if (showing_media_indicator_) { | 823 if (showing_media_indicator_) { |
| 830 title_width = | 824 title_width = |
| 831 media_indicator_button_->x() - kAfterTitleSpacing - title_left; | 825 media_indicator_button_->x() - kAfterTitleSpacing - title_left; |
| 832 } else if (close_button_->visible()) { | 826 } else if (close_button_->visible()) { |
| 833 // Allow the title to overlay the close button's empty border padding. | 827 // Allow the title to overlay the close button's empty border padding. |
| 834 title_width = close_button_->x() + close_button_->GetInsets().left() - | 828 title_width = close_button_->x() + close_button_->GetInsets().left() - |
| 835 kAfterTitleSpacing - title_left; | 829 kAfterTitleSpacing - title_left; |
| 836 } | 830 } |
| 837 gfx::Rect rect(title_left, lb.y(), std::max(title_width, 0), lb.height()); | 831 gfx::Rect rect(title_left, lb.y(), std::max(title_width, 0), lb.height()); |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 const gfx::ImageSkia& image) { | 1663 const gfx::ImageSkia& image) { |
| 1670 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1664 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
| 1671 ImageCacheEntry entry; | 1665 ImageCacheEntry entry; |
| 1672 entry.resource_id = resource_id; | 1666 entry.resource_id = resource_id; |
| 1673 entry.scale_factor = scale_factor; | 1667 entry.scale_factor = scale_factor; |
| 1674 entry.image = image; | 1668 entry.image = image; |
| 1675 image_cache_->push_front(entry); | 1669 image_cache_->push_front(entry); |
| 1676 if (image_cache_->size() > kMaxImageCacheSize) | 1670 if (image_cache_->size() > kMaxImageCacheSize) |
| 1677 image_cache_->pop_back(); | 1671 image_cache_->pop_back(); |
| 1678 } | 1672 } |
| OLD | NEW |