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 "third_party/skia/include/core/SkBitmap.h" |
9 #include "ui/base/resource/resource_bundle.h" | 9 #include "ui/base/resource/resource_bundle.h" |
10 #include "ui/compositor/layer.h" | 10 #include "ui/compositor/layer.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 | 74 |
75 Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) { | 75 Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) { |
76 } | 76 } |
77 | 77 |
78 Shadow::~Shadow() { | 78 Shadow::~Shadow() { |
79 } | 79 } |
80 | 80 |
81 void Shadow::Init(Style style) { | 81 void Shadow::Init(Style style) { |
82 style_ = style; | 82 style_ = style; |
83 | 83 |
84 layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH)); | 84 layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN)); |
| 85 shadow_layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH)); |
| 86 layer()->Add(shadow_layer_.get()); |
| 87 |
85 UpdateImagesForStyle(); | 88 UpdateImagesForStyle(); |
86 layer()->set_name("Shadow"); | 89 shadow_layer_->set_name("Shadow"); |
87 layer()->SetVisible(true); | 90 shadow_layer_->SetVisible(true); |
88 layer()->SetFillsBoundsOpaquely(false); | 91 shadow_layer_->SetFillsBoundsOpaquely(false); |
89 layer()->SetOpacity(GetOpacityForStyle(style_)); | 92 shadow_layer_->SetOpacity(GetOpacityForStyle(style_)); |
90 } | 93 } |
91 | 94 |
92 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) { | 95 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) { |
93 content_bounds_ = content_bounds; | 96 content_bounds_ = content_bounds; |
94 UpdateLayerBounds(); | 97 UpdateLayerBounds(); |
95 } | 98 } |
96 | 99 |
97 void Shadow::SetStyle(Style style) { | 100 void Shadow::SetStyle(Style style) { |
98 if (style_ == style) | 101 if (style_ == style) |
99 return; | 102 return; |
100 | 103 |
101 Style old_style = style_; | 104 Style old_style = style_; |
102 style_ = style; | 105 style_ = style; |
103 | 106 |
104 // Stop waiting for any as yet unfinished implicit animations. | 107 // Stop waiting for any as yet unfinished implicit animations. |
105 StopObservingImplicitAnimations(); | 108 StopObservingImplicitAnimations(); |
106 | 109 |
107 // If we're switching to or from the small style, don't bother with | 110 // If we're switching to or from the small style, don't bother with |
108 // animations. | 111 // animations. |
109 if (style == STYLE_SMALL || old_style == STYLE_SMALL) { | 112 if (style == STYLE_SMALL || old_style == STYLE_SMALL) { |
110 UpdateImagesForStyle(); | 113 UpdateImagesForStyle(); |
111 layer()->SetOpacity(GetOpacityForStyle(style)); | 114 shadow_layer_->SetOpacity(GetOpacityForStyle(style)); |
112 return; | 115 return; |
113 } | 116 } |
114 | 117 |
115 // If we're becoming active, switch images now. Because the inactive image | 118 // If we're becoming active, switch images now. Because the inactive image |
116 // has a very low opacity the switch isn't noticeable and this approach | 119 // has a very low opacity the switch isn't noticeable and this approach |
117 // allows us to use only a single set of shadow images at a time. | 120 // allows us to use only a single set of shadow images at a time. |
118 if (style == STYLE_ACTIVE) { | 121 if (style == STYLE_ACTIVE) { |
119 UpdateImagesForStyle(); | 122 UpdateImagesForStyle(); |
120 // Opacity was baked into inactive image, start opacity low to match. | 123 // Opacity was baked into inactive image, start opacity low to match. |
121 layer()->SetOpacity(kInactiveShadowOpacity); | 124 shadow_layer_->SetOpacity(kInactiveShadowOpacity); |
122 } | 125 } |
123 | 126 |
124 { | 127 { |
125 // Property sets within this scope will be implicitly animated. | 128 // Property sets within this scope will be implicitly animated. |
126 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); | 129 ui::ScopedLayerAnimationSettings settings(shadow_layer_->GetAnimator()); |
127 settings.AddObserver(this); | 130 settings.AddObserver(this); |
128 settings.SetTransitionDuration( | 131 settings.SetTransitionDuration( |
129 base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs)); | 132 base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs)); |
130 switch (style_) { | 133 switch (style_) { |
131 case STYLE_ACTIVE: | 134 case STYLE_ACTIVE: |
132 layer()->SetOpacity(kActiveShadowOpacity); | 135 shadow_layer_->SetOpacity(kActiveShadowOpacity); |
133 break; | 136 break; |
134 case STYLE_INACTIVE: | 137 case STYLE_INACTIVE: |
135 layer()->SetOpacity(kInactiveShadowOpacity); | 138 shadow_layer_->SetOpacity(kInactiveShadowOpacity); |
136 break; | 139 break; |
137 default: | 140 default: |
138 NOTREACHED() << "Unhandled style " << style_; | 141 NOTREACHED() << "Unhandled style " << style_; |
139 break; | 142 break; |
140 } | 143 } |
141 } | 144 } |
142 } | 145 } |
143 | 146 |
144 void Shadow::OnImplicitAnimationsCompleted() { | 147 void Shadow::OnImplicitAnimationsCompleted() { |
145 // If we just finished going inactive, switch images. This doesn't cause | 148 // If we just finished going inactive, switch images. This doesn't cause |
146 // a visual pop because the inactive image opacity is so low. | 149 // a visual pop because the inactive image opacity is so low. |
147 if (style_ == STYLE_INACTIVE) { | 150 if (style_ == STYLE_INACTIVE) { |
148 UpdateImagesForStyle(); | 151 UpdateImagesForStyle(); |
149 // Opacity is baked into inactive image, so set fully opaque. | 152 // Opacity is baked into inactive image, so set fully opaque. |
150 layer()->SetOpacity(1.0f); | 153 shadow_layer_->SetOpacity(1.0f); |
151 } | 154 } |
152 } | 155 } |
153 | 156 |
154 void Shadow::UpdateImagesForStyle() { | 157 void Shadow::UpdateImagesForStyle() { |
155 ResourceBundle& res = ResourceBundle::GetSharedInstance(); | 158 ResourceBundle& res = ResourceBundle::GetSharedInstance(); |
156 gfx::Image image; | 159 gfx::Image image; |
157 switch (style_) { | 160 switch (style_) { |
158 case STYLE_ACTIVE: | 161 case STYLE_ACTIVE: |
159 image = res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE); | 162 image = res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE); |
160 break; | 163 break; |
161 case STYLE_INACTIVE: | 164 case STYLE_INACTIVE: |
162 image = res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE); | 165 image = res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE); |
163 break; | 166 break; |
164 case STYLE_SMALL: | 167 case STYLE_SMALL: |
165 image = res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL); | 168 image = res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL); |
166 break; | 169 break; |
167 default: | 170 default: |
168 NOTREACHED() << "Unhandled style " << style_; | 171 NOTREACHED() << "Unhandled style " << style_; |
169 break; | 172 break; |
170 } | 173 } |
171 | 174 |
172 // Calculate shadow aperture for style. | 175 // Calculate shadow aperture for style. |
173 int shadow_aperture = GetShadowApertureForStyle(style_); | 176 int shadow_aperture = GetShadowApertureForStyle(style_); |
174 gfx::Rect aperture(shadow_aperture, | 177 gfx::Rect aperture(shadow_aperture, |
175 shadow_aperture, | 178 shadow_aperture, |
176 image.Width() - shadow_aperture * 2, | 179 image.Width() - shadow_aperture * 2, |
177 image.Height() - shadow_aperture * 2); | 180 image.Height() - shadow_aperture * 2); |
178 | 181 |
179 // Update nine-patch layer with new bitmap and aperture. | 182 // Update nine-patch layer with new bitmap and aperture. |
180 layer()->UpdateNinePatchLayerBitmap(image.AsBitmap(), aperture); | 183 shadow_layer_->UpdateNinePatchLayerBitmap(image.AsBitmap(), aperture); |
181 | 184 |
182 // Update interior inset for style. | 185 // Update interior inset for style. |
183 interior_inset_ = GetInteriorInsetForStyle(style_); | 186 interior_inset_ = GetInteriorInsetForStyle(style_); |
184 | 187 |
185 // Image sizes may have changed. | 188 // Image sizes may have changed. |
186 UpdateLayerBounds(); | 189 UpdateLayerBounds(); |
187 } | 190 } |
188 | 191 |
189 void Shadow::UpdateLayerBounds() { | 192 void Shadow::UpdateLayerBounds() { |
190 // Update bounds based on content bounds and interior inset. | 193 // Update bounds based on content bounds and interior inset. |
191 gfx::Rect layer_bounds = content_bounds_; | 194 gfx::Rect layer_bounds = content_bounds_; |
192 layer_bounds.Inset(-interior_inset_, -interior_inset_); | 195 layer_bounds.Inset(-interior_inset_, -interior_inset_); |
193 layer()->SetBounds(layer_bounds); | 196 layer()->SetBounds(layer_bounds); |
| 197 shadow_layer_->SetBounds(gfx::Rect(layer_bounds.size())); |
194 | 198 |
195 // Calculate shadow border for style. Note that |border| is in layer space | 199 // Calculate shadow border for style. Note that border is in layer space |
196 // and it cannot exceed the bounds of the layer. | 200 // and it cannot exceed the bounds of the layer. |
197 int shadow_aperture = GetShadowApertureForStyle(style_); | 201 int shadow_aperture = GetShadowApertureForStyle(style_); |
198 int border_width = std::min(shadow_aperture * 2, layer_bounds.width()); | 202 gfx::Rect border(shadow_aperture, shadow_aperture, |
199 int border_height = std::min(shadow_aperture * 2, layer_bounds.height()); | 203 shadow_aperture * 2, shadow_aperture * 2); |
200 gfx::Rect border(border_width / 2, | 204 if (layer_bounds.width() < border.width() || |
201 border_height / 2, | 205 layer_bounds.height() < border.height()) { |
202 border_width, | 206 shadow_layer_->SetVisible(false); |
203 border_height); | 207 } else { |
204 layer()->UpdateNinePatchLayerBorder(border); | 208 shadow_layer_->SetVisible(true); |
| 209 shadow_layer_->UpdateNinePatchLayerBorder(border); |
| 210 } |
205 } | 211 } |
206 | 212 |
207 } // namespace wm | 213 } // namespace wm |
OLD | NEW |