paged_view_structure.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2018 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_PAGED_VIEW_STRUCTURE_H_
  5. #define ASH_APP_LIST_PAGED_VIEW_STRUCTURE_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "ash/ash_export.h"
  9. #include "base/check_op.h"
  10. namespace ash {
  11. class AppsGridView;
  12. class AppListItem;
  13. class AppListItemView;
  14. struct GridIndex;
  15. // Manages the mapping between AppListItemList index, view model index, and
  16. // visual pages in the apps grid view.
  17. class ASH_EXPORT PagedViewStructure {
  18. public:
  19. using Page = std::vector<AppListItemView*>;
  20. using Pages = std::vector<Page>;
  21. // Class that disables empty page or overflow sanitization when in scope.
  22. class ScopedSanitizeLock {
  23. public:
  24. explicit ScopedSanitizeLock(PagedViewStructure* view_structure);
  25. ScopedSanitizeLock(const ScopedSanitizeLock&) = delete;
  26. ScopedSanitizeLock& operator=(const ScopedSanitizeLock&) = delete;
  27. ~ScopedSanitizeLock();
  28. private:
  29. PagedViewStructure* const view_structure_;
  30. };
  31. explicit PagedViewStructure(AppsGridView* apps_grid_view);
  32. PagedViewStructure(const PagedViewStructure& other) = delete;
  33. PagedViewStructure& operator=(PagedViewStructure& other) = delete;
  34. ~PagedViewStructure();
  35. enum class Mode {
  36. // Paged, with partially full pages created by page break items.
  37. kPartialPages,
  38. // Paged, with all pages full. Used for folders.
  39. kFullPages,
  40. // A single long page. Ignores page breaks in the data model. Used for
  41. // scrollable apps grid.
  42. kSinglePage
  43. };
  44. void Init(Mode mode);
  45. // Temporarily disables sanitization of empty pages and page overflow. The
  46. // sanitization will remain disabled while the returned object remains in
  47. // scope. The paged view structure will be sanitized when the returned object
  48. // gets destroyed.
  49. // This should be used in cases where paged view structure has to be updated
  50. // in two or more steps, in which case view structure should only be sanitized
  51. // after the final step.
  52. // NOTE: The caller should ensure that the returned object does not outlive
  53. // the PagedViewStructure instance.
  54. std::unique_ptr<ScopedSanitizeLock> GetSanitizeLock();
  55. // Permanently allows empty pages in this paged view structure.
  56. void AllowEmptyPages();
  57. // Loads the view structure and mode from another `PagedViewStructure`.
  58. // `other` view structure should be associated with the same apps grid.
  59. // This will attempt to sanitize view structure - use `GetSanitizeLock()`
  60. // beforehand to avoid sanitization.
  61. void LoadFromOther(const PagedViewStructure& other);
  62. // Loads the view structure based on the position and page position in the
  63. // metadata of item views in the view model.
  64. void LoadFromMetadata();
  65. // Saves page position change of each item view to metadata of item views
  66. // in the view model.
  67. void SaveToMetadata();
  68. // Operations allowed to modify the view structure.
  69. void Move(AppListItemView* view, const GridIndex& target_index);
  70. void Remove(AppListItemView* view);
  71. void Add(AppListItemView* view, const GridIndex& target_index);
  72. // Convert between the model index and the visual index. The model index
  73. // is the index of the item in AppListModel (Also the same index in
  74. // AppListItemList). The visual index is the GridIndex struct above with
  75. // page/slot info of where to display the item.
  76. GridIndex GetIndexFromModelIndex(int model_index) const;
  77. int GetModelIndexFromIndex(const GridIndex& index) const;
  78. // Returns the last possible visual index to add an item view.
  79. GridIndex GetLastTargetIndex() const;
  80. // Returns the last possible visual index to add an item view in the specified
  81. // page, used only for drag reordering.
  82. GridIndex GetLastTargetIndexOfPage(int page_index) const;
  83. // Returns the target model index if moving the item view to specified target
  84. // visual index.
  85. int GetTargetModelIndexForMove(AppListItem* moved_item,
  86. const GridIndex& index) const;
  87. // Returns the target `AppsGridView::item_list_` index if moving the item view
  88. // to specified target visual index.
  89. int GetTargetItemListIndexForMove(AppListItem* moved_item,
  90. const GridIndex& index) const;
  91. // Returns true if the visual index is valid position to which an item view
  92. // can be moved.
  93. bool IsValidReorderTargetIndex(const GridIndex& index) const;
  94. // Adds a page break at the end of |pages_|.
  95. void AppendPage();
  96. // Returns true if the page has no empty slot.
  97. bool IsFullPage(int page_index) const;
  98. // Returns total number of pages in the view structure.
  99. int total_pages() const { return pages_.size(); }
  100. // Returns total number of item views in the specified page.
  101. int items_on_page(int page_index) const {
  102. DCHECK_LT(page_index, total_pages());
  103. return pages_[page_index].size();
  104. }
  105. Mode mode() const { return mode_; }
  106. const Pages& pages() const { return pages_; }
  107. private:
  108. // Skips the item view being dragged if it exists in the specified
  109. // |page|.
  110. int CalculateTargetSlot(const Page& page) const;
  111. // Sanitizes the paged view structure - it clears page overflow and
  112. // removes empty pages. A sanitization step is skipped if any sanitization
  113. // disablers for that step are active.
  114. void Sanitize();
  115. // Clear overflowing item views by moving them to the next page.
  116. void ClearOverflow();
  117. // Removes empty pages.
  118. void ClearEmptyPages();
  119. // Returns TilesPerPage() from `apps_grid_view_`.
  120. int TilesPerPage(int page) const;
  121. // Not const for tests.
  122. Mode mode_ = Mode::kPartialPages;
  123. // Represents the item views' locations in each page.
  124. Pages pages_;
  125. AppsGridView* const apps_grid_view_; // Not owned.
  126. // The number of active `ScopedSanitizeLocks` that disable
  127. // sanitization of empty pages and page overflow sanitization.
  128. int sanitize_locks_ = 0;
  129. // Whether this view structure allows empty pages.
  130. bool empty_pages_allowed_ = false;
  131. };
  132. } // namespace ash
  133. #endif // ASH_APP_LIST_PAGED_VIEW_STRUCTURE_H_