| Index: athena/wm/window_overview_mode.cc
|
| diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc
|
| deleted file mode 100644
|
| index 2f39c415528ee94094b724ecd2e718cf31858261..0000000000000000000000000000000000000000
|
| --- a/athena/wm/window_overview_mode.cc
|
| +++ /dev/null
|
| @@ -1,870 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "athena/wm/window_overview_mode.h"
|
| -
|
| -#include <complex>
|
| -#include <vector>
|
| -
|
| -#include "athena/util/athena_constants.h"
|
| -#include "athena/wm/overview_toolbar.h"
|
| -#include "athena/wm/public/window_list_provider.h"
|
| -#include "athena/wm/public/window_list_provider_observer.h"
|
| -#include "athena/wm/split_view_controller.h"
|
| -#include "base/bind.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/aura/window_property.h"
|
| -#include "ui/aura/window_targeter.h"
|
| -#include "ui/aura/window_tree_host.h"
|
| -#include "ui/compositor/closure_animation_observer.h"
|
| -#include "ui/compositor/compositor.h"
|
| -#include "ui/compositor/compositor_animation_observer.h"
|
| -#include "ui/compositor/scoped_layer_animation_settings.h"
|
| -#include "ui/events/event_handler.h"
|
| -#include "ui/events/gestures/fling_curve.h"
|
| -#include "ui/gfx/frame_time.h"
|
| -#include "ui/gfx/transform.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 {
|
| -
|
| -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.
|
| - float progress;
|
| -
|
| - // The top-most and bottom-most vertical position of the window in overview
|
| - // mode.
|
| - float max_y;
|
| - float min_y;
|
| -
|
| - // |split| is set if this window is one of the two split windows in split-view
|
| - // mode.
|
| - bool split;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*);
|
| -DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState,
|
| - kWindowOverviewState,
|
| - 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;
|
| - gfx::Transform transform;
|
| - transform.Translate(
|
| - x_translate, window->bounds().height() * kScrollWindowPositionInOverview);
|
| - transform.Scale(scale, scale);
|
| - return transform;
|
| -}
|
| -
|
| -// Gets the transform for the window in its current state.
|
| -gfx::Transform GetTransformForState(aura::Window* window,
|
| - WindowOverviewState* state) {
|
| - if (state->split)
|
| - return GetTransformForSplitWindow(window, kOverviewDefaultScale);
|
| -
|
| - const float kProgressToStartShrinking = 0.07;
|
| - const float kOverviewScale = 0.75f;
|
| - float scale = kOverviewScale;
|
| - if (state->progress < kProgressToStartShrinking) {
|
| - const float kShrunkMinimumScale = 0.7f;
|
| - scale = gfx::Tween::FloatValueBetween(
|
| - state->progress / kProgressToStartShrinking,
|
| - kShrunkMinimumScale,
|
| - kOverviewScale);
|
| - }
|
| - int container_width = window->parent()->bounds().width();
|
| - int window_width = window->bounds().width();
|
| - int window_x = window->bounds().x();
|
| - float x_translate = (container_width - (window_width * scale)) / 2 - window_x;
|
| - float y_translate = gfx::Tween::FloatValueBetween(
|
| - state->progress, state->min_y, state->max_y);
|
| - gfx::Transform transform;
|
| - transform.Translate(x_translate, y_translate);
|
| - transform.Scale(scale, scale);
|
| - return transform;
|
| -}
|
| -
|
| -// 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();
|
| - }
|
| -
|
| - // 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) {
|
| - bool should_hide = true;
|
| - if (split_view_controller->IsSplitViewModeActive()) {
|
| - should_hide = window != split_view_controller->left_window() &&
|
| - window != split_view_controller->right_window();
|
| - } else {
|
| - aura::Window* active = aura::client::GetActivationClient(
|
| - window->GetRootWindow())->GetActiveWindow();
|
| - should_hide = active != window && wm::GetTransientParent(active) != window;
|
| - }
|
| - if (should_hide)
|
| - window->Hide();
|
| -}
|
| -
|
| -// Resets the overview-related state for |window|.
|
| -void RestoreWindowState(aura::Window* window,
|
| - SplitViewController* split_view_controller) {
|
| - window->ClearProperty(kWindowOverviewState);
|
| -
|
| - AnimateTransientGroupSetter setter(window);
|
| -
|
| - 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.
|
| - setter.SetOpacity(1.0f);
|
| -
|
| - wm::SetShadowType(window, wm::SHADOW_TYPE_NONE);
|
| -}
|
| -
|
| -gfx::RectF GetTransformedBounds(aura::Window* window) {
|
| - gfx::Transform transform;
|
| - gfx::RectF bounds = window->bounds();
|
| - transform.Translate(bounds.x(), bounds.y());
|
| - transform.PreconcatTransform(window->layer()->transform());
|
| - transform.Translate(-bounds.x(), -bounds.y());
|
| - transform.TransformRect(&bounds);
|
| - return bounds;
|
| -}
|
| -
|
| -void TransformSplitWindowScale(aura::Window* window, float scale) {
|
| - gfx::Transform transform = window->layer()->GetTargetTransform();
|
| - if (transform.Scale2d() == gfx::Vector2dF(scale, scale))
|
| - return;
|
| - AnimateTransientGroupSetter setter(window);
|
| - setter.SetTransform(GetTransformForSplitWindow(window, scale));
|
| -}
|
| -
|
| -void AnimateWindowTo(aura::Window* animate_window,
|
| - aura::Window* target_window) {
|
| - AnimateTransientGroupSetter setter(animate_window);
|
| -
|
| - WindowOverviewState* target_state =
|
| - target_window->GetProperty(kWindowOverviewState);
|
| - setter.SetWindowProgress(target_state->progress);
|
| -}
|
| -
|
| -// Always returns the same target.
|
| -class StaticWindowTargeter : public aura::WindowTargeter {
|
| - public:
|
| - explicit StaticWindowTargeter(aura::Window* target) : target_(target) {}
|
| - ~StaticWindowTargeter() override {}
|
| -
|
| - private:
|
| - // aura::WindowTargeter:
|
| - ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
|
| - ui::Event* event) override {
|
| - return target_;
|
| - }
|
| -
|
| - ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* root,
|
| - ui::LocatedEvent* event) override {
|
| - return target_;
|
| - }
|
| -
|
| - aura::Window* target_;
|
| - DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter);
|
| -};
|
| -
|
| -class WindowOverviewModeImpl : public WindowOverviewMode,
|
| - public ui::EventHandler,
|
| - public ui::CompositorAnimationObserver,
|
| - public WindowListProviderObserver {
|
| - public:
|
| - WindowOverviewModeImpl(aura::Window* container,
|
| - WindowListProvider* window_list_provider,
|
| - SplitViewController* split_view_controller,
|
| - WindowOverviewModeDelegate* delegate)
|
| - : container_(container),
|
| - window_list_provider_(window_list_provider),
|
| - split_view_controller_(split_view_controller),
|
| - delegate_(delegate),
|
| - scoped_targeter_(new aura::ScopedWindowTargeter(
|
| - container,
|
| - scoped_ptr<ui::EventTargeter>(
|
| - new StaticWindowTargeter(container)))),
|
| - dragged_window_(nullptr) {
|
| - CHECK(delegate_);
|
| - container_->set_target_handler(this);
|
| -
|
| - // Prepare the desired transforms for all the windows, and set the initial
|
| - // state on the windows.
|
| - ComputeTerminalStatesForAllWindows();
|
| - SetInitialWindowStates();
|
| -
|
| - window_list_provider_->AddObserver(this);
|
| - }
|
| -
|
| - ~WindowOverviewModeImpl() override {
|
| - window_list_provider_->RemoveObserver(this);
|
| - container_->set_target_handler(container_->delegate());
|
| - RemoveAnimationObserver();
|
| - const aura::Window::Windows& windows =
|
| - window_list_provider_->GetWindowList();
|
| - if (windows.empty())
|
| - return;
|
| - for (aura::Window* window : windows)
|
| - RestoreWindowState(window, split_view_controller_);
|
| - }
|
| -
|
| - private:
|
| - // Computes the transforms for all windows in both the topmost and bottom-most
|
| - // positions. The transforms are set in the |kWindowOverviewState| property of
|
| - // the windows.
|
| - void ComputeTerminalStatesForAllWindows() {
|
| - size_t index = 0;
|
| -
|
| - const aura::Window::Windows& windows =
|
| - window_list_provider_->GetWindowList();
|
| - for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
|
| - iter != windows.rend();
|
| - ++iter, ++index) {
|
| - aura::Window* window = (*iter);
|
| - wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR_ALWAYS_ACTIVE);
|
| -
|
| - WindowOverviewState* state = new WindowOverviewState;
|
| - window->SetProperty(kWindowOverviewState, state);
|
| - if (split_view_controller_->IsSplitViewModeActive() &&
|
| - (window == split_view_controller_->left_window() ||
|
| - window == split_view_controller_->right_window())) {
|
| - // Do not let the left/right windows be scrolled.
|
| - gfx::Transform transform =
|
| - GetTransformForSplitWindow(window, kOverviewDefaultScale);
|
| - state->max_y = state->min_y = transform.To2dTranslation().y();
|
| - state->split = true;
|
| - --index;
|
| - continue;
|
| - }
|
| - state->split = false;
|
| - UpdateTerminalStateForWindowAtIndex(window, index, windows.size());
|
| - }
|
| - }
|
| -
|
| - // Computes the terminal states (i.e. the transforms for the top-most and
|
| - // bottom-most position in the stack) for |window|. |window_count| is the
|
| - // number of windows in the stack, and |index| is the position of the window
|
| - // in the stack (0 being the front-most window).
|
| - void UpdateTerminalStateForWindowAtIndex(aura::Window* window,
|
| - size_t index,
|
| - size_t window_count) {
|
| - const int kGapBetweenWindowsBottom = 10;
|
| - const int kGapBetweenWindowsTop = 5;
|
| -
|
| - int top =
|
| - (window_count - index - 1) * kGapBetweenWindowsTop + kSystemUIHeight;
|
| - int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom);
|
| -
|
| - WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
|
| - CHECK(state);
|
| - if (state->split)
|
| - return;
|
| - state->min_y = top;
|
| - state->max_y = bottom - window->bounds().y();
|
| - state->progress = 0.f;
|
| - }
|
| -
|
| - // Sets the initial position for the windows for the overview mode.
|
| - void SetInitialWindowStates() {
|
| - // The initial overview state of the topmost three windows.
|
| - const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f };
|
| - size_t index = 0;
|
| - const aura::Window::Windows& windows =
|
| - window_list_provider_->GetWindowList();
|
| - for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
|
| - iter != windows.rend();
|
| - ++iter) {
|
| - float progress = 0.f;
|
| - aura::Window* window = *iter;
|
| - if (split_view_controller_->IsSplitViewModeActive() &&
|
| - (window == split_view_controller_->left_window() ||
|
| - window == split_view_controller_->right_window())) {
|
| - progress = 1;
|
| - } else {
|
| - if (index < arraysize(kInitialProgress))
|
| - progress = kInitialProgress[index];
|
| - ++index;
|
| - }
|
| -
|
| - TransientGroupSetter setter(window);
|
| -
|
| - // Unset any in-progress animation.
|
| - setter.AbortAllAnimations();
|
| -
|
| - // Showing transient parent will show the transient children if any.
|
| - window->Show();
|
| -
|
| - setter.SetTransform(gfx::Transform());
|
| - // Setup the animation.
|
| - {
|
| - AnimateTransientGroupSetter setter(window);
|
| - setter.SetWindowProgress(progress);
|
| - }
|
| - }
|
| - }
|
| -
|
| - aura::Window* SelectWindowAt(ui::LocatedEvent* event) {
|
| - CHECK_EQ(container_, event->target());
|
| - // Find the old targeter to find the target of the event.
|
| - ui::EventTarget* window = container_;
|
| - ui::EventTargeter* targeter = scoped_targeter_->old_targeter();
|
| - while (!targeter && window->GetParentTarget()) {
|
| - window = window->GetParentTarget();
|
| - targeter = window->GetEventTargeter();
|
| - }
|
| - if (!targeter)
|
| - return nullptr;
|
| - aura::Window* target = static_cast<aura::Window*>(
|
| - targeter->FindTargetForLocatedEvent(container_, event));
|
| - while (target && target->parent() != container_)
|
| - target = target->parent();
|
| - 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
|
| - // scrolling up; and positive when scrolling down.
|
| - void DoScroll(float delta_y) {
|
| - const float kEpsilon = 1e-3f;
|
| - float delta_y_p = std::abs(delta_y) / GetScrollableHeight();
|
| - const aura::Window::Windows& windows =
|
| - window_list_provider_->GetWindowList();
|
| - if (delta_y < 0) {
|
| - // Scroll up. Start with the top-most (i.e. behind-most in terms of
|
| - // z-index) window, and try to scroll them up.
|
| - for (aura::Window::Windows::const_iterator iter = windows.begin();
|
| - delta_y_p > kEpsilon && iter != windows.end();
|
| - ++iter) {
|
| - aura::Window* window = (*iter);
|
| - WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
|
| - if (state->progress > kEpsilon) {
|
| - // 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;
|
| - TransientGroupSetter setter(window);
|
| - setter.SetWindowProgress(std::max(0.f, state->progress - apply * 3));
|
| - delta_y_p -= apply;
|
| - }
|
| - }
|
| - } else {
|
| - // Scroll down. Start with the bottom-most (i.e. front-most in terms of
|
| - // z-index) window, and try to scroll them down.
|
| - aura::Window::Windows::const_reverse_iterator iter;
|
| - for (iter = windows.rbegin();
|
| - delta_y_p > kEpsilon && iter != windows.rend();
|
| - ++iter) {
|
| - aura::Window* window = (*iter);
|
| - WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
|
| - 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.
|
| - TransientGroupSetter setter(window);
|
| - setter.SetWindowProgress(std::min(1.f, state->progress + delta_y_p));
|
| - delta_y_p /= 2.f;
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - int GetScrollableHeight() const {
|
| - const float kScrollableFraction = 0.85f;
|
| - const float kScrollableFractionInSplit = 0.5f;
|
| - const float fraction = split_view_controller_->IsSplitViewModeActive()
|
| - ? kScrollableFractionInSplit
|
| - : kScrollableFraction;
|
| - return container_->bounds().height() * fraction;
|
| - }
|
| -
|
| - void CreateFlingerFor(const ui::GestureEvent& event) {
|
| - gfx::Vector2dF velocity(event.details().velocity_x(),
|
| - event.details().velocity_y());
|
| - fling_.reset(new ui::FlingCurve(velocity, gfx::FrameTime::Now()));
|
| - }
|
| -
|
| - void AddAnimationObserver() {
|
| - ui::Compositor* compositor = container_->GetHost()->compositor();
|
| - if (!compositor->HasAnimationObserver(this))
|
| - compositor->AddAnimationObserver(this);
|
| - }
|
| -
|
| - void RemoveAnimationObserver() {
|
| - ui::Compositor* compositor = container_->GetHost()->compositor();
|
| - if (compositor->HasAnimationObserver(this))
|
| - compositor->RemoveAnimationObserver(this);
|
| - }
|
| -
|
| - aura::Window* GetSplitWindowDropTarget(const ui::GestureEvent& event) const {
|
| - if (!split_view_controller_->IsSplitViewModeActive())
|
| - return nullptr;
|
| - CHECK(dragged_window_);
|
| - CHECK_NE(split_view_controller_->left_window(), dragged_window_);
|
| - CHECK_NE(split_view_controller_->right_window(), dragged_window_);
|
| - aura::Window* window = split_view_controller_->left_window();
|
| - if (GetTransformedBounds(window).Contains(event.location()))
|
| - return window;
|
| - window = split_view_controller_->right_window();
|
| - if (GetTransformedBounds(window).Contains(event.location()))
|
| - return window;
|
| - return nullptr;
|
| - }
|
| -
|
| - void DragWindow(const ui::GestureEvent& event) {
|
| - CHECK(dragged_window_);
|
| - CHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, event.type());
|
| - CHECK(overview_toolbar_);
|
| - gfx::Vector2dF dragged_distance =
|
| - dragged_start_location_ - event.location();
|
| - WindowOverviewState* dragged_state =
|
| - dragged_window_->GetProperty(kWindowOverviewState);
|
| - CHECK(dragged_state);
|
| - gfx::Transform transform =
|
| - GetTransformForState(dragged_window_, dragged_state);
|
| - transform.Translate(-dragged_distance.x(), 0);
|
| - TransientGroupSetter setter(dragged_window_);
|
| - setter.SetTransform(transform);
|
| -
|
| - // Update the toolbar.
|
| - const int kMinDistanceForActionButtons = 20;
|
| - if (fabs(dragged_distance.x()) > kMinDistanceForActionButtons)
|
| - overview_toolbar_->ShowActionButtons();
|
| - else
|
| - overview_toolbar_->HideActionButtons();
|
| -
|
| - // See if the touch-point is above one of the action-buttons.
|
| - OverviewToolbar::ActionType new_action =
|
| - overview_toolbar_->GetHighlightAction(event);
|
| -
|
| - // If the touch-point is not above any of the action buttons, then highlight
|
| - // the close-button by default, if the user has dragged enough to close the
|
| - // window.
|
| - if (new_action == OverviewToolbar::ACTION_TYPE_NONE) {
|
| - if (fabs(dragged_distance.x()) > kMinDistanceForDismissal)
|
| - new_action = OverviewToolbar::ACTION_TYPE_CLOSE;
|
| - else
|
| - new_action = OverviewToolbar::ACTION_TYPE_NONE;
|
| - }
|
| - OverviewToolbar::ActionType previous_action =
|
| - overview_toolbar_->current_action();
|
| - overview_toolbar_->SetHighlightAction(new_action);
|
| -
|
| - aura::Window* split_drop = GetSplitWindowDropTarget(event);
|
| -
|
| - // If the user has selected to get into split-view mode, then show the
|
| - // window with full opacity. Otherwise, fade it out as it closes. Animate
|
| - // the opacity if transitioning to/from the split-view button.
|
| - bool animate_opacity =
|
| - (new_action != previous_action) &&
|
| - ((new_action == OverviewToolbar::ACTION_TYPE_SPLIT) ||
|
| - (previous_action == OverviewToolbar::ACTION_TYPE_SPLIT));
|
| - float ratio = std::min(
|
| - 1.f, std::abs(dragged_distance.x()) / kMinDistanceForDismissal);
|
| - float opacity =
|
| - (new_action == OverviewToolbar::ACTION_TYPE_SPLIT || split_drop)
|
| - ? 1
|
| - : gfx::Tween::FloatValueBetween(ratio, kMaxOpacity, kMinOpacity);
|
| - if (animate_opacity) {
|
| - AnimateTransientGroupSetter setter(dragged_window_);
|
| - setter.SetOpacity(opacity);
|
| - } else {
|
| - TransientGroupSetter setter(dragged_window_);
|
| - setter.SetOpacity(opacity);
|
| - }
|
| -
|
| - if (split_view_controller_->IsSplitViewModeActive()) {
|
| - float scale = kOverviewDefaultScale;
|
| - if (split_drop == split_view_controller_->left_window())
|
| - scale = kMaxScaleForSplitTarget;
|
| - TransformSplitWindowScale(split_view_controller_->left_window(), scale);
|
| -
|
| - scale = kOverviewDefaultScale;
|
| - if (split_drop == split_view_controller_->right_window())
|
| - scale = kMaxScaleForSplitTarget;
|
| - TransformSplitWindowScale(split_view_controller_->right_window(), scale);
|
| - }
|
| - }
|
| -
|
| - bool ShouldCloseDragWindow(const ui::GestureEvent& event) const {
|
| - gfx::Vector2dF dragged_distance =
|
| - dragged_start_location_ - event.location();
|
| - if (event.type() == ui::ET_GESTURE_SCROLL_END)
|
| - return std::abs(dragged_distance.x()) >= kMinDistanceForDismissal;
|
| - CHECK_EQ(ui::ET_SCROLL_FLING_START, event.type());
|
| - const bool dragging_towards_right = dragged_distance.x() < 0;
|
| - const bool swipe_towards_right = event.details().velocity_x() > 0;
|
| - if (dragging_towards_right != swipe_towards_right)
|
| - return false;
|
| - const float kMinVelocityForDismissal = 500.f;
|
| - return std::abs(event.details().velocity_x()) > kMinVelocityForDismissal;
|
| - }
|
| -
|
| - void CloseDragWindow(const ui::GestureEvent& gesture) {
|
| - // Animate |dragged_window_| offscreen first, then destroy it.
|
| - {
|
| - AnimateTransientGroupSetter setter(dragged_window_);
|
| -
|
| - WindowOverviewState* dragged_state =
|
| - dragged_window_->GetProperty(kWindowOverviewState);
|
| - CHECK(dragged_state);
|
| - gfx::Transform transform = dragged_window_->layer()->transform();
|
| - gfx::RectF transformed_bounds = dragged_window_->bounds();
|
| - transform.TransformRect(&transformed_bounds);
|
| - float transform_x = 0.f;
|
| - if (gesture.location().x() > dragged_start_location_.x())
|
| - transform_x = container_->bounds().right() - transformed_bounds.x();
|
| - else
|
| - transform_x = -(transformed_bounds.x() + transformed_bounds.width());
|
| - transform.Translate(transform_x / kOverviewDefaultScale, 0);
|
| -
|
| - setter.SetOpacity(kMinOpacity);
|
| - }
|
| - delete dragged_window_;
|
| - dragged_window_ = nullptr;
|
| - }
|
| -
|
| - void RestoreDragWindow() {
|
| - CHECK(dragged_window_);
|
| - WindowOverviewState* dragged_state =
|
| - dragged_window_->GetProperty(kWindowOverviewState);
|
| - CHECK(dragged_state);
|
| -
|
| - AnimateTransientGroupSetter setter(dragged_window_);
|
| - setter.SetTransform(GetTransformForState(dragged_window_, dragged_state));
|
| - setter.SetOpacity(1.0f);
|
| - dragged_window_ = nullptr;
|
| - }
|
| -
|
| - void EndDragWindow(const ui::GestureEvent& gesture) {
|
| - CHECK(dragged_window_);
|
| - CHECK(overview_toolbar_);
|
| - OverviewToolbar::ActionType action = overview_toolbar_->current_action();
|
| - overview_toolbar_.reset();
|
| - if (action == OverviewToolbar::ACTION_TYPE_SPLIT) {
|
| - delegate_->OnSelectSplitViewWindow(
|
| - nullptr, dragged_window_, dragged_window_);
|
| - return;
|
| - }
|
| -
|
| - // If the window is dropped on one of the left/right windows in split-mode,
|
| - // then switch that window.
|
| - aura::Window* split_drop = GetSplitWindowDropTarget(gesture);
|
| - if (split_drop) {
|
| - aura::Window* left = split_view_controller_->left_window();
|
| - aura::Window* right = split_view_controller_->right_window();
|
| - if (left == split_drop)
|
| - left = dragged_window_;
|
| - else
|
| - right = dragged_window_;
|
| - delegate_->OnSelectSplitViewWindow(left, right, dragged_window_);
|
| - return;
|
| - }
|
| -
|
| - if (ShouldCloseDragWindow(gesture))
|
| - CloseDragWindow(gesture);
|
| - else
|
| - RestoreDragWindow();
|
| - }
|
| -
|
| - void SelectWindow(aura::Window* window) {
|
| - if (!split_view_controller_->IsSplitViewModeActive()) {
|
| - delegate_->OnSelectWindow(window);
|
| - } else {
|
| - // If the selected window is one of the left/right windows, then keep the
|
| - // current state.
|
| - if (window == split_view_controller_->left_window() ||
|
| - window == split_view_controller_->right_window()) {
|
| - delegate_->OnSelectSplitViewWindow(
|
| - split_view_controller_->left_window(),
|
| - split_view_controller_->right_window(),
|
| - window);
|
| - } else {
|
| - delegate_->OnSelectWindow(window);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // ui::EventHandler:
|
| - void OnMouseEvent(ui::MouseEvent* mouse) override {
|
| - if (mouse->type() == ui::ET_MOUSE_PRESSED) {
|
| - aura::Window* select = SelectWindowAt(mouse);
|
| - if (select) {
|
| - mouse->SetHandled();
|
| - SelectWindow(select);
|
| - }
|
| - } else if (mouse->type() == ui::ET_MOUSEWHEEL) {
|
| - DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset());
|
| - }
|
| - }
|
| -
|
| - void OnScrollEvent(ui::ScrollEvent* scroll) override {
|
| - if (scroll->type() == ui::ET_SCROLL)
|
| - DoScroll(scroll->y_offset());
|
| - }
|
| -
|
| - void OnGestureEvent(ui::GestureEvent* gesture) override {
|
| - if (gesture->type() == ui::ET_GESTURE_TAP) {
|
| - aura::Window* select = SelectWindowAt(gesture);
|
| - if (select) {
|
| - gesture->SetHandled();
|
| - SelectWindow(select);
|
| - }
|
| - } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
|
| - if (std::abs(gesture->details().scroll_x_hint()) >
|
| - std::abs(gesture->details().scroll_y_hint()) * 2) {
|
| - dragged_start_location_ = gesture->location();
|
| - dragged_window_ = SelectWindowAt(gesture);
|
| - if (split_view_controller_->IsSplitViewModeActive() &&
|
| - (dragged_window_ == split_view_controller_->left_window() ||
|
| - dragged_window_ == split_view_controller_->right_window())) {
|
| - // TODO(sad): Allow closing the left/right window. Closing one of
|
| - // 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_ = nullptr;
|
| - }
|
| -
|
| - if (dragged_window_) {
|
| - // Show the toolbar (for closing a window, or going into split-view
|
| - // mode). If already in split-view mode, then do not show the 'Split'
|
| - // option.
|
| - overview_toolbar_.reset(new OverviewToolbar(container_));
|
| - if (!split_view_controller_->CanActivateSplitViewMode()) {
|
| - overview_toolbar_->DisableAction(
|
| - OverviewToolbar::ACTION_TYPE_SPLIT);
|
| - }
|
| - }
|
| - }
|
| - } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
|
| - if (dragged_window_)
|
| - DragWindow(*gesture);
|
| - else
|
| - DoScroll(gesture->details().scroll_y());
|
| - gesture->SetHandled();
|
| - } else if (gesture->type() == ui::ET_GESTURE_SCROLL_END) {
|
| - if (dragged_window_)
|
| - EndDragWindow(*gesture);
|
| - gesture->SetHandled();
|
| - } else if (gesture->type() == ui::ET_SCROLL_FLING_START) {
|
| - if (dragged_window_) {
|
| - EndDragWindow(*gesture);
|
| - } else {
|
| - CreateFlingerFor(*gesture);
|
| - AddAnimationObserver();
|
| - }
|
| - gesture->SetHandled();
|
| - } else if (gesture->type() == ui::ET_GESTURE_TAP_DOWN) {
|
| - if (fling_) {
|
| - fling_.reset();
|
| - RemoveAnimationObserver();
|
| - gesture->SetHandled();
|
| - }
|
| - dragged_window_ = nullptr;
|
| - }
|
| - }
|
| -
|
| - // ui::CompositorAnimationObserver:
|
| - void OnAnimationStep(base::TimeTicks timestamp) override {
|
| - CHECK(fling_);
|
| - gfx::Vector2dF delta;
|
| - bool fling_active = fling_->ComputeScrollDeltaAtTime(timestamp, &delta);
|
| -
|
| - if (!delta.IsZero())
|
| - DoScroll(delta.y());
|
| -
|
| - if (!fling_active) {
|
| - fling_.reset();
|
| - RemoveAnimationObserver();
|
| - }
|
| - }
|
| -
|
| - // WindowListProviderObserver:
|
| - void OnWindowStackingChangedInList() override {
|
| - // Recompute the states of all windows. There isn't enough information at
|
| - // this point to do anything more clever.
|
| - ComputeTerminalStatesForAllWindows();
|
| - SetInitialWindowStates();
|
| - }
|
| -
|
| - 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())
|
| - return;
|
| - CHECK_LE(index, static_cast<int>(windows.size()));
|
| - if (index == 0) {
|
| - // The back-most window has been removed. Move all the remaining windows
|
| - // one step backwards.
|
| - for (int i = windows.size() - 1; i > 0; --i) {
|
| - UpdateTerminalStateForWindowAtIndex(
|
| - windows[i], windows.size() - 1 - i, windows.size());
|
| - AnimateWindowTo(windows[i], windows[i - 1]);
|
| - }
|
| - UpdateTerminalStateForWindowAtIndex(windows.front(),
|
| - windows.size() - 1,
|
| - windows.size());
|
| - AnimateWindowTo(windows.front(), removed_window);
|
| - } else {
|
| - // Move all windows behind the removed window one step forwards.
|
| - for (int i = 0; i < index - 1; ++i) {
|
| - UpdateTerminalStateForWindowAtIndex(windows[i], windows.size() - 1 - i,
|
| - windows.size());
|
| - AnimateWindowTo(windows[i], windows[i + 1]);
|
| - }
|
| - UpdateTerminalStateForWindowAtIndex(windows[index - 1],
|
| - windows.size() - index,
|
| - windows.size());
|
| - AnimateWindowTo(windows[index - 1], removed_window);
|
| - }
|
| - }
|
| -
|
| - const int kMinDistanceForDismissal = 300;
|
| - const float kMaxOpacity = 1.0f;
|
| - const float kMinOpacity = 0.2f;
|
| - const float kMaxScaleForSplitTarget = 0.9f;
|
| -
|
| - aura::Window* container_;
|
| - // Provider of the stack of windows to show in the overview mode. Not owned.
|
| - WindowListProvider* window_list_provider_;
|
| - SplitViewController* split_view_controller_;
|
| -
|
| - WindowOverviewModeDelegate* delegate_;
|
| - scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_;
|
| - scoped_ptr<ui::FlingCurve> fling_;
|
| -
|
| - aura::Window* dragged_window_;
|
| - gfx::Point dragged_start_location_;
|
| - scoped_ptr<OverviewToolbar> overview_toolbar_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -// static
|
| -scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create(
|
| - aura::Window* container,
|
| - WindowListProvider* window_list_provider,
|
| - SplitViewController* split_view_controller,
|
| - WindowOverviewModeDelegate* delegate) {
|
| - return scoped_ptr<WindowOverviewMode>(
|
| - new WindowOverviewModeImpl(container, window_list_provider,
|
| - split_view_controller, delegate));
|
| -}
|
| -
|
| -} // namespace athena
|
|
|