12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/views/app_list_main_view.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/bind.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/callback.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/files/file_path.h"
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/message_loop/message_loop.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/app_list_constants.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/app_list/app_list_folder_item.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/app_list/app_list_item.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/app_list_model.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/app_list/app_list_switches.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/app_list_view_delegate.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/pagination_model.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/search_box_model.h"
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/app_list/views/app_list_folder_view.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/views/app_list_item_view.h"
244ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "ui/app_list/views/apps_container_view.h"
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/app_list/views/apps_grid_view.h"
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/app_list/views/contents_switcher_view.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/views/contents_view.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/app_list/views/search_box_view.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/views/border.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/layout/box_layout.h"
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/layout/fill_layout.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace app_list {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Border padding space around the bubble contents.
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kPadding = 1;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The maximum allowed time to wait for icon loading in milliseconds.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMaxIconLoadingWaitTimeInMs = 50;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// A view that holds another view and takes its preferred size. This is used for
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// wrapping the search box view so it still gets laid out while hidden. This is
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// a separate class so it can notify the main view on search box visibility
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// change.
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass SearchBoxContainerView : public views::View {
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SearchBoxContainerView(AppListMainView* host, SearchBoxView* search_box)
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : host_(host), search_box_(search_box) {
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SetLayoutManager(new views::FillLayout());
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AddChildView(search_box);
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~SearchBoxContainerView() {}
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Overridden from views::View:
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void ChildVisibilityChanged(views::View* child) OVERRIDE {
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK_EQ(search_box_, child);
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    host_->NotifySearchBoxVisibilityChanged();
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppListMainView* host_;
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SearchBoxView* search_box_;
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(SearchBoxContainerView);
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// AppListMainView::IconLoader
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AppListMainView::IconLoader : public AppListItemObserver {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IconLoader(AppListMainView* owner,
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             AppListItem* item,
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)             float scale)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : owner_(owner),
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        item_(item) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    item_->AddObserver(this);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Triggers icon loading for given |scale_factor|.
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    item_->icon().GetRepresentation(scale);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~IconLoader() {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    item_->RemoveObserver(this);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // AppListItemObserver overrides:
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ItemIconChanged() OVERRIDE {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    owner_->OnItemIconLoaded(this);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Note that IconLoader is released here.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppListMainView* owner_;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListItem* item_;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(IconLoader);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// AppListMainView:
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AppListMainView::AppListMainView(AppListViewDelegate* delegate,
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                 int initial_apps_page,
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                 gfx::NativeView parent)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : delegate_(delegate),
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      model_(delegate->GetModel()),
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      search_box_view_(NULL),
115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      contents_view_(NULL),
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      contents_switcher_view_(NULL),
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      weak_ptr_factory_(this) {
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetBorder(
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      views::Border::CreateEmptyBorder(kPadding, kPadding, kPadding, kPadding));
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  search_box_view_ = new SearchBoxView(this, delegate);
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  views::View* container = new SearchBoxContainerView(this, search_box_view_);
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (switches::IsExperimentalAppListEnabled()) {
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    container->SetBorder(
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        views::Border::CreateEmptyBorder(kExperimentalWindowPadding,
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         kExperimentalWindowPadding,
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         0,
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         kExperimentalWindowPadding));
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddChildView(container);
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AddContentsViews();
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Switch the apps grid view to the specified page.
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  app_list::PaginationModel* pagination_model = GetAppsPaginationModel();
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (pagination_model->is_valid_page(initial_apps_page))
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    pagination_model->SelectPage(initial_apps_page, false);
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Starts icon loading early.
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PreloadIcons(parent);
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppListMainView::AddContentsViews() {
1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  contents_view_ = new ContentsView(this);
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (app_list::switches::IsExperimentalAppListEnabled()) {
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    contents_switcher_view_ = new ContentsSwitcherView(contents_view_);
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    contents_view_->SetContentsSwitcherView(contents_switcher_view_);
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
1496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  contents_view_->InitNamedPages(model_, delegate_);
1506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AddChildView(contents_view_);
1516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (contents_switcher_view_)
1526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AddChildView(contents_switcher_view_);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  search_box_view_->set_contents_view(contents_view_);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view_->SetPaintToLayer(true);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view_->SetFillsBoundsOpaquely(false);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view_->layer()->SetMasksToBounds(true);
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  delegate_->StartSearch();
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AppListMainView::~AppListMainView() {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_icon_loaders_.clear();
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListMainView::ShowAppListWhenReady() {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_icon_loaders_.empty()) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    icon_loading_wait_timer_.Stop();
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetWidget()->Show();
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (icon_loading_wait_timer_.IsRunning())
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_loading_wait_timer_.Start(
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kMaxIconLoadingWaitTimeInMs),
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, &AppListMainView::OnIconLoadingWaitTimer);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1834ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid AppListMainView::ResetForShow() {
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (switches::IsExperimentalAppListEnabled()) {
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    contents_view_->SetActivePage(contents_view_->GetPageIndexForNamedPage(
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ContentsView::NAMED_PAGE_START));
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1884ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  contents_view_->apps_container_view()->ResetForShowApps();
1894ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  // We clear the search when hiding so when app list appears it is not showing
1904ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  // search results.
1914ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  search_box_view_->ClearSearch();
1924ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch}
1934ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListMainView::Close() {
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_loading_wait_timer_.Stop();
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  contents_view_->CancelDrag();
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListMainView::Prerender() {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view_->Prerender();
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppListMainView::ModelChanged() {
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  pending_icon_loaders_.clear();
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  model_ = delegate_->GetModel();
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  search_box_view_->ModelChanged();
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delete contents_view_;
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  contents_view_ = NULL;
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (contents_switcher_view_) {
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    delete contents_switcher_view_;
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    contents_switcher_view_ = NULL;
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AddContentsViews();
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Layout();
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppListMainView::UpdateSearchBoxVisibility() {
2186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  bool visible =
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      !contents_view_->IsNamedPageActive(ContentsView::NAMED_PAGE_START) ||
2206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      contents_view_->IsShowingSearchResults();
2216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  search_box_view_->SetVisible(visible);
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (visible && GetWidget() && GetWidget()->IsVisible())
2236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    search_box_view_->search_box()->RequestFocus();
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void AppListMainView::OnStartPageSearchTextfieldChanged(
2276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const base::string16& new_contents) {
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  search_box_view_->SetVisible(true);
2296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  search_box_view_->search_box()->SetText(new_contents);
2306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  search_box_view_->search_box()->RequestFocus();
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
233b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void AppListMainView::SetDragAndDropHostOfCurrentAppList(
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ApplicationDragAndDropHost* drag_and_drop_host) {
235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
237b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool AppListMainView::ShouldCenterWindow() const {
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return delegate_->ShouldCenterWindow();
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)PaginationModel* AppListMainView::GetAppsPaginationModel() {
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return contents_view_->apps_container_view()
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ->apps_grid_view()
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ->pagination_model();
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppListMainView::PreloadIcons(gfx::NativeView parent) {
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float scale_factor = 1.0f;
250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (parent)
251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scale_factor = ui::GetScaleFactorForNativeView(parent);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The PaginationModel could have -1 as the initial selected page and
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // assumes first page (i.e. index 0) will be used in this case.
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const int selected_page =
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      std::max(0, GetAppsPaginationModel()->selected_page());
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const AppsGridView* const apps_grid_view =
25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      contents_view_->apps_container_view()->apps_grid_view();
26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const int tiles_per_page =
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      apps_grid_view->cols() * apps_grid_view->rows_per_page();
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int start_model_index = selected_page * tiles_per_page;
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const int end_model_index =
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::min(static_cast<int>(model_->top_level_item_list()->item_count()),
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               start_model_index + tiles_per_page);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_icon_loaders_.clear();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = start_model_index; i < end_model_index; ++i) {
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AppListItem* item = model_->top_level_item_list()->item_at(i);
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (item->icon().HasRepresentation(scale_factor))
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pending_icon_loaders_.push_back(new IconLoader(this, item, scale_factor));
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListMainView::OnIconLoadingWaitTimer() {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetWidget()->Show();
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListMainView::OnItemIconLoaded(IconLoader* loader) {
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<IconLoader>::iterator it = std::find(
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_icon_loaders_.begin(), pending_icon_loaders_.end(), loader);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(it != pending_icon_loaders_.end());
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_icon_loaders_.erase(it);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_icon_loaders_.empty() && icon_loading_wait_timer_.IsRunning()) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    icon_loading_wait_timer_.Stop();
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetWidget()->Show();
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AppListMainView::NotifySearchBoxVisibilityChanged() {
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Repaint the AppListView's background which will repaint the background for
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the search box. This is needed because this view paints to a layer and
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // won't propagate paints upward.
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (parent())
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    parent()->SchedulePaint();
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppListMainView::ActivateApp(AppListItem* item, int event_flags) {
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(jennyz): Activate the folder via AppListModel notification.
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (item->GetItemType() == AppListFolderItem::kItemType)
3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    contents_view_->ShowFolderContent(static_cast<AppListFolderItem*>(item));
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  else
3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    item->Activate(event_flags);
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AppListMainView::GetShortcutPathForApp(
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& app_id,
312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::Callback<void(const base::FilePath&)>& callback) {
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->GetShortcutPathForApp(app_id, callback);
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void AppListMainView::CancelDragInActiveFolder() {
3176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents_view_->apps_container_view()
3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ->app_list_folder_view()
3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ->items_grid_view()
3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ->EndDrag(true);
3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListMainView::QueryChanged(SearchBoxView* sender) {
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::string16 query;
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TrimWhitespace(model_->search_box()->text(), base::TRIM_ALL, &query);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool should_show_search = !query.empty();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view_->ShowSearchResults(should_show_search);
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  UpdateSearchBoxVisibility();
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  delegate_->StartSearch();
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void AppListMainView::OnResultInstalled(SearchResult* result) {
334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Clears the search to show the apps grid. The last installed app
335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // should be highlighted and made visible already.
336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  search_box_view_->ClearSearch();
337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
339ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid AppListMainView::OnResultUninstalled(SearchResult* result) {
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Resubmit the query via a posted task so that all observers for the
341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // uninstall notification are notified.
342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&AppListMainView::QueryChanged,
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 search_box_view_));
347ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
348ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace app_list
350