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