ambient_shield_view.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/ambient/ui/ambient_shield_view.h"
  5. #include <array>
  6. #include "ash/ambient/ui/ambient_view_ids.h"
  7. #include "ash/style/dark_light_mode_controller_impl.h"
  8. #include "ui/base/metadata/metadata_impl_macros.h"
  9. #include "ui/compositor/layer_delegate.h"
  10. #include "ui/gfx/canvas.h"
  11. #include "ui/gfx/color_palette.h"
  12. #include "ui/gfx/skia_paint_util.h"
  13. #include "ui/views/background.h"
  14. #include "ui/views/layout/flex_layout.h"
  15. #include "ui/views/layout/flex_layout_types.h"
  16. #include "ui/views/view.h"
  17. #include "ui/views/view_class_properties.h"
  18. namespace ash {
  19. namespace {
  20. // Gray gradient from 5% to 50%.
  21. constexpr std::array<SkColor, 2> kDarkModeColors{
  22. SkColorSetA(gfx::kGoogleGrey900, 12),
  23. SkColorSetA(gfx::kGoogleGrey900, 128)};
  24. // Gray gradient from 0% to 20%.
  25. constexpr std::array<SkColor, 2> kLightModeColors{
  26. SkColorSetA(gfx::kGoogleGrey900, 0), SkColorSetA(gfx::kGoogleGrey900, 51)};
  27. class GradientBackground : public views::Background {
  28. public:
  29. enum class Orientation {
  30. kHorizontal,
  31. kVertical,
  32. kDiagonalAscending,
  33. kDiagonalDescending
  34. };
  35. GradientBackground(Orientation orientation,
  36. SkColor start_color,
  37. SkColor end_color)
  38. : orientation_(orientation),
  39. start_color_(start_color),
  40. end_color_(end_color) {}
  41. GradientBackground(const GradientBackground&) = delete;
  42. GradientBackground& operator=(const GradientBackground&) = delete;
  43. ~GradientBackground() override = default;
  44. // views::Background:
  45. void Paint(gfx::Canvas* canvas, views::View* view) const override {
  46. const auto& bounds = view->GetContentsBounds();
  47. const auto& points = GetPoints(bounds);
  48. cc::PaintFlags flags;
  49. flags.setBlendMode(SkBlendMode::kSrcOver);
  50. flags.setShader(gfx::CreateGradientShader(points.front(), points.back(),
  51. start_color_, end_color_));
  52. canvas->DrawRect(bounds, flags);
  53. }
  54. private:
  55. const std::array<gfx::Point, 2> GetPoints(const gfx::Rect& bounds) const {
  56. switch (orientation_) {
  57. case Orientation::kHorizontal:
  58. return {bounds.left_center(), bounds.right_center()};
  59. case Orientation::kVertical:
  60. return {bounds.top_center(), bounds.bottom_center()};
  61. case Orientation::kDiagonalAscending:
  62. return {bounds.bottom_left(), bounds.top_right()};
  63. case Orientation::kDiagonalDescending:
  64. return {bounds.origin(), bounds.bottom_right()};
  65. }
  66. }
  67. const Orientation orientation_;
  68. const SkColor start_color_;
  69. const SkColor end_color_;
  70. };
  71. std::unique_ptr<GradientBackground> CreateGradientBackground(
  72. GradientBackground::Orientation orientation,
  73. const std::array<SkColor, 2> colors) {
  74. return std::make_unique<GradientBackground>(orientation, colors.front(),
  75. colors.back());
  76. }
  77. } // namespace
  78. AmbientShieldView::AmbientShieldView() {
  79. SetID(AmbientViewID::kAmbientShieldView);
  80. InitLayout();
  81. }
  82. AmbientShieldView::~AmbientShieldView() = default;
  83. void AmbientShieldView::InitLayout() {
  84. const views::FlexSpecification kScaleUnbounded(
  85. views::MinimumFlexSizeRule::kPreferred,
  86. views::MaximumFlexSizeRule::kUnbounded);
  87. views::FlexLayout* layout =
  88. SetLayoutManager(std::make_unique<views::FlexLayout>());
  89. layout->SetOrientation(views::LayoutOrientation::kVertical);
  90. layout->SetMainAxisAlignment(views::LayoutAlignment::kCenter);
  91. layout->SetCrossAxisAlignment(views::LayoutAlignment::kStretch);
  92. views::View* top = AddChildView(std::make_unique<views::View>());
  93. views::View* bottom = AddChildView(std::make_unique<views::View>());
  94. for (auto* view : {top, bottom})
  95. view->SetProperty(views::kFlexBehaviorKey, kScaleUnbounded);
  96. // TODO(b/223270660): Listen for dark/light mode changes.
  97. bool dark_mode = DarkLightModeControllerImpl::Get()->IsDarkModeEnabled();
  98. const auto& colors = dark_mode ? kDarkModeColors : kLightModeColors;
  99. top->SetBackground(views::CreateSolidBackground(colors.front()));
  100. bottom->SetBackground(CreateGradientBackground(
  101. GradientBackground::Orientation::kVertical, colors));
  102. }
  103. BEGIN_METADATA(AmbientShieldView, views::View)
  104. END_METADATA
  105. } // namespace ash