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 "ash/wm/compact_layout_manager.h" | 5 #include "ash/wm/compact_layout_manager.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "ash/shell.h" | 9 #include "ash/shell.h" |
| 10 #include "ash/shell_delegate.h" | 10 #include "ash/shell_delegate.h" |
| 11 #include "ash/shell_window_ids.h" | 11 #include "ash/shell_window_ids.h" |
| 12 #include "ash/wm/window_util.h" | 12 #include "ash/wm/window_util.h" |
| 13 #include "base/memory/scoped_vector.h" | |
| 13 #include "ui/aura/client/aura_constants.h" | 14 #include "ui/aura/client/aura_constants.h" |
| 14 #include "ui/aura/window.h" | 15 #include "ui/aura/window.h" |
| 15 #include "ui/gfx/compositor/scoped_layer_animation_settings.h" | 16 #include "ui/gfx/compositor/scoped_layer_animation_settings.h" |
| 16 #include "ui/gfx/compositor/layer.h" | 17 #include "ui/gfx/compositor/layer.h" |
| 17 #include "ui/gfx/compositor/layer_animation_sequence.h" | 18 #include "ui/gfx/compositor/layer_animation_sequence.h" |
| 18 #include "ui/gfx/screen.h" | 19 #include "ui/gfx/screen.h" |
| 19 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
| 20 | 21 |
| 21 namespace ash { | 22 namespace ash { |
| 22 namespace internal { | 23 namespace internal { |
| 23 | 24 |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| 26 typedef std::vector<aura::Window*> WindowList; | 27 typedef std::vector<aura::Window*> WindowList; |
| 27 typedef std::vector<aura::Window*>::const_iterator WindowListConstIter; | 28 typedef std::vector<aura::Window*>::const_iterator WindowListConstIter; |
| 28 | 29 |
| 29 // Convenience method to get the layer of this container. | 30 // Convenience method to get the layer of this container. |
| 30 ui::Layer* GetDefaultContainerLayer() { | 31 ui::Layer* GetDefaultContainerLayer() { |
| 31 return Shell::GetInstance()->GetContainer( | 32 return Shell::GetInstance()->GetContainer( |
| 32 internal::kShellWindowId_DefaultContainer)->layer(); | 33 internal::kShellWindowId_DefaultContainer)->layer(); |
| 33 } | 34 } |
| 34 | 35 |
| 35 // Whether it is a window that should be animated on entrance. | 36 // Whether it is a window that should be animated on entrance. |
| 36 bool ShouldAnimateOnEntrance(aura::Window* window) { | 37 bool ShouldAnimateOnEntrance(aura::Window* window) { |
| 37 return window && | 38 return window && |
| 38 window->type() == aura::client::WINDOW_TYPE_NORMAL && | 39 window->type() == aura::client::WINDOW_TYPE_NORMAL && |
| 39 window_util::IsWindowMaximized(window); | 40 window_util::IsWindowMaximized(window); |
| 40 } | 41 } |
| 41 | 42 |
| 42 // Adjust layer bounds to grow or shrink in |delta_width|. | |
| 43 void AdjustContainerLayerWidth(int delta_width) { | |
| 44 gfx::Rect bounds(GetDefaultContainerLayer()->bounds()); | |
| 45 bounds.set_width(bounds.width() + delta_width); | |
| 46 GetDefaultContainerLayer()->SetBounds(bounds); | |
| 47 GetDefaultContainerLayer()->GetCompositor()->WidgetSizeChanged( | |
| 48 GetDefaultContainerLayer()->bounds().size()); | |
| 49 } | |
| 50 } // namespace | 43 } // namespace |
| 51 | 44 |
| 52 ///////////////////////////////////////////////////////////////////////////// | 45 ///////////////////////////////////////////////////////////////////////////// |
| 53 // CompactLayoutManager, public: | 46 // CompactLayoutManager, public: |
| 54 | 47 |
| 55 CompactLayoutManager::CompactLayoutManager() | 48 CompactLayoutManager::CompactLayoutManager() |
| 56 : status_area_widget_(NULL), | 49 : status_area_widget_(NULL), |
| 57 current_window_(NULL) { | 50 current_window_(NULL) { |
| 58 } | 51 } |
| 59 | 52 |
| 60 CompactLayoutManager::~CompactLayoutManager() { | 53 CompactLayoutManager::~CompactLayoutManager() { |
| 61 } | 54 } |
| 62 | 55 |
| 63 ///////////////////////////////////////////////////////////////////////////// | 56 ///////////////////////////////////////////////////////////////////////////// |
| 64 // CompactLayoutManager, LayoutManager overrides: | 57 // CompactLayoutManager, LayoutManager overrides: |
| 65 | 58 |
| 66 void CompactLayoutManager::OnWindowAddedToLayout(aura::Window* child) { | 59 void CompactLayoutManager::OnWindowAddedToLayout(aura::Window* child) { |
| 67 BaseLayoutManager::OnWindowAddedToLayout(child); | 60 BaseLayoutManager::OnWindowAddedToLayout(child); |
| 68 UpdateStatusAreaVisibility(); | 61 UpdateStatusAreaVisibility(); |
| 69 if (windows().size() > 1 && | |
| 70 child->type() == aura::client::WINDOW_TYPE_NORMAL) { | |
| 71 // The first window is already contained in the current layer, | |
| 72 // add subsequent windows to layer bounds calculation. | |
| 73 AdjustContainerLayerWidth(child->bounds().width()); | |
| 74 } | |
| 75 } | 62 } |
| 76 | 63 |
| 77 void CompactLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { | 64 void CompactLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { |
| 78 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); | 65 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); |
| 79 UpdateStatusAreaVisibility(); | 66 UpdateStatusAreaVisibility(); |
| 80 if (windows().size() > 1 && ShouldAnimateOnEntrance(child)) | |
| 81 AdjustContainerLayerWidth(-child->bounds().width()); | |
| 82 | |
| 83 if (child == current_window_) { | 67 if (child == current_window_) { |
| 84 LayoutWindows(current_window_); | 68 LayoutWindows(current_window_); |
| 85 SwitchToReplacementWindow(); | 69 SwitchToReplacementWindow(); |
| 86 } | 70 } |
| 87 } | 71 } |
| 88 | 72 |
| 89 void CompactLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child, | 73 void CompactLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child, |
| 90 bool visible) { | 74 bool visible) { |
| 91 BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible); | 75 BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible); |
| 92 UpdateStatusAreaVisibility(); | 76 UpdateStatusAreaVisibility(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 } | 121 } |
| 138 // Always animate to |window| when there is a stacking change. | 122 // Always animate to |window| when there is a stacking change. |
| 139 AnimateSlideTo(window->bounds().x()); | 123 AnimateSlideTo(window->bounds().x()); |
| 140 } | 124 } |
| 141 } | 125 } |
| 142 | 126 |
| 143 ///////////////////////////////////////////////////////////////////////////// | 127 ///////////////////////////////////////////////////////////////////////////// |
| 144 // CompactLayoutManager, AnimationDelegate overrides: | 128 // CompactLayoutManager, AnimationDelegate overrides: |
| 145 | 129 |
| 146 void CompactLayoutManager::OnImplicitAnimationsCompleted() { | 130 void CompactLayoutManager::OnImplicitAnimationsCompleted() { |
| 147 if (!GetDefaultContainerLayer()->GetAnimator()->is_animating()) | 131 HideWindows(); |
| 148 HideWindows(); | |
| 149 } | 132 } |
| 150 | 133 |
| 151 ////////////////////////////////////////////////////////////////////////////// | 134 ////////////////////////////////////////////////////////////////////////////// |
| 152 // CompactLayoutManager, private: | 135 // CompactLayoutManager, private: |
| 153 | 136 |
| 154 void CompactLayoutManager::UpdateStatusAreaVisibility() { | 137 void CompactLayoutManager::UpdateStatusAreaVisibility() { |
| 155 if (!status_area_widget_) | 138 if (!status_area_widget_) |
| 156 return; | 139 return; |
| 157 // Full screen windows should hide the status area widget. | 140 // Full screen windows should hide the status area widget. |
| 158 bool has_fullscreen = window_util::HasFullscreenWindow(windows()); | 141 bool has_fullscreen = window_util::HasFullscreenWindow(windows()); |
| 159 bool widget_visible = status_area_widget_->IsVisible(); | 142 bool widget_visible = status_area_widget_->IsVisible(); |
| 160 if (has_fullscreen && widget_visible) | 143 if (has_fullscreen && widget_visible) |
| 161 status_area_widget_->Hide(); | 144 status_area_widget_->Hide(); |
| 162 else if (!has_fullscreen && !widget_visible) | 145 else if (!has_fullscreen && !widget_visible) |
| 163 status_area_widget_->Show(); | 146 status_area_widget_->Show(); |
| 164 } | 147 } |
| 165 | 148 |
| 166 void CompactLayoutManager::AnimateSlideTo(int offset_x) { | 149 void CompactLayoutManager::AnimateSlideTo(int offset_x) { |
| 167 ui::ScopedLayerAnimationSettings settings( | 150 // If we were waiting for another implicit animation to complete, forget |
| 168 GetDefaultContainerLayer()->GetAnimator()); | 151 // about it since we're about to start observing a new animation. |
| 169 settings.AddObserver(this); | 152 StopObservingImplicitAnimations(); |
| 153 ScopedVector<ui::ScopedLayerAnimationSettings> settings; | |
|
sky
2012/02/13 22:21:13
Is there a reason you're creating this outside the
| |
| 170 ui::Transform transform; | 154 ui::Transform transform; |
| 171 transform.ConcatTranslate(-offset_x, 0); | 155 transform.SetTranslateX(-offset_x); |
| 172 GetDefaultContainerLayer()->SetTransform(transform); // Will be animated! | 156 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate(); |
| 157 const WindowList& windows_list = shell_delegate->GetCycleWindowList( | |
| 158 ShellDelegate::SOURCE_KEYBOARD, | |
| 159 ShellDelegate::ORDER_LINEAR); | |
| 160 for (WindowListConstIter const_it = windows_list.begin(); | |
| 161 const_it != windows_list.end(); | |
| 162 ++const_it) { | |
| 163 settings.push_back(new ui::ScopedLayerAnimationSettings( | |
| 164 (*const_it)->layer()->GetAnimator())); | |
| 165 settings[settings.size() - 1]->AddObserver(this); | |
| 166 (*const_it)->layer()->SetTransform(transform); | |
|
alicet1
2012/02/13 22:32:46
I'm not sure this will work properly -- this will
| |
| 167 } | |
| 173 } | 168 } |
| 174 | 169 |
| 175 void CompactLayoutManager::LayoutWindows(aura::Window* skip) { | 170 void CompactLayoutManager::LayoutWindows(aura::Window* skip) { |
| 176 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate(); | 171 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate(); |
| 177 const WindowList& windows_list = shell_delegate->GetCycleWindowList( | 172 const WindowList& windows_list = shell_delegate->GetCycleWindowList( |
| 178 ShellDelegate::SOURCE_KEYBOARD, | 173 ShellDelegate::SOURCE_KEYBOARD, |
| 179 ShellDelegate::ORDER_LINEAR); | 174 ShellDelegate::ORDER_LINEAR); |
| 180 int new_x = 0; | 175 int new_x = 0; |
| 181 for (WindowListConstIter const_it = windows_list.begin(); | 176 for (WindowListConstIter const_it = windows_list.begin(); |
| 182 const_it != windows_list.end(); | 177 const_it != windows_list.end(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 void CompactLayoutManager::SwitchToReplacementWindow() { | 232 void CompactLayoutManager::SwitchToReplacementWindow() { |
| 238 current_window_ = FindReplacementWindow(current_window_); | 233 current_window_ = FindReplacementWindow(current_window_); |
| 239 if (current_window_) { | 234 if (current_window_) { |
| 240 ActivateWindow(current_window_); | 235 ActivateWindow(current_window_); |
| 241 AnimateSlideTo(current_window_->bounds().x()); | 236 AnimateSlideTo(current_window_->bounds().x()); |
| 242 } | 237 } |
| 243 } | 238 } |
| 244 | 239 |
| 245 } // namespace internal | 240 } // namespace internal |
| 246 } // namespace ash | 241 } // namespace ash |
| OLD | NEW |