| 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/wm/public/window_list_provider.h" |
| 11 #include "base/bind.h" | 12 #include "base/bind.h" |
| 12 #include "base/macros.h" | 13 #include "base/macros.h" |
| 13 #include "ui/aura/scoped_window_targeter.h" | 14 #include "ui/aura/scoped_window_targeter.h" |
| 14 #include "ui/aura/window.h" | 15 #include "ui/aura/window.h" |
| 15 #include "ui/aura/window_delegate.h" | 16 #include "ui/aura/window_delegate.h" |
| 16 #include "ui/aura/window_property.h" | 17 #include "ui/aura/window_property.h" |
| 17 #include "ui/aura/window_targeter.h" | 18 #include "ui/aura/window_targeter.h" |
| 18 #include "ui/aura/window_tree_host.h" | 19 #include "ui/aura/window_tree_host.h" |
| 19 #include "ui/compositor/compositor.h" | 20 #include "ui/compositor/compositor.h" |
| 20 #include "ui/compositor/compositor_animation_observer.h" | 21 #include "ui/compositor/compositor_animation_observer.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 } // namespace | 68 } // namespace |
| 68 | 69 |
| 69 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) | 70 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) |
| 70 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, | 71 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, |
| 71 kWindowOverviewState, | 72 kWindowOverviewState, |
| 72 NULL) | 73 NULL) |
| 73 namespace athena { | 74 namespace athena { |
| 74 | 75 |
| 75 namespace { | 76 namespace { |
| 76 | 77 |
| 77 bool ShouldShowWindowInOverviewMode(aura::Window* window) { | |
| 78 return window->type() == ui::wm::WINDOW_TYPE_NORMAL; | |
| 79 } | |
| 80 | |
| 81 // Gets the transform for the window in its current state. | 78 // Gets the transform for the window in its current state. |
| 82 gfx::Transform GetTransformForState(WindowOverviewState* state) { | 79 gfx::Transform GetTransformForState(WindowOverviewState* state) { |
| 83 return gfx::Tween::TransformValueBetween(state->progress, | 80 return gfx::Tween::TransformValueBetween(state->progress, |
| 84 state->top, | 81 state->top, |
| 85 state->bottom); | 82 state->bottom); |
| 86 } | 83 } |
| 87 | 84 |
| 88 // Sets the progress-state for the window in the overview mode. | 85 // Sets the progress-state for the window in the overview mode. |
| 89 void SetWindowProgress(aura::Window* window, float progress) { | 86 void SetWindowProgress(aura::Window* window, float progress) { |
| 90 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 87 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 | 121 |
| 125 aura::Window* target_; | 122 aura::Window* target_; |
| 126 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); | 123 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); |
| 127 }; | 124 }; |
| 128 | 125 |
| 129 class WindowOverviewModeImpl : public WindowOverviewMode, | 126 class WindowOverviewModeImpl : public WindowOverviewMode, |
| 130 public ui::EventHandler, | 127 public ui::EventHandler, |
| 131 public ui::CompositorAnimationObserver { | 128 public ui::CompositorAnimationObserver { |
| 132 public: | 129 public: |
| 133 WindowOverviewModeImpl(aura::Window* container, | 130 WindowOverviewModeImpl(aura::Window* container, |
| 131 const WindowListProvider* window_list_provider, |
| 134 WindowOverviewModeDelegate* delegate) | 132 WindowOverviewModeDelegate* delegate) |
| 135 : container_(container), | 133 : container_(container), |
| 134 window_list_provider_(window_list_provider), |
| 136 delegate_(delegate), | 135 delegate_(delegate), |
| 137 scoped_targeter_(new aura::ScopedWindowTargeter( | 136 scoped_targeter_(new aura::ScopedWindowTargeter( |
| 138 container, | 137 container, |
| 139 scoped_ptr<ui::EventTargeter>( | 138 scoped_ptr<ui::EventTargeter>( |
| 140 new StaticWindowTargeter(container)))), | 139 new StaticWindowTargeter(container)))), |
| 141 dragged_window_(NULL) { | 140 dragged_window_(NULL) { |
| 142 container_->set_target_handler(this); | 141 container_->set_target_handler(this); |
| 143 | 142 |
| 144 // Prepare the desired transforms for all the windows, and set the initial | 143 // Prepare the desired transforms for all the windows, and set the initial |
| 145 // state on the windows. | 144 // state on the windows. |
| 146 ComputeTerminalStatesForAllWindows(); | 145 ComputeTerminalStatesForAllWindows(); |
| 147 SetInitialWindowStates(); | 146 SetInitialWindowStates(); |
| 148 } | 147 } |
| 149 | 148 |
| 150 virtual ~WindowOverviewModeImpl() { | 149 virtual ~WindowOverviewModeImpl() { |
| 151 container_->set_target_handler(container_->delegate()); | 150 container_->set_target_handler(container_->delegate()); |
| 152 RemoveAnimationObserver(); | 151 RemoveAnimationObserver(); |
| 153 const aura::Window::Windows& windows = container_->children(); | 152 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 154 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 153 if (windows.empty()) |
| 155 iter != windows.end(); | 154 return; |
| 156 ++iter) { | 155 std::for_each(windows.begin(), windows.end(), &RestoreWindowState); |
| 157 if ((*iter)->GetProperty(kWindowOverviewState)) | |
| 158 RestoreWindowState(*iter); | |
| 159 } | |
| 160 } | 156 } |
| 161 | 157 |
| 162 private: | 158 private: |
| 163 // Computes the transforms for all windows in both the topmost and bottom-most | 159 // Computes the transforms for all windows in both the topmost and bottom-most |
| 164 // positions. The transforms are set in the |kWindowOverviewState| property of | 160 // positions. The transforms are set in the |kWindowOverviewState| property of |
| 165 // the windows. | 161 // the windows. |
| 166 void ComputeTerminalStatesForAllWindows() { | 162 void ComputeTerminalStatesForAllWindows() { |
| 167 const aura::Window::Windows& windows = container_->children(); | 163 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 168 size_t window_count = std::count_if(windows.begin(), windows.end(), | 164 size_t window_count = windows.size(); |
| 169 ShouldShowWindowInOverviewMode); | |
| 170 | |
| 171 size_t index = 0; | 165 size_t index = 0; |
| 172 const gfx::Size container_size = container_->bounds().size(); | 166 const gfx::Size container_size = container_->bounds().size(); |
| 173 | 167 |
| 174 const int kGapBetweenWindowsBottom = 10; | 168 const int kGapBetweenWindowsBottom = 10; |
| 175 const int kGapBetweenWindowsTop = 5; | 169 const int kGapBetweenWindowsTop = 5; |
| 176 | 170 |
| 177 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | 171 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
| 178 iter != windows.rend(); | 172 iter != windows.rend(); |
| 179 ++iter) { | 173 ++iter, ++index) { |
| 180 aura::Window* window = (*iter); | 174 aura::Window* window = (*iter); |
| 181 if (!ShouldShowWindowInOverviewMode(window)) | |
| 182 continue; | |
| 183 | 175 |
| 184 gfx::Transform top_transform; | 176 gfx::Transform top_transform; |
| 185 int top = (window_count - index - 1) * kGapBetweenWindowsTop; | 177 int top = (window_count - index - 1) * kGapBetweenWindowsTop; |
| 186 float x_translate = container_size.width() * (1 - kMinScale) / 2.; | 178 float x_translate = container_size.width() * (1 - kMinScale) / 2.; |
| 187 top_transform.Translate(x_translate, top); | 179 top_transform.Translate(x_translate, top); |
| 188 top_transform.Scale(kMinScale, kMinScale); | 180 top_transform.Scale(kMinScale, kMinScale); |
| 189 | 181 |
| 190 gfx::Transform bottom_transform; | 182 gfx::Transform bottom_transform; |
| 191 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); | 183 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); |
| 192 x_translate = container_size.width() * (1 - kMaxScale) / 2.; | 184 x_translate = container_size.width() * (1 - kMaxScale) / 2.; |
| 193 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); | 185 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); |
| 194 bottom_transform.Scale(kMaxScale, kMaxScale); | 186 bottom_transform.Scale(kMaxScale, kMaxScale); |
| 195 | 187 |
| 196 WindowOverviewState* state = new WindowOverviewState; | 188 WindowOverviewState* state = new WindowOverviewState; |
| 197 state->top = top_transform; | 189 state->top = top_transform; |
| 198 state->bottom = bottom_transform; | 190 state->bottom = bottom_transform; |
| 199 state->progress = 0.f; | 191 state->progress = 0.f; |
| 200 state->shadow = CreateShadowForWindow(window); | 192 state->shadow = CreateShadowForWindow(window); |
| 201 window->SetProperty(kWindowOverviewState, state); | 193 window->SetProperty(kWindowOverviewState, state); |
| 202 | |
| 203 index++; | |
| 204 } | 194 } |
| 205 } | 195 } |
| 206 | 196 |
| 207 // Sets the initial position for the windows for the overview mode. | 197 // Sets the initial position for the windows for the overview mode. |
| 208 void SetInitialWindowStates() { | 198 void SetInitialWindowStates() { |
| 199 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 200 size_t window_count = windows.size(); |
| 209 // The initial overview state of the topmost three windows. | 201 // The initial overview state of the topmost three windows. |
| 210 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; | 202 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; |
| 211 size_t index = 0; | 203 for (size_t i = 0; i < window_count; ++i) { |
| 212 const aura::Window::Windows& windows = container_->children(); | |
| 213 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | |
| 214 iter != windows.rend(); | |
| 215 ++iter) { | |
| 216 aura::Window* window = (*iter); | |
| 217 if (!window->GetProperty(kWindowOverviewState)) | |
| 218 continue; | |
| 219 | |
| 220 float progress = 0.f; | 204 float progress = 0.f; |
| 221 if (index < arraysize(kInitialProgress)) | 205 aura::Window* window = windows[window_count - 1 - i]; |
| 222 progress = kInitialProgress[index]; | 206 if (i < arraysize(kInitialProgress)) |
| 207 progress = kInitialProgress[i]; |
| 223 | 208 |
| 224 scoped_refptr<ui::LayerAnimator> animator = | 209 scoped_refptr<ui::LayerAnimator> animator = |
| 225 window->layer()->GetAnimator(); | 210 window->layer()->GetAnimator(); |
| 226 | 211 |
| 227 // Unset any in-progress animation. | 212 // Unset any in-progress animation. |
| 228 { | 213 { |
| 229 ui::ScopedLayerAnimationSettings settings(animator); | 214 ui::ScopedLayerAnimationSettings settings(animator); |
| 230 settings.SetPreemptionStrategy( | 215 settings.SetPreemptionStrategy( |
| 231 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); | 216 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); |
| 232 window->Show(); | 217 window->Show(); |
| 233 window->SetTransform(gfx::Transform()); | 218 window->SetTransform(gfx::Transform()); |
| 234 } | 219 } |
| 235 // Setup the animation. | 220 // Setup the animation. |
| 236 { | 221 { |
| 237 ui::ScopedLayerAnimationSettings settings(animator); | 222 ui::ScopedLayerAnimationSettings settings(animator); |
| 238 settings.SetPreemptionStrategy( | 223 settings.SetPreemptionStrategy( |
| 239 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 224 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 240 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 225 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
| 241 SetWindowProgress(window, progress); | 226 SetWindowProgress(window, progress); |
| 242 } | 227 } |
| 243 index++; | |
| 244 } | 228 } |
| 245 } | 229 } |
| 246 | 230 |
| 247 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { | 231 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { |
| 248 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); | 232 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); |
| 249 shadow->Init(wm::Shadow::STYLE_ACTIVE); | 233 shadow->Init(wm::Shadow::STYLE_ACTIVE); |
| 250 shadow->SetContentBounds(gfx::Rect(window->bounds().size())); | 234 shadow->SetContentBounds(gfx::Rect(container_->bounds().size())); |
| 251 shadow->layer()->SetVisible(true); | 235 shadow->layer()->SetVisible(true); |
| 252 window->layer()->Add(shadow->layer()); | 236 window->layer()->Add(shadow->layer()); |
| 253 return shadow.Pass(); | 237 return shadow.Pass(); |
| 254 } | 238 } |
| 255 | 239 |
| 256 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { | 240 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { |
| 257 CHECK_EQ(container_, event->target()); | 241 CHECK_EQ(container_, event->target()); |
| 258 // Find the old targeter to find the target of the event. | 242 // Find the old targeter to find the target of the event. |
| 259 ui::EventTarget* window = container_; | 243 ui::EventTarget* window = container_; |
| 260 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); | 244 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); |
| 261 while (!targeter && window->GetParentTarget()) { | 245 while (!targeter && window->GetParentTarget()) { |
| 262 window = window->GetParentTarget(); | 246 window = window->GetParentTarget(); |
| 263 targeter = window->GetEventTargeter(); | 247 targeter = window->GetEventTargeter(); |
| 264 } | 248 } |
| 265 if (!targeter) | 249 if (!targeter) |
| 266 return NULL; | 250 return NULL; |
| 267 aura::Window* target = static_cast<aura::Window*>( | 251 aura::Window* target = static_cast<aura::Window*>( |
| 268 targeter->FindTargetForLocatedEvent(container_, event)); | 252 targeter->FindTargetForLocatedEvent(container_, event)); |
| 269 while (target && target->parent() != container_) | 253 while (target && target->parent() != container_) |
| 270 target = target->parent(); | 254 target = target->parent(); |
| 271 return target; | 255 return target; |
| 272 } | 256 } |
| 273 | 257 |
| 274 // Scroll the window list by |delta_y| amount. |delta_y| is negative when | 258 // Scroll the window list by |delta_y| amount. |delta_y| is negative when |
| 275 // scrolling up; and positive when scrolling down. | 259 // scrolling up; and positive when scrolling down. |
| 276 void DoScroll(float delta_y) { | 260 void DoScroll(float delta_y) { |
| 277 const float kEpsilon = 1e-3f; | 261 const float kEpsilon = 1e-3f; |
| 278 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); | 262 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); |
| 279 const aura::Window::Windows& windows = container_->children(); | 263 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 280 if (delta_y < 0) { | 264 if (delta_y < 0) { |
| 281 // Scroll up. Start with the top-most (i.e. behind-most in terms of | 265 // Scroll up. Start with the top-most (i.e. behind-most in terms of |
| 282 // z-index) window, and try to scroll them up. | 266 // z-index) window, and try to scroll them up. |
| 283 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 267 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
| 284 delta_y_p > kEpsilon && iter != windows.end(); | 268 delta_y_p > kEpsilon && iter != windows.end(); |
| 285 ++iter) { | 269 ++iter) { |
| 286 aura::Window* window = (*iter); | 270 aura::Window* window = (*iter); |
| 287 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 271 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 288 if (!state) | |
| 289 continue; | |
| 290 if (state->progress > kEpsilon) { | 272 if (state->progress > kEpsilon) { |
| 291 // It is possible to scroll |window| up. Scroll it up, and update | 273 // It is possible to scroll |window| up. Scroll it up, and update |
| 292 // |delta_y_p| for the next window. | 274 // |delta_y_p| for the next window. |
| 293 float apply = delta_y_p * state->progress; | 275 float apply = delta_y_p * state->progress; |
| 294 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); | 276 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); |
| 295 delta_y_p -= apply; | 277 delta_y_p -= apply; |
| 296 } | 278 } |
| 297 } | 279 } |
| 298 } else { | 280 } else { |
| 299 // Scroll down. Start with the bottom-most (i.e. front-most in terms of | 281 // Scroll down. Start with the bottom-most (i.e. front-most in terms of |
| 300 // z-index) window, and try to scroll them down. | 282 // z-index) window, and try to scroll them down. |
| 301 for (aura::Window::Windows::const_reverse_iterator iter = | 283 aura::Window::Windows::const_reverse_iterator iter; |
| 302 windows.rbegin(); | 284 for (iter = windows.rbegin(); |
| 303 delta_y_p > kEpsilon && iter != windows.rend(); | 285 delta_y_p > kEpsilon && iter != windows.rend(); |
| 304 ++iter) { | 286 ++iter) { |
| 305 aura::Window* window = (*iter); | 287 aura::Window* window = (*iter); |
| 306 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 288 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 307 if (!state) | |
| 308 continue; | |
| 309 if (1.f - state->progress > kEpsilon) { | 289 if (1.f - state->progress > kEpsilon) { |
| 310 // It is possible to scroll |window| down. Scroll it down, and update | 290 // It is possible to scroll |window| down. Scroll it down, and update |
| 311 // |delta_y_p| for the next window. | 291 // |delta_y_p| for the next window. |
| 312 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); | 292 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); |
| 313 delta_y_p /= 2.f; | 293 delta_y_p /= 2.f; |
| 314 } | 294 } |
| 315 } | 295 } |
| 316 } | 296 } |
| 317 } | 297 } |
| 318 | 298 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 } | 494 } |
| 515 } | 495 } |
| 516 | 496 |
| 517 const int kMinDistanceForDismissal = 300; | 497 const int kMinDistanceForDismissal = 300; |
| 518 const float kMinScale = 0.6f; | 498 const float kMinScale = 0.6f; |
| 519 const float kMaxScale = 0.95f; | 499 const float kMaxScale = 0.95f; |
| 520 const float kMaxOpacity = 1.0f; | 500 const float kMaxOpacity = 1.0f; |
| 521 const float kMinOpacity = 0.2f; | 501 const float kMinOpacity = 0.2f; |
| 522 | 502 |
| 523 aura::Window* container_; | 503 aura::Window* container_; |
| 504 // Provider of the stack of windows to show in the overview mode. Not owned. |
| 505 const WindowListProvider* window_list_provider_; |
| 524 WindowOverviewModeDelegate* delegate_; | 506 WindowOverviewModeDelegate* delegate_; |
| 525 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 507 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
| 526 scoped_ptr<ui::FlingCurve> fling_; | 508 scoped_ptr<ui::FlingCurve> fling_; |
| 527 | 509 |
| 528 aura::Window* dragged_window_; | 510 aura::Window* dragged_window_; |
| 529 gfx::Point dragged_start_location_; | 511 gfx::Point dragged_start_location_; |
| 530 | 512 |
| 531 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 513 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
| 532 }; | 514 }; |
| 533 | 515 |
| 534 } // namespace | 516 } // namespace |
| 535 | 517 |
| 536 // static | 518 // static |
| 537 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 519 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
| 538 aura::Window* container, | 520 aura::Window* container, |
| 521 const WindowListProvider* window_list_provider, |
| 539 WindowOverviewModeDelegate* delegate) { | 522 WindowOverviewModeDelegate* delegate) { |
| 540 return scoped_ptr<WindowOverviewMode>( | 523 return scoped_ptr<WindowOverviewMode>( |
| 541 new WindowOverviewModeImpl(container, delegate)); | 524 new WindowOverviewModeImpl(container, window_list_provider, delegate)); |
| 542 } | 525 } |
| 543 | 526 |
| 544 } // namespace athena | 527 } // namespace athena |
| OLD | NEW |