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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 // Desaturate favicon HSL shift values. | 119 // Desaturate favicon HSL shift values. |
120 const double kDesaturateHue = -1.0; | 120 const double kDesaturateHue = -1.0; |
121 const double kDesaturateSaturation = 0.0; | 121 const double kDesaturateSaturation = 0.0; |
122 const double kDesaturateLightness = 0.6; | 122 const double kDesaturateLightness = 0.6; |
123 | 123 |
124 // Parameters for PaintTabBackgroundUsingParams(). | |
125 struct PaintBackgroundParams { | |
126 PaintBackgroundParams(bool is_active, | |
127 gfx::ImageSkia* fill_image_ptr, | |
128 bool has_custom_image, | |
129 gfx::Rect rect, | |
130 SkColor stroke_color, | |
131 SkColor toolbar_color, | |
132 SkColor background_tab_color) | |
133 : is_active(is_active), | |
134 fill_image(fill_image_ptr ? *fill_image_ptr : gfx::ImageSkia()), | |
135 has_custom_image(has_custom_image), | |
136 rect(rect), | |
137 stroke_color(stroke_color), | |
138 toolbar_color(toolbar_color), | |
139 background_tab_color(background_tab_color) {} | |
140 | |
141 const bool is_active; | |
142 const gfx::ImageSkia fill_image; | |
143 const bool has_custom_image; | |
144 const gfx::Rect rect; | |
145 const SkColor stroke_color; | |
146 const SkColor toolbar_color; | |
147 const SkColor background_tab_color; | |
148 }; | |
149 | |
150 //////////////////////////////////////////////////////////////////////////////// | 124 //////////////////////////////////////////////////////////////////////////////// |
151 // ImageCacheEntryMetadata | 125 // ImageCacheEntryMetadata |
152 // | 126 // |
153 // All metadata necessary to uniquely identify a cached image. | 127 // All metadata necessary to uniquely identify a cached image. |
154 struct ImageCacheEntryMetadata { | 128 struct ImageCacheEntryMetadata { |
155 ImageCacheEntryMetadata(int resource_id, | 129 ImageCacheEntryMetadata(int resource_id, |
156 SkColor fill_color, | 130 SkColor fill_color, |
157 SkColor stroke_color, | 131 SkColor stroke_color, |
158 bool use_fill_and_stroke_images, | 132 bool use_fill_and_stroke_images, |
159 float scale_factor, | 133 float scale_factor, |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 theme_r.height() - toolbar_overlap, false); | 451 theme_r.height() - toolbar_overlap, false); |
478 | 452 |
479 // Draw center. Instead of masking out the top portion we simply skip over it | 453 // Draw center. Instead of masking out the top portion we simply skip over it |
480 // by incrementing by the top padding, since it's a simple rectangle. | 454 // by incrementing by the top padding, since it's a simple rectangle. |
481 rect.Inset(g_mask_images.l_width, tab_insets.top(), g_mask_images.r_width, | 455 rect.Inset(g_mask_images.l_width, tab_insets.top(), g_mask_images.r_width, |
482 toolbar_overlap); | 456 toolbar_overlap); |
483 canvas->TileImageInt(fill_image, rect.x(), rect.y(), g_mask_images.l_width, | 457 canvas->TileImageInt(fill_image, rect.x(), rect.y(), g_mask_images.l_width, |
484 tab_insets.top(), rect.width(), rect.height()); | 458 tab_insets.top(), rect.width(), rect.height()); |
485 } | 459 } |
486 | 460 |
487 void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, | |
488 gfx::Canvas* stroke_canvas, | |
489 views::GlowHoverController* hc, | |
490 const PaintBackgroundParams& params) { | |
491 const gfx::Rect& rect = params.rect; | |
492 const SkScalar kMinHoverRadius = 16; | |
493 const SkScalar radius = | |
494 std::max(SkFloatToScalar(rect.width() / 4.f), kMinHoverRadius); | |
495 const bool draw_hover = !params.is_active && hc; | |
496 SkPoint hover_location( | |
497 gfx::PointToSkPoint(draw_hover ? hc->location() : gfx::Point())); | |
498 const SkColor hover_color = | |
499 SkColorSetA(params.toolbar_color, draw_hover ? hc->GetAlpha() : 255); | |
500 | |
501 if (ui::MaterialDesignController::IsModeMaterial()) { | |
502 gfx::Path fill; | |
503 SkPaint paint; | |
504 paint.setAntiAlias(true); | |
505 | |
506 // Draw the fill. | |
507 { | |
508 gfx::ScopedCanvas scoped_canvas(fill_canvas); | |
509 const float scale = fill_canvas->UndoDeviceScaleFactor(); | |
510 | |
511 fill = GetFillPath(scale, rect.size()); | |
512 { | |
513 gfx::ScopedCanvas clip_scoper(fill_canvas); | |
514 fill_canvas->ClipPath(fill, true); | |
515 if (!params.fill_image.isNull()) { | |
516 gfx::ScopedCanvas scale_scoper(fill_canvas); | |
517 fill_canvas->sk_canvas()->scale(scale, scale); | |
518 fill_canvas->TileImageInt(params.fill_image, rect.x(), rect.y(), 0, 0, | |
519 rect.width(), rect.height()); | |
520 } else { | |
521 paint.setColor(params.is_active ? params.toolbar_color | |
522 : params.background_tab_color); | |
523 fill_canvas->DrawRect( | |
524 gfx::ScaleToEnclosingRect(gfx::Rect(rect.size()), scale), | |
525 paint); | |
526 } | |
527 if (draw_hover) { | |
528 hover_location.scale(SkFloatToScalar(scale)); | |
529 DrawHighlight(fill_canvas, hover_location, radius * scale, | |
530 hover_color); | |
531 } | |
532 } | |
533 } | |
534 | |
535 // Draw the stroke. | |
536 { | |
537 gfx::ScopedCanvas scoped_canvas(stroke_canvas); | |
538 const float scale = stroke_canvas->UndoDeviceScaleFactor(); | |
539 | |
540 gfx::Path stroke = GetBorderPath(scale, false, false, rect.size()); | |
541 Op(stroke, fill, kDifference_SkPathOp, &stroke); | |
542 if (!params.is_active) { | |
543 // Clip out the bottom line; this will be drawn for us by | |
544 // TabStrip::PaintChildren(). | |
545 stroke_canvas->ClipRect(gfx::RectF(rect.width() * scale, | |
546 rect.height() * scale - 1)); | |
547 } | |
548 paint.setColor(params.stroke_color); | |
549 stroke_canvas->DrawPath(stroke, paint); | |
550 } | |
551 } else { | |
552 gfx::Canvas* canvas = stroke_canvas; | |
553 if (draw_hover) { | |
554 // Draw everything to a temporary canvas so we can extract an image for | |
555 // use in masking the hover glow. | |
556 gfx::Canvas background_canvas(rect.size(), canvas->image_scale(), false); | |
557 PaintTabFill(&background_canvas, params.fill_image, rect, | |
558 params.is_active); | |
559 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | |
560 canvas->DrawImageInt(background_image, 0, 0); | |
561 | |
562 gfx::Canvas hover_canvas(rect.size(), canvas->image_scale(), false); | |
563 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); | |
564 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( | |
565 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | |
566 canvas->DrawImageInt(result, 0, 0); | |
567 } else { | |
568 PaintTabFill(canvas, params.fill_image, rect, params.is_active); | |
569 } | |
570 | |
571 // Now draw the stroke, highlights, and shadows around the tab edge. | |
572 TabImages* stroke_images = | |
573 params.is_active ? &g_active_images : &g_inactive_images; | |
574 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); | |
575 canvas->TileImageInt( | |
576 *stroke_images->image_c, stroke_images->l_width, 0, | |
577 rect.width() - stroke_images->l_width - stroke_images->r_width, | |
578 rect.height()); | |
579 canvas->DrawImageInt(*stroke_images->image_r, | |
580 rect.width() - stroke_images->r_width, 0); | |
581 } | |
582 } | |
583 | |
584 // Desaturates the favicon. Should only be used for when a tab encounters a | 461 // Desaturates the favicon. Should only be used for when a tab encounters a |
585 // network error state. | 462 // network error state. |
586 void PaintDesaturatedFavIcon(gfx::Canvas* canvas, | 463 void PaintDesaturatedFavIcon(gfx::Canvas* canvas, |
587 gfx::ImageSkia& favicon, | 464 gfx::ImageSkia& favicon, |
588 const gfx::Rect& bounds) { | 465 const gfx::Rect& bounds) { |
589 color_utils::HSL shift = {kDesaturateHue, | 466 color_utils::HSL shift = {kDesaturateHue, |
590 kDesaturateSaturation, | 467 kDesaturateSaturation, |
591 kDesaturateLightness}; | 468 kDesaturateLightness}; |
592 gfx::ImageSkia desaturated_favicon = | 469 gfx::ImageSkia desaturated_favicon = |
593 gfx::ImageSkiaOperations::CreateHSLShiftedImage(favicon, shift); | 470 gfx::ImageSkiaOperations::CreateHSLShiftedImage(favicon, shift); |
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1579 } | 1456 } |
1580 canvas->DrawImageInt(it->stroke_image, 0, 0); | 1457 canvas->DrawImageInt(it->stroke_image, 0, 0); |
1581 } | 1458 } |
1582 | 1459 |
1583 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, | 1460 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, |
1584 gfx::Canvas* stroke_canvas, | 1461 gfx::Canvas* stroke_canvas, |
1585 bool is_active, | 1462 bool is_active, |
1586 int fill_id, | 1463 int fill_id, |
1587 bool has_custom_image, | 1464 bool has_custom_image, |
1588 int y_offset) { | 1465 int y_offset) { |
1589 views::GlowHoverController* hc = | 1466 const ui::ThemeProvider* tp = GetThemeProvider(); |
1590 hover_controller_.ShouldDraw() ? &hover_controller_ : nullptr; | 1467 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); |
1591 gfx::ImageSkia* fill_image = | 1468 gfx::ImageSkia* fill_image = tp->GetImageSkiaNamed(fill_id); |
1592 has_custom_image || !ui::MaterialDesignController::IsModeMaterial() | |
1593 ? GetThemeProvider()->GetImageSkiaNamed(fill_id) | |
1594 : nullptr; | |
1595 // The tab image needs to be lined up with the background image | 1469 // The tab image needs to be lined up with the background image |
1596 // so that it feels partially transparent. These offsets represent the tab | 1470 // so that it feels partially transparent. These offsets represent the tab |
1597 // position within the frame background image. | 1471 // position within the frame background image. |
1598 gfx::Rect rect(GetLocalBounds()); | 1472 const int x_offset = GetMirroredX() + background_offset_.x(); |
1599 rect.Offset(GetMirroredX() + background_offset_.x(), y_offset); | |
1600 PaintBackgroundParams params( | |
1601 is_active, fill_image, has_custom_image, rect, | |
1602 controller_->GetToolbarTopSeparatorColor(), | |
1603 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR), | |
1604 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); | |
1605 | 1473 |
1606 PaintTabBackgroundUsingParams(fill_canvas, stroke_canvas, hc, params); | 1474 const SkScalar kMinHoverRadius = 16; |
| 1475 const SkScalar radius = |
| 1476 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius); |
| 1477 const bool draw_hover = !is_active && hover_controller_.ShouldDraw(); |
| 1478 SkPoint hover_location(gfx::PointToSkPoint(hover_controller_.location())); |
| 1479 const SkColor hover_color = |
| 1480 SkColorSetA(toolbar_color, hover_controller_.GetAlpha()); |
| 1481 |
| 1482 if (ui::MaterialDesignController::IsModeMaterial()) { |
| 1483 gfx::Path fill; |
| 1484 SkPaint paint; |
| 1485 paint.setAntiAlias(true); |
| 1486 |
| 1487 // Draw the fill. |
| 1488 { |
| 1489 gfx::ScopedCanvas scoped_canvas(fill_canvas); |
| 1490 const float scale = fill_canvas->UndoDeviceScaleFactor(); |
| 1491 |
| 1492 fill = GetFillPath(scale, size()); |
| 1493 { |
| 1494 gfx::ScopedCanvas clip_scoper(fill_canvas); |
| 1495 fill_canvas->ClipPath(fill, true); |
| 1496 if (has_custom_image) { |
| 1497 gfx::ScopedCanvas scale_scoper(fill_canvas); |
| 1498 fill_canvas->sk_canvas()->scale(scale, scale); |
| 1499 fill_canvas->TileImageInt(*fill_image, x_offset, y_offset, 0, 0, |
| 1500 width(), height()); |
| 1501 } else { |
| 1502 paint.setColor( |
| 1503 is_active ? toolbar_color |
| 1504 : tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); |
| 1505 fill_canvas->DrawRect( |
| 1506 gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), paint); |
| 1507 } |
| 1508 if (draw_hover) { |
| 1509 hover_location.scale(SkFloatToScalar(scale)); |
| 1510 DrawHighlight(fill_canvas, hover_location, radius * scale, |
| 1511 hover_color); |
| 1512 } |
| 1513 } |
| 1514 } |
| 1515 |
| 1516 // Draw the stroke. |
| 1517 { |
| 1518 gfx::ScopedCanvas scoped_canvas(stroke_canvas); |
| 1519 const float scale = stroke_canvas->UndoDeviceScaleFactor(); |
| 1520 |
| 1521 gfx::Path stroke = GetBorderPath(scale, false, false, size()); |
| 1522 Op(stroke, fill, kDifference_SkPathOp, &stroke); |
| 1523 if (!is_active) { |
| 1524 // Clip out the bottom line; this will be drawn for us by |
| 1525 // TabStrip::PaintChildren(). |
| 1526 stroke_canvas->ClipRect( |
| 1527 gfx::RectF(width() * scale, height() * scale - 1)); |
| 1528 } |
| 1529 paint.setColor(controller_->GetToolbarTopSeparatorColor()); |
| 1530 stroke_canvas->DrawPath(stroke, paint); |
| 1531 } |
| 1532 } else { |
| 1533 gfx::Canvas* canvas = stroke_canvas; |
| 1534 gfx::Rect rect(gfx::Point(x_offset, y_offset), size()); |
| 1535 if (draw_hover) { |
| 1536 // Draw everything to a temporary canvas so we can extract an image for |
| 1537 // use in masking the hover glow. |
| 1538 gfx::Canvas background_canvas(size(), canvas->image_scale(), false); |
| 1539 PaintTabFill(&background_canvas, *fill_image, rect, is_active); |
| 1540 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); |
| 1541 canvas->DrawImageInt(background_image, 0, 0); |
| 1542 |
| 1543 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); |
| 1544 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); |
| 1545 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( |
| 1546 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); |
| 1547 canvas->DrawImageInt(result, 0, 0); |
| 1548 } else { |
| 1549 PaintTabFill(canvas, *fill_image, rect, is_active); |
| 1550 } |
| 1551 |
| 1552 // Now draw the stroke, highlights, and shadows around the tab edge. |
| 1553 TabImages* stroke_images = |
| 1554 is_active ? &g_active_images : &g_inactive_images; |
| 1555 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); |
| 1556 canvas->TileImageInt( |
| 1557 *stroke_images->image_c, stroke_images->l_width, 0, |
| 1558 width() - stroke_images->l_width - stroke_images->r_width, height()); |
| 1559 canvas->DrawImageInt(*stroke_images->image_r, |
| 1560 width() - stroke_images->r_width, 0); |
| 1561 } |
1607 } | 1562 } |
1608 | 1563 |
1609 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( | 1564 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( |
1610 gfx::Canvas* canvas, | 1565 gfx::Canvas* canvas, |
1611 const gfx::Rect& favicon_draw_bounds) { | 1566 const gfx::Rect& favicon_draw_bounds) { |
1612 // The pinned tab title changed indicator consists of two parts: | 1567 // The pinned tab title changed indicator consists of two parts: |
1613 // . a clear (totally transparent) part over the bottom right (or left in rtl) | 1568 // . a clear (totally transparent) part over the bottom right (or left in rtl) |
1614 // of the favicon. This is done by drawing the favicon to a canvas, then | 1569 // of the favicon. This is done by drawing the favicon to a canvas, then |
1615 // drawing the clear part on top of the favicon. | 1570 // drawing the clear part on top of the favicon. |
1616 // . a circle in the bottom right (or left in rtl) of the favicon. | 1571 // . a circle in the bottom right (or left in rtl) of the favicon. |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1857 gfx::Rect Tab::GetImmersiveBarRect() const { | 1812 gfx::Rect Tab::GetImmersiveBarRect() const { |
1858 // The main bar is as wide as the normal tab's horizontal top line. | 1813 // The main bar is as wide as the normal tab's horizontal top line. |
1859 // This top line of the tab extends a few pixels left and right of the | 1814 // This top line of the tab extends a few pixels left and right of the |
1860 // center image due to pixels in the rounded corner images. | 1815 // center image due to pixels in the rounded corner images. |
1861 const int kBarPadding = 1; | 1816 const int kBarPadding = 1; |
1862 int main_bar_left = g_active_images.l_width - kBarPadding; | 1817 int main_bar_left = g_active_images.l_width - kBarPadding; |
1863 int main_bar_right = width() - g_active_images.r_width + kBarPadding; | 1818 int main_bar_right = width() - g_active_images.r_width + kBarPadding; |
1864 return gfx::Rect( | 1819 return gfx::Rect( |
1865 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); | 1820 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); |
1866 } | 1821 } |
OLD | NEW |