| OLD | NEW |
| 1 // Copyright (c) 2011 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 "ash/wm/shadow.h" | 5 #include "ash/wm/shadow.h" |
| 6 | 6 |
| 7 #include "ash/wm/image_grid.h" | 7 #include "ash/wm/image_grid.h" |
| 8 #include "grit/ui_resources.h" | 8 #include "grit/ui_resources.h" |
| 9 #include "ui/base/resource/resource_bundle.h" | 9 #include "ui/base/resource/resource_bundle.h" |
| 10 #include "ui/gfx/compositor/scoped_layer_animation_settings.h" |
| 11 |
| 12 namespace { |
| 13 |
| 14 // Shadow opacity for active window. |
| 15 const float kActiveShadowOpacity = 1.0f; |
| 16 |
| 17 // Shadow opacity for inactive window. |
| 18 const float kInactiveShadowOpacity = 0.2f; |
| 19 |
| 20 // Duration for opacity animation in milliseconds. |
| 21 const int64 kAnimationDurationMs = 200; |
| 22 |
| 23 } // namespace |
| 10 | 24 |
| 11 namespace ash { | 25 namespace ash { |
| 12 namespace internal { | 26 namespace internal { |
| 13 | 27 |
| 14 Shadow::Shadow() { | 28 Shadow::Shadow() { |
| 15 } | 29 } |
| 16 | 30 |
| 17 Shadow::~Shadow() { | 31 Shadow::~Shadow() { |
| 18 } | 32 } |
| 19 | 33 |
| 20 ui::Layer* Shadow::layer() const { return image_grid_->layer(); } | |
| 21 | |
| 22 void Shadow::Init() { | 34 void Shadow::Init() { |
| 35 style_ = STYLE_ACTIVE; |
| 23 image_grid_.reset(new ImageGrid); | 36 image_grid_.reset(new ImageGrid); |
| 24 | 37 UpdateImagesForStyle(); |
| 25 ResourceBundle& res = ResourceBundle::GetSharedInstance(); | 38 image_grid_->layer()->set_name("Shadow"); |
| 26 image_grid_->Init(&res.GetImageNamed(IDR_AURA_SHADOW_RECT_TOP_LEFT), | 39 image_grid_->layer()->SetOpacity(kActiveShadowOpacity); |
| 27 &res.GetImageNamed(IDR_AURA_SHADOW_RECT_TOP), | |
| 28 &res.GetImageNamed(IDR_AURA_SHADOW_RECT_TOP_RIGHT), | |
| 29 &res.GetImageNamed(IDR_AURA_SHADOW_RECT_LEFT), | |
| 30 NULL, | |
| 31 &res.GetImageNamed(IDR_AURA_SHADOW_RECT_RIGHT), | |
| 32 &res.GetImageNamed(IDR_AURA_SHADOW_RECT_BOTTOM_LEFT), | |
| 33 &res.GetImageNamed(IDR_AURA_SHADOW_RECT_BOTTOM), | |
| 34 &res.GetImageNamed(IDR_AURA_SHADOW_RECT_BOTTOM_RIGHT)); | |
| 35 } | 40 } |
| 36 | 41 |
| 37 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) { | 42 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) { |
| 38 content_bounds_ = content_bounds; | 43 content_bounds_ = content_bounds; |
| 44 UpdateImageGridBounds(); |
| 45 } |
| 46 |
| 47 ui::Layer* Shadow::layer() const { |
| 48 return image_grid_->layer(); |
| 49 } |
| 50 |
| 51 void Shadow::SetStyle(Style style) { |
| 52 if (style_ == style) |
| 53 return; |
| 54 style_ = style; |
| 55 |
| 56 // Stop waiting for any as yet unfinished implicit animations. |
| 57 StopObservingImplicitAnimations(); |
| 58 |
| 59 // If we're becoming active, switch images now. Because the inactive image |
| 60 // has a very low opacity the switch isn't noticeable and this approach |
| 61 // allows us to use only a single set of shadow images at a time. |
| 62 if (style == STYLE_ACTIVE) { |
| 63 UpdateImagesForStyle(); |
| 64 // Opacity was baked into inactive image, start opacity low to match. |
| 65 image_grid_->layer()->SetOpacity(kInactiveShadowOpacity); |
| 66 } |
| 67 |
| 68 { |
| 69 // Property sets within this scope will be implicitly animated. |
| 70 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); |
| 71 settings.AddObserver(this); |
| 72 settings.SetTransitionDuration( |
| 73 base::TimeDelta::FromMilliseconds(kAnimationDurationMs)); |
| 74 switch (style_) { |
| 75 case STYLE_ACTIVE: |
| 76 image_grid_->layer()->SetOpacity(kActiveShadowOpacity); |
| 77 break; |
| 78 case STYLE_INACTIVE: |
| 79 image_grid_->layer()->SetOpacity(kInactiveShadowOpacity); |
| 80 break; |
| 81 default: |
| 82 NOTREACHED(); |
| 83 break; |
| 84 } |
| 85 } |
| 86 } |
| 87 |
| 88 void Shadow::OnImplicitAnimationsCompleted() { |
| 89 // If we just finished going inactive, switch images. This doesn't cause |
| 90 // a visual pop because the inactive image opacity is so low. |
| 91 if (style_ == STYLE_INACTIVE) { |
| 92 UpdateImagesForStyle(); |
| 93 // Opacity is baked into inactive image, so set fully opaque. |
| 94 image_grid_->layer()->SetOpacity(1.0f); |
| 95 } |
| 96 } |
| 97 |
| 98 void Shadow::UpdateImagesForStyle() { |
| 99 ResourceBundle& res = ResourceBundle::GetSharedInstance(); |
| 100 switch (style_) { |
| 101 case STYLE_ACTIVE: |
| 102 image_grid_->SetImages( |
| 103 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_TOP_LEFT), |
| 104 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_TOP), |
| 105 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_TOP_RIGHT), |
| 106 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_LEFT), |
| 107 NULL, |
| 108 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_RIGHT), |
| 109 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_BOTTOM_LEFT), |
| 110 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_BOTTOM), |
| 111 &res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE_BOTTOM_RIGHT)); |
| 112 break; |
| 113 case STYLE_INACTIVE: |
| 114 image_grid_->SetImages( |
| 115 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_TOP_LEFT), |
| 116 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_TOP), |
| 117 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_TOP_RIGHT), |
| 118 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_LEFT), |
| 119 NULL, |
| 120 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_RIGHT), |
| 121 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_BOTTOM_LEFT), |
| 122 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_BOTTOM), |
| 123 &res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE_BOTTOM_RIGHT)); |
| 124 break; |
| 125 default: |
| 126 NOTREACHED(); |
| 127 break; |
| 128 } |
| 129 |
| 130 // Image sizes may have changed. |
| 131 UpdateImageGridBounds(); |
| 132 } |
| 133 |
| 134 void Shadow::UpdateImageGridBounds() { |
| 39 image_grid_->SetSize( | 135 image_grid_->SetSize( |
| 40 gfx::Size(content_bounds.width() + | 136 gfx::Size(content_bounds_.width() + |
| 41 image_grid_->left_image_width() + | 137 image_grid_->left_image_width() + |
| 42 image_grid_->right_image_width(), | 138 image_grid_->right_image_width(), |
| 43 content_bounds.height() + | 139 content_bounds_.height() + |
| 44 image_grid_->top_image_height() + | 140 image_grid_->top_image_height() + |
| 45 image_grid_->bottom_image_height())); | 141 image_grid_->bottom_image_height())); |
| 46 image_grid_->layer()->SetBounds( | 142 image_grid_->layer()->SetBounds( |
| 47 gfx::Rect(content_bounds.x() - image_grid_->left_image_width(), | 143 gfx::Rect(content_bounds_.x() - image_grid_->left_image_width(), |
| 48 content_bounds.y() - image_grid_->top_image_height(), | 144 content_bounds_.y() - image_grid_->top_image_height(), |
| 49 image_grid_->layer()->bounds().width(), | 145 image_grid_->layer()->bounds().width(), |
| 50 image_grid_->layer()->bounds().height())); | 146 image_grid_->layer()->bounds().height())); |
| 51 } | 147 } |
| 52 | 148 |
| 53 } // namespace internal | 149 } // namespace internal |
| 54 } // namespace ash | 150 } // namespace ash |
| OLD | NEW |