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

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

Issue 2586653002: Improve CrOS WM shadow drawing for small windows. (Closed)
Patch Set: wrapping 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 const int smaller_dimension =
145 std::min(content_bounds_.width(), content_bounds_.height());
146 const int size_adjusted_elevation = std::min(
147 (smaller_dimension - 2 * kRoundedCornerRadius) / 4, ElevationForStyle());
148 const ShadowDetails& details =
149 GetDetailsForElevation(size_adjusted_elevation);
150 gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) +
151 gfx::Insets(kRoundedCornerRadius);
152 if (size_adjusted_elevation != effective_elevation_) {
153 shadow_layer_->UpdateNinePatchLayerImage(details.ninebox_image);
154 // The ninebox grid is defined in terms of the image size. The shadow blurs
155 // in both inward and outward directions from the edge of the contents, so
156 // the aperture goes further inside the image than the shadow margins (which
157 // represent exterior blur).
158 gfx::Rect aperture(details.ninebox_image.size());
159 aperture.Inset(blur_region);
160 shadow_layer_->UpdateNinePatchLayerAperture(aperture);
161 }
162 effective_elevation_ = size_adjusted_elevation;
163
140 // Shadow margins are negative, so this expands outwards from 164 // Shadow margins are negative, so this expands outwards from
141 // |content_bounds_|. 165 // |content_bounds_|.
142 const gfx::Insets margins = gfx::ShadowValue::GetMargin(details.values); 166 const gfx::Insets margins = gfx::ShadowValue::GetMargin(details.values);
143 gfx::Rect new_layer_bounds = content_bounds_; 167 gfx::Rect new_layer_bounds = content_bounds_;
144 new_layer_bounds.Inset(margins); 168 new_layer_bounds.Inset(margins);
145 gfx::Rect shadow_layer_bounds(new_layer_bounds.size()); 169 gfx::Rect shadow_layer_bounds(new_layer_bounds.size());
146 170
147 // When there's an old shadow fading out, the bounds of layer() have to be 171 // When there's an old shadow fading out, the bounds of layer() have to be
148 // big enough to encompass both shadows. 172 // big enough to encompass both shadows.
149 if (fading_layer_) { 173 if (fading_layer_) {
(...skipping 17 matching lines...) Expand all
167 } 191 }
168 192
169 shadow_layer_->SetBounds(shadow_layer_bounds); 193 shadow_layer_->SetBounds(shadow_layer_bounds);
170 194
171 // Occlude the region inside the bounding box. Occlusion uses shadow layer 195 // 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. 196 // space. See nine_patch_layer.h for more context on what's going on here.
173 gfx::Rect occlusion_bounds(shadow_layer_bounds.size()); 197 gfx::Rect occlusion_bounds(shadow_layer_bounds.size());
174 occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius)); 198 occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius));
175 shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds); 199 shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds);
176 200
177 // The border is more or less the same inset as the aperture, but can be no 201 // 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( 202 shadow_layer_->UpdateNinePatchLayerBorder(
187 gfx::Rect(border_x, border_y, border_w, border_h)); 203 gfx::Rect(blur_region.left(), blur_region.top(), blur_region.width(),
188 204 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 } 205 }
204 206
205 int Shadow::ElevationForStyle() { 207 int Shadow::ElevationForStyle() {
206 switch (style_) { 208 switch (style_) {
207 case STYLE_ACTIVE: 209 case STYLE_ACTIVE:
208 return 24; 210 return 24;
209 case STYLE_INACTIVE: 211 case STYLE_INACTIVE:
210 return 8; 212 return 8;
211 case STYLE_SMALL: 213 case STYLE_SMALL:
212 return 6; 214 return 6;
213 } 215 }
214 NOTREACHED(); 216 NOTREACHED();
215 return 0; 217 return 0;
216 } 218 }
217 219
218 } // namespace wm 220 } // 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