summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorcalamity@chromium.org <calamity@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-15 09:20:43 +0000
committercalamity@chromium.org <calamity@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-15 09:20:43 +0000
commit861bdb5554f52e520b302280f5fa0db14e74d9f7 (patch)
tree7457d9f807e09e7a52cfefed0aba63886aacdc88 /ui
parent372f56266647d68df8bafd1bca20d284a5dad79b (diff)
downloadchromium_src-861bdb5554f52e520b302280f5fa0db14e74d9f7.zip
chromium_src-861bdb5554f52e520b302280f5fa0db14e74d9f7.tar.gz
chromium_src-861bdb5554f52e520b302280f5fa0db14e74d9f7.tar.bz2
Allow app list tiles to show search results in the experimental app list.
This CL makes app results show as tiles in the experimental app list by making TileItemViews take SearchResults instead of AppListItems and by introducing a DisplayType for SearchResults which determines which surface the result will display on. Only 4 tiles appear at any one time. This will be fixed in a future patch. This CL also has the side effect of fixing a focus bug which was happening because StartPageView was listening to the AppListModel. BUG=398801, 349727 Review URL: https://codereview.chromium.org/439703002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289826 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/app_list/app_list_model.cc17
-rw-r--r--ui/app_list/app_list_model.h10
-rw-r--r--ui/app_list/search_result.cc4
-rw-r--r--ui/app_list/search_result_observer.h15
-rw-r--r--ui/app_list/views/app_list_main_view.cc7
-rw-r--r--ui/app_list/views/app_list_view_unittest.cc38
-rw-r--r--ui/app_list/views/search_result_list_view.cc14
-rw-r--r--ui/app_list/views/start_page_view.cc80
-rw-r--r--ui/app_list/views/start_page_view.h41
-rw-r--r--ui/app_list/views/tile_item_view.cc53
-rw-r--r--ui/app_list/views/tile_item_view.h14
11 files changed, 204 insertions, 89 deletions
diff --git a/ui/app_list/app_list_model.cc b/ui/app_list/app_list_model.cc
index 5714137..2d0f58f 100644
--- a/ui/app_list/app_list_model.cc
+++ b/ui/app_list/app_list_model.cc
@@ -10,7 +10,6 @@
#include "ui/app_list/app_list_item.h"
#include "ui/app_list/app_list_model_observer.h"
#include "ui/app_list/search_box_model.h"
-#include "ui/app_list/search_result.h"
namespace app_list {
@@ -285,6 +284,22 @@ void AppListModel::SetFoldersEnabled(bool folders_enabled) {
DeleteItem(folder_ids[i]);
}
+std::vector<SearchResult*> AppListModel::FilterSearchResultsByDisplayType(
+ SearchResults* results,
+ SearchResult::DisplayType display_type,
+ size_t max_results) {
+ std::vector<SearchResult*> matches;
+ for (size_t i = 0; i < results->item_count(); ++i) {
+ SearchResult* item = results->GetItemAt(i);
+ if (item->display_type() == display_type) {
+ matches.push_back(item);
+ if (matches.size() == max_results)
+ break;
+ }
+ }
+ return matches;
+}
+
// Private methods
void AppListModel::OnListItemMoved(size_t from_index,
diff --git a/ui/app_list/app_list_model.h b/ui/app_list/app_list_model.h
index 9caa323..20e6728 100644
--- a/ui/app_list/app_list_model.h
+++ b/ui/app_list/app_list_model.h
@@ -6,6 +6,7 @@
#define UI_APP_LIST_APP_LIST_MODEL_H_
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
@@ -13,6 +14,7 @@
#include "ui/app_list/app_list_export.h"
#include "ui/app_list/app_list_item_list.h"
#include "ui/app_list/app_list_item_list_observer.h"
+#include "ui/app_list/search_result.h"
#include "ui/base/models/list_model.h"
namespace app_list {
@@ -22,7 +24,6 @@ class AppListItem;
class AppListItemList;
class AppListModelObserver;
class SearchBoxModel;
-class SearchResult;
// Master model of app list that consists of three sub models: AppListItemList,
// SearchBoxModel and SearchResults. The AppListItemList sub model owns a list
@@ -116,6 +117,13 @@ class APP_LIST_EXPORT AppListModel : public AppListItemListObserver {
// false, removes any non-OEM folders.
void SetFoldersEnabled(bool folders_enabled);
+ // Filters the given |results| by |display_type|. The returned list is
+ // truncated to |max_results|.
+ static std::vector<SearchResult*> FilterSearchResultsByDisplayType(
+ SearchResults* results,
+ SearchResult::DisplayType display_type,
+ size_t max_results);
+
AppListItemList* top_level_item_list() { return top_level_item_list_.get(); }
SearchBoxModel* search_box() { return search_box_.get(); }
diff --git a/ui/app_list/search_result.cc b/ui/app_list/search_result.cc
index bfa1da9..653d089 100644
--- a/ui/app_list/search_result.cc
+++ b/ui/app_list/search_result.cc
@@ -32,7 +32,9 @@ SearchResult::SearchResult()
percent_downloaded_(0) {
}
-SearchResult::~SearchResult() {}
+SearchResult::~SearchResult() {
+ FOR_EACH_OBSERVER(SearchResultObserver, observers_, OnResultDestroying());
+}
void SearchResult::SetIcon(const gfx::ImageSkia& icon) {
icon_ = icon;
diff --git a/ui/app_list/search_result_observer.h b/ui/app_list/search_result_observer.h
index bef7564..09249ae 100644
--- a/ui/app_list/search_result_observer.h
+++ b/ui/app_list/search_result_observer.h
@@ -12,22 +12,25 @@ namespace app_list {
class APP_LIST_EXPORT SearchResultObserver {
public:
// Invoked when the SearchResult's icon has changed.
- virtual void OnIconChanged() = 0;
+ virtual void OnIconChanged() {}
// Invoked when the SearchResult's actions have changed.
- virtual void OnActionsChanged() = 0;
+ virtual void OnActionsChanged() {}
// Invoked when the SearchResult's is_installing flag has changed.
- virtual void OnIsInstallingChanged() = 0;
+ virtual void OnIsInstallingChanged() {}
// Invoked when the download percentage has changed.
- virtual void OnPercentDownloadedChanged() = 0;
+ virtual void OnPercentDownloadedChanged() {}
// Invoked when the item represented by the SearchResult is installed.
- virtual void OnItemInstalled() = 0;
+ virtual void OnItemInstalled() {}
// Invoked when the item represented by the SearchResult is uninstalled.
- virtual void OnItemUninstalled() = 0;
+ virtual void OnItemUninstalled() {}
+
+ // Invoked just before the SearchResult is destroyed.
+ virtual void OnResultDestroying() {}
protected:
virtual ~SearchResultObserver() {}
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index c0f7a83..70c926c 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -152,6 +152,8 @@ void AppListMainView::AddContentsViews() {
contents_view_->SetPaintToLayer(true);
contents_view_->SetFillsBoundsOpaquely(false);
contents_view_->layer()->SetMasksToBounds(true);
+
+ delegate_->StartSearch();
}
AppListMainView::~AppListMainView() {
@@ -317,10 +319,7 @@ void AppListMainView::QueryChanged(SearchBoxView* sender) {
contents_view_->ShowSearchResults(should_show_search);
UpdateSearchBoxVisibility();
- if (should_show_search)
- delegate_->StartSearch();
- else
- delegate_->StopSearch();
+ delegate_->StartSearch();
}
void AppListMainView::OnResultInstalled(SearchResult* result) {
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc
index 880269a..96a60f2 100644
--- a/ui/app_list/views/app_list_view_unittest.cc
+++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -61,6 +61,15 @@ size_t GetVisibleTileItemViews(const std::vector<TileItemView*>& tiles) {
// Choose a set that is 3 regular app list pages and 2 landscape app list pages.
const int kInitialItems = 34;
+class TestTileSearchResult : public SearchResult {
+ public:
+ TestTileSearchResult() { set_display_type(DISPLAY_TILE); }
+ virtual ~TestTileSearchResult() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestTileSearchResult);
+};
+
// Allows the same tests to run with different contexts: either an Ash-style
// root window or a desktop window tree host.
class AppListViewTestContext {
@@ -313,7 +322,6 @@ void AppListViewTestContext::RunStartPageTest() {
ShowContentsViewPageAndVerify(contents_view->GetPageIndexForNamedPage(
ContentsView::NAMED_PAGE_START));
EXPECT_FALSE(main_view->search_box_view()->visible());
- EXPECT_EQ(3u, GetVisibleTileItemViews(start_page_view->tile_views()));
gfx::Size view_size(view_->GetPreferredSize());
ShowContentsViewPageAndVerify(
@@ -325,10 +333,12 @@ void AppListViewTestContext::RunStartPageTest() {
EXPECT_EQ(view_size.ToString(), view_->GetPreferredSize().ToString());
// Check tiles hide and show on deletion and addition.
- model->CreateAndAddItem("Test app");
- EXPECT_EQ(4u, GetVisibleTileItemViews(start_page_view->tile_views()));
- model->DeleteItem(model->GetItemName(0));
- EXPECT_EQ(3u, GetVisibleTileItemViews(start_page_view->tile_views()));
+ model->results()->Add(new TestTileSearchResult());
+ start_page_view->UpdateForTesting();
+ EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views()));
+ model->results()->RemoveAll();
+ start_page_view->UpdateForTesting();
+ EXPECT_EQ(0u, GetVisibleTileItemViews(start_page_view->tile_views()));
} else {
EXPECT_EQ(NULL, start_page_view);
}
@@ -410,21 +420,25 @@ void AppListViewTestContext::RunProfileChangeTest() {
EXPECT_EQ(view_->app_list_main_view()->contents_view(),
contents_switcher_view->contents_view());
EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view));
- EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views()));
} else {
EXPECT_EQ(NULL, contents_switcher_view);
EXPECT_EQ(NULL, start_page_view);
}
// New model updates should be processed by the start page view.
- delegate_->GetTestModel()->CreateAndAddItem("Test App");
- if (test_type_ == EXPERIMENTAL)
- EXPECT_EQ(2u, GetVisibleTileItemViews(start_page_view->tile_views()));
+ delegate_->GetTestModel()->results()->Add(new TestTileSearchResult());
+ if (test_type_ == EXPERIMENTAL) {
+ start_page_view->UpdateForTesting();
+ EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views()));
+ }
// Old model updates should be ignored.
- original_test_model->CreateAndAddItem("Test App 2");
- if (test_type_ == EXPERIMENTAL)
- EXPECT_EQ(2u, GetVisibleTileItemViews(start_page_view->tile_views()));
+ original_test_model->results()->Add(new TestTileSearchResult());
+ original_test_model->results()->Add(new TestTileSearchResult());
+ if (test_type_ == EXPERIMENTAL) {
+ start_page_view->UpdateForTesting();
+ EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views()));
+ }
Close();
}
diff --git a/ui/app_list/views/search_result_list_view.cc b/ui/app_list/views/search_result_list_view.cc
index 6f2b176..76e7898 100644
--- a/ui/app_list/views/search_result_list_view.cc
+++ b/ui/app_list/views/search_result_list_view.cc
@@ -12,6 +12,7 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/app_list/app_list_switches.h"
#include "ui/app_list/app_list_view_delegate.h"
+#include "ui/app_list/search_result.h"
#include "ui/app_list/views/search_result_list_view_delegate.h"
#include "ui/app_list/views/search_result_view.h"
#include "ui/events/event.h"
@@ -163,14 +164,19 @@ SearchResultView* SearchResultListView::GetResultViewAt(int index) {
}
void SearchResultListView::Update() {
- last_visible_index_ = 0;
+ std::vector<SearchResult*> display_results =
+ AppListModel::FilterSearchResultsByDisplayType(
+ results_,
+ SearchResult::DISPLAY_LIST,
+ results_container_->child_count());
+ last_visible_index_ = display_results.size() - 1;
+
for (size_t i = 0; i < static_cast<size_t>(results_container_->child_count());
++i) {
SearchResultView* result_view = GetResultViewAt(i);
- if (i < results_->item_count()) {
- result_view->SetResult(results_->GetItemAt(i));
+ if (i < display_results.size()) {
+ result_view->SetResult(display_results[i]);
result_view->SetVisible(true);
- last_visible_index_ = i;
} else {
result_view->SetResult(NULL);
result_view->SetVisible(false);
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc
index affdc2d..d9d41d2 100644
--- a/ui/app_list/views/start_page_view.cc
+++ b/ui/app_list/views/start_page_view.cc
@@ -9,6 +9,7 @@
#include "ui/app_list/app_list_item.h"
#include "ui/app_list/app_list_model.h"
#include "ui/app_list/app_list_view_delegate.h"
+#include "ui/app_list/search_result.h"
#include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/search_result_list_view.h"
@@ -95,14 +96,15 @@ class DummySearchBoxView : public SearchBoxView {
StartPageView::StartPageView(AppListMainView* app_list_main_view,
AppListViewDelegate* view_delegate)
: app_list_main_view_(app_list_main_view),
- model_(NULL),
+ search_results_model_(NULL),
view_delegate_(view_delegate),
search_box_view_(new DummySearchBoxView(this, view_delegate_)),
results_view_(
new SearchResultListView(app_list_main_view, view_delegate)),
instant_container_(new views::View),
tiles_container_(new views::View),
- show_state_(SHOW_START_PAGE) {
+ show_state_(SHOW_START_PAGE),
+ update_factory_(this) {
// The view containing the start page WebContents and DummySearchBoxView.
InitInstantContainer();
AddChildView(instant_container_);
@@ -120,8 +122,8 @@ StartPageView::StartPageView(AppListMainView* app_list_main_view,
StartPageView::~StartPageView() {
view_delegate_->RemoveObserver(this);
- if (model_)
- model_->RemoveObserver(this);
+ if (search_results_model_)
+ search_results_model_->RemoveObserver(this);
}
void StartPageView::InitInstantContainer() {
@@ -168,29 +170,22 @@ void StartPageView::InitTilesContainer() {
void StartPageView::SetModel(AppListModel* model) {
DCHECK(model);
- if (model_)
- model_->RemoveObserver(this);
- model_ = model;
- model_->AddObserver(this);
- results_view_->SetResults(model_->results());
+ if (search_results_model_)
+ search_results_model_->RemoveObserver(this);
+ search_results_model_ = model->results();
+ search_results_model_->AddObserver(this);
+ results_view_->SetResults(search_results_model_);
Reset();
}
void StartPageView::Reset() {
SetShowState(SHOW_START_PAGE);
- if (!model_ || !model_->top_level_item_list())
- return;
-
- for (size_t i = 0; i < kNumStartPageTiles; ++i) {
- AppListItem* item = NULL;
- if (i < model_->top_level_item_list()->item_count())
- item = model_->top_level_item_list()->item_at(i);
- tile_views_[i]->SetAppListItem(item);
- }
+ Update();
}
void StartPageView::ShowSearchResults() {
SetShowState(SHOW_SEARCH_RESULTS);
+ Update();
}
void StartPageView::SetShowState(ShowState show_state) {
@@ -207,6 +202,9 @@ void StartPageView::SetShowState(ShowState show_state) {
show_state_ = show_state;
+ if (show_state_ == SHOW_START_PAGE)
+ search_box_view_->ClearSearch();
+
results_view_->UpdateAutoLaunchState();
if (show_state == SHOW_SEARCH_RESULTS)
results_view_->SetSelectedIndex(0);
@@ -216,6 +214,10 @@ bool StartPageView::IsShowingSearchResults() const {
return show_state_ == SHOW_SEARCH_RESULTS;
}
+void StartPageView::UpdateForTesting() {
+ Update();
+}
+
bool StartPageView::OnKeyPressed(const ui::KeyEvent& event) {
if (show_state_ == SHOW_SEARCH_RESULTS)
return results_view_->OnKeyPressed(event);
@@ -236,6 +238,32 @@ void StartPageView::Layout() {
tiles_container_->SetBoundsRect(bounds);
}
+void StartPageView::Update() {
+ std::vector<SearchResult*> display_results =
+ AppListModel::FilterSearchResultsByDisplayType(search_results_model_,
+ SearchResult::DISPLAY_TILE,
+ kNumStartPageTiles);
+ for (size_t i = 0; i < kNumStartPageTiles; ++i) {
+ SearchResult* item = NULL;
+ if (i < display_results.size())
+ item = display_results[i];
+ tile_views_[i]->SetSearchResult(item);
+ }
+ tiles_container_->Layout();
+ Layout();
+ update_factory_.InvalidateWeakPtrs();
+}
+
+void StartPageView::ScheduleUpdate() {
+ // When search results are added one by one, each addition generates an update
+ // request. Consolidates those update requests into one Update call.
+ if (!update_factory_.HasWeakPtrs()) {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&StartPageView::Update, update_factory_.GetWeakPtr()));
+ }
+}
+
void StartPageView::QueryChanged(SearchBoxView* sender) {
// Forward the search terms on to the real search box and clear the dummy
// search box.
@@ -248,20 +276,20 @@ void StartPageView::OnProfilesChanged() {
SetModel(view_delegate_->GetModel());
}
-void StartPageView::OnAppListModelStatusChanged() {
- Reset();
+void StartPageView::ListItemsAdded(size_t start, size_t count) {
+ ScheduleUpdate();
}
-void StartPageView::OnAppListItemAdded(AppListItem* item) {
- Reset();
+void StartPageView::ListItemsRemoved(size_t start, size_t count) {
+ ScheduleUpdate();
}
-void StartPageView::OnAppListItemDeleted() {
- Reset();
+void StartPageView::ListItemMoved(size_t index, size_t target_index) {
+ ScheduleUpdate();
}
-void StartPageView::OnAppListItemUpdated(AppListItem* item) {
- Reset();
+void StartPageView::ListItemsChanged(size_t start, size_t count) {
+ ScheduleUpdate();
}
} // namespace app_list
diff --git a/ui/app_list/views/start_page_view.h b/ui/app_list/views/start_page_view.h
index b429f8b..5c29414 100644
--- a/ui/app_list/views/start_page_view.h
+++ b/ui/app_list/views/start_page_view.h
@@ -6,24 +6,26 @@
#define UI_APP_LIST_VIEWS_START_PAGE_VIEW_H_
#include "base/basictypes.h"
-#include "ui/app_list/app_list_model_observer.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/app_list/app_list_export.h"
+#include "ui/app_list/app_list_model.h"
#include "ui/app_list/app_list_view_delegate_observer.h"
#include "ui/app_list/views/search_box_view_delegate.h"
+#include "ui/base/models/list_model_observer.h"
#include "ui/views/view.h"
namespace app_list {
class AppListMainView;
-class AppListModel;
class AppListViewDelegate;
class SearchResultListView;
class TileItemView;
// The start page for the experimental app list.
-class StartPageView : public views::View,
- public SearchBoxViewDelegate,
- public AppListViewDelegateObserver,
- public AppListModelObserver {
+class APP_LIST_EXPORT StartPageView : public views::View,
+ public ui::ListModelObserver,
+ public SearchBoxViewDelegate,
+ public AppListViewDelegateObserver {
public:
StartPageView(AppListMainView* app_list_main_view,
AppListViewDelegate* view_delegate);
@@ -34,6 +36,8 @@ class StartPageView : public views::View,
bool IsShowingSearchResults() const;
+ void UpdateForTesting();
+
const std::vector<TileItemView*>& tile_views() const { return tile_views_; }
SearchBoxView* dummy_search_box_view() { return search_box_view_; }
@@ -53,22 +57,30 @@ class StartPageView : public views::View,
void SetShowState(ShowState show_state);
void SetModel(AppListModel* model);
+ // Updates UI with model.
+ void Update();
+
+ // Schedules an Update() call using |update_factory_|. Does nothing if there
+ // is a pending call.
+ void ScheduleUpdate();
+
// Overridden from SearchBoxViewDelegate:
virtual void QueryChanged(SearchBoxView* sender) OVERRIDE;
// Overridden from AppListViewDelegateObserver:
virtual void OnProfilesChanged() OVERRIDE;
- // Overridden from AppListModelObserver:
- virtual void OnAppListModelStatusChanged() OVERRIDE;
- virtual void OnAppListItemAdded(AppListItem* item) OVERRIDE;
- virtual void OnAppListItemDeleted() OVERRIDE;
- virtual void OnAppListItemUpdated(AppListItem* item) OVERRIDE;
+ // Overridden from ui::ListModelObserver:
+ virtual void ListItemsAdded(size_t start, size_t count) OVERRIDE;
+ virtual void ListItemsRemoved(size_t start, size_t count) OVERRIDE;
+ virtual void ListItemMoved(size_t index, size_t target_index) OVERRIDE;
+ virtual void ListItemsChanged(size_t start, size_t count) OVERRIDE;
// The parent view of ContentsView which is the parent of this view.
AppListMainView* app_list_main_view_;
- AppListModel* model_; // Owned by AppListSyncableService.
+ AppListModel::SearchResults*
+ search_results_model_; // Owned by AppListSyncableService.
AppListViewDelegate* view_delegate_; // Owned by AppListView.
@@ -81,6 +93,11 @@ class StartPageView : public views::View,
ShowState show_state_;
+ // ScheduleUpdate() generates a single weak pointer; if one exists then an
+ // update is pending. Further calls to ScheduleUpdate() will have no effect.
+ // Once the Update() completes, the weak pointer is invalidated.
+ base::WeakPtrFactory<StartPageView> update_factory_;
+
DISALLOW_COPY_AND_ASSIGN(StartPageView);
};
diff --git a/ui/app_list/views/tile_item_view.cc b/ui/app_list/views/tile_item_view.cc
index 9997fab..029df19 100644
--- a/ui/app_list/views/tile_item_view.cc
+++ b/ui/app_list/views/tile_item_view.cc
@@ -9,6 +9,7 @@
#include "ui/app_list/app_list_item.h"
#include "ui/app_list/app_list_model.h"
#include "ui/app_list/app_list_view_delegate.h"
+#include "ui/app_list/search_result.h"
#include "ui/app_list/views/app_list_main_view.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_analysis.h"
@@ -92,7 +93,7 @@ TileItemView::TileItemView()
title_->SetFontList(rb.GetFontList(kItemTextFontStyle));
title_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
- // When |item_| is NULL, the tile is invisible. Calling SetAppListItem with a
+ // When |item_| is NULL, the tile is invisible. Calling SetSearchResult with a
// non-NULL item makes the tile visible.
SetVisible(false);
@@ -101,29 +102,32 @@ TileItemView::TileItemView()
}
TileItemView::~TileItemView() {
+ if (item_)
+ item_->RemoveObserver(this);
}
-void TileItemView::SetAppListItem(AppListItem* item) {
- // TODO(calamity): This will not update if the contents of |item_| have
- // changed since it was last assigned. Add an observer to refresh when the
- // item changes.
- if (item == item_)
- return;
+void TileItemView::SetSearchResult(SearchResult* item) {
+ SetVisible(item != NULL);
+
+ SearchResult* old_item = item_;
+ if (old_item)
+ old_item->RemoveObserver(this);
item_ = item;
- if (!item) {
- SetVisible(false);
- icon_->SetImage(NULL);
- title_->SetText(base::string16());
+
+ if (!item)
return;
- }
- SetVisible(true);
- icon_->SetImage(item_->icon());
- title_->SetText(base::UTF8ToUTF16(item_->name()));
+ item_->AddObserver(this);
- background_->set_strip_color(
- color_utils::CalculateKMeanColorOfBitmap(*item_->icon().bitmap()));
+ title_->SetText(item_->title());
+
+ // Only refresh the icon if it's different from the old one. This prevents
+ // flickering.
+ if (old_item == NULL ||
+ !item->icon().BackedBySameObjectAs(old_item->icon())) {
+ OnIconChanged();
+ }
}
gfx::Size TileItemView::GetPreferredSize() const {
@@ -132,7 +136,20 @@ gfx::Size TileItemView::GetPreferredSize() const {
void TileItemView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
- item_->Activate(event.flags());
+ item_->Open(event.flags());
+}
+
+void TileItemView::OnIconChanged() {
+ icon_->SetImage(item_->icon());
+ background_->set_strip_color(
+ color_utils::CalculateKMeanColorOfBitmap(*item_->icon().bitmap()));
+ SchedulePaint();
+}
+
+void TileItemView::OnResultDestroying() {
+ if (item_)
+ item_->RemoveObserver(this);
+ item_ = NULL;
}
} // namespace app_list
diff --git a/ui/app_list/views/tile_item_view.h b/ui/app_list/views/tile_item_view.h
index e319915..2f6cefd 100644
--- a/ui/app_list/views/tile_item_view.h
+++ b/ui/app_list/views/tile_item_view.h
@@ -6,6 +6,7 @@
#define UI_APP_LIST_VIEWS_TILE_ITEM_VIEW_H_
#include "ui/app_list/app_list_export.h"
+#include "ui/app_list/search_result_observer.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/custom_button.h"
@@ -16,16 +17,17 @@ class Label;
namespace app_list {
-class AppListItem;
+class SearchResult;
// The view for a tile in the app list on the start/search page.
class APP_LIST_EXPORT TileItemView : public views::CustomButton,
- public views::ButtonListener {
+ public views::ButtonListener,
+ public SearchResultObserver {
public:
TileItemView();
virtual ~TileItemView();
- void SetAppListItem(AppListItem* item);
+ void SetSearchResult(SearchResult* item);
private:
class TileItemBackground;
@@ -37,8 +39,12 @@ class APP_LIST_EXPORT TileItemView : public views::CustomButton,
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
+ // Overridden from SearchResultObserver:
+ virtual void OnIconChanged() OVERRIDE;
+ virtual void OnResultDestroying() OVERRIDE;
+
// Owned by the model provided by the AppListViewDelegate.
- AppListItem* item_;
+ SearchResult* item_;
views::ImageView* icon_; // Owned by views hierarchy.
views::Label* title_; // Owned by views hierarchy.