Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: ui/wm/core/shadow.cc

Issue 2589163003: Add shadow/corner radius to notifications (toasts and in-center). (Closed)
Patch Set: sky reviews Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/border.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "ui/wm/core/shadow.h" 5 #include "ui/wm/core/shadow.h"
6 6
7 #include "base/lazy_instance.h"
8 #include "ui/base/resource/resource_bundle.h" 7 #include "ui/base/resource/resource_bundle.h"
9 #include "ui/compositor/layer.h" 8 #include "ui/compositor/layer.h"
10 #include "ui/compositor/scoped_layer_animation_settings.h" 9 #include "ui/compositor/scoped_layer_animation_settings.h"
11 #include "ui/gfx/geometry/insets.h" 10 #include "ui/gfx/geometry/insets.h"
12 #include "ui/gfx/image/image_skia_operations.h" 11 #include "ui/gfx/shadow_util.h"
13 #include "ui/wm/core/shadow_types.h" 12 #include "ui/wm/core/shadow_types.h"
14 13
15 namespace wm { 14 namespace wm {
16 15
17 namespace { 16 namespace {
18 17
19 // Rounded corners are overdrawn on top of the window's content layer, 18 // Rounded corners are overdrawn on top of the window's content layer,
20 // we need to exclude them from the occlusion area. 19 // we need to exclude them from the occlusion area.
21 const int kRoundedCornerRadius = 2; 20 const int kRoundedCornerRadius = 2;
22 21
23 // Duration for opacity animation in milliseconds. 22 // Duration for opacity animation in milliseconds.
24 const int kShadowAnimationDurationMs = 100; 23 const int kShadowAnimationDurationMs = 100;
25 24
26 struct ShadowDetails {
27 // Description of the shadows.
28 gfx::ShadowValues values;
29 // Cached ninebox image based on |values|.
30 gfx::ImageSkia ninebox_image;
31 };
32
33 // Map from elevation to a cached shadow.
34 using ShadowDetailsMap = std::map<int, ShadowDetails>;
35 base::LazyInstance<ShadowDetailsMap> g_shadow_cache = LAZY_INSTANCE_INITIALIZER;
36
37 const ShadowDetails& GetDetailsForElevation(int elevation) {
38 auto iter = g_shadow_cache.Get().find(elevation);
39 if (iter != g_shadow_cache.Get().end())
40 return iter->second;
41
42 auto insertion =
43 g_shadow_cache.Get().insert(std::make_pair(elevation, ShadowDetails()));
44 DCHECK(insertion.second);
45 ShadowDetails* shadow = &insertion.first->second;
46 // To match the CSS notion of blur (spread outside the bounding box) to the
47 // Skia notion of blur (spread outside and inside the bounding box), we have
48 // to double the designer-provided blur values.
49 const int kBlurCorrection = 2;
50 // "Key shadow": y offset is elevation and blur is twice the elevation.
51 shadow->values.emplace_back(gfx::Vector2d(0, elevation),
52 kBlurCorrection * elevation * 2,
53 SkColorSetA(SK_ColorBLACK, 0x3d));
54 // "Ambient shadow": no offset and blur matches the elevation.
55 shadow->values.emplace_back(gfx::Vector2d(), kBlurCorrection * elevation,
56 SkColorSetA(SK_ColorBLACK, 0x1f));
57 // To see what this looks like for elevation 24, try this CSS:
58 // box-shadow: 0 24px 48px rgba(0, 0, 0, .24),
59 // 0 0 24px rgba(0, 0, 0, .12);
60 shadow->ninebox_image = gfx::ImageSkiaOperations::CreateShadowNinebox(
61 shadow->values, kRoundedCornerRadius);
62 return *shadow;
63 }
64
65 } // namespace 25 } // namespace
66 26
67 Shadow::Shadow() : desired_elevation_(ShadowElevation::NONE) {} 27 Shadow::Shadow() : desired_elevation_(ShadowElevation::NONE) {}
68 28
69 Shadow::~Shadow() {} 29 Shadow::~Shadow() {}
70 30
71 void Shadow::Init(ShadowElevation elevation) { 31 void Shadow::Init(ShadowElevation elevation) {
72 desired_elevation_ = elevation; 32 desired_elevation_ = elevation;
73 layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN)); 33 layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN));
74 RecreateShadowLayer(); 34 RecreateShadowLayer();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 93
134 UpdateLayerBounds(); 94 UpdateLayerBounds();
135 } 95 }
136 96
137 void Shadow::UpdateLayerBounds() { 97 void Shadow::UpdateLayerBounds() {
138 if (content_bounds_.IsEmpty()) 98 if (content_bounds_.IsEmpty())
139 return; 99 return;
140 100
141 // The ninebox assumption breaks down when the window is too small for the 101 // The ninebox assumption breaks down when the window is too small for the
142 // desired elevation. The height/width of |blur_region| will be 4 * elevation 102 // desired elevation. The height/width of |blur_region| will be 4 * elevation
143 // (see GetDetailsForElevation), so cap elevation at the most we can handle. 103 // (see ShadowDetails::Get), so cap elevation at the most we can handle.
144 const int smaller_dimension = 104 const int smaller_dimension =
145 std::min(content_bounds_.width(), content_bounds_.height()); 105 std::min(content_bounds_.width(), content_bounds_.height());
146 const int size_adjusted_elevation = 106 const int size_adjusted_elevation =
147 std::min((smaller_dimension - 2 * kRoundedCornerRadius) / 4, 107 std::min((smaller_dimension - 2 * kRoundedCornerRadius) / 4,
148 static_cast<int>(desired_elevation_)); 108 static_cast<int>(desired_elevation_));
149 const ShadowDetails& details = 109 const auto& details =
150 GetDetailsForElevation(size_adjusted_elevation); 110 gfx::ShadowDetails::Get(size_adjusted_elevation, kRoundedCornerRadius);
151 gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) + 111 gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) +
152 gfx::Insets(kRoundedCornerRadius); 112 gfx::Insets(kRoundedCornerRadius);
153 if (size_adjusted_elevation != effective_elevation_) { 113 if (size_adjusted_elevation != effective_elevation_) {
154 shadow_layer_->UpdateNinePatchLayerImage(details.ninebox_image); 114 shadow_layer_->UpdateNinePatchLayerImage(details.ninebox_image);
155 // The ninebox grid is defined in terms of the image size. The shadow blurs 115 // The ninebox grid is defined in terms of the image size. The shadow blurs
156 // in both inward and outward directions from the edge of the contents, so 116 // in both inward and outward directions from the edge of the contents, so
157 // the aperture goes further inside the image than the shadow margins (which 117 // the aperture goes further inside the image than the shadow margins (which
158 // represent exterior blur). 118 // represent exterior blur).
159 gfx::Rect aperture(details.ninebox_image.size()); 119 gfx::Rect aperture(details.ninebox_image.size());
160 aperture.Inset(blur_region); 120 aperture.Inset(blur_region);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius)); 159 occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius));
200 shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds); 160 shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds);
201 161
202 // The border is the same inset as the aperture. 162 // The border is the same inset as the aperture.
203 shadow_layer_->UpdateNinePatchLayerBorder( 163 shadow_layer_->UpdateNinePatchLayerBorder(
204 gfx::Rect(blur_region.left(), blur_region.top(), blur_region.width(), 164 gfx::Rect(blur_region.left(), blur_region.top(), blur_region.width(),
205 blur_region.height())); 165 blur_region.height()));
206 } 166 }
207 167
208 } // namespace wm 168 } // namespace wm
OLDNEW
« no previous file with comments | « ui/views/border.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698