Chromium Code Reviews| 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 "grit/ui_resources.h" | 7 #include "grit/ui_resources.h" |
| 8 #include "third_party/skia/include/core/SkBitmap.h" | |
| 8 #include "ui/base/resource/resource_bundle.h" | 9 #include "ui/base/resource/resource_bundle.h" |
| 10 #include "ui/compositor/layer.h" | |
| 9 #include "ui/compositor/scoped_layer_animation_settings.h" | 11 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 10 #include "ui/wm/core/image_grid.h" | |
| 11 | 12 |
| 12 namespace { | 13 namespace { |
| 13 | 14 |
| 14 // Shadow opacity for different styles. | 15 // Shadow opacity for different styles. |
| 15 const float kActiveShadowOpacity = 1.0f; | 16 const float kActiveShadowOpacity = 1.0f; |
| 16 const float kInactiveShadowOpacity = 0.2f; | 17 const float kInactiveShadowOpacity = 0.2f; |
| 17 const float kSmallShadowOpacity = 1.0f; | 18 const float kSmallShadowOpacity = 1.0f; |
| 18 | 19 |
| 20 // Shadow aperture for different styles. | |
|
oshima
2014/07/11 23:03:41
can you add comment that why we're using different
hshi1
2014/07/11 23:18:03
Done.
| |
| 21 const int kActiveInteriorAperture = 134; | |
| 22 const int kInactiveInteriorAperture = 134; | |
| 23 const int kSmallInteriorAperture = 9; | |
| 24 | |
| 19 // Interior inset for different styles. | 25 // Interior inset for different styles. |
| 20 const int kActiveInteriorInset = 0; | 26 const int kActiveInteriorInset = 64; |
| 21 const int kInactiveInteriorInset = 0; | 27 const int kInactiveInteriorInset = 64; |
| 22 const int kSmallInteriorInset = 5; | 28 const int kSmallInteriorInset = 4; |
| 23 | 29 |
| 24 // Duration for opacity animation in milliseconds. | 30 // Duration for opacity animation in milliseconds. |
| 25 const int kShadowAnimationDurationMs = 100; | 31 const int kShadowAnimationDurationMs = 100; |
| 26 | 32 |
| 27 float GetOpacityForStyle(wm::Shadow::Style style) { | 33 float GetOpacityForStyle(wm::Shadow::Style style) { |
| 28 switch (style) { | 34 switch (style) { |
| 29 case wm::Shadow::STYLE_ACTIVE: | 35 case wm::Shadow::STYLE_ACTIVE: |
| 30 return kActiveShadowOpacity; | 36 return kActiveShadowOpacity; |
| 31 case wm::Shadow::STYLE_INACTIVE: | 37 case wm::Shadow::STYLE_INACTIVE: |
| 32 return kInactiveShadowOpacity; | 38 return kInactiveShadowOpacity; |
| 33 case wm::Shadow::STYLE_SMALL: | 39 case wm::Shadow::STYLE_SMALL: |
| 34 return kSmallShadowOpacity; | 40 return kSmallShadowOpacity; |
| 35 } | 41 } |
| 36 return 1.0f; | 42 return 1.0f; |
| 37 } | 43 } |
| 38 | 44 |
| 45 int GetShadowApertureForStyle(wm::Shadow::Style style) { | |
| 46 switch (style) { | |
| 47 case wm::Shadow::STYLE_ACTIVE: | |
| 48 return kActiveInteriorAperture; | |
| 49 case wm::Shadow::STYLE_INACTIVE: | |
| 50 return kInactiveInteriorAperture; | |
| 51 case wm::Shadow::STYLE_SMALL: | |
| 52 return kSmallInteriorAperture; | |
| 53 } | |
| 54 return 0; | |
| 55 } | |
| 56 | |
| 39 int GetInteriorInsetForStyle(wm::Shadow::Style style) { | 57 int GetInteriorInsetForStyle(wm::Shadow::Style style) { |
| 40 switch (style) { | 58 switch (style) { |
| 41 case wm::Shadow::STYLE_ACTIVE: | 59 case wm::Shadow::STYLE_ACTIVE: |
| 42 return kActiveInteriorInset; | 60 return kActiveInteriorInset; |
| 43 case wm::Shadow::STYLE_INACTIVE: | 61 case wm::Shadow::STYLE_INACTIVE: |
| 44 return kInactiveInteriorInset; | 62 return kInactiveInteriorInset; |
| 45 case wm::Shadow::STYLE_SMALL: | 63 case wm::Shadow::STYLE_SMALL: |
| 46 return kSmallInteriorInset; | 64 return kSmallInteriorInset; |
| 47 } | 65 } |
| 48 return 0; | 66 return 0; |
| 49 } | 67 } |
| 50 | 68 |
| 51 } // namespace | 69 } // namespace |
| 52 | 70 |
| 53 namespace wm { | 71 namespace wm { |
| 54 | 72 |
| 55 Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) { | 73 Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) { |
| 56 } | 74 } |
| 57 | 75 |
| 58 Shadow::~Shadow() { | 76 Shadow::~Shadow() { |
| 59 } | 77 } |
| 60 | 78 |
| 61 void Shadow::Init(Style style) { | 79 void Shadow::Init(Style style) { |
| 62 style_ = style; | 80 style_ = style; |
| 63 image_grid_.reset(new ImageGrid); | 81 |
| 82 layer_.reset(new ui::Layer()); | |
| 83 layer()->SetShowNinePatch(); | |
| 64 UpdateImagesForStyle(); | 84 UpdateImagesForStyle(); |
| 65 image_grid_->layer()->set_name("Shadow"); | 85 layer()->set_name("Shadow"); |
| 66 image_grid_->layer()->SetOpacity(GetOpacityForStyle(style_)); | 86 layer()->SetVisible(true); |
| 87 layer()->SetOpacity(GetOpacityForStyle(style_)); | |
| 67 } | 88 } |
| 68 | 89 |
| 69 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) { | 90 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) { |
| 70 content_bounds_ = content_bounds; | 91 content_bounds_ = content_bounds; |
| 71 UpdateImageGridBounds(); | 92 UpdateImageBounds(); |
| 72 } | |
| 73 | |
| 74 ui::Layer* Shadow::layer() const { | |
| 75 return image_grid_->layer(); | |
| 76 } | 93 } |
| 77 | 94 |
| 78 void Shadow::SetStyle(Style style) { | 95 void Shadow::SetStyle(Style style) { |
| 79 if (style_ == style) | 96 if (style_ == style) |
| 80 return; | 97 return; |
| 81 | 98 |
| 82 Style old_style = style_; | 99 Style old_style = style_; |
| 83 style_ = style; | 100 style_ = style; |
| 84 | 101 |
| 85 // Stop waiting for any as yet unfinished implicit animations. | 102 // Stop waiting for any as yet unfinished implicit animations. |
| 86 StopObservingImplicitAnimations(); | 103 StopObservingImplicitAnimations(); |
| 87 | 104 |
| 88 // If we're switching to or from the small style, don't bother with | 105 // If we're switching to or from the small style, don't bother with |
| 89 // animations. | 106 // animations. |
| 90 if (style == STYLE_SMALL || old_style == STYLE_SMALL) { | 107 if (style == STYLE_SMALL || old_style == STYLE_SMALL) { |
| 91 UpdateImagesForStyle(); | 108 UpdateImagesForStyle(); |
| 92 image_grid_->layer()->SetOpacity(GetOpacityForStyle(style)); | 109 layer()->SetOpacity(GetOpacityForStyle(style)); |
| 93 return; | 110 return; |
| 94 } | 111 } |
| 95 | 112 |
| 96 // If we're becoming active, switch images now. Because the inactive image | 113 // If we're becoming active, switch images now. Because the inactive image |
| 97 // has a very low opacity the switch isn't noticeable and this approach | 114 // has a very low opacity the switch isn't noticeable and this approach |
| 98 // allows us to use only a single set of shadow images at a time. | 115 // allows us to use only a single set of shadow images at a time. |
| 99 if (style == STYLE_ACTIVE) { | 116 if (style == STYLE_ACTIVE) { |
| 100 UpdateImagesForStyle(); | 117 UpdateImagesForStyle(); |
| 101 // Opacity was baked into inactive image, start opacity low to match. | 118 // Opacity was baked into inactive image, start opacity low to match. |
| 102 image_grid_->layer()->SetOpacity(kInactiveShadowOpacity); | 119 layer()->SetOpacity(kInactiveShadowOpacity); |
| 103 } | 120 } |
| 104 | 121 |
| 105 { | 122 { |
| 106 // Property sets within this scope will be implicitly animated. | 123 // Property sets within this scope will be implicitly animated. |
| 107 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); | 124 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); |
| 108 settings.AddObserver(this); | 125 settings.AddObserver(this); |
| 109 settings.SetTransitionDuration( | 126 settings.SetTransitionDuration( |
| 110 base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs)); | 127 base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs)); |
| 111 switch (style_) { | 128 switch (style_) { |
| 112 case STYLE_ACTIVE: | 129 case STYLE_ACTIVE: |
| 113 image_grid_->layer()->SetOpacity(kActiveShadowOpacity); | 130 layer()->SetOpacity(kActiveShadowOpacity); |
| 114 break; | 131 break; |
| 115 case STYLE_INACTIVE: | 132 case STYLE_INACTIVE: |
| 116 image_grid_->layer()->SetOpacity(kInactiveShadowOpacity); | 133 layer()->SetOpacity(kInactiveShadowOpacity); |
| 117 break; | 134 break; |
| 118 default: | 135 default: |
| 119 NOTREACHED() << "Unhandled style " << style_; | 136 NOTREACHED() << "Unhandled style " << style_; |
| 120 break; | 137 break; |
| 121 } | 138 } |
| 122 } | 139 } |
| 123 } | 140 } |
| 124 | 141 |
| 125 void Shadow::OnImplicitAnimationsCompleted() { | 142 void Shadow::OnImplicitAnimationsCompleted() { |
| 126 // If we just finished going inactive, switch images. This doesn't cause | 143 // If we just finished going inactive, switch images. This doesn't cause |
| 127 // a visual pop because the inactive image opacity is so low. | 144 // a visual pop because the inactive image opacity is so low. |
| 128 if (style_ == STYLE_INACTIVE) { | 145 if (style_ == STYLE_INACTIVE) { |
| 129 UpdateImagesForStyle(); | 146 UpdateImagesForStyle(); |
| 130 // Opacity is baked into inactive image, so set fully opaque. | 147 // Opacity is baked into inactive image, so set fully opaque. |
| 131 image_grid_->layer()->SetOpacity(1.0f); | 148 layer()->SetOpacity(1.0f); |
| 132 } | 149 } |
| 133 } | 150 } |
| 134 | 151 |
| 135 void Shadow::UpdateImagesForStyle() { | 152 void Shadow::UpdateImagesForStyle() { |
| 136 ResourceBundle& res = ResourceBundle::GetSharedInstance(); | 153 ResourceBundle& res = ResourceBundle::GetSharedInstance(); |
| 154 gfx::Image image; | |
| 137 switch (style_) { | 155 switch (style_) { |
| 138 case STYLE_ACTIVE: | 156 case STYLE_ACTIVE: |
| 139 image_grid_->SetImages( | 157 image = res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE); |
| 140 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_TOP_LEFT), | |
| 141 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_TOP), | |
| 142 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_TOP_RIGHT), | |
| 143 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_LEFT), | |
| 144 NULL, | |
| 145 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_RIGHT), | |
| 146 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_BOTTOM_LEFT), | |
| 147 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_BOTTOM), | |
| 148 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_BOTTOM_RIGHT)); | |
| 149 break; | 158 break; |
| 150 case STYLE_INACTIVE: | 159 case STYLE_INACTIVE: |
| 151 image_grid_->SetImages( | 160 image = res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE); |
| 152 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_TOP_LEFT), | |
| 153 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_TOP), | |
| 154 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_TOP_RIGHT), | |
| 155 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_LEFT), | |
| 156 NULL, | |
| 157 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_RIGHT), | |
| 158 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_BOTTOM_LEFT), | |
| 159 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_BOTTOM), | |
| 160 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_BOTTOM_RIGHT)); | |
| 161 break; | 161 break; |
| 162 case STYLE_SMALL: | 162 case STYLE_SMALL: |
| 163 image_grid_->SetImages( | 163 image = res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL); |
| 164 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP_LEFT), | |
| 165 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP), | |
| 166 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP_RIGHT), | |
| 167 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_LEFT), | |
| 168 NULL, | |
| 169 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_RIGHT), | |
| 170 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM_LEFT), | |
| 171 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM), | |
| 172 &res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM_RIGHT)); | |
| 173 break; | 164 break; |
| 174 default: | 165 default: |
| 175 NOTREACHED() << "Unhandled style " << style_; | 166 NOTREACHED() << "Unhandled style " << style_; |
| 176 break; | 167 break; |
| 177 } | 168 } |
| 178 | 169 |
| 170 // Calculate shadow aperture and border for style. | |
| 171 int shadow_aperture = GetShadowApertureForStyle(style_); | |
| 172 gfx::Rect aperture(shadow_aperture, | |
| 173 shadow_aperture, | |
| 174 image.Width() - shadow_aperture * 2, | |
| 175 image.Height() - shadow_aperture * 2); | |
| 176 gfx::Rect border(shadow_aperture, | |
| 177 shadow_aperture, | |
| 178 shadow_aperture * 2, | |
| 179 shadow_aperture * 2); | |
| 180 | |
| 181 // Update nine-patch layer image with aperture and border. | |
| 182 layer()->UpdateNinePatchBitmap(image.AsBitmap(), aperture, border); | |
| 183 | |
| 179 // Update interior inset for style. | 184 // Update interior inset for style. |
| 180 interior_inset_ = GetInteriorInsetForStyle(style_); | 185 interior_inset_ = GetInteriorInsetForStyle(style_); |
| 181 | 186 |
| 182 // Image sizes may have changed. | 187 // Image sizes may have changed. |
| 183 UpdateImageGridBounds(); | 188 UpdateImageBounds(); |
| 184 } | 189 } |
| 185 | 190 |
| 186 void Shadow::UpdateImageGridBounds() { | 191 void Shadow::UpdateImageBounds() { |
| 187 // Update bounds based on content bounds and image sizes. | 192 // Update bounds based on content bounds and image sizes. |
| 188 gfx::Rect image_grid_bounds = content_bounds_; | 193 gfx::Rect image_bounds = content_bounds_; |
| 189 image_grid_bounds.Inset(interior_inset_, interior_inset_); | 194 image_bounds.Inset(-interior_inset_, -interior_inset_); |
| 190 image_grid_->SetContentBounds(image_grid_bounds); | 195 layer()->SetBounds(image_bounds); |
| 191 } | 196 } |
| 192 | 197 |
| 193 } // namespace wm | 198 } // namespace wm |
| OLD | NEW |