| 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/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "chrome/browser/defaults.h" | 12 #include "chrome/browser/defaults.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_resources.h" | 16 #include "chrome/browser/ui/tabs/tab_resources.h" |
| 17 #include "chrome/browser/ui/tabs/tab_utils.h" | 17 #include "chrome/browser/ui/tabs/tab_utils.h" |
| 18 #include "chrome/browser/ui/view_ids.h" | 18 #include "chrome/browser/ui/view_ids.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" |
| 25 #include "content/public/browser/user_metrics.h" |
| 24 #include "grit/theme_resources.h" | 26 #include "grit/theme_resources.h" |
| 25 #include "third_party/skia/include/effects/SkGradientShader.h" | 27 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 26 #include "ui/accessibility/ax_view_state.h" | 28 #include "ui/accessibility/ax_view_state.h" |
| 27 #include "ui/aura/env.h" | 29 #include "ui/aura/env.h" |
| 28 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| 29 #include "ui/base/models/list_selection_model.h" | 31 #include "ui/base/models/list_selection_model.h" |
| 30 #include "ui/base/resource/resource_bundle.h" | 32 #include "ui/base/resource/resource_bundle.h" |
| 31 #include "ui/base/theme_provider.h" | 33 #include "ui/base/theme_provider.h" |
| 32 #include "ui/gfx/animation/animation_container.h" | 34 #include "ui/gfx/animation/animation_container.h" |
| 33 #include "ui/gfx/animation/multi_animation.h" | 35 #include "ui/gfx/animation/multi_animation.h" |
| 34 #include "ui/gfx/animation/throb_animation.h" | 36 #include "ui/gfx/animation/throb_animation.h" |
| 35 #include "ui/gfx/canvas.h" | 37 #include "ui/gfx/canvas.h" |
| 36 #include "ui/gfx/color_analysis.h" | 38 #include "ui/gfx/color_analysis.h" |
| 37 #include "ui/gfx/favicon_size.h" | 39 #include "ui/gfx/favicon_size.h" |
| 38 #include "ui/gfx/image/image_skia_operations.h" | 40 #include "ui/gfx/image/image_skia_operations.h" |
| 39 #include "ui/gfx/path.h" | 41 #include "ui/gfx/path.h" |
| 40 #include "ui/gfx/rect_conversions.h" | 42 #include "ui/gfx/rect_conversions.h" |
| 41 #include "ui/gfx/skia_util.h" | 43 #include "ui/gfx/skia_util.h" |
| 42 #include "ui/resources/grit/ui_resources.h" | 44 #include "ui/resources/grit/ui_resources.h" |
| 43 #include "ui/views/border.h" | 45 #include "ui/views/border.h" |
| 44 #include "ui/views/controls/button/image_button.h" | 46 #include "ui/views/controls/button/image_button.h" |
| 45 #include "ui/views/controls/label.h" | 47 #include "ui/views/controls/label.h" |
| 46 #include "ui/views/rect_based_targeting_utils.h" | 48 #include "ui/views/rect_based_targeting_utils.h" |
| 47 #include "ui/views/view_targeter.h" | 49 #include "ui/views/view_targeter.h" |
| 48 #include "ui/views/widget/tooltip_manager.h" | 50 #include "ui/views/widget/tooltip_manager.h" |
| 49 #include "ui/views/widget/widget.h" | 51 #include "ui/views/widget/widget.h" |
| 50 #include "ui/views/window/non_client_view.h" | 52 #include "ui/views/window/non_client_view.h" |
| 51 | 53 |
| 54 using base::UserMetricsAction; |
| 55 |
| 52 namespace { | 56 namespace { |
| 53 | 57 |
| 54 // Padding around the "content" of a tab, occupied by the tab border graphics. | 58 // Padding around the "content" of a tab, occupied by the tab border graphics. |
| 55 const int kLeftPadding = 22; | 59 const int kLeftPadding = 22; |
| 56 const int kTopPadding = 4; | 60 const int kTopPadding = 4; |
| 57 const int kRightPadding = 17; | 61 const int kRightPadding = 17; |
| 58 const int kBottomPadding = 2; | 62 const int kBottomPadding = 2; |
| 59 | 63 |
| 60 // Height of the shadow at the top of the tab image assets. | 64 // Height of the shadow at the top of the tab image assets. |
| 61 const int kDropShadowHeight = 4; | 65 const int kDropShadowHeight = 4; |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 | 406 |
| 403 Tab::Tab(TabController* controller) | 407 Tab::Tab(TabController* controller) |
| 404 : controller_(controller), | 408 : controller_(controller), |
| 405 closing_(false), | 409 closing_(false), |
| 406 dragging_(false), | 410 dragging_(false), |
| 407 detached_(false), | 411 detached_(false), |
| 408 favicon_hiding_offset_(0), | 412 favicon_hiding_offset_(0), |
| 409 loading_animation_frame_(0), | 413 loading_animation_frame_(0), |
| 410 immersive_loading_step_(0), | 414 immersive_loading_step_(0), |
| 411 should_display_crashed_favicon_(false), | 415 should_display_crashed_favicon_(false), |
| 412 animating_media_state_(TAB_MEDIA_STATE_NONE), | |
| 413 close_button_(NULL), | 416 close_button_(NULL), |
| 417 media_indicator_button_(NULL), |
| 414 title_(new views::Label()), | 418 title_(new views::Label()), |
| 415 tab_activated_with_last_tap_down_(false), | 419 tab_activated_with_last_tap_down_(false), |
| 416 hover_controller_(this), | 420 hover_controller_(this), |
| 417 showing_icon_(false), | 421 showing_icon_(false), |
| 418 showing_media_indicator_(false), | 422 showing_media_indicator_(false), |
| 419 showing_close_button_(false), | 423 showing_close_button_(false), |
| 420 close_button_color_(0) { | 424 close_button_color_(0) { |
| 421 DCHECK(controller); | 425 DCHECK(controller); |
| 422 InitTabResources(); | 426 InitTabResources(); |
| 423 | 427 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 #else | 506 #else |
| 503 StartCrashAnimation(); | 507 StartCrashAnimation(); |
| 504 #endif | 508 #endif |
| 505 } | 509 } |
| 506 } else { | 510 } else { |
| 507 if (IsPerformingCrashAnimation()) | 511 if (IsPerformingCrashAnimation()) |
| 508 StopCrashAnimation(); | 512 StopCrashAnimation(); |
| 509 ResetCrashedFavicon(); | 513 ResetCrashedFavicon(); |
| 510 } | 514 } |
| 511 | 515 |
| 512 if (data_.media_state != old.media_state) { | 516 if (data_.media_state != old.media_state) |
| 513 if (data_.media_state != TAB_MEDIA_STATE_NONE) | 517 GetMediaIndicatorButton()->TransitionToMediaState(data_.media_state); |
| 514 animating_media_state_ = data_.media_state; | |
| 515 StartMediaIndicatorAnimation(); | |
| 516 } | |
| 517 | 518 |
| 518 if (old.mini != data_.mini) { | 519 if (old.mini != data_.mini) { |
| 519 StopAndDeleteAnimation( | 520 StopAndDeleteAnimation( |
| 520 mini_title_change_animation_.PassAs<gfx::Animation>()); | 521 mini_title_change_animation_.PassAs<gfx::Animation>()); |
| 521 } | 522 } |
| 522 | 523 |
| 523 DataChanged(old); | 524 DataChanged(old); |
| 524 | 525 |
| 525 Layout(); | 526 Layout(); |
| 526 SchedulePaint(); | 527 SchedulePaint(); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 | 636 |
| 636 void Tab::AnimationProgressed(const gfx::Animation* animation) { | 637 void Tab::AnimationProgressed(const gfx::Animation* animation) { |
| 637 // Ignore if the pulse animation is being performed on active tab because | 638 // Ignore if the pulse animation is being performed on active tab because |
| 638 // it repaints the same image. See |Tab::PaintTabBackground()|. | 639 // it repaints the same image. See |Tab::PaintTabBackground()|. |
| 639 if (animation == pulse_animation_.get() && IsActive()) | 640 if (animation == pulse_animation_.get() && IsActive()) |
| 640 return; | 641 return; |
| 641 SchedulePaint(); | 642 SchedulePaint(); |
| 642 } | 643 } |
| 643 | 644 |
| 644 void Tab::AnimationCanceled(const gfx::Animation* animation) { | 645 void Tab::AnimationCanceled(const gfx::Animation* animation) { |
| 645 if (media_indicator_animation_ == animation) | |
| 646 animating_media_state_ = data_.media_state; | |
| 647 SchedulePaint(); | 646 SchedulePaint(); |
| 648 } | 647 } |
| 649 | 648 |
| 650 void Tab::AnimationEnded(const gfx::Animation* animation) { | 649 void Tab::AnimationEnded(const gfx::Animation* animation) { |
| 651 if (media_indicator_animation_ == animation) | |
| 652 animating_media_state_ = data_.media_state; | |
| 653 SchedulePaint(); | 650 SchedulePaint(); |
| 654 } | 651 } |
| 655 | 652 |
| 656 //////////////////////////////////////////////////////////////////////////////// | 653 //////////////////////////////////////////////////////////////////////////////// |
| 657 // Tab, views::ButtonListener overrides: | 654 // Tab, views::ButtonListener overrides: |
| 658 | 655 |
| 659 void Tab::ButtonPressed(views::Button* sender, const ui::Event& event) { | 656 void Tab::ButtonPressed(views::Button* sender, const ui::Event& event) { |
| 657 if (media_indicator_button_ && media_indicator_button_->visible()) { |
| 658 if (media_indicator_button_->enabled()) |
| 659 content::RecordAction(UserMetricsAction("CloseTab_MuteToggleAvailable")); |
| 660 else if (data_.media_state == TAB_MEDIA_STATE_AUDIO_PLAYING) |
| 661 content::RecordAction(UserMetricsAction("CloseTab_AudioIndicator")); |
| 662 else |
| 663 content::RecordAction(UserMetricsAction("CloseTab_RecordingIndicator")); |
| 664 } else { |
| 665 content::RecordAction(UserMetricsAction("CloseTab_NoMediaIndicator")); |
| 666 } |
| 667 |
| 660 const CloseTabSource source = | 668 const CloseTabSource source = |
| 661 (event.type() == ui::ET_MOUSE_RELEASED && | 669 (event.type() == ui::ET_MOUSE_RELEASED && |
| 662 (event.flags() & ui::EF_FROM_TOUCH) == 0) ? CLOSE_TAB_FROM_MOUSE : | 670 (event.flags() & ui::EF_FROM_TOUCH) == 0) ? CLOSE_TAB_FROM_MOUSE : |
| 663 CLOSE_TAB_FROM_TOUCH; | 671 CLOSE_TAB_FROM_TOUCH; |
| 664 DCHECK_EQ(close_button_, sender); | 672 DCHECK_EQ(close_button_, sender); |
| 665 controller_->CloseTab(this, source); | 673 controller_->CloseTab(this, source); |
| 666 if (event.type() == ui::ET_GESTURE_TAP) | 674 if (event.type() == ui::ET_GESTURE_TAP) |
| 667 TouchUMA::RecordGestureAction(TouchUMA::GESTURE_TABCLOSE_TAP); | 675 TouchUMA::RecordGestureAction(TouchUMA::GESTURE_TABCLOSE_TAP); |
| 668 } | 676 } |
| 669 | 677 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 const int left = kViewSpacing; | 771 const int left = kViewSpacing; |
| 764 const int right = width() - (lb.width() + close_button_size.width() + left); | 772 const int right = width() - (lb.width() + close_button_size.width() + left); |
| 765 close_button_->SetBorder( | 773 close_button_->SetBorder( |
| 766 views::Border::CreateEmptyBorder(top, left, bottom, right)); | 774 views::Border::CreateEmptyBorder(top, left, bottom, right)); |
| 767 close_button_->SetPosition(gfx::Point(lb.width(), 0)); | 775 close_button_->SetPosition(gfx::Point(lb.width(), 0)); |
| 768 close_button_->SizeToPreferredSize(); | 776 close_button_->SizeToPreferredSize(); |
| 769 } | 777 } |
| 770 close_button_->SetVisible(showing_close_button_); | 778 close_button_->SetVisible(showing_close_button_); |
| 771 | 779 |
| 772 showing_media_indicator_ = ShouldShowMediaIndicator(); | 780 showing_media_indicator_ = ShouldShowMediaIndicator(); |
| 773 media_indicator_bounds_.SetRect(lb.x(), lb.y(), 0, 0); | |
| 774 if (showing_media_indicator_) { | 781 if (showing_media_indicator_) { |
| 775 const gfx::Image& media_indicator_image = | 782 views::ImageButton* const button = GetMediaIndicatorButton(); |
| 776 chrome::GetTabMediaIndicatorImage(animating_media_state_); | 783 const gfx::Size image_size(button->GetPreferredSize()); |
| 777 media_indicator_bounds_.set_width(media_indicator_image.Width()); | |
| 778 media_indicator_bounds_.set_height(media_indicator_image.Height()); | |
| 779 media_indicator_bounds_.set_y( | |
| 780 lb.y() + (lb.height() - media_indicator_bounds_.height() + 1) / 2); | |
| 781 const int right = showing_close_button_ ? | 784 const int right = showing_close_button_ ? |
| 782 close_button_->x() + close_button_->GetInsets().left() : lb.right(); | 785 close_button_->x() + close_button_->GetInsets().left() : lb.right(); |
| 783 media_indicator_bounds_.set_x( | 786 gfx::Rect bounds( |
| 784 std::max(lb.x(), right - media_indicator_bounds_.width())); | 787 std::max(lb.x(), right - image_size.width()), |
| 785 MaybeAdjustLeftForMiniTab(&media_indicator_bounds_); | 788 lb.y() + (lb.height() - image_size.height() + 1) / 2, |
| 789 image_size.width(), |
| 790 image_size.height()); |
| 791 MaybeAdjustLeftForMiniTab(&bounds); |
| 792 button->SetBoundsRect(bounds); |
| 793 button->SetVisible(true); |
| 794 } else if (media_indicator_button_) { |
| 795 media_indicator_button_->SetVisible(false); |
| 786 } | 796 } |
| 787 | 797 |
| 788 // Size the title to fill the remaining width and use all available height. | 798 // Size the title to fill the remaining width and use all available height. |
| 789 bool show_title = !data().mini || width() >= kMiniTabRendererAsNormalTabWidth; | 799 bool show_title = !data().mini || width() >= kMiniTabRendererAsNormalTabWidth; |
| 790 if (show_title) { | 800 if (show_title) { |
| 791 int title_left = favicon_bounds_.right() + kFaviconTitleSpacing; | 801 int title_left = favicon_bounds_.right() + kFaviconTitleSpacing; |
| 792 int title_width = lb.width() - title_left; | 802 int title_width = lb.width() - title_left; |
| 793 if (showing_media_indicator_) { | 803 if (showing_media_indicator_) { |
| 794 title_width = media_indicator_bounds_.x() - kViewSpacing - title_left; | 804 title_width = media_indicator_button_->x() - kViewSpacing - title_left; |
| 795 } else if (close_button_->visible()) { | 805 } else if (close_button_->visible()) { |
| 796 // Allow the title to overlay the close button's empty border padding. | 806 // Allow the title to overlay the close button's empty border padding. |
| 797 title_width = close_button_->x() + close_button_->GetInsets().left() - | 807 title_width = close_button_->x() + close_button_->GetInsets().left() - |
| 798 kViewSpacing - title_left; | 808 kViewSpacing - title_left; |
| 799 } | 809 } |
| 800 gfx::Rect rect(title_left, lb.y(), std::max(title_width, 0), lb.height()); | 810 gfx::Rect rect(title_left, lb.y(), std::max(title_width, 0), lb.height()); |
| 801 const int title_height = title_->GetPreferredSize().height(); | 811 const int title_height = title_->GetPreferredSize().height(); |
| 802 if (title_height > rect.height()) { | 812 if (title_height > rect.height()) { |
| 803 rect.set_y(lb.y() - (title_height - rect.height()) / 2); | 813 rect.set_y(lb.y() - (title_height - rect.height()) / 2); |
| 804 rect.set_height(title_height); | 814 rect.set_height(title_height); |
| 805 } | 815 } |
| 806 rect.set_x(GetMirroredXForRect(rect)); | |
| 807 title_->SetBoundsRect(rect); | 816 title_->SetBoundsRect(rect); |
| 808 } | 817 } |
| 809 title_->SetVisible(show_title); | 818 title_->SetVisible(show_title); |
| 810 } | 819 } |
| 811 | 820 |
| 812 void Tab::OnThemeChanged() { | 821 void Tab::OnThemeChanged() { |
| 813 LoadTabImages(); | 822 LoadTabImages(); |
| 814 } | 823 } |
| 815 | 824 |
| 816 const char* Tab::GetClassName() const { | 825 const char* Tab::GetClassName() const { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 Tab* closest_tab = controller_->GetTabAt(this, event.location()); | 906 Tab* closest_tab = controller_->GetTabAt(this, event.location()); |
| 898 if (closest_tab) | 907 if (closest_tab) |
| 899 controller_->CloseTab(closest_tab, CLOSE_TAB_FROM_MOUSE); | 908 controller_->CloseTab(closest_tab, CLOSE_TAB_FROM_MOUSE); |
| 900 } | 909 } |
| 901 } else if (event.IsOnlyLeftMouseButton() && !event.IsShiftDown() && | 910 } else if (event.IsOnlyLeftMouseButton() && !event.IsShiftDown() && |
| 902 !event.IsControlDown()) { | 911 !event.IsControlDown()) { |
| 903 // If the tab was already selected mouse pressed doesn't change the | 912 // If the tab was already selected mouse pressed doesn't change the |
| 904 // selection. Reset it now to handle the case where multiple tabs were | 913 // selection. Reset it now to handle the case where multiple tabs were |
| 905 // selected. | 914 // selected. |
| 906 controller_->SelectTab(this); | 915 controller_->SelectTab(this); |
| 916 |
| 917 if (media_indicator_button_ && media_indicator_button_->visible() && |
| 918 media_indicator_button_->bounds().Contains(event.location())) { |
| 919 content::RecordAction(UserMetricsAction("TabMediaIndicator_Clicked")); |
| 920 } |
| 907 } | 921 } |
| 908 } | 922 } |
| 909 | 923 |
| 910 void Tab::OnMouseCaptureLost() { | 924 void Tab::OnMouseCaptureLost() { |
| 911 controller_->EndDrag(END_DRAG_CAPTURE_LOST); | 925 controller_->EndDrag(END_DRAG_CAPTURE_LOST); |
| 912 } | 926 } |
| 913 | 927 |
| 914 void Tab::OnMouseEntered(const ui::MouseEvent& event) { | 928 void Tab::OnMouseEntered(const ui::MouseEvent& event) { |
| 915 hover_controller_.Show(views::GlowHoverController::SUBTLE); | 929 hover_controller_.Show(views::GlowHoverController::SUBTLE); |
| 916 } | 930 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 const SkColor title_color = GetThemeProvider()->GetColor(IsSelected() ? | 1027 const SkColor title_color = GetThemeProvider()->GetColor(IsSelected() ? |
| 1014 ThemeProperties::COLOR_TAB_TEXT : | 1028 ThemeProperties::COLOR_TAB_TEXT : |
| 1015 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); | 1029 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); |
| 1016 title_->SetVisible(!data().mini || | 1030 title_->SetVisible(!data().mini || |
| 1017 width() > kMiniTabRendererAsNormalTabWidth); | 1031 width() > kMiniTabRendererAsNormalTabWidth); |
| 1018 title_->SetEnabledColor(title_color); | 1032 title_->SetEnabledColor(title_color); |
| 1019 | 1033 |
| 1020 if (show_icon) | 1034 if (show_icon) |
| 1021 PaintIcon(canvas); | 1035 PaintIcon(canvas); |
| 1022 | 1036 |
| 1023 if (show_media_indicator) | |
| 1024 PaintMediaIndicator(canvas); | |
| 1025 | |
| 1026 // If the close button color has changed, generate a new one. | 1037 // If the close button color has changed, generate a new one. |
| 1027 if (!close_button_color_ || title_color != close_button_color_) { | 1038 if (!close_button_color_ || title_color != close_button_color_) { |
| 1028 close_button_color_ = title_color; | 1039 close_button_color_ = title_color; |
| 1029 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1040 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 1030 close_button_->SetBackground(close_button_color_, | 1041 close_button_->SetBackground(close_button_color_, |
| 1031 rb.GetImageSkiaNamed(IDR_CLOSE_1), | 1042 rb.GetImageSkiaNamed(IDR_CLOSE_1), |
| 1032 rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK)); | 1043 rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK)); |
| 1033 } | 1044 } |
| 1034 } | 1045 } |
| 1035 | 1046 |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 bounds, true, SkPaint()); | 1345 bounds, true, SkPaint()); |
| 1335 } else if (!data().favicon.isNull()) { | 1346 } else if (!data().favicon.isNull()) { |
| 1336 // Paint the normal favicon. | 1347 // Paint the normal favicon. |
| 1337 DrawIconCenter(canvas, data().favicon, 0, | 1348 DrawIconCenter(canvas, data().favicon, 0, |
| 1338 data().favicon.width(), | 1349 data().favicon.width(), |
| 1339 data().favicon.height(), | 1350 data().favicon.height(), |
| 1340 bounds, true, SkPaint()); | 1351 bounds, true, SkPaint()); |
| 1341 } | 1352 } |
| 1342 } | 1353 } |
| 1343 | 1354 |
| 1344 void Tab::PaintMediaIndicator(gfx::Canvas* canvas) { | |
| 1345 if (media_indicator_bounds_.IsEmpty() || !media_indicator_animation_) | |
| 1346 return; | |
| 1347 | |
| 1348 gfx::Rect bounds = media_indicator_bounds_; | |
| 1349 bounds.set_x(GetMirroredXForRect(bounds)); | |
| 1350 | |
| 1351 SkPaint paint; | |
| 1352 paint.setAntiAlias(true); | |
| 1353 double opaqueness = media_indicator_animation_->GetCurrentValue(); | |
| 1354 if (data_.media_state == TAB_MEDIA_STATE_NONE) | |
| 1355 opaqueness = 1.0 - opaqueness; // Fading out, not in. | |
| 1356 paint.setAlpha(opaqueness * SK_AlphaOPAQUE); | |
| 1357 | |
| 1358 const gfx::ImageSkia& media_indicator_image = | |
| 1359 *(chrome::GetTabMediaIndicatorImage(animating_media_state_). | |
| 1360 ToImageSkia()); | |
| 1361 DrawIconAtLocation(canvas, media_indicator_image, 0, | |
| 1362 bounds.x(), bounds.y(), media_indicator_image.width(), | |
| 1363 media_indicator_image.height(), true, paint); | |
| 1364 } | |
| 1365 | |
| 1366 void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, | 1355 void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, |
| 1367 TabRendererData::NetworkState state) { | 1356 TabRendererData::NetworkState state) { |
| 1368 static bool initialized = false; | 1357 static bool initialized = false; |
| 1369 static int loading_animation_frame_count = 0; | 1358 static int loading_animation_frame_count = 0; |
| 1370 static int waiting_animation_frame_count = 0; | 1359 static int waiting_animation_frame_count = 0; |
| 1371 static int waiting_to_loading_frame_count_ratio = 0; | 1360 static int waiting_to_loading_frame_count_ratio = 0; |
| 1372 if (!initialized) { | 1361 if (!initialized) { |
| 1373 initialized = true; | 1362 initialized = true; |
| 1374 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1363 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 1375 gfx::ImageSkia loading_animation(*rb.GetImageSkiaNamed(IDR_THROBBER)); | 1364 gfx::ImageSkia loading_animation(*rb.GetImageSkiaNamed(IDR_THROBBER)); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1432 if (available_width >= width_per_icon && | 1421 if (available_width >= width_per_icon && |
| 1433 available_width < (width_per_icon + kPaddingBetweenIcons)) { | 1422 available_width < (width_per_icon + kPaddingBetweenIcons)) { |
| 1434 return 1; | 1423 return 1; |
| 1435 } | 1424 } |
| 1436 return available_width / (width_per_icon + kPaddingBetweenIcons); | 1425 return available_width / (width_per_icon + kPaddingBetweenIcons); |
| 1437 } | 1426 } |
| 1438 | 1427 |
| 1439 bool Tab::ShouldShowIcon() const { | 1428 bool Tab::ShouldShowIcon() const { |
| 1440 return chrome::ShouldTabShowFavicon( | 1429 return chrome::ShouldTabShowFavicon( |
| 1441 IconCapacity(), data().mini, IsActive(), data().show_icon, | 1430 IconCapacity(), data().mini, IsActive(), data().show_icon, |
| 1442 animating_media_state_); | 1431 media_indicator_button_ ? media_indicator_button_->showing_media_state() : |
| 1432 data_.media_state); |
| 1443 } | 1433 } |
| 1444 | 1434 |
| 1445 bool Tab::ShouldShowMediaIndicator() const { | 1435 bool Tab::ShouldShowMediaIndicator() const { |
| 1446 return chrome::ShouldTabShowMediaIndicator( | 1436 return chrome::ShouldTabShowMediaIndicator( |
| 1447 IconCapacity(), data().mini, IsActive(), data().show_icon, | 1437 IconCapacity(), data().mini, IsActive(), data().show_icon, |
| 1448 animating_media_state_); | 1438 media_indicator_button_ ? media_indicator_button_->showing_media_state() : |
| 1439 data_.media_state); |
| 1449 } | 1440 } |
| 1450 | 1441 |
| 1451 bool Tab::ShouldShowCloseBox() const { | 1442 bool Tab::ShouldShowCloseBox() const { |
| 1452 return chrome::ShouldTabShowCloseButton( | 1443 return chrome::ShouldTabShowCloseButton( |
| 1453 IconCapacity(), data().mini, IsActive()); | 1444 IconCapacity(), data().mini, IsActive()); |
| 1454 } | 1445 } |
| 1455 | 1446 |
| 1456 double Tab::GetThrobValue() { | 1447 double Tab::GetThrobValue() { |
| 1457 const bool is_selected = IsSelected(); | 1448 const bool is_selected = IsSelected(); |
| 1458 const double min = is_selected ? kSelectedTabOpacity : 0; | 1449 const double min = is_selected ? kSelectedTabOpacity : 0; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 | 1484 |
| 1494 void Tab::StartCrashAnimation() { | 1485 void Tab::StartCrashAnimation() { |
| 1495 crash_icon_animation_.reset(new FaviconCrashAnimation(this)); | 1486 crash_icon_animation_.reset(new FaviconCrashAnimation(this)); |
| 1496 crash_icon_animation_->Start(); | 1487 crash_icon_animation_->Start(); |
| 1497 } | 1488 } |
| 1498 | 1489 |
| 1499 bool Tab::IsPerformingCrashAnimation() const { | 1490 bool Tab::IsPerformingCrashAnimation() const { |
| 1500 return crash_icon_animation_.get() && data_.IsCrashed(); | 1491 return crash_icon_animation_.get() && data_.IsCrashed(); |
| 1501 } | 1492 } |
| 1502 | 1493 |
| 1503 void Tab::StartMediaIndicatorAnimation() { | |
| 1504 media_indicator_animation_ = | |
| 1505 chrome::CreateTabMediaIndicatorFadeAnimation(data_.media_state); | |
| 1506 media_indicator_animation_->set_delegate(this); | |
| 1507 media_indicator_animation_->Start(); | |
| 1508 } | |
| 1509 | |
| 1510 void Tab::ScheduleIconPaint() { | 1494 void Tab::ScheduleIconPaint() { |
| 1511 gfx::Rect bounds = favicon_bounds_; | 1495 gfx::Rect bounds = favicon_bounds_; |
| 1512 if (bounds.IsEmpty()) | 1496 if (bounds.IsEmpty()) |
| 1513 return; | 1497 return; |
| 1514 | 1498 |
| 1515 // Extends the area to the bottom when sad_favicon is animating. | 1499 // Extends the area to the bottom when sad_favicon is animating. |
| 1516 if (IsPerformingCrashAnimation()) | 1500 if (IsPerformingCrashAnimation()) |
| 1517 bounds.set_height(height() - bounds.y()); | 1501 bounds.set_height(height() - bounds.y()); |
| 1518 bounds.set_x(GetMirroredXForRect(bounds)); | 1502 bounds.set_x(GetMirroredXForRect(bounds)); |
| 1519 SchedulePaintInRect(bounds); | 1503 SchedulePaintInRect(bounds); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1539 *frame_id = 0; | 1523 *frame_id = 0; |
| 1540 } else if (data().incognito) { | 1524 } else if (data().incognito) { |
| 1541 *tab_id = IDR_THEME_TAB_BACKGROUND_INCOGNITO; | 1525 *tab_id = IDR_THEME_TAB_BACKGROUND_INCOGNITO; |
| 1542 *frame_id = IDR_THEME_FRAME_INCOGNITO; | 1526 *frame_id = IDR_THEME_FRAME_INCOGNITO; |
| 1543 } else { | 1527 } else { |
| 1544 *tab_id = IDR_THEME_TAB_BACKGROUND; | 1528 *tab_id = IDR_THEME_TAB_BACKGROUND; |
| 1545 *frame_id = IDR_THEME_FRAME; | 1529 *frame_id = IDR_THEME_FRAME; |
| 1546 } | 1530 } |
| 1547 } | 1531 } |
| 1548 | 1532 |
| 1533 MediaIndicatorButton* Tab::GetMediaIndicatorButton() { |
| 1534 if (!media_indicator_button_) { |
| 1535 media_indicator_button_ = new MediaIndicatorButton(); |
| 1536 AddChildView(media_indicator_button_); // Takes ownership. |
| 1537 } |
| 1538 return media_indicator_button_; |
| 1539 } |
| 1540 |
| 1549 //////////////////////////////////////////////////////////////////////////////// | 1541 //////////////////////////////////////////////////////////////////////////////// |
| 1550 // Tab, private static: | 1542 // Tab, private static: |
| 1551 | 1543 |
| 1552 // static | 1544 // static |
| 1553 void Tab::InitTabResources() { | 1545 void Tab::InitTabResources() { |
| 1554 static bool initialized = false; | 1546 static bool initialized = false; |
| 1555 if (initialized) | 1547 if (initialized) |
| 1556 return; | 1548 return; |
| 1557 | 1549 |
| 1558 initialized = true; | 1550 initialized = true; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1603 const gfx::ImageSkia& image) { | 1595 const gfx::ImageSkia& image) { |
| 1604 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1596 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
| 1605 ImageCacheEntry entry; | 1597 ImageCacheEntry entry; |
| 1606 entry.resource_id = resource_id; | 1598 entry.resource_id = resource_id; |
| 1607 entry.scale_factor = scale_factor; | 1599 entry.scale_factor = scale_factor; |
| 1608 entry.image = image; | 1600 entry.image = image; |
| 1609 image_cache_->push_front(entry); | 1601 image_cache_->push_front(entry); |
| 1610 if (image_cache_->size() > kMaxImageCacheSize) | 1602 if (image_cache_->size() > kMaxImageCacheSize) |
| 1611 image_cache_->pop_back(); | 1603 image_cache_->pop_back(); |
| 1612 } | 1604 } |
| OLD | NEW |