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

Unified Diff: ui/wm/core/shadow.cc

Issue 2550593002: Update WM shadows for MD. (Closed)
Patch Set: fix border for small windows 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/wm/core/shadow.cc
diff --git a/ui/wm/core/shadow.cc b/ui/wm/core/shadow.cc
index 78853435c6cc81720b66c08c0bf0c2268b8b885b..83190954208d81601426d32d89684697b7b71fb6 100644
--- a/ui/wm/core/shadow.cc
+++ b/ui/wm/core/shadow.cc
@@ -4,11 +4,14 @@
#include "ui/wm/core/shadow.h"
-#include "third_party/skia/include/core/SkBitmap.h"
+#include "base/lazy_instance.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/resources/grit/ui_resources.h"
+#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/image/image_skia_operations.h"
+
+namespace wm {
namespace {
@@ -16,18 +19,6 @@ namespace {
// inactive/active shadow.
const float kInactiveShadowAnimationOpacity = 0.2f;
-// Shadow aperture for different styles.
-// Note that this may be greater than interior inset to allow shadows with
-// curved corners that extend inwards beyond a window's borders.
-const int kActiveInteriorAperture = 134;
-const int kInactiveInteriorAperture = 134;
-const int kSmallInteriorAperture = 9;
-
-// Interior inset for different styles.
-const int kActiveInteriorInset = 64;
-const int kInactiveInteriorInset = 64;
-const int kSmallInteriorInset = 4;
-
// Rounded corners are overdrawn on top of the window's content layer,
// we need to exclude them from the occlusion area.
const int kRoundedCornerRadius = 2;
@@ -35,39 +26,50 @@ const int kRoundedCornerRadius = 2;
// Duration for opacity animation in milliseconds.
const int kShadowAnimationDurationMs = 100;
-int GetShadowApertureForStyle(wm::Shadow::Style style) {
- switch (style) {
- case wm::Shadow::STYLE_ACTIVE:
- return kActiveInteriorAperture;
- case wm::Shadow::STYLE_INACTIVE:
- return kInactiveInteriorAperture;
- case wm::Shadow::STYLE_SMALL:
- return kSmallInteriorAperture;
- }
- return 0;
-}
-
-int GetInteriorInsetForStyle(wm::Shadow::Style style) {
- switch (style) {
- case wm::Shadow::STYLE_ACTIVE:
- return kActiveInteriorInset;
- case wm::Shadow::STYLE_INACTIVE:
- return kInactiveInteriorInset;
- case wm::Shadow::STYLE_SMALL:
- return kSmallInteriorInset;
- }
- return 0;
+struct ShadowDetails {
+ // Description of the shadows.
+ gfx::ShadowValues values;
+ // Cached ninebox image based on |values|.
+ gfx::ImageSkia ninebox_image;
+};
+
+// Map from elevation to a cached shadow.
+using ShadowDetailsMap = std::map<int, ShadowDetails>;
+base::LazyInstance<ShadowDetailsMap> g_shadow_cache = LAZY_INSTANCE_INITIALIZER;
+
+const ShadowDetails& GetDetailsForElevation(int elevation) {
+ auto iter = g_shadow_cache.Get().find(elevation);
+ if (iter != g_shadow_cache.Get().end())
+ return iter->second;
+
+ auto insertion =
+ g_shadow_cache.Get().insert(std::make_pair(elevation, ShadowDetails()));
+ DCHECK(insertion.second);
+ ShadowDetails* shadow = &insertion.first->second;
+ // To match the CSS notion of blur (spread outside the bounding box) to the
+ // Skia notion of blur (spread outside and inside the bounding box), we have
+ // to double the designer-provided blur values.
+ const int kBlurCorrection = 2;
+ // "Key shadow": y offset is elevation and blur is twice the elevation.
+ shadow->values.emplace_back(gfx::Vector2d(0, elevation),
+ kBlurCorrection * elevation * 2,
+ SkColorSetA(SK_ColorBLACK, 0x3d));
+ // "Ambient shadow": no offset and blur matches the elevation.
+ shadow->values.emplace_back(gfx::Vector2d(), kBlurCorrection * elevation,
+ SkColorSetA(SK_ColorBLACK, 0x1f));
+ // To see what this looks like for elevation 24, try this CSS:
+ // box-shadow: 0 24px 48px rgba(0, 0, 0, .24),
+ // 0 0 24px rgba(0, 0, 0, .12);
+ shadow->ninebox_image = gfx::ImageSkiaOperations::CreateShadowNinebox(
+ shadow->values, kRoundedCornerRadius);
+ return *shadow;
}
} // namespace
-namespace wm {
+Shadow::Shadow() {}
-Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) {
-}
-
-Shadow::~Shadow() {
-}
+Shadow::~Shadow() {}
void Shadow::Init(Style style) {
style_ = style;
@@ -149,59 +151,61 @@ void Shadow::OnImplicitAnimationsCompleted() {
}
void Shadow::UpdateImagesForStyle() {
- ResourceBundle& res = ResourceBundle::GetSharedInstance();
- gfx::Image image;
- switch (style_) {
- case STYLE_ACTIVE:
- image = res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE);
- break;
- case STYLE_INACTIVE:
- image = res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE);
- break;
- case STYLE_SMALL:
- image = res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL);
- break;
- default:
- NOTREACHED() << "Unhandled style " << style_;
- break;
- }
-
- shadow_layer_->UpdateNinePatchLayerImage(image.AsImageSkia());
- image_size_ = image.Size();
- interior_inset_ = GetInteriorInsetForStyle(style_);
-
- // Image sizes may have changed.
+ const ShadowDetails& details = GetDetailsForElevation(ElevationForStyle());
+ shadow_layer_->UpdateNinePatchLayerImage(details.ninebox_image);
+ // The ninebox grid is defined in terms of the image size. The shadow blurs in
+ // both inward and outward directions from the edge of the contents, so the
+ // aperture goes further inside the image than the shadow margins (which
+ // represent exterior blur).
+ gfx::Rect aperture(details.ninebox_image.size());
+ gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) +
+ gfx::Insets(kRoundedCornerRadius);
+ aperture.Inset(blur_region);
+ shadow_layer_->UpdateNinePatchLayerAperture(aperture);
UpdateLayerBounds();
}
void Shadow::UpdateLayerBounds() {
- // Update bounds based on content bounds and interior inset.
+ const ShadowDetails& details = GetDetailsForElevation(ElevationForStyle());
+ // Shadow margins are negative, so this expands outwards from
+ // |content_bounds_|.
+ const gfx::Insets margins = gfx::ShadowValue::GetMargin(details.values);
gfx::Rect layer_bounds = content_bounds_;
- layer_bounds.Inset(-interior_inset_, -interior_inset_);
+ layer_bounds.Inset(margins);
layer()->SetBounds(layer_bounds);
- shadow_layer_->SetBounds(gfx::Rect(layer_bounds.size()));
-
- // Update the shadow aperture and border for style. Note that border is in
- // layer space and it cannot exceed the bounds of the layer.
- int aperture = GetShadowApertureForStyle(style_);
- int aperture_x = std::min(aperture, layer_bounds.width() / 2);
- int aperture_y = std::min(aperture, layer_bounds.height() / 2);
- gfx::Rect aperture_rect(aperture_x, aperture_y,
- image_size_.width() - aperture_x * 2,
- image_size_.height() - aperture_y * 2);
-
- shadow_layer_->UpdateNinePatchLayerAperture(aperture_rect);
+ const gfx::Rect shadow_layer_bounds(layer_bounds.size());
+ shadow_layer_->SetBounds(shadow_layer_bounds);
+
+ // Occlude the region inside the bounding box. Occlusion uses shadow layer
+ // space. See nine_patch_layer.h for more context on what's going on here.
+ gfx::Rect occlusion_bounds = shadow_layer_bounds;
+ occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius));
+ shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds);
+
+ // The border is more or less the same inset as the aperture, but can be no
+ // larger than the shadow layer. When the shadow layer is too small, shrink
+ // the dimensions proportionally.
+ gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) +
+ gfx::Insets(kRoundedCornerRadius);
+ int border_w = std::min(blur_region.width(), shadow_layer_bounds.width());
+ int border_x = border_w * blur_region.left() / blur_region.width();
+ int border_h = std::min(blur_region.height(), shadow_layer_bounds.height());
+ int border_y = border_h * blur_region.top() / blur_region.height();
shadow_layer_->UpdateNinePatchLayerBorder(
- gfx::Rect(aperture_x, aperture_y, aperture_x * 2, aperture_y * 2));
-
- // The content bounds in the shadow's layer space are offsetted by
- // |interior_inset_|. The occlusion area also has to be shrunk to allow
- // rounded corners overdrawing on top of the window's content.
- gfx::Rect content_bounds(interior_inset_ + kRoundedCornerRadius,
- interior_inset_ + kRoundedCornerRadius,
- content_bounds_.width() - 2 * kRoundedCornerRadius,
- content_bounds_.height() - 2 * kRoundedCornerRadius);
- shadow_layer_->UpdateNinePatchOcclusion(content_bounds);
+ gfx::Rect(border_x, border_y, border_w, border_h));
+}
+
+int Shadow::ElevationForStyle() {
+ switch (style_) {
+ case STYLE_ACTIVE:
+ return 24;
+ case STYLE_INACTIVE:
+ return 8;
+ case STYLE_SMALL:
+ return 6;
+ }
+ NOTREACHED();
+ return 0;
}
} // namespace wm
« 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