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/frame/opaque_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "chrome/grit/generated_resources.h" | 25 #include "chrome/grit/generated_resources.h" |
26 #include "components/signin/core/browser/signin_header_helper.h" | 26 #include "components/signin/core/browser/signin_header_helper.h" |
27 #include "components/signin/core/common/profile_management_switches.h" | 27 #include "components/signin/core/common/profile_management_switches.h" |
28 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
29 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
30 #include "grit/theme_resources.h" | 30 #include "grit/theme_resources.h" |
31 #include "ui/accessibility/ax_view_state.h" | 31 #include "ui/accessibility/ax_view_state.h" |
32 #include "ui/base/hit_test.h" | 32 #include "ui/base/hit_test.h" |
33 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
34 #include "ui/base/resource/material_design/material_design_controller.h" | 34 #include "ui/base/resource/material_design/material_design_controller.h" |
35 #include "ui/base/resource/resource_bundle.h" | |
36 #include "ui/base/theme_provider.h" | 35 #include "ui/base/theme_provider.h" |
37 #include "ui/gfx/canvas.h" | 36 #include "ui/gfx/canvas.h" |
38 #include "ui/gfx/font_list.h" | 37 #include "ui/gfx/font_list.h" |
39 #include "ui/gfx/geometry/rect_conversions.h" | 38 #include "ui/gfx/geometry/rect_conversions.h" |
40 #include "ui/gfx/image/image.h" | 39 #include "ui/gfx/image/image.h" |
41 #include "ui/gfx/image/image_skia.h" | 40 #include "ui/gfx/image/image_skia.h" |
42 #include "ui/gfx/path.h" | 41 #include "ui/gfx/path.h" |
43 #include "ui/resources/grit/ui_resources.h" | 42 #include "ui/resources/grit/ui_resources.h" |
44 #include "ui/views/controls/button/image_button.h" | 43 #include "ui/views/controls/button/image_button.h" |
45 #include "ui/views/controls/image_view.h" | 44 #include "ui/views/controls/image_view.h" |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 tp->GetImageSkiaNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER)); | 612 tp->GetImageSkiaNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER)); |
614 frame_background_->PaintRestored(canvas, this); | 613 frame_background_->PaintRestored(canvas, this); |
615 | 614 |
616 // Note: When we don't have a toolbar, we need to draw some kind of bottom | 615 // Note: When we don't have a toolbar, we need to draw some kind of bottom |
617 // edge here. Because the App Window graphics we use for this have an | 616 // edge here. Because the App Window graphics we use for this have an |
618 // attached client edge and their sizing algorithm is a little involved, we do | 617 // attached client edge and their sizing algorithm is a little involved, we do |
619 // all this in PaintRestoredClientEdge(). | 618 // all this in PaintRestoredClientEdge(). |
620 } | 619 } |
621 | 620 |
622 void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { | 621 void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { |
623 ui::ThemeProvider* tp = GetThemeProvider(); | |
624 frame_background_->set_frame_color(GetFrameColor()); | 622 frame_background_->set_frame_color(GetFrameColor()); |
625 frame_background_->set_theme_image(GetFrameImage()); | 623 frame_background_->set_theme_image(GetFrameImage()); |
626 frame_background_->set_theme_overlay_image(GetFrameOverlayImage()); | 624 frame_background_->set_theme_overlay_image(GetFrameOverlayImage()); |
627 frame_background_->set_top_area_height(GetTopAreaHeight()); | 625 frame_background_->set_top_area_height(GetTopAreaHeight()); |
628 frame_background_->set_maximized_top_inset( | 626 frame_background_->set_maximized_top_inset( |
629 GetTopInset(true) - GetTopInset(false)); | 627 GetTopInset(true) - GetTopInset(false)); |
630 | |
631 frame_background_->PaintMaximized(canvas, this); | 628 frame_background_->PaintMaximized(canvas, this); |
632 | |
633 // TODO(jamescook): Migrate this into FrameBackground. | |
634 if (!browser_view()->IsToolbarVisible()) { | |
635 // There's no toolbar to edge the frame border, so we need to draw a bottom | |
636 // edge. The graphic we use for this has a built in client edge, so we clip | |
637 // it off the bottom. | |
638 gfx::ImageSkia* top_center = tp->GetImageSkiaNamed(IDR_APP_TOP_CENTER); | |
639 int edge_height = top_center->height() - kClientEdgeThickness; | |
640 canvas->TileImageInt(*top_center, 0, | |
641 frame()->client_view()->y() - edge_height, width(), edge_height); | |
642 } | |
643 } | 629 } |
644 | 630 |
645 void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { | 631 void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { |
646 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); | 632 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
647 if (toolbar_bounds.IsEmpty()) | 633 if (toolbar_bounds.IsEmpty()) |
648 return; | 634 return; |
649 gfx::Point toolbar_origin(toolbar_bounds.origin()); | 635 gfx::Point toolbar_origin(toolbar_bounds.origin()); |
650 ConvertPointToTarget(browser_view(), this, &toolbar_origin); | 636 ConvertPointToTarget(browser_view(), this, &toolbar_origin); |
651 toolbar_bounds.set_origin(toolbar_origin); | 637 toolbar_bounds.set_origin(toolbar_origin); |
652 int x = toolbar_bounds.x(); | |
653 const int y = toolbar_bounds.y(); | |
654 const int w = toolbar_bounds.width(); | |
655 const int h = toolbar_bounds.height(); | 638 const int h = toolbar_bounds.height(); |
| 639 ui::ThemeProvider* tp = GetThemeProvider(); |
| 640 const SkColor separator_color = |
| 641 tp->GetColor(ThemeProperties::COLOR_TOOLBAR_SEPARATOR); |
656 | 642 |
657 // Background. | 643 // Background. |
658 const bool normal_mode = browser_view()->IsTabStripVisible(); | 644 if (browser_view()->IsTabStripVisible()) { |
659 if (normal_mode) { | |
660 // We need to create a separate layer to hold the background, so we can mask | 645 // We need to create a separate layer to hold the background, so we can mask |
661 // off the corners before compositing onto the frame. | 646 // off the corners before compositing onto the frame. |
| 647 int x = toolbar_bounds.x(); |
| 648 const int y = toolbar_bounds.y(); |
| 649 const int w = toolbar_bounds.width(); |
662 canvas->sk_canvas()->saveLayer( | 650 canvas->sk_canvas()->saveLayer( |
663 gfx::RectToSkRect(gfx::Rect(x - kContentEdgeShadowThickness, y, | 651 gfx::RectToSkRect(gfx::Rect(x - kContentEdgeShadowThickness, y, |
664 w + kContentEdgeShadowThickness * 2, h)), | 652 w + kContentEdgeShadowThickness * 2, h)), |
665 nullptr); | 653 nullptr); |
666 } | |
667 | 654 |
668 // The top stroke is drawn using the IDR_CONTENT_TOP_XXX images, which overlay | 655 // The top stroke is drawn using the IDR_CONTENT_TOP_XXX images, which |
669 // the toolbar. The top 2 px of these images is the actual top stroke + | 656 // overlay the toolbar. The top 2 px of these images is the actual top |
670 // shadow, and is partly transparent, so the toolbar background shouldn't be | 657 // stroke + shadow, and is partly transparent, so the toolbar background |
671 // drawn over it. Furthermore, the toolbar may be in popup mode, where we | 658 // shouldn't be drawn over it. |
672 // don't want rounded corners at all, and in that case dividing the toolbar | 659 const int split_point = std::min(kContentEdgeShadowThickness, h); |
673 // assets at this point, plus manipulating the horizontal offset of the top | 660 if (h > split_point) { |
674 // pieces, lets us make the toolbar look almost as if it's intended to have | 661 // Tile the toolbar image starting at the frame edge on the left and where |
675 // square corners. | 662 // the tabstrip is on the top. |
676 const int split_point = std::min(kContentEdgeShadowThickness, h); | 663 const int split_y = y + split_point; |
677 int split_y = y + split_point; | 664 const int bg_y = |
678 int split_h = h - split_point; | 665 GetTopInset(false) + Tab::GetYInsetForActiveTabBackground(); |
679 ui::ThemeProvider* tp = GetThemeProvider(); | 666 canvas->TileImageInt(*tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR), |
680 if (split_h) { | 667 x + GetThemeBackgroundXInset(), split_y - bg_y, x, |
681 // Tile the toolbar image starting at the frame edge on the left and where | 668 split_y, w, h - split_point); |
682 // the horizontal tabstrip is (or would be) on the top. | 669 } |
683 const int kToolbarBackground = IDR_THEME_TOOLBAR; | |
684 // Avoid theming popup or app windows. | |
685 gfx::ImageSkia* bg = normal_mode ? | |
686 tp->GetImageSkiaNamed(kToolbarBackground) : | |
687 ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
688 kToolbarBackground); | |
689 const int bg_y = | |
690 GetTopInset(false) + Tab::GetYInsetForActiveTabBackground(); | |
691 canvas->TileImageInt(*bg, x + GetThemeBackgroundXInset(), split_y - bg_y, x, | |
692 split_y, w, split_h); | |
693 } | |
694 | 670 |
695 gfx::ImageSkia* left = tp->GetImageSkiaNamed(IDR_CONTENT_TOP_LEFT_CORNER); | |
696 const int left_x = x - kContentEdgeShadowThickness; | |
697 int img_w = left->width(); | |
698 gfx::ImageSkia* right = tp->GetImageSkiaNamed(IDR_CONTENT_TOP_RIGHT_CORNER); | |
699 int right_x = toolbar_bounds.right() + kContentEdgeShadowThickness - img_w; | |
700 if (normal_mode) { | |
701 // Mask out the corners. | 671 // Mask out the corners. |
| 672 gfx::ImageSkia* left = tp->GetImageSkiaNamed(IDR_CONTENT_TOP_LEFT_CORNER); |
| 673 const int img_w = left->width(); |
| 674 x -= kContentEdgeShadowThickness; |
702 SkPaint paint; | 675 SkPaint paint; |
703 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | 676 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); |
704 canvas->DrawImageInt( | 677 canvas->DrawImageInt( |
705 *tp->GetImageSkiaNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK), 0, 0, img_w, | 678 *tp->GetImageSkiaNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK), 0, 0, img_w, |
706 h, left_x, y, img_w, h, false, paint); | 679 h, x, y, img_w, h, false, paint); |
| 680 const int right_x = |
| 681 toolbar_bounds.right() + kContentEdgeShadowThickness - img_w; |
707 canvas->DrawImageInt( | 682 canvas->DrawImageInt( |
708 *tp->GetImageSkiaNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK), 0, 0, img_w, | 683 *tp->GetImageSkiaNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK), 0, 0, img_w, |
709 h, right_x, y, img_w, h, false, paint); | 684 h, right_x, y, img_w, h, false, paint); |
710 canvas->Restore(); | 685 canvas->Restore(); |
711 | 686 |
712 // Corner and side strokes. | 687 // Corner and side strokes. |
713 canvas->DrawImageInt(*left, 0, 0, img_w, h, left_x, y, img_w, h, false); | 688 canvas->DrawImageInt(*left, 0, 0, img_w, h, x, y, img_w, h, false); |
714 canvas->DrawImageInt(*right, 0, 0, img_w, h, right_x, y, img_w, h, false); | 689 canvas->DrawImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_TOP_RIGHT_CORNER), |
715 } else { | 690 0, 0, img_w, h, right_x, y, img_w, h, false); |
716 // Corner and side strokes. | 691 |
717 if (split_h) { | 692 // Top stroke. |
718 const int img_h = left->height() - split_h; | 693 x += img_w; |
719 canvas->DrawImageInt(*left, 0, img_h, img_w, split_h, left_x, split_y, | 694 canvas->TileImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_TOP_CENTER), x, y, |
720 img_w, split_h, false); | 695 right_x - x, split_point); |
721 canvas->DrawImageInt(*right, 0, img_h, img_w, split_h, right_x, split_y, | 696 |
722 img_w, split_h, false); | 697 if (ui::MaterialDesignController::IsModeMaterial()) { |
| 698 // Toolbar/content separator. |
| 699 toolbar_bounds.Inset(kClientEdgeThickness, 0); |
| 700 BrowserView::Paint1pxHorizontalLine(canvas, separator_color, |
| 701 toolbar_bounds); |
| 702 return; |
723 } | 703 } |
724 --img_w; | |
725 canvas->DrawImageInt(*left, 1, 0, img_w, split_point, left_x, y, img_w, | |
726 split_point, false); | |
727 ++right_x; | |
728 canvas->DrawImageInt(*right, 0, 0, img_w, split_point, right_x, y, img_w, | |
729 split_point, false); | |
730 } | 704 } |
731 | 705 |
732 // Top stroke. | |
733 x = left_x + img_w; | |
734 canvas->TileImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_TOP_CENTER), x, y, | |
735 right_x - x, split_point); | |
736 | |
737 // Toolbar/content separator. | 706 // Toolbar/content separator. |
738 const SkColor separator_color = | 707 toolbar_bounds.Inset(kClientEdgeThickness, h - kClientEdgeThickness, |
739 tp->GetColor(ThemeProperties::COLOR_TOOLBAR_SEPARATOR); | 708 kClientEdgeThickness, 0); |
740 if (ui::MaterialDesignController::IsModeMaterial()) { | 709 canvas->FillRect(toolbar_bounds, separator_color); |
741 toolbar_bounds.Inset(kClientEdgeThickness, 0); | |
742 BrowserView::Paint1pxHorizontalLine(canvas, separator_color, | |
743 toolbar_bounds); | |
744 } else { | |
745 toolbar_bounds.Inset(kClientEdgeThickness, h - kClientEdgeThickness, | |
746 kClientEdgeThickness, 0); | |
747 canvas->FillRect(toolbar_bounds, separator_color); | |
748 } | |
749 } | 710 } |
750 | 711 |
751 void OpaqueBrowserFrameView::PaintClientEdge(gfx::Canvas* canvas) { | 712 void OpaqueBrowserFrameView::PaintClientEdge(gfx::Canvas* canvas) { |
752 ui::ThemeProvider* tp = GetThemeProvider(); | |
753 int y = frame()->client_view()->y(); | |
754 | |
755 gfx::Rect client_bounds = | 713 gfx::Rect client_bounds = |
756 layout_->CalculateClientAreaBounds(width(), height()); | 714 layout_->CalculateClientAreaBounds(width(), height()); |
757 const int x = client_bounds.x(); | 715 const int x = client_bounds.x(); |
| 716 int y = client_bounds.y(); |
758 const int w = client_bounds.width(); | 717 const int w = client_bounds.width(); |
759 const int right = client_bounds.right(); | 718 const int right = client_bounds.right(); |
760 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); | 719 const bool normal_mode = browser_view()->IsTabStripVisible(); |
| 720 ui::ThemeProvider* tp = GetThemeProvider(); |
| 721 const SkColor toolbar_color = normal_mode ? |
| 722 tp->GetColor(ThemeProperties::COLOR_TOOLBAR) : |
| 723 ThemeProperties::GetDefaultColor(ThemeProperties::COLOR_TOOLBAR); |
761 | 724 |
762 if (IsToolbarVisible()) { | 725 const gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
| 726 if (normal_mode) { |
763 // The client edge images start below the toolbar. | 727 // The client edge images start below the toolbar. |
764 y += browser_view()->GetToolbarBounds().bottom(); | 728 y += toolbar_bounds.bottom(); |
765 } else { | 729 } else { |
766 // The toolbar isn't going to draw a top edge for us, so draw one ourselves. | 730 // The toolbar isn't going to draw a top edge for us, so draw one ourselves. |
| 731 if (IsToolbarVisible()) { |
| 732 y += toolbar_bounds.y() + kContentEdgeShadowThickness + |
| 733 kClientEdgeThickness; |
| 734 } |
767 gfx::ImageSkia* top_left = tp->GetImageSkiaNamed(IDR_APP_TOP_LEFT); | 735 gfx::ImageSkia* top_left = tp->GetImageSkiaNamed(IDR_APP_TOP_LEFT); |
768 const int img_w = top_left->width(); | 736 const int img_w = top_left->width(); |
769 const int height = top_left->height(); | 737 const int height = top_left->height(); |
770 const int top_y = y - height; | 738 const int top_y = y - height; |
771 canvas->DrawImageInt(*top_left, 0, 0, img_w, height, x - img_w, top_y, | 739 canvas->DrawImageInt(*top_left, 0, 0, img_w, height, x - img_w, top_y, |
772 img_w, height, false); | 740 img_w, height, false); |
773 canvas->TileImageInt(*tp->GetImageSkiaNamed(IDR_APP_TOP_CENTER), 0, 0, x, | 741 canvas->TileImageInt(*tp->GetImageSkiaNamed(IDR_APP_TOP_CENTER), 0, 0, x, |
774 top_y, w, height); | 742 top_y, w, height); |
775 canvas->DrawImageInt(*tp->GetImageSkiaNamed(IDR_APP_TOP_RIGHT), 0, 0, img_w, | 743 canvas->DrawImageInt(*tp->GetImageSkiaNamed(IDR_APP_TOP_RIGHT), 0, 0, img_w, |
776 height, right, top_y, img_w, height, false); | 744 height, right, top_y, img_w, height, false); |
| 745 client_bounds.set_y(y); |
777 client_bounds.Inset(-kClientEdgeThickness, -kClientEdgeThickness, | 746 client_bounds.Inset(-kClientEdgeThickness, -kClientEdgeThickness, |
778 -kClientEdgeThickness, client_bounds.height()); | 747 -kClientEdgeThickness, client_bounds.height()); |
779 canvas->FillRect(client_bounds, toolbar_color); | 748 canvas->FillRect(client_bounds, toolbar_color); |
780 } | 749 } |
781 | 750 |
782 // In maximized mode, the only edge to draw is the top one, so we're done. | 751 // In maximized mode, the only edge to draw is the top one, so we're done. |
783 if (layout_->IsTitleBarCondensed()) | 752 if (layout_->IsTitleBarCondensed()) |
784 return; | 753 return; |
785 | 754 |
786 const int bottom = std::max(y, height() - NonClientBorderThickness()); | 755 const int bottom = std::max(y, height() - NonClientBorderThickness()); |
787 int height = bottom - y; | 756 int height = bottom - y; |
788 | 757 |
789 // Draw the client edge images. | 758 // Draw the client edge images. |
790 gfx::ImageSkia* right_image = tp->GetImageSkiaNamed(IDR_CONTENT_RIGHT_SIDE); | 759 gfx::ImageSkia* right_image = tp->GetImageSkiaNamed(IDR_CONTENT_RIGHT_SIDE); |
791 const int img_w = right_image->width(); | 760 const int img_w = right_image->width(); |
792 canvas->TileImageInt(*right_image, right, y, img_w, height); | 761 canvas->TileImageInt(*right_image, right, y, img_w, height); |
793 canvas->DrawImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER), | 762 canvas->DrawImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER), |
794 right, bottom); | 763 right, bottom); |
795 gfx::ImageSkia* bottom_image = | 764 gfx::ImageSkia* bottom_image = |
796 tp->GetImageSkiaNamed(IDR_CONTENT_BOTTOM_CENTER); | 765 tp->GetImageSkiaNamed(IDR_CONTENT_BOTTOM_CENTER); |
797 canvas->TileImageInt(*bottom_image, x, bottom, w, bottom_image->height()); | 766 canvas->TileImageInt(*bottom_image, x, bottom, w, bottom_image->height()); |
798 canvas->DrawImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER), | 767 canvas->DrawImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER), |
799 x - img_w, bottom); | 768 x - img_w, bottom); |
800 gfx::ImageSkia* left_image = tp->GetImageSkiaNamed(IDR_CONTENT_LEFT_SIDE); | 769 canvas->TileImageInt(*tp->GetImageSkiaNamed(IDR_CONTENT_LEFT_SIDE), x - img_w, |
801 canvas->TileImageInt(*left_image, x - img_w, y, img_w, height); | 770 y, img_w, height); |
802 | 771 |
803 // Draw the toolbar color so that the client edges show the right color even | 772 // Draw the toolbar color so that the client edges show the right color even |
804 // where not covered by the toolbar image. NOTE: We do this after drawing the | 773 // where not covered by the toolbar image. NOTE: We do this after drawing the |
805 // images because the images are meant to alpha-blend atop the frame whereas | 774 // images because the images are meant to alpha-blend atop the frame whereas |
806 // these rects are meant to be fully opaque, without anything overlaid. | 775 // these rects are meant to be fully opaque, without anything overlaid. |
807 gfx::Rect side(x - kClientEdgeThickness, y, kClientEdgeThickness, | 776 gfx::Rect side(x - kClientEdgeThickness, y, kClientEdgeThickness, |
808 bottom + kClientEdgeThickness - y); | 777 bottom + kClientEdgeThickness - y); |
809 canvas->FillRect(side, toolbar_color); | 778 canvas->FillRect(side, toolbar_color); |
810 canvas->FillRect(gfx::Rect(x, bottom, w, kClientEdgeThickness), | 779 canvas->FillRect(gfx::Rect(x, bottom, w, kClientEdgeThickness), |
811 toolbar_color); | 780 toolbar_color); |
812 side.set_x(right); | 781 side.set_x(right); |
813 canvas->FillRect(side, toolbar_color); | 782 canvas->FillRect(side, toolbar_color); |
814 } | 783 } |
OLD | NEW |