| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "athena/wm/window_overview_mode.h" | 5 #include "athena/wm/window_overview_mode.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "athena/common/closure_animation_observer.h" | 11 #include "athena/common/closure_animation_observer.h" |
| 12 #include "athena/wm/public/window_list_provider.h" | |
| 13 #include "base/bind.h" | 12 #include "base/bind.h" |
| 14 #include "base/macros.h" | 13 #include "base/macros.h" |
| 15 #include "ui/aura/scoped_window_targeter.h" | 14 #include "ui/aura/scoped_window_targeter.h" |
| 16 #include "ui/aura/window.h" | 15 #include "ui/aura/window.h" |
| 17 #include "ui/aura/window_delegate.h" | 16 #include "ui/aura/window_delegate.h" |
| 18 #include "ui/aura/window_property.h" | 17 #include "ui/aura/window_property.h" |
| 19 #include "ui/aura/window_targeter.h" | 18 #include "ui/aura/window_targeter.h" |
| 20 #include "ui/aura/window_tree_host.h" | 19 #include "ui/aura/window_tree_host.h" |
| 21 #include "ui/compositor/compositor.h" | 20 #include "ui/compositor/compositor.h" |
| 22 #include "ui/compositor/compositor_animation_observer.h" | 21 #include "ui/compositor/compositor_animation_observer.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 44 } // namespace | 43 } // namespace |
| 45 | 44 |
| 46 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) | 45 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) |
| 47 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, | 46 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, |
| 48 kWindowOverviewState, | 47 kWindowOverviewState, |
| 49 NULL) | 48 NULL) |
| 50 namespace athena { | 49 namespace athena { |
| 51 | 50 |
| 52 namespace { | 51 namespace { |
| 53 | 52 |
| 53 bool ShouldShowWindowInOverviewMode(aura::Window* window) { |
| 54 return window->type() == ui::wm::WINDOW_TYPE_NORMAL; |
| 55 } |
| 56 |
| 54 // Gets the transform for the window in its current state. | 57 // Gets the transform for the window in its current state. |
| 55 gfx::Transform GetTransformForState(WindowOverviewState* state) { | 58 gfx::Transform GetTransformForState(WindowOverviewState* state) { |
| 56 return gfx::Tween::TransformValueBetween(state->progress, | 59 return gfx::Tween::TransformValueBetween(state->progress, |
| 57 state->top, | 60 state->top, |
| 58 state->bottom); | 61 state->bottom); |
| 59 } | 62 } |
| 60 | 63 |
| 61 // Sets the progress-state for the window in the overview mode. | 64 // Sets the progress-state for the window in the overview mode. |
| 62 void SetWindowProgress(aura::Window* window, float progress) { | 65 void SetWindowProgress(aura::Window* window, float progress) { |
| 63 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 66 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 101 |
| 99 aura::Window* target_; | 102 aura::Window* target_; |
| 100 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); | 103 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); |
| 101 }; | 104 }; |
| 102 | 105 |
| 103 class WindowOverviewModeImpl : public WindowOverviewMode, | 106 class WindowOverviewModeImpl : public WindowOverviewMode, |
| 104 public ui::EventHandler, | 107 public ui::EventHandler, |
| 105 public ui::CompositorAnimationObserver { | 108 public ui::CompositorAnimationObserver { |
| 106 public: | 109 public: |
| 107 WindowOverviewModeImpl(aura::Window* container, | 110 WindowOverviewModeImpl(aura::Window* container, |
| 108 const WindowListProvider* window_list_provider, | |
| 109 WindowOverviewModeDelegate* delegate) | 111 WindowOverviewModeDelegate* delegate) |
| 110 : container_(container), | 112 : container_(container), |
| 111 window_list_provider_(window_list_provider), | |
| 112 delegate_(delegate), | 113 delegate_(delegate), |
| 113 scoped_targeter_(new aura::ScopedWindowTargeter( | 114 scoped_targeter_(new aura::ScopedWindowTargeter( |
| 114 container, | 115 container, |
| 115 scoped_ptr<ui::EventTargeter>( | 116 scoped_ptr<ui::EventTargeter>( |
| 116 new StaticWindowTargeter(container)))), | 117 new StaticWindowTargeter(container)))), |
| 117 dragged_window_(NULL) { | 118 dragged_window_(NULL) { |
| 118 container_->set_target_handler(this); | 119 container_->set_target_handler(this); |
| 119 | 120 |
| 120 // Prepare the desired transforms for all the windows, and set the initial | 121 // Prepare the desired transforms for all the windows, and set the initial |
| 121 // state on the windows. | 122 // state on the windows. |
| 122 ComputeTerminalStatesForAllWindows(); | 123 ComputeTerminalStatesForAllWindows(); |
| 123 SetInitialWindowStates(); | 124 SetInitialWindowStates(); |
| 124 } | 125 } |
| 125 | 126 |
| 126 virtual ~WindowOverviewModeImpl() { | 127 virtual ~WindowOverviewModeImpl() { |
| 127 container_->set_target_handler(container_->delegate()); | 128 container_->set_target_handler(container_->delegate()); |
| 128 RemoveAnimationObserver(); | 129 RemoveAnimationObserver(); |
| 129 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | 130 const aura::Window::Windows& windows = container_->children(); |
| 130 if (windows.empty()) | 131 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
| 131 return; | 132 iter != windows.end(); |
| 132 std::for_each(windows.begin(), windows.end(), &RestoreWindowState); | 133 ++iter) { |
| 134 if ((*iter)->GetProperty(kWindowOverviewState)) |
| 135 RestoreWindowState(*iter); |
| 136 } |
| 133 } | 137 } |
| 134 | 138 |
| 135 private: | 139 private: |
| 136 // Computes the transforms for all windows in both the topmost and bottom-most | 140 // Computes the transforms for all windows in both the topmost and bottom-most |
| 137 // positions. The transforms are set in the |kWindowOverviewState| property of | 141 // positions. The transforms are set in the |kWindowOverviewState| property of |
| 138 // the windows. | 142 // the windows. |
| 139 void ComputeTerminalStatesForAllWindows() { | 143 void ComputeTerminalStatesForAllWindows() { |
| 140 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | 144 const aura::Window::Windows& windows = container_->children(); |
| 141 size_t window_count = windows.size(); | 145 size_t window_count = std::count_if(windows.begin(), windows.end(), |
| 146 ShouldShowWindowInOverviewMode); |
| 147 |
| 142 size_t index = 0; | 148 size_t index = 0; |
| 143 const gfx::Size container_size = container_->bounds().size(); | 149 const gfx::Size container_size = container_->bounds().size(); |
| 144 | 150 |
| 145 const int kGapBetweenWindowsBottom = 10; | 151 const int kGapBetweenWindowsBottom = 10; |
| 146 const int kGapBetweenWindowsTop = 5; | 152 const int kGapBetweenWindowsTop = 5; |
| 147 | 153 |
| 148 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | 154 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
| 149 iter != windows.rend(); | 155 iter != windows.rend(); |
| 150 ++iter, ++index) { | 156 ++iter) { |
| 151 aura::Window* window = (*iter); | 157 aura::Window* window = (*iter); |
| 158 if (!ShouldShowWindowInOverviewMode(window)) |
| 159 continue; |
| 152 | 160 |
| 153 gfx::Transform top_transform; | 161 gfx::Transform top_transform; |
| 154 int top = (window_count - index - 1) * kGapBetweenWindowsTop; | 162 int top = (window_count - index - 1) * kGapBetweenWindowsTop; |
| 155 float x_translate = container_size.width() * (1 - kMinScale) / 2.; | 163 float x_translate = container_size.width() * (1 - kMinScale) / 2.; |
| 156 top_transform.Translate(x_translate, top); | 164 top_transform.Translate(x_translate, top); |
| 157 top_transform.Scale(kMinScale, kMinScale); | 165 top_transform.Scale(kMinScale, kMinScale); |
| 158 | 166 |
| 159 gfx::Transform bottom_transform; | 167 gfx::Transform bottom_transform; |
| 160 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); | 168 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); |
| 161 x_translate = container_size.width() * (1 - kMaxScale) / 2.; | 169 x_translate = container_size.width() * (1 - kMaxScale) / 2.; |
| 162 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); | 170 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); |
| 163 bottom_transform.Scale(kMaxScale, kMaxScale); | 171 bottom_transform.Scale(kMaxScale, kMaxScale); |
| 164 | 172 |
| 165 WindowOverviewState* state = new WindowOverviewState; | 173 WindowOverviewState* state = new WindowOverviewState; |
| 166 state->top = top_transform; | 174 state->top = top_transform; |
| 167 state->bottom = bottom_transform; | 175 state->bottom = bottom_transform; |
| 168 state->progress = 0.f; | 176 state->progress = 0.f; |
| 169 window->SetProperty(kWindowOverviewState, state); | 177 window->SetProperty(kWindowOverviewState, state); |
| 170 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); | 178 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); |
| 179 |
| 180 index++; |
| 171 } | 181 } |
| 172 } | 182 } |
| 173 | 183 |
| 174 // Sets the initial position for the windows for the overview mode. | 184 // Sets the initial position for the windows for the overview mode. |
| 175 void SetInitialWindowStates() { | 185 void SetInitialWindowStates() { |
| 176 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | |
| 177 size_t window_count = windows.size(); | |
| 178 // The initial overview state of the topmost three windows. | 186 // The initial overview state of the topmost three windows. |
| 179 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; | 187 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; |
| 180 for (size_t i = 0; i < window_count; ++i) { | 188 size_t index = 0; |
| 189 const aura::Window::Windows& windows = container_->children(); |
| 190 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
| 191 iter != windows.rend(); |
| 192 ++iter) { |
| 193 aura::Window* window = (*iter); |
| 194 if (!window->GetProperty(kWindowOverviewState)) |
| 195 continue; |
| 196 |
| 181 float progress = 0.f; | 197 float progress = 0.f; |
| 182 aura::Window* window = windows[window_count - 1 - i]; | 198 if (index < arraysize(kInitialProgress)) |
| 183 if (i < arraysize(kInitialProgress)) | 199 progress = kInitialProgress[index]; |
| 184 progress = kInitialProgress[i]; | |
| 185 | 200 |
| 186 scoped_refptr<ui::LayerAnimator> animator = | 201 scoped_refptr<ui::LayerAnimator> animator = |
| 187 window->layer()->GetAnimator(); | 202 window->layer()->GetAnimator(); |
| 188 | 203 |
| 189 // Unset any in-progress animation. | 204 // Unset any in-progress animation. |
| 190 { | 205 { |
| 191 ui::ScopedLayerAnimationSettings settings(animator); | 206 ui::ScopedLayerAnimationSettings settings(animator); |
| 192 settings.SetPreemptionStrategy( | 207 settings.SetPreemptionStrategy( |
| 193 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); | 208 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); |
| 194 window->Show(); | 209 window->Show(); |
| 195 window->SetTransform(gfx::Transform()); | 210 window->SetTransform(gfx::Transform()); |
| 196 } | 211 } |
| 197 // Setup the animation. | 212 // Setup the animation. |
| 198 { | 213 { |
| 199 ui::ScopedLayerAnimationSettings settings(animator); | 214 ui::ScopedLayerAnimationSettings settings(animator); |
| 200 settings.SetPreemptionStrategy( | 215 settings.SetPreemptionStrategy( |
| 201 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 216 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 202 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 217 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
| 203 SetWindowProgress(window, progress); | 218 SetWindowProgress(window, progress); |
| 204 } | 219 } |
| 220 index++; |
| 205 } | 221 } |
| 206 } | 222 } |
| 207 | 223 |
| 208 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { | 224 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { |
| 209 CHECK_EQ(container_, event->target()); | 225 CHECK_EQ(container_, event->target()); |
| 210 // Find the old targeter to find the target of the event. | 226 // Find the old targeter to find the target of the event. |
| 211 ui::EventTarget* window = container_; | 227 ui::EventTarget* window = container_; |
| 212 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); | 228 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); |
| 213 while (!targeter && window->GetParentTarget()) { | 229 while (!targeter && window->GetParentTarget()) { |
| 214 window = window->GetParentTarget(); | 230 window = window->GetParentTarget(); |
| 215 targeter = window->GetEventTargeter(); | 231 targeter = window->GetEventTargeter(); |
| 216 } | 232 } |
| 217 if (!targeter) | 233 if (!targeter) |
| 218 return NULL; | 234 return NULL; |
| 219 aura::Window* target = static_cast<aura::Window*>( | 235 aura::Window* target = static_cast<aura::Window*>( |
| 220 targeter->FindTargetForLocatedEvent(container_, event)); | 236 targeter->FindTargetForLocatedEvent(container_, event)); |
| 221 while (target && target->parent() != container_) | 237 while (target && target->parent() != container_) |
| 222 target = target->parent(); | 238 target = target->parent(); |
| 223 return target; | 239 return target; |
| 224 } | 240 } |
| 225 | 241 |
| 226 // Scroll the window list by |delta_y| amount. |delta_y| is negative when | 242 // Scroll the window list by |delta_y| amount. |delta_y| is negative when |
| 227 // scrolling up; and positive when scrolling down. | 243 // scrolling up; and positive when scrolling down. |
| 228 void DoScroll(float delta_y) { | 244 void DoScroll(float delta_y) { |
| 229 const float kEpsilon = 1e-3f; | 245 const float kEpsilon = 1e-3f; |
| 230 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); | 246 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); |
| 231 aura::Window::Windows windows = window_list_provider_->GetWindowList(); | 247 const aura::Window::Windows& windows = container_->children(); |
| 232 if (delta_y < 0) { | 248 if (delta_y < 0) { |
| 233 // Scroll up. Start with the top-most (i.e. behind-most in terms of | 249 // Scroll up. Start with the top-most (i.e. behind-most in terms of |
| 234 // z-index) window, and try to scroll them up. | 250 // z-index) window, and try to scroll them up. |
| 235 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 251 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
| 236 delta_y_p > kEpsilon && iter != windows.end(); | 252 delta_y_p > kEpsilon && iter != windows.end(); |
| 237 ++iter) { | 253 ++iter) { |
| 238 aura::Window* window = (*iter); | 254 aura::Window* window = (*iter); |
| 239 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 255 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 256 if (!state) |
| 257 continue; |
| 240 if (state->progress > kEpsilon) { | 258 if (state->progress > kEpsilon) { |
| 241 // It is possible to scroll |window| up. Scroll it up, and update | 259 // It is possible to scroll |window| up. Scroll it up, and update |
| 242 // |delta_y_p| for the next window. | 260 // |delta_y_p| for the next window. |
| 243 float apply = delta_y_p * state->progress; | 261 float apply = delta_y_p * state->progress; |
| 244 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); | 262 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); |
| 245 delta_y_p -= apply; | 263 delta_y_p -= apply; |
| 246 } | 264 } |
| 247 } | 265 } |
| 248 } else { | 266 } else { |
| 249 // Scroll down. Start with the bottom-most (i.e. front-most in terms of | 267 // Scroll down. Start with the bottom-most (i.e. front-most in terms of |
| 250 // z-index) window, and try to scroll them down. | 268 // z-index) window, and try to scroll them down. |
| 251 aura::Window::Windows::const_reverse_iterator iter; | 269 for (aura::Window::Windows::const_reverse_iterator iter = |
| 252 for (iter = windows.rbegin(); | 270 windows.rbegin(); |
| 253 delta_y_p > kEpsilon && iter != windows.rend(); | 271 delta_y_p > kEpsilon && iter != windows.rend(); |
| 254 ++iter) { | 272 ++iter) { |
| 255 aura::Window* window = (*iter); | 273 aura::Window* window = (*iter); |
| 256 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 274 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 275 if (!state) |
| 276 continue; |
| 257 if (1.f - state->progress > kEpsilon) { | 277 if (1.f - state->progress > kEpsilon) { |
| 258 // It is possible to scroll |window| down. Scroll it down, and update | 278 // It is possible to scroll |window| down. Scroll it down, and update |
| 259 // |delta_y_p| for the next window. | 279 // |delta_y_p| for the next window. |
| 260 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); | 280 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); |
| 261 delta_y_p /= 2.f; | 281 delta_y_p /= 2.f; |
| 262 } | 282 } |
| 263 } | 283 } |
| 264 } | 284 } |
| 265 } | 285 } |
| 266 | 286 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 482 } |
| 463 } | 483 } |
| 464 | 484 |
| 465 const int kMinDistanceForDismissal = 300; | 485 const int kMinDistanceForDismissal = 300; |
| 466 const float kMinScale = 0.6f; | 486 const float kMinScale = 0.6f; |
| 467 const float kMaxScale = 0.95f; | 487 const float kMaxScale = 0.95f; |
| 468 const float kMaxOpacity = 1.0f; | 488 const float kMaxOpacity = 1.0f; |
| 469 const float kMinOpacity = 0.2f; | 489 const float kMinOpacity = 0.2f; |
| 470 | 490 |
| 471 aura::Window* container_; | 491 aura::Window* container_; |
| 472 // Provider of the stack of windows to show in the overview mode. Not owned. | |
| 473 const WindowListProvider* window_list_provider_; | |
| 474 WindowOverviewModeDelegate* delegate_; | 492 WindowOverviewModeDelegate* delegate_; |
| 475 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 493 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
| 476 scoped_ptr<ui::FlingCurve> fling_; | 494 scoped_ptr<ui::FlingCurve> fling_; |
| 477 | 495 |
| 478 aura::Window* dragged_window_; | 496 aura::Window* dragged_window_; |
| 479 gfx::Point dragged_start_location_; | 497 gfx::Point dragged_start_location_; |
| 480 | 498 |
| 481 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 499 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
| 482 }; | 500 }; |
| 483 | 501 |
| 484 } // namespace | 502 } // namespace |
| 485 | 503 |
| 486 // static | 504 // static |
| 487 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 505 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
| 488 aura::Window* container, | 506 aura::Window* container, |
| 489 const WindowListProvider* window_list_provider, | |
| 490 WindowOverviewModeDelegate* delegate) { | 507 WindowOverviewModeDelegate* delegate) { |
| 491 return scoped_ptr<WindowOverviewMode>( | 508 return scoped_ptr<WindowOverviewMode>( |
| 492 new WindowOverviewModeImpl(container, window_list_provider, delegate)); | 509 new WindowOverviewModeImpl(container, delegate)); |
| 493 } | 510 } |
| 494 | 511 |
| 495 } // namespace athena | 512 } // namespace athena |
| OLD | NEW |