| 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/macros.h" | 12 #include "base/macros.h" |
| 12 #include "ui/aura/scoped_window_targeter.h" | 13 #include "ui/aura/scoped_window_targeter.h" |
| 13 #include "ui/aura/window.h" | 14 #include "ui/aura/window.h" |
| 14 #include "ui/aura/window_delegate.h" | 15 #include "ui/aura/window_delegate.h" |
| 15 #include "ui/aura/window_property.h" | 16 #include "ui/aura/window_property.h" |
| 16 #include "ui/aura/window_targeter.h" | 17 #include "ui/aura/window_targeter.h" |
| 17 #include "ui/compositor/scoped_layer_animation_settings.h" | 18 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 18 #include "ui/events/event_handler.h" | 19 #include "ui/events/event_handler.h" |
| 19 #include "ui/gfx/transform.h" | 20 #include "ui/gfx/transform.h" |
| 20 #include "ui/wm/core/shadow.h" | 21 #include "ui/wm/core/shadow.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 38 } // namespace | 39 } // namespace |
| 39 | 40 |
| 40 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) | 41 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) |
| 41 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, | 42 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, |
| 42 kWindowOverviewState, | 43 kWindowOverviewState, |
| 43 NULL) | 44 NULL) |
| 44 namespace athena { | 45 namespace athena { |
| 45 | 46 |
| 46 namespace { | 47 namespace { |
| 47 | 48 |
| 48 bool ShouldShowWindowInOverviewMode(aura::Window* window) { | |
| 49 return window->type() == ui::wm::WINDOW_TYPE_NORMAL; | |
| 50 } | |
| 51 | |
| 52 // Sets the progress-state for the window in the overview mode. | 49 // Sets the progress-state for the window in the overview mode. |
| 53 void SetWindowProgress(aura::Window* window, float progress) { | 50 void SetWindowProgress(aura::Window* window, float progress) { |
| 54 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 51 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 55 gfx::Transform transform = | 52 gfx::Transform transform = |
| 56 gfx::Tween::TransformValueBetween(progress, state->top, state->bottom); | 53 gfx::Tween::TransformValueBetween(progress, state->top, state->bottom); |
| 57 window->SetTransform(transform); | 54 window->SetTransform(transform); |
| 58 state->progress = progress; | 55 state->progress = progress; |
| 59 } | 56 } |
| 60 | 57 |
| 61 // Resets the overview-related state for |window|. | 58 // Resets the overview-related state for |window|. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 89 } | 86 } |
| 90 | 87 |
| 91 aura::Window* target_; | 88 aura::Window* target_; |
| 92 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); | 89 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); |
| 93 }; | 90 }; |
| 94 | 91 |
| 95 class WindowOverviewModeImpl : public WindowOverviewMode, | 92 class WindowOverviewModeImpl : public WindowOverviewMode, |
| 96 public ui::EventHandler { | 93 public ui::EventHandler { |
| 97 public: | 94 public: |
| 98 WindowOverviewModeImpl(aura::Window* container, | 95 WindowOverviewModeImpl(aura::Window* container, |
| 96 const WindowListProvider* window_list_provider, |
| 99 WindowOverviewModeDelegate* delegate) | 97 WindowOverviewModeDelegate* delegate) |
| 100 : container_(container), | 98 : container_(container), |
| 99 window_list_provider_(window_list_provider), |
| 101 delegate_(delegate), | 100 delegate_(delegate), |
| 102 scoped_targeter_(new aura::ScopedWindowTargeter( | 101 scoped_targeter_(new aura::ScopedWindowTargeter( |
| 103 container, | 102 container, |
| 104 scoped_ptr<ui::EventTargeter>( | 103 scoped_ptr<ui::EventTargeter>( |
| 105 new StaticWindowTargeter(container)))) { | 104 new StaticWindowTargeter(container)))) { |
| 106 container_->set_target_handler(this); | 105 container_->set_target_handler(this); |
| 107 | 106 |
| 108 // Prepare the desired transforms for all the windows, and set the initial | 107 // Prepare the desired transforms for all the windows, and set the initial |
| 109 // state on the windows. | 108 // state on the windows. |
| 110 ComputeTerminalStatesForAllWindows(); | 109 ComputeTerminalStatesForAllWindows(); |
| 111 SetInitialWindowStates(); | 110 SetInitialWindowStates(); |
| 112 } | 111 } |
| 113 | 112 |
| 114 virtual ~WindowOverviewModeImpl() { | 113 virtual ~WindowOverviewModeImpl() { |
| 115 container_->set_target_handler(container_->delegate()); | 114 container_->set_target_handler(container_->delegate()); |
| 116 | 115 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 117 const aura::Window::Windows& windows = container_->children(); | 116 if (windows.empty()) |
| 118 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 117 return; |
| 119 iter != windows.end(); | 118 std::for_each(windows.begin(), windows.end(), &RestoreWindowState); |
| 120 ++iter) { | |
| 121 if ((*iter)->GetProperty(kWindowOverviewState)) | |
| 122 RestoreWindowState(*iter); | |
| 123 } | |
| 124 } | 119 } |
| 125 | 120 |
| 126 private: | 121 private: |
| 127 // Computes the transforms for all windows in both the topmost and bottom-most | 122 // Computes the transforms for all windows in both the topmost and bottom-most |
| 128 // positions. The transforms are set in the |kWindowOverviewState| property of | 123 // positions. The transforms are set in the |kWindowOverviewState| property of |
| 129 // the windows. | 124 // the windows. |
| 130 void ComputeTerminalStatesForAllWindows() { | 125 void ComputeTerminalStatesForAllWindows() { |
| 131 const aura::Window::Windows& windows = container_->children(); | 126 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 132 size_t window_count = std::count_if(windows.begin(), windows.end(), | 127 size_t window_count = windows.size(); |
| 133 ShouldShowWindowInOverviewMode); | |
| 134 | |
| 135 size_t index = 0; | 128 size_t index = 0; |
| 136 const gfx::Size container_size = container_->bounds().size(); | 129 const gfx::Size container_size = container_->bounds().size(); |
| 137 | 130 |
| 138 const int kGapBetweenWindowsBottom = 10; | 131 const int kGapBetweenWindowsBottom = 10; |
| 139 const int kGapBetweenWindowsTop = 5; | 132 const int kGapBetweenWindowsTop = 5; |
| 140 const float kMinScale = 0.6f; | 133 const float kMinScale = 0.6f; |
| 141 const float kMaxScale = 0.95f; | 134 const float kMaxScale = 0.95f; |
| 142 | 135 |
| 143 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | 136 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
| 144 iter != windows.rend(); | 137 iter != windows.rend(); |
| 145 ++iter) { | 138 ++iter, ++index) { |
| 146 aura::Window* window = (*iter); | 139 aura::Window* window = (*iter); |
| 147 if (!ShouldShowWindowInOverviewMode(window)) | |
| 148 continue; | |
| 149 | 140 |
| 150 gfx::Transform top_transform; | 141 gfx::Transform top_transform; |
| 151 int top = (window_count - index - 1) * kGapBetweenWindowsTop; | 142 int top = (window_count - index - 1) * kGapBetweenWindowsTop; |
| 152 float x_translate = container_size.width() * (1 - kMinScale) / 2.; | 143 float x_translate = container_size.width() * (1 - kMinScale) / 2.; |
| 153 top_transform.Translate(x_translate, top); | 144 top_transform.Translate(x_translate, top); |
| 154 top_transform.Scale(kMinScale, kMinScale); | 145 top_transform.Scale(kMinScale, kMinScale); |
| 155 | 146 |
| 156 gfx::Transform bottom_transform; | 147 gfx::Transform bottom_transform; |
| 157 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); | 148 int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom); |
| 158 x_translate = container_size.width() * (1 - kMaxScale) / 2.; | 149 x_translate = container_size.width() * (1 - kMaxScale) / 2.; |
| 159 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); | 150 bottom_transform.Translate(x_translate, bottom - window->bounds().y()); |
| 160 bottom_transform.Scale(kMaxScale, kMaxScale); | 151 bottom_transform.Scale(kMaxScale, kMaxScale); |
| 161 | 152 |
| 162 WindowOverviewState* state = new WindowOverviewState; | 153 WindowOverviewState* state = new WindowOverviewState; |
| 163 state->top = top_transform; | 154 state->top = top_transform; |
| 164 state->bottom = bottom_transform; | 155 state->bottom = bottom_transform; |
| 165 state->progress = 0.f; | 156 state->progress = 0.f; |
| 166 state->shadow = CreateShadowForWindow(window); | 157 state->shadow = CreateShadowForWindow(window); |
| 167 window->SetProperty(kWindowOverviewState, state); | 158 window->SetProperty(kWindowOverviewState, state); |
| 168 | |
| 169 index++; | |
| 170 } | 159 } |
| 171 } | 160 } |
| 172 | 161 |
| 173 // Sets the initial position for the windows for the overview mode. | 162 // Sets the initial position for the windows for the overview mode. |
| 174 void SetInitialWindowStates() { | 163 void SetInitialWindowStates() { |
| 164 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 165 size_t window_count = windows.size(); |
| 175 // The initial overview state of the topmost three windows. | 166 // The initial overview state of the topmost three windows. |
| 176 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; | 167 const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; |
| 177 size_t index = 0; | 168 for (size_t i = 0; i < window_count; ++i) { |
| 178 const aura::Window::Windows& windows = container_->children(); | |
| 179 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | |
| 180 iter != windows.rend(); | |
| 181 ++iter) { | |
| 182 aura::Window* window = (*iter); | |
| 183 if (!window->GetProperty(kWindowOverviewState)) | |
| 184 continue; | |
| 185 | |
| 186 float progress = 0.f; | 169 float progress = 0.f; |
| 187 if (index < arraysize(kInitialProgress)) | 170 aura::Window* window = windows[window_count - 1 - i]; |
| 188 progress = kInitialProgress[index]; | 171 if (i < arraysize(kInitialProgress)) |
| 172 progress = kInitialProgress[i]; |
| 189 | 173 |
| 190 scoped_refptr<ui::LayerAnimator> animator = | 174 scoped_refptr<ui::LayerAnimator> animator = |
| 191 window->layer()->GetAnimator(); | 175 window->layer()->GetAnimator(); |
| 192 | 176 |
| 193 // Unset any in-progress animation. | 177 // Unset any in-progress animation. |
| 194 { | 178 { |
| 195 ui::ScopedLayerAnimationSettings settings(animator); | 179 ui::ScopedLayerAnimationSettings settings(animator); |
| 196 settings.SetPreemptionStrategy( | 180 settings.SetPreemptionStrategy( |
| 197 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); | 181 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); |
| 198 window->Show(); | 182 window->Show(); |
| 199 window->SetTransform(gfx::Transform()); | 183 window->SetTransform(gfx::Transform()); |
| 200 } | 184 } |
| 201 // Setup the animation. | 185 // Setup the animation. |
| 202 { | 186 { |
| 203 ui::ScopedLayerAnimationSettings settings(animator); | 187 ui::ScopedLayerAnimationSettings settings(animator); |
| 204 settings.SetPreemptionStrategy( | 188 settings.SetPreemptionStrategy( |
| 205 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 189 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 206 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 190 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
| 207 SetWindowProgress(window, progress); | 191 SetWindowProgress(window, progress); |
| 208 } | 192 } |
| 209 index++; | |
| 210 } | 193 } |
| 211 } | 194 } |
| 212 | 195 |
| 213 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { | 196 scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) { |
| 214 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); | 197 scoped_ptr<wm::Shadow> shadow(new wm::Shadow()); |
| 215 shadow->Init(wm::Shadow::STYLE_ACTIVE); | 198 shadow->Init(wm::Shadow::STYLE_ACTIVE); |
| 216 shadow->SetContentBounds(gfx::Rect(window->bounds().size())); | 199 shadow->SetContentBounds(gfx::Rect(container_->bounds().size())); |
| 217 shadow->layer()->SetVisible(true); | 200 shadow->layer()->SetVisible(true); |
| 218 window->layer()->Add(shadow->layer()); | 201 window->layer()->Add(shadow->layer()); |
| 219 return shadow.Pass(); | 202 return shadow.Pass(); |
| 220 } | 203 } |
| 221 | 204 |
| 222 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { | 205 aura::Window* SelectWindowAt(ui::LocatedEvent* event) { |
| 223 CHECK_EQ(container_, event->target()); | 206 CHECK_EQ(container_, event->target()); |
| 224 // Find the old targeter to find the target of the event. | 207 // Find the old targeter to find the target of the event. |
| 225 ui::EventTarget* window = container_; | 208 ui::EventTarget* window = container_; |
| 226 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); | 209 ui::EventTargeter* targeter = scoped_targeter_->old_targeter(); |
| 227 while (!targeter && window->GetParentTarget()) { | 210 while (!targeter && window->GetParentTarget()) { |
| 228 window = window->GetParentTarget(); | 211 window = window->GetParentTarget(); |
| 229 targeter = window->GetEventTargeter(); | 212 targeter = window->GetEventTargeter(); |
| 230 } | 213 } |
| 231 if (!targeter) | 214 if (!targeter) |
| 232 return NULL; | 215 return NULL; |
| 233 aura::Window* target = static_cast<aura::Window*>( | 216 aura::Window* target = static_cast<aura::Window*>( |
| 234 targeter->FindTargetForLocatedEvent(container_, event)); | 217 targeter->FindTargetForLocatedEvent(container_, event)); |
| 235 while (target && target->parent() != container_) | 218 while (target && target->parent() != container_) |
| 236 target = target->parent(); | 219 target = target->parent(); |
| 237 return target; | 220 return target; |
| 238 } | 221 } |
| 239 | 222 |
| 240 // Scroll the window list by |delta_y| amount. |delta_y| is negative when | 223 // Scroll the window list by |delta_y| amount. |delta_y| is negative when |
| 241 // scrolling up; and positive when scrolling down. | 224 // scrolling up; and positive when scrolling down. |
| 242 void DoScroll(float delta_y) { | 225 void DoScroll(float delta_y) { |
| 243 const float kEpsilon = 1e-3f; | 226 const float kEpsilon = 1e-3f; |
| 244 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); | 227 float delta_y_p = std::abs(delta_y) / GetScrollableHeight(); |
| 245 const aura::Window::Windows& windows = container_->children(); | 228 aura::Window::Windows windows = window_list_provider_->GetWindowList(); |
| 246 if (delta_y < 0) { | 229 if (delta_y < 0) { |
| 247 // Scroll up. Start with the top-most (i.e. behind-most in terms of | 230 // Scroll up. Start with the top-most (i.e. behind-most in terms of |
| 248 // z-index) window, and try to scroll them up. | 231 // z-index) window, and try to scroll them up. |
| 249 for (aura::Window::Windows::const_iterator iter = windows.begin(); | 232 for (aura::Window::Windows::const_iterator iter = windows.begin(); |
| 250 delta_y_p > kEpsilon && iter != windows.end(); | 233 delta_y_p > kEpsilon && iter != windows.end(); |
| 251 ++iter) { | 234 ++iter) { |
| 252 aura::Window* window = (*iter); | 235 aura::Window* window = (*iter); |
| 253 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 236 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 254 if (!state) | |
| 255 continue; | |
| 256 if (state->progress > kEpsilon) { | 237 if (state->progress > kEpsilon) { |
| 257 // It is possible to scroll |window| up. Scroll it up, and update | 238 // It is possible to scroll |window| up. Scroll it up, and update |
| 258 // |delta_y_p| for the next window. | 239 // |delta_y_p| for the next window. |
| 259 float apply = delta_y_p * state->progress; | 240 float apply = delta_y_p * state->progress; |
| 260 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); | 241 SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); |
| 261 delta_y_p -= apply; | 242 delta_y_p -= apply; |
| 262 } | 243 } |
| 263 } | 244 } |
| 264 } else { | 245 } else { |
| 265 // Scroll down. Start with the bottom-most (i.e. front-most in terms of | 246 // Scroll down. Start with the bottom-most (i.e. front-most in terms of |
| 266 // z-index) window, and try to scroll them down. | 247 // z-index) window, and try to scroll them down. |
| 267 for (aura::Window::Windows::const_reverse_iterator iter = | 248 aura::Window::Windows::const_reverse_iterator iter; |
| 268 windows.rbegin(); | 249 for (iter = windows.rbegin(); |
| 269 delta_y_p > kEpsilon && iter != windows.rend(); | 250 delta_y_p > kEpsilon && iter != windows.rend(); |
| 270 ++iter) { | 251 ++iter) { |
| 271 aura::Window* window = (*iter); | 252 aura::Window* window = (*iter); |
| 272 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 253 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 273 if (!state) | |
| 274 continue; | |
| 275 if (1.f - state->progress > kEpsilon) { | 254 if (1.f - state->progress > kEpsilon) { |
| 276 // It is possible to scroll |window| down. Scroll it down, and update | 255 // It is possible to scroll |window| down. Scroll it down, and update |
| 277 // |delta_y_p| for the next window. | 256 // |delta_y_p| for the next window. |
| 278 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); | 257 SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); |
| 279 delta_y_p /= 2.f; | 258 delta_y_p /= 2.f; |
| 280 } | 259 } |
| 281 } | 260 } |
| 282 } | 261 } |
| 283 } | 262 } |
| 284 | 263 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 311 if (select) { | 290 if (select) { |
| 312 gesture->SetHandled(); | 291 gesture->SetHandled(); |
| 313 delegate_->OnSelectWindow(select); | 292 delegate_->OnSelectWindow(select); |
| 314 } | 293 } |
| 315 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { | 294 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { |
| 316 DoScroll(gesture->details().scroll_y()); | 295 DoScroll(gesture->details().scroll_y()); |
| 317 } | 296 } |
| 318 } | 297 } |
| 319 | 298 |
| 320 aura::Window* container_; | 299 aura::Window* container_; |
| 300 // Provider of the stack of windows to show in the overview mode. Not owned. |
| 301 const WindowListProvider* window_list_provider_; |
| 321 WindowOverviewModeDelegate* delegate_; | 302 WindowOverviewModeDelegate* delegate_; |
| 322 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 303 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
| 323 | 304 |
| 324 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 305 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
| 325 }; | 306 }; |
| 326 | 307 |
| 327 } // namespace | 308 } // namespace |
| 328 | 309 |
| 329 // static | 310 // static |
| 330 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 311 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
| 331 aura::Window* container, | 312 aura::Window* container, |
| 313 const WindowListProvider* window_list_provider, |
| 332 WindowOverviewModeDelegate* delegate) { | 314 WindowOverviewModeDelegate* delegate) { |
| 333 return scoped_ptr<WindowOverviewMode>( | 315 return scoped_ptr<WindowOverviewMode>( |
| 334 new WindowOverviewModeImpl(container, delegate)); | 316 new WindowOverviewModeImpl(container, window_list_provider, delegate)); |
| 335 } | 317 } |
| 336 | 318 |
| 337 } // namespace athena | 319 } // namespace athena |
| OLD | NEW |