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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 #include "ui/base/material_design/material_design_controller.h" | 37 #include "ui/base/material_design/material_design_controller.h" |
| 38 #include "ui/base/models/list_selection_model.h" | 38 #include "ui/base/models/list_selection_model.h" |
| 39 #include "ui/base/resource/resource_bundle.h" | 39 #include "ui/base/resource/resource_bundle.h" |
| 40 #include "ui/base/theme_provider.h" | 40 #include "ui/base/theme_provider.h" |
| 41 #include "ui/gfx/animation/animation_container.h" | 41 #include "ui/gfx/animation/animation_container.h" |
| 42 #include "ui/gfx/animation/throb_animation.h" | 42 #include "ui/gfx/animation/throb_animation.h" |
| 43 #include "ui/gfx/canvas.h" | 43 #include "ui/gfx/canvas.h" |
| 44 #include "ui/gfx/color_analysis.h" | 44 #include "ui/gfx/color_analysis.h" |
| 45 #include "ui/gfx/favicon_size.h" | 45 #include "ui/gfx/favicon_size.h" |
| 46 #include "ui/gfx/geometry/rect_conversions.h" | 46 #include "ui/gfx/geometry/rect_conversions.h" |
| 47 #include "ui/gfx/image/canvas_image_source.h" | |
| 47 #include "ui/gfx/image/image_skia_operations.h" | 48 #include "ui/gfx/image/image_skia_operations.h" |
| 48 #include "ui/gfx/paint_vector_icon.h" | 49 #include "ui/gfx/paint_vector_icon.h" |
| 49 #include "ui/gfx/path.h" | 50 #include "ui/gfx/path.h" |
| 50 #include "ui/gfx/scoped_canvas.h" | 51 #include "ui/gfx/scoped_canvas.h" |
| 51 #include "ui/gfx/skia_util.h" | 52 #include "ui/gfx/skia_util.h" |
| 52 #include "ui/gfx/vector_icons_public.h" | 53 #include "ui/gfx/vector_icons_public.h" |
| 53 #include "ui/resources/grit/ui_resources.h" | 54 #include "ui/resources/grit/ui_resources.h" |
| 54 #include "ui/views/border.h" | 55 #include "ui/views/border.h" |
| 55 #include "ui/views/controls/button/image_button.h" | 56 #include "ui/views/controls/button/image_button.h" |
| 56 #include "ui/views/controls/label.h" | 57 #include "ui/views/controls/label.h" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 // The minimum opacity (out of 1) when a tab (either active or inactive) is | 111 // The minimum opacity (out of 1) when a tab (either active or inactive) is |
| 111 // throbbing in the immersive mode light strip. | 112 // throbbing in the immersive mode light strip. |
| 112 const double kImmersiveTabMinThrobOpacity = 0.66; | 113 const double kImmersiveTabMinThrobOpacity = 0.66; |
| 113 | 114 |
| 114 // Number of steps in the immersive mode loading animation. | 115 // Number of steps in the immersive mode loading animation. |
| 115 const int kImmersiveLoadingStepCount = 32; | 116 const int kImmersiveLoadingStepCount = 32; |
| 116 | 117 |
| 117 const char kTabCloseButtonName[] = "TabCloseButton"; | 118 const char kTabCloseButtonName[] = "TabCloseButton"; |
| 118 | 119 |
| 119 //////////////////////////////////////////////////////////////////////////////// | 120 //////////////////////////////////////////////////////////////////////////////// |
| 121 // PaintBackgroundParams | |
| 122 | |
| 123 struct PaintBackgroundParams { | |
| 124 views::GlowHoverController* hc; | |
|
oshima
2016/07/26 21:11:26
I was hoping that we can resolve this w/o having a
Greg Levin
2016/07/28 15:48:04
As per offline discussion, made hc a separate arg
| |
| 125 bool is_active; | |
| 126 gfx::ImageSkia* fill_image; | |
|
Greg Levin
2016/07/15 22:24:48
Note sure if this should be a pointer, but was hav
oshima
2016/07/26 21:11:26
You should be able to just use gfx::ImageSkia inst
Greg Levin
2016/07/28 15:48:04
Done. (Got the const issues worked out.)
| |
| 127 bool has_custom_image; | |
|
oshima
2016/07/26 21:11:26
can you use if the fill_image is null?
Greg Levin
2016/07/28 15:48:04
I don't think so. If I'm reading the code right,
oshima
2016/07/28 16:56:06
can't you leave ImageSkia empty (isNull() return t
Greg Levin
2016/07/28 20:03:54
I don't think so. fill_id, which is used to get f
| |
| 128 int x_offset; | |
| 129 int y_offset; | |
|
oshima
2016/07/26 21:11:26
gfx::Point offset;
Greg Levin
2016/07/28 15:48:04
Done.
| |
| 130 gfx::Size size; | |
| 131 SkColor stroke_color; | |
| 132 SkColor toolbar_color; | |
| 133 SkColor background_color; | |
| 134 }; | |
| 135 | |
| 136 void PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, | |
| 137 const PaintBackgroundParams& params); | |
| 138 | |
| 139 //////////////////////////////////////////////////////////////////////////////// | |
| 140 // TabImageSource | |
| 141 // | |
| 142 // This subclass of CanvasImageSource allows the inactive tab image to be cached | |
| 143 // once and rendered correctly for all scale factors. | |
| 144 class TabImageSource : public gfx::CanvasImageSource { | |
| 145 public: | |
| 146 TabImageSource(Tab* tab, int fill_id, int y_offset); | |
| 147 ~TabImageSource() override {} | |
| 148 | |
| 149 // gfx::CanvasImageSource override. | |
| 150 void Draw(gfx::Canvas* canvas) override; | |
| 151 | |
| 152 private: | |
| 153 PaintBackgroundParams params_; | |
| 154 | |
| 155 DISALLOW_COPY_AND_ASSIGN(TabImageSource); | |
| 156 }; | |
| 157 | |
| 158 TabImageSource::TabImageSource(Tab* tab, int fill_id, int y_offset) | |
| 159 : gfx::CanvasImageSource(tab->size(), true) { | |
| 160 params_.hc = nullptr; | |
| 161 params_.is_active = false; | |
| 162 params_.fill_image = tab->GetThemeProvider()->GetImageSkiaNamed(fill_id); | |
| 163 params_.has_custom_image = false; | |
| 164 params_.x_offset = 0; | |
| 165 params_.y_offset = y_offset; | |
| 166 params_.size = tab->size(); | |
| 167 params_.stroke_color = tab->controller()->GetToolbarTopSeparatorColor(); | |
| 168 params_.toolbar_color = | |
| 169 tab->GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR); | |
| 170 params_.background_color = | |
| 171 tab->GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB); | |
| 172 } | |
| 173 | |
| 174 void TabImageSource::Draw(gfx::Canvas* canvas) { | |
| 175 PaintTabBackgroundUsingFillId(canvas, params_); | |
| 176 } | |
| 177 | |
| 178 //////////////////////////////////////////////////////////////////////////////// | |
| 120 // ImageCacheEntryMetadata | 179 // ImageCacheEntryMetadata |
| 121 // | 180 // |
| 122 // All metadata necessary to uniquely identify a cached image. | 181 // All metadata necessary to uniquely identify a cached image. |
| 123 struct ImageCacheEntryMetadata { | 182 struct ImageCacheEntryMetadata { |
| 124 ImageCacheEntryMetadata(int resource_id, | 183 ImageCacheEntryMetadata(int resource_id, |
| 125 SkColor fill_color, | 184 SkColor fill_color, |
| 126 SkColor stroke_color, | 185 SkColor stroke_color, |
| 127 ui::ScaleFactor scale_factor, | |
| 128 const gfx::Size& size); | 186 const gfx::Size& size); |
| 129 | 187 |
| 130 ~ImageCacheEntryMetadata(); | 188 ~ImageCacheEntryMetadata(); |
| 131 | 189 |
| 132 bool operator==(const ImageCacheEntryMetadata& rhs) const; | 190 bool operator==(const ImageCacheEntryMetadata& rhs) const; |
| 133 | 191 |
| 134 int resource_id; // Only needed by pre-MD | 192 int resource_id; // Only needed by pre-MD |
| 135 SkColor fill_color; // Both colors only needed by MD | 193 SkColor fill_color; // Both colors only needed by MD |
| 136 SkColor stroke_color; | 194 SkColor stroke_color; |
| 137 ui::ScaleFactor scale_factor; | |
| 138 gfx::Size size; | 195 gfx::Size size; |
| 139 }; | 196 }; |
| 140 | 197 |
| 141 ImageCacheEntryMetadata::ImageCacheEntryMetadata(int resource_id, | 198 ImageCacheEntryMetadata::ImageCacheEntryMetadata(int resource_id, |
| 142 SkColor fill_color, | 199 SkColor fill_color, |
| 143 SkColor stroke_color, | 200 SkColor stroke_color, |
| 144 ui::ScaleFactor scale_factor, | |
| 145 const gfx::Size& size) | 201 const gfx::Size& size) |
| 146 : resource_id(resource_id), | 202 : resource_id(resource_id), |
| 147 fill_color(fill_color), | 203 fill_color(fill_color), |
| 148 stroke_color(stroke_color), | 204 stroke_color(stroke_color), |
| 149 scale_factor(scale_factor), | |
| 150 size(size) { | 205 size(size) { |
| 151 DCHECK_NE(ui::SCALE_FACTOR_NONE, scale_factor); | |
| 152 | |
| 153 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones | 206 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones |
| 154 // so they don't cause incorrect cache misses. | 207 // so they don't cause incorrect cache misses. |
| 155 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted. | 208 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted. |
| 156 if (ui::MaterialDesignController::IsModeMaterial()) | 209 if (ui::MaterialDesignController::IsModeMaterial()) |
| 157 resource_id = 0; | 210 resource_id = 0; |
| 158 else | 211 else |
| 159 fill_color = stroke_color = SK_ColorTRANSPARENT; | 212 fill_color = stroke_color = SK_ColorTRANSPARENT; |
| 160 } | 213 } |
| 161 | 214 |
| 162 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {} | 215 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {} |
| 163 | 216 |
| 164 bool ImageCacheEntryMetadata::operator==( | 217 bool ImageCacheEntryMetadata::operator==( |
| 165 const ImageCacheEntryMetadata& rhs) const { | 218 const ImageCacheEntryMetadata& rhs) const { |
| 166 return resource_id == rhs.resource_id && fill_color == rhs.fill_color && | 219 return resource_id == rhs.resource_id && fill_color == rhs.fill_color && |
| 167 stroke_color == rhs.stroke_color && scale_factor == rhs.scale_factor && | 220 stroke_color == rhs.stroke_color && size == rhs.size; |
| 168 size == rhs.size; | |
| 169 } | 221 } |
| 170 | 222 |
| 171 //////////////////////////////////////////////////////////////////////////////// | 223 //////////////////////////////////////////////////////////////////////////////// |
| 172 // ImageCacheEntry and cache management | 224 // ImageCacheEntry and cache management |
| 173 // | 225 // |
| 174 // A cached image and the metadata used to generate it. | 226 // A cached image and the metadata used to generate it. |
| 175 struct ImageCacheEntry { | 227 struct ImageCacheEntry { |
| 176 ImageCacheEntry(const ImageCacheEntryMetadata& metadata, | 228 ImageCacheEntry(const ImageCacheEntryMetadata& metadata, |
| 177 const gfx::ImageSkia& image); | 229 Tab* tab, |
| 230 int fill_id, | |
| 231 int y_offset); | |
| 178 ~ImageCacheEntry(); | 232 ~ImageCacheEntry(); |
| 179 | 233 |
| 180 ImageCacheEntryMetadata metadata; | 234 ImageCacheEntryMetadata metadata; |
| 181 gfx::ImageSkia image; | 235 gfx::ImageSkia image; |
| 182 }; | 236 }; |
| 183 | 237 |
| 184 ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata, | 238 ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata, |
| 185 const gfx::ImageSkia& image) | 239 Tab* tab, |
| 186 : metadata(metadata), image(image) {} | 240 int fill_id, |
| 241 int y_offset) | |
| 242 : metadata(metadata), | |
| 243 image(new TabImageSource(tab, fill_id, y_offset), tab->size()) {} | |
| 187 | 244 |
| 188 ImageCacheEntry::~ImageCacheEntry() {} | 245 ImageCacheEntry::~ImageCacheEntry() {} |
| 189 | 246 |
| 190 typedef std::list<ImageCacheEntry> ImageCache; | 247 typedef std::list<ImageCacheEntry> ImageCache; |
| 191 | 248 |
| 192 // As the majority of the tabs are inactive, and painting tabs is slowish, | 249 // As the majority of the tabs are inactive, and painting tabs is slowish, |
| 193 // we cache a handful of the inactive tab backgrounds here. | 250 // we cache a handful of the inactive tab backgrounds here. |
| 194 static ImageCache* g_image_cache = nullptr; | 251 static ImageCache* g_image_cache = nullptr; |
| 195 | 252 |
| 196 struct TabImages { | 253 struct TabImages { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 canvas->sk_canvas()->drawRect( | 323 canvas->sk_canvas()->drawRect( |
| 267 SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), | 324 SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), |
| 268 paint); | 325 paint); |
| 269 } | 326 } |
| 270 | 327 |
| 271 // Returns whether the favicon for the given URL should be colored according to | 328 // Returns whether the favicon for the given URL should be colored according to |
| 272 // the browser theme. | 329 // the browser theme. |
| 273 bool ShouldThemifyFaviconForUrl(const GURL& url) { | 330 bool ShouldThemifyFaviconForUrl(const GURL& url) { |
| 274 return url.SchemeIs(content::kChromeUIScheme) && | 331 return url.SchemeIs(content::kChromeUIScheme) && |
| 275 url.host() != chrome::kChromeUIHelpHost && | 332 url.host() != chrome::kChromeUIHelpHost && |
| 276 url.host() != chrome::kChromeUIUberHost && | 333 url.host() != chrome::kChromeUIUberHost; |
| 277 url.host() != chrome::kChromeUIAppLauncherPageHost; | |
|
Greg Levin
2016/07/15 22:24:48
Removed by merge
| |
| 278 } | 334 } |
| 279 | 335 |
| 280 // Computes a path corresponding to the tab's content region inside the outer | 336 // Computes a path corresponding to the tab's content region inside the outer |
| 281 // stroke. | 337 // stroke. |
| 282 void GetFillPath(float scale, const gfx::Size& size, SkPath* fill) { | 338 void GetFillPath(float scale, const gfx::Size& size, SkPath* fill) { |
| 283 const float right = size.width() * scale; | 339 const float right = size.width() * scale; |
| 284 // The bottom of the tab needs to be pixel-aligned or else when we call | 340 // The bottom of the tab needs to be pixel-aligned or else when we call |
| 285 // ClipPath with anti-aliasing enabled it can cause artifacts. | 341 // ClipPath with anti-aliasing enabled it can cause artifacts. |
| 286 const float bottom = std::ceil(size.height() * scale); | 342 const float bottom = std::ceil(size.height() * scale); |
| 287 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); | 343 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 | 439 |
| 384 // Draw center. Instead of masking out the top portion we simply skip over it | 440 // Draw center. Instead of masking out the top portion we simply skip over it |
| 385 // by incrementing by the top padding, since it's a simple rectangle. | 441 // by incrementing by the top padding, since it's a simple rectangle. |
| 386 canvas->TileImageInt( | 442 canvas->TileImageInt( |
| 387 *fill_image, x_offset + g_mask_images.l_width, | 443 *fill_image, x_offset + g_mask_images.l_width, |
| 388 y_offset + tab_insets.top(), g_mask_images.l_width, tab_insets.top(), | 444 y_offset + tab_insets.top(), g_mask_images.l_width, tab_insets.top(), |
| 389 size.width() - g_mask_images.l_width - g_mask_images.r_width, | 445 size.width() - g_mask_images.l_width - g_mask_images.r_width, |
| 390 size.height() - tab_insets.top() - toolbar_overlap); | 446 size.height() - tab_insets.top() - toolbar_overlap); |
| 391 } | 447 } |
| 392 | 448 |
| 449 // For use by Tab and TabImageSource | |
| 450 void PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, | |
| 451 const PaintBackgroundParams& params) { | |
| 452 const SkScalar kMinHoverRadius = 16; | |
| 453 const SkScalar radius = | |
| 454 std::max(SkFloatToScalar(params.size.width() / 4.f), kMinHoverRadius); | |
| 455 const bool draw_hover = !params.is_active && params.hc; | |
| 456 SkPoint hover_location( | |
| 457 PointToSkPoint(draw_hover ? params.hc->location() : gfx::Point())); | |
| 458 const SkColor hover_color = SkColorSetA( | |
| 459 params.toolbar_color, draw_hover ? params.hc->GetAlpha() : 255); | |
| 460 | |
| 461 if (ui::MaterialDesignController::IsModeMaterial()) { | |
| 462 gfx::ScopedCanvas scoped_canvas(canvas); | |
| 463 const float scale = canvas->UndoDeviceScaleFactor(); | |
| 464 | |
| 465 // Draw the fill. | |
| 466 SkPath fill; | |
| 467 GetFillPath(scale, params.size, &fill); | |
| 468 SkPaint paint; | |
| 469 paint.setAntiAlias(true); | |
| 470 { | |
| 471 gfx::ScopedCanvas clip_scoper(canvas); | |
| 472 canvas->ClipPath(fill, true); | |
| 473 if (params.has_custom_image) { | |
| 474 gfx::ScopedCanvas scale_scoper(canvas); | |
| 475 canvas->sk_canvas()->scale(scale, scale); | |
| 476 canvas->TileImageInt(*params.fill_image, params.x_offset, | |
| 477 params.y_offset, 0, 0, params.size.width(), | |
| 478 params.size.height()); | |
| 479 } else { | |
| 480 paint.setColor(params.is_active ? params.toolbar_color | |
| 481 : params.background_color); | |
| 482 canvas->DrawRect( | |
| 483 gfx::ScaleToEnclosingRect(gfx::Rect(params.size), scale), paint); | |
| 484 } | |
| 485 if (draw_hover) { | |
| 486 hover_location.scale(SkFloatToScalar(scale)); | |
| 487 DrawHighlight(canvas, hover_location, radius * scale, hover_color); | |
| 488 } | |
| 489 } | |
| 490 | |
| 491 // Draw the stroke. | |
| 492 SkPath stroke; | |
| 493 GetBorderPath(scale, params.size, false, &stroke); | |
| 494 Op(stroke, fill, kDifference_SkPathOp, &stroke); | |
| 495 if (!params.is_active) { | |
| 496 // Clip out the bottom line; this will be drawn for us by | |
| 497 // TabStrip::PaintChildren(). | |
| 498 canvas->sk_canvas()->clipRect(SkRect::MakeWH( | |
| 499 params.size.width() * scale, params.size.height() * scale - 1)); | |
| 500 } | |
| 501 paint.setColor(params.stroke_color); | |
| 502 canvas->DrawPath(stroke, paint); | |
| 503 } else { | |
| 504 if (draw_hover) { | |
| 505 // Draw everything to a temporary canvas so we can extract an image for | |
| 506 // use in masking the hover glow. | |
| 507 gfx::Canvas background_canvas(params.size, canvas->image_scale(), false); | |
| 508 PaintTabFill(&background_canvas, params.fill_image, params.x_offset, | |
| 509 params.y_offset, params.size, params.is_active); | |
| 510 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | |
| 511 canvas->DrawImageInt(background_image, 0, 0); | |
| 512 | |
| 513 gfx::Canvas hover_canvas(params.size, canvas->image_scale(), false); | |
| 514 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); | |
| 515 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( | |
| 516 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | |
| 517 canvas->DrawImageInt(result, 0, 0); | |
| 518 } else { | |
| 519 PaintTabFill(canvas, params.fill_image, params.x_offset, params.y_offset, | |
| 520 params.size, params.is_active); | |
| 521 } | |
| 522 | |
| 523 // Now draw the stroke, highlights, and shadows around the tab edge. | |
| 524 TabImages* stroke_images = | |
| 525 params.is_active ? &g_active_images : &g_inactive_images; | |
| 526 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); | |
| 527 canvas->TileImageInt( | |
| 528 *stroke_images->image_c, stroke_images->l_width, 0, | |
| 529 params.size.width() - stroke_images->l_width - stroke_images->r_width, | |
| 530 params.size.height()); | |
| 531 canvas->DrawImageInt(*stroke_images->image_r, | |
| 532 params.size.width() - stroke_images->r_width, 0); | |
| 533 } | |
| 534 } | |
| 535 | |
| 393 } // namespace | 536 } // namespace |
| 394 | 537 |
| 395 //////////////////////////////////////////////////////////////////////////////// | 538 //////////////////////////////////////////////////////////////////////////////// |
| 396 // FaviconCrashAnimation | 539 // FaviconCrashAnimation |
| 397 // | 540 // |
| 398 // A custom animation subclass to manage the favicon crash animation. | 541 // A custom animation subclass to manage the favicon crash animation. |
| 399 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, | 542 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, |
| 400 public gfx::AnimationDelegate { | 543 public gfx::AnimationDelegate { |
| 401 public: | 544 public: |
| 402 explicit FaviconCrashAnimation(Tab* target) | 545 explicit FaviconCrashAnimation(Tab* target) |
| (...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1447 // We only cache the image when it's the default image and we're not hovered, | 1590 // We only cache the image when it's the default image and we're not hovered, |
| 1448 // to avoid caching a background image that isn't the same for all tabs. | 1591 // to avoid caching a background image that isn't the same for all tabs. |
| 1449 if (has_custom_image || hover_controller_.ShouldDraw()) { | 1592 if (has_custom_image || hover_controller_.ShouldDraw()) { |
| 1450 PaintTabBackgroundUsingFillId(canvas, false, fill_id, has_custom_image, | 1593 PaintTabBackgroundUsingFillId(canvas, false, fill_id, has_custom_image, |
| 1451 y_offset); | 1594 y_offset); |
| 1452 return; | 1595 return; |
| 1453 } | 1596 } |
| 1454 | 1597 |
| 1455 const ImageCacheEntryMetadata metadata( | 1598 const ImageCacheEntryMetadata metadata( |
| 1456 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), | 1599 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), |
| 1457 controller_->GetToolbarTopSeparatorColor(), | 1600 controller_->GetToolbarTopSeparatorColor(), size()); |
| 1458 ui::GetSupportedScaleFactor(canvas->image_scale()), size()); | |
| 1459 auto it = std::find_if( | 1601 auto it = std::find_if( |
| 1460 g_image_cache->begin(), g_image_cache->end(), | 1602 g_image_cache->begin(), g_image_cache->end(), |
| 1461 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); | 1603 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); |
| 1462 if (it == g_image_cache->end()) { | 1604 if (it == g_image_cache->end()) { |
| 1463 gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false); | 1605 g_image_cache->emplace_front(metadata, this, fill_id, y_offset); |
| 1464 PaintTabBackgroundUsingFillId(&tmp_canvas, false, fill_id, false, y_offset); | |
| 1465 g_image_cache->emplace_front(metadata, | |
| 1466 gfx::ImageSkia(tmp_canvas.ExtractImageRep())); | |
| 1467 if (g_image_cache->size() > kMaxImageCacheSize) | 1606 if (g_image_cache->size() > kMaxImageCacheSize) |
| 1468 g_image_cache->pop_back(); | 1607 g_image_cache->pop_back(); |
| 1469 it = g_image_cache->begin(); | 1608 it = g_image_cache->begin(); |
| 1470 } | 1609 } |
| 1471 canvas->DrawImageInt(it->image, 0, 0); | 1610 canvas->DrawImageInt(it->image, 0, 0); |
| 1472 } | 1611 } |
| 1473 | 1612 |
| 1474 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, | 1613 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, |
| 1475 bool is_active, | 1614 bool is_active, |
| 1476 int fill_id, | 1615 int fill_id, |
| 1477 bool has_custom_image, | 1616 bool has_custom_image, |
| 1478 int y_offset) { | 1617 int y_offset) { |
| 1479 const ui::ThemeProvider* tp = GetThemeProvider(); | 1618 PaintBackgroundParams params; |
| 1480 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); | 1619 params.hc = hover_controller_.ShouldDraw() ? &hover_controller_ : nullptr; |
| 1481 gfx::ImageSkia* fill_image = tp->GetImageSkiaNamed(fill_id); | 1620 params.is_active = is_active; |
| 1621 params.fill_image = GetThemeProvider()->GetImageSkiaNamed(fill_id); | |
| 1622 params.has_custom_image = has_custom_image; | |
| 1482 // The tab image needs to be lined up with the background image | 1623 // The tab image needs to be lined up with the background image |
| 1483 // so that it feels partially transparent. These offsets represent the tab | 1624 // so that it feels partially transparent. These offsets represent the tab |
| 1484 // position within the frame background image. | 1625 // position within the frame background image. |
| 1485 const int x_offset = GetMirroredX() + background_offset_.x(); | 1626 params.x_offset = GetMirroredX() + background_offset_.x(); |
| 1627 params.y_offset = y_offset; | |
| 1628 params.size = size(); | |
| 1629 params.stroke_color = controller_->GetToolbarTopSeparatorColor(); | |
| 1630 params.toolbar_color = | |
| 1631 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR); | |
| 1632 params.background_color = | |
| 1633 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB); | |
| 1486 | 1634 |
| 1487 const SkScalar kMinHoverRadius = 16; | 1635 ::PaintTabBackgroundUsingFillId(canvas, params); |
| 1488 const SkScalar radius = | |
| 1489 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius); | |
| 1490 const bool draw_hover = !is_active && hover_controller_.ShouldDraw(); | |
| 1491 SkPoint hover_location(PointToSkPoint(hover_controller_.location())); | |
| 1492 const SkColor hover_color = | |
| 1493 SkColorSetA(toolbar_color, hover_controller_.GetAlpha()); | |
| 1494 | |
| 1495 if (ui::MaterialDesignController::IsModeMaterial()) { | |
| 1496 gfx::ScopedCanvas scoped_canvas(canvas); | |
| 1497 const float scale = canvas->UndoDeviceScaleFactor(); | |
| 1498 | |
| 1499 // Draw the fill. | |
| 1500 SkPath fill; | |
| 1501 GetFillPath(scale, size(), &fill); | |
| 1502 SkPaint paint; | |
| 1503 paint.setAntiAlias(true); | |
| 1504 { | |
| 1505 gfx::ScopedCanvas clip_scoper(canvas); | |
| 1506 canvas->ClipPath(fill, true); | |
| 1507 if (has_custom_image) { | |
| 1508 gfx::ScopedCanvas scale_scoper(canvas); | |
| 1509 canvas->sk_canvas()->scale(scale, scale); | |
| 1510 canvas->TileImageInt(*fill_image, x_offset, y_offset, 0, 0, width(), | |
| 1511 height()); | |
| 1512 } else { | |
| 1513 paint.setColor( | |
| 1514 is_active ? toolbar_color | |
| 1515 : tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); | |
| 1516 canvas->DrawRect(gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), | |
| 1517 paint); | |
| 1518 } | |
| 1519 if (draw_hover) { | |
| 1520 hover_location.scale(SkFloatToScalar(scale)); | |
| 1521 DrawHighlight(canvas, hover_location, radius * scale, hover_color); | |
| 1522 } | |
| 1523 } | |
| 1524 | |
| 1525 // Draw the stroke. | |
| 1526 SkPath stroke; | |
| 1527 GetBorderPath(scale, size(), false, &stroke); | |
| 1528 Op(stroke, fill, kDifference_SkPathOp, &stroke); | |
| 1529 if (!is_active) { | |
| 1530 // Clip out the bottom line; this will be drawn for us by | |
| 1531 // TabStrip::PaintChildren(). | |
| 1532 canvas->sk_canvas()->clipRect( | |
| 1533 SkRect::MakeWH(width() * scale, height() * scale - 1)); | |
| 1534 } | |
| 1535 paint.setColor(controller_->GetToolbarTopSeparatorColor()); | |
| 1536 canvas->DrawPath(stroke, paint); | |
| 1537 } else { | |
| 1538 if (draw_hover) { | |
| 1539 // Draw everything to a temporary canvas so we can extract an image for | |
| 1540 // use in masking the hover glow. | |
| 1541 gfx::Canvas background_canvas(size(), canvas->image_scale(), false); | |
| 1542 PaintTabFill(&background_canvas, fill_image, x_offset, y_offset, size(), | |
| 1543 is_active); | |
| 1544 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | |
| 1545 canvas->DrawImageInt(background_image, 0, 0); | |
| 1546 | |
| 1547 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); | |
| 1548 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); | |
| 1549 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( | |
| 1550 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | |
| 1551 canvas->DrawImageInt(result, 0, 0); | |
| 1552 } else { | |
| 1553 PaintTabFill(canvas, fill_image, x_offset, y_offset, size(), is_active); | |
| 1554 } | |
| 1555 | |
| 1556 // Now draw the stroke, highlights, and shadows around the tab edge. | |
| 1557 TabImages* stroke_images = | |
| 1558 is_active ? &g_active_images : &g_inactive_images; | |
| 1559 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); | |
| 1560 canvas->TileImageInt( | |
| 1561 *stroke_images->image_c, stroke_images->l_width, 0, | |
| 1562 width() - stroke_images->l_width - stroke_images->r_width, height()); | |
| 1563 canvas->DrawImageInt(*stroke_images->image_r, | |
| 1564 width() - stroke_images->r_width, 0); | |
| 1565 } | |
| 1566 } | 1636 } |
| 1567 | 1637 |
| 1568 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( | 1638 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( |
| 1569 gfx::Canvas* canvas, | 1639 gfx::Canvas* canvas, |
| 1570 const gfx::Rect& favicon_draw_bounds) { | 1640 const gfx::Rect& favicon_draw_bounds) { |
| 1571 // The pinned tab title changed indicator consists of two parts: | 1641 // The pinned tab title changed indicator consists of two parts: |
| 1572 // . a clear (totally transparent) part over the bottom right (or left in rtl) | 1642 // . a clear (totally transparent) part over the bottom right (or left in rtl) |
| 1573 // of the favicon. This is done by drawing the favicon to a canvas, then | 1643 // of the favicon. This is done by drawing the favicon to a canvas, then |
| 1574 // drawing the clear part on top of the favicon. | 1644 // drawing the clear part on top of the favicon. |
| 1575 // . a circle in the bottom right (or left in rtl) of the favicon. | 1645 // . a circle in the bottom right (or left in rtl) of the favicon. |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1804 gfx::Rect Tab::GetImmersiveBarRect() const { | 1874 gfx::Rect Tab::GetImmersiveBarRect() const { |
| 1805 // The main bar is as wide as the normal tab's horizontal top line. | 1875 // The main bar is as wide as the normal tab's horizontal top line. |
| 1806 // This top line of the tab extends a few pixels left and right of the | 1876 // This top line of the tab extends a few pixels left and right of the |
| 1807 // center image due to pixels in the rounded corner images. | 1877 // center image due to pixels in the rounded corner images. |
| 1808 const int kBarPadding = 1; | 1878 const int kBarPadding = 1; |
| 1809 int main_bar_left = g_active_images.l_width - kBarPadding; | 1879 int main_bar_left = g_active_images.l_width - kBarPadding; |
| 1810 int main_bar_right = width() - g_active_images.r_width + kBarPadding; | 1880 int main_bar_right = width() - g_active_images.r_width + kBarPadding; |
| 1811 return gfx::Rect( | 1881 return gfx::Rect( |
| 1812 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); | 1882 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); |
| 1813 } | 1883 } |
| OLD | NEW |