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

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

Issue 385123005: Change ui::wm::Shadow to use cc::NinePatchLayer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Separate update functions for Bitmap/Border. The border needs to be clamped to stay within layer bo… Created 6 years, 5 months 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 | Annotate | Revision Log
« no previous file with comments | « ui/wm/core/shadow.h ('k') | no next file » | 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 "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.
21 // Note that this may be greater than interior inset to allow shadows with
22 // curved corners that extend inwards beyond a window's borders.
23 const int kActiveInteriorAperture = 134;
24 const int kInactiveInteriorAperture = 134;
25 const int kSmallInteriorAperture = 9;
26
19 // Interior inset for different styles. 27 // Interior inset for different styles.
20 const int kActiveInteriorInset = 0; 28 const int kActiveInteriorInset = 64;
21 const int kInactiveInteriorInset = 0; 29 const int kInactiveInteriorInset = 64;
22 const int kSmallInteriorInset = 5; 30 const int kSmallInteriorInset = 4;
23 31
24 // Duration for opacity animation in milliseconds. 32 // Duration for opacity animation in milliseconds.
25 const int kShadowAnimationDurationMs = 100; 33 const int kShadowAnimationDurationMs = 100;
26 34
27 float GetOpacityForStyle(wm::Shadow::Style style) { 35 float GetOpacityForStyle(wm::Shadow::Style style) {
28 switch (style) { 36 switch (style) {
29 case wm::Shadow::STYLE_ACTIVE: 37 case wm::Shadow::STYLE_ACTIVE:
30 return kActiveShadowOpacity; 38 return kActiveShadowOpacity;
31 case wm::Shadow::STYLE_INACTIVE: 39 case wm::Shadow::STYLE_INACTIVE:
32 return kInactiveShadowOpacity; 40 return kInactiveShadowOpacity;
33 case wm::Shadow::STYLE_SMALL: 41 case wm::Shadow::STYLE_SMALL:
34 return kSmallShadowOpacity; 42 return kSmallShadowOpacity;
35 } 43 }
36 return 1.0f; 44 return 1.0f;
37 } 45 }
38 46
47 int GetShadowApertureForStyle(wm::Shadow::Style style) {
48 switch (style) {
49 case wm::Shadow::STYLE_ACTIVE:
50 return kActiveInteriorAperture;
51 case wm::Shadow::STYLE_INACTIVE:
52 return kInactiveInteriorAperture;
53 case wm::Shadow::STYLE_SMALL:
54 return kSmallInteriorAperture;
55 }
56 return 0;
57 }
58
39 int GetInteriorInsetForStyle(wm::Shadow::Style style) { 59 int GetInteriorInsetForStyle(wm::Shadow::Style style) {
40 switch (style) { 60 switch (style) {
41 case wm::Shadow::STYLE_ACTIVE: 61 case wm::Shadow::STYLE_ACTIVE:
42 return kActiveInteriorInset; 62 return kActiveInteriorInset;
43 case wm::Shadow::STYLE_INACTIVE: 63 case wm::Shadow::STYLE_INACTIVE:
44 return kInactiveInteriorInset; 64 return kInactiveInteriorInset;
45 case wm::Shadow::STYLE_SMALL: 65 case wm::Shadow::STYLE_SMALL:
46 return kSmallInteriorInset; 66 return kSmallInteriorInset;
47 } 67 }
48 return 0; 68 return 0;
49 } 69 }
50 70
51 } // namespace 71 } // namespace
52 72
53 namespace wm { 73 namespace wm {
54 74
55 Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) { 75 Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) {
56 } 76 }
57 77
58 Shadow::~Shadow() { 78 Shadow::~Shadow() {
59 } 79 }
60 80
61 void Shadow::Init(Style style) { 81 void Shadow::Init(Style style) {
62 style_ = style; 82 style_ = style;
63 image_grid_.reset(new ImageGrid); 83
84 layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH));
64 UpdateImagesForStyle(); 85 UpdateImagesForStyle();
65 image_grid_->layer()->set_name("Shadow"); 86 layer()->set_name("Shadow");
66 image_grid_->layer()->SetOpacity(GetOpacityForStyle(style_)); 87 layer()->SetVisible(true);
88 layer()->SetFillsBoundsOpaquely(false);
89 layer()->SetOpacity(GetOpacityForStyle(style_));
67 } 90 }
68 91
69 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) { 92 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) {
70 content_bounds_ = content_bounds; 93 content_bounds_ = content_bounds;
71 UpdateImageGridBounds(); 94 UpdateLayerBounds();
72 }
73
74 ui::Layer* Shadow::layer() const {
75 return image_grid_->layer();
76 } 95 }
77 96
78 void Shadow::SetStyle(Style style) { 97 void Shadow::SetStyle(Style style) {
79 if (style_ == style) 98 if (style_ == style)
80 return; 99 return;
81 100
82 Style old_style = style_; 101 Style old_style = style_;
83 style_ = style; 102 style_ = style;
84 103
85 // Stop waiting for any as yet unfinished implicit animations. 104 // Stop waiting for any as yet unfinished implicit animations.
86 StopObservingImplicitAnimations(); 105 StopObservingImplicitAnimations();
87 106
88 // If we're switching to or from the small style, don't bother with 107 // If we're switching to or from the small style, don't bother with
89 // animations. 108 // animations.
90 if (style == STYLE_SMALL || old_style == STYLE_SMALL) { 109 if (style == STYLE_SMALL || old_style == STYLE_SMALL) {
91 UpdateImagesForStyle(); 110 UpdateImagesForStyle();
92 image_grid_->layer()->SetOpacity(GetOpacityForStyle(style)); 111 layer()->SetOpacity(GetOpacityForStyle(style));
93 return; 112 return;
94 } 113 }
95 114
96 // If we're becoming active, switch images now. Because the inactive image 115 // 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 116 // 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. 117 // allows us to use only a single set of shadow images at a time.
99 if (style == STYLE_ACTIVE) { 118 if (style == STYLE_ACTIVE) {
100 UpdateImagesForStyle(); 119 UpdateImagesForStyle();
101 // Opacity was baked into inactive image, start opacity low to match. 120 // Opacity was baked into inactive image, start opacity low to match.
102 image_grid_->layer()->SetOpacity(kInactiveShadowOpacity); 121 layer()->SetOpacity(kInactiveShadowOpacity);
103 } 122 }
104 123
105 { 124 {
106 // Property sets within this scope will be implicitly animated. 125 // Property sets within this scope will be implicitly animated.
107 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); 126 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
108 settings.AddObserver(this); 127 settings.AddObserver(this);
109 settings.SetTransitionDuration( 128 settings.SetTransitionDuration(
110 base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs)); 129 base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs));
111 switch (style_) { 130 switch (style_) {
112 case STYLE_ACTIVE: 131 case STYLE_ACTIVE:
113 image_grid_->layer()->SetOpacity(kActiveShadowOpacity); 132 layer()->SetOpacity(kActiveShadowOpacity);
114 break; 133 break;
115 case STYLE_INACTIVE: 134 case STYLE_INACTIVE:
116 image_grid_->layer()->SetOpacity(kInactiveShadowOpacity); 135 layer()->SetOpacity(kInactiveShadowOpacity);
117 break; 136 break;
118 default: 137 default:
119 NOTREACHED() << "Unhandled style " << style_; 138 NOTREACHED() << "Unhandled style " << style_;
120 break; 139 break;
121 } 140 }
122 } 141 }
123 } 142 }
124 143
125 void Shadow::OnImplicitAnimationsCompleted() { 144 void Shadow::OnImplicitAnimationsCompleted() {
126 // If we just finished going inactive, switch images. This doesn't cause 145 // If we just finished going inactive, switch images. This doesn't cause
127 // a visual pop because the inactive image opacity is so low. 146 // a visual pop because the inactive image opacity is so low.
128 if (style_ == STYLE_INACTIVE) { 147 if (style_ == STYLE_INACTIVE) {
129 UpdateImagesForStyle(); 148 UpdateImagesForStyle();
130 // Opacity is baked into inactive image, so set fully opaque. 149 // Opacity is baked into inactive image, so set fully opaque.
131 image_grid_->layer()->SetOpacity(1.0f); 150 layer()->SetOpacity(1.0f);
132 } 151 }
133 } 152 }
134 153
135 void Shadow::UpdateImagesForStyle() { 154 void Shadow::UpdateImagesForStyle() {
136 ResourceBundle& res = ResourceBundle::GetSharedInstance(); 155 ResourceBundle& res = ResourceBundle::GetSharedInstance();
156 gfx::Image image;
137 switch (style_) { 157 switch (style_) {
138 case STYLE_ACTIVE: 158 case STYLE_ACTIVE:
139 image_grid_->SetImages( 159 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; 160 break;
150 case STYLE_INACTIVE: 161 case STYLE_INACTIVE:
151 image_grid_->SetImages( 162 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; 163 break;
162 case STYLE_SMALL: 164 case STYLE_SMALL:
163 image_grid_->SetImages( 165 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; 166 break;
174 default: 167 default:
175 NOTREACHED() << "Unhandled style " << style_; 168 NOTREACHED() << "Unhandled style " << style_;
176 break; 169 break;
177 } 170 }
178 171
172 // Calculate shadow aperture for style.
173 int shadow_aperture = GetShadowApertureForStyle(style_);
174 gfx::Rect aperture(shadow_aperture,
175 shadow_aperture,
176 image.Width() - shadow_aperture * 2,
177 image.Height() - shadow_aperture * 2);
178
179 // Update nine-patch layer with new bitmap and aperture.
180 layer()->UpdateNinePatchLayerBitmap(image.AsBitmap(), aperture);
181
179 // Update interior inset for style. 182 // Update interior inset for style.
180 interior_inset_ = GetInteriorInsetForStyle(style_); 183 interior_inset_ = GetInteriorInsetForStyle(style_);
181 184
182 // Image sizes may have changed. 185 // Image sizes may have changed.
183 UpdateImageGridBounds(); 186 UpdateLayerBounds();
184 } 187 }
185 188
186 void Shadow::UpdateImageGridBounds() { 189 void Shadow::UpdateLayerBounds() {
187 // Update bounds based on content bounds and image sizes. 190 // Update bounds based on content bounds and interior inset.
188 gfx::Rect image_grid_bounds = content_bounds_; 191 gfx::Rect layer_bounds = content_bounds_;
189 image_grid_bounds.Inset(interior_inset_, interior_inset_); 192 layer_bounds.Inset(-interior_inset_, -interior_inset_);
190 image_grid_->SetContentBounds(image_grid_bounds); 193 layer()->SetBounds(layer_bounds);
194
195 // Calculate shadow border for style. Note that |border| is in layer space
196 // and it cannot exceed the bounds of the layer.
197 int shadow_aperture = GetShadowApertureForStyle(style_);
198 int border_width = std::min(shadow_aperture * 2, layer_bounds.width());
199 int border_height = std::min(shadow_aperture * 2, layer_bounds.height());
200 gfx::Rect border(border_width / 2,
201 border_height / 2,
202 border_width,
203 border_height);
204 layer()->UpdateNinePatchLayerBorder(border);
191 } 205 }
192 206
193 } // namespace wm 207 } // namespace wm
OLDNEW
« no previous file with comments | « ui/wm/core/shadow.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698