diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-13 21:34:24 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-13 21:34:24 +0000 |
commit | d69a820b742aeeb6ba6d6521eb4d328b27ead35f (patch) | |
tree | 8b1b84f1eb0860e5825ff47c6dbe72f42b6ae2bb | |
parent | bb7edffa557429eb8653f26458ec499621c76dc2 (diff) | |
download | chromium_src-d69a820b742aeeb6ba6d6521eb4d328b27ead35f.zip chromium_src-d69a820b742aeeb6ba6d6521eb4d328b27ead35f.tar.gz chromium_src-d69a820b742aeeb6ba6d6521eb4d328b27ead35f.tar.bz2 |
app_list: Update over-scroll animation.
- Remove over-scroll animation on app icons;
- Add an over-scroll animation on bubble widget itself by shifting 48px in the
scroll direction and snap back after over-scroll;
BUG=none.
TEST=Verify bubble moves with touch when over-scroll happens and snaps back afterwards.
R=sky@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10915265
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156639 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/wm/app_list_controller.cc | 57 | ||||
-rw-r--r-- | ash/wm/app_list_controller.h | 16 | ||||
-rw-r--r-- | ui/app_list/apps_grid_view.cc | 20 | ||||
-rw-r--r-- | ui/app_list/pagination_model.cc | 4 | ||||
-rw-r--r-- | ui/app_list/pagination_model.h | 3 |
5 files changed, 84 insertions, 16 deletions
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc index 5ae14a9..8f6ebcb 100644 --- a/ash/wm/app_list_controller.cc +++ b/ash/wm/app_list_controller.cc @@ -33,6 +33,12 @@ const int kAnimationDurationMs = 200; // Offset in pixels to animation away/towards the launcher. const int kAnimationOffset = 8; +// Duration for snap back animation after over-scroll in milliseconds. +const int kSnapBackAnimationDurationMs = 100; + +// The maximum shift in pixels when over-scroll happens. +const int kMaxOverScrollShift = 48; + ui::Layer* GetLayer(views::Widget* widget) { return widget->GetNativeView()->layer(); } @@ -85,8 +91,10 @@ gfx::Rect OffsetTowardsShelf(const gfx::Rect& rect) { AppListController::AppListController() : pagination_model_(new app_list::PaginationModel), is_visible_(false), - view_(NULL) { + view_(NULL), + should_snap_back_(false) { Shell::GetInstance()->AddShellObserver(this); + pagination_model_->AddObserver(this); } AppListController::~AppListController() { @@ -96,6 +104,7 @@ AppListController::~AppListController() { view_->GetWidget()->CloseNow(); Shell::GetInstance()->RemoveShellObserver(this); + pagination_model_->RemoveObserver(this); } void AppListController::SetVisible(bool visible) { @@ -181,6 +190,7 @@ void AppListController::ScheduleAnimation() { gfx::Rect target_bounds; if (is_visible_) { target_bounds = layer->bounds(); + view_bounds_ = target_bounds; layer->SetBounds(OffsetTowardsShelf(layer->bounds())); } else { target_bounds = OffsetTowardsShelf(layer->bounds()); @@ -220,8 +230,10 @@ void AppListController::ProcessLocatedEvent(aura::Window* target, } void AppListController::UpdateBounds() { - if (view_ && is_visible_) + if (view_ && is_visible_) { view_->UpdateBounds(); + view_bounds_ = view_->GetWidget()->GetNativeView()->bounds(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -306,5 +318,46 @@ void AppListController::OnLauncherIconPositionsChanged() { UpdateBounds(); } +//////////////////////////////////////////////////////////////////////////////// +// AppListController, PaginationModelObserver implementation: + +void AppListController::TotalPagesChanged() { +} + +void AppListController::SelectedPageChanged(int old_selected, + int new_selected) { +} + +void AppListController::TransitionChanged() { + // |view_| could be NULL when app list is closed with a running transition. + if (!view_) + return; + + const app_list::PaginationModel::Transition& transition = + pagination_model_->transition(); + if (pagination_model_->is_valid_page(transition.target_page)) + return; + + if (pagination_model_->scrolling()) { + const int current_page = pagination_model_->selected_page(); + const int dir = transition.target_page > current_page ? -1 : 1; + + const double progress = 1.0 - pow(1.0 - transition.progress, 4); + const int shift = kMaxOverScrollShift * progress * dir; + + gfx::Rect shifted(view_bounds_); + shifted.set_x(shifted.x() + shift); + view_->GetWidget()->SetBounds(shifted); + should_snap_back_ = true; + } else if (should_snap_back_) { + should_snap_back_ = false; + ui::Layer* layer = GetLayer(view_->GetWidget()); + ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); + animation.SetTransitionDuration( + base::TimeDelta::FromMilliseconds(kSnapBackAnimationDurationMs)); + layer->SetBounds(view_bounds_); + } +} + } // namespace internal } // namespace ash diff --git a/ash/wm/app_list_controller.h b/ash/wm/app_list_controller.h index a360c28..a841609 100644 --- a/ash/wm/app_list_controller.h +++ b/ash/wm/app_list_controller.h @@ -10,10 +10,12 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/timer.h" +#include "ui/app_list/pagination_model_observer.h" #include "ui/aura/event_filter.h" #include "ui/aura/focus_change_observer.h" #include "ui/aura/root_window_observer.h" #include "ui/compositor/layer_animation_observer.h" +#include "ui/gfx/rect.h" #include "ui/views/widget/widget_observer.h" namespace app_list { @@ -38,7 +40,8 @@ class AppListController : public aura::EventFilter, public ui::ImplicitAnimationObserver, public views::WidgetObserver, public ShellObserver, - public LauncherIconObserver { + public LauncherIconObserver, + public app_list::PaginationModelObserver { public: AppListController(); virtual ~AppListController(); @@ -104,6 +107,11 @@ class AppListController : public aura::EventFilter, // LauncherIconObserver overrides: virtual void OnLauncherIconPositionsChanged() OVERRIDE; + // app_list::PaginationModelObserver overrides: + virtual void TotalPagesChanged() OVERRIDE; + virtual void SelectedPageChanged(int old_selected, int new_selected) OVERRIDE; + virtual void TransitionChanged() OVERRIDE; + scoped_ptr<app_list::PaginationModel> pagination_model_; // Whether we should show or hide app list widget. @@ -112,6 +120,12 @@ class AppListController : public aura::EventFilter, // The AppListView this class manages, owned by its widget. app_list::AppListView* view_; + // Cached bounds of |view_| for snapping back animation after over-scroll. + gfx::Rect view_bounds_; + + // Whether should schedule snap back animation. + bool should_snap_back_; + DISALLOW_COPY_AND_ASSIGN(AppListController); }; diff --git a/ui/app_list/apps_grid_view.cc b/ui/app_list/apps_grid_view.cc index e578303..380ca00 100644 --- a/ui/app_list/apps_grid_view.cc +++ b/ui/app_list/apps_grid_view.cc @@ -25,13 +25,6 @@ const int kPagePadding = 40; const int kPreferredTileWidth = 88; const int kPreferredTileHeight = 98; -// Max extra column padding space in pixels for invalid page transition. -const int kMaxExtraColPaddingForInvalidTransition = 15; - -// Extra column padding space in pixels of first column for invalid page -// transition. -const int kBaseExtraColPaddingForInvalidTransition = 50; - } // namespace namespace app_list { @@ -132,10 +125,7 @@ void AppsGridView::Layout() { // Transition to right means negative offset. const int dir = transition.target_page > current_page ? -1 : 1; const int transition_offset = is_valid ? - transition.progress * page_width * dir : - transition.progress * kMaxExtraColPaddingForInvalidTransition * dir; - const int base_transition_offset = is_valid ? 0 : - transition.progress * kBaseExtraColPaddingForInvalidTransition * dir; + transition.progress * page_width * dir : 0; const int first_visible_index = current_page * tiles_per_page(); const int last_visible_index = (current_page + 1) * tiles_per_page() - 1; @@ -156,7 +146,6 @@ void AppsGridView::Layout() { x_offset += transition_offset; } else { const int col = i % cols_; - x_offset += base_transition_offset; if (transition_offset > 0) x_offset += transition_offset * col; else @@ -342,7 +331,12 @@ void AppsGridView::SelectedPageChanged(int old_selected, int new_selected) { } void AppsGridView::TransitionChanged() { - Layout(); + // Update layout for valid page transition only since over-scroll no longer + // animates app icons. + const PaginationModel::Transition& transition = + pagination_model_->transition(); + if (pagination_model_->is_valid_page(transition.target_page)) + Layout(); } } // namespace app_list diff --git a/ui/app_list/pagination_model.cc b/ui/app_list/pagination_model.cc index cadc1ea..e05896c 100644 --- a/ui/app_list/pagination_model.cc +++ b/ui/app_list/pagination_model.cc @@ -15,6 +15,7 @@ PaginationModel::PaginationModel() : total_pages_(-1), selected_page_(-1), transition_(-1, 0), + scrolling_(false), pending_selected_page_(-1), transition_duration_ms_(0) { } @@ -100,6 +101,7 @@ void PaginationModel::SetTransitionDuration(int duration_ms) { } void PaginationModel::StartScroll() { + scrolling_ = true; // Cancels current transition animation (if any). transition_animation_.reset(); } @@ -131,6 +133,8 @@ void PaginationModel::UpdateScroll(double delta) { } void PaginationModel::EndScroll(bool cancel) { + scrolling_ = false; + if (!has_transition()) return; diff --git a/ui/app_list/pagination_model.h b/ui/app_list/pagination_model.h index 89b057a..7026294 100644 --- a/ui/app_list/pagination_model.h +++ b/ui/app_list/pagination_model.h @@ -80,6 +80,7 @@ class APP_LIST_EXPORT PaginationModel : public ui::AnimationDelegate { int total_pages() const { return total_pages_; } int selected_page() const { return selected_page_; } const Transition& transition() const { return transition_; } + bool scrolling() const { return scrolling_; } bool is_valid_page(int page) const { return page >= 0 && page < total_pages_; @@ -118,6 +119,8 @@ class APP_LIST_EXPORT PaginationModel : public ui::AnimationDelegate { Transition transition_; + bool scrolling_; // Whether a scroll is in progress. + // Pending selected page when SelectedPage is called during a transition. If // multiple SelectPage is called while a transition is in progress, only the // last target page is remembered here. |