Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: chrome/browser/ui/views/tabs/tab.cc

Issue 2091053002: Change chrome:// favicons in tabstrip based on theming. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix mac Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/alias.h" 12 #include "base/debug/alias.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "chrome/browser/themes/theme_properties.h" 16 #include "chrome/browser/themes/theme_properties.h"
17 #include "chrome/browser/ui/browser.h" 17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/layout_constants.h" 18 #include "chrome/browser/ui/layout_constants.h"
19 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" 19 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
20 #include "chrome/browser/ui/tabs/tab_utils.h" 20 #include "chrome/browser/ui/tabs/tab_utils.h"
21 #include "chrome/browser/ui/view_ids.h" 21 #include "chrome/browser/ui/view_ids.h"
22 #include "chrome/browser/ui/views/tabs/alert_indicator_button.h" 22 #include "chrome/browser/ui/views/tabs/alert_indicator_button.h"
23 #include "chrome/browser/ui/views/tabs/tab_controller.h" 23 #include "chrome/browser/ui/views/tabs/tab_controller.h"
24 #include "chrome/browser/ui/views/touch_uma/touch_uma.h" 24 #include "chrome/browser/ui/views/touch_uma/touch_uma.h"
25 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/grit/generated_resources.h" 26 #include "chrome/grit/generated_resources.h"
27 #include "content/public/browser/user_metrics.h" 27 #include "content/public/browser/user_metrics.h"
28 #include "content/public/common/url_constants.h"
28 #include "grit/components_scaled_resources.h" 29 #include "grit/components_scaled_resources.h"
29 #include "grit/components_strings.h" 30 #include "grit/components_strings.h"
30 #include "grit/theme_resources.h" 31 #include "grit/theme_resources.h"
31 #include "third_party/skia/include/effects/SkGradientShader.h" 32 #include "third_party/skia/include/effects/SkGradientShader.h"
32 #include "third_party/skia/include/pathops/SkPathOps.h" 33 #include "third_party/skia/include/pathops/SkPathOps.h"
33 #include "ui/accessibility/ax_view_state.h" 34 #include "ui/accessibility/ax_view_state.h"
34 #include "ui/base/l10n/l10n_util.h" 35 #include "ui/base/l10n/l10n_util.h"
35 #include "ui/base/material_design/material_design_controller.h" 36 #include "ui/base/material_design/material_design_controller.h"
36 #include "ui/base/models/list_selection_model.h" 37 #include "ui/base/models/list_selection_model.h"
37 #include "ui/base/resource/resource_bundle.h" 38 #include "ui/base/resource/resource_bundle.h"
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 void AnimateToState(double state) override { 157 void AnimateToState(double state) override {
157 const double kHidingOffset = 158 const double kHidingOffset =
158 Tab::GetMinimumInactiveSize().height() - GetLayoutInsets(TAB).height(); 159 Tab::GetMinimumInactiveSize().height() - GetLayoutInsets(TAB).height();
159 160
160 if (state < .5) { 161 if (state < .5) {
161 // Animate the normal icon down. 162 // Animate the normal icon down.
162 target_->SetFaviconHidingOffset( 163 target_->SetFaviconHidingOffset(
163 static_cast<int>(floor(kHidingOffset * 2.0 * state))); 164 static_cast<int>(floor(kHidingOffset * 2.0 * state)));
164 } else { 165 } else {
165 // Animate the crashed icon up. 166 // Animate the crashed icon up.
166 target_->set_should_display_crashed_favicon(); 167 target_->SetShouldDisplayCrashedFavicon(true);
167 target_->SetFaviconHidingOffset( 168 target_->SetFaviconHidingOffset(
168 static_cast<int>( 169 static_cast<int>(
169 floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset)))); 170 floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset))));
170 } 171 }
171 } 172 }
172 173
173 private: 174 private:
174 Tab* target_; 175 Tab* target_;
175 176
176 DISALLOW_COPY_AND_ASSIGN(FaviconCrashAnimation); 177 DISALLOW_COPY_AND_ASSIGN(FaviconCrashAnimation);
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 title = data_.loading ? 600 title = data_.loading ?
600 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : 601 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) :
601 CoreTabHelper::GetDefaultTitle(); 602 CoreTabHelper::GetDefaultTitle();
602 } else { 603 } else {
603 Browser::FormatTitleForDisplay(&title); 604 Browser::FormatTitleForDisplay(&title);
604 } 605 }
605 title_->SetText(title); 606 title_->SetText(title);
606 607
607 if (!data_.IsCrashed()) { 608 if (!data_.IsCrashed()) {
608 crash_icon_animation_->Stop(); 609 crash_icon_animation_->Stop();
609 should_display_crashed_favicon_ = false; 610 SetShouldDisplayCrashedFavicon(false);
610 favicon_hiding_offset_ = 0; 611 favicon_hiding_offset_ = 0;
611 } else if (!should_display_crashed_favicon_ && 612 } else if (!should_display_crashed_favicon_ &&
612 !crash_icon_animation_->is_animating()) { 613 !crash_icon_animation_->is_animating()) {
613 data_.alert_state = TabAlertState::NONE; 614 data_.alert_state = TabAlertState::NONE;
614 crash_icon_animation_->Start(); 615 crash_icon_animation_->Start();
615 } 616 }
616 617
617 if (data_.alert_state != old.alert_state) 618 if (data_.alert_state != old.alert_state)
618 alert_indicator_button_->TransitionToAlertState(data_.alert_state); 619 alert_indicator_button_->TransitionToAlertState(data_.alert_state);
619 620
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 // provided vertical space. 972 // provided vertical space.
972 title_->SetBoundsRect( 973 title_->SetBoundsRect(
973 gfx::Rect(title_left, lb.y(), std::max(title_width, 0), lb.height())); 974 gfx::Rect(title_left, lb.y(), std::max(title_width, 0), lb.height()));
974 } 975 }
975 title_->SetVisible(show_title); 976 title_->SetVisible(show_title);
976 } 977 }
977 978
978 void Tab::OnThemeChanged() { 979 void Tab::OnThemeChanged() {
979 LoadTabImages(); 980 LoadTabImages();
980 OnButtonColorMaybeChanged(); 981 OnButtonColorMaybeChanged();
982 favicon_ = gfx::ImageSkia();
981 } 983 }
982 984
983 const char* Tab::GetClassName() const { 985 const char* Tab::GetClassName() const {
984 return kViewClassName; 986 return kViewClassName;
985 } 987 }
986 988
987 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const { 989 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const {
988 // Note: Anything that affects the tooltip text should be accounted for when 990 // Note: Anything that affects the tooltip text should be accounted for when
989 // calling TooltipTextChanged() from Tab::DataChanged(). 991 // calling TooltipTextChanged() from Tab::DataChanged().
990 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.alert_state); 992 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.alert_state);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 const int ideal_delta = width() - GetPinnedWidth(); 1155 const int ideal_delta = width() - GetPinnedWidth();
1154 const int ideal_x = (GetPinnedWidth() - bounds->width()) / 2; 1156 const int ideal_x = (GetPinnedWidth() - bounds->width()) / 2;
1155 bounds->set_x( 1157 bounds->set_x(
1156 bounds->x() + static_cast<int>( 1158 bounds->x() + static_cast<int>(
1157 (1 - static_cast<float>(ideal_delta) / 1159 (1 - static_cast<float>(ideal_delta) /
1158 static_cast<float>(kPinnedTabExtraWidthToRenderAsNormal)) * 1160 static_cast<float>(kPinnedTabExtraWidthToRenderAsNormal)) *
1159 (ideal_x - bounds->x()))); 1161 (ideal_x - bounds->x())));
1160 } 1162 }
1161 1163
1162 void Tab::DataChanged(const TabRendererData& old) { 1164 void Tab::DataChanged(const TabRendererData& old) {
1165 // Clear the cached themed favicon except in the case of about:crash, which
1166 // should go on using the old icon, whatever it was.
1167 if (data().url != GURL(content::kChromeUICrashURL))
1168 favicon_ = gfx::ImageSkia();
Peter Kasting 2016/06/30 00:07:04 Do we have to clear on every change? Are there ch
Evan Stade 2016/06/30 15:39:45 I think the answer is yes, but I'm not sure if it'
1169
1163 if (data().alert_state != old.alert_state || data().title != old.title) 1170 if (data().alert_state != old.alert_state || data().title != old.title)
1164 TooltipTextChanged(); 1171 TooltipTextChanged();
1165 1172
1166 if (data().blocked == old.blocked) 1173 if (data().blocked == old.blocked)
1167 return; 1174 return;
1168 1175
1169 if (data().blocked) 1176 if (data().blocked)
1170 StartPulse(); 1177 StartPulse();
1171 else 1178 else
1172 StopPulse(); 1179 StopPulse();
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 // by incrementing by the top padding, since it's a simple rectangle. 1419 // by incrementing by the top padding, since it's a simple rectangle.
1413 canvas->TileImageInt(*fill_image, x_offset + mask_images_.l_width, 1420 canvas->TileImageInt(*fill_image, x_offset + mask_images_.l_width,
1414 y_offset + tab_insets.top(), mask_images_.l_width, 1421 y_offset + tab_insets.top(), mask_images_.l_width,
1415 tab_insets.top(), 1422 tab_insets.top(),
1416 width() - mask_images_.l_width - mask_images_.r_width, 1423 width() - mask_images_.l_width - mask_images_.r_width,
1417 height() - tab_insets.top() - toolbar_overlap); 1424 height() - tab_insets.top() - toolbar_overlap);
1418 } 1425 }
1419 1426
1420 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( 1427 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon(
1421 gfx::Canvas* canvas, 1428 gfx::Canvas* canvas,
1422 const gfx::ImageSkia& favicon,
1423 const gfx::Rect& favicon_draw_bounds) { 1429 const gfx::Rect& favicon_draw_bounds) {
1424 // The pinned tab title changed indicator consists of two parts: 1430 // The pinned tab title changed indicator consists of two parts:
1425 // . a clear (totally transparent) part over the bottom right (or left in rtl) 1431 // . a clear (totally transparent) part over the bottom right (or left in rtl)
1426 // of the favicon. This is done by drawing the favicon to a canvas, then 1432 // of the favicon. This is done by drawing the favicon to a canvas, then
1427 // drawing the clear part on top of the favicon. 1433 // drawing the clear part on top of the favicon.
1428 // . a circle in the bottom right (or left in rtl) of the favicon. 1434 // . a circle in the bottom right (or left in rtl) of the favicon.
1429 if (!favicon.isNull()) { 1435 if (!favicon_.isNull()) {
1430 const float kIndicatorCropRadius = 4.5; 1436 const float kIndicatorCropRadius = 4.5;
1431 gfx::Canvas icon_canvas(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize), 1437 gfx::Canvas icon_canvas(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize),
1432 canvas->image_scale(), false); 1438 canvas->image_scale(), false);
1433 icon_canvas.DrawImageInt(favicon, 0, 0); 1439 icon_canvas.DrawImageInt(favicon_, 0, 0);
1434 SkPaint clear_paint; 1440 SkPaint clear_paint;
1435 clear_paint.setAntiAlias(true); 1441 clear_paint.setAntiAlias(true);
1436 clear_paint.setXfermodeMode(SkXfermode::kClear_Mode); 1442 clear_paint.setXfermodeMode(SkXfermode::kClear_Mode);
1437 const int circle_x = base::i18n::IsRTL() ? 0 : gfx::kFaviconSize; 1443 const int circle_x = base::i18n::IsRTL() ? 0 : gfx::kFaviconSize;
1438 icon_canvas.DrawCircle(gfx::PointF(circle_x, gfx::kFaviconSize), 1444 icon_canvas.DrawCircle(gfx::PointF(circle_x, gfx::kFaviconSize),
1439 kIndicatorCropRadius, clear_paint); 1445 kIndicatorCropRadius, clear_paint);
1440 canvas->DrawImageInt(gfx::ImageSkia(icon_canvas.ExtractImageRep()), 0, 0, 1446 canvas->DrawImageInt(gfx::ImageSkia(icon_canvas.ExtractImageRep()), 0, 0,
1441 favicon_draw_bounds.width(), 1447 favicon_draw_bounds.width(),
1442 favicon_draw_bounds.height(), favicon_draw_bounds.x(), 1448 favicon_draw_bounds.height(), favicon_draw_bounds.x(),
1443 favicon_draw_bounds.y(), favicon_draw_bounds.width(), 1449 favicon_draw_bounds.y(), favicon_draw_bounds.width(),
(...skipping 15 matching lines...) Expand all
1459 } 1465 }
1460 1466
1461 void Tab::PaintIcon(gfx::Canvas* canvas) { 1467 void Tab::PaintIcon(gfx::Canvas* canvas) {
1462 gfx::Rect bounds = favicon_bounds_; 1468 gfx::Rect bounds = favicon_bounds_;
1463 bounds.set_x(GetMirroredXForRect(bounds)); 1469 bounds.set_x(GetMirroredXForRect(bounds));
1464 bounds.Offset(0, favicon_hiding_offset_); 1470 bounds.Offset(0, favicon_hiding_offset_);
1465 bounds.Intersect(GetContentsBounds()); 1471 bounds.Intersect(GetContentsBounds());
1466 if (bounds.IsEmpty()) 1472 if (bounds.IsEmpty())
1467 return; 1473 return;
1468 1474
1469 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { 1475 // Throbber will do its own painting.
1470 // Throbber will do its own painting. 1476 if (data().network_state != TabRendererData::NETWORK_STATE_NONE)
1471 return; 1477 return;
1478
1479 // Ensure that |favicon_| is created.
1480 if (favicon_.isNull()) {
1481 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
1482 favicon_ = should_display_crashed_favicon_
1483 ? *rb->GetImageSkiaNamed(IDR_CRASH_SAD_FAVICON)
1484 : data().favicon;
1485 // Themify the icon if it's a chrome:// page or if it's the sadtab favicon.
Peter Kasting 2016/06/30 00:07:04 Should this share code with the bookmark bar? Sho
Evan Stade 2016/06/30 15:39:45 I didn't share code because I didn't see a clear a
1486 if (!favicon_.isNull() &&
1487 (should_display_crashed_favicon_ ||
1488 (data().url.SchemeIs(content::kChromeUIScheme)) ||
1489 favicon_.BackedBySameObjectAs(
1490 *rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON)))) {
1491 color_utils::HSL icon_shift =
1492 GetThemeProvider()->GetTint(ThemeProperties::TINT_BUTTONS);
1493 favicon_ =
1494 gfx::ImageSkiaOperations::CreateHSLShiftedImage(favicon_, icon_shift);
1495 }
1472 } 1496 }
1473 const gfx::ImageSkia& favicon =
1474 should_display_crashed_favicon_
1475 ? *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
1476 IDR_CRASH_SAD_FAVICON)
1477 : data().favicon;
1478 1497
1479 if (showing_pinned_tab_title_changed_indicator_ && 1498 if (showing_pinned_tab_title_changed_indicator_ &&
1480 !should_display_crashed_favicon_) { 1499 !should_display_crashed_favicon_) {
1481 PaintPinnedTabTitleChangedIndicatorAndIcon(canvas, favicon, bounds); 1500 PaintPinnedTabTitleChangedIndicatorAndIcon(canvas, bounds);
1482 } else if (!favicon.isNull()) { 1501 } else if (!favicon_.isNull()) {
1483 canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), 1502 canvas->DrawImageInt(favicon_, 0, 0, bounds.width(), bounds.height(),
1484 bounds.x(), bounds.y(), bounds.width(), 1503 bounds.x(), bounds.y(), bounds.width(),
1485 bounds.height(), false); 1504 bounds.height(), false);
1486 } 1505 }
1487 } 1506 }
1488 1507
1489 void Tab::AdvanceLoadingAnimation() { 1508 void Tab::AdvanceLoadingAnimation() {
1490 const TabRendererData::NetworkState state = data().network_state; 1509 const TabRendererData::NetworkState state = data().network_state;
1491 if (controller_->IsImmersiveStyle()) { 1510 if (controller_->IsImmersiveStyle()) {
1492 throbber_->SetVisible(false); 1511 throbber_->SetVisible(false);
1493 if (state == TabRendererData::NETWORK_STATE_WAITING) { 1512 if (state == TabRendererData::NETWORK_STATE_WAITING) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 const double offset = 1606 const double offset =
1588 is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity; 1607 is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity;
1589 1608
1590 if (pulse_animation_->is_animating()) 1609 if (pulse_animation_->is_animating())
1591 val += pulse_animation_->GetCurrentValue() * offset; 1610 val += pulse_animation_->GetCurrentValue() * offset;
1592 else if (hover_controller_.ShouldDraw()) 1611 else if (hover_controller_.ShouldDraw())
1593 val += hover_controller_.GetAnimationValue() * offset; 1612 val += hover_controller_.GetAnimationValue() * offset;
1594 return val; 1613 return val;
1595 } 1614 }
1596 1615
1616 void Tab::SetShouldDisplayCrashedFavicon(bool value) {
1617 if (value == should_display_crashed_favicon_)
1618 return;
1619
1620 should_display_crashed_favicon_ = value;
1621 favicon_ = gfx::ImageSkia();
1622 }
1623
1597 void Tab::SetFaviconHidingOffset(int offset) { 1624 void Tab::SetFaviconHidingOffset(int offset) {
1598 favicon_hiding_offset_ = offset; 1625 favicon_hiding_offset_ = offset;
1599 ScheduleIconPaint(); 1626 ScheduleIconPaint();
1600 } 1627 }
1601 1628
1602 void Tab::OnButtonColorMaybeChanged() { 1629 void Tab::OnButtonColorMaybeChanged() {
1603 // The theme provider may be null if we're not currently in a widget 1630 // The theme provider may be null if we're not currently in a widget
1604 // hierarchy. 1631 // hierarchy.
1605 const ui::ThemeProvider* theme_provider = GetThemeProvider(); 1632 const ui::ThemeProvider* theme_provider = GetThemeProvider();
1606 if (!theme_provider) 1633 if (!theme_provider)
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 inactive_images_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER); 1768 inactive_images_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER);
1742 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); 1769 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT);
1743 inactive_images_.l_width = inactive_images_.image_l->width(); 1770 inactive_images_.l_width = inactive_images_.image_l->width();
1744 inactive_images_.r_width = inactive_images_.image_r->width(); 1771 inactive_images_.r_width = inactive_images_.image_r->width();
1745 1772
1746 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT); 1773 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT);
1747 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT); 1774 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT);
1748 mask_images_.l_width = mask_images_.image_l->width(); 1775 mask_images_.l_width = mask_images_.image_l->width();
1749 mask_images_.r_width = mask_images_.image_r->width(); 1776 mask_images_.r_width = mask_images_.image_r->width();
1750 } 1777 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698