app_list_main_view.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/app_list/views/app_list_main_view.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include "ash/app_list/app_list_metrics.h"
  10. #include "ash/app_list/app_list_model_provider.h"
  11. #include "ash/app_list/app_list_util.h"
  12. #include "ash/app_list/app_list_view_delegate.h"
  13. #include "ash/app_list/model/app_list_folder_item.h"
  14. #include "ash/app_list/model/app_list_item.h"
  15. #include "ash/app_list/views/app_list_folder_view.h"
  16. #include "ash/app_list/views/app_list_item_view.h"
  17. #include "ash/app_list/views/app_list_view.h"
  18. #include "ash/app_list/views/apps_container_view.h"
  19. #include "ash/app_list/views/apps_grid_view.h"
  20. #include "ash/app_list/views/contents_view.h"
  21. #include "ash/app_list/views/expand_arrow_view.h"
  22. #include "ash/app_list/views/paged_apps_grid_view.h"
  23. #include "ash/app_list/views/search_box_view.h"
  24. #include "ash/app_list/views/search_result_base_view.h"
  25. #include "ash/app_list/views/search_result_page_view.h"
  26. #include "ash/constants/ash_features.h"
  27. #include "ash/public/cpp/app_list/app_list_features.h"
  28. #include "ash/public/cpp/pagination/pagination_model.h"
  29. #include "ash/search_box/search_box_view_base.h"
  30. #include "base/bind.h"
  31. #include "base/callback.h"
  32. #include "base/files/file_path.h"
  33. #include "base/strings/string_util.h"
  34. #include "ui/aura/window.h"
  35. #include "ui/compositor/layer.h"
  36. #include "ui/gfx/geometry/insets.h"
  37. #include "ui/views/border.h"
  38. #include "ui/views/controls/button/button.h"
  39. #include "ui/views/controls/textfield/textfield.h"
  40. #include "ui/views/layout/fill_layout.h"
  41. #include "ui/views/widget/widget.h"
  42. #include "ui/wm/public/activation_client.h"
  43. namespace ash {
  44. ////////////////////////////////////////////////////////////////////////////////
  45. // AppListMainView:
  46. AppListMainView::AppListMainView(AppListViewDelegate* delegate,
  47. AppListView* app_list_view)
  48. : delegate_(delegate), app_list_view_(app_list_view) {
  49. // We need a layer to apply transform to in small display so that the apps
  50. // grid fits in the display.
  51. SetPaintToLayer();
  52. layer()->SetFillsBoundsOpaquely(false);
  53. }
  54. AppListMainView::~AppListMainView() = default;
  55. void AppListMainView::Init(int initial_apps_page,
  56. SearchBoxView* search_box_view) {
  57. search_box_view_ = search_box_view;
  58. AddContentsViews();
  59. // Switch the apps grid view to the specified page.
  60. PaginationModel* pagination_model = GetAppsPaginationModel();
  61. if (pagination_model->is_valid_page(initial_apps_page))
  62. pagination_model->SelectPage(initial_apps_page, false);
  63. }
  64. void AppListMainView::AddContentsViews() {
  65. DCHECK(search_box_view_);
  66. auto contents_view = std::make_unique<ContentsView>(app_list_view_);
  67. contents_view->Init();
  68. contents_view->SetPaintToLayer(ui::LAYER_NOT_DRAWN);
  69. contents_view->layer()->SetMasksToBounds(true);
  70. contents_view_ = AddChildView(std::move(contents_view));
  71. search_box_view_->set_contents_view(contents_view_);
  72. }
  73. void AppListMainView::ShowAppListWhenReady() {
  74. // After switching to tablet mode, other app windows may be active. Show the
  75. // app list without activating it to avoid breaking other windows' state.
  76. const aura::Window* active_window =
  77. wm::GetActivationClient(
  78. app_list_view_->GetWidget()->GetNativeView()->GetRootWindow())
  79. ->GetActiveWindow();
  80. if (app_list_view_->is_tablet_mode() && active_window)
  81. GetWidget()->ShowInactive();
  82. else
  83. GetWidget()->Show();
  84. }
  85. void AppListMainView::SetDragAndDropHostOfCurrentAppList(
  86. ApplicationDragAndDropHost* drag_and_drop_host) {
  87. contents_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
  88. }
  89. PaginationModel* AppListMainView::GetAppsPaginationModel() {
  90. return contents_view_->apps_container_view()
  91. ->apps_grid_view()
  92. ->pagination_model();
  93. }
  94. void AppListMainView::NotifySearchBoxVisibilityChanged() {
  95. // Repaint the AppListView's background which will repaint the background for
  96. // the search box. This is needed because this view paints to a layer and
  97. // won't propagate paints upward.
  98. if (parent())
  99. parent()->SchedulePaint();
  100. }
  101. const char* AppListMainView::GetClassName() const {
  102. return "AppListMainView";
  103. }
  104. void AppListMainView::Layout() {
  105. gfx::Rect rect = GetContentsBounds();
  106. if (!rect.IsEmpty())
  107. contents_view_->SetBoundsRect(rect);
  108. }
  109. void AppListMainView::QueryChanged(const std::u16string& trimmed_query,
  110. bool initiated_by_user) {
  111. app_list_view_->SetStateFromSearchBoxView(trimmed_query.empty(),
  112. initiated_by_user);
  113. contents_view_->ShowSearchResults(search_box_view_->is_search_box_active() ||
  114. !trimmed_query.empty());
  115. contents_view_->search_result_page_view()->UpdateForNewSearch();
  116. }
  117. void AppListMainView::ActiveChanged(SearchBoxViewBase* sender) {
  118. // Do not update views on closing.
  119. if (app_list_view_->app_list_state() == AppListViewState::kClosed)
  120. return;
  121. if (search_box_view_->is_search_box_active()) {
  122. // Show zero state suggestions when search box is activated with an empty
  123. // query.
  124. const bool is_query_empty = sender->IsSearchBoxTrimmedQueryEmpty();
  125. if (features::IsProductivityLauncherEnabled()) {
  126. app_list_view_->SetStateFromSearchBoxView(
  127. is_query_empty, true /*triggered_by_contents_change*/);
  128. contents_view_->ShowSearchResults(true);
  129. } else {
  130. if (is_query_empty)
  131. search_box_view_->ShowZeroStateSuggestions();
  132. }
  133. } else {
  134. // Close the search results page if the search box is inactive.
  135. contents_view_->ShowSearchResults(false);
  136. }
  137. }
  138. void AppListMainView::OnSearchBoxKeyEvent(ui::KeyEvent* event) {
  139. app_list_view_->RedirectKeyEventToSearchBox(event);
  140. if (!IsUnhandledUpDownKeyEvent(*event))
  141. return;
  142. // Handles arrow key events from the search box while the search box is
  143. // inactive. This covers both folder traversal and apps grid traversal. Search
  144. // result traversal is handled in |HandleKeyEvent|
  145. AppListPage* page =
  146. contents_view_->GetPageView(contents_view_->GetActivePageIndex());
  147. views::View* arrow_view = contents_view_->expand_arrow_view();
  148. views::View* next_view = nullptr;
  149. if (event->key_code() == ui::VKEY_UP) {
  150. if (arrow_view && arrow_view->IsFocusable())
  151. next_view = arrow_view;
  152. else
  153. next_view = page->GetLastFocusableView();
  154. } else {
  155. next_view = page->GetFirstFocusableView();
  156. }
  157. if (next_view)
  158. next_view->RequestFocus();
  159. event->SetHandled();
  160. }
  161. bool AppListMainView::CanSelectSearchResults() {
  162. // If there's a result, keyboard selection is allowed.
  163. return !!contents_view_->search_result_page_view()->CanSelectSearchResults();
  164. }
  165. void AppListMainView::AssistantButtonPressed() {
  166. delegate_->StartAssistant();
  167. }
  168. void AppListMainView::CloseButtonPressed() {
  169. // Deactivate the search box.
  170. search_box_view_->SetSearchBoxActive(false, ui::ET_UNKNOWN);
  171. search_box_view_->ClearSearch();
  172. }
  173. } // namespace ash