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 bool is_active; | |
125 gfx::ImageSkia fill_image; | |
126 bool has_custom_image; | |
127 gfx::Point offset; | |
128 gfx::Size size; | |
oshima
2016/07/28 16:56:06
Sorry I should have noticed this before, but looks
Greg Levin
2016/07/28 20:03:54
Is this a strong preference? I don't have a sense
oshima
2016/07/28 20:45:48
It just looked to me that drawing code uses it as
Greg Levin
2016/08/10 20:03:09
Done.
| |
129 SkColor stroke_color; | |
130 SkColor toolbar_color; | |
131 SkColor background_color; | |
132 }; | |
133 | |
134 void PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, | |
135 views::GlowHoverController* hc, | |
136 const PaintBackgroundParams& params); | |
137 | |
138 //////////////////////////////////////////////////////////////////////////////// | |
139 // TabImageSource | |
140 // | |
141 // This subclass of CanvasImageSource allows the inactive tab image to be cached | |
142 // once and rendered correctly for all scale factors. | |
143 class TabImageSource : public gfx::CanvasImageSource { | |
144 public: | |
145 TabImageSource(Tab* tab, int fill_id, int y_offset); | |
146 ~TabImageSource() override {} | |
147 | |
148 // gfx::CanvasImageSource override. | |
149 void Draw(gfx::Canvas* canvas) override; | |
150 | |
151 private: | |
152 PaintBackgroundParams params_; | |
153 | |
154 DISALLOW_COPY_AND_ASSIGN(TabImageSource); | |
155 }; | |
156 | |
157 TabImageSource::TabImageSource(Tab* tab, int fill_id, int y_offset) | |
158 : gfx::CanvasImageSource(tab->size(), true) { | |
159 params_.is_active = false; | |
160 params_.fill_image = *tab->GetThemeProvider()->GetImageSkiaNamed(fill_id); | |
161 params_.has_custom_image = false; | |
162 params_.offset.SetPoint(0, y_offset); | |
163 params_.size = tab->size(); | |
164 params_.stroke_color = tab->controller()->GetToolbarTopSeparatorColor(); | |
165 params_.toolbar_color = | |
166 tab->GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR); | |
167 params_.background_color = | |
168 tab->GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB); | |
169 } | |
170 | |
171 void TabImageSource::Draw(gfx::Canvas* canvas) { | |
172 PaintTabBackgroundUsingFillId(canvas, nullptr, params_); | |
173 } | |
174 | |
175 //////////////////////////////////////////////////////////////////////////////// | |
120 // ImageCacheEntryMetadata | 176 // ImageCacheEntryMetadata |
121 // | 177 // |
122 // All metadata necessary to uniquely identify a cached image. | 178 // All metadata necessary to uniquely identify a cached image. |
123 struct ImageCacheEntryMetadata { | 179 struct ImageCacheEntryMetadata { |
124 ImageCacheEntryMetadata(int resource_id, | 180 ImageCacheEntryMetadata(int resource_id, |
125 SkColor fill_color, | 181 SkColor fill_color, |
126 SkColor stroke_color, | 182 SkColor stroke_color, |
127 ui::ScaleFactor scale_factor, | |
128 const gfx::Size& size); | 183 const gfx::Size& size); |
129 | 184 |
130 ~ImageCacheEntryMetadata(); | 185 ~ImageCacheEntryMetadata(); |
131 | 186 |
132 bool operator==(const ImageCacheEntryMetadata& rhs) const; | 187 bool operator==(const ImageCacheEntryMetadata& rhs) const; |
133 | 188 |
134 int resource_id; // Only needed by pre-MD | 189 int resource_id; // Only needed by pre-MD |
135 SkColor fill_color; // Both colors only needed by MD | 190 SkColor fill_color; // Both colors only needed by MD |
136 SkColor stroke_color; | 191 SkColor stroke_color; |
137 ui::ScaleFactor scale_factor; | |
138 gfx::Size size; | 192 gfx::Size size; |
139 }; | 193 }; |
140 | 194 |
141 ImageCacheEntryMetadata::ImageCacheEntryMetadata(int resource_id, | 195 ImageCacheEntryMetadata::ImageCacheEntryMetadata(int resource_id, |
142 SkColor fill_color, | 196 SkColor fill_color, |
143 SkColor stroke_color, | 197 SkColor stroke_color, |
144 ui::ScaleFactor scale_factor, | |
145 const gfx::Size& size) | 198 const gfx::Size& size) |
146 : resource_id(resource_id), | 199 : resource_id(resource_id), |
147 fill_color(fill_color), | 200 fill_color(fill_color), |
148 stroke_color(stroke_color), | 201 stroke_color(stroke_color), |
149 scale_factor(scale_factor), | |
150 size(size) { | 202 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 | 203 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones |
154 // so they don't cause incorrect cache misses. | 204 // so they don't cause incorrect cache misses. |
155 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted. | 205 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted. |
156 if (ui::MaterialDesignController::IsModeMaterial()) | 206 if (ui::MaterialDesignController::IsModeMaterial()) |
157 resource_id = 0; | 207 resource_id = 0; |
158 else | 208 else |
159 fill_color = stroke_color = SK_ColorTRANSPARENT; | 209 fill_color = stroke_color = SK_ColorTRANSPARENT; |
160 } | 210 } |
161 | 211 |
162 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {} | 212 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {} |
163 | 213 |
164 bool ImageCacheEntryMetadata::operator==( | 214 bool ImageCacheEntryMetadata::operator==( |
165 const ImageCacheEntryMetadata& rhs) const { | 215 const ImageCacheEntryMetadata& rhs) const { |
166 return resource_id == rhs.resource_id && fill_color == rhs.fill_color && | 216 return resource_id == rhs.resource_id && fill_color == rhs.fill_color && |
167 stroke_color == rhs.stroke_color && scale_factor == rhs.scale_factor && | 217 stroke_color == rhs.stroke_color && size == rhs.size; |
168 size == rhs.size; | |
169 } | 218 } |
170 | 219 |
171 //////////////////////////////////////////////////////////////////////////////// | 220 //////////////////////////////////////////////////////////////////////////////// |
172 // ImageCacheEntry and cache management | 221 // ImageCacheEntry and cache management |
173 // | 222 // |
174 // A cached image and the metadata used to generate it. | 223 // A cached image and the metadata used to generate it. |
175 struct ImageCacheEntry { | 224 struct ImageCacheEntry { |
176 ImageCacheEntry(const ImageCacheEntryMetadata& metadata, | 225 ImageCacheEntry(const ImageCacheEntryMetadata& metadata, |
177 const gfx::ImageSkia& image); | 226 Tab* tab, |
227 int fill_id, | |
228 int y_offset); | |
178 ~ImageCacheEntry(); | 229 ~ImageCacheEntry(); |
179 | 230 |
180 ImageCacheEntryMetadata metadata; | 231 ImageCacheEntryMetadata metadata; |
181 gfx::ImageSkia image; | 232 gfx::ImageSkia image; |
182 }; | 233 }; |
183 | 234 |
184 ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata, | 235 ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata, |
185 const gfx::ImageSkia& image) | 236 Tab* tab, |
186 : metadata(metadata), image(image) {} | 237 int fill_id, |
238 int y_offset) | |
239 : metadata(metadata), | |
240 image(new TabImageSource(tab, fill_id, y_offset), tab->size()) {} | |
187 | 241 |
188 ImageCacheEntry::~ImageCacheEntry() {} | 242 ImageCacheEntry::~ImageCacheEntry() {} |
189 | 243 |
190 typedef std::list<ImageCacheEntry> ImageCache; | 244 typedef std::list<ImageCacheEntry> ImageCache; |
191 | 245 |
192 // As the majority of the tabs are inactive, and painting tabs is slowish, | 246 // As the majority of the tabs are inactive, and painting tabs is slowish, |
193 // we cache a handful of the inactive tab backgrounds here. | 247 // we cache a handful of the inactive tab backgrounds here. |
194 static ImageCache* g_image_cache = nullptr; | 248 static ImageCache* g_image_cache = nullptr; |
195 | 249 |
196 struct TabImages { | 250 struct TabImages { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 canvas->sk_canvas()->drawRect( | 320 canvas->sk_canvas()->drawRect( |
267 SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), | 321 SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), |
268 paint); | 322 paint); |
269 } | 323 } |
270 | 324 |
271 // Returns whether the favicon for the given URL should be colored according to | 325 // Returns whether the favicon for the given URL should be colored according to |
272 // the browser theme. | 326 // the browser theme. |
273 bool ShouldThemifyFaviconForUrl(const GURL& url) { | 327 bool ShouldThemifyFaviconForUrl(const GURL& url) { |
274 return url.SchemeIs(content::kChromeUIScheme) && | 328 return url.SchemeIs(content::kChromeUIScheme) && |
275 url.host() != chrome::kChromeUIHelpHost && | 329 url.host() != chrome::kChromeUIHelpHost && |
276 url.host() != chrome::kChromeUIUberHost && | 330 url.host() != chrome::kChromeUIUberHost; |
277 url.host() != chrome::kChromeUIAppLauncherPageHost; | |
278 } | 331 } |
279 | 332 |
280 // Computes a path corresponding to the tab's content region inside the outer | 333 // Computes a path corresponding to the tab's content region inside the outer |
281 // stroke. | 334 // stroke. |
282 void GetFillPath(float scale, const gfx::Size& size, SkPath* fill) { | 335 void GetFillPath(float scale, const gfx::Size& size, SkPath* fill) { |
283 const float right = size.width() * scale; | 336 const float right = size.width() * scale; |
284 // The bottom of the tab needs to be pixel-aligned or else when we call | 337 // 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. | 338 // ClipPath with anti-aliasing enabled it can cause artifacts. |
286 const float bottom = std::ceil(size.height() * scale); | 339 const float bottom = std::ceil(size.height() * scale); |
287 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); | 340 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 1.5 * scale); | 397 1.5 * scale); |
345 } | 398 } |
346 path->lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale); | 399 path->lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale); |
347 path->rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale, | 400 path->rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale, |
348 1.5 * scale); | 401 1.5 * scale); |
349 path->rLineTo(0, 1); | 402 path->rLineTo(0, 1); |
350 path->close(); | 403 path->close(); |
351 } | 404 } |
352 | 405 |
353 void PaintTabFill(gfx::Canvas* canvas, | 406 void PaintTabFill(gfx::Canvas* canvas, |
354 gfx::ImageSkia* fill_image, | 407 const gfx::ImageSkia& fill_image, |
355 int x_offset, | 408 int x_offset, |
356 int y_offset, | 409 int y_offset, |
357 const gfx::Size& size, | 410 const gfx::Size& size, |
358 bool is_active) { | 411 bool is_active) { |
359 const gfx::Insets tab_insets(GetLayoutInsets(TAB)); | 412 const gfx::Insets tab_insets(GetLayoutInsets(TAB)); |
360 // If this isn't the foreground tab, don't draw over the toolbar, but do | 413 // If this isn't the foreground tab, don't draw over the toolbar, but do |
361 // include the 1 px divider stroke at the bottom. | 414 // include the 1 px divider stroke at the bottom. |
362 const int toolbar_overlap = is_active ? 0 : (tab_insets.bottom() - 1); | 415 const int toolbar_overlap = is_active ? 0 : (tab_insets.bottom() - 1); |
363 | 416 |
364 // Draw left edge. | 417 // Draw left edge. |
365 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage( | 418 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage( |
366 *fill_image, x_offset, y_offset, g_mask_images.l_width, size.height()); | 419 fill_image, x_offset, y_offset, g_mask_images.l_width, size.height()); |
367 gfx::ImageSkia theme_l = gfx::ImageSkiaOperations::CreateMaskedImage( | 420 gfx::ImageSkia theme_l = gfx::ImageSkiaOperations::CreateMaskedImage( |
368 tab_l, *g_mask_images.image_l); | 421 tab_l, *g_mask_images.image_l); |
369 canvas->DrawImageInt( | 422 canvas->DrawImageInt( |
370 theme_l, 0, 0, theme_l.width(), theme_l.height() - toolbar_overlap, 0, 0, | 423 theme_l, 0, 0, theme_l.width(), theme_l.height() - toolbar_overlap, 0, 0, |
371 theme_l.width(), theme_l.height() - toolbar_overlap, false); | 424 theme_l.width(), theme_l.height() - toolbar_overlap, false); |
372 | 425 |
373 // Draw right edge. | 426 // Draw right edge. |
374 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage( | 427 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage( |
375 *fill_image, x_offset + size.width() - g_mask_images.r_width, y_offset, | 428 fill_image, x_offset + size.width() - g_mask_images.r_width, y_offset, |
376 g_mask_images.r_width, size.height()); | 429 g_mask_images.r_width, size.height()); |
377 gfx::ImageSkia theme_r = gfx::ImageSkiaOperations::CreateMaskedImage( | 430 gfx::ImageSkia theme_r = gfx::ImageSkiaOperations::CreateMaskedImage( |
378 tab_r, *g_mask_images.image_r); | 431 tab_r, *g_mask_images.image_r); |
379 canvas->DrawImageInt(theme_r, 0, 0, theme_r.width(), | 432 canvas->DrawImageInt(theme_r, 0, 0, theme_r.width(), |
380 theme_r.height() - toolbar_overlap, | 433 theme_r.height() - toolbar_overlap, |
381 size.width() - theme_r.width(), 0, theme_r.width(), | 434 size.width() - theme_r.width(), 0, theme_r.width(), |
382 theme_r.height() - toolbar_overlap, false); | 435 theme_r.height() - toolbar_overlap, false); |
383 | 436 |
384 // Draw center. Instead of masking out the top portion we simply skip over it | 437 // 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. | 438 // by incrementing by the top padding, since it's a simple rectangle. |
386 canvas->TileImageInt( | 439 canvas->TileImageInt( |
387 *fill_image, x_offset + g_mask_images.l_width, | 440 fill_image, x_offset + g_mask_images.l_width, y_offset + tab_insets.top(), |
388 y_offset + tab_insets.top(), g_mask_images.l_width, tab_insets.top(), | 441 g_mask_images.l_width, tab_insets.top(), |
389 size.width() - g_mask_images.l_width - g_mask_images.r_width, | 442 size.width() - g_mask_images.l_width - g_mask_images.r_width, |
390 size.height() - tab_insets.top() - toolbar_overlap); | 443 size.height() - tab_insets.top() - toolbar_overlap); |
391 } | 444 } |
392 | 445 |
446 // For use by Tab and TabImageSource | |
447 void PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, | |
448 views::GlowHoverController* hc, | |
449 const PaintBackgroundParams& params) { | |
450 const SkScalar kMinHoverRadius = 16; | |
451 const SkScalar radius = | |
452 std::max(SkFloatToScalar(params.size.width() / 4.f), kMinHoverRadius); | |
453 const bool draw_hover = !params.is_active && hc; | |
454 SkPoint hover_location( | |
455 PointToSkPoint(draw_hover ? hc->location() : gfx::Point())); | |
456 const SkColor hover_color = | |
457 SkColorSetA(params.toolbar_color, draw_hover ? hc->GetAlpha() : 255); | |
458 | |
459 if (ui::MaterialDesignController::IsModeMaterial()) { | |
460 gfx::ScopedCanvas scoped_canvas(canvas); | |
461 const float scale = canvas->UndoDeviceScaleFactor(); | |
462 | |
463 // Draw the fill. | |
464 SkPath fill; | |
465 GetFillPath(scale, params.size, &fill); | |
466 SkPaint paint; | |
467 paint.setAntiAlias(true); | |
468 { | |
469 gfx::ScopedCanvas clip_scoper(canvas); | |
470 canvas->ClipPath(fill, true); | |
471 if (params.has_custom_image) { | |
472 gfx::ScopedCanvas scale_scoper(canvas); | |
473 canvas->sk_canvas()->scale(scale, scale); | |
474 canvas->TileImageInt(params.fill_image, params.offset.x(), | |
475 params.offset.y(), 0, 0, params.size.width(), | |
476 params.size.height()); | |
477 } else { | |
478 paint.setColor(params.is_active ? params.toolbar_color | |
479 : params.background_color); | |
480 canvas->DrawRect( | |
481 gfx::ScaleToEnclosingRect(gfx::Rect(params.size), scale), paint); | |
482 } | |
483 if (draw_hover) { | |
484 hover_location.scale(SkFloatToScalar(scale)); | |
485 DrawHighlight(canvas, hover_location, radius * scale, hover_color); | |
486 } | |
487 } | |
488 | |
489 // Draw the stroke. | |
490 SkPath stroke; | |
491 GetBorderPath(scale, params.size, false, &stroke); | |
492 Op(stroke, fill, kDifference_SkPathOp, &stroke); | |
493 if (!params.is_active) { | |
494 // Clip out the bottom line; this will be drawn for us by | |
495 // TabStrip::PaintChildren(). | |
496 canvas->sk_canvas()->clipRect(SkRect::MakeWH( | |
497 params.size.width() * scale, params.size.height() * scale - 1)); | |
498 } | |
499 paint.setColor(params.stroke_color); | |
500 canvas->DrawPath(stroke, paint); | |
501 } else { | |
502 if (draw_hover) { | |
503 // Draw everything to a temporary canvas so we can extract an image for | |
504 // use in masking the hover glow. | |
505 gfx::Canvas background_canvas(params.size, canvas->image_scale(), false); | |
506 PaintTabFill(&background_canvas, params.fill_image, params.offset.x(), | |
507 params.offset.y(), params.size, params.is_active); | |
508 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | |
509 canvas->DrawImageInt(background_image, 0, 0); | |
510 | |
511 gfx::Canvas hover_canvas(params.size, canvas->image_scale(), false); | |
512 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); | |
513 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( | |
514 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | |
515 canvas->DrawImageInt(result, 0, 0); | |
516 } else { | |
517 PaintTabFill(canvas, params.fill_image, params.offset.x(), | |
518 params.offset.y(), params.size, params.is_active); | |
519 } | |
520 | |
521 // Now draw the stroke, highlights, and shadows around the tab edge. | |
522 TabImages* stroke_images = | |
523 params.is_active ? &g_active_images : &g_inactive_images; | |
524 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); | |
525 canvas->TileImageInt( | |
526 *stroke_images->image_c, stroke_images->l_width, 0, | |
527 params.size.width() - stroke_images->l_width - stroke_images->r_width, | |
528 params.size.height()); | |
529 canvas->DrawImageInt(*stroke_images->image_r, | |
530 params.size.width() - stroke_images->r_width, 0); | |
531 } | |
532 } | |
533 | |
393 } // namespace | 534 } // namespace |
394 | 535 |
395 //////////////////////////////////////////////////////////////////////////////// | 536 //////////////////////////////////////////////////////////////////////////////// |
396 // FaviconCrashAnimation | 537 // FaviconCrashAnimation |
397 // | 538 // |
398 // A custom animation subclass to manage the favicon crash animation. | 539 // A custom animation subclass to manage the favicon crash animation. |
399 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, | 540 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, |
400 public gfx::AnimationDelegate { | 541 public gfx::AnimationDelegate { |
401 public: | 542 public: |
402 explicit FaviconCrashAnimation(Tab* target) | 543 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, | 1588 // 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. | 1589 // to avoid caching a background image that isn't the same for all tabs. |
1449 if (has_custom_image || hover_controller_.ShouldDraw()) { | 1590 if (has_custom_image || hover_controller_.ShouldDraw()) { |
1450 PaintTabBackgroundUsingFillId(canvas, false, fill_id, has_custom_image, | 1591 PaintTabBackgroundUsingFillId(canvas, false, fill_id, has_custom_image, |
1451 y_offset); | 1592 y_offset); |
1452 return; | 1593 return; |
1453 } | 1594 } |
1454 | 1595 |
1455 const ImageCacheEntryMetadata metadata( | 1596 const ImageCacheEntryMetadata metadata( |
1456 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), | 1597 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), |
1457 controller_->GetToolbarTopSeparatorColor(), | 1598 controller_->GetToolbarTopSeparatorColor(), size()); |
1458 ui::GetSupportedScaleFactor(canvas->image_scale()), size()); | |
1459 auto it = std::find_if( | 1599 auto it = std::find_if( |
1460 g_image_cache->begin(), g_image_cache->end(), | 1600 g_image_cache->begin(), g_image_cache->end(), |
1461 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); | 1601 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); |
1462 if (it == g_image_cache->end()) { | 1602 if (it == g_image_cache->end()) { |
1463 gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false); | 1603 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) | 1604 if (g_image_cache->size() > kMaxImageCacheSize) |
1468 g_image_cache->pop_back(); | 1605 g_image_cache->pop_back(); |
1469 it = g_image_cache->begin(); | 1606 it = g_image_cache->begin(); |
1470 } | 1607 } |
1471 canvas->DrawImageInt(it->image, 0, 0); | 1608 canvas->DrawImageInt(it->image, 0, 0); |
1472 } | 1609 } |
1473 | 1610 |
1474 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, | 1611 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, |
1475 bool is_active, | 1612 bool is_active, |
1476 int fill_id, | 1613 int fill_id, |
1477 bool has_custom_image, | 1614 bool has_custom_image, |
1478 int y_offset) { | 1615 int y_offset) { |
1479 const ui::ThemeProvider* tp = GetThemeProvider(); | 1616 views::GlowHoverController* hc = |
1480 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); | 1617 hover_controller_.ShouldDraw() ? &hover_controller_ : nullptr; |
1481 gfx::ImageSkia* fill_image = tp->GetImageSkiaNamed(fill_id); | 1618 PaintBackgroundParams params; |
1619 params.is_active = is_active; | |
1620 params.fill_image = *GetThemeProvider()->GetImageSkiaNamed(fill_id); | |
oshima
2016/07/28 16:56:06
you can set this only if
has_custom_image || !ui::
Greg Levin
2016/07/28 20:03:54
Done.
(I see this is good from a resource saving p
oshima
2016/07/28 20:45:48
It wasn't for saving resource. It's creating a ima
Greg Levin
2016/08/10 20:03:09
Acknowledged.
| |
1621 params.has_custom_image = has_custom_image; | |
1482 // The tab image needs to be lined up with the background image | 1622 // The tab image needs to be lined up with the background image |
1483 // so that it feels partially transparent. These offsets represent the tab | 1623 // so that it feels partially transparent. These offsets represent the tab |
1484 // position within the frame background image. | 1624 // position within the frame background image. |
1485 const int x_offset = GetMirroredX() + background_offset_.x(); | 1625 params.offset.SetPoint(GetMirroredX() + background_offset_.x(), y_offset); |
1626 params.size = size(); | |
1627 params.stroke_color = controller_->GetToolbarTopSeparatorColor(); | |
1628 params.toolbar_color = | |
1629 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR); | |
1630 params.background_color = | |
1631 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB); | |
1486 | 1632 |
1487 const SkScalar kMinHoverRadius = 16; | 1633 ::PaintTabBackgroundUsingFillId(canvas, hc, 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 } | 1634 } |
1567 | 1635 |
1568 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( | 1636 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( |
1569 gfx::Canvas* canvas, | 1637 gfx::Canvas* canvas, |
1570 const gfx::Rect& favicon_draw_bounds) { | 1638 const gfx::Rect& favicon_draw_bounds) { |
1571 // The pinned tab title changed indicator consists of two parts: | 1639 // The pinned tab title changed indicator consists of two parts: |
1572 // . a clear (totally transparent) part over the bottom right (or left in rtl) | 1640 // . 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 | 1641 // of the favicon. This is done by drawing the favicon to a canvas, then |
1574 // drawing the clear part on top of the favicon. | 1642 // drawing the clear part on top of the favicon. |
1575 // . a circle in the bottom right (or left in rtl) of the favicon. | 1643 // . 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 { | 1872 gfx::Rect Tab::GetImmersiveBarRect() const { |
1805 // The main bar is as wide as the normal tab's horizontal top line. | 1873 // 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 | 1874 // 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. | 1875 // center image due to pixels in the rounded corner images. |
1808 const int kBarPadding = 1; | 1876 const int kBarPadding = 1; |
1809 int main_bar_left = g_active_images.l_width - kBarPadding; | 1877 int main_bar_left = g_active_images.l_width - kBarPadding; |
1810 int main_bar_right = width() - g_active_images.r_width + kBarPadding; | 1878 int main_bar_right = width() - g_active_images.r_width + kBarPadding; |
1811 return gfx::Rect( | 1879 return gfx::Rect( |
1812 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); | 1880 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); |
1813 } | 1881 } |
OLD | NEW |