Commit 1142801b authored by minch's avatar minch Committed by Chromium LUCI CQ

bento: Add animation of zero state

Bug: 1158583
Change-Id: I9c444c57c86d368477827f48f75cf9fd3197d117
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2623714
Commit-Queue: Min Chen <minch@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843656}
parent c08610c1
......@@ -11,12 +11,14 @@
#include "ash/wm/desks/desk_mini_view.h"
#include "ash/wm/desks/desks_bar_view.h"
#include "ash/wm/desks/expanded_state_new_desk_button.h"
#include "ash/wm/desks/zero_state_button.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_session.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/transform_util.h"
namespace ash {
......@@ -33,6 +35,12 @@ constexpr base::TimeDelta kExistingMiniViewsAnimationDuration =
constexpr base::TimeDelta kRemovedMiniViewsFadeOutDuration =
base::TimeDelta::FromMilliseconds(200);
constexpr base::TimeDelta kZeroStateAnimationDuration =
base::TimeDelta::FromMilliseconds(200);
// Scale for entering/exiting zero state.
constexpr float kEnterOrExitZeroStateScale = 0.6f;
// |settings| will be initialized with a fast-out-slow-in animation with the
// given |duration|.
void InitScopedAnimationSettings(ui::ScopedLayerAnimationSettings* settings,
......@@ -61,26 +69,87 @@ void AnimateMiniViews(std::vector<DeskMiniView*> mini_views,
AnimateView(mini_view, begin_transform);
}
// Scales down the given |view| to |kEnterOrExitZeroStateScale| and fading out
// it at the same time. Scale down animation will be around the |start| point.
void ScaleDownAndFadeOutView(views::View* view, const gfx::Point& start) {
ui::Layer* layer = view->layer();
ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
InitScopedAnimationSettings(&settings, kZeroStateAnimationDuration);
const gfx::Point end = view->bounds().CenterPoint();
layer->SetTransform(gfx::GetScaleTransform(
gfx::Point(start.x() - end.x(), start.y() - end.y()),
kEnterOrExitZeroStateScale));
layer->SetOpacity(0.f);
}
// Scales up the given |view| from |kEnterOrExitZeroStateScale| to identity and
// fading in it at the same time. Scale up animation will be around the |start|
// point.
void ScaleUpAndFadeInView(views::View* view, const gfx::Point& start) {
DCHECK(view);
const gfx::Point end = view->bounds().CenterPoint();
ui::Layer* layer = view->layer();
layer->SetTransform(gfx::GetScaleTransform(
gfx::Point(start.x() - end.x(), start.y() - end.y()),
kEnterOrExitZeroStateScale));
ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
InitScopedAnimationSettings(&settings, kZeroStateAnimationDuration);
layer->SetTransform(kEndTransform);
layer->SetOpacity(1.f);
}
void PositionWindowsInOverview() {
auto* controller = Shell::Get()->overview_controller();
DCHECK(controller->InOverviewSession());
controller->overview_session()->PositionWindows(true);
}
// A self-deleting object that performs a fade out animation on
// |removed_mini_view|'s layer by changing its opacity from 1 to 0,
// and deleting |removed_mini_view| and itself when the animation is complete.
// |removed_mini_view|'s layer by changing its opacity from 1 to 0 and scales
// down it around the center of |bar_view| while switching back to zero state in
// Bento. |removed_mini_view_| and the object itserlf will be deleted when the
// animation is complete.
// TODO(afakhry): Consider generalizing HidingWindowAnimationObserverBase to be
// reusable for the mini_view removal animation.
class RemovedMiniViewFadeOutAnimation : public ui::ImplicitAnimationObserver {
class RemovedMiniViewAnimation : public ui::ImplicitAnimationObserver {
public:
RemovedMiniViewFadeOutAnimation(DeskMiniView* removed_mini_view)
: removed_mini_view_(removed_mini_view) {
RemovedMiniViewAnimation(DeskMiniView* removed_mini_view,
DesksBarView* bar_view,
const bool to_zero_state)
: removed_mini_view_(removed_mini_view),
bar_view_(bar_view),
to_zero_state_(to_zero_state) {
ui::Layer* layer = removed_mini_view_->layer();
ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
InitScopedAnimationSettings(&settings, kRemovedMiniViewsFadeOutDuration);
settings.AddObserver(this);
if (to_zero_state_) {
DCHECK(bar_view_);
const gfx::Point start = bar_view->bounds().CenterPoint();
const gfx::Point end = removed_mini_view->bounds().CenterPoint();
layer->SetTransform(gfx::GetScaleTransform(
gfx::Point(start.x() - end.x(), start.y() - end.y()),
kEnterOrExitZeroStateScale));
} else {
layer->SetTransform(kEndTransform);
}
layer->SetOpacity(0);
}
~RemovedMiniViewFadeOutAnimation() override {
RemovedMiniViewAnimation(const RemovedMiniViewAnimation&) = delete;
RemovedMiniViewAnimation& operator=(const RemovedMiniViewAnimation&) = delete;
~RemovedMiniViewAnimation() override {
DCHECK(removed_mini_view_->parent());
removed_mini_view_->parent()->RemoveChildViewT(removed_mini_view_);
if (to_zero_state_) {
DCHECK(bar_view_);
bar_view_->zero_state_default_desk_button()->SetVisible(true);
bar_view_->zero_state_new_desk_button()->SetVisible(true);
}
}
// ui::ImplicitAnimationObserver:
......@@ -88,8 +157,8 @@ class RemovedMiniViewFadeOutAnimation : public ui::ImplicitAnimationObserver {
private:
DeskMiniView* removed_mini_view_;
DISALLOW_COPY_AND_ASSIGN(RemovedMiniViewFadeOutAnimation);
DesksBarView* bar_view_;
const bool to_zero_state_;
};
} // namespace
......@@ -110,9 +179,7 @@ void PerformNewDeskMiniViewAnimation(
DCHECK(!layer->GetTargetTransform().IsIdentity());
layer->SetTransform(gfx::Transform());
auto* controller = Shell::Get()->overview_controller();
DCHECK(controller->InOverviewSession());
controller->overview_session()->PositionWindows(true);
PositionWindowsInOverview();
}
gfx::Transform begin_transform;
......@@ -160,7 +227,8 @@ void PerformRemoveDeskMiniViewAnimation(
gfx::Transform mini_views_right_begin_transform;
mini_views_right_begin_transform.Translate(-shift_x, 0);
new RemovedMiniViewFadeOutAnimation(removed_mini_view);
new RemovedMiniViewAnimation(removed_mini_view, /*bar_view=*/nullptr,
/*to_zero_state=*/false);
AnimateMiniViews(mini_views_left, mini_views_left_begin_transform);
AnimateMiniViews(mini_views_right, mini_views_right_begin_transform);
......@@ -171,4 +239,39 @@ void PerformRemoveDeskMiniViewAnimation(
}
}
void PerformZeroStateToExpandedStateMiniViewAnimation(DesksBarView* bar_view) {
ui::Layer* layer = bar_view->background_view()->layer();
ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
InitScopedAnimationSettings(&settings, kZeroStateAnimationDuration);
layer->SetTransform(kEndTransform);
const gfx::Point start = bar_view->bounds().CenterPoint();
for (auto* mini_view : bar_view->mini_views())
ScaleUpAndFadeInView(mini_view, start);
ScaleUpAndFadeInView(bar_view->expanded_state_new_desk_button(), start);
PositionWindowsInOverview();
}
void PerformExpandedStateToZeroStateMiniViewAnimation(
DesksBarView* bar_view,
std::vector<DeskMiniView*> removed_mini_views) {
for (auto* mini_view : removed_mini_views)
new RemovedMiniViewAnimation(mini_view, bar_view, /*to_zero_state=*/true);
const gfx::Rect bounds = bar_view->bounds();
ScaleDownAndFadeOutView(bar_view->expanded_state_new_desk_button(),
bounds.CenterPoint());
ui::Layer* layer = bar_view->background_view()->layer();
ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
InitScopedAnimationSettings(&settings, kZeroStateAnimationDuration);
gfx::Transform transform;
transform.Translate(0,
-(bounds.height() - DesksBarView::kZeroStateBarHeight));
layer->SetTransform(transform);
PositionWindowsInOverview();
}
} // namespace ash
......@@ -54,6 +54,29 @@ void PerformRemoveDeskMiniViewAnimation(
ExpandedStateNewDeskButton* expanded_state_new_desk_button,
int shift_x);
// Performs the animation of switching from zero state desks bar to expanded
// state desks bar. It scales up and fades in the current mini views and the
// ExpandedStateNewDeskButton. Also animates the bar's background view from the
// zero state bar's height to the expanded bar's height.
void PerformZeroStateToExpandedStateMiniViewAnimation(DesksBarView* bar_view);
// Performs the animation of switching from expanded state desks bar to zero
// state desks bar. This happens when a desk is removed such that a single desk
// is remaining. It scales down and fades out the |removed_mini_views| and the
// ExpandedStateNewDeskButton. |removed_mini_views| will be removed from the
// views hierarchy. But the ExpandedStateNewDeskButton will be kept and set to
// invisible. It will also animate the bar's background view from the expanded
// bar's height to zero state bar's height.
//
// * Notes:
// - It assumes the background view, |removed_mini_views| and the
// ExpandedStateNewDeskButton are still laid out at their previous positions
// before the bar state transition.
// - Layout will be done once the animation is completed.
void PerformExpandedStateToZeroStateMiniViewAnimation(
DesksBarView* bar_view,
std::vector<DeskMiniView*> removed_mini_views);
} // namespace ash
#endif // ASH_WM_DESKS_DESK_MINI_VIEW_ANIMATIONS_H_
......@@ -505,7 +505,6 @@ void DesksBarView::OnDeskRemoved(const Desk* desk) {
auto partition_iter = mini_views_.erase(iter);
UpdateMinimumWidthToFitContents();
overview_grid_->OnDesksChanged();
const bool is_bento_enabled = features::IsBentoEnabled();
if (is_bento_enabled)
expanded_state_new_desk_button_->UpdateButtonState();
......@@ -517,12 +516,15 @@ void DesksBarView::OnDeskRemoved(const Desk* desk) {
// Switch to zero state if there is a single desk after removing.
if (is_bento_enabled && mini_views_.size() == 1) {
scroll_view_contents_->RemoveChildView(removed_mini_view);
scroll_view_contents_->RemoveChildView(mini_views_[0]);
std::vector<DeskMiniView*> removed_mini_views;
removed_mini_views.push_back(removed_mini_view);
removed_mini_views.push_back(mini_views_[0]);
mini_views_.clear();
SetExpanded(false);
// Keep current layout until the animation is completed.
PerformExpandedStateToZeroStateMiniViewAnimation(this, removed_mini_views);
return;
}
overview_grid_->OnDesksChanged();
PerformRemoveDeskMiniViewAnimation(
removed_mini_view,
std::vector<DeskMiniView*>(mini_views_.begin(), partition_iter),
......@@ -549,7 +551,10 @@ void DesksBarView::UpdateNewMiniViews(bool initializing_bar_view,
const auto& desks = DesksController::Get()->desks();
if (is_bento_enabled) {
if (IsZeroState() && !expanding_bar_view) {
SetExpanded(false);
UpdateBentoDeskButtonsVisibility();
gfx::Transform transform;
transform.Translate(0, -(height() - kZeroStateBarHeight));
background_view_->layer()->SetTransform(transform);
return;
}
} else if (desks.size() < 2) {
......@@ -602,9 +607,9 @@ void DesksBarView::UpdateNewMiniViews(bool initializing_bar_view,
UpdateMinimumWidthToFitContents();
overview_grid_->OnDesksChanged();
// TODO(mimch): Add the expanding animation.
if (expanding_bar_view) {
SetExpanded(true);
UpdateBentoDeskButtonsVisibility();
PerformZeroStateToExpandedStateMiniViewAnimation(this);
return;
}
......@@ -663,16 +668,4 @@ void DesksBarView::UpdateBentoDeskButtonsVisibility() {
expanded_state_new_desk_button_->SetVisible(!is_zero_state);
}
void DesksBarView::SetExpanded(bool expanded) {
DCHECK(features::IsBentoEnabled());
UpdateBentoDeskButtonsVisibility();
gfx::Transform transform;
if (!expanded)
transform.Translate(0, -(height() - kZeroStateBarHeight));
background_view_->layer()->SetTransform(transform);
overview_grid_->PositionWindows(/*animate=*/true, /*ignored_items=*/{});
}
} // namespace ash
......@@ -155,10 +155,6 @@ class ASH_EXPORT DesksBarView : public views::View,
// Bento is enabled.
void UpdateBentoDeskButtonsVisibility();
// Translates the background view and positions windows in overview while
// switching between zero state desks bar and expanded desks bar.
void SetExpanded(bool expanded);
// A view that shows a dark gary transparent background that can be animated
// when the very first mini_views are created.
views::View* background_view_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment