blob: 9d32872f742516c8d5140f3d392c25e7f1a3fad8 [file] [log] [blame]
Avi Drissman3e1a26c2022-09-15 20:26:031// Copyright 2012 The Chromium Authors
[email protected]a54e65b2011-11-21 22:03:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Tommy C. Li092c628a2018-03-29 20:32:155#ifndef UI_COMPOSITOR_EXTRA_SHADOW_H_
6#define UI_COMPOSITOR_EXTRA_SHADOW_H_
[email protected]a54e65b2011-11-21 22:03:347
danakj25c52c32016-04-12 21:51:088#include <memory>
9
Keishi Hattori0e45c022021-11-27 09:25:5210#include "base/memory/raw_ptr.h"
[email protected]116302fc2012-05-05 21:45:4111#include "ui/compositor/layer_animation_observer.h"
Ahmed Fakhry349729742019-07-26 03:17:4312#include "ui/compositor/layer_owner.h"
tfarina3b0452d2014-12-31 15:20:0913#include "ui/gfx/geometry/rect.h"
Xiaodan Zhuc176db62022-01-25 01:47:1914#include "ui/gfx/shadow_util.h"
David Reveman60c9b242017-11-28 02:24:5015
[email protected]a54e65b2011-11-21 22:03:3416namespace ui {
17class Layer;
[email protected]a54e65b2011-11-21 22:03:3418
[email protected]a54e65b2011-11-21 22:03:3419// Simple class that draws a drop shadow around content at given bounds.
Ahmed Fakhry349729742019-07-26 03:17:4320class Shadow : public ui::ImplicitAnimationObserver, public ui::LayerOwner {
[email protected]a54e65b2011-11-21 22:03:3421 public:
Xiaodan Zhue1930d42023-07-18 17:51:0222 // Mapping from elevation to key and ambient shadow colors. The first color is
23 // the key shadow color and the second is the ambient shadow color.
Xiaodan Zhu6622a402023-07-12 01:59:5024 using ElevationToColorsMap = base::flat_map<int, std::pair<SkColor, SkColor>>;
25
[email protected]a54e65b2011-11-21 22:03:3426 Shadow();
Peter Boströmc8c12352021-09-21 23:37:1527
28 Shadow(const Shadow&) = delete;
29 Shadow& operator=(const Shadow&) = delete;
30
dchenga74e3542014-10-27 21:15:0531 ~Shadow() override;
[email protected]a8bd1cb2012-02-17 23:05:5432
Trent Apted280f4ff2018-02-07 07:11:5333 // Initialize for the the given shadow |elevation|. This is passed to
34 // gfx::ShadowValue::MakeMdShadowValues() and controls the y-offset and blur
35 // for the shadow style.
36 void Init(int elevation);
[email protected]a54e65b2011-11-21 22:03:3437
varkha52d14032016-07-16 04:23:5838 // Exposed to allow setting animation parameters for bounds and opacity
39 // animations.
Ahmed Fakhry349729742019-07-26 03:17:4340 ui::Layer* shadow_layer() { return shadow_layer_owner_.layer(); }
41
42 ui::Layer* fading_layer() { return fading_layer_owner_.layer(); }
varkha52d14032016-07-16 04:23:5843
[email protected]a54e65b2011-11-21 22:03:3444 const gfx::Rect& content_bounds() const { return content_bounds_; }
Trent Apted280f4ff2018-02-07 07:11:5345 int desired_elevation() const { return desired_elevation_; }
Xiaodan Zhu6622a402023-07-12 01:59:5046 const ElevationToColorsMap& color_map() const { return color_map_; }
[email protected]a54e65b2011-11-21 22:03:3447
[email protected]98a59132014-07-16 22:49:5248 // Moves and resizes the shadow layer to frame |content_bounds|.
Ahmed Fakhry349729742019-07-26 03:17:4349 // This should be used to adjust the shadow's size and position (rather than
50 // applying transformations to the `layer()` of this Shadow).
[email protected]a54e65b2011-11-21 22:03:3451 void SetContentBounds(const gfx::Rect& content_bounds);
52
estadeba7b9d72017-01-04 20:06:0653 // Sets the shadow's appearance, animating opacity as necessary.
Trent Apted280f4ff2018-02-07 07:11:5354 void SetElevation(int elevation);
[email protected]a8bd1cb2012-02-17 23:05:5455
revemanc2ac3cdd2017-01-26 02:50:5156 // Sets the radius for the rounded corners to take into account when
57 // adjusting the shadow layer to frame |content_bounds|. 0 or greater.
58 void SetRoundedCornerRadius(int rounded_corner_radius);
59
Xiaodan Zhuc176db62022-01-25 01:47:1960 // Set shadow style.
61 void SetShadowStyle(gfx::ShadowStyle style);
62
Xiaodan Zhu6622a402023-07-12 01:59:5063 // Set customized key and ambient shadows color map for certain elevations.
64 void SetElevationToColorsMap(const ElevationToColorsMap& color_map);
65
David Reveman60c9b242017-11-28 02:24:5066 const gfx::ShadowDetails* details_for_testing() const { return details_; }
Xiaodan Zhub6919452023-09-11 17:59:2667 int rounded_corner_radius_for_testing() const {
68 return rounded_corner_radius_;
69 }
David Reveman60c9b242017-11-28 02:24:5070
[email protected]a8bd1cb2012-02-17 23:05:5471 // ui::ImplicitAnimationObserver overrides:
dchenga74e3542014-10-27 21:15:0572 void OnImplicitAnimationsCompleted() override;
[email protected]a8bd1cb2012-02-17 23:05:5473
[email protected]a54e65b2011-11-21 22:03:3474 private:
Ahmed Fakhryfc28da5f2019-07-30 18:05:3275 // A shadow layer owner that correctly updates the nine patch layer details
76 // when it gets recreated.
77 class ShadowLayerOwner : public ui::LayerOwner {
78 public:
79 explicit ShadowLayerOwner(Shadow* owner,
80 std::unique_ptr<Layer> layer = nullptr);
Peter Boströmc8c12352021-09-21 23:37:1581
82 ShadowLayerOwner(const ShadowLayerOwner&) = delete;
83 ShadowLayerOwner& operator=(const ShadowLayerOwner&) = delete;
84
Ahmed Fakhryfc28da5f2019-07-30 18:05:3285 ~ShadowLayerOwner() override;
86
87 // ui::LayerOwner:
88 std::unique_ptr<Layer> RecreateLayer() override;
89
90 private:
Keishi Hattori0e45c022021-11-27 09:25:5291 const raw_ptr<Shadow> owner_shadow_;
Ahmed Fakhryfc28da5f2019-07-30 18:05:3292 };
93
estadeba7b9d72017-01-04 20:06:0694 // Updates the shadow layer and its image to reflect |desired_elevation_|.
estade77932372016-12-12 23:31:4395 void RecreateShadowLayer();
[email protected]a8bd1cb2012-02-17 23:05:5496
Xiaodan Zhue1930d42023-07-18 17:51:0297 // Updates the shadow appearance based on the inteior inset, the current
98 // |content_bounds_|, shadow style, and colors.
99 void UpdateShadowAppearance();
[email protected]a8bd1cb2012-02-17 23:05:54100
estadeba7b9d72017-01-04 20:06:06101 // The goal elevation, set when the transition animation starts. The elevation
102 // dictates the shadow's display characteristics and is proportional to the
103 // size of the blur and its offset. This may not match reality if the window
104 // isn't big enough to support it.
Trent Apted280f4ff2018-02-07 07:11:53105 int desired_elevation_ = 0;
estaded1acf852016-12-07 20:23:20106
revemanc2ac3cdd2017-01-26 02:50:51107 // Rounded corners are drawn on top of the window's content layer,
108 // we need to exclude them from the occlusion area.
Trent Apted280f4ff2018-02-07 07:11:53109 int rounded_corner_radius_ = 2;
revemanc2ac3cdd2017-01-26 02:50:51110
Ahmed Fakhry349729742019-07-26 03:17:43111 // The details of the shadow image that's currently set on |shadow_layer()|.
David Reveman60c9b242017-11-28 02:24:50112 // This will be null until a positive elevation has been set. Once set, it
113 // will always point to a global ShadowDetails instance that is guaranteed
114 // to outlive the Shadow instance. See ui/gfx/shadow_util.h for how these
115 // ShadowDetails instances are created.
Paul Semel89e1f63c2023-06-19 13:34:10116 raw_ptr<const gfx::ShadowDetails, LeakedDanglingUntriaged> details_ = nullptr;
David Reveman60c9b242017-11-28 02:24:50117
Xiaodan Zhuc176db62022-01-25 01:47:19118 // The style of shadow. Use MD style by default.
119 gfx::ShadowStyle style_ = gfx::ShadowStyle::kMaterialDesign;
120
Xiaodan Zhu6622a402023-07-12 01:59:50121 // The customized key and ambient shadows color map for certain elevations.
122 ElevationToColorsMap color_map_;
123
Ahmed Fakhry349729742019-07-26 03:17:43124 // The owner of the actual shadow layer corresponding to a cc::NinePatchLayer.
Ahmed Fakhryfc28da5f2019-07-30 18:05:32125 ShadowLayerOwner shadow_layer_owner_;
[email protected]3ddb6822014-07-23 16:38:10126
estadeba7b9d72017-01-04 20:06:06127 // When the elevation changes, the old shadow cross-fades with the new one.
Ahmed Fakhry349729742019-07-26 03:17:43128 // When non-null, this owns an old |shadow_layer()| that's being animated out.
129 ui::LayerOwner fading_layer_owner_;
estade77932372016-12-12 23:31:43130
[email protected]a54e65b2011-11-21 22:03:34131 // Bounds of the content that the shadow encloses.
132 gfx::Rect content_bounds_;
Xiaodan Zhu9ab84d32023-08-02 05:09:51133
134 // The layer bounds since content bounds were last set.
135 gfx::Rect last_layer_bounds_;
[email protected]a54e65b2011-11-21 22:03:34136};
137
Tommy C. Li092c628a2018-03-29 20:32:15138} // namespace ui
[email protected]a54e65b2011-11-21 22:03:34139
Tommy C. Li092c628a2018-03-29 20:32:15140#endif // UI_COMPOSITOR_EXTRA_SHADOW_H_