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

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

Issue 2550593002: Update WM shadows for MD. (Closed)
Patch Set: fix corners 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
Index: ui/wm/core/shadow.cc
diff --git a/ui/wm/core/shadow.cc b/ui/wm/core/shadow.cc
index 78853435c6cc81720b66c08c0bf0c2268b8b885b..eda7f78f2ecd201302915aa11d6ef7ce89f756bf 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,43 @@ 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;
+struct ShadowDetails {
+ gfx::ShadowValues values;
+ gfx::ImageSkia image;
James Cook 2016/12/05 23:38:35 nit: document either here or above struct what thi
Evan Stade 2016/12/06 00:53:21 Done.
+};
+
+// Map from elevation to a cached shadow.
+typedef std::map<int, ShadowDetails> ShadowDetailsMap;
+base::LazyInstance<ShadowDetailsMap> g_shadow_cache = LAZY_INSTANCE_INITIALIZER;
+
+const ShadowDetails& GetDetailsForElevation(int elevation) {
+ auto insertion =
+ g_shadow_cache.Get().insert(std::make_pair(elevation, ShadowDetails()));
James Cook 2016/12/05 23:38:35 optional: would emplace work here?
Evan Stade 2016/12/06 00:53:21 yes it would if map::emplace were allowed :~( "st
James Cook 2016/12/06 18:17:51 I learned something new today!
+ ShadowDetails* shadow = &insertion.first->second;
+ // If there was an insertion, initialize the new ShadowDetails.
+ if (insertion.second) {
James Cook 2016/12/05 23:38:35 I think this would be clearer if it did std::map::
Evan Stade 2016/12/06 00:53:21 Done.
+ // 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));
+ shadow->image = gfx::ImageSkiaOperations::CreateShadowNinebox(
+ shadow->values, kRoundedCornerRadius);
}
- return 0;
+ return *shadow;
}
} // namespace
-namespace wm {
+Shadow::Shadow() : style_(STYLE_ACTIVE) {}
James Cook 2016/12/05 23:38:35 optional: init in header?
Evan Stade 2016/12/06 00:53:21 Done.
-Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) {
-}
-
-Shadow::~Shadow() {
-}
+Shadow::~Shadow() {}
void Shadow::Init(Style style) {
style_ = style;
@@ -149,59 +144,53 @@ 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);
James Cook 2016/12/05 23:38:35 Can you file a bug about updating Mustash to use t
Evan Stade 2016/12/06 00:53:21 Done.
- 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.image);
UpdateLayerBounds();
}
void Shadow::UpdateLayerBounds() {
- // Update bounds based on content bounds and interior inset.
+ const ShadowDetails& details = GetDetailsForElevation(ElevationForStyle());
+ const gfx::Insets margins = gfx::ShadowValue::GetMargin(details.values);
James Cook 2016/12/05 23:38:35 nit: maybe comment that these insets push the boun
Evan Stade 2016/12/06 00:53:21 done
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);
- 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 shadow_layer_bounds(layer_bounds.size());
+ shadow_layer_->SetBounds(shadow_layer_bounds);
+
+ // Occlude the region inside the bounding box. Occlusion uses shadow layer
+ // space.
+ gfx::Rect occlusion_bounds = shadow_layer_bounds;
+ occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius));
+ shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds);
+
+ // The ninebox grid is defined in terms of the image size. We have to take
+ // into account the inner blur as well as outer blur and offset.
+ gfx::Rect aperture(details.image.size());
+ gfx::Insets blur_region = gfx::ShadowValue::GetBlurRegion(details.values) +
+ gfx::Insets(kRoundedCornerRadius);
+ aperture.Inset(blur_region);
+ shadow_layer_->UpdateNinePatchLayerAperture(aperture);
+
+ // The border is more or less the same inset as the aperture, but can be no
+ // larger than the shadow layer.
+ gfx::Rect border_rect(blur_region.left(), blur_region.top(),
+ blur_region.width(), blur_region.height());
+ border_rect.ClampToCenteredSize(shadow_layer_bounds.size());
+ shadow_layer_->UpdateNinePatchLayerBorder(border_rect);
+}
James Cook 2016/12/05 23:38:35 I'm having a hard time following this function. Ma
Evan Stade 2016/12/06 00:53:21 no kidding. Figuring this out cost me a lot of hai
James Cook 2016/12/06 18:17:51 The new docs here help. I think adding a note abou
Evan Stade 2016/12/07 01:56:42 done, except included a CSS snippet instead of the
+
+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

Powered by Google App Engine
This is Rietveld 408576698