Chromium Code Reviews| 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 |