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 "ui/wm/core/shadow.h" | 5 #include "ui/wm/core/shadow.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "ui/base/resource/resource_bundle.h" | 8 #include "ui/base/resource/resource_bundle.h" |
9 #include "ui/compositor/layer.h" | 9 #include "ui/compositor/layer.h" |
10 #include "ui/compositor/scoped_layer_animation_settings.h" | 10 #include "ui/compositor/scoped_layer_animation_settings.h" |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 UpdateLayerBounds(); | 123 UpdateLayerBounds(); |
124 } | 124 } |
125 | 125 |
126 void Shadow::RecreateShadowLayer() { | 126 void Shadow::RecreateShadowLayer() { |
127 shadow_layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH)); | 127 shadow_layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH)); |
128 shadow_layer_->set_name("Shadow"); | 128 shadow_layer_->set_name("Shadow"); |
129 shadow_layer_->SetVisible(true); | 129 shadow_layer_->SetVisible(true); |
130 shadow_layer_->SetFillsBoundsOpaquely(false); | 130 shadow_layer_->SetFillsBoundsOpaquely(false); |
131 layer()->Add(shadow_layer_.get()); | 131 layer()->Add(shadow_layer_.get()); |
132 | 132 |
133 const ShadowDetails& details = GetDetailsForElevation(ElevationForStyle()); | |
134 shadow_layer_->UpdateNinePatchLayerImage(details.ninebox_image); | |
135 UpdateLayerBounds(); | 133 UpdateLayerBounds(); |
136 } | 134 } |
137 | 135 |
138 void Shadow::UpdateLayerBounds() { | 136 void Shadow::UpdateLayerBounds() { |
139 const ShadowDetails& details = GetDetailsForElevation(ElevationForStyle()); | 137 if (content_bounds_.IsEmpty()) |
138 return; | |
139 | |
140 // The elevation depends on the style, but the ninebox assumption breaks down | |
141 // when the window is too small. The height/width of |blur_region| will be | |
142 // 4 * elevation (see GetDetailsForElevation), so cap elevation at the most we | |
143 // can handle. | |
144 int size_adjusted_elevation = | |
145 std::min((std::min(content_bounds_.width(), content_bounds_.height()) - | |
146 2 * kRoundedCornerRadius) / | |
James Cook
2016/12/19 19:51:49
nit: wrapping is really ugly here. Maybe try pulli
Evan Stade
2016/12/19 21:09:41
Done.
| |
147 4, | |
148 ElevationForStyle()); | |
149 const ShadowDetails& details = | |
150 GetDetailsForElevation(size_adjusted_elevation); | |
151 gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) + | |
152 gfx::Insets(kRoundedCornerRadius); | |
153 if (size_adjusted_elevation != effective_elevation_) { | |
154 shadow_layer_->UpdateNinePatchLayerImage(details.ninebox_image); | |
155 // 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 | |
157 // the aperture goes further inside the image than the shadow margins (which | |
158 // represent exterior blur). | |
159 gfx::Rect aperture(details.ninebox_image.size()); | |
160 aperture.Inset(blur_region); | |
161 shadow_layer_->UpdateNinePatchLayerAperture(aperture); | |
162 } | |
163 effective_elevation_ = size_adjusted_elevation; | |
164 | |
140 // Shadow margins are negative, so this expands outwards from | 165 // Shadow margins are negative, so this expands outwards from |
141 // |content_bounds_|. | 166 // |content_bounds_|. |
142 const gfx::Insets margins = gfx::ShadowValue::GetMargin(details.values); | 167 const gfx::Insets margins = gfx::ShadowValue::GetMargin(details.values); |
143 gfx::Rect new_layer_bounds = content_bounds_; | 168 gfx::Rect new_layer_bounds = content_bounds_; |
144 new_layer_bounds.Inset(margins); | 169 new_layer_bounds.Inset(margins); |
145 gfx::Rect shadow_layer_bounds(new_layer_bounds.size()); | 170 gfx::Rect shadow_layer_bounds(new_layer_bounds.size()); |
146 | 171 |
147 // When there's an old shadow fading out, the bounds of layer() have to be | 172 // When there's an old shadow fading out, the bounds of layer() have to be |
148 // big enough to encompass both shadows. | 173 // big enough to encompass both shadows. |
149 if (fading_layer_) { | 174 if (fading_layer_) { |
(...skipping 17 matching lines...) Expand all Loading... | |
167 } | 192 } |
168 | 193 |
169 shadow_layer_->SetBounds(shadow_layer_bounds); | 194 shadow_layer_->SetBounds(shadow_layer_bounds); |
170 | 195 |
171 // Occlude the region inside the bounding box. Occlusion uses shadow layer | 196 // Occlude the region inside the bounding box. Occlusion uses shadow layer |
172 // space. See nine_patch_layer.h for more context on what's going on here. | 197 // space. See nine_patch_layer.h for more context on what's going on here. |
173 gfx::Rect occlusion_bounds(shadow_layer_bounds.size()); | 198 gfx::Rect occlusion_bounds(shadow_layer_bounds.size()); |
174 occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius)); | 199 occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius)); |
175 shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds); | 200 shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds); |
176 | 201 |
177 // The border is more or less the same inset as the aperture, but can be no | 202 // The border is the same inset as the aperture. |
178 // larger than the shadow layer. When the shadow layer is too small, shrink | |
179 // the dimensions proportionally. | |
180 gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) + | |
181 gfx::Insets(kRoundedCornerRadius); | |
182 int border_w = std::min(blur_region.width(), shadow_layer_bounds.width()); | |
183 int border_x = border_w * blur_region.left() / blur_region.width(); | |
184 int border_h = std::min(blur_region.height(), shadow_layer_bounds.height()); | |
185 int border_y = border_h * blur_region.top() / blur_region.height(); | |
186 shadow_layer_->UpdateNinePatchLayerBorder( | 203 shadow_layer_->UpdateNinePatchLayerBorder( |
187 gfx::Rect(border_x, border_y, border_w, border_h)); | 204 gfx::Rect(blur_region.left(), blur_region.top(), blur_region.width(), |
188 | 205 blur_region.height())); |
189 // The ninebox grid is defined in terms of the image size. The shadow blurs in | |
190 // both inward and outward directions from the edge of the contents, so the | |
191 // aperture goes further inside the image than the shadow margins (which | |
192 // represent exterior blur). | |
193 gfx::Rect aperture(details.ninebox_image.size()); | |
194 // The insets for the aperture are nominally |blur_region| but we need to | |
195 // resize them if the contents are too small. | |
196 // TODO(estade): by cutting out parts of ninebox, we lose the smooth | |
197 // horizontal or vertical transition. This isn't very noticeable, but we may | |
198 // need to address it by using a separate shadow layer for each ShadowValue, | |
199 // by adjusting the shadow for very small windows, or other means. | |
200 aperture.Inset(gfx::Insets(border_y, border_x, border_h - border_y, | |
201 border_w - border_x)); | |
202 shadow_layer_->UpdateNinePatchLayerAperture(aperture); | |
203 } | 206 } |
204 | 207 |
205 int Shadow::ElevationForStyle() { | 208 int Shadow::ElevationForStyle() { |
206 switch (style_) { | 209 switch (style_) { |
207 case STYLE_ACTIVE: | 210 case STYLE_ACTIVE: |
208 return 24; | 211 return 24; |
209 case STYLE_INACTIVE: | 212 case STYLE_INACTIVE: |
210 return 8; | 213 return 8; |
211 case STYLE_SMALL: | 214 case STYLE_SMALL: |
212 return 6; | 215 return 6; |
213 } | 216 } |
214 NOTREACHED(); | 217 NOTREACHED(); |
215 return 0; | 218 return 0; |
216 } | 219 } |
217 | 220 |
218 } // namespace wm | 221 } // namespace wm |
OLD | NEW |