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

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

Issue 1401633003: Implement Material Design for the tabstrip. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resync Created 5 years 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
« no previous file with comments | « chrome/browser/ui/views/tabs/tab.h ('k') | chrome/browser/ui/views/tabs/tab_strip.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <limits> 7 #include <limits>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/alias.h" 10 #include "base/debug/alias.h"
11 #include "base/profiler/scoped_tracker.h" 11 #include "base/profiler/scoped_tracker.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/themes/theme_properties.h" 13 #include "chrome/browser/themes/theme_properties.h"
14 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/layout_constants.h" 15 #include "chrome/browser/ui/layout_constants.h"
16 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" 16 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
17 #include "chrome/browser/ui/tabs/tab_utils.h" 17 #include "chrome/browser/ui/tabs/tab_utils.h"
18 #include "chrome/browser/ui/view_ids.h" 18 #include "chrome/browser/ui/view_ids.h"
19 #include "chrome/browser/ui/views/tabs/media_indicator_button.h" 19 #include "chrome/browser/ui/views/tabs/media_indicator_button.h"
20 #include "chrome/browser/ui/views/tabs/tab_controller.h" 20 #include "chrome/browser/ui/views/tabs/tab_controller.h"
21 #include "chrome/browser/ui/views/theme_image_mapper.h" 21 #include "chrome/browser/ui/views/theme_image_mapper.h"
22 #include "chrome/browser/ui/views/touch_uma/touch_uma.h" 22 #include "chrome/browser/ui/views/touch_uma/touch_uma.h"
23 #include "chrome/common/chrome_switches.h" 23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/grit/generated_resources.h" 24 #include "chrome/grit/generated_resources.h"
25 #include "content/public/browser/user_metrics.h" 25 #include "content/public/browser/user_metrics.h"
26 #include "grit/components_scaled_resources.h" 26 #include "grit/components_scaled_resources.h"
27 #include "grit/theme_resources.h" 27 #include "grit/theme_resources.h"
28 #include "third_party/skia/include/effects/SkGradientShader.h" 28 #include "third_party/skia/include/effects/SkGradientShader.h"
29 #include "third_party/skia/include/pathops/SkPathOps.h"
29 #include "ui/accessibility/ax_view_state.h" 30 #include "ui/accessibility/ax_view_state.h"
30 #include "ui/base/l10n/l10n_util.h" 31 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/base/models/list_selection_model.h" 32 #include "ui/base/models/list_selection_model.h"
33 #include "ui/base/resource/material_design/material_design_controller.h"
32 #include "ui/base/resource/resource_bundle.h" 34 #include "ui/base/resource/resource_bundle.h"
33 #include "ui/base/theme_provider.h" 35 #include "ui/base/theme_provider.h"
34 #include "ui/gfx/animation/animation_container.h" 36 #include "ui/gfx/animation/animation_container.h"
35 #include "ui/gfx/animation/multi_animation.h" 37 #include "ui/gfx/animation/multi_animation.h"
36 #include "ui/gfx/animation/throb_animation.h" 38 #include "ui/gfx/animation/throb_animation.h"
37 #include "ui/gfx/canvas.h" 39 #include "ui/gfx/canvas.h"
38 #include "ui/gfx/color_analysis.h" 40 #include "ui/gfx/color_analysis.h"
39 #include "ui/gfx/favicon_size.h" 41 #include "ui/gfx/favicon_size.h"
40 #include "ui/gfx/geometry/rect_conversions.h" 42 #include "ui/gfx/geometry/rect_conversions.h"
41 #include "ui/gfx/image/image_skia_operations.h" 43 #include "ui/gfx/image/image_skia_operations.h"
42 #include "ui/gfx/paint_vector_icon.h" 44 #include "ui/gfx/paint_vector_icon.h"
43 #include "ui/gfx/path.h" 45 #include "ui/gfx/path.h"
46 #include "ui/gfx/scoped_canvas.h"
44 #include "ui/gfx/skia_util.h" 47 #include "ui/gfx/skia_util.h"
45 #include "ui/gfx/vector_icons_public.h" 48 #include "ui/gfx/vector_icons_public.h"
46 #include "ui/resources/grit/ui_resources.h" 49 #include "ui/resources/grit/ui_resources.h"
47 #include "ui/views/border.h" 50 #include "ui/views/border.h"
48 #include "ui/views/controls/button/image_button.h" 51 #include "ui/views/controls/button/image_button.h"
49 #include "ui/views/controls/label.h" 52 #include "ui/views/controls/label.h"
50 #include "ui/views/rect_based_targeting_utils.h" 53 #include "ui/views/rect_based_targeting_utils.h"
51 #include "ui/views/view_targeter.h" 54 #include "ui/views/view_targeter.h"
52 #include "ui/views/widget/tooltip_manager.h" 55 #include "ui/views/widget/tooltip_manager.h"
53 #include "ui/views/widget/widget.h" 56 #include "ui/views/widget/widget.h"
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 scale_factor(ui::SCALE_FACTOR_NONE) { 432 scale_factor(ui::SCALE_FACTOR_NONE) {
430 } 433 }
431 434
432 Tab::ImageCacheEntry::~ImageCacheEntry() {} 435 Tab::ImageCacheEntry::~ImageCacheEntry() {}
433 436
434 //////////////////////////////////////////////////////////////////////////////// 437 ////////////////////////////////////////////////////////////////////////////////
435 // Tab, statics: 438 // Tab, statics:
436 439
437 // static 440 // static
438 const char Tab::kViewClassName[] = "Tab"; 441 const char Tab::kViewClassName[] = "Tab";
442 const SkColor Tab::kInactiveTabColor = SkColorSetRGB(0xD0, 0xD0, 0xD0);
439 Tab::TabImages Tab::active_images_ = {0}; 443 Tab::TabImages Tab::active_images_ = {0};
440 Tab::TabImages Tab::inactive_images_ = {0}; 444 Tab::TabImages Tab::inactive_images_ = {0};
441 Tab::TabImages Tab::mask_images_ = {0}; 445 Tab::TabImages Tab::mask_images_ = {0};
442 Tab::ImageCache* Tab::image_cache_ = NULL; 446 Tab::ImageCache* Tab::image_cache_ = NULL;
443 447
444 //////////////////////////////////////////////////////////////////////////////// 448 ////////////////////////////////////////////////////////////////////////////////
445 // Tab, public: 449 // Tab, public:
446 450
447 Tab::Tab(TabController* controller) 451 Tab::Tab(TabController* controller)
448 : controller_(controller), 452 : controller_(controller),
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 // buttons is available for click-to-select. If neither are visible, the 645 // buttons is available for click-to-select. If neither are visible, the
642 // entire tab region is available. 646 // entire tab region is available.
643 const int indicator_left = showing_media_indicator_ ? 647 const int indicator_left = showing_media_indicator_ ?
644 media_indicator_button_->x() : width(); 648 media_indicator_button_->x() : width();
645 const int close_button_left = showing_close_button_ ? 649 const int close_button_left = showing_close_button_ ?
646 close_button_->x() : width(); 650 close_button_->x() : width();
647 return std::min(indicator_left, close_button_left); 651 return std::min(indicator_left, close_button_left);
648 } 652 }
649 653
650 gfx::Size Tab::GetMinimumInactiveSize() { 654 gfx::Size Tab::GetMinimumInactiveSize() {
651 // Since we use images, the real minimum height of the image is 655 int height;
652 // defined most accurately by the height of the end cap images. 656 if (ui::MaterialDesignController::IsModeMaterial()) {
653 InitTabResources(); 657 const int kTabHeight = 29;
654 int height = active_images_.image_l->height(); 658 height = kTabHeight;
659 } else {
660 // Since we use images, the real minimum height of the image is
661 // defined most accurately by the height of the end cap images.
662 InitTabResources();
663 height = active_images_.image_l->height();
664 }
665
655 return gfx::Size(GetLayoutInsets(TAB).width(), height); 666 return gfx::Size(GetLayoutInsets(TAB).width(), height);
656 } 667 }
657 668
658 // static 669 // static
659 gfx::Size Tab::GetMinimumActiveSize() { 670 gfx::Size Tab::GetMinimumActiveSize() {
660 gfx::Size minimum_size = GetMinimumInactiveSize(); 671 gfx::Size minimum_size = GetMinimumInactiveSize();
661 minimum_size.Enlarge(gfx::kFaviconSize, 0); 672 minimum_size.Enlarge(gfx::kFaviconSize, 0);
662 return minimum_size; 673 return minimum_size;
663 } 674 }
664 675
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 bool Tab::GetHitTestMask(gfx::Path* mask) const { 769 bool Tab::GetHitTestMask(gfx::Path* mask) const {
759 DCHECK(mask); 770 DCHECK(mask);
760 771
761 // When the window is maximized we don't want to shave off the edges or top 772 // When the window is maximized we don't want to shave off the edges or top
762 // shadow of the tab, such that the user can click anywhere along the top 773 // shadow of the tab, such that the user can click anywhere along the top
763 // edge of the screen to select a tab. Ditto for immersive fullscreen. 774 // edge of the screen to select a tab. Ditto for immersive fullscreen.
764 const views::Widget* widget = GetWidget(); 775 const views::Widget* widget = GetWidget();
765 const bool extend_to_top = 776 const bool extend_to_top =
766 widget && (widget->IsMaximized() || widget->IsFullscreen()); 777 widget && (widget->IsMaximized() || widget->IsFullscreen());
767 778
768 // Hit mask constants. 779 if (ui::MaterialDesignController::IsModeMaterial()) {
769 const SkScalar kTabCapWidth = 15; 780 SkPath border;
770 const SkScalar kTabTopCurveWidth = 4; 781 const float scale = GetWidget()->GetCompositor()->device_scale_factor();
771 const SkScalar kTabBottomCurveWidth = 3; 782 GetBorderPath(scale, extend_to_top, &border);
783 mask->addPath(border, SkMatrix::MakeScale(1 / scale));
784 } else {
785 // Hit mask constants.
786 const SkScalar kTabCapWidth = 15;
787 const SkScalar kTabTopCurveWidth = 4;
788 const SkScalar kTabBottomCurveWidth = 3;
772 #if defined(OS_MACOSX) 789 #if defined(OS_MACOSX)
773 // Mac's Cocoa UI doesn't have shadows. 790 // Mac's Cocoa UI doesn't have shadows.
774 const SkScalar kTabInset = 0; 791 const SkScalar kTabInset = 0;
775 #elif defined(TOOLKIT_VIEWS) 792 #elif defined(TOOLKIT_VIEWS)
776 // The views browser UI has shadows in the left, right and top parts of the 793 // The views browser UI has shadows in the left, right and top parts of the
777 // tab. 794 // tab.
778 const SkScalar kTabInset = 6; 795 const SkScalar kTabInset = 6;
779 #endif 796 #endif
780 797
781 SkScalar left = kTabInset; 798 SkScalar left = kTabInset;
782 SkScalar top = GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT); 799 SkScalar top = GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT);
783 SkScalar right = SkIntToScalar(width()) - kTabInset; 800 SkScalar right = SkIntToScalar(width()) - kTabInset;
784 SkScalar bottom = SkIntToScalar(height()); 801 SkScalar bottom = SkIntToScalar(height());
785 802
786 // Start in the lower-left corner. 803 // Start in the lower-left corner.
787 mask->moveTo(left, bottom); 804 mask->moveTo(left, bottom);
788 805
789 // Left end cap. 806 // Left end cap.
790 mask->lineTo(left + kTabBottomCurveWidth, bottom - kTabBottomCurveWidth); 807 mask->lineTo(left + kTabBottomCurveWidth, bottom - kTabBottomCurveWidth);
791 mask->lineTo(left + kTabCapWidth - kTabTopCurveWidth, 808 mask->lineTo(left + kTabCapWidth - kTabTopCurveWidth,
792 top + kTabTopCurveWidth); 809 top + kTabTopCurveWidth);
793 mask->lineTo(left + kTabCapWidth, top); 810 mask->lineTo(left + kTabCapWidth, top);
794 811
795 // Extend over the top shadow area if we have one and the caller wants it. 812 // Extend over the top shadow area if we have one and the caller wants it.
796 if (top > 0 && extend_to_top) { 813 if (top > 0 && extend_to_top) {
797 mask->lineTo(left + kTabCapWidth, 0); 814 mask->lineTo(left + kTabCapWidth, 0);
798 mask->lineTo(right - kTabCapWidth, 0); 815 mask->lineTo(right - kTabCapWidth, 0);
816 }
817
818 // Connect to the right cap.
819 mask->lineTo(right - kTabCapWidth, top);
820
821 // Right end cap.
822 mask->lineTo(right - kTabCapWidth + kTabTopCurveWidth,
823 top + kTabTopCurveWidth);
824 mask->lineTo(right - kTabBottomCurveWidth, bottom - kTabBottomCurveWidth);
825 mask->lineTo(right, bottom);
826
827 // Close out the path.
828 mask->lineTo(left, bottom);
829 mask->close();
799 } 830 }
800 831
801 // Connect to the right cap.
802 mask->lineTo(right - kTabCapWidth, top);
803
804 // Right end cap.
805 mask->lineTo(right - kTabCapWidth + kTabTopCurveWidth,
806 top + kTabTopCurveWidth);
807 mask->lineTo(right - kTabBottomCurveWidth, bottom - kTabBottomCurveWidth);
808 mask->lineTo(right, bottom);
809
810 // Close out the path.
811 mask->lineTo(left, bottom);
812 mask->close();
813
814 // It is possible for a portion of the tab to be occluded if tabs are 832 // It is possible for a portion of the tab to be occluded if tabs are
815 // stacked, so modify the hit test mask to only include the visible 833 // stacked, so modify the hit test mask to only include the visible
816 // region of the tab. 834 // region of the tab.
817 gfx::Rect clip; 835 gfx::Rect clip;
818 controller_->ShouldPaintTab(this, &clip); 836 controller_->ShouldPaintTab(this, &clip);
819 if (clip.size().GetArea()) { 837 if (clip.size().GetArea()) {
820 SkRect intersection(mask->getBounds()); 838 SkRect intersection(mask->getBounds());
821 mask->reset(); 839 mask->reset();
822 if (!intersection.intersect(RectToSkRect(clip))) 840 if (!intersection.intersect(RectToSkRect(clip)))
823 return false; 841 return false;
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 int alpha = 255; 1251 int alpha = 255;
1234 if (pinned_title_change_animation_->current_part_index() == 0) { 1252 if (pinned_title_change_animation_->current_part_index() == 0) {
1235 x = pinned_title_change_animation_->CurrentValueBetween( 1253 x = pinned_title_change_animation_->CurrentValueBetween(
1236 width() + radius - kPinnedTitleChangeInitialXOffset, radius); 1254 width() + radius - kPinnedTitleChangeInitialXOffset, radius);
1237 } else if (pinned_title_change_animation_->current_part_index() == 2) { 1255 } else if (pinned_title_change_animation_->current_part_index() == 2) {
1238 x = pinned_title_change_animation_->CurrentValueBetween(radius, -radius); 1256 x = pinned_title_change_animation_->CurrentValueBetween(radius, -radius);
1239 alpha = pinned_title_change_animation_->CurrentValueBetween(255, 0); 1257 alpha = pinned_title_change_animation_->CurrentValueBetween(255, 0);
1240 } 1258 }
1241 SkPoint p; 1259 SkPoint p;
1242 p.set(SkDoubleToScalar(x), 0); 1260 p.set(SkDoubleToScalar(x), 0);
1243 gfx::Canvas background_canvas(size(), canvas->image_scale(), false); 1261 if (ui::MaterialDesignController::IsModeMaterial()) {
1244 PaintInactiveTabBackground(&background_canvas); 1262 PaintInactiveTabBackground(canvas);
1245 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); 1263 gfx::ScopedCanvas scoped_canvas(canvas);
1246 canvas->DrawImageInt(background_image, 0, 0); 1264 const float scale = canvas->UndoDeviceScaleFactor();
1247 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); 1265 SkPath fill;
1248 DrawHighlight(&hover_canvas, p, SkFloatToScalar(radius), alpha); 1266 GetFillPath(scale, &fill);
1249 gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage( 1267 canvas->ClipPath(fill, true);
1250 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); 1268 p.scale(SkFloatToScalar(scale));
1251 canvas->DrawImageInt(hover_image, 0, 0); 1269 DrawHighlight(canvas, p, SkFloatToScalar(radius * scale), alpha);
1270 } else {
1271 gfx::Canvas background_canvas(size(), canvas->image_scale(), false);
1272 PaintInactiveTabBackground(&background_canvas);
1273 gfx::ImageSkia background_image(background_canvas.ExtractImageRep());
1274 canvas->DrawImageInt(background_image, 0, 0);
1275 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false);
1276 DrawHighlight(&hover_canvas, p, SkFloatToScalar(radius), alpha);
1277 gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage(
1278 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image);
1279 canvas->DrawImageInt(hover_image, 0, 0);
1280 }
1252 } 1281 }
1253 1282
1254 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { 1283 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) {
1255 bool has_custom_image; 1284 bool has_custom_image;
1256 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); 1285 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image);
1257 // Explicitly map the id so we cache correctly. 1286 // Explicitly map the id so we cache correctly.
1258 const chrome::HostDesktopType host_desktop_type = GetHostDesktopType(this); 1287 const chrome::HostDesktopType host_desktop_type = GetHostDesktopType(this);
1259 fill_id = chrome::MapThemeImage(host_desktop_type, fill_id); 1288 fill_id = chrome::MapThemeImage(host_desktop_type, fill_id);
1260 1289
1261 // If the theme is providing a custom background image, then its top edge 1290 // If the theme is providing a custom background image, then its top edge
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 // so that it feels partially transparent. These offsets represent the tab 1325 // so that it feels partially transparent. These offsets represent the tab
1297 // position within the frame background image. 1326 // position within the frame background image.
1298 const int x_offset = GetMirroredX() + background_offset_.x(); 1327 const int x_offset = GetMirroredX() + background_offset_.x();
1299 1328
1300 const SkScalar radius = SkFloatToScalar(width() / 3.f); 1329 const SkScalar radius = SkFloatToScalar(width() / 3.f);
1301 const bool draw_hover = 1330 const bool draw_hover =
1302 !is_active && hover_controller_.ShouldDraw() && radius > 0; 1331 !is_active && hover_controller_.ShouldDraw() && radius > 0;
1303 SkPoint hover_location(PointToSkPoint(hover_controller_.location())); 1332 SkPoint hover_location(PointToSkPoint(hover_controller_.location()));
1304 const SkAlpha hover_alpha = hover_controller_.GetAlpha(); 1333 const SkAlpha hover_alpha = hover_controller_.GetAlpha();
1305 1334
1306 if (draw_hover) { 1335 if (ui::MaterialDesignController::IsModeMaterial()) {
1307 // Draw everything to a temporary canvas so we can extract an image for use 1336 gfx::ScopedCanvas scoped_canvas(canvas);
1308 // in masking the hover glow. 1337 const float scale = canvas->UndoDeviceScaleFactor();
1309 gfx::Canvas background_canvas(size(), canvas->image_scale(), false);
1310 PaintTabFill(&background_canvas, fill_image, x_offset, y_offset, is_active);
1311 gfx::ImageSkia background_image(background_canvas.ExtractImageRep());
1312 canvas->DrawImageInt(background_image, 0, 0);
1313 1338
1314 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); 1339 // Draw the fill.
1315 DrawHighlight(&hover_canvas, hover_location, radius, hover_alpha); 1340 SkPath fill;
1316 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( 1341 GetFillPath(scale, &fill);
1317 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); 1342 SkPaint paint;
1318 canvas->DrawImageInt(result, 0, 0); 1343 paint.setAntiAlias(true);
1344 {
1345 gfx::ScopedCanvas clip_scoper(canvas);
1346 canvas->ClipPath(fill, true);
1347 if (has_custom_image) {
1348 gfx::ScopedCanvas scale_scoper(canvas);
1349 canvas->sk_canvas()->scale(scale, scale);
1350 canvas->TileImageInt(*fill_image, x_offset, y_offset, 0, 0, width(),
1351 height());
1352 } else {
1353 paint.setColor(
1354 is_active ? SkColorSetRGB(0xF2, 0xF2, 0xF2) : kInactiveTabColor);
1355 canvas->DrawRect(gfx::ScaleToEnclosingRect(GetLocalBounds(), scale),
1356 paint);
1357 }
1358 if (draw_hover) {
1359 hover_location.scale(SkFloatToScalar(scale));
1360 DrawHighlight(canvas, hover_location, radius * scale, hover_alpha);
1361 }
1362 }
1363
1364 // Draw the stroke.
1365 SkPath stroke;
1366 GetBorderPath(scale, false, &stroke);
1367 Op(stroke, fill, kDifference_SkPathOp, &stroke);
1368 if (!is_active) {
1369 // Clip out the bottom line; this will be drawn for us by
1370 // TabStrip::PaintChildren().
1371 canvas->sk_canvas()->clipRect(
1372 SkRect::MakeWH(width() * scale, height() * scale - 1));
1373 }
1374 paint.setARGB(0x40, 0x00, 0x00, 0x00);
1375 canvas->DrawPath(stroke, paint);
1319 } else { 1376 } else {
1320 PaintTabFill(canvas, fill_image, x_offset, y_offset, is_active); 1377 if (draw_hover) {
1378 // Draw everything to a temporary canvas so we can extract an image for
1379 // use in masking the hover glow.
1380 gfx::Canvas background_canvas(size(), canvas->image_scale(), false);
1381 PaintTabFill(&background_canvas, fill_image, x_offset, y_offset,
1382 is_active);
1383 gfx::ImageSkia background_image(background_canvas.ExtractImageRep());
1384 canvas->DrawImageInt(background_image, 0, 0);
1385
1386 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false);
1387 DrawHighlight(&hover_canvas, hover_location, radius, hover_alpha);
1388 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage(
1389 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image);
1390 canvas->DrawImageInt(result, 0, 0);
1391 } else {
1392 PaintTabFill(canvas, fill_image, x_offset, y_offset, is_active);
1393 }
1394
1395 // Now draw the stroke, highlights, and shadows around the tab edge.
1396 TabImages* stroke_images = is_active ? &active_images_ : &inactive_images_;
1397 canvas->DrawImageInt(*stroke_images->image_l, 0, 0);
1398 canvas->TileImageInt(
1399 *stroke_images->image_c, stroke_images->l_width, 0,
1400 width() - stroke_images->l_width - stroke_images->r_width, height());
1401 canvas->DrawImageInt(*stroke_images->image_r,
1402 width() - stroke_images->r_width, 0);
1321 } 1403 }
1322
1323 // Now draw the stroke, highlights, and shadows around the tab edge.
1324 TabImages* stroke_images = is_active ? &active_images_ : &inactive_images_;
1325 canvas->DrawImageInt(*stroke_images->image_l, 0, 0);
1326 canvas->TileImageInt(
1327 *stroke_images->image_c, stroke_images->l_width, 0,
1328 width() - stroke_images->l_width - stroke_images->r_width, height());
1329 canvas->DrawImageInt(*stroke_images->image_r,
1330 width() - stroke_images->r_width, 0);
1331 } 1404 }
1332 1405
1333 void Tab::PaintTabFill(gfx::Canvas* canvas, 1406 void Tab::PaintTabFill(gfx::Canvas* canvas,
1334 gfx::ImageSkia* fill_image, 1407 gfx::ImageSkia* fill_image,
1335 int x_offset, 1408 int x_offset,
1336 int y_offset, 1409 int y_offset,
1337 bool is_active) { 1410 bool is_active) {
1338 const gfx::Insets tab_insets(GetLayoutInsets(TAB)); 1411 const gfx::Insets tab_insets(GetLayoutInsets(TAB));
1339 // If this isn't the foreground tab, don't draw over the toolbar, but do 1412 // If this isn't the foreground tab, don't draw over the toolbar, but do
1340 // include the 1 px divider stroke at the bottom. 1413 // include the 1 px divider stroke at the bottom.
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 if (bounds.IsEmpty()) 1609 if (bounds.IsEmpty())
1537 return; 1610 return;
1538 1611
1539 // Extends the area to the bottom when the crash animation is in progress. 1612 // Extends the area to the bottom when the crash animation is in progress.
1540 if (crash_icon_animation_) 1613 if (crash_icon_animation_)
1541 bounds.set_height(height() - bounds.y()); 1614 bounds.set_height(height() - bounds.y());
1542 bounds.set_x(GetMirroredXForRect(bounds)); 1615 bounds.set_x(GetMirroredXForRect(bounds));
1543 SchedulePaintInRect(bounds); 1616 SchedulePaintInRect(bounds);
1544 } 1617 }
1545 1618
1619 void Tab::GetFillPath(float scale, SkPath* fill) const {
1620 const float right = width() * scale;
1621 const float bottom = height() * scale;
1622
1623 fill->moveTo(right - 1, bottom);
1624 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, -2 * scale,
1625 -1.5 * scale);
1626 fill->lineTo(right - 1 - 13.5 * scale, 2.5 * scale);
1627 // Prevent overdraw in the center near minimum width (only happens if
1628 // scale < 2). We could instead avoid this by increasing the tab inset
1629 // values, but that would shift all the content inward as well, unless we
1630 // then overlapped the content on the endcaps, by which point we'd have a
1631 // huge mess.
1632 const float total_endcap_width = 31 * scale + 2;
1633 const float overlap = total_endcap_width - right;
1634 const float offset = (overlap > 0) ? (overlap / 2) : 0;
1635 fill->rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale + offset,
1636 -1.5 * scale, -2 * scale + offset, -1.5 * scale);
1637 if (overlap < 0)
1638 fill->lineTo(1 + 15.5 * scale, scale);
1639 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale - offset, 0.5 * scale,
1640 -2 * scale - offset, 1.5 * scale);
1641 fill->lineTo(1 + 2 * scale, bottom - 1.5 * scale);
1642 fill->rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale, -2 * scale,
1643 1.5 * scale);
1644 fill->close();
1645 }
1646
1647 void Tab::GetBorderPath(float scale, bool extend_to_top, SkPath* path) const {
1648 const float top = scale - 1;
1649 const float right = width() * scale;
1650 const float bottom = height() * scale;
1651
1652 path->moveTo(0, bottom);
1653 path->rLineTo(0, -1);
1654 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale,
1655 -1.5 * scale);
1656 path->lineTo(13.5 * scale, top + 1.5 * scale);
1657 if (extend_to_top) {
1658 // Create the vertical extension by extending the side diagonals until they
1659 // reach the top of the bounds.
1660 const float dy = 2.5 * scale - 1;
1661 const float dx = 11.5 / 25 * dy;
1662 path->rLineTo(dx, -dy);
1663 path->lineTo(right - 13.5 * scale - dx, 0);
1664 path->rLineTo(dx, dy);
1665 } else {
1666 path->rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale, 2 * scale,
1667 -1.5 * scale);
1668 path->lineTo(right - 15.5 * scale, top);
1669 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale,
1670 1.5 * scale);
1671 }
1672 path->lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale);
1673 path->rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale,
1674 1.5 * scale);
1675 path->rLineTo(0, 1);
1676 path->close();
1677 }
1678
1546 gfx::Rect Tab::GetImmersiveBarRect() const { 1679 gfx::Rect Tab::GetImmersiveBarRect() const {
1547 // The main bar is as wide as the normal tab's horizontal top line. 1680 // The main bar is as wide as the normal tab's horizontal top line.
1548 // This top line of the tab extends a few pixels left and right of the 1681 // This top line of the tab extends a few pixels left and right of the
1549 // center image due to pixels in the rounded corner images. 1682 // center image due to pixels in the rounded corner images.
1550 const int kBarPadding = 1; 1683 const int kBarPadding = 1;
1551 int main_bar_left = active_images_.l_width - kBarPadding; 1684 int main_bar_left = active_images_.l_width - kBarPadding;
1552 int main_bar_right = width() - active_images_.r_width + kBarPadding; 1685 int main_bar_right = width() - active_images_.r_width + kBarPadding;
1553 return gfx::Rect( 1686 return gfx::Rect(
1554 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); 1687 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight);
1555 } 1688 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 const gfx::ImageSkia& image) { 1746 const gfx::ImageSkia& image) {
1614 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); 1747 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE);
1615 ImageCacheEntry entry; 1748 ImageCacheEntry entry;
1616 entry.resource_id = resource_id; 1749 entry.resource_id = resource_id;
1617 entry.scale_factor = scale_factor; 1750 entry.scale_factor = scale_factor;
1618 entry.image = image; 1751 entry.image = image;
1619 image_cache_->push_front(entry); 1752 image_cache_->push_front(entry);
1620 if (image_cache_->size() > kMaxImageCacheSize) 1753 if (image_cache_->size() > kMaxImageCacheSize)
1621 image_cache_->pop_back(); 1754 image_cache_->pop_back();
1622 } 1755 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/tab.h ('k') | chrome/browser/ui/views/tabs/tab_strip.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698