| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/ambient/ui/ambient_shield_view.h" |
| |
| #include <array> |
| |
| #include "ash/ambient/ui/ambient_view_ids.h" |
| #include "ash/style/dark_light_mode_controller_impl.h" |
| #include "ui/base/metadata/metadata_impl_macros.h" |
| #include "ui/compositor/layer_delegate.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/color_palette.h" |
| #include "ui/gfx/skia_paint_util.h" |
| #include "ui/views/background.h" |
| #include "ui/views/layout/flex_layout.h" |
| #include "ui/views/layout/flex_layout_types.h" |
| #include "ui/views/view.h" |
| #include "ui/views/view_class_properties.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| // Gray gradient from 5% to 50%. |
| constexpr std::array<SkColor, 2> kDarkModeColors{ |
| SkColorSetA(gfx::kGoogleGrey900, 12), |
| SkColorSetA(gfx::kGoogleGrey900, 128)}; |
| |
| // Gray gradient from 0% to 20%. |
| constexpr std::array<SkColor, 2> kLightModeColors{ |
| SkColorSetA(gfx::kGoogleGrey900, 0), SkColorSetA(gfx::kGoogleGrey900, 51)}; |
| |
| class GradientBackground : public views::Background { |
| public: |
| enum class Orientation { |
| kHorizontal, |
| kVertical, |
| kDiagonalAscending, |
| kDiagonalDescending |
| }; |
| |
| GradientBackground(Orientation orientation, |
| SkColor start_color, |
| SkColor end_color) |
| : orientation_(orientation), |
| start_color_(start_color), |
| end_color_(end_color) {} |
| |
| GradientBackground(const GradientBackground&) = delete; |
| GradientBackground& operator=(const GradientBackground&) = delete; |
| |
| ~GradientBackground() override = default; |
| |
| // views::Background: |
| void Paint(gfx::Canvas* canvas, views::View* view) const override { |
| const auto& bounds = view->GetContentsBounds(); |
| const auto& points = GetPoints(bounds); |
| |
| cc::PaintFlags flags; |
| flags.setBlendMode(SkBlendMode::kSrcOver); |
| flags.setShader(gfx::CreateGradientShader(points.front(), points.back(), |
| start_color_, end_color_)); |
| |
| canvas->DrawRect(bounds, flags); |
| } |
| |
| private: |
| const std::array<gfx::Point, 2> GetPoints(const gfx::Rect& bounds) const { |
| switch (orientation_) { |
| case Orientation::kHorizontal: |
| return {bounds.left_center(), bounds.right_center()}; |
| case Orientation::kVertical: |
| return {bounds.top_center(), bounds.bottom_center()}; |
| case Orientation::kDiagonalAscending: |
| return {bounds.bottom_left(), bounds.top_right()}; |
| case Orientation::kDiagonalDescending: |
| return {bounds.origin(), bounds.bottom_right()}; |
| } |
| } |
| |
| const Orientation orientation_; |
| const SkColor start_color_; |
| const SkColor end_color_; |
| }; |
| |
| std::unique_ptr<GradientBackground> CreateGradientBackground( |
| GradientBackground::Orientation orientation, |
| const std::array<SkColor, 2> colors) { |
| return std::make_unique<GradientBackground>(orientation, colors.front(), |
| colors.back()); |
| } |
| |
| } // namespace |
| |
| AmbientShieldView::AmbientShieldView() { |
| SetID(AmbientViewID::kAmbientShieldView); |
| InitLayout(); |
| } |
| |
| AmbientShieldView::~AmbientShieldView() = default; |
| |
| void AmbientShieldView::InitLayout() { |
| const views::FlexSpecification kScaleUnbounded( |
| views::MinimumFlexSizeRule::kPreferred, |
| views::MaximumFlexSizeRule::kUnbounded); |
| |
| views::FlexLayout* layout = |
| SetLayoutManager(std::make_unique<views::FlexLayout>()); |
| layout->SetOrientation(views::LayoutOrientation::kVertical); |
| layout->SetMainAxisAlignment(views::LayoutAlignment::kCenter); |
| layout->SetCrossAxisAlignment(views::LayoutAlignment::kStretch); |
| |
| views::View* top = AddChildView(std::make_unique<views::View>()); |
| views::View* bottom = AddChildView(std::make_unique<views::View>()); |
| |
| for (auto* view : {top, bottom}) |
| view->SetProperty(views::kFlexBehaviorKey, kScaleUnbounded); |
| |
| // TODO(b/223270660): Listen for dark/light mode changes. |
| bool dark_mode = DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(); |
| const auto& colors = dark_mode ? kDarkModeColors : kLightModeColors; |
| |
| top->SetBackground(views::CreateSolidBackground(colors.front())); |
| bottom->SetBackground(CreateGradientBackground( |
| GradientBackground::Orientation::kVertical, colors)); |
| } |
| |
| BEGIN_METADATA(AmbientShieldView) |
| END_METADATA |
| |
| } // namespace ash |