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" |
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/tab_contents/core_tab_helper.h" | 15 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" |
16 #include "chrome/browser/ui/tabs/tab_utils.h" | 16 #include "chrome/browser/ui/tabs/tab_utils.h" |
17 #include "chrome/browser/ui/view_ids.h" | 17 #include "chrome/browser/ui/view_ids.h" |
18 #include "chrome/browser/ui/views/layout_constants.h" | 18 #include "chrome/browser/ui/views/layout_constants.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 Loading... | |
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 Loading... | |
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 Loading... | |
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 { | |
Peter Kasting
2015/12/09 01:20:30
This arm is copied verbatim from before, just inde
| |
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 Loading... | |
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 { | |
Peter Kasting
2015/12/09 01:20:30
Same here.
| |
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 Loading... | |
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 { |
Peter Kasting
2015/12/09 01:20:30
Same here.
| |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |