apps_container_view.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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. #ifndef ASH_APP_LIST_VIEWS_APPS_CONTAINER_VIEW_H_
  5. #define ASH_APP_LIST_VIEWS_APPS_CONTAINER_VIEW_H_
  6. #include <stddef.h>
  7. #include <memory>
  8. #include "ash/app_list/app_list_model_provider.h"
  9. #include "ash/app_list/app_list_view_provider.h"
  10. #include "ash/app_list/model/app_list_folder_item.h"
  11. #include "ash/app_list/views/app_list_folder_controller.h"
  12. #include "ash/app_list/views/app_list_nudge_controller.h"
  13. #include "ash/app_list/views/app_list_page.h"
  14. #include "ash/app_list/views/app_list_toast_container_view.h"
  15. #include "ash/app_list/views/paged_apps_grid_view.h"
  16. #include "ash/app_list/views/search_result_page_dialog_controller.h"
  17. #include "ash/ash_export.h"
  18. #include "ash/public/cpp/pagination/pagination_model_observer.h"
  19. #include "base/callback_helpers.h"
  20. #include "base/memory/weak_ptr.h"
  21. #include "ui/views/controls/separator.h"
  22. #include "ui/views/focus/focus_manager.h"
  23. namespace ash {
  24. class ApplicationDragAndDropHost;
  25. class AppListFolderItem;
  26. class AppListFolderView;
  27. class AppListKeyboardController;
  28. class AppListNudgeController;
  29. class ContentsView;
  30. class ContinueSectionView;
  31. class FolderBackgroundView;
  32. class GradientLayerDelegate;
  33. class PageSwitcher;
  34. class SearchResultPageAnchoredDialog;
  35. class SuggestionChipContainerView;
  36. // AppsContainerView contains a root level AppsGridView to render the root level
  37. // app items, and a AppListFolderView to render the app items inside the active
  38. // folder. With productivity launcher, it also contains the continue section,
  39. // recent apps, and an optional separator.
  40. class ASH_EXPORT AppsContainerView
  41. : public AppListPage,
  42. public AppListModelProvider::Observer,
  43. public AppListFolderController,
  44. public PaginationModelObserver,
  45. public PagedAppsGridView::ContainerDelegate,
  46. public AppListToastContainerView::Delegate,
  47. public views::FocusChangeListener,
  48. public AppListViewProvider {
  49. public:
  50. explicit AppsContainerView(ContentsView* contents_view);
  51. AppsContainerView(const AppsContainerView&) = delete;
  52. AppsContainerView& operator=(const AppsContainerView&) = delete;
  53. ~AppsContainerView() override;
  54. // Resets the app list to a state where it shows the main grid view. This is
  55. // called when the user opens the launcher for the first time or when the user
  56. // hides and then shows it.
  57. void ResetForShowApps();
  58. // Sets |drag_and_drop_host_| for the current app list in both
  59. // app_list_folder_view_ and root level apps_grid_view_.
  60. void SetDragAndDropHostOfCurrentAppList(
  61. ApplicationDragAndDropHost* drag_and_drop_host);
  62. // Returns true if it is currently showing an active folder page.
  63. bool IsInFolderView() const;
  64. // Updates the visibility of the items in this view according to
  65. // |app_list_state| and |is_in_drag|.
  66. void UpdateControlVisibility(AppListViewState app_list_state,
  67. bool is_in_drag);
  68. // Called when tablet mode starts and ends.
  69. void OnTabletModeChanged(bool started);
  70. // Minimal margin for apps grid within the apps container. Set to ensure there
  71. // is enough space to fit page switcher next to the apps grid.
  72. int GetMinHorizontalMarginForAppsGrid() const;
  73. // The minimal top margin for the apps grid (measured from the top of the
  74. // search box to the top of the apps grid). This margin includes space for
  75. // search box and suggestion chips.
  76. // For productivity launcher UI, this will not include space for continue
  77. // section and recent apps.
  78. int GetMinTopMarginForAppsGrid(const gfx::Size& search_box_size) const;
  79. // Returns the ideal margins for content within the apps container. The actual
  80. // margins may differ depending on available screen real-estate. For example,
  81. // margins may be smaller if the apps grid contents would not fit within the
  82. // ideal margins.
  83. int GetIdealHorizontalMargin() const;
  84. int GetIdealVerticalMargin() const;
  85. // Calculates the apps container margins depending on the available content
  86. // bounds, and search box size.
  87. // |available_bounds| - The bounds available to lay out the full apps
  88. // container.
  89. // |search_box_size| - The expected search box size. Used to determine the
  90. // the amount of space in apps container available to the apps grid
  91. //
  92. // NOTE: This should not call into ContentsView::GetSearchBoxBounds*()
  93. // methods, as CalculateMarginsForAvailableBounds is used to calculate the
  94. // search box bounds.
  95. const gfx::Insets& CalculateMarginsForAvailableBounds(
  96. const gfx::Rect& available_bounds,
  97. const gfx::Size& search_box_size);
  98. // views::View overrides:
  99. void Layout() override;
  100. bool OnKeyPressed(const ui::KeyEvent& event) override;
  101. const char* GetClassName() const override;
  102. void OnGestureEvent(ui::GestureEvent* event) override;
  103. void OnBoundsChanged(const gfx::Rect& old_bounds) override;
  104. void AddedToWidget() override;
  105. void RemovedFromWidget() override;
  106. // views::FocusChangeListener overrides:
  107. void OnWillChangeFocus(View* focused_before, View* focused_now) override {}
  108. void OnDidChangeFocus(View* focused_before, View* focused_now) override;
  109. // AppListPage overrides:
  110. void OnShown() override;
  111. void OnWillBeHidden() override;
  112. void OnHidden() override;
  113. void OnAnimationStarted(AppListState from_state,
  114. AppListState to_state) override;
  115. void UpdatePageOpacityForState(AppListState state,
  116. float search_box_opacity,
  117. bool restore_opacity) override;
  118. void UpdatePageBoundsForState(AppListState state,
  119. const gfx::Rect& contents_bounds,
  120. const gfx::Rect& search_box_bounds) override;
  121. gfx::Rect GetPageBoundsForState(
  122. AppListState state,
  123. const gfx::Rect& contents_bounds,
  124. const gfx::Rect& search_box_bounds) const override;
  125. void AnimateOpacity(float current_progress,
  126. AppListViewState target_view_state,
  127. const OpacityAnimator& animator) override;
  128. void AnimateYPosition(AppListViewState target_view_state,
  129. const TransformAnimator& animator,
  130. float default_offset) override;
  131. // AppListModelProvider::Observer:
  132. void OnActiveAppListModelsChanged(AppListModel* model,
  133. SearchModel* search_model) override;
  134. // AppListFolderController:
  135. void ShowFolderForItemView(AppListItemView* folder_item_view,
  136. bool focus_name_input,
  137. base::OnceClosure hide_callback) override;
  138. void ShowApps(AppListItemView* folder_item_view, bool select_folder) override;
  139. void ReparentFolderItemTransit(AppListFolderItem* folder_item) override;
  140. void ReparentDragEnded() override;
  141. // PaginationModelObserver:
  142. void SelectedPageChanged(int old_selected, int new_selected) override;
  143. void TransitionChanged() override;
  144. void TransitionStarted() override;
  145. void TransitionEnded() override;
  146. void ScrollStarted() override;
  147. void ScrollEnded() override;
  148. // PagedAppsGridView::ContainerDelegate:
  149. bool IsPointWithinPageFlipBuffer(const gfx::Point& point) const override;
  150. bool IsPointWithinBottomDragBuffer(const gfx::Point& point,
  151. int page_flip_zone_size) const override;
  152. void OnCardifiedStateStarted() override;
  153. void OnCardifiedStateEnded() override;
  154. // AppListToastContainerView::Delegate:
  155. void OnNudgeRemoved() override;
  156. // Handles `AppListController::UpdateAppListWithNewSortingOrder()` for the
  157. // app list container.
  158. void UpdateForNewSortingOrder(
  159. const absl::optional<AppListSortOrder>& new_order,
  160. bool animate,
  161. base::OnceClosure update_position_closure,
  162. base::OnceClosure animation_done_closure);
  163. // Updates the continue section visibility based on user preference.
  164. void UpdateContinueSectionVisibility();
  165. // Called by app list controller when the app list visibility is about to
  166. // change - when the app list is about to be shown, initiates zero state
  167. // search in order to update set of apps shown in recent apps and continue
  168. // section contents.
  169. void OnAppListVisibilityWillChange(bool visible);
  170. // Updates the nudge in `toast_container_` when app list visibility changes.
  171. void OnAppListVisibilityChanged(bool shown);
  172. // AppListViewProvider:
  173. ContinueSectionView* GetContinueSectionView() override;
  174. RecentAppsView* GetRecentAppsView() override;
  175. AppsGridView* GetAppsGridView() override;
  176. AppListToastContainerView* GetToastContainerView() override;
  177. views::Separator* separator() { return separator_; }
  178. PagedAppsGridView* apps_grid_view() { return apps_grid_view_; }
  179. FolderBackgroundView* folder_background_view() {
  180. return folder_background_view_;
  181. }
  182. AppListFolderView* app_list_folder_view() { return app_list_folder_view_; }
  183. PageSwitcher* page_switcher() { return page_switcher_; }
  184. views::View* scrollable_container_for_test() { return scrollable_container_; }
  185. SuggestionChipContainerView* suggestion_chip_container_view_for_test() {
  186. return suggestion_chip_container_view_;
  187. }
  188. AppListToastContainerView* toast_container() { return toast_container_; }
  189. AppListNudgeController* app_list_nudge_controller() {
  190. return app_list_nudge_controller_.get();
  191. }
  192. // Updates recent apps from app list model. `needs_layout` indicates whether
  193. // the apps container relaid out when the recent apps results are updated.
  194. void UpdateRecentApps(bool needs_layout);
  195. // Updates suggestion chips from app list model.
  196. void UpdateSuggestionChips();
  197. // Temporarily disables blur on suggestion chips view background. The blur
  198. // will remained disabled until the returned closure runner goes out of scope.
  199. base::ScopedClosureRunner DisableSuggestionChipsBlur();
  200. // Gets the height of the `separator_` including its vertical margin.
  201. int GetSeparatorHeight();
  202. SearchResultPageAnchoredDialog* dialog_for_test() {
  203. return dialog_controller_->dialog();
  204. }
  205. private:
  206. enum ShowState {
  207. SHOW_NONE, // initial state
  208. SHOW_APPS,
  209. SHOW_ACTIVE_FOLDER,
  210. SHOW_ITEM_REPARENT,
  211. };
  212. class ContinueContainer;
  213. void SetShowState(ShowState show_state, bool show_apps_with_animation);
  214. // Updates the whole container opacity to match the app list state.
  215. void UpdateContainerOpacityForState(AppListState state);
  216. // Updates the opacity of the apps container elements for the current app list
  217. // view position.
  218. // |progress| - The current app list view drag progress.
  219. // |restore_opacity| - Whether the opacity should be restored to the non-drag
  220. // state.
  221. void UpdateContentsOpacity(float progress, bool restore_opacity);
  222. // Updates the y position of the apps container elements for the current app
  223. // list view position.
  224. // |progress| - The current app list view drag progress.
  225. void UpdateContentsYPosition(float progress);
  226. // Suggestion chips and apps grid view become unfocusable if |disabled| is
  227. // true. This is used to trap focus within the folder when it is opened.
  228. void DisableFocusForShowingActiveFolder(bool disabled);
  229. // Returns expected suggestion chip container's y position based on the app
  230. // list transition progress.
  231. int GetExpectedSuggestionChipY(float progress);
  232. struct GridLayout {
  233. int columns;
  234. int rows;
  235. int first_page_rows;
  236. };
  237. // Returns the number of columns and rows |apps_grid_view_| should display,
  238. // depending on the current display work area size.
  239. GridLayout CalculateGridLayout() const;
  240. // Calculates the grid layout and updates the number of rows and columns shown
  241. // in the top level apps grid.
  242. void UpdateTopLevelGridDimensions();
  243. // Returns the space available to the apps grid for laying out its contents.
  244. gfx::Rect CalculateAvailableBoundsForAppsGrid(
  245. const gfx::Rect& contents_bounds) const;
  246. // Depending on the provided apps container contents bounds and grid layout,
  247. // updates `app_list_config_` to be used within the apps container, and passes
  248. // it on to child views that require it.
  249. void UpdateAppListConfig(const gfx::Rect& contents_bounds);
  250. // Updates the apps container UI to display contents from the active app list
  251. // model. Should be called to initialize the apps container contents, and
  252. // whenever the active app list model changes.
  253. void UpdateForActiveAppListModel();
  254. // Callback returned by DisableBlur().
  255. void OnSuggestionChipsBlurDisablerReleased();
  256. // Updates the bounds of the gradient mask to fit the current bounds of the
  257. // `scrollable_container_`.
  258. void UpdateGradientMaskBounds();
  259. // Creates a layer mask for gradient alpha when the feature is enabled. The
  260. // gradient appears at the top and bottom of the 'scrollable_container_' to
  261. // create a "fade out" effect when dragging the whole page.
  262. void MaybeCreateGradientMask();
  263. // Removes the gradient mask from being set as the mask layer.
  264. void MaybeRemoveGradientMask();
  265. // Called when the animation to fade out app list items is completed.
  266. // `aborted` indicates whether the fade out animation is aborted.
  267. void OnAppsGridViewFadeOutAnimationEnded(
  268. const absl::optional<AppListSortOrder>& new_order,
  269. bool aborted);
  270. // Called when the animation to fade in app list items is completed.
  271. // `aborted` indicates whether the fade in animation is aborted.
  272. void OnAppsGridViewFadeInAnimationEnded(bool aborted);
  273. // Called at the end of the reorder animation. In detail, it is executed in
  274. // the following scenarios:
  275. // (1) At the end of the fade out animation when the fade out is aborted, or
  276. // (2) At the end of the fade in animation.
  277. void OnReorderAnimationEnded();
  278. // Called after sort to handle focus.
  279. void HandleFocusAfterSort();
  280. // While true, the gradient mask will not be removed as a mask layer until
  281. // cardified state ends.
  282. bool keep_gradient_mask_for_cardified_state_ = false;
  283. ContentsView* const contents_view_;
  284. // The app list config used to configure sizing and layout of apps grid items
  285. // within the apps container.
  286. std::unique_ptr<AppListConfig> app_list_config_;
  287. std::unique_ptr<AppListKeyboardController> app_list_keyboard_controller_;
  288. std::unique_ptr<AppListNudgeController> app_list_nudge_controller_;
  289. // Controller for showing a modal dialog in the continue section.
  290. std::unique_ptr<SearchResultPageDialogController> dialog_controller_;
  291. // The number of active requests to disable blur.
  292. size_t suggestion_chips_blur_disabler_count_ = 0;
  293. // Contains the |continue_section_| and the |apps_grid_view_|, which are views
  294. // that are affected by paging. Owned by views hierarchy.
  295. views::View* scrollable_container_ = nullptr;
  296. // The views below are owned by views hierarchy.
  297. SuggestionChipContainerView* suggestion_chip_container_view_ = nullptr;
  298. ContinueContainer* continue_container_ = nullptr;
  299. views::Separator* separator_ = nullptr;
  300. AppListToastContainerView* toast_container_ = nullptr;
  301. PagedAppsGridView* apps_grid_view_ = nullptr;
  302. AppListFolderView* app_list_folder_view_ = nullptr;
  303. PageSwitcher* page_switcher_ = nullptr;
  304. FolderBackgroundView* folder_background_view_ = nullptr;
  305. ShowState show_state_ = SHOW_NONE;
  306. // Whether the apps container is the current active app list page.
  307. bool is_active_page_ = false;
  308. // The distance between y position of suggestion chip container and apps grid
  309. // view. This is used in dragging to avoid duplicate calculation of apps grid
  310. // view's y position.
  311. int chip_grid_y_distance_ = 0;
  312. struct CachedContainerMargins {
  313. gfx::Size bounds_size;
  314. gfx::Size search_box_size;
  315. gfx::Insets margins;
  316. };
  317. // The last result returned by CalculateMarginsForAvailableBounds() -
  318. // subsequent calls to that method will return the result cached in
  319. // |cached_container_margins_|, provided the method arguments match the cached
  320. // arguments (otherwise the margins will be recalculated).
  321. CachedContainerMargins cached_container_margins_;
  322. std::unique_ptr<GradientLayerDelegate> gradient_layer_delegate_;
  323. // A closure to update item positions. It should run at the end of the fade
  324. // out animation when items are reordered.
  325. base::OnceClosure update_position_closure_;
  326. // A closure that runs at the end of the reorder animation.
  327. base::OnceClosure reorder_animation_done_closure_;
  328. base::WeakPtrFactory<AppsContainerView> weak_ptr_factory_{this};
  329. };
  330. } // namespace ash
  331. #endif // ASH_APP_LIST_VIEWS_APPS_CONTAINER_VIEW_H_