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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 | 109 |
110 // The minimum opacity (out of 1) when a tab (either active or inactive) is | 110 // The minimum opacity (out of 1) when a tab (either active or inactive) is |
111 // throbbing in the immersive mode light strip. | 111 // throbbing in the immersive mode light strip. |
112 const double kImmersiveTabMinThrobOpacity = 0.66; | 112 const double kImmersiveTabMinThrobOpacity = 0.66; |
113 | 113 |
114 // Number of steps in the immersive mode loading animation. | 114 // Number of steps in the immersive mode loading animation. |
115 const int kImmersiveLoadingStepCount = 32; | 115 const int kImmersiveLoadingStepCount = 32; |
116 | 116 |
117 const char kTabCloseButtonName[] = "TabCloseButton"; | 117 const char kTabCloseButtonName[] = "TabCloseButton"; |
118 | 118 |
119 // Parameters for PaintTabBackgroundUsingParams(). | |
120 struct PaintBackgroundParams { | |
121 PaintBackgroundParams(bool is_active, | |
122 gfx::ImageSkia* fill_image_ptr, | |
123 bool has_custom_image, | |
124 gfx::Rect rect, | |
125 SkColor stroke_color, | |
126 SkColor toolbar_color, | |
127 SkColor background_color) | |
128 : is_active(is_active), | |
129 fill_image(fill_image_ptr ? *fill_image_ptr : gfx::ImageSkia()), | |
130 has_custom_image(has_custom_image), | |
131 rect(rect), | |
132 stroke_color(stroke_color), | |
133 toolbar_color(toolbar_color), | |
134 background_color(background_color) {} | |
135 | |
136 const bool is_active; | |
137 const gfx::ImageSkia fill_image; | |
138 const bool has_custom_image; | |
139 const gfx::Rect rect; | |
140 const SkColor stroke_color; | |
141 const SkColor toolbar_color; | |
142 const SkColor background_color; | |
143 }; | |
144 | |
119 //////////////////////////////////////////////////////////////////////////////// | 145 //////////////////////////////////////////////////////////////////////////////// |
120 // ImageCacheEntryMetadata | 146 // ImageCacheEntryMetadata |
121 // | 147 // |
122 // All metadata necessary to uniquely identify a cached image. | 148 // All metadata necessary to uniquely identify a cached image. |
123 struct ImageCacheEntryMetadata { | 149 struct ImageCacheEntryMetadata { |
124 ImageCacheEntryMetadata(int resource_id, | 150 ImageCacheEntryMetadata(int resource_id, |
125 SkColor fill_color, | 151 SkColor fill_color, |
126 SkColor stroke_color, | 152 SkColor stroke_color, |
127 ui::ScaleFactor scale_factor, | 153 ui::ScaleFactor scale_factor, |
128 const gfx::Size& size); | 154 const gfx::Size& size); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 path.lineTo(left, bottom); | 429 path.lineTo(left, bottom); |
404 path.close(); | 430 path.close(); |
405 | 431 |
406 // Unscaling is not necessary since we never scaled up to begin with. | 432 // Unscaling is not necessary since we never scaled up to begin with. |
407 } | 433 } |
408 | 434 |
409 return path; | 435 return path; |
410 } | 436 } |
411 | 437 |
412 void PaintTabFill(gfx::Canvas* canvas, | 438 void PaintTabFill(gfx::Canvas* canvas, |
413 gfx::ImageSkia* fill_image, | 439 const gfx::ImageSkia& fill_image, |
414 int x_offset, | 440 gfx::Rect rect, |
415 int y_offset, | |
416 const gfx::Size& size, | |
417 bool is_active) { | 441 bool is_active) { |
418 const gfx::Insets tab_insets(GetLayoutInsets(TAB)); | 442 const gfx::Insets tab_insets(GetLayoutInsets(TAB)); |
419 // If this isn't the foreground tab, don't draw over the toolbar, but do | 443 // If this isn't the foreground tab, don't draw over the toolbar, but do |
420 // include the 1 px divider stroke at the bottom. | 444 // include the 1 px divider stroke at the bottom. |
421 const int toolbar_overlap = is_active ? 0 : (tab_insets.bottom() - 1); | 445 const int toolbar_overlap = is_active ? 0 : (tab_insets.bottom() - 1); |
422 | 446 |
423 // Draw left edge. | 447 // Draw left edge. |
424 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage( | 448 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage( |
425 *fill_image, x_offset, y_offset, g_mask_images.l_width, size.height()); | 449 fill_image, rect.x(), rect.y(), g_mask_images.l_width, rect.height()); |
426 gfx::ImageSkia theme_l = gfx::ImageSkiaOperations::CreateMaskedImage( | 450 gfx::ImageSkia theme_l = gfx::ImageSkiaOperations::CreateMaskedImage( |
427 tab_l, *g_mask_images.image_l); | 451 tab_l, *g_mask_images.image_l); |
428 canvas->DrawImageInt( | 452 canvas->DrawImageInt( |
429 theme_l, 0, 0, theme_l.width(), theme_l.height() - toolbar_overlap, 0, 0, | 453 theme_l, 0, 0, theme_l.width(), theme_l.height() - toolbar_overlap, 0, 0, |
430 theme_l.width(), theme_l.height() - toolbar_overlap, false); | 454 theme_l.width(), theme_l.height() - toolbar_overlap, false); |
431 | 455 |
432 // Draw right edge. | 456 // Draw right edge. |
433 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage( | 457 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage( |
434 *fill_image, x_offset + size.width() - g_mask_images.r_width, y_offset, | 458 fill_image, rect.right() - g_mask_images.r_width, rect.y(), |
435 g_mask_images.r_width, size.height()); | 459 g_mask_images.r_width, rect.height()); |
436 gfx::ImageSkia theme_r = gfx::ImageSkiaOperations::CreateMaskedImage( | 460 gfx::ImageSkia theme_r = gfx::ImageSkiaOperations::CreateMaskedImage( |
437 tab_r, *g_mask_images.image_r); | 461 tab_r, *g_mask_images.image_r); |
438 canvas->DrawImageInt(theme_r, 0, 0, theme_r.width(), | 462 canvas->DrawImageInt(theme_r, 0, 0, theme_r.width(), |
439 theme_r.height() - toolbar_overlap, | 463 theme_r.height() - toolbar_overlap, |
440 size.width() - theme_r.width(), 0, theme_r.width(), | 464 rect.width() - theme_r.width(), 0, theme_r.width(), |
441 theme_r.height() - toolbar_overlap, false); | 465 theme_r.height() - toolbar_overlap, false); |
442 | 466 |
443 // Draw center. Instead of masking out the top portion we simply skip over it | 467 // Draw center. Instead of masking out the top portion we simply skip over it |
444 // by incrementing by the top padding, since it's a simple rectangle. | 468 // by incrementing by the top padding, since it's a simple rectangle. |
445 canvas->TileImageInt( | 469 rect.Inset(g_mask_images.l_width, tab_insets.top(), g_mask_images.r_width, |
446 *fill_image, x_offset + g_mask_images.l_width, | 470 toolbar_overlap); |
447 y_offset + tab_insets.top(), g_mask_images.l_width, tab_insets.top(), | 471 canvas->TileImageInt(fill_image, rect.x(), rect.y(), g_mask_images.l_width, |
448 size.width() - g_mask_images.l_width - g_mask_images.r_width, | 472 tab_insets.top(), rect.width(), rect.height()); |
449 size.height() - tab_insets.top() - toolbar_overlap); | 473 } |
474 | |
475 void PaintTabBackgroundUsingParams(gfx::Canvas* canvas, | |
476 views::GlowHoverController* hc, | |
477 const PaintBackgroundParams& params) { | |
478 const SkScalar kMinHoverRadius = 16; | |
479 const SkScalar radius = | |
480 std::max(SkFloatToScalar(params.rect.width() / 4.f), kMinHoverRadius); | |
481 const bool draw_hover = !params.is_active && hc; | |
482 SkPoint hover_location( | |
483 gfx::PointToSkPoint(draw_hover ? hc->location() : gfx::Point())); | |
484 const SkColor hover_color = | |
485 SkColorSetA(params.toolbar_color, draw_hover ? hc->GetAlpha() : 255); | |
486 | |
487 if (ui::MaterialDesignController::IsModeMaterial()) { | |
488 gfx::ScopedCanvas scoped_canvas(canvas); | |
489 const float scale = canvas->UndoDeviceScaleFactor(); | |
490 | |
491 // Draw the fill. | |
492 gfx::Path fill = GetFillPath(scale, params.rect.size()); | |
493 SkPaint paint; | |
494 paint.setAntiAlias(true); | |
495 { | |
496 gfx::ScopedCanvas clip_scoper(canvas); | |
497 canvas->ClipPath(fill, true); | |
498 if (!params.fill_image.isNull()) { | |
499 gfx::ScopedCanvas scale_scoper(canvas); | |
500 canvas->sk_canvas()->scale(scale, scale); | |
501 canvas->TileImageInt(params.fill_image, params.rect.x(), | |
502 params.rect.y(), 0, 0, params.rect.width(), | |
503 params.rect.height()); | |
504 } else { | |
505 paint.setColor(params.is_active ? params.toolbar_color | |
506 : params.background_color); | |
507 canvas->DrawRect( | |
508 gfx::ScaleToEnclosingRect(gfx::Rect(params.rect.size()), scale), | |
509 paint); | |
510 } | |
511 if (draw_hover) { | |
512 hover_location.scale(SkFloatToScalar(scale)); | |
513 DrawHighlight(canvas, hover_location, radius * scale, hover_color); | |
514 } | |
515 } | |
516 | |
517 // Draw the stroke. | |
518 gfx::Path stroke = GetBorderPath(scale, false, false, params.rect.size()); | |
519 Op(stroke, fill, kDifference_SkPathOp, &stroke); | |
520 if (!params.is_active) { | |
521 // Clip out the bottom line; this will be drawn for us by | |
522 // TabStrip::PaintChildren(). | |
523 canvas->ClipRect(gfx::RectF(params.rect.width() * scale, | |
524 params.rect.height() * scale - 1)); | |
Greg Levin
2016/08/09 17:28:18
NOTE: Change missed in previous Merge
| |
525 } | |
526 paint.setColor(params.stroke_color); | |
527 canvas->DrawPath(stroke, paint); | |
528 } else { | |
529 if (draw_hover) { | |
530 // Draw everything to a temporary canvas so we can extract an image for | |
531 // use in masking the hover glow. | |
532 gfx::Canvas background_canvas(params.rect.size(), canvas->image_scale(), | |
533 false); | |
534 PaintTabFill(&background_canvas, params.fill_image, params.rect, | |
535 params.is_active); | |
536 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | |
537 canvas->DrawImageInt(background_image, 0, 0); | |
538 | |
539 gfx::Canvas hover_canvas(params.rect.size(), canvas->image_scale(), | |
540 false); | |
541 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); | |
542 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( | |
543 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | |
544 canvas->DrawImageInt(result, 0, 0); | |
545 } else { | |
546 PaintTabFill(canvas, params.fill_image, params.rect, params.is_active); | |
547 } | |
548 | |
549 // Now draw the stroke, highlights, and shadows around the tab edge. | |
550 TabImages* stroke_images = | |
551 params.is_active ? &g_active_images : &g_inactive_images; | |
552 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); | |
553 canvas->TileImageInt( | |
554 *stroke_images->image_c, stroke_images->l_width, 0, | |
555 params.rect.width() - stroke_images->l_width - stroke_images->r_width, | |
556 params.rect.height()); | |
557 canvas->DrawImageInt(*stroke_images->image_r, | |
558 params.rect.width() - stroke_images->r_width, 0); | |
559 } | |
450 } | 560 } |
451 | 561 |
452 } // namespace | 562 } // namespace |
453 | 563 |
454 //////////////////////////////////////////////////////////////////////////////// | 564 //////////////////////////////////////////////////////////////////////////////// |
455 // FaviconCrashAnimation | 565 // FaviconCrashAnimation |
456 // | 566 // |
457 // A custom animation subclass to manage the favicon crash animation. | 567 // A custom animation subclass to manage the favicon crash animation. |
458 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, | 568 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, |
459 public gfx::AnimationDelegate { | 569 public gfx::AnimationDelegate { |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1477 it = g_image_cache->begin(); | 1587 it = g_image_cache->begin(); |
1478 } | 1588 } |
1479 canvas->DrawImageInt(it->image, 0, 0); | 1589 canvas->DrawImageInt(it->image, 0, 0); |
1480 } | 1590 } |
1481 | 1591 |
1482 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, | 1592 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, |
1483 bool is_active, | 1593 bool is_active, |
1484 int fill_id, | 1594 int fill_id, |
1485 bool has_custom_image, | 1595 bool has_custom_image, |
1486 int y_offset) { | 1596 int y_offset) { |
1487 const ui::ThemeProvider* tp = GetThemeProvider(); | 1597 views::GlowHoverController* hc = |
1488 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); | 1598 hover_controller_.ShouldDraw() ? &hover_controller_ : nullptr; |
1489 gfx::ImageSkia* fill_image = tp->GetImageSkiaNamed(fill_id); | 1599 gfx::ImageSkia* fill_image = |
1600 has_custom_image || !ui::MaterialDesignController::IsModeMaterial() | |
1601 ? GetThemeProvider()->GetImageSkiaNamed(fill_id) | |
1602 : nullptr; | |
1490 // The tab image needs to be lined up with the background image | 1603 // The tab image needs to be lined up with the background image |
1491 // so that it feels partially transparent. These offsets represent the tab | 1604 // so that it feels partially transparent. These offsets represent the tab |
1492 // position within the frame background image. | 1605 // position within the frame background image. |
1493 const int x_offset = GetMirroredX() + background_offset_.x(); | 1606 gfx::Rect rect(GetLocalBounds()); |
1607 rect.Offset(GetMirroredX() + background_offset_.x(), y_offset); | |
1608 PaintBackgroundParams params( | |
1609 is_active, fill_image, has_custom_image, rect, | |
1610 controller_->GetToolbarTopSeparatorColor(), | |
1611 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR), | |
1612 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); | |
1494 | 1613 |
1495 const SkScalar kMinHoverRadius = 16; | 1614 PaintTabBackgroundUsingParams(canvas, hc, params); |
1496 const SkScalar radius = | |
1497 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius); | |
1498 const bool draw_hover = !is_active && hover_controller_.ShouldDraw(); | |
1499 SkPoint hover_location(gfx::PointToSkPoint(hover_controller_.location())); | |
1500 const SkColor hover_color = | |
1501 SkColorSetA(toolbar_color, hover_controller_.GetAlpha()); | |
1502 | |
1503 if (ui::MaterialDesignController::IsModeMaterial()) { | |
1504 gfx::ScopedCanvas scoped_canvas(canvas); | |
1505 const float scale = canvas->UndoDeviceScaleFactor(); | |
1506 | |
1507 // Draw the fill. | |
1508 gfx::Path fill = GetFillPath(scale, size()); | |
1509 SkPaint paint; | |
1510 paint.setAntiAlias(true); | |
1511 { | |
1512 gfx::ScopedCanvas clip_scoper(canvas); | |
1513 canvas->ClipPath(fill, true); | |
1514 if (has_custom_image) { | |
1515 gfx::ScopedCanvas scale_scoper(canvas); | |
1516 canvas->sk_canvas()->scale(scale, scale); | |
1517 canvas->TileImageInt(*fill_image, x_offset, y_offset, 0, 0, width(), | |
1518 height()); | |
1519 } else { | |
1520 paint.setColor( | |
1521 is_active ? toolbar_color | |
1522 : tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); | |
1523 canvas->DrawRect(gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), | |
1524 paint); | |
1525 } | |
1526 if (draw_hover) { | |
1527 hover_location.scale(SkFloatToScalar(scale)); | |
1528 DrawHighlight(canvas, hover_location, radius * scale, hover_color); | |
1529 } | |
1530 } | |
1531 | |
1532 // Draw the stroke. | |
1533 gfx::Path stroke = GetBorderPath(scale, false, false, size()); | |
1534 Op(stroke, fill, kDifference_SkPathOp, &stroke); | |
1535 if (!is_active) { | |
1536 // Clip out the bottom line; this will be drawn for us by | |
1537 // TabStrip::PaintChildren(). | |
1538 canvas->ClipRect(gfx::RectF(width() * scale, height() * scale - 1)); | |
1539 } | |
1540 paint.setColor(controller_->GetToolbarTopSeparatorColor()); | |
1541 canvas->DrawPath(stroke, paint); | |
1542 } else { | |
1543 if (draw_hover) { | |
1544 // Draw everything to a temporary canvas so we can extract an image for | |
1545 // use in masking the hover glow. | |
1546 gfx::Canvas background_canvas(size(), canvas->image_scale(), false); | |
1547 PaintTabFill(&background_canvas, fill_image, x_offset, y_offset, size(), | |
1548 is_active); | |
1549 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | |
1550 canvas->DrawImageInt(background_image, 0, 0); | |
1551 | |
1552 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); | |
1553 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); | |
1554 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( | |
1555 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | |
1556 canvas->DrawImageInt(result, 0, 0); | |
1557 } else { | |
1558 PaintTabFill(canvas, fill_image, x_offset, y_offset, size(), is_active); | |
1559 } | |
1560 | |
1561 // Now draw the stroke, highlights, and shadows around the tab edge. | |
1562 TabImages* stroke_images = | |
1563 is_active ? &g_active_images : &g_inactive_images; | |
1564 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); | |
1565 canvas->TileImageInt( | |
1566 *stroke_images->image_c, stroke_images->l_width, 0, | |
1567 width() - stroke_images->l_width - stroke_images->r_width, height()); | |
1568 canvas->DrawImageInt(*stroke_images->image_r, | |
1569 width() - stroke_images->r_width, 0); | |
1570 } | |
1571 } | 1615 } |
1572 | 1616 |
1573 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( | 1617 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( |
1574 gfx::Canvas* canvas, | 1618 gfx::Canvas* canvas, |
1575 const gfx::Rect& favicon_draw_bounds) { | 1619 const gfx::Rect& favicon_draw_bounds) { |
1576 // The pinned tab title changed indicator consists of two parts: | 1620 // The pinned tab title changed indicator consists of two parts: |
1577 // . a clear (totally transparent) part over the bottom right (or left in rtl) | 1621 // . a clear (totally transparent) part over the bottom right (or left in rtl) |
1578 // of the favicon. This is done by drawing the favicon to a canvas, then | 1622 // of the favicon. This is done by drawing the favicon to a canvas, then |
1579 // drawing the clear part on top of the favicon. | 1623 // drawing the clear part on top of the favicon. |
1580 // . a circle in the bottom right (or left in rtl) of the favicon. | 1624 // . 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... | |
1809 gfx::Rect Tab::GetImmersiveBarRect() const { | 1853 gfx::Rect Tab::GetImmersiveBarRect() const { |
1810 // The main bar is as wide as the normal tab's horizontal top line. | 1854 // The main bar is as wide as the normal tab's horizontal top line. |
1811 // This top line of the tab extends a few pixels left and right of the | 1855 // This top line of the tab extends a few pixels left and right of the |
1812 // center image due to pixels in the rounded corner images. | 1856 // center image due to pixels in the rounded corner images. |
1813 const int kBarPadding = 1; | 1857 const int kBarPadding = 1; |
1814 int main_bar_left = g_active_images.l_width - kBarPadding; | 1858 int main_bar_left = g_active_images.l_width - kBarPadding; |
1815 int main_bar_right = width() - g_active_images.r_width + kBarPadding; | 1859 int main_bar_right = width() - g_active_images.r_width + kBarPadding; |
1816 return gfx::Rect( | 1860 return gfx::Rect( |
1817 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); | 1861 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); |
1818 } | 1862 } |
OLD | NEW |