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