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

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

Issue 2586653002: Improve CrOS WM shadow drawing for small windows. (Closed)
Patch Set: . Created 4 years 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/wm/core/shadow.h ('k') | ui/wm/core/shadow_unittest.cc » ('j') | 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" 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
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
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
OLDNEW
« no previous file with comments | « ui/wm/core/shadow.h ('k') | ui/wm/core/shadow_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698