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 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 91 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
92 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 92 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
93 | 93 |
94 settings.AddObserver(new ui::ClosureAnimationObserver( | 94 settings.AddObserver(new ui::ClosureAnimationObserver( |
95 base::Bind(&HideWindowIfNotVisible, window, split_view_controller))); | 95 base::Bind(&HideWindowIfNotVisible, window, split_view_controller))); |
96 | 96 |
97 window->SetTransform(gfx::Transform()); | 97 window->SetTransform(gfx::Transform()); |
98 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); | 98 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); |
99 } | 99 } |
100 | 100 |
101 gfx::RectF GetTransformedBounds(aura::Window* window) { | |
102 gfx::Transform transform; | |
103 gfx::RectF bounds = window->bounds(); | |
104 transform.Translate(bounds.x(), bounds.y()); | |
105 transform.PreconcatTransform(window->layer()->transform()); | |
106 transform.Translate(-bounds.x(), -bounds.y()); | |
107 transform.TransformRect(&bounds); | |
108 return bounds; | |
109 } | |
110 | |
111 gfx::Transform GetTransformForSplitWindow(aura::Window* window, float scale) { | |
112 int x_translate = window->bounds().width() * (1 - scale) / 2; | |
113 gfx::Transform transform; | |
114 transform.Translate(x_translate, window->bounds().height() * 0.65); | |
115 transform.Scale(scale, scale); | |
116 return transform; | |
117 } | |
118 | |
119 void TransformSplitWindowScale(aura::Window* window, float scale) { | |
120 gfx::Transform transform = window->layer()->GetTargetTransform(); | |
121 if (transform.Scale2d() == gfx::Vector2dF(scale, scale)) | |
122 return; | |
123 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | |
124 window->SetTransform(GetTransformForSplitWindow(window, scale)); | |
125 } | |
126 | |
101 // Always returns the same target. | 127 // Always returns the same target. |
102 class StaticWindowTargeter : public aura::WindowTargeter { | 128 class StaticWindowTargeter : public aura::WindowTargeter { |
103 public: | 129 public: |
104 explicit StaticWindowTargeter(aura::Window* target) : target_(target) {} | 130 explicit StaticWindowTargeter(aura::Window* target) : target_(target) {} |
105 virtual ~StaticWindowTargeter() {} | 131 virtual ~StaticWindowTargeter() {} |
106 | 132 |
107 private: | 133 private: |
108 // aura::WindowTargeter: | 134 // aura::WindowTargeter: |
109 virtual ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, | 135 virtual ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, |
110 ui::Event* event) OVERRIDE { | 136 ui::Event* event) OVERRIDE { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 ++iter, ++index) { | 197 ++iter, ++index) { |
172 aura::Window* window = (*iter); | 198 aura::Window* window = (*iter); |
173 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); | 199 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE); |
174 | 200 |
175 WindowOverviewState* state = new WindowOverviewState; | 201 WindowOverviewState* state = new WindowOverviewState; |
176 window->SetProperty(kWindowOverviewState, state); | 202 window->SetProperty(kWindowOverviewState, state); |
177 if (split_view_controller_->IsSplitViewModeActive() && | 203 if (split_view_controller_->IsSplitViewModeActive() && |
178 (window == split_view_controller_->left_window() || | 204 (window == split_view_controller_->left_window() || |
179 window == split_view_controller_->right_window())) { | 205 window == split_view_controller_->right_window())) { |
180 // Do not let the left/right windows be scrolled. | 206 // Do not let the left/right windows be scrolled. |
181 int x_translate = window->bounds().width() * (1 - kMaxScale) / 2; | 207 state->top = GetTransformForSplitWindow(window, kMaxScale); |
182 state->top.Translate(x_translate, window->bounds().height() * 0.65); | |
183 state->top.Scale(kMaxScale, kMaxScale); | |
184 state->bottom = state->top; | 208 state->bottom = state->top; |
185 --index; | 209 --index; |
186 continue; | 210 continue; |
187 } | 211 } |
188 UpdateTerminalStateForWindowAtIndex(window, index, windows.size()); | 212 UpdateTerminalStateForWindowAtIndex(window, index, windows.size()); |
189 } | 213 } |
190 } | 214 } |
191 | 215 |
192 void UpdateTerminalStateForWindowAtIndex(aura::Window* window, | 216 void UpdateTerminalStateForWindowAtIndex(aura::Window* window, |
193 size_t index, | 217 size_t index, |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 if (!compositor->HasAnimationObserver(this)) | 360 if (!compositor->HasAnimationObserver(this)) |
337 compositor->AddAnimationObserver(this); | 361 compositor->AddAnimationObserver(this); |
338 } | 362 } |
339 | 363 |
340 void RemoveAnimationObserver() { | 364 void RemoveAnimationObserver() { |
341 ui::Compositor* compositor = container_->GetHost()->compositor(); | 365 ui::Compositor* compositor = container_->GetHost()->compositor(); |
342 if (compositor->HasAnimationObserver(this)) | 366 if (compositor->HasAnimationObserver(this)) |
343 compositor->RemoveAnimationObserver(this); | 367 compositor->RemoveAnimationObserver(this); |
344 } | 368 } |
345 | 369 |
370 aura::Window* IsSplitWindowDropTarget(const ui::GestureEvent& event) const { | |
oshima
2014/09/03 20:02:58
Can this really be const?
(split_view_controller_-
sadrul
2014/09/03 20:14:27
The compiler doesn't seem to complain. (I can remo
oshima
2014/09/03 20:53:48
I'm actually onthe fence as split_view_controller
| |
371 if (!split_view_controller_->IsSplitViewModeActive()) | |
372 return NULL; | |
373 CHECK(dragged_window_); | |
374 CHECK_NE(split_view_controller_->left_window(), dragged_window_); | |
375 CHECK_NE(split_view_controller_->right_window(), dragged_window_); | |
376 aura::Window* window = split_view_controller_->left_window(); | |
377 if (GetTransformedBounds(window).Contains(event.location())) | |
378 return window; | |
379 window = split_view_controller_->right_window(); | |
380 if (GetTransformedBounds(window).Contains(event.location())) | |
381 return window; | |
382 return NULL; | |
383 } | |
384 | |
346 void DragWindow(const ui::GestureEvent& event) { | 385 void DragWindow(const ui::GestureEvent& event) { |
347 CHECK(dragged_window_); | 386 CHECK(dragged_window_); |
348 CHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, event.type()); | 387 CHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, event.type()); |
349 CHECK(overview_toolbar_); | 388 CHECK(overview_toolbar_); |
350 gfx::Vector2dF dragged_distance = | 389 gfx::Vector2dF dragged_distance = |
351 dragged_start_location_ - event.location(); | 390 dragged_start_location_ - event.location(); |
352 WindowOverviewState* dragged_state = | 391 WindowOverviewState* dragged_state = |
353 dragged_window_->GetProperty(kWindowOverviewState); | 392 dragged_window_->GetProperty(kWindowOverviewState); |
354 CHECK(dragged_state); | 393 CHECK(dragged_state); |
355 gfx::Transform transform = GetTransformForState(dragged_state); | 394 gfx::Transform transform = GetTransformForState(dragged_state); |
(...skipping 17 matching lines...) Expand all Loading... | |
373 if (new_action == OverviewToolbar::ACTION_TYPE_NONE) { | 412 if (new_action == OverviewToolbar::ACTION_TYPE_NONE) { |
374 if (fabs(dragged_distance.x()) > kMinDistanceForDismissal) | 413 if (fabs(dragged_distance.x()) > kMinDistanceForDismissal) |
375 new_action = OverviewToolbar::ACTION_TYPE_CLOSE; | 414 new_action = OverviewToolbar::ACTION_TYPE_CLOSE; |
376 else | 415 else |
377 new_action = OverviewToolbar::ACTION_TYPE_NONE; | 416 new_action = OverviewToolbar::ACTION_TYPE_NONE; |
378 } | 417 } |
379 OverviewToolbar::ActionType previous_action = | 418 OverviewToolbar::ActionType previous_action = |
380 overview_toolbar_->current_action(); | 419 overview_toolbar_->current_action(); |
381 overview_toolbar_->SetHighlightAction(new_action); | 420 overview_toolbar_->SetHighlightAction(new_action); |
382 | 421 |
422 aura::Window* split_drop = IsSplitWindowDropTarget(event); | |
423 | |
383 // If the user has selected to get into split-view mode, then show the | 424 // If the user has selected to get into split-view mode, then show the |
384 // window with full opacity. Otherwise, fade it out as it closes. Animate | 425 // window with full opacity. Otherwise, fade it out as it closes. Animate |
385 // the opacity if transitioning to/from the split-view button. | 426 // the opacity if transitioning to/from the split-view button. |
386 bool animate_opacity = | 427 bool animate_opacity = |
387 (new_action != previous_action) && | 428 (new_action != previous_action) && |
388 ((new_action == OverviewToolbar::ACTION_TYPE_SPLIT) || | 429 ((new_action == OverviewToolbar::ACTION_TYPE_SPLIT) || |
389 (previous_action == OverviewToolbar::ACTION_TYPE_SPLIT)); | 430 (previous_action == OverviewToolbar::ACTION_TYPE_SPLIT)); |
390 float ratio = std::min( | 431 float ratio = std::min( |
391 1.f, std::abs(dragged_distance.x()) / kMinDistanceForDismissal); | 432 1.f, std::abs(dragged_distance.x()) / kMinDistanceForDismissal); |
392 float opacity = | 433 float opacity = |
393 (new_action == OverviewToolbar::ACTION_TYPE_SPLIT) | 434 (new_action == OverviewToolbar::ACTION_TYPE_SPLIT || split_drop) |
394 ? 1 | 435 ? 1 |
395 : gfx::Tween::FloatValueBetween(ratio, kMaxOpacity, kMinOpacity); | 436 : gfx::Tween::FloatValueBetween(ratio, kMaxOpacity, kMinOpacity); |
396 if (animate_opacity) { | 437 if (animate_opacity) { |
397 ui::ScopedLayerAnimationSettings settings( | 438 ui::ScopedLayerAnimationSettings settings( |
398 dragged_window_->layer()->GetAnimator()); | 439 dragged_window_->layer()->GetAnimator()); |
399 dragged_window_->layer()->SetOpacity(opacity); | 440 dragged_window_->layer()->SetOpacity(opacity); |
400 } else { | 441 } else { |
401 dragged_window_->layer()->SetOpacity(opacity); | 442 dragged_window_->layer()->SetOpacity(opacity); |
402 } | 443 } |
444 | |
445 if (split_view_controller_->IsSplitViewModeActive()) { | |
446 float scale = kMaxScale; | |
447 if (split_drop == split_view_controller_->left_window()) | |
448 scale = kMaxScaleForSplitTarget; | |
449 TransformSplitWindowScale(split_view_controller_->left_window(), scale); | |
450 | |
451 scale = kMaxScale; | |
452 if (split_drop == split_view_controller_->right_window()) | |
453 scale = kMaxScaleForSplitTarget; | |
454 TransformSplitWindowScale(split_view_controller_->right_window(), scale); | |
455 } | |
403 } | 456 } |
404 | 457 |
405 bool ShouldCloseDragWindow(const ui::GestureEvent& event) const { | 458 bool ShouldCloseDragWindow(const ui::GestureEvent& event) const { |
406 gfx::Vector2dF dragged_distance = | 459 gfx::Vector2dF dragged_distance = |
407 dragged_start_location_ - event.location(); | 460 dragged_start_location_ - event.location(); |
408 if (event.type() == ui::ET_GESTURE_SCROLL_END) | 461 if (event.type() == ui::ET_GESTURE_SCROLL_END) |
409 return std::abs(dragged_distance.x()) >= kMinDistanceForDismissal; | 462 return std::abs(dragged_distance.x()) >= kMinDistanceForDismissal; |
410 CHECK_EQ(ui::ET_SCROLL_FLING_START, event.type()); | 463 CHECK_EQ(ui::ET_SCROLL_FLING_START, event.type()); |
411 const bool dragging_towards_right = dragged_distance.x() < 0; | 464 const bool dragging_towards_right = dragged_distance.x() < 0; |
412 const bool swipe_towards_right = event.details().velocity_x() > 0; | 465 const bool swipe_towards_right = event.details().velocity_x() > 0; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
475 dragged_window_->SetTransform(GetTransformForState(dragged_state)); | 528 dragged_window_->SetTransform(GetTransformForState(dragged_state)); |
476 dragged_window_->layer()->SetOpacity(1.f); | 529 dragged_window_->layer()->SetOpacity(1.f); |
477 dragged_window_ = NULL; | 530 dragged_window_ = NULL; |
478 } | 531 } |
479 | 532 |
480 void EndDragWindow(const ui::GestureEvent& gesture) { | 533 void EndDragWindow(const ui::GestureEvent& gesture) { |
481 CHECK(dragged_window_); | 534 CHECK(dragged_window_); |
482 CHECK(overview_toolbar_); | 535 CHECK(overview_toolbar_); |
483 OverviewToolbar::ActionType action = overview_toolbar_->current_action(); | 536 OverviewToolbar::ActionType action = overview_toolbar_->current_action(); |
484 overview_toolbar_.reset(); | 537 overview_toolbar_.reset(); |
485 if (action == OverviewToolbar::ACTION_TYPE_SPLIT) | 538 if (action == OverviewToolbar::ACTION_TYPE_SPLIT) { |
486 delegate_->OnSplitViewMode(NULL, dragged_window_); | 539 delegate_->OnSplitViewMode(NULL, dragged_window_); |
487 else if (ShouldCloseDragWindow(gesture)) | 540 return; |
541 } | |
542 | |
543 // If the window is dropped on one of the left/right windows in split-mode, | |
544 // then switch that window. | |
545 aura::Window* split_drop = IsSplitWindowDropTarget(gesture); | |
546 if (split_drop) { | |
547 aura::Window* left = split_view_controller_->left_window(); | |
548 aura::Window* right = split_view_controller_->right_window(); | |
549 if (left == split_drop) | |
550 left = dragged_window_; | |
551 else | |
552 right = dragged_window_; | |
553 delegate_->OnSplitViewMode(left, right); | |
554 return; | |
555 } | |
556 | |
557 if (ShouldCloseDragWindow(gesture)) | |
488 CloseDragWindow(gesture); | 558 CloseDragWindow(gesture); |
489 else | 559 else |
490 RestoreDragWindow(); | 560 RestoreDragWindow(); |
491 } | 561 } |
492 | 562 |
493 void SelectWindow(aura::Window* window) { | 563 void SelectWindow(aura::Window* window) { |
494 if (!split_view_controller_->IsSplitViewModeActive()) { | 564 if (!split_view_controller_->IsSplitViewModeActive()) { |
495 delegate_->OnSelectWindow(window); | 565 delegate_->OnSelectWindow(window); |
496 } else { | 566 } else { |
497 // If the selected window is one of the left/right windows, then keep the | 567 // If the selected window is one of the left/right windows, then keep the |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 aura::Window* select = SelectWindowAt(gesture); | 599 aura::Window* select = SelectWindowAt(gesture); |
530 if (select) { | 600 if (select) { |
531 gesture->SetHandled(); | 601 gesture->SetHandled(); |
532 SelectWindow(select); | 602 SelectWindow(select); |
533 } | 603 } |
534 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { | 604 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
535 if (std::abs(gesture->details().scroll_x_hint()) > | 605 if (std::abs(gesture->details().scroll_x_hint()) > |
536 std::abs(gesture->details().scroll_y_hint()) * 2) { | 606 std::abs(gesture->details().scroll_y_hint()) * 2) { |
537 dragged_start_location_ = gesture->location(); | 607 dragged_start_location_ = gesture->location(); |
538 dragged_window_ = SelectWindowAt(gesture); | 608 dragged_window_ = SelectWindowAt(gesture); |
539 if (dragged_window_) | 609 if (split_view_controller_->IsSplitViewModeActive() && |
610 (dragged_window_ == split_view_controller_->left_window() || | |
611 dragged_window_ == split_view_controller_->right_window())) { | |
612 dragged_window_ = NULL; | |
oshima
2014/09/03 20:02:58
does this mean I cannot close the window in split
sadrul
2014/09/03 20:14:27
Yes. I am going to do that in the next patch. I ha
| |
613 } | |
614 | |
615 if (dragged_window_) { | |
616 // Show the toolbar (for closing a window, or going into split-view | |
617 // mode). If already in split-view mode, then do not show the 'Split' | |
618 // option. | |
540 overview_toolbar_.reset(new OverviewToolbar(container_)); | 619 overview_toolbar_.reset(new OverviewToolbar(container_)); |
620 if (split_view_controller_->IsSplitViewModeActive()) { | |
621 overview_toolbar_->DisableAction( | |
622 OverviewToolbar::ACTION_TYPE_SPLIT); | |
623 } | |
624 } | |
541 } | 625 } |
542 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { | 626 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { |
543 if (dragged_window_) | 627 if (dragged_window_) |
544 DragWindow(*gesture); | 628 DragWindow(*gesture); |
545 else | 629 else |
546 DoScroll(gesture->details().scroll_y()); | 630 DoScroll(gesture->details().scroll_y()); |
547 gesture->SetHandled(); | 631 gesture->SetHandled(); |
548 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_END) { | 632 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_END) { |
549 if (dragged_window_) | 633 if (dragged_window_) |
550 EndDragWindow(*gesture); | 634 EndDragWindow(*gesture); |
(...skipping 28 matching lines...) Expand all Loading... | |
579 } else { | 663 } else { |
580 DoScroll(scroll.y()); | 664 DoScroll(scroll.y()); |
581 } | 665 } |
582 } | 666 } |
583 | 667 |
584 const int kMinDistanceForDismissal = 300; | 668 const int kMinDistanceForDismissal = 300; |
585 const float kMinScale = 0.6f; | 669 const float kMinScale = 0.6f; |
586 const float kMaxScale = 0.75f; | 670 const float kMaxScale = 0.75f; |
587 const float kMaxOpacity = 1.0f; | 671 const float kMaxOpacity = 1.0f; |
588 const float kMinOpacity = 0.2f; | 672 const float kMinOpacity = 0.2f; |
673 const float kMaxScaleForSplitTarget = 0.9f; | |
589 | 674 |
590 aura::Window* container_; | 675 aura::Window* container_; |
591 // Provider of the stack of windows to show in the overview mode. Not owned. | 676 // Provider of the stack of windows to show in the overview mode. Not owned. |
592 const WindowListProvider* window_list_provider_; | 677 const WindowListProvider* window_list_provider_; |
593 SplitViewController* split_view_controller_; | 678 SplitViewController* split_view_controller_; |
594 | 679 |
595 WindowOverviewModeDelegate* delegate_; | 680 WindowOverviewModeDelegate* delegate_; |
596 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 681 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
597 scoped_ptr<ui::FlingCurve> fling_; | 682 scoped_ptr<ui::FlingCurve> fling_; |
598 | 683 |
(...skipping 11 matching lines...) Expand all Loading... | |
610 aura::Window* container, | 695 aura::Window* container, |
611 const WindowListProvider* window_list_provider, | 696 const WindowListProvider* window_list_provider, |
612 SplitViewController* split_view_controller, | 697 SplitViewController* split_view_controller, |
613 WindowOverviewModeDelegate* delegate) { | 698 WindowOverviewModeDelegate* delegate) { |
614 return scoped_ptr<WindowOverviewMode>( | 699 return scoped_ptr<WindowOverviewMode>( |
615 new WindowOverviewModeImpl(container, window_list_provider, | 700 new WindowOverviewModeImpl(container, window_list_provider, |
616 split_view_controller, delegate)); | 701 split_view_controller, delegate)); |
617 } | 702 } |
618 | 703 |
619 } // namespace athena | 704 } // namespace athena |
OLD | NEW |