Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / athena / wm / window_overview_mode.cc
index 5eb7729..6a3a55f 100644 (file)
@@ -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"
 #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)
+                                 nullptr);
+
 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,102 @@ 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) {
+  }
+  ~TransientGroupSetter() {}
+
+  // Aborts all animations including its transient children.
+  void AbortAllAnimations() {
+    window_->layer()->GetAnimator()->AbortAllAnimations();
+    for (aura::Window* transient_child : wm::GetTransientChildren(window_))
+      transient_child->layer()->GetAnimator()->AbortAllAnimations();
+  }
 
-  gfx::Transform transform = GetTransformForState(window, state);
-  window->SetTransform(transform);
-}
+  // 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 (aura::Window* 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 (aura::Window* 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 (aura::Window* 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 +204,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 +217,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,37 +244,34 @@ 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.
 class StaticWindowTargeter : public aura::WindowTargeter {
  public:
   explicit StaticWindowTargeter(aura::Window* target) : target_(target) {}
-  virtual ~StaticWindowTargeter() {}
+  ~StaticWindowTargeter() override {}
 
  private:
   // aura::WindowTargeter:
-  virtual ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
-                                              ui::Event* event) OVERRIDE {
+  ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
+                                      ui::Event* event) override {
     return target_;
   }
 
-  virtual ui::EventTarget* FindTargetForLocatedEvent(
-      ui::EventTarget* root,
-      ui::LocatedEvent* event) OVERRIDE {
+  ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* root,
+                                             ui::LocatedEvent* event) override {
     return target_;
   }
 
@@ -211,7 +296,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
             container,
             scoped_ptr<ui::EventTargeter>(
                 new StaticWindowTargeter(container)))),
-        dragged_window_(NULL) {
+        dragged_window_(nullptr) {
     CHECK(delegate_);
     container_->set_target_handler(this);
 
@@ -223,7 +308,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
     window_list_provider_->AddObserver(this);
   }
 
-  virtual ~WindowOverviewModeImpl() {
+  ~WindowOverviewModeImpl() override {
     window_list_provider_->RemoveObserver(this);
     container_->set_target_handler(container_->delegate());
     RemoveAnimationObserver();
@@ -231,10 +316,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 (aura::Window* window : windows)
+      RestoreWindowState(window, split_view_controller_);
   }
 
  private:
@@ -314,20 +397,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);
       }
     }
   }
@@ -342,12 +424,14 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
       targeter = window->GetEventTargeter();
     }
     if (!targeter)
-      return NULL;
+      return nullptr;
     aura::Window* target = static_cast<aura::Window*>(
         targeter->FindTargetForLocatedEvent(container_, event));
     while (target && target->parent() != container_)
       target = target->parent();
-    return target;
+    aura::Window* transient_parent =
+        target ? wm::GetTransientParent(target) : nullptr;
+    return transient_parent ? transient_parent : target;
   }
 
   // Scroll the window list by |delta_y| amount. |delta_y| is negative when
@@ -369,7 +453,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 +470,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;
         }
       }
@@ -421,7 +507,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
 
   aura::Window* GetSplitWindowDropTarget(const ui::GestureEvent& event) const {
     if (!split_view_controller_->IsSplitViewModeActive())
-      return NULL;
+      return nullptr;
     CHECK(dragged_window_);
     CHECK_NE(split_view_controller_->left_window(), dragged_window_);
     CHECK_NE(split_view_controller_->right_window(), dragged_window_);
@@ -431,7 +517,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
     window = split_view_controller_->right_window();
     if (GetTransformedBounds(window).Contains(event.location()))
       return window;
-    return NULL;
+    return nullptr;
   }
 
   void DragWindow(const ui::GestureEvent& event) {
@@ -446,7 +532,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 +575,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 +612,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,11 +626,11 @@ 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;
+    dragged_window_ = nullptr;
   }
 
   void RestoreDragWindow() {
@@ -554,14 +639,10 @@ 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);
-    dragged_window_ = NULL;
+    AnimateTransientGroupSetter setter(dragged_window_);
+    setter.SetTransform(GetTransformForState(dragged_window_, dragged_state));
+    setter.SetOpacity(1.0f);
+    dragged_window_ = nullptr;
   }
 
   void EndDragWindow(const ui::GestureEvent& gesture) {
@@ -570,9 +651,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
     OverviewToolbar::ActionType action = overview_toolbar_->current_action();
     overview_toolbar_.reset();
     if (action == OverviewToolbar::ACTION_TYPE_SPLIT) {
-      delegate_->OnSelectSplitViewWindow(NULL,
-                                         dragged_window_,
-                                         dragged_window_);
+      delegate_->OnSelectSplitViewWindow(
+          nullptr, dragged_window_, dragged_window_);
       return;
     }
 
@@ -615,7 +695,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
   }
 
   // ui::EventHandler:
-  virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE {
+  void OnMouseEvent(ui::MouseEvent* mouse) override {
     if (mouse->type() == ui::ET_MOUSE_PRESSED) {
       aura::Window* select = SelectWindowAt(mouse);
       if (select) {
@@ -627,12 +707,12 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
     }
   }
 
-  virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE {
+  void OnScrollEvent(ui::ScrollEvent* scroll) override {
     if (scroll->type() == ui::ET_SCROLL)
       DoScroll(scroll->y_offset());
   }
 
-  virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE {
+  void OnGestureEvent(ui::GestureEvent* gesture) override {
     if (gesture->type() == ui::ET_GESTURE_TAP) {
       aura::Window* select = SelectWindowAt(gesture);
       if (select) {
@@ -651,7 +731,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
           // these windows will terminate the split-view mode. Until then, do
           // not allow closing these (since otherwise it gets into an undefined
           // state).
-          dragged_window_ = NULL;
+          dragged_window_ = nullptr;
         }
 
         if (dragged_window_) {
@@ -689,34 +769,37 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
         RemoveAnimationObserver();
         gesture->SetHandled();
       }
-      dragged_window_ = NULL;
+      dragged_window_ = nullptr;
     }
   }
 
   // ui::CompositorAnimationObserver:
-  virtual void OnAnimationStep(base::TimeTicks timestamp) OVERRIDE {
+  void OnAnimationStep(base::TimeTicks timestamp) override {
     CHECK(fling_);
-    if (fling_->start_timestamp() > timestamp)
-      return;
-    gfx::Vector2dF scroll = fling_->GetScrollAmountAtTime(timestamp);
-    if (scroll.IsZero()) {
+    gfx::Vector2dF delta;
+    bool fling_active = fling_->ComputeScrollDeltaAtTime(timestamp, &delta);
+
+    if (!delta.IsZero())
+      DoScroll(delta.y());
+
+    if (!fling_active) {
       fling_.reset();
       RemoveAnimationObserver();
-    } else {
-      DoScroll(scroll.y());
     }
   }
 
   // WindowListProviderObserver:
-  virtual void OnWindowStackingChanged() OVERRIDE {
+  void OnWindowStackingChangedInList() override {
     // Recompute the states of all windows. There isn't enough information at
     // this point to do anything more clever.
     ComputeTerminalStatesForAllWindows();
     SetInitialWindowStates();
   }
 
-  virtual void OnWindowRemoved(aura::Window* removed_window,
-                               int index) OVERRIDE {
+  void OnWindowAddedToList(aura::Window* removed_window) override {}
+
+  void OnWindowRemovedFromList(aura::Window* removed_window,
+                               int index) override {
     const aura::Window::Windows& windows =
         window_list_provider_->GetWindowList();
     if (windows.empty())