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/gtk/tabs/tab_renderer_gtk.h" | 5 #include "chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 favicon_bounds_.height()); | 495 favicon_bounds_.height()); |
496 cairo_clip(cr); | 496 cairo_clip(cr); |
497 | 497 |
498 // The tab is rendered into a windowless widget whose offset is at the | 498 // The tab is rendered into a windowless widget whose offset is at the |
499 // coordinate event->area. Translate by these offsets so we can render at | 499 // coordinate event->area. Translate by these offsets so we can render at |
500 // (0,0) to match Windows' rendering metrics. | 500 // (0,0) to match Windows' rendering metrics. |
501 cairo_matrix_t cairo_matrix; | 501 cairo_matrix_t cairo_matrix; |
502 cairo_matrix_init_translate(&cairo_matrix, x(), y()); | 502 cairo_matrix_init_translate(&cairo_matrix, x(), y()); |
503 cairo_set_matrix(cr, &cairo_matrix); | 503 cairo_set_matrix(cr, &cairo_matrix); |
504 | 504 |
505 // Which background should we be painting? | |
506 int theme_id; | |
507 int offset_y = 0; | |
508 if (IsActive()) { | |
509 theme_id = IDR_THEME_TOOLBAR; | |
510 } else { | |
511 theme_id = data_.incognito ? IDR_THEME_TAB_BACKGROUND_INCOGNITO : | |
512 IDR_THEME_TAB_BACKGROUND; | |
513 | |
514 if (!theme_service_->HasCustomImage(theme_id)) | |
515 offset_y = background_offset_y_; | |
516 } | |
517 | |
518 // Paint the background behind the favicon. | 505 // Paint the background behind the favicon. |
519 const gfx::Image tab_bg = theme_service_->GetImageNamed(theme_id); | 506 SetTabBackgroundImageAsSource(cr, widget, favicon_bounds_); |
520 tab_bg.ToCairo()->SetSource(cr, widget, -x(), -offset_y); | |
521 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); | |
522 cairo_rectangle(cr, | 507 cairo_rectangle(cr, |
523 favicon_bounds_.x(), favicon_bounds_.y(), | 508 favicon_bounds_.x(), favicon_bounds_.y(), |
524 favicon_bounds_.width(), favicon_bounds_.height()); | 509 favicon_bounds_.width(), favicon_bounds_.height()); |
525 cairo_fill(cr); | 510 cairo_fill(cr); |
526 | 511 |
527 if (!IsActive()) { | 512 if (!IsActive()) { |
528 double throb_value = GetThrobValue(); | 513 double throb_value = GetThrobValue(); |
529 if (throb_value > 0) { | 514 if (throb_value > 0) { |
530 cairo_push_group(cr); | 515 cairo_push_group(cr); |
531 gfx::Image active_bg = | 516 gfx::Image active_bg = |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 favicon_overlay_animation_->is_animating()) { | 935 favicon_overlay_animation_->is_animating()) { |
951 if (data_.capture_state == PROJECTING) { | 936 if (data_.capture_state == PROJECTING) { |
952 theme_service_->GetImageNamed(IDR_TAB_CAPTURE).ToCairo()-> | 937 theme_service_->GetImageNamed(IDR_TAB_CAPTURE).ToCairo()-> |
953 SetSource(cr, | 938 SetSource(cr, |
954 widget, | 939 widget, |
955 favicon_bounds_.x(), | 940 favicon_bounds_.x(), |
956 favicon_bounds_.y() + favicon_hiding_offset_); | 941 favicon_bounds_.y() + favicon_hiding_offset_); |
957 cairo_paint(cr); | 942 cairo_paint(cr); |
958 } else if (data_.capture_state == RECORDING) { | 943 } else if (data_.capture_state == RECORDING) { |
959 // Add mask around the recording overlay image (red dot). | 944 // Add mask around the recording overlay image (red dot). |
960 gfx::CairoCachedSurface* tab_bg; | |
961 if (IsActive()) { | |
962 tab_bg = theme_service_->GetImageNamed(IDR_THEME_TOOLBAR).ToCairo(); | |
963 } else { | |
964 int theme_id = data_.incognito ? | |
965 IDR_THEME_TAB_BACKGROUND_INCOGNITO : IDR_THEME_TAB_BACKGROUND; | |
966 tab_bg = theme_service_->GetImageNamed(theme_id).ToCairo(); | |
967 } | |
968 tab_bg->SetSource(cr, widget, -background_offset_x_, 0); | |
969 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); | |
970 | |
971 gfx::CairoCachedSurface* recording_mask = | 945 gfx::CairoCachedSurface* recording_mask = |
972 theme_service_->GetImageNamed(IDR_TAB_RECORDING_MASK).ToCairo(); | 946 theme_service_->GetImageNamed(IDR_TAB_RECORDING_MASK).ToCairo(); |
973 int offset_from_right = data_.cairo_overlay.Width() + | 947 int offset_from_right = data_.cairo_overlay.Width() + |
974 (recording_mask->Width() - data_.cairo_overlay.Width()) / 2; | 948 (recording_mask->Width() - data_.cairo_overlay.Width()) / 2; |
975 int favicon_x = favicon_bounds_.x() + favicon_bounds_.width() - | 949 int favicon_x = favicon_bounds_.x() + favicon_bounds_.width() - |
976 offset_from_right; | 950 offset_from_right; |
977 int offset_from_bottom = data_.cairo_overlay.Height() + | 951 int offset_from_bottom = data_.cairo_overlay.Height() + |
978 (recording_mask->Height() - data_.cairo_overlay.Height()) / 2; | 952 (recording_mask->Height() - data_.cairo_overlay.Height()) / 2; |
979 int favicon_y = favicon_bounds_.y() + favicon_hiding_offset_ + | 953 int favicon_y = favicon_bounds_.y() + favicon_hiding_offset_ + |
980 favicon_bounds_.height() - offset_from_bottom; | 954 favicon_bounds_.height() - offset_from_bottom; |
| 955 SetTabBackgroundImageAsSource(cr, widget, |
| 956 gfx::Rect(favicon_x, favicon_y, recording_mask->Width(), |
| 957 recording_mask->Height())); |
981 recording_mask->MaskSource(cr, widget, favicon_x, favicon_y); | 958 recording_mask->MaskSource(cr, widget, favicon_x, favicon_y); |
982 | 959 |
983 if (!IsActive()) { | 960 if (!IsActive()) { |
984 double throb_value = GetThrobValue(); | 961 double throb_value = GetThrobValue(); |
985 if (throb_value > 0) { | 962 if (throb_value > 0) { |
986 cairo_push_group(cr); | 963 cairo_push_group(cr); |
987 gfx::CairoCachedSurface* active_bg = | 964 gfx::CairoCachedSurface* active_bg = |
988 theme_service_->GetImageNamed(IDR_THEME_TOOLBAR).ToCairo(); | 965 theme_service_->GetImageNamed(IDR_THEME_TOOLBAR).ToCairo(); |
989 active_bg->SetSource(cr, widget, -background_offset_x_, 0); | 966 active_bg->SetSource(cr, widget, -background_offset_x_, 0); |
990 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); | 967 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); |
(...skipping 28 matching lines...) Expand all Loading... |
1019 double throb_value = GetThrobValue(); | 996 double throb_value = GetThrobValue(); |
1020 if (throb_value > 0) { | 997 if (throb_value > 0) { |
1021 cairo_push_group(cr); | 998 cairo_push_group(cr); |
1022 PaintActiveTabBackground(widget, cr); | 999 PaintActiveTabBackground(widget, cr); |
1023 cairo_pop_group_to_source(cr); | 1000 cairo_pop_group_to_source(cr); |
1024 cairo_paint_with_alpha(cr, throb_value); | 1001 cairo_paint_with_alpha(cr, throb_value); |
1025 } | 1002 } |
1026 } | 1003 } |
1027 } | 1004 } |
1028 | 1005 |
1029 void TabRendererGtk::DrawTabBackground( | 1006 void TabRendererGtk::SetTabBackgroundImageAsSource(cairo_t* cr, |
1030 cairo_t* cr, | 1007 GtkWidget* widget, |
1031 GtkWidget* widget, | 1008 const gfx::Rect& bounds) { |
1032 const gfx::Image& tab_bg, | 1009 int tab_bg_id = 0; |
1033 int offset_x, | 1010 int tab_bg_offset_y = 0; |
1034 int offset_y) { | 1011 int tab_bg_overlay_id = 0; |
1035 tab_bg.ToCairo()->SetSource(cr, widget, -offset_x, -offset_y); | 1012 if (IsActive()) { |
| 1013 tab_bg_id = IDR_THEME_TOOLBAR; |
| 1014 |
| 1015 // The image at |tab_bg_id| is aligned with the top of the tab. |
| 1016 tab_bg_offset_y = 0; |
| 1017 } else { |
| 1018 tab_bg_id = data_.incognito ? IDR_THEME_TAB_BACKGROUND_INCOGNITO : |
| 1019 IDR_THEME_TAB_BACKGROUND; |
| 1020 // |tab_bg_id| is the tinted frame image. Set |tab_bg_offset_y_| so that |
| 1021 // the image is aligned with the top of the frame. |
| 1022 tab_bg_offset_y = background_offset_y_; |
| 1023 |
| 1024 tab_bg_overlay_id = data_.incognito ? |
| 1025 IDR_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY : |
| 1026 IDR_THEME_TAB_BACKGROUND_OVERLAY; |
| 1027 } |
| 1028 gfx::Image tab_bg = theme_service_->GetImageNamed(tab_bg_id); |
| 1029 tab_bg.ToCairo()->SetSource(cr, widget, -background_offset_x_, |
| 1030 -tab_bg_offset_y); |
1036 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); | 1031 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); |
1037 | 1032 |
| 1033 // The default theme does not provide overlay images. |
| 1034 if (tab_bg_overlay_id != 0 && |
| 1035 theme_service_->HasCustomImage(tab_bg_overlay_id)) { |
| 1036 cairo_push_group(cr); |
| 1037 cairo_rectangle(cr, bounds.x(), bounds.y(), bounds.width(), |
| 1038 bounds.height()); |
| 1039 cairo_fill_preserve(cr); |
| 1040 |
| 1041 gfx::Image tab_bg_overlay = |
| 1042 theme_service_->GetImageNamed(tab_bg_overlay_id); |
| 1043 // |tab_bg_overlay| is aligned with the top of the tab. |
| 1044 tab_bg_overlay.ToCairo()->SetSource(cr, widget, -background_offset_x_, 0); |
| 1045 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); |
| 1046 cairo_fill(cr); |
| 1047 |
| 1048 cairo_pop_group_to_source(cr); |
| 1049 } |
| 1050 } |
| 1051 |
| 1052 void TabRendererGtk::DrawTabBackground(cairo_t* cr, GtkWidget* widget) { |
| 1053 SetTabBackgroundImageAsSource(cr, widget, |
| 1054 gfx::Rect(0, 0, width(), tab_inactive_l_height_)); |
| 1055 |
1038 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1056 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1039 | 1057 |
1040 // Draw left edge | 1058 // Draw left edge |
1041 gfx::Image& tab_l_mask = rb.GetNativeImageNamed(IDR_TAB_ALPHA_LEFT); | 1059 gfx::Image& tab_l_mask = rb.GetNativeImageNamed(IDR_TAB_ALPHA_LEFT); |
1042 tab_l_mask.ToCairo()->MaskSource(cr, widget, 0, 0); | 1060 tab_l_mask.ToCairo()->MaskSource(cr, widget, 0, 0); |
1043 | 1061 |
1044 // Draw center | 1062 // Draw center |
1045 cairo_rectangle(cr, | 1063 cairo_rectangle(cr, |
1046 tab_active_l_width_, kDropShadowOffset, | 1064 tab_active_l_width_, kDropShadowOffset, |
1047 width() - (2 * tab_active_l_width_), | 1065 width() - (2 * tab_active_l_width_), |
(...skipping 29 matching lines...) Expand all Loading... |
1077 cairo_fill(cr); | 1095 cairo_fill(cr); |
1078 | 1096 |
1079 // Draw right drop shadow | 1097 // Draw right drop shadow |
1080 active_image_r.ToCairo()->SetSource( | 1098 active_image_r.ToCairo()->SetSource( |
1081 cr, widget, width() - active_image_r.ToCairo()->Width(), 0); | 1099 cr, widget, width() - active_image_r.ToCairo()->Width(), 0); |
1082 cairo_paint(cr); | 1100 cairo_paint(cr); |
1083 } | 1101 } |
1084 | 1102 |
1085 void TabRendererGtk::PaintInactiveTabBackground(GtkWidget* widget, | 1103 void TabRendererGtk::PaintInactiveTabBackground(GtkWidget* widget, |
1086 cairo_t* cr) { | 1104 cairo_t* cr) { |
1087 int theme_id = data_.incognito ? | 1105 DrawTabBackground(cr, widget); |
1088 IDR_THEME_TAB_BACKGROUND_INCOGNITO : IDR_THEME_TAB_BACKGROUND; | |
1089 | |
1090 gfx::Image tab_bg = theme_service_->GetImageNamed(theme_id); | |
1091 | |
1092 // If the theme is providing a custom background image, then its top edge | |
1093 // should be at the top of the tab. Otherwise, we assume that the background | |
1094 // image is a composited foreground + frame image. | |
1095 int offset_y = theme_service_->HasCustomImage(theme_id) ? | |
1096 0 : background_offset_y_; | |
1097 | |
1098 DrawTabBackground(cr, widget, tab_bg, background_offset_x_, offset_y); | |
1099 | |
1100 DrawTabShadow(cr, widget, IDR_TAB_INACTIVE_LEFT, IDR_TAB_INACTIVE_CENTER, | 1106 DrawTabShadow(cr, widget, IDR_TAB_INACTIVE_LEFT, IDR_TAB_INACTIVE_CENTER, |
1101 IDR_TAB_INACTIVE_RIGHT); | 1107 IDR_TAB_INACTIVE_RIGHT); |
1102 } | 1108 } |
1103 | 1109 |
1104 void TabRendererGtk::PaintActiveTabBackground(GtkWidget* widget, | 1110 void TabRendererGtk::PaintActiveTabBackground(GtkWidget* widget, |
1105 cairo_t* cr) { | 1111 cairo_t* cr) { |
1106 gfx::Image tab_bg = theme_service_->GetImageNamed(IDR_THEME_TOOLBAR); | 1112 DrawTabBackground(cr, widget); |
1107 | |
1108 DrawTabBackground(cr, widget, tab_bg, background_offset_x_, 0); | |
1109 DrawTabShadow(cr, widget, IDR_TAB_ACTIVE_LEFT, IDR_TAB_ACTIVE_CENTER, | 1113 DrawTabShadow(cr, widget, IDR_TAB_ACTIVE_LEFT, IDR_TAB_ACTIVE_CENTER, |
1110 IDR_TAB_ACTIVE_RIGHT); | 1114 IDR_TAB_ACTIVE_RIGHT); |
1111 } | 1115 } |
1112 | 1116 |
1113 void TabRendererGtk::PaintLoadingAnimation(GtkWidget* widget, | 1117 void TabRendererGtk::PaintLoadingAnimation(GtkWidget* widget, |
1114 cairo_t* cr) { | 1118 cairo_t* cr) { |
1115 int id = loading_animation_.animation_state() == ANIMATION_WAITING ? | 1119 int id = loading_animation_.animation_state() == ANIMATION_WAITING ? |
1116 IDR_THROBBER_WAITING : IDR_THROBBER; | 1120 IDR_THROBBER_WAITING : IDR_THROBBER; |
1117 gfx::Image throbber = theme_service_->GetImageNamed(id); | 1121 gfx::Image throbber = theme_service_->GetImageNamed(id); |
1118 | 1122 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 GdkPixbuf* tab_close = rb.GetNativeImageNamed(IDR_CLOSE_1).ToGdkPixbuf(); | 1252 GdkPixbuf* tab_close = rb.GetNativeImageNamed(IDR_CLOSE_1).ToGdkPixbuf(); |
1249 close_button_width_ = gdk_pixbuf_get_width(tab_close); | 1253 close_button_width_ = gdk_pixbuf_get_width(tab_close); |
1250 close_button_height_ = gdk_pixbuf_get_height(tab_close); | 1254 close_button_height_ = gdk_pixbuf_get_height(tab_close); |
1251 | 1255 |
1252 const gfx::Font& base_font = rb.GetFont(ui::ResourceBundle::BaseFont); | 1256 const gfx::Font& base_font = rb.GetFont(ui::ResourceBundle::BaseFont); |
1253 title_font_ = new gfx::Font(base_font.GetFontName(), kFontPixelSize); | 1257 title_font_ = new gfx::Font(base_font.GetFontName(), kFontPixelSize); |
1254 title_font_height_ = title_font_->GetHeight(); | 1258 title_font_height_ = title_font_->GetHeight(); |
1255 | 1259 |
1256 initialized_ = true; | 1260 initialized_ = true; |
1257 } | 1261 } |
OLD | NEW |