Chromium Code Reviews| Index: ui/app_list/views/contents_view.cc |
| diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc |
| index a6fd2c41428b3a1d2e0e7090eeb3d6a6147d2687..f15ee29282631b7c8b31ef57537a1dcd617f7efb 100644 |
| --- a/ui/app_list/views/contents_view.cc |
| +++ b/ui/app_list/views/contents_view.cc |
| @@ -10,7 +10,6 @@ |
| #include "ui/app_list/app_list_constants.h" |
| #include "ui/app_list/app_list_switches.h" |
| #include "ui/app_list/app_list_view_delegate.h" |
| -#include "ui/app_list/pagination_model.h" |
| #include "ui/app_list/views/app_list_folder_view.h" |
| #include "ui/app_list/views/app_list_main_view.h" |
| #include "ui/app_list/views/apps_container_view.h" |
| @@ -18,7 +17,6 @@ |
| #include "ui/app_list/views/search_result_list_view.h" |
| #include "ui/app_list/views/start_page_view.h" |
| #include "ui/events/event.h" |
| -#include "ui/views/animation/bounds_animator.h" |
| #include "ui/views/view_model.h" |
| #include "ui/views/view_model_utils.h" |
| @@ -39,8 +37,7 @@ ContentsView::ContentsView(AppListMainView* app_list_main_view, |
| AppListViewDelegate* view_delegate) |
| : start_page_view_(NULL), |
| app_list_main_view_(app_list_main_view), |
| - view_model_(new views::ViewModel), |
| - bounds_animator_(new views::BoundsAnimator(this)) { |
| + view_model_(new views::ViewModel) { |
| DCHECK(model); |
| search_results_view_ = |
| @@ -53,12 +50,17 @@ ContentsView::ContentsView(AppListMainView* app_list_main_view, |
| } |
| apps_container_view_ = new AppsContainerView(app_list_main_view, model); |
| - active_page_ = AddLauncherPage(apps_container_view_, NAMED_PAGE_APPS); |
| + int apps_page_index = AddLauncherPage(apps_container_view_, NAMED_PAGE_APPS); |
| search_results_view_->SetResults(model->results()); |
| + |
| + pagination_model_.SetTotalPages(view_model_->view_size()); |
| + pagination_model_.SelectPage(apps_page_index, false); |
| + pagination_model_.AddObserver(this); |
| } |
| ContentsView::~ContentsView() { |
| + pagination_model_.RemoveObserver(this); |
| } |
| void ContentsView::CancelDrag() { |
| @@ -78,19 +80,25 @@ void ContentsView::SetDragAndDropHostOfCurrentAppList( |
| } |
| void ContentsView::SetActivePage(int page_index) { |
| - if (active_page_ == page_index) |
| + if (GetActivePageIndex() == page_index) |
| return; |
| - active_page_ = page_index; |
| + // Start animating to the new page. |
| + pagination_model_.SelectPage(page_index, true); |
| ActivePageChanged(); |
| } |
| +int ContentsView::GetActivePageIndex() const { |
| + // The active page is changed at the beginning of an animation, not the end. |
| + return pagination_model_.SelectedTargetPage(); |
| +} |
| + |
| bool ContentsView::IsNamedPageActive(NamedPage named_page) const { |
| std::map<NamedPage, int>::const_iterator it = |
| named_page_to_view_.find(named_page); |
| if (it == named_page_to_view_.end()) |
| return false; |
| - return it->second == active_page_; |
| + return it->second == GetActivePageIndex(); |
| } |
| int ContentsView::GetPageIndexForNamedPage(NamedPage named_page) const { |
| @@ -116,52 +124,57 @@ void ContentsView::ActivePageChanged() { |
| if (IsNamedPageActive(NAMED_PAGE_START)) |
| start_page_view_->Reset(); |
| - |
| - AnimateToIdealBounds(); |
| } |
| -void ContentsView::CalculateIdealBounds() { |
| +void ContentsView::CalculateAndSetBounds(bool ideal) { |
| gfx::Rect rect(GetContentsBounds()); |
| if (rect.IsEmpty()) |
| return; |
| - if (app_list::switches::IsExperimentalAppListEnabled()) { |
| - gfx::Rect incoming_target(rect); |
| - gfx::Rect outgoing_target(rect); |
| - outgoing_target.set_x(-outgoing_target.width()); |
| - |
| - for (int i = 0; i < view_model_->view_size(); ++i) { |
| - view_model_->set_ideal_bounds( |
| - i, i == active_page_ ? incoming_target : outgoing_target); |
| + // The bounds calculations will potentially be mid-transition (depending on |
| + // the state of the PaginationModel). |
| + int current_page = std::max(0, pagination_model_.selected_page()); |
|
calamity
2014/06/12 03:05:08
When can this be negative?
Matt Giuca
2014/06/16 00:59:05
pagination_model_.selected_page() is -1 by default
|
| + int target_page = current_page; |
| + double progress = 1; |
| + if (pagination_model_.has_transition()) { |
| + const PaginationModel::Transition& transition = |
| + pagination_model_.transition(); |
| + if (pagination_model_.is_valid_page(transition.target_page)) { |
| + target_page = transition.target_page; |
| + // If |ideal|, assume that any pending animation has already completed. |
| + if (!ideal) |
| + progress = transition.progress; |
| } |
| - return; |
| } |
| - gfx::Rect container_frame(rect); |
| - gfx::Rect results_frame(rect); |
| - |
| - // Offsets apps grid and result list based on |active_page_|. |
| - // SearchResultListView is on top of apps grid. Visible view is left in |
| - // visible area and invisible ones is put out of the visible area. |
| - int contents_area_height = rect.height(); |
| - if (IsNamedPageActive(NAMED_PAGE_APPS)) |
| - results_frame.Offset(0, -contents_area_height); |
| - else if (IsNamedPageActive(NAMED_PAGE_SEARCH_RESULTS)) |
| - container_frame.Offset(0, contents_area_height); |
| - else |
| - NOTREACHED() << "Page " << active_page_ << " invalid in current app list."; |
| + gfx::Rect incoming_target(rect); |
| + gfx::Rect outgoing_target(rect); |
| + int dir = target_page > current_page ? -1 : 1; |
| - view_model_->set_ideal_bounds(GetPageIndexForNamedPage(NAMED_PAGE_APPS), |
| - container_frame); |
| - view_model_->set_ideal_bounds( |
| - GetPageIndexForNamedPage(NAMED_PAGE_SEARCH_RESULTS), results_frame); |
| -} |
| + if (app_list::switches::IsExperimentalAppListEnabled()) { |
| + // The experimental app list transitions horizontally. |
| + int page_width = rect.width(); |
| + int transition_offset = progress * page_width * dir; |
| + |
| + outgoing_target.set_x(transition_offset); |
| + incoming_target.set_x(dir < 0 ? transition_offset + page_width |
| + : transition_offset - page_width); |
| + } else { |
| + // The normal app list transitions vertically. |
| + int page_height = rect.height(); |
| + int transition_offset = progress * page_height * dir; |
| + |
| + outgoing_target.set_y(transition_offset); |
| + incoming_target.set_y(dir < 0 ? transition_offset + page_height |
| + : transition_offset - page_height); |
| + } |
| -void ContentsView::AnimateToIdealBounds() { |
| - CalculateIdealBounds(); |
| - for (int i = 0; i < view_model_->view_size(); ++i) { |
| - bounds_animator_->AnimateViewTo(view_model_->view_at(i), |
| - view_model_->ideal_bounds(i)); |
| + if (ideal) { |
| + view_model_->set_ideal_bounds(current_page, outgoing_target); |
| + view_model_->set_ideal_bounds(target_page, incoming_target); |
|
calamity
2014/06/12 03:05:08
It looks like ideal bounds aren't really used anyw
Matt Giuca
2014/06/16 00:59:05
I guess if something isn't used at all, but semant
|
| + } else { |
| + view_model_->view_at(current_page)->SetBoundsRect(outgoing_target); |
| + view_model_->view_at(target_page)->SetBoundsRect(incoming_target); |
| } |
| } |
| @@ -197,6 +210,13 @@ int ContentsView::AddLauncherPage(views::View* view, NamedPage named_page) { |
| return page_index; |
| } |
| +void ContentsView::FinishCurrentAnimationForTests() { |
| + if (!pagination_model_.has_transition()) |
| + return; |
|
calamity
2014/06/12 03:05:08
nit: blank line after early return.
Matt Giuca
2014/06/16 00:59:05
Done.
|
| + pagination_model_.SelectPage(pagination_model_.transition().target_page, |
| + false); |
| +} |
| + |
| gfx::Size ContentsView::GetPreferredSize() const { |
| const gfx::Size container_size = |
| apps_container_view_->apps_grid_view()->GetPreferredSize(); |
| @@ -208,12 +228,12 @@ gfx::Size ContentsView::GetPreferredSize() const { |
| } |
| void ContentsView::Layout() { |
| - CalculateIdealBounds(); |
| + CalculateAndSetBounds(true); |
| views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); |
| } |
| bool ContentsView::OnKeyPressed(const ui::KeyEvent& event) { |
| - return view_model_->view_at(active_page_)->OnKeyPressed(event); |
| + return view_model_->view_at(GetActivePageIndex())->OnKeyPressed(event); |
| } |
| bool ContentsView::OnMouseWheel(const ui::MouseWheelEvent& event) { |
| @@ -236,6 +256,19 @@ bool ContentsView::OnMouseWheel(const ui::MouseWheelEvent& event) { |
| return false; |
| } |
| +void ContentsView::TotalPagesChanged() { |
| +} |
| + |
| +void ContentsView::SelectedPageChanged(int old_selected, int new_selected) { |
| +} |
| + |
| +void ContentsView::TransitionStarted() { |
| +} |
| + |
| +void ContentsView::TransitionChanged() { |
| + CalculateAndSetBounds(false); |
| +} |
| + |
| void ContentsView::OnGestureEvent(ui::GestureEvent* event) { |
| if (!IsNamedPageActive(NAMED_PAGE_APPS)) |
| return; |