OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/tabs/tab.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/browser/defaults.h" | 10 #include "chrome/browser/defaults.h" |
11 #include "chrome/browser/themes/theme_service.h" | 11 #include "chrome/browser/themes/theme_service.h" |
12 #include "chrome/browser/ui/tabs/tab_resources.h" | 12 #include "chrome/browser/ui/tabs/tab_resources.h" |
13 #include "chrome/browser/ui/views/tabs/tab_controller.h" | 13 #include "chrome/browser/ui/views/tabs/tab_controller.h" |
14 #include "grit/generated_resources.h" | 14 #include "grit/generated_resources.h" |
15 #include "grit/theme_resources.h" | 15 #include "grit/theme_resources.h" |
16 #include "grit/theme_resources_standard.h" | 16 #include "grit/theme_resources_standard.h" |
17 #include "grit/ui_resources.h" | 17 #include "grit/ui_resources.h" |
18 #include "third_party/skia/include/effects/SkGradientShader.h" | 18 #include "third_party/skia/include/effects/SkGradientShader.h" |
19 #include "ui/base/animation/multi_animation.h" | 19 #include "ui/base/animation/multi_animation.h" |
20 #include "ui/base/animation/throb_animation.h" | 20 #include "ui/base/animation/throb_animation.h" |
21 #include "ui/base/layout.h" | 21 #include "ui/base/layout.h" |
22 #include "ui/base/resource/resource_bundle.h" | 22 #include "ui/base/resource/resource_bundle.h" |
23 #include "ui/gfx/canvas.h" | 23 #include "ui/gfx/canvas.h" |
24 #include "ui/gfx/favicon_size.h" | 24 #include "ui/gfx/favicon_size.h" |
25 #include "ui/gfx/font.h" | 25 #include "ui/gfx/font.h" |
| 26 #include "ui/gfx/image/image_skia_operations.h" |
26 #include "ui/gfx/path.h" | 27 #include "ui/gfx/path.h" |
27 #include "ui/gfx/skbitmap_operations.h" | |
28 #include "ui/views/controls/button/image_button.h" | 28 #include "ui/views/controls/button/image_button.h" |
29 #include "ui/views/widget/tooltip_manager.h" | 29 #include "ui/views/widget/tooltip_manager.h" |
30 #include "ui/views/widget/widget.h" | 30 #include "ui/views/widget/widget.h" |
31 #include "ui/views/window/non_client_view.h" | 31 #include "ui/views/window/non_client_view.h" |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 // Padding around the "content" of a tab, occupied by the tab border graphics. | 35 // Padding around the "content" of a tab, occupied by the tab border graphics. |
36 | 36 |
37 int left_padding() { | 37 int left_padding() { |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 gfx::Rect(width(), height())); | 556 gfx::Rect(width(), height())); |
557 canvas->sk_canvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); | 557 canvas->sk_canvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); |
558 PaintActiveTabBackground(canvas, GetTabBackgroundImage(data().mode)); | 558 PaintActiveTabBackground(canvas, GetTabBackgroundImage(data().mode)); |
559 canvas->Restore(); | 559 canvas->Restore(); |
560 } | 560 } |
561 } | 561 } |
562 } | 562 } |
563 | 563 |
564 void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) { | 564 void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) { |
565 // Render the inactive tab background. We'll use this for clipping. | 565 // Render the inactive tab background. We'll use this for clipping. |
566 gfx::Canvas background_canvas(size(), false); | 566 gfx::Canvas background_canvas(size(), canvas->scale_factor(), false); |
567 PaintInactiveTabBackground(&background_canvas); | 567 PaintInactiveTabBackground(&background_canvas); |
568 | 568 |
569 gfx::ImageSkia background_image = background_canvas.ExtractBitmap(); | 569 gfx::ImageSkia background_image(background_canvas.ExtractImageSkiaRep()); |
570 | 570 |
571 // Draw a radial gradient to hover_canvas. | 571 // Draw a radial gradient to hover_canvas. |
572 gfx::Canvas hover_canvas(size(), false); | 572 gfx::Canvas hover_canvas(size(), canvas->scale_factor(), false); |
573 int radius = kMiniTitleChangeGradientRadius; | 573 int radius = kMiniTitleChangeGradientRadius; |
574 int x0 = width() + radius - kMiniTitleChangeInitialXOffset; | 574 int x0 = width() + radius - kMiniTitleChangeInitialXOffset; |
575 int x1 = radius; | 575 int x1 = radius; |
576 int x2 = -radius; | 576 int x2 = -radius; |
577 int x; | 577 int x; |
578 if (mini_title_animation_->current_part_index() == 0) { | 578 if (mini_title_animation_->current_part_index() == 0) { |
579 x = mini_title_animation_->CurrentValueBetween(x0, x1); | 579 x = mini_title_animation_->CurrentValueBetween(x0, x1); |
580 } else if (mini_title_animation_->current_part_index() == 1) { | 580 } else if (mini_title_animation_->current_part_index() == 1) { |
581 x = x1; | 581 x = x1; |
582 } else { | 582 } else { |
583 x = mini_title_animation_->CurrentValueBetween(x1, x2); | 583 x = mini_title_animation_->CurrentValueBetween(x1, x2); |
584 } | 584 } |
585 SkPoint center_point; | 585 SkPoint center_point; |
586 center_point.iset(x, 0); | 586 center_point.iset(x, 0); |
587 SkColor colors[2] = { kMiniTitleChangeGradientColor1, | 587 SkColor colors[2] = { kMiniTitleChangeGradientColor1, |
588 kMiniTitleChangeGradientColor2 }; | 588 kMiniTitleChangeGradientColor2 }; |
589 SkShader* shader = SkGradientShader::CreateRadial(center_point, | 589 SkShader* shader = SkGradientShader::CreateRadial(center_point, |
590 SkIntToScalar(radius), colors, NULL, 2, SkShader::kClamp_TileMode); | 590 SkIntToScalar(radius), colors, NULL, 2, SkShader::kClamp_TileMode); |
591 SkPaint paint; | 591 SkPaint paint; |
592 paint.setShader(shader); | 592 paint.setShader(shader); |
593 shader->unref(); | 593 shader->unref(); |
594 hover_canvas.DrawRect(gfx::Rect(x - radius, -radius, radius * 2, radius * 2), | 594 hover_canvas.DrawRect(gfx::Rect(x - radius, -radius, radius * 2, radius * 2), |
595 paint); | 595 paint); |
596 | 596 |
597 // Draw the radial gradient clipped to the background into hover_image. | 597 // Draw the radial gradient clipped to the background into hover_image. |
598 gfx::ImageSkia hover_image = SkBitmapOperations::CreateMaskedBitmap( | 598 gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage( |
599 hover_canvas.ExtractBitmap(), background_image); | 599 gfx::ImageSkia(hover_canvas.ExtractImageSkiaRep()), background_image); |
600 | 600 |
601 // Draw the tab background to the canvas. | 601 // Draw the tab background to the canvas. |
602 canvas->DrawImageInt(background_image, 0, 0); | 602 canvas->DrawImageInt(background_image, 0, 0); |
603 | 603 |
604 // And then the gradient on top of that. | 604 // And then the gradient on top of that. |
605 if (mini_title_animation_->current_part_index() == 2) { | 605 if (mini_title_animation_->current_part_index() == 2) { |
606 canvas->SaveLayerAlpha(mini_title_animation_->CurrentValueBetween(255, 0)); | 606 canvas->SaveLayerAlpha(mini_title_animation_->CurrentValueBetween(255, 0)); |
607 canvas->DrawImageInt(hover_image, 0, 0); | 607 canvas->DrawImageInt(hover_image, 0, 0); |
608 canvas->Restore(); | 608 canvas->Restore(); |
609 } else { | 609 } else { |
(...skipping 25 matching lines...) Expand all Loading... |
635 | 635 |
636 // If the theme is providing a custom background image, then its top edge | 636 // If the theme is providing a custom background image, then its top edge |
637 // should be at the top of the tab. Otherwise, we assume that the background | 637 // should be at the top of the tab. Otherwise, we assume that the background |
638 // image is a composited foreground + frame image. | 638 // image is a composited foreground + frame image. |
639 int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ? | 639 int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ? |
640 0 : background_offset_.y(); | 640 0 : background_offset_.y(); |
641 | 641 |
642 // We need a gfx::Canvas object to be able to extract the image from. | 642 // We need a gfx::Canvas object to be able to extract the image from. |
643 // We draw everything to this canvas and then output it to the canvas | 643 // We draw everything to this canvas and then output it to the canvas |
644 // parameter in addition to using it to mask the hover glow if needed. | 644 // parameter in addition to using it to mask the hover glow if needed. |
645 gfx::Canvas background_canvas(size(), false); | 645 gfx::Canvas background_canvas(size(), canvas->scale_factor(), false); |
646 | 646 |
647 // Draw left edge. Don't draw over the toolbar, as we're not the foreground | 647 // Draw left edge. Don't draw over the toolbar, as we're not the foreground |
648 // tab. | 648 // tab. |
649 gfx::ImageSkia tab_l = SkBitmapOperations::CreateTiledBitmap( | 649 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage( |
650 *tab_bg, offset, bg_offset_y, tab_image->l_width, height()); | 650 *tab_bg, offset, bg_offset_y, tab_image->l_width, height()); |
651 gfx::ImageSkia theme_l = | 651 gfx::ImageSkia theme_l = |
652 SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l); | 652 gfx::ImageSkiaOperations::CreateMaskedImage(tab_l, *alpha->image_l); |
653 background_canvas.DrawImageInt(theme_l, | 653 background_canvas.DrawImageInt(theme_l, |
654 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap, | 654 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap, |
655 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap, | 655 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap, |
656 false); | 656 false); |
657 | 657 |
658 // Draw right edge. Again, don't draw over the toolbar. | 658 // Draw right edge. Again, don't draw over the toolbar. |
659 gfx::ImageSkia tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg, | 659 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage(*tab_bg, |
660 offset + width() - tab_image->r_width, bg_offset_y, | 660 offset + width() - tab_image->r_width, bg_offset_y, |
661 tab_image->r_width, height()); | 661 tab_image->r_width, height()); |
662 gfx::ImageSkia theme_r = | 662 gfx::ImageSkia theme_r = |
663 SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r); | 663 gfx::ImageSkiaOperations::CreateMaskedImage(tab_r, *alpha->image_r); |
664 background_canvas.DrawImageInt(theme_r, | 664 background_canvas.DrawImageInt(theme_r, |
665 0, 0, theme_r.width(), theme_r.height() - kToolbarOverlap, | 665 0, 0, theme_r.width(), theme_r.height() - kToolbarOverlap, |
666 width() - theme_r.width(), 0, theme_r.width(), | 666 width() - theme_r.width(), 0, theme_r.width(), |
667 theme_r.height() - kToolbarOverlap, false); | 667 theme_r.height() - kToolbarOverlap, false); |
668 | 668 |
669 // Draw center. Instead of masking out the top portion we simply skip over | 669 // Draw center. Instead of masking out the top portion we simply skip over |
670 // it by incrementing by GetDropShadowHeight(), since it's a simple | 670 // it by incrementing by GetDropShadowHeight(), since it's a simple |
671 // rectangle. And again, don't draw over the toolbar. | 671 // rectangle. And again, don't draw over the toolbar. |
672 background_canvas.TileImageInt(*tab_bg, | 672 background_canvas.TileImageInt(*tab_bg, |
673 offset + tab_image->l_width, | 673 offset + tab_image->l_width, |
674 bg_offset_y + drop_shadow_height() + tab_image->y_offset, | 674 bg_offset_y + drop_shadow_height() + tab_image->y_offset, |
675 tab_image->l_width, | 675 tab_image->l_width, |
676 drop_shadow_height() + tab_image->y_offset, | 676 drop_shadow_height() + tab_image->y_offset, |
677 width() - tab_image->l_width - tab_image->r_width, | 677 width() - tab_image->l_width - tab_image->r_width, |
678 height() - drop_shadow_height() - kToolbarOverlap - tab_image->y_offset); | 678 height() - drop_shadow_height() - kToolbarOverlap - tab_image->y_offset); |
679 | 679 |
680 canvas->DrawImageInt(background_canvas.ExtractBitmap(), 0, 0); | 680 canvas->DrawImageInt( |
| 681 gfx::ImageSkia(background_canvas.ExtractImageSkiaRep()), 0, 0); |
681 | 682 |
682 if (!GetThemeProvider()->HasCustomImage(tab_id) && | 683 if (!GetThemeProvider()->HasCustomImage(tab_id) && |
683 hover_controller().ShouldDraw()) { | 684 hover_controller().ShouldDraw()) { |
684 hover_controller().Draw(canvas, background_canvas.ExtractBitmap()); | 685 hover_controller().Draw(canvas, background_canvas.ExtractImageSkiaRep()); |
685 } | 686 } |
686 | 687 |
687 // Now draw the highlights/shadows around the tab edge. | 688 // Now draw the highlights/shadows around the tab edge. |
688 canvas->DrawImageInt(*tab_inactive_image->image_l, 0, 0); | 689 canvas->DrawImageInt(*tab_inactive_image->image_l, 0, 0); |
689 canvas->TileImageInt(*tab_inactive_image->image_c, | 690 canvas->TileImageInt(*tab_inactive_image->image_c, |
690 tab_inactive_image->l_width, 0, | 691 tab_inactive_image->l_width, 0, |
691 width() - tab_inactive_image->l_width - | 692 width() - tab_inactive_image->l_width - |
692 tab_inactive_image->r_width, | 693 tab_inactive_image->r_width, |
693 height()); | 694 height()); |
694 canvas->DrawImageInt(*tab_inactive_image->image_r, | 695 canvas->DrawImageInt(*tab_inactive_image->image_r, |
695 width() - tab_inactive_image->r_width, 0); | 696 width() - tab_inactive_image->r_width, 0); |
696 } | 697 } |
697 | 698 |
698 void Tab::PaintActiveTabBackground(gfx::Canvas* canvas, | 699 void Tab::PaintActiveTabBackground(gfx::Canvas* canvas, |
699 gfx::ImageSkia* tab_background) { | 700 gfx::ImageSkia* tab_background) { |
700 DCHECK(tab_background); | 701 DCHECK(tab_background); |
701 | 702 |
702 int offset = GetMirroredX() + background_offset_.x(); | 703 int offset = GetMirroredX() + background_offset_.x(); |
703 | 704 |
704 TabImage* tab_image = | 705 TabImage* tab_image = |
705 controller() && controller()->IsInstantExtendedAPIEnabled() ? | 706 controller() && controller()->IsInstantExtendedAPIEnabled() ? |
706 &tab_active_search_ : &tab_active_; | 707 &tab_active_search_ : &tab_active_; |
707 TabImage* alpha = &tab_alpha_; | 708 TabImage* alpha = &tab_alpha_; |
708 | 709 |
709 // Draw left edge. | 710 // Draw left edge. |
710 gfx::ImageSkia tab_l = SkBitmapOperations::CreateTiledBitmap( | 711 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage( |
711 *tab_background, offset, 0, tab_image->l_width, height()); | 712 *tab_background, offset, 0, tab_image->l_width, height()); |
712 gfx::ImageSkia theme_l = | 713 gfx::ImageSkia theme_l = |
713 SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l); | 714 gfx::ImageSkiaOperations::CreateMaskedImage(tab_l, *alpha->image_l); |
714 canvas->DrawImageInt(theme_l, 0, 0); | 715 canvas->DrawImageInt(theme_l, 0, 0); |
715 | 716 |
716 // Draw right edge. | 717 // Draw right edge. |
717 gfx::ImageSkia tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_background, | 718 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage( |
| 719 *tab_background, |
718 offset + width() - tab_image->r_width, 0, tab_image->r_width, height()); | 720 offset + width() - tab_image->r_width, 0, tab_image->r_width, height()); |
719 gfx::ImageSkia theme_r = | 721 gfx::ImageSkia theme_r = |
720 SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r); | 722 gfx::ImageSkiaOperations::CreateMaskedImage(tab_r, *alpha->image_r); |
721 canvas->DrawImageInt(theme_r, width() - tab_image->r_width, 0); | 723 canvas->DrawImageInt(theme_r, width() - tab_image->r_width, 0); |
722 | 724 |
723 // Draw center. Instead of masking out the top portion we simply skip over it | 725 // Draw center. Instead of masking out the top portion we simply skip over it |
724 // by incrementing by GetDropShadowHeight(), since it's a simple rectangle. | 726 // by incrementing by GetDropShadowHeight(), since it's a simple rectangle. |
725 canvas->TileImageInt(*tab_background, | 727 canvas->TileImageInt(*tab_background, |
726 offset + tab_image->l_width, | 728 offset + tab_image->l_width, |
727 drop_shadow_height() + tab_image->y_offset, | 729 drop_shadow_height() + tab_image->y_offset, |
728 tab_image->l_width, | 730 tab_image->l_width, |
729 drop_shadow_height() + tab_image->y_offset, | 731 drop_shadow_height() + tab_image->y_offset, |
730 width() - tab_image->l_width - tab_image->r_width, | 732 width() - tab_image->l_width - tab_image->r_width, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 rb.GetImageSkiaNamed(IDR_TAB_ACTIVE_RIGHT_SEARCH); | 816 rb.GetImageSkiaNamed(IDR_TAB_ACTIVE_RIGHT_SEARCH); |
815 tab_active_search_.l_width = tab_active_search_.image_l->width(); | 817 tab_active_search_.l_width = tab_active_search_.image_l->width(); |
816 tab_active_search_.r_width = tab_active_search_.image_r->width(); | 818 tab_active_search_.r_width = tab_active_search_.image_r->width(); |
817 | 819 |
818 tab_inactive_.image_l = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_LEFT); | 820 tab_inactive_.image_l = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_LEFT); |
819 tab_inactive_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER); | 821 tab_inactive_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER); |
820 tab_inactive_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); | 822 tab_inactive_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); |
821 tab_inactive_.l_width = tab_inactive_.image_l->width(); | 823 tab_inactive_.l_width = tab_inactive_.image_l->width(); |
822 tab_inactive_.r_width = tab_inactive_.image_r->width(); | 824 tab_inactive_.r_width = tab_inactive_.image_r->width(); |
823 } | 825 } |
OLD | NEW |