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" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
29 #include "ui/base/models/list_selection_model.h" | 29 #include "ui/base/models/list_selection_model.h" |
30 #include "ui/base/resource/resource_bundle.h" | 30 #include "ui/base/resource/resource_bundle.h" |
31 #include "ui/base/theme_provider.h" | 31 #include "ui/base/theme_provider.h" |
32 #include "ui/gfx/animation/animation_container.h" | 32 #include "ui/gfx/animation/animation_container.h" |
33 #include "ui/gfx/animation/multi_animation.h" | 33 #include "ui/gfx/animation/multi_animation.h" |
34 #include "ui/gfx/animation/throb_animation.h" | 34 #include "ui/gfx/animation/throb_animation.h" |
35 #include "ui/gfx/canvas.h" | 35 #include "ui/gfx/canvas.h" |
36 #include "ui/gfx/color_analysis.h" | 36 #include "ui/gfx/color_analysis.h" |
37 #include "ui/gfx/favicon_size.h" | 37 #include "ui/gfx/favicon_size.h" |
| 38 #include "ui/gfx/font.h" |
38 #include "ui/gfx/image/image_skia_operations.h" | 39 #include "ui/gfx/image/image_skia_operations.h" |
39 #include "ui/gfx/path.h" | 40 #include "ui/gfx/path.h" |
40 #include "ui/gfx/rect_conversions.h" | 41 #include "ui/gfx/rect_conversions.h" |
41 #include "ui/gfx/skia_util.h" | 42 #include "ui/gfx/skia_util.h" |
42 #include "ui/gfx/text_elider.h" | 43 #include "ui/gfx/text_elider.h" |
43 #include "ui/views/border.h" | 44 #include "ui/views/border.h" |
44 #include "ui/views/controls/button/image_button.h" | 45 #include "ui/views/controls/button/image_button.h" |
45 #include "ui/views/controls/label.h" | |
46 #include "ui/views/rect_based_targeting_utils.h" | 46 #include "ui/views/rect_based_targeting_utils.h" |
47 #include "ui/views/widget/tooltip_manager.h" | 47 #include "ui/views/widget/tooltip_manager.h" |
48 #include "ui/views/widget/widget.h" | 48 #include "ui/views/widget/widget.h" |
49 #include "ui/views/window/non_client_view.h" | 49 #include "ui/views/window/non_client_view.h" |
50 | 50 |
51 #if defined(USE_ASH) | 51 #if defined(USE_ASH) |
52 #include "ui/aura/env.h" | 52 #include "ui/aura/env.h" |
53 #endif | 53 #endif |
54 | 54 |
55 namespace { | 55 namespace { |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 // Tab, statics: | 368 // Tab, statics: |
369 | 369 |
370 // static | 370 // static |
371 const char Tab::kViewClassName[] = "Tab"; | 371 const char Tab::kViewClassName[] = "Tab"; |
372 | 372 |
373 // static | 373 // static |
374 Tab::TabImage Tab::tab_alpha_ = {0}; | 374 Tab::TabImage Tab::tab_alpha_ = {0}; |
375 Tab::TabImage Tab::tab_active_ = {0}; | 375 Tab::TabImage Tab::tab_active_ = {0}; |
376 Tab::TabImage Tab::tab_inactive_ = {0}; | 376 Tab::TabImage Tab::tab_inactive_ = {0}; |
377 // static | 377 // static |
| 378 gfx::Font* Tab::font_ = NULL; |
| 379 // static |
| 380 int Tab::font_height_ = 0; |
| 381 // static |
378 Tab::ImageCache* Tab::image_cache_ = NULL; | 382 Tab::ImageCache* Tab::image_cache_ = NULL; |
379 | 383 |
380 //////////////////////////////////////////////////////////////////////////////// | 384 //////////////////////////////////////////////////////////////////////////////// |
381 // Tab, public: | 385 // Tab, public: |
382 | 386 |
383 Tab::Tab(TabController* controller) | 387 Tab::Tab(TabController* controller) |
384 : controller_(controller), | 388 : controller_(controller), |
385 closing_(false), | 389 closing_(false), |
386 dragging_(false), | 390 dragging_(false), |
387 favicon_hiding_offset_(0), | 391 favicon_hiding_offset_(0), |
388 loading_animation_frame_(0), | 392 loading_animation_frame_(0), |
389 immersive_loading_step_(0), | 393 immersive_loading_step_(0), |
390 should_display_crashed_favicon_(false), | 394 should_display_crashed_favicon_(false), |
391 animating_media_state_(TAB_MEDIA_STATE_NONE), | 395 animating_media_state_(TAB_MEDIA_STATE_NONE), |
392 close_button_(NULL), | |
393 title_(new views::Label()), | |
394 tab_activated_with_last_gesture_begin_(false), | 396 tab_activated_with_last_gesture_begin_(false), |
395 hover_controller_(this), | 397 hover_controller_(this), |
396 showing_icon_(false), | 398 showing_icon_(false), |
397 showing_media_indicator_(false), | 399 showing_media_indicator_(false), |
398 showing_close_button_(false), | 400 showing_close_button_(false), |
399 close_button_color_(0) { | 401 close_button_color_(0) { |
400 DCHECK(controller); | 402 DCHECK(controller); |
401 InitTabResources(); | 403 InitTabResources(); |
402 | 404 |
403 // So we get don't get enter/exit on children and don't prematurely stop the | 405 // So we get don't get enter/exit on children and don't prematurely stop the |
404 // hover. | 406 // hover. |
405 set_notify_enter_exit_on_child(true); | 407 set_notify_enter_exit_on_child(true); |
406 | 408 |
407 set_id(VIEW_ID_TAB); | 409 set_id(VIEW_ID_TAB); |
408 | 410 |
409 title_->set_directionality_mode(gfx::DIRECTIONALITY_FROM_TEXT); | |
410 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); | |
411 title_->SetElideBehavior(gfx::FADE_TAIL); | |
412 | |
413 // Add the Close Button. | 411 // Add the Close Button. |
414 close_button_ = new TabCloseButton(this); | 412 close_button_ = new TabCloseButton(this); |
415 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 413 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
416 close_button_->SetImage(views::CustomButton::STATE_NORMAL, | 414 close_button_->SetImage(views::CustomButton::STATE_NORMAL, |
417 rb.GetImageSkiaNamed(IDR_CLOSE_1)); | 415 rb.GetImageSkiaNamed(IDR_CLOSE_1)); |
418 close_button_->SetImage(views::CustomButton::STATE_HOVERED, | 416 close_button_->SetImage(views::CustomButton::STATE_HOVERED, |
419 rb.GetImageSkiaNamed(IDR_CLOSE_1_H)); | 417 rb.GetImageSkiaNamed(IDR_CLOSE_1_H)); |
420 close_button_->SetImage(views::CustomButton::STATE_PRESSED, | 418 close_button_->SetImage(views::CustomButton::STATE_PRESSED, |
421 rb.GetImageSkiaNamed(IDR_CLOSE_1_P)); | 419 rb.GetImageSkiaNamed(IDR_CLOSE_1_P)); |
422 close_button_->SetAccessibleName( | 420 close_button_->SetAccessibleName( |
(...skipping 22 matching lines...) Expand all Loading... |
445 return controller_->IsTabSelected(this); | 443 return controller_->IsTabSelected(this); |
446 } | 444 } |
447 | 445 |
448 void Tab::SetData(const TabRendererData& data) { | 446 void Tab::SetData(const TabRendererData& data) { |
449 if (data_.Equals(data)) | 447 if (data_.Equals(data)) |
450 return; | 448 return; |
451 | 449 |
452 TabRendererData old(data_); | 450 TabRendererData old(data_); |
453 data_ = data; | 451 data_ = data; |
454 | 452 |
455 base::string16 title = data_.title; | |
456 if (title.empty()) { | |
457 title = data_.loading ? | |
458 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : | |
459 CoreTabHelper::GetDefaultTitle(); | |
460 } else { | |
461 Browser::FormatTitleForDisplay(&title); | |
462 } | |
463 title_->SetText(title); | |
464 | |
465 if (data_.IsCrashed()) { | 453 if (data_.IsCrashed()) { |
466 if (!should_display_crashed_favicon_ && !IsPerformingCrashAnimation()) { | 454 if (!should_display_crashed_favicon_ && !IsPerformingCrashAnimation()) { |
467 data_.media_state = TAB_MEDIA_STATE_NONE; | 455 data_.media_state = TAB_MEDIA_STATE_NONE; |
468 #if defined(OS_CHROMEOS) | 456 #if defined(OS_CHROMEOS) |
469 // On Chrome OS, we reload killed tabs automatically when the user | 457 // On Chrome OS, we reload killed tabs automatically when the user |
470 // switches to them. Don't display animations for these unless they're | 458 // switches to them. Don't display animations for these unless they're |
471 // selected (i.e. in the foreground) -- we won't reload these | 459 // selected (i.e. in the foreground) -- we won't reload these |
472 // automatically since we don't want to get into a crash loop. | 460 // automatically since we don't want to get into a crash loop. |
473 if (IsSelected() || | 461 if (IsSelected() || |
474 data_.crashed_status != base::TERMINATION_STATUS_PROCESS_WAS_KILLED) | 462 data_.crashed_status != base::TERMINATION_STATUS_PROCESS_WAS_KILLED) |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 | 679 |
692 void Tab::Layout() { | 680 void Tab::Layout() { |
693 gfx::Rect lb = GetContentsBounds(); | 681 gfx::Rect lb = GetContentsBounds(); |
694 if (lb.IsEmpty()) | 682 if (lb.IsEmpty()) |
695 return; | 683 return; |
696 lb.Inset(kLeftPadding, kTopPadding, kRightPadding, kBottomPadding); | 684 lb.Inset(kLeftPadding, kTopPadding, kRightPadding, kBottomPadding); |
697 | 685 |
698 // The height of the content of the Tab is the largest of the favicon, | 686 // The height of the content of the Tab is the largest of the favicon, |
699 // the title text and the close button graphic. | 687 // the title text and the close button graphic. |
700 const int kTabIconSize = gfx::kFaviconSize; | 688 const int kTabIconSize = gfx::kFaviconSize; |
701 const int font_height = title_->font_list().GetHeight(); | 689 int content_height = std::max(kTabIconSize, font_height_); |
702 int content_height = std::max(kTabIconSize, font_height); | |
703 close_button_->SetBorder(views::Border::NullBorder()); | 690 close_button_->SetBorder(views::Border::NullBorder()); |
704 gfx::Size close_button_size(close_button_->GetPreferredSize()); | 691 gfx::Size close_button_size(close_button_->GetPreferredSize()); |
705 content_height = std::max(content_height, close_button_size.height()); | 692 content_height = std::max(content_height, close_button_size.height()); |
706 | 693 |
707 // Size the Favicon. | 694 // Size the Favicon. |
708 showing_icon_ = ShouldShowIcon(); | 695 showing_icon_ = ShouldShowIcon(); |
709 if (showing_icon_) { | 696 if (showing_icon_) { |
710 // Use the size of the favicon as apps use a bigger favicon size. | 697 // Use the size of the favicon as apps use a bigger favicon size. |
711 int favicon_top = kTopPadding + content_height / 2 - kTabIconSize / 2; | 698 int favicon_top = kTopPadding + content_height / 2 - kTabIconSize / 2; |
712 int favicon_left = lb.x(); | 699 int favicon_left = lb.x(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 std::max(lb.x(), right - media_indicator_bounds_.width())); | 751 std::max(lb.x(), right - media_indicator_bounds_.width())); |
765 MaybeAdjustLeftForMiniTab(&media_indicator_bounds_); | 752 MaybeAdjustLeftForMiniTab(&media_indicator_bounds_); |
766 } else { | 753 } else { |
767 media_indicator_bounds_.SetRect(lb.x(), lb.y(), 0, 0); | 754 media_indicator_bounds_.SetRect(lb.x(), lb.y(), 0, 0); |
768 } | 755 } |
769 | 756 |
770 const int title_text_offset = is_host_desktop_type_ash ? | 757 const int title_text_offset = is_host_desktop_type_ash ? |
771 kTitleTextOffsetYAsh : kTitleTextOffsetY; | 758 kTitleTextOffsetYAsh : kTitleTextOffsetY; |
772 int title_left = favicon_bounds_.right() + kFaviconTitleSpacing; | 759 int title_left = favicon_bounds_.right() + kFaviconTitleSpacing; |
773 int title_top = kTopPadding + title_text_offset + | 760 int title_top = kTopPadding + title_text_offset + |
774 (content_height - font_height) / 2; | 761 (content_height - font_height_) / 2; |
775 gfx::Rect title_bounds(title_left, title_top, 0, 0); | |
776 // Size the Title text to fill the remaining space. | 762 // Size the Title text to fill the remaining space. |
777 if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) { | 763 if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) { |
778 // If the user has big fonts, the title will appear rendered too far down | 764 // If the user has big fonts, the title will appear rendered too far down |
779 // on the y-axis if we use the regular top padding, so we need to adjust it | 765 // on the y-axis if we use the regular top padding, so we need to adjust it |
780 // so that the text appears centered. | 766 // so that the text appears centered. |
781 gfx::Size minimum_size = GetMinimumUnselectedSize(); | 767 gfx::Size minimum_size = GetMinimumUnselectedSize(); |
782 int text_height = title_top + font_height + kBottomPadding; | 768 int text_height = title_top + font_height_ + kBottomPadding; |
783 if (text_height > minimum_size.height()) | 769 if (text_height > minimum_size.height()) |
784 title_top -= (text_height - minimum_size.height()) / 2; | 770 title_top -= (text_height - minimum_size.height()) / 2; |
785 | 771 |
786 int title_width; | 772 int title_width; |
787 if (showing_media_indicator_) { | 773 if (showing_media_indicator_) { |
788 title_width = media_indicator_bounds_.x() - kTitleCloseButtonSpacing - | 774 title_width = media_indicator_bounds_.x() - kTitleCloseButtonSpacing - |
789 title_left; | 775 title_left; |
790 } else if (close_button_->visible()) { | 776 } else if (close_button_->visible()) { |
791 // The close button has an empty border with some padding (see details | 777 // The close button has an empty border with some padding (see details |
792 // above where the close-button's bounds is set). Allow the title to | 778 // above where the close-button's bounds is set). Allow the title to |
793 // overlap the empty padding. | 779 // overlap the empty padding. |
794 title_width = close_button_->x() + close_button_->GetInsets().left() - | 780 title_width = close_button_->x() + close_button_->GetInsets().left() - |
795 kTitleCloseButtonSpacing - title_left; | 781 kTitleCloseButtonSpacing - title_left; |
796 } else { | 782 } else { |
797 title_width = lb.width() - title_left; | 783 title_width = lb.width() - title_left; |
798 } | 784 } |
799 title_width = std::max(title_width, 0); | 785 title_width = std::max(title_width, 0); |
800 title_bounds.SetRect(title_left, title_top, title_width, font_height); | 786 title_bounds_.SetRect(title_left, title_top, title_width, font_height_); |
| 787 } else { |
| 788 title_bounds_.SetRect(title_left, title_top, 0, 0); |
801 } | 789 } |
802 | 790 |
803 title_bounds.set_x(GetMirroredXForRect(title_bounds)); | 791 // Certain UI elements within the Tab (the favicon, etc.) are not represented |
804 title_->SetBoundsRect(title_bounds); | 792 // as child Views (which is the preferred method). Instead, these UI elements |
| 793 // are drawn directly on the canvas from within Tab::OnPaint(). The Tab's |
| 794 // child Views (for example, the Tab's close button which is a views::Button |
| 795 // instance) are automatically mirrored by the mirroring infrastructure in |
| 796 // views. The elements Tab draws directly on the canvas need to be manually |
| 797 // mirrored if the View's layout is right-to-left. |
| 798 title_bounds_.set_x(GetMirroredXForRect(title_bounds_)); |
805 } | 799 } |
806 | 800 |
807 void Tab::OnThemeChanged() { | 801 void Tab::OnThemeChanged() { |
808 LoadTabImages(); | 802 LoadTabImages(); |
809 } | 803 } |
810 | 804 |
811 const char* Tab::GetClassName() const { | 805 const char* Tab::GetClassName() const { |
812 return kViewClassName; | 806 return kViewClassName; |
813 } | 807 } |
814 | 808 |
(...skipping 24 matching lines...) Expand all Loading... |
839 } | 833 } |
840 | 834 |
841 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const { | 835 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const { |
842 // Note: Anything that affects the tooltip text should be accounted for when | 836 // Note: Anything that affects the tooltip text should be accounted for when |
843 // calling TooltipTextChanged() from Tab::DataChanged(). | 837 // calling TooltipTextChanged() from Tab::DataChanged(). |
844 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.media_state); | 838 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.media_state); |
845 return !tooltip->empty(); | 839 return !tooltip->empty(); |
846 } | 840 } |
847 | 841 |
848 bool Tab::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* origin) const { | 842 bool Tab::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* origin) const { |
849 origin->set_x(title_->x() + 10); | 843 origin->set_x(title_bounds_.x() + 10); |
850 origin->set_y(-views::TooltipManager::GetTooltipHeight() - 4); | 844 origin->set_y(-views::TooltipManager::GetTooltipHeight() - 4); |
851 return true; | 845 return true; |
852 } | 846 } |
853 | 847 |
854 bool Tab::OnMousePressed(const ui::MouseEvent& event) { | 848 bool Tab::OnMousePressed(const ui::MouseEvent& event) { |
855 controller_->OnMouseEventInTab(this, event); | 849 controller_->OnMouseEventInTab(this, event); |
856 | 850 |
857 // Allow a right click from touch to drag, which corresponds to a long click. | 851 // Allow a right click from touch to drag, which corresponds to a long click. |
858 if (event.IsOnlyLeftMouseButton() || | 852 if (event.IsOnlyLeftMouseButton() || |
859 (event.IsOnlyRightMouseButton() && event.flags() & ui::EF_FROM_TOUCH)) { | 853 (event.IsOnlyRightMouseButton() && event.flags() & ui::EF_FROM_TOUCH)) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 } | 976 } |
983 | 977 |
984 void Tab::GetAccessibleState(ui::AXViewState* state) { | 978 void Tab::GetAccessibleState(ui::AXViewState* state) { |
985 state->role = ui::AX_ROLE_TAB; | 979 state->role = ui::AX_ROLE_TAB; |
986 state->name = data_.title; | 980 state->name = data_.title; |
987 } | 981 } |
988 | 982 |
989 //////////////////////////////////////////////////////////////////////////////// | 983 //////////////////////////////////////////////////////////////////////////////// |
990 // Tab, private | 984 // Tab, private |
991 | 985 |
| 986 const gfx::Rect& Tab::GetTitleBounds() const { |
| 987 return title_bounds_; |
| 988 } |
| 989 |
| 990 const gfx::Rect& Tab::GetIconBounds() const { |
| 991 return favicon_bounds_; |
| 992 } |
| 993 |
992 void Tab::MaybeAdjustLeftForMiniTab(gfx::Rect* bounds) const { | 994 void Tab::MaybeAdjustLeftForMiniTab(gfx::Rect* bounds) const { |
993 if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) | 995 if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) |
994 return; | 996 return; |
995 const int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth(); | 997 const int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth(); |
996 const int ideal_delta = width() - GetMiniWidth(); | 998 const int ideal_delta = width() - GetMiniWidth(); |
997 const int ideal_x = (GetMiniWidth() - bounds->width()) / 2; | 999 const int ideal_x = (GetMiniWidth() - bounds->width()) / 2; |
998 bounds->set_x(bounds->x() + static_cast<int>( | 1000 bounds->set_x(bounds->x() + static_cast<int>( |
999 (1 - static_cast<float>(ideal_delta) / static_cast<float>(mini_delta)) * | 1001 (1 - static_cast<float>(ideal_delta) / static_cast<float>(mini_delta)) * |
1000 (ideal_x - bounds->x()))); | 1002 (ideal_x - bounds->x()))); |
1001 } | 1003 } |
(...skipping 17 matching lines...) Expand all Loading... |
1019 const bool show_media_indicator = ShouldShowMediaIndicator(); | 1021 const bool show_media_indicator = ShouldShowMediaIndicator(); |
1020 const bool show_close_button = ShouldShowCloseBox(); | 1022 const bool show_close_button = ShouldShowCloseBox(); |
1021 if (show_icon != showing_icon_ || | 1023 if (show_icon != showing_icon_ || |
1022 show_media_indicator != showing_media_indicator_ || | 1024 show_media_indicator != showing_media_indicator_ || |
1023 show_close_button != showing_close_button_) { | 1025 show_close_button != showing_close_button_) { |
1024 Layout(); | 1026 Layout(); |
1025 } | 1027 } |
1026 | 1028 |
1027 PaintTabBackground(canvas); | 1029 PaintTabBackground(canvas); |
1028 | 1030 |
1029 const SkColor title_color = GetThemeProvider()->GetColor(IsSelected() ? | 1031 SkColor title_color = GetThemeProvider()-> |
1030 ThemeProperties::COLOR_TAB_TEXT : | 1032 GetColor(IsSelected() ? |
1031 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); | 1033 ThemeProperties::COLOR_TAB_TEXT : |
1032 if (!data().mini || width() > kMiniTabRendererAsNormalTabWidth) { | 1034 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); |
1033 title_->SetEnabledColor(title_color); | 1035 |
1034 title_->Paint(canvas, views::CullSet()); | 1036 if (!data().mini || width() > kMiniTabRendererAsNormalTabWidth) |
1035 } | 1037 PaintTitle(canvas, title_color); |
1036 | 1038 |
1037 if (show_icon) | 1039 if (show_icon) |
1038 PaintIcon(canvas); | 1040 PaintIcon(canvas); |
1039 | 1041 |
1040 if (show_media_indicator) | 1042 if (show_media_indicator) |
1041 PaintMediaIndicator(canvas); | 1043 PaintMediaIndicator(canvas); |
1042 | 1044 |
1043 // If the close button color has changed, generate a new one. | 1045 // If the close button color has changed, generate a new one. |
1044 if (!close_button_color_ || title_color != close_button_color_) { | 1046 if (!close_button_color_ || title_color != close_button_color_) { |
1045 close_button_color_ = title_color; | 1047 close_button_color_ = title_color; |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 height() - kDropShadowHeight); | 1324 height() - kDropShadowHeight); |
1323 | 1325 |
1324 // Now draw the highlights/shadows around the tab edge. | 1326 // Now draw the highlights/shadows around the tab edge. |
1325 canvas->DrawImageInt(*tab_image->image_l, 0, 0); | 1327 canvas->DrawImageInt(*tab_image->image_l, 0, 0); |
1326 canvas->TileImageInt(*tab_image->image_c, tab_image->l_width, 0, | 1328 canvas->TileImageInt(*tab_image->image_c, tab_image->l_width, 0, |
1327 width() - tab_image->l_width - tab_image->r_width, height()); | 1329 width() - tab_image->l_width - tab_image->r_width, height()); |
1328 canvas->DrawImageInt(*tab_image->image_r, width() - tab_image->r_width, 0); | 1330 canvas->DrawImageInt(*tab_image->image_r, width() - tab_image->r_width, 0); |
1329 } | 1331 } |
1330 | 1332 |
1331 void Tab::PaintIcon(gfx::Canvas* canvas) { | 1333 void Tab::PaintIcon(gfx::Canvas* canvas) { |
1332 gfx::Rect bounds = favicon_bounds_; | 1334 gfx::Rect bounds = GetIconBounds(); |
1333 if (bounds.IsEmpty()) | 1335 if (bounds.IsEmpty()) |
1334 return; | 1336 return; |
1335 | 1337 |
1336 bounds.set_x(GetMirroredXForRect(bounds)); | 1338 bounds.set_x(GetMirroredXForRect(bounds)); |
1337 | 1339 |
1338 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { | 1340 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { |
1339 // Paint network activity (aka throbber) animation frame. | 1341 // Paint network activity (aka throbber) animation frame. |
1340 ui::ThemeProvider* tp = GetThemeProvider(); | 1342 ui::ThemeProvider* tp = GetThemeProvider(); |
1341 gfx::ImageSkia frames(*tp->GetImageSkiaNamed( | 1343 gfx::ImageSkia frames(*tp->GetImageSkiaNamed( |
1342 (data().network_state == TabRendererData::NETWORK_STATE_WAITING) ? | 1344 (data().network_state == TabRendererData::NETWORK_STATE_WAITING) ? |
1343 IDR_THROBBER_WAITING : IDR_THROBBER)); | 1345 IDR_THROBBER_WAITING : IDR_THROBBER)); |
1344 | 1346 |
1345 int icon_size = frames.height(); | 1347 int icon_size = frames.height(); |
1346 int image_offset = loading_animation_frame_ * icon_size; | 1348 int image_offset = loading_animation_frame_ * icon_size; |
1347 DrawIconCenter(canvas, frames, image_offset, | 1349 DrawIconCenter(canvas, frames, image_offset, |
1348 icon_size, icon_size, | 1350 icon_size, icon_size, |
1349 bounds, false, SkPaint()); | 1351 bounds, false, SkPaint()); |
1350 } else if (should_display_crashed_favicon_) { | 1352 } else if (should_display_crashed_favicon_) { |
1351 // Paint crash favicon. | 1353 // Paint crash favicon. |
1352 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1354 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1353 gfx::ImageSkia crashed_favicon(*rb.GetImageSkiaNamed(IDR_SAD_FAVICON)); | 1355 gfx::ImageSkia crashed_favicon(*rb.GetImageSkiaNamed(IDR_SAD_FAVICON)); |
1354 bounds.set_y(bounds.y() + favicon_hiding_offset_); | 1356 bounds.set_y(bounds.y() + favicon_hiding_offset_); |
1355 DrawIconCenter(canvas, crashed_favicon, 0, | 1357 DrawIconCenter(canvas, crashed_favicon, 0, |
1356 crashed_favicon.width(), | 1358 crashed_favicon.width(), |
1357 crashed_favicon.height(), | 1359 crashed_favicon.height(), |
1358 bounds, true, SkPaint()); | 1360 bounds, true, SkPaint()); |
1359 } else if (!data().favicon.isNull()) { | 1361 } else if (!data().favicon.isNull()) { |
1360 // Paint the normal favicon. | 1362 // Paint the normal favicon. |
1361 DrawIconCenter(canvas, data().favicon, 0, | 1363 DrawIconCenter(canvas, data().favicon, 0, |
1362 data().favicon.width(), | 1364 data().favicon.width(), |
1363 data().favicon.height(), | 1365 data().favicon.height(), |
1364 bounds, true, SkPaint()); | 1366 bounds, true, SkPaint()); |
1365 } | 1367 } |
1366 } | 1368 } |
1367 | 1369 |
1368 void Tab::PaintMediaIndicator(gfx::Canvas* canvas) { | 1370 void Tab::PaintMediaIndicator(gfx::Canvas* canvas) { |
(...skipping 11 matching lines...) Expand all Loading... |
1380 paint.setAlpha(opaqueness * SK_AlphaOPAQUE); | 1382 paint.setAlpha(opaqueness * SK_AlphaOPAQUE); |
1381 | 1383 |
1382 const gfx::ImageSkia& media_indicator_image = | 1384 const gfx::ImageSkia& media_indicator_image = |
1383 *(chrome::GetTabMediaIndicatorImage(animating_media_state_). | 1385 *(chrome::GetTabMediaIndicatorImage(animating_media_state_). |
1384 ToImageSkia()); | 1386 ToImageSkia()); |
1385 DrawIconAtLocation(canvas, media_indicator_image, 0, | 1387 DrawIconAtLocation(canvas, media_indicator_image, 0, |
1386 bounds.x(), bounds.y(), media_indicator_image.width(), | 1388 bounds.x(), bounds.y(), media_indicator_image.width(), |
1387 media_indicator_image.height(), true, paint); | 1389 media_indicator_image.height(), true, paint); |
1388 } | 1390 } |
1389 | 1391 |
| 1392 void Tab::PaintTitle(gfx::Canvas* canvas, SkColor title_color) { |
| 1393 // Paint the Title. |
| 1394 base::string16 title = data().title; |
| 1395 if (title.empty()) { |
| 1396 title = data().loading ? |
| 1397 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : |
| 1398 CoreTabHelper::GetDefaultTitle(); |
| 1399 } else { |
| 1400 Browser::FormatTitleForDisplay(&title); |
| 1401 } |
| 1402 |
| 1403 canvas->DrawFadedString(title, gfx::FontList(*font_), title_color, |
| 1404 GetTitleBounds(), 0); |
| 1405 } |
| 1406 |
1390 void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, | 1407 void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, |
1391 TabRendererData::NetworkState state) { | 1408 TabRendererData::NetworkState state) { |
1392 static bool initialized = false; | 1409 static bool initialized = false; |
1393 static int loading_animation_frame_count = 0; | 1410 static int loading_animation_frame_count = 0; |
1394 static int waiting_animation_frame_count = 0; | 1411 static int waiting_animation_frame_count = 0; |
1395 static int waiting_to_loading_frame_count_ratio = 0; | 1412 static int waiting_to_loading_frame_count_ratio = 0; |
1396 if (!initialized) { | 1413 if (!initialized) { |
1397 initialized = true; | 1414 initialized = true; |
1398 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1415 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1399 gfx::ImageSkia loading_animation(*rb.GetImageSkiaNamed(IDR_THROBBER)); | 1416 gfx::ImageSkia loading_animation(*rb.GetImageSkiaNamed(IDR_THROBBER)); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1522 } | 1539 } |
1523 | 1540 |
1524 void Tab::StartMediaIndicatorAnimation() { | 1541 void Tab::StartMediaIndicatorAnimation() { |
1525 media_indicator_animation_ = | 1542 media_indicator_animation_ = |
1526 chrome::CreateTabMediaIndicatorFadeAnimation(data_.media_state); | 1543 chrome::CreateTabMediaIndicatorFadeAnimation(data_.media_state); |
1527 media_indicator_animation_->set_delegate(this); | 1544 media_indicator_animation_->set_delegate(this); |
1528 media_indicator_animation_->Start(); | 1545 media_indicator_animation_->Start(); |
1529 } | 1546 } |
1530 | 1547 |
1531 void Tab::ScheduleIconPaint() { | 1548 void Tab::ScheduleIconPaint() { |
1532 gfx::Rect bounds = favicon_bounds_; | 1549 gfx::Rect bounds = GetIconBounds(); |
1533 if (bounds.IsEmpty()) | 1550 if (bounds.IsEmpty()) |
1534 return; | 1551 return; |
1535 | 1552 |
1536 // Extends the area to the bottom when sad_favicon is animating. | 1553 // Extends the area to the bottom when sad_favicon is |
| 1554 // animating. |
1537 if (IsPerformingCrashAnimation()) | 1555 if (IsPerformingCrashAnimation()) |
1538 bounds.set_height(height() - bounds.y()); | 1556 bounds.set_height(height() - bounds.y()); |
1539 bounds.set_x(GetMirroredXForRect(bounds)); | 1557 bounds.set_x(GetMirroredXForRect(bounds)); |
1540 SchedulePaintInRect(bounds); | 1558 SchedulePaintInRect(bounds); |
1541 } | 1559 } |
1542 | 1560 |
1543 gfx::Rect Tab::GetImmersiveBarRect() const { | 1561 gfx::Rect Tab::GetImmersiveBarRect() const { |
1544 // The main bar is as wide as the normal tab's horizontal top line. | 1562 // The main bar is as wide as the normal tab's horizontal top line. |
1545 // This top line of the tab extends a few pixels left and right of the | 1563 // This top line of the tab extends a few pixels left and right of the |
1546 // center image due to pixels in the rounded corner images. | 1564 // center image due to pixels in the rounded corner images. |
(...skipping 23 matching lines...) Expand all Loading... |
1570 //////////////////////////////////////////////////////////////////////////////// | 1588 //////////////////////////////////////////////////////////////////////////////// |
1571 // Tab, private static: | 1589 // Tab, private static: |
1572 | 1590 |
1573 // static | 1591 // static |
1574 void Tab::InitTabResources() { | 1592 void Tab::InitTabResources() { |
1575 static bool initialized = false; | 1593 static bool initialized = false; |
1576 if (initialized) | 1594 if (initialized) |
1577 return; | 1595 return; |
1578 | 1596 |
1579 initialized = true; | 1597 initialized = true; |
| 1598 |
| 1599 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 1600 font_ = new gfx::Font(rb.GetFont(ui::ResourceBundle::BaseFont)); |
| 1601 font_height_ = font_->GetHeight(); |
| 1602 |
1580 image_cache_ = new ImageCache(); | 1603 image_cache_ = new ImageCache(); |
1581 | 1604 |
1582 // Load the tab images once now, and maybe again later if the theme changes. | 1605 // Load the tab images once now, and maybe again later if the theme changes. |
1583 LoadTabImages(); | 1606 LoadTabImages(); |
1584 } | 1607 } |
1585 | 1608 |
1586 // static | 1609 // static |
1587 void Tab::LoadTabImages() { | 1610 void Tab::LoadTabImages() { |
1588 // We're not letting people override tab images just yet. | 1611 // We're not letting people override tab images just yet. |
1589 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1612 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 const gfx::ImageSkia& image) { | 1647 const gfx::ImageSkia& image) { |
1625 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1648 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
1626 ImageCacheEntry entry; | 1649 ImageCacheEntry entry; |
1627 entry.resource_id = resource_id; | 1650 entry.resource_id = resource_id; |
1628 entry.scale_factor = scale_factor; | 1651 entry.scale_factor = scale_factor; |
1629 entry.image = image; | 1652 entry.image = image; |
1630 image_cache_->push_front(entry); | 1653 image_cache_->push_front(entry); |
1631 if (image_cache_->size() > kMaxImageCacheSize) | 1654 if (image_cache_->size() > kMaxImageCacheSize) |
1632 image_cache_->pop_back(); | 1655 image_cache_->pop_back(); |
1633 } | 1656 } |
OLD | NEW |