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