diff options
author | tapted@chromium.org <tapted@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-10 07:32:47 +0000 |
---|---|---|
committer | tapted@chromium.org <tapted@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-10 07:32:47 +0000 |
commit | 1cffa0b72693752efc88d37c2142919703bf5add (patch) | |
tree | 77e0463893fb05885149d4e021fb20fb4a33216f /ui/app_list | |
parent | a267ff14ffc271d52522affde71803bd29bca3e3 (diff) | |
download | chromium_src-1cffa0b72693752efc88d37c2142919703bf5add.zip chromium_src-1cffa0b72693752efc88d37c2142919703bf5add.tar.gz chromium_src-1cffa0b72693752efc88d37c2142919703bf5add.tar.bz2 |
(re)Implement Profile Switching on the Windows App Launcher
Since app list models are now owned by a syncable service, relying on
that model emptying out and re-filling to switch profiles on Windows no
longer works.
This re-implements profile switching for the Windows App Launcher by
re-creating its AppListMainView, and all the children, whenever the
profile changes in the AppListViewDelegate.
BUG=322384
TEST=Switching profiles with the Windows App Launcher should work again.
Review URL: https://codereview.chromium.org/106163011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239699 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/app_list')
-rw-r--r-- | ui/app_list/app_list.gyp | 1 | ||||
-rw-r--r-- | ui/app_list/test/app_list_test_view_delegate.h | 3 | ||||
-rw-r--r-- | ui/app_list/views/app_list_main_view.cc | 28 | ||||
-rw-r--r-- | ui/app_list/views/app_list_main_view.h | 21 | ||||
-rw-r--r-- | ui/app_list/views/app_list_main_view_unittest.cc | 90 | ||||
-rw-r--r-- | ui/app_list/views/app_list_view.cc | 1 | ||||
-rw-r--r-- | ui/app_list/views/page_switcher.h | 2 | ||||
-rw-r--r-- | ui/app_list/views/search_box_view.cc | 23 | ||||
-rw-r--r-- | ui/app_list/views/search_box_view.h | 6 |
9 files changed, 148 insertions, 27 deletions
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp index 15f01f2..e766c21 100644 --- a/ui/app_list/app_list.gyp +++ b/ui/app_list/app_list.gyp @@ -215,6 +215,7 @@ 'cocoa/signin_view_controller_unittest.mm', 'cocoa/test/apps_grid_controller_test_helper.h', 'cocoa/test/apps_grid_controller_test_helper.mm', + 'views/app_list_main_view_unittest.cc', 'views/apps_grid_view_unittest.cc', 'views/test/apps_grid_view_test_api.cc', 'views/test/apps_grid_view_test_api.h', diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h index 16455c9..0142398 100644 --- a/ui/app_list/test/app_list_test_view_delegate.h +++ b/ui/app_list/test/app_list_test_view_delegate.h @@ -69,6 +69,7 @@ class AppListTestViewDelegate : public AppListViewDelegate { // Do a bulk replacement of the items in the model. void ReplaceTestModel(int item_count); + AppListTestModel* ReleaseTestModel() { return model_.release(); } AppListTestModel* GetTestModel() { return model_.get(); } private: @@ -79,6 +80,8 @@ class AppListTestViewDelegate : public AppListViewDelegate { scoped_ptr<AppListTestModel> model_; ObserverList<AppListViewDelegateObserver> observers_; SpeechUIModel speech_ui_; + + DISALLOW_COPY_AND_ASSIGN(AppListTestViewDelegate); }; } // namespace test diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc index a4cd7a9..e6f7a7c 100644 --- a/ui/app_list/views/app_list_main_view.cc +++ b/ui/app_list/views/app_list_main_view.cc @@ -81,26 +81,30 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate, PaginationModel* pagination_model, gfx::NativeView parent) : delegate_(delegate), + pagination_model_(pagination_model), model_(delegate->GetModel()), search_box_view_(NULL), contents_view_(NULL), weak_ptr_factory_(this) { // Starts icon loading early. - PreloadIcons(pagination_model, parent); + PreloadIcons(parent); SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, kInnerPadding, kInnerPadding, kInnerPadding)); - search_box_view_ = new SearchBoxView(this, delegate, model_); + search_box_view_ = new SearchBoxView(this, delegate); AddChildView(search_box_view_); + AddContentsView(); +} +void AppListMainView::AddContentsView() { contents_view_ = new ContentsView(this, - pagination_model, + pagination_model_, model_, - delegate ? delegate->GetStartPageContents() : NULL); + delegate_ ? delegate_->GetStartPageContents() : NULL); AddChildView(contents_view_); search_box_view_->set_contents_view(contents_view_); @@ -141,13 +145,23 @@ void AppListMainView::Prerender() { contents_view_->Prerender(); } +void AppListMainView::ModelChanged() { + pending_icon_loaders_.clear(); + model_ = delegate_->GetModel(); + search_box_view_->ModelChanged(); + delete contents_view_; + contents_view_ = NULL; + pagination_model_->SelectPage(0, false /* animate */); + AddContentsView(); + Layout(); +} + void AppListMainView::SetDragAndDropHostOfCurrentAppList( ApplicationDragAndDropHost* drag_and_drop_host) { contents_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host); } -void AppListMainView::PreloadIcons(PaginationModel* pagination_model, - gfx::NativeView parent) { +void AppListMainView::PreloadIcons(gfx::NativeView parent) { ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P; if (parent) scale_factor = ui::GetScaleFactorForNativeView(parent); @@ -155,7 +169,7 @@ void AppListMainView::PreloadIcons(PaginationModel* pagination_model, float scale = ui::GetImageScale(scale_factor); // |pagination_model| could have -1 as the initial selected page and // assumes first page (i.e. index 0) will be used in this case. - const int selected_page = std::max(0, pagination_model->selected_page()); + const int selected_page = std::max(0, pagination_model_->selected_page()); const int tiles_per_page = kPreferredCols * kPreferredRows; const int start_model_index = selected_page * tiles_per_page; diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h index c0de4a0..1e119aa 100644 --- a/ui/app_list/views/app_list_main_view.h +++ b/ui/app_list/views/app_list_main_view.h @@ -10,6 +10,7 @@ #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" +#include "ui/app_list/app_list_export.h" #include "ui/app_list/views/apps_grid_view_delegate.h" #include "ui/app_list/views/search_box_view_delegate.h" #include "ui/app_list/views/search_result_list_view_delegate.h" @@ -31,10 +32,10 @@ class SearchBoxView; // AppListMainView contains the normal view of the app list, which is shown // when the user is signed in. -class AppListMainView : public views::View, - public AppsGridViewDelegate, - public SearchBoxViewDelegate, - public SearchResultListViewDelegate { +class APP_LIST_EXPORT AppListMainView : public views::View, + public AppsGridViewDelegate, + public SearchBoxViewDelegate, + public SearchResultListViewDelegate { public: // Takes ownership of |delegate|. explicit AppListMainView(AppListViewDelegate* delegate, @@ -48,6 +49,8 @@ class AppListMainView : public views::View, void Prerender(); + void ModelChanged(); + SearchBoxView* search_box_view() const { return search_box_view_; } // If |drag_and_drop_host| is not NULL it will be called upon drag and drop @@ -60,10 +63,11 @@ class AppListMainView : public views::View, private: class IconLoader; - // Loads icon image for the apps in the selected page of |pagination_model|. + void AddContentsView(); + + // Loads icon image for the apps in the selected page of |pagination_model_|. // |parent| is used to determine the image scale factor to use. - void PreloadIcons(PaginationModel* pagination_model, - gfx::NativeView parent); + void PreloadIcons(gfx::NativeView parent); // Invoked when |icon_loading_wait_timer_| fires. void OnIconLoadingWaitTimer(); @@ -89,7 +93,8 @@ class AppListMainView : public views::View, virtual void OnResultInstalled(SearchResult* result) OVERRIDE; virtual void OnResultUninstalled(SearchResult* result) OVERRIDE; - AppListViewDelegate* delegate_; // Owned by parent (AppListView) + AppListViewDelegate* delegate_; // Owned by parent view (AppListView). + PaginationModel* pagination_model_; // Owned by AppListController. AppListModel* model_; // Unowned; ownership is handled by |delegate_|. SearchBoxView* search_box_view_; // Owned by views hierarchy. diff --git a/ui/app_list/views/app_list_main_view_unittest.cc b/ui/app_list/views/app_list_main_view_unittest.cc new file mode 100644 index 0000000..6ca1820 --- /dev/null +++ b/ui/app_list/views/app_list_main_view_unittest.cc @@ -0,0 +1,90 @@ +// Copyright 2013 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 "ui/app_list/views/app_list_main_view.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/app_list/pagination_model.h" +#include "ui/app_list/test/app_list_test_model.h" +#include "ui/app_list/test/app_list_test_view_delegate.h" +#include "ui/app_list/views/apps_container_view.h" +#include "ui/app_list/views/apps_grid_view.h" +#include "ui/app_list/views/contents_view.h" +#include "ui/views/test/views_test_base.h" +#include "ui/views/view_model.h" +#include "ui/views/widget/widget.h" + +namespace app_list { +namespace test { + +namespace { + +const int kInitialItems = 2; + +class AppListMainViewTest : public views::ViewsTestBase { + public: + AppListMainViewTest() + : widget_(NULL), + main_view_(NULL) {} + + virtual ~AppListMainViewTest() {} + + // testing::Test overrides: + virtual void SetUp() OVERRIDE { + views::ViewsTestBase::SetUp(); + delegate_.reset(new AppListTestViewDelegate); + delegate_->GetTestModel()->PopulateApps(kInitialItems); + + main_view_ = + new AppListMainView(delegate_.get(), &pagination_model_, GetContext()); + main_view_->SetPaintToLayer(true); + + widget_ = new views::Widget; + views::Widget::InitParams params = + CreateParams(views::Widget::InitParams::TYPE_POPUP); + params.bounds.set_size(main_view_->GetPreferredSize()); + widget_->Init(params); + + widget_->SetContentsView(main_view_); + } + + virtual void TearDown() OVERRIDE { + widget_->Close(); + views::ViewsTestBase::TearDown(); + delegate_.reset(); + } + + const views::ViewModel* ViewModel() { + return main_view_->contents_view()->apps_container_view()->apps_grid_view() + ->view_model_for_test(); + } + + protected: + views::Widget* widget_; // Owned by native window. + AppListMainView* main_view_; // Owned by |widget_|. + PaginationModel pagination_model_; + scoped_ptr<AppListTestViewDelegate> delegate_; + + private: + DISALLOW_COPY_AND_ASSIGN(AppListMainViewTest); +}; + +} // namespace + +// Tests changing the AppListModel when switching profiles. +TEST_F(AppListMainViewTest, ModelChanged) { + EXPECT_EQ(kInitialItems, ViewModel()->view_size()); + + // The model is owned by a profile keyed service, which is never destroyed + // until after profile switching. + scoped_ptr<AppListModel> old_model(delegate_->ReleaseTestModel()); + + const int kReplacementItems = 5; + delegate_->ReplaceTestModel(kReplacementItems); + main_view_->ModelChanged(); + EXPECT_EQ(kReplacementItems, ViewModel()->view_size()); +} + +} // namespace test +} // namespace app_list diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index e3d3156..fc15fc5 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc @@ -217,6 +217,7 @@ void AppListView::OnProfilesChanged() { void AppListView::SetProfileByPath(const base::FilePath& profile_path) { delegate_->SetProfileByPath(profile_path); + app_list_main_view_->ModelChanged(); } void AppListView::AddObserver(AppListViewObserver* observer) { diff --git a/ui/app_list/views/page_switcher.h b/ui/app_list/views/page_switcher.h index 7e1ab9d..b05da99 100644 --- a/ui/app_list/views/page_switcher.h +++ b/ui/app_list/views/page_switcher.h @@ -50,7 +50,7 @@ class PageSwitcher : public views::View, virtual void TransitionStarted() OVERRIDE; virtual void TransitionChanged() OVERRIDE; - PaginationModel* model_; // Owned by parent AppListView. + PaginationModel* model_; // Owned by AppListController. views::View* buttons_; // Owned by views hierarchy. DISALLOW_COPY_AND_ASSIGN(PageSwitcher); diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index 8344dc2..c975177 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc @@ -41,16 +41,14 @@ const int kMenuXOffsetFromButton = -7; } // namespace SearchBoxView::SearchBoxView(SearchBoxViewDelegate* delegate, - AppListViewDelegate* view_delegate, - AppListModel* model) + AppListViewDelegate* view_delegate) : delegate_(delegate), view_delegate_(view_delegate), - model_(model), + model_(NULL), icon_view_(new views::ImageView), speech_button_(NULL), search_box_(new views::Textfield), contents_view_(NULL) { - DCHECK(model_); AddChildView(icon_view_); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); @@ -71,16 +69,25 @@ SearchBoxView::SearchBoxView(SearchBoxViewDelegate* delegate, search_box_->SetController(this); AddChildView(search_box_); - model_->search_box()->AddObserver(this); - IconChanged(); - SpeechRecognitionButtonPropChanged(); - HintTextChanged(); + ModelChanged(); } SearchBoxView::~SearchBoxView() { model_->search_box()->RemoveObserver(this); } +void SearchBoxView::ModelChanged() { + if (model_) + model_->search_box()->RemoveObserver(this); + + model_ = view_delegate_->GetModel(); + DCHECK(model_); + model_->search_box()->AddObserver(this); + IconChanged(); + SpeechRecognitionButtonPropChanged(); + HintTextChanged(); +} + bool SearchBoxView::HasSearch() const { return !search_box_->text().empty(); } diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h index 20d15cc..440ffba 100644 --- a/ui/app_list/views/search_box_view.h +++ b/ui/app_list/views/search_box_view.h @@ -38,10 +38,10 @@ class SearchBoxView : public views::View, public SearchBoxModelObserver { public: SearchBoxView(SearchBoxViewDelegate* delegate, - AppListViewDelegate* view_delegate, - AppListModel* model); + AppListViewDelegate* view_delegate); virtual ~SearchBoxView(); + void ModelChanged(); bool HasSearch() const; void ClearSearch(); void InvalidateMenu(); @@ -87,7 +87,7 @@ class SearchBoxView : public views::View, SearchBoxViewDelegate* delegate_; // Not owned. AppListViewDelegate* view_delegate_; // Not owned. - AppListModel* model_; // Owned by AppListView. + AppListModel* model_; // Owned by the profile-keyed service. scoped_ptr<AppListMenuViews> menu_; |