Commit c50e7d35 authored by Weidong Guo's avatar Weidong Guo Committed by Commit Bot

Improve app list transition animation triggered by dragging

Changes:
1. Avoid calculating and updating opacity for all apps for each dragging
   update. Instead, calculate opacity of each row in current page and
   only update changed apps. Also avoid button press on page switcher
   during dragging to prevent opacity not being reset.
2. Clear search results after widget has been destroyed to avoid jank
   during close animation.

Bug: 897384
Change-Id: Id0e848cc82f60740212467c64e05d032081ad45b
Reviewed-on: https://chromium-review.googlesource.com/c/1292386Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarYury Khmel <khmel@chromium.org>
Commit-Queue: Weidong Guo <weidongg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601755}
parent 5107d9c9
...@@ -683,11 +683,15 @@ void AppListControllerImpl::ViewShown(int64_t display_id) { ...@@ -683,11 +683,15 @@ void AppListControllerImpl::ViewShown(int64_t display_id) {
} }
void AppListControllerImpl::ViewClosing() { void AppListControllerImpl::ViewClosing() {
if (client_)
client_->ViewClosing();
}
void AppListControllerImpl::ViewClosed() {
// Clear results to prevent initializing the next app list view with outdated // Clear results to prevent initializing the next app list view with outdated
// results. // results.
presenter_.GetView()->search_box_view()->ClearSearch();
if (client_) if (client_)
client_->ViewClosing(); client_->StartSearch(base::string16());
} }
void AppListControllerImpl::GetWallpaperProminentColors( void AppListControllerImpl::GetWallpaperProminentColors(
......
...@@ -171,6 +171,7 @@ class ASH_EXPORT AppListControllerImpl ...@@ -171,6 +171,7 @@ class ASH_EXPORT AppListControllerImpl
int event_flags) override; int event_flags) override;
void ViewShown(int64_t display_id) override; void ViewShown(int64_t display_id) override;
void ViewClosing() override; void ViewClosing() override;
void ViewClosed() override;
void GetWallpaperProminentColors( void GetWallpaperProminentColors(
GetWallpaperProminentColorsCallback callback) override; GetWallpaperProminentColorsCallback callback) override;
void ActivateItem(const std::string& id, int event_flags) override; void ActivateItem(const std::string& id, int event_flags) override;
......
...@@ -117,13 +117,17 @@ void AppListPresenterDelegateImpl::OnShown(int64_t display_id) { ...@@ -117,13 +117,17 @@ void AppListPresenterDelegateImpl::OnShown(int64_t display_id) {
controller_->ViewShown(display_id); controller_->ViewShown(display_id);
} }
void AppListPresenterDelegateImpl::OnDismissed() { void AppListPresenterDelegateImpl::OnClosing() {
DCHECK(is_visible_); DCHECK(is_visible_);
DCHECK(view_); DCHECK(view_);
is_visible_ = false; is_visible_ = false;
controller_->ViewClosing(); controller_->ViewClosing();
} }
void AppListPresenterDelegateImpl::OnClosed() {
controller_->ViewClosed();
}
gfx::Vector2d AppListPresenterDelegateImpl::GetVisibilityAnimationOffset( gfx::Vector2d AppListPresenterDelegateImpl::GetVisibilityAnimationOffset(
aura::Window* root_window) { aura::Window* root_window) {
DCHECK(Shell::HasInstance()); DCHECK(Shell::HasInstance());
......
...@@ -51,7 +51,8 @@ class ASH_EXPORT AppListPresenterDelegateImpl ...@@ -51,7 +51,8 @@ class ASH_EXPORT AppListPresenterDelegateImpl
int64_t display_id, int64_t display_id,
int current_apps_page) override; int current_apps_page) override;
void OnShown(int64_t display_id) override; void OnShown(int64_t display_id) override;
void OnDismissed() override; void OnClosing() override;
void OnClosed() override;
gfx::Vector2d GetVisibilityAnimationOffset( gfx::Vector2d GetVisibilityAnimationOffset(
aura::Window* root_window) override; aura::Window* root_window) override;
base::TimeDelta GetVisibilityAnimationDuration(aura::Window* root_window, base::TimeDelta GetVisibilityAnimationDuration(aura::Window* root_window,
......
...@@ -87,6 +87,9 @@ class ASH_PUBLIC_EXPORT AppListViewDelegate { ...@@ -87,6 +87,9 @@ class ASH_PUBLIC_EXPORT AppListViewDelegate {
// Invoked when the app list is closing. // Invoked when the app list is closing.
virtual void ViewClosing() = 0; virtual void ViewClosing() = 0;
// Invoked when the app list is closed.
virtual void ViewClosed() = 0;
// Gets the wallpaper prominent colors. // Gets the wallpaper prominent colors.
using GetWallpaperProminentColorsCallback = using GetWallpaperProminentColorsCallback =
base::OnceCallback<void(const std::vector<SkColor>&)>; base::OnceCallback<void(const std::vector<SkColor>&)>;
......
...@@ -45,8 +45,11 @@ class APP_LIST_PRESENTER_EXPORT AppListPresenterDelegate { ...@@ -45,8 +45,11 @@ class APP_LIST_PRESENTER_EXPORT AppListPresenterDelegate {
// Called when app list is shown. // Called when app list is shown.
virtual void OnShown(int64_t display_id) = 0; virtual void OnShown(int64_t display_id) = 0;
// Called when app list is dismissed // Called when app list is closing.
virtual void OnDismissed() = 0; virtual void OnClosing() = 0;
// Called when app list is closed.
virtual void OnClosed() = 0;
// Returns the offset vector by which the app list window should animate // Returns the offset vector by which the app list window should animate
// when it gets shown or hidden. // when it gets shown or hidden.
......
...@@ -161,7 +161,7 @@ void AppListPresenterImpl::Dismiss(base::TimeTicks event_time_stamp) { ...@@ -161,7 +161,7 @@ void AppListPresenterImpl::Dismiss(base::TimeTicks event_time_stamp) {
if (view_->GetWidget()->IsActive()) if (view_->GetWidget()->IsActive())
view_->GetWidget()->Deactivate(); view_->GetWidget()->Deactivate();
delegate_->OnDismissed(); delegate_->OnClosing();
ScheduleAnimation(); ScheduleAnimation();
NotifyTargetVisibilityChanged(GetTargetVisibility()); NotifyTargetVisibilityChanged(GetTargetVisibility());
NotifyVisibilityChanged(GetTargetVisibility(), display_id); NotifyVisibilityChanged(GetTargetVisibility(), display_id);
...@@ -402,6 +402,10 @@ void AppListPresenterImpl::OnWidgetDestroying(views::Widget* widget) { ...@@ -402,6 +402,10 @@ void AppListPresenterImpl::OnWidgetDestroying(views::Widget* widget) {
ResetView(); ResetView();
} }
void AppListPresenterImpl::OnWidgetDestroyed(views::Widget* widget) {
delegate_->OnClosed();
}
void AppListPresenterImpl::OnWidgetVisibilityChanged(views::Widget* widget, void AppListPresenterImpl::OnWidgetVisibilityChanged(views::Widget* widget,
bool visible) { bool visible) {
DCHECK_EQ(view_->GetWidget(), widget); DCHECK_EQ(view_->GetWidget(), widget);
......
...@@ -129,6 +129,7 @@ class APP_LIST_PRESENTER_EXPORT AppListPresenterImpl ...@@ -129,6 +129,7 @@ class APP_LIST_PRESENTER_EXPORT AppListPresenterImpl
// views::WidgetObserver overrides: // views::WidgetObserver overrides:
void OnWidgetDestroying(views::Widget* widget) override; void OnWidgetDestroying(views::Widget* widget) override;
void OnWidgetDestroyed(views::Widget* widget) override;
void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override; void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override;
// PaginationModelObserver overrides: // PaginationModelObserver overrides:
......
...@@ -58,7 +58,8 @@ class AppListPresenterDelegateTest : public AppListPresenterDelegate { ...@@ -58,7 +58,8 @@ class AppListPresenterDelegateTest : public AppListPresenterDelegate {
view->Initialize(params); view->Initialize(params);
} }
void OnShown(int64_t display_id) override { on_shown_called_ = true; } void OnShown(int64_t display_id) override { on_shown_called_ = true; }
void OnDismissed() override { on_dismissed_called_ = true; } void OnClosing() override { on_dismissed_called_ = true; }
void OnClosed() override {}
gfx::Vector2d GetVisibilityAnimationOffset(aura::Window*) override { gfx::Vector2d GetVisibilityAnimationOffset(aura::Window*) override {
return gfx::Vector2d(0, 0); return gfx::Vector2d(0, 0);
} }
......
...@@ -66,6 +66,7 @@ class AppListTestViewDelegate : public AppListViewDelegate, ...@@ -66,6 +66,7 @@ class AppListTestViewDelegate : public AppListViewDelegate,
void ViewShown(int64_t display_id) override {} void ViewShown(int64_t display_id) override {}
void DismissAppList() override; void DismissAppList() override;
void ViewClosing() override {} void ViewClosing() override {}
void ViewClosed() override {}
void GetWallpaperProminentColors( void GetWallpaperProminentColors(
GetWallpaperProminentColorsCallback callback) override {} GetWallpaperProminentColorsCallback callback) override {}
void ActivateItem(const std::string& id, int event_flags) override; void ActivateItem(const std::string& id, int event_flags) override;
......
...@@ -518,14 +518,7 @@ void AppListView::Layout() { ...@@ -518,14 +518,7 @@ void AppListView::Layout() {
app_list_background_shield_bounds); app_list_background_shield_bounds);
} }
// Translate the background shield to avoid holes left by rounded corner in UpdateAppListBackgroundYPosition();
// fullscreen state.
gfx::Transform transform;
if (app_list_state_ == AppListViewState::FULLSCREEN_ALL_APPS ||
app_list_state_ == AppListViewState::FULLSCREEN_SEARCH) {
transform.Translate(0, -kAppListBackgroundRadius);
}
app_list_background_shield_->SetTransform(transform);
} }
void AppListView::GetAccessibleNodeData(ui::AXNodeData* node_data) { void AppListView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
...@@ -1348,9 +1341,7 @@ void AppListView::StartCloseAnimation(base::TimeDelta animation_duration) { ...@@ -1348,9 +1341,7 @@ void AppListView::StartCloseAnimation(base::TimeDelta animation_duration) {
if (is_side_shelf_) if (is_side_shelf_)
return; return;
if (app_list_state_ != AppListViewState::CLOSED) SetState(AppListViewState::CLOSED);
SetState(AppListViewState::CLOSED);
app_list_main_view_->contents_view()->FadeOutOnClose(animation_duration); app_list_main_view_->contents_view()->FadeOutOnClose(animation_duration);
} }
...@@ -1512,25 +1503,15 @@ void AppListView::UpdateChildViewsYPositionAndOpacity() { ...@@ -1512,25 +1503,15 @@ void AppListView::UpdateChildViewsYPositionAndOpacity() {
if (app_list_state_ == AppListViewState::CLOSED) if (app_list_state_ == AppListViewState::CLOSED)
return; return;
// Update the Y position of the background shield. UpdateAppListBackgroundYPosition();
float app_list_transition_progress = GetAppListTransitionProgress();
gfx::Transform transform;
if (app_list_transition_progress >= 1 && app_list_transition_progress <= 2) {
// Translate background shield so that it ends drag at y position
// -|kAppListBackgroundRadius| when dragging between peeking and fullscreen.
transform.Translate(
0, -kAppListBackgroundRadius * (app_list_transition_progress - 1));
}
app_list_background_shield_->SetTransform(transform);
// Update the opacity of the background shield. // Update the opacity of the background shield.
float shield_opacity = const float shield_opacity =
is_background_blur_enabled_ ? kAppListOpacityWithBlur : kAppListOpacity; is_background_blur_enabled_ ? kAppListOpacityWithBlur : kAppListOpacity;
app_list_background_shield_->layer()->SetOpacity( app_list_background_shield_->layer()->SetOpacity(
is_in_drag_ ? background_opacity_ : shield_opacity); is_in_drag_ ? background_opacity_ : shield_opacity);
search_box_view_->UpdateOpacity(); search_box_view_->UpdateOpacity();
app_list_main_view_->contents_view()->UpdateYPositionAndOpacity(); app_list_main_view_->contents_view()->UpdateYPositionAndOpacity();
} }
...@@ -1710,4 +1691,23 @@ gfx::Rect AppListView::GetPreferredWidgetBoundsForState( ...@@ -1710,4 +1691,23 @@ gfx::Rect AppListView::GetPreferredWidgetBoundsForState(
parent->bounds().width(), GetFullscreenStateHeight()); parent->bounds().width(), GetFullscreenStateHeight());
} }
void AppListView::UpdateAppListBackgroundYPosition() {
// Update the y position of the background shield.
gfx::Transform transform;
if (is_in_drag_) {
float app_list_transition_progress = GetAppListTransitionProgress();
if (app_list_transition_progress >= 1 &&
app_list_transition_progress <= 2) {
// Translate background shield so that it ends drag at y position
// -|kAppListBackgroundRadius| when dragging between peeking and
// fullscreen.
transform.Translate(
0, -kAppListBackgroundRadius * (app_list_transition_progress - 1));
}
} else if (is_fullscreen()) {
transform.Translate(0, -kAppListBackgroundRadius);
}
app_list_background_shield_->SetTransform(transform);
}
} // namespace app_list } // namespace app_list
...@@ -344,6 +344,10 @@ class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView { ...@@ -344,6 +344,10 @@ class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView {
// widget is initialized. // widget is initialized.
gfx::Rect GetPreferredWidgetBoundsForState(AppListViewState state); gfx::Rect GetPreferredWidgetBoundsForState(AppListViewState state);
// Updates y position of |app_list_background_shield_| based on the
// |app_list_state_| and |is_in_drag_|.
void UpdateAppListBackgroundYPosition();
AppListViewDelegate* delegate_; // Weak. Owned by AppListService. AppListViewDelegate* delegate_; // Weak. Owned by AppListService.
AppListModel* const model_; // Not Owned. AppListModel* const model_; // Not Owned.
SearchModel* const search_model_; // Not Owned. SearchModel* const search_model_; // Not Owned.
......
...@@ -157,6 +157,11 @@ void AppsContainerView::UpdateControlVisibility(AppListViewState app_list_state, ...@@ -157,6 +157,11 @@ void AppsContainerView::UpdateControlVisibility(AppListViewState app_list_state,
apps_grid_view_->UpdateControlVisibility(app_list_state, is_in_drag); apps_grid_view_->UpdateControlVisibility(app_list_state, is_in_drag);
page_switcher_->SetVisible( page_switcher_->SetVisible(
app_list_state == AppListViewState::FULLSCREEN_ALL_APPS || is_in_drag); app_list_state == AppListViewState::FULLSCREEN_ALL_APPS || is_in_drag);
// Ignore button press during dragging to avoid app list item views' opacity
// being set to wrong value.
page_switcher_->set_ignore_button_press(is_in_drag);
if (suggestion_chip_container_view_) { if (suggestion_chip_container_view_) {
suggestion_chip_container_view_->SetVisible( suggestion_chip_container_view_->SetVisible(
app_list_state == AppListViewState::FULLSCREEN_ALL_APPS || app_list_state == AppListViewState::FULLSCREEN_ALL_APPS ||
......
...@@ -1968,19 +1968,19 @@ void AppsGridView::UpdateOpacity() { ...@@ -1968,19 +1968,19 @@ void AppsGridView::UpdateOpacity() {
} }
} }
// Updates the opacity of all apps. The opacity of the app starting at 0.f if (view_structure_.pages().empty())
// when the ceterline of the app is |kAllAppsOpacityStartPx| above the bottom return;
// of work area and transitioning to 1.0f by the time the centerline reaches
// |kAllAppsOpacityEndPx| above the work area bottom.
float centerline_above_work_area = 0.f;
const float drag_amount_above_peeking = current_height - peeking_height;
const float opacity_factor = drag_amount_above_peeking / shelf_height;
for (int i = 0; i < view_model_.view_size(); ++i) {
AppListItemView* item_view = GetItemViewAt(i);
if (item_view == drag_view_)
continue;
gfx::Rect view_bounds = view_model_.ideal_bounds(i); // Updates the opacity of the apps in current page. The opacity of the app
// starting at 0.f when the ceterline of the app is |kAllAppsOpacityStartPx|
// above the bottom of work area and transitioning to 1.0f by the time the
// centerline reaches |kAllAppsOpacityEndPx| above the work area bottom.
const int selected_page = pagination_model_.selected_page();
auto current_page = view_structure_.pages()[selected_page];
float centerline_above_work_area = 0.f;
for (size_t i = 0; i < current_page.size(); i += cols_) {
AppListItemView* item_view = current_page[i];
gfx::Rect view_bounds = item_view->bounds();
views::View::ConvertRectToScreen(this, &view_bounds); views::View::ConvertRectToScreen(this, &view_bounds);
centerline_above_work_area = std::max<float>( centerline_above_work_area = std::max<float>(
app_list_view->GetScreenBottom() - view_bounds.CenterPoint().y(), 0.f); app_list_view->GetScreenBottom() - view_bounds.CenterPoint().y(), 0.f);
...@@ -1989,21 +1989,16 @@ void AppsGridView::UpdateOpacity() { ...@@ -1989,21 +1989,16 @@ void AppsGridView::UpdateOpacity() {
(kAllAppsOpacityEndPx - kAllAppsOpacityStartPx), (kAllAppsOpacityEndPx - kAllAppsOpacityStartPx),
0.f), 0.f),
1.0f); 1.0f);
opacity = should_restore_opacity ? 1.0f : opacity;
// The first row of apps should be shown gradually if start with dragging up if (opacity == item_view->layer()->opacity())
// from PEEKING and should not be shown if start with dragging down from continue;
// PEEKING.
GridIndex index = GetIndexOfView(item_view);
if ((index.page == 0 && index.slot < cols_ &&
contents_view_->app_list_view()->drag_started_from_peeking()) &&
((drag_amount_above_peeking >= 0 &&
drag_amount_above_peeking <= shelf_height) ||
(drag_amount_above_peeking < 0 &&
centerline_above_work_area >= kAllAppsOpacityStartPx))) {
opacity = std::max(opacity * opacity_factor, 0.f);
}
item_view->layer()->SetOpacity(should_restore_opacity ? 1.0f : opacity); const size_t end_index = std::min(current_page.size() - 1, i + cols_ - 1);
for (size_t j = i; j <= end_index; ++j) {
if (current_page[j] != drag_view_)
current_page[j]->layer()->SetOpacity(opacity);
}
} }
} }
......
...@@ -231,7 +231,7 @@ void PageSwitcher::Layout() { ...@@ -231,7 +231,7 @@ void PageSwitcher::Layout() {
void PageSwitcher::ButtonPressed(views::Button* sender, void PageSwitcher::ButtonPressed(views::Button* sender,
const ui::Event& event) { const ui::Event& event) {
if (!model_) if (!model_ || ignore_button_press_)
return; return;
for (int i = 0; i < buttons_->child_count(); ++i) { for (int i = 0; i < buttons_->child_count(); ++i) {
......
...@@ -27,6 +27,8 @@ class PageSwitcher : public views::View, ...@@ -27,6 +27,8 @@ class PageSwitcher : public views::View,
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
void Layout() override; void Layout() override;
void set_ignore_button_press(bool ignore) { ignore_button_press_ = ignore; }
private: private:
// Overridden from views::ButtonListener: // Overridden from views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override;
...@@ -44,6 +46,9 @@ class PageSwitcher : public views::View, ...@@ -44,6 +46,9 @@ class PageSwitcher : public views::View,
// True if the page switcher button strip should grow vertically. // True if the page switcher button strip should grow vertically.
const bool vertical_; const bool vertical_;
// True if button press should be ignored.
bool ignore_button_press_ = false;
DISALLOW_COPY_AND_ASSIGN(PageSwitcher); DISALLOW_COPY_AND_ASSIGN(PageSwitcher);
}; };
......
...@@ -273,6 +273,10 @@ class ExampleAppListViewDelegate : public app_list::AppListViewDelegate { ...@@ -273,6 +273,10 @@ class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
// Nothing needs to be done. // Nothing needs to be done.
} }
void ViewClosed() override {
// Nothing needs to be done.
}
void GetWallpaperProminentColors( void GetWallpaperProminentColors(
GetWallpaperProminentColorsCallback callback) override { GetWallpaperProminentColorsCallback callback) override {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
......
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