Index: athena/wm/window_overview_mode.cc |
diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc |
index ce6774420e59d5182c58f42ccddeaaa05a59bb99..f6726dbd81aeb3a1709ef094b85f51f374243c8c 100644 |
--- a/athena/wm/window_overview_mode.cc |
+++ b/athena/wm/window_overview_mode.cc |
@@ -4,8 +4,7 @@ |
#include "athena/wm/window_overview_mode.h" |
-#include <algorithm> |
-#include <functional> |
+#include <complex> |
#include <vector> |
#include "athena/wm/overview_toolbar.h" |
@@ -13,7 +12,7 @@ |
#include "athena/wm/public/window_list_provider_observer.h" |
#include "athena/wm/split_view_controller.h" |
#include "base/bind.h" |
-#include "base/macros.h" |
+#include "base/memory/scoped_vector.h" |
#include "ui/aura/scoped_window_targeter.h" |
#include "ui/aura/window.h" |
#include "ui/aura/window_delegate.h" |
@@ -31,11 +30,10 @@ |
#include "ui/wm/core/shadow_types.h" |
#include "ui/wm/core/window_animations.h" |
#include "ui/wm/core/window_util.h" |
+#include "ui/wm/public/activation_client.h" |
namespace { |
-const float kOverviewDefaultScale = 0.75f; |
- |
struct WindowOverviewState { |
// The current overview state of the window. 0.f means the window is at the |
// topmost position. 1.f means the window is at the bottom-most position. |
@@ -53,14 +51,17 @@ struct WindowOverviewState { |
} // namespace |
-DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) |
+DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*); |
DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, |
kWindowOverviewState, |
- NULL) |
+ NULL); |
+ |
namespace athena { |
namespace { |
+const float kOverviewDefaultScale = 0.75f; |
+ |
gfx::Transform GetTransformForSplitWindow(aura::Window* window, float scale) { |
const float kScrollWindowPositionInOverview = 0.65f; |
int x_translate = window->bounds().width() * (1 - scale) / 2; |
@@ -99,14 +100,103 @@ gfx::Transform GetTransformForState(aura::Window* window, |
return transform; |
} |
-// Sets the progress-state for the window in the overview mode. |
-void SetWindowProgress(aura::Window* window, float progress) { |
- WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
- state->progress = progress; |
+// A utility class used to set the transform/opacity to the window and |
+// its transient children. |
+class TransientGroupSetter { |
+ public: |
+ explicit TransientGroupSetter(aura::Window* window) |
+ : window_(window) { |
Mr4D (OOO till 08-26)
2014/10/08 15:32:29
This would fit into one line.
oshima
2014/10/08 19:05:30
Done.
|
+ } |
+ ~TransientGroupSetter() {} |
- gfx::Transform transform = GetTransformForState(window, state); |
- window->SetTransform(transform); |
-} |
+ // Aborts all animations including its transient children. |
+ void AbortAllAnimations() { |
+ window_->layer()->GetAnimator()->AbortAllAnimations(); |
+ for (auto* transient_child : wm::GetTransientChildren(window_)) |
+ transient_child->layer()->GetAnimator()->AbortAllAnimations(); |
+ } |
+ |
+ // Applys transform to the window and its transient children. |
+ // Transient children gets a tranfrorm with the offset relateive |
+ // it its transient parent. |
+ void SetTransform(const gfx::Transform& transform) { |
+ window_->SetTransform(transform); |
+ for (auto* transient_child : wm::GetTransientChildren(window_)) { |
+ gfx::Rect window_bounds = window_->bounds(); |
+ gfx::Rect child_bounds = transient_child->bounds(); |
+ gfx::Transform transient_window_transform(TranslateTransformOrigin( |
+ child_bounds.origin() - window_bounds.origin(), transform)); |
+ transient_child->SetTransform(transient_window_transform); |
+ } |
+ } |
+ |
+ // Sets the opacity to the window and its transient children. |
+ void SetOpacity(float opacity) { |
+ window_->layer()->SetOpacity(opacity); |
+ for (auto* transient_child : wm::GetTransientChildren(window_)) { |
+ transient_child->layer()->SetOpacity(opacity); |
+ } |
+ } |
+ |
+ // Apply the transform with the overview scroll |progress|. |
+ void SetWindowProgress(float progress) { |
+ WindowOverviewState* state = window_->GetProperty(kWindowOverviewState); |
+ state->progress = progress; |
+ |
+ SetTransform(GetTransformForState(window_, state)); |
+ } |
+ |
+ private: |
+ static gfx::Transform TranslateTransformOrigin( |
+ const gfx::Vector2d& new_origin, |
+ const gfx::Transform& transform) { |
+ gfx::Transform result; |
+ result.Translate(-new_origin.x(), -new_origin.y()); |
+ result.PreconcatTransform(transform); |
+ result.Translate(new_origin.x(), new_origin.y()); |
+ return result; |
+ } |
+ |
+ aura::Window* window_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TransientGroupSetter); |
+}; |
+ |
+// TransientGroupSetter with animation. |
+class AnimateTransientGroupSetter : public TransientGroupSetter { |
+ public: |
+ explicit AnimateTransientGroupSetter(aura::Window* window) |
+ : TransientGroupSetter(window) { |
+ animation_settings_.push_back(CreateScopedLayerAnimationSettings(window)); |
+ for (auto* transient_child : wm::GetTransientChildren(window)) { |
+ animation_settings_.push_back( |
+ CreateScopedLayerAnimationSettings(transient_child)); |
+ } |
+ } |
+ ~AnimateTransientGroupSetter() {} |
+ |
+ ui::ScopedLayerAnimationSettings* GetMainWindowAnimationSettings() { |
+ CHECK(animation_settings_.size()); |
+ return animation_settings_[0]; |
+ } |
+ |
+ private: |
+ static ui::ScopedLayerAnimationSettings* CreateScopedLayerAnimationSettings( |
+ aura::Window* window) { |
+ const int kTransitionMs = 250; |
+ |
+ ui::ScopedLayerAnimationSettings* settings = |
+ new ui::ScopedLayerAnimationSettings(window->layer()->GetAnimator()); |
+ settings->SetPreemptionStrategy( |
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
+ settings->SetTransitionDuration( |
+ base::TimeDelta::FromMilliseconds(kTransitionMs)); |
+ return settings; |
+ } |
+ |
+ ScopedVector<ui::ScopedLayerAnimationSettings> animation_settings_; |
+ DISALLOW_COPY_AND_ASSIGN(AnimateTransientGroupSetter); |
+}; |
void HideWindowIfNotVisible(aura::Window* window, |
SplitViewController* split_view_controller) { |
@@ -115,7 +205,9 @@ void HideWindowIfNotVisible(aura::Window* window, |
should_hide = window != split_view_controller->left_window() && |
window != split_view_controller->right_window(); |
} else { |
- should_hide = !wm::IsActiveWindow(window); |
+ aura::Window* active = aura::client::GetActivationClient( |
+ window->GetRootWindow())->GetActiveWindow(); |
+ should_hide = active != window && wm::GetTransientParent(active) != window; |
} |
if (should_hide) |
window->Hide(); |
@@ -126,18 +218,15 @@ void RestoreWindowState(aura::Window* window, |
SplitViewController* split_view_controller) { |
window->ClearProperty(kWindowOverviewState); |
- ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
- settings.SetPreemptionStrategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
- settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
- |
- settings.AddObserver(new ui::ClosureAnimationObserver( |
- base::Bind(&HideWindowIfNotVisible, window, split_view_controller))); |
+ AnimateTransientGroupSetter setter(window); |
- window->SetTransform(gfx::Transform()); |
+ setter.GetMainWindowAnimationSettings()->AddObserver( |
+ new ui::ClosureAnimationObserver( |
+ base::Bind(&HideWindowIfNotVisible, window, split_view_controller))); |
+ setter.SetTransform(gfx::Transform()); |
// Reset the window opacity in case the user is dragging a window. |
- window->layer()->SetOpacity(1.0f); |
+ setter.SetOpacity(1.0f); |
wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); |
} |
@@ -156,19 +245,17 @@ void TransformSplitWindowScale(aura::Window* window, float scale) { |
gfx::Transform transform = window->layer()->GetTargetTransform(); |
if (transform.Scale2d() == gfx::Vector2dF(scale, scale)) |
return; |
- ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
- window->SetTransform(GetTransformForSplitWindow(window, scale)); |
+ AnimateTransientGroupSetter setter(window); |
+ setter.SetTransform(GetTransformForSplitWindow(window, scale)); |
} |
void AnimateWindowTo(aura::Window* animate_window, |
aura::Window* target_window) { |
- ui::ScopedLayerAnimationSettings settings( |
- animate_window->layer()->GetAnimator()); |
- settings.SetPreemptionStrategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
+ AnimateTransientGroupSetter setter(animate_window); |
+ |
WindowOverviewState* target_state = |
target_window->GetProperty(kWindowOverviewState); |
- SetWindowProgress(animate_window, target_state->progress); |
+ setter.SetWindowProgress(target_state->progress); |
} |
// Always returns the same target. |
@@ -231,10 +318,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
window_list_provider_->GetWindowList(); |
if (windows.empty()) |
return; |
- std::for_each(windows.begin(), |
- windows.end(), |
- std::bind2nd(std::ptr_fun(&RestoreWindowState), |
- split_view_controller_)); |
+ for (auto* window : windows) |
+ RestoreWindowState(window, split_view_controller_); |
} |
private: |
@@ -314,20 +399,19 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
++index; |
} |
- scoped_refptr<ui::LayerAnimator> animator = |
- window->layer()->GetAnimator(); |
+ TransientGroupSetter setter(window); |
// Unset any in-progress animation. |
- animator->AbortAllAnimations(); |
+ setter.AbortAllAnimations(); |
+ |
+ // Showing transient parent will show the transient children if any. |
window->Show(); |
- window->SetTransform(gfx::Transform()); |
+ |
+ setter.SetTransform(gfx::Transform()); |
// Setup the animation. |
{ |
- ui::ScopedLayerAnimationSettings settings(animator); |
- settings.SetPreemptionStrategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
- settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
- SetWindowProgress(window, progress); |
+ AnimateTransientGroupSetter setter(window); |
+ setter.SetWindowProgress(progress); |
} |
} |
} |
@@ -347,7 +431,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
targeter->FindTargetForLocatedEvent(container_, event)); |
while (target && target->parent() != container_) |
target = target->parent(); |
- return target; |
+ aura::Window* transient_parent = wm::GetTransientParent(target); |
+ return transient_parent ? transient_parent : target; |
} |
// Scroll the window list by |delta_y| amount. |delta_y| is negative when |
@@ -369,7 +454,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
// It is possible to scroll |window| up. Scroll it up, and update |
// |delta_y_p| for the next window. |
float apply = delta_y_p * state->progress; |
- SetWindowProgress(window, std::max(0.f, state->progress - apply * 3)); |
+ TransientGroupSetter setter(window); |
+ setter.SetWindowProgress(std::max(0.f, state->progress - apply * 3)); |
delta_y_p -= apply; |
} |
} |
@@ -385,7 +471,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
if (1.f - state->progress > kEpsilon) { |
// It is possible to scroll |window| down. Scroll it down, and update |
// |delta_y_p| for the next window. |
- SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p)); |
+ TransientGroupSetter setter(window); |
+ setter.SetWindowProgress(std::min(1.f, state->progress + delta_y_p)); |
delta_y_p /= 2.f; |
} |
} |
@@ -446,7 +533,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
gfx::Transform transform = |
GetTransformForState(dragged_window_, dragged_state); |
transform.Translate(-dragged_distance.x(), 0); |
- dragged_window_->SetTransform(transform); |
+ TransientGroupSetter setter(dragged_window_); |
+ setter.SetTransform(transform); |
// Update the toolbar. |
const int kMinDistanceForActionButtons = 20; |
@@ -488,11 +576,11 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
? 1 |
: gfx::Tween::FloatValueBetween(ratio, kMaxOpacity, kMinOpacity); |
if (animate_opacity) { |
- ui::ScopedLayerAnimationSettings settings( |
- dragged_window_->layer()->GetAnimator()); |
- dragged_window_->layer()->SetOpacity(opacity); |
+ AnimateTransientGroupSetter setter(dragged_window_); |
+ setter.SetOpacity(opacity); |
} else { |
- dragged_window_->layer()->SetOpacity(opacity); |
+ TransientGroupSetter setter(dragged_window_); |
+ setter.SetOpacity(opacity); |
} |
if (split_view_controller_->IsSplitViewModeActive()) { |
@@ -525,9 +613,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
void CloseDragWindow(const ui::GestureEvent& gesture) { |
// Animate |dragged_window_| offscreen first, then destroy it. |
{ |
- wm::ScopedHidingAnimationSettings settings(dragged_window_); |
- settings.layer_animation_settings()->SetPreemptionStrategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
+ AnimateTransientGroupSetter setter(dragged_window_); |
WindowOverviewState* dragged_state = |
dragged_window_->GetProperty(kWindowOverviewState); |
@@ -541,8 +627,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
else |
transform_x = -(transformed_bounds.x() + transformed_bounds.width()); |
transform.Translate(transform_x / kOverviewDefaultScale, 0); |
- dragged_window_->SetTransform(transform); |
- dragged_window_->layer()->SetOpacity(kMinOpacity); |
+ |
+ setter.SetOpacity(kMinOpacity); |
} |
delete dragged_window_; |
dragged_window_ = NULL; |
@@ -554,13 +640,9 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
dragged_window_->GetProperty(kWindowOverviewState); |
CHECK(dragged_state); |
- ui::ScopedLayerAnimationSettings settings( |
- dragged_window_->layer()->GetAnimator()); |
- settings.SetPreemptionStrategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
- dragged_window_->SetTransform( |
- GetTransformForState(dragged_window_, dragged_state)); |
- dragged_window_->layer()->SetOpacity(1.f); |
+ AnimateTransientGroupSetter setter(dragged_window_); |
+ setter.SetTransform(GetTransformForState(dragged_window_, dragged_state)); |
+ setter.SetOpacity(1.0f); |
dragged_window_ = NULL; |
} |