holding_space_item_views_section.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2020 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_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEWS_SECTION_H_
  5. #define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEWS_SECTION_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "ash/public/cpp/holding_space/holding_space_item.h"
  11. #include "third_party/abseil-cpp/absl/types/optional.h"
  12. #include "ui/views/view.h"
  13. namespace ui {
  14. class CallbackLayerAnimationObserver;
  15. class LayerAnimationObserver;
  16. } // namespace ui
  17. namespace views {
  18. class ScrollView;
  19. } // namespace views
  20. namespace ash {
  21. class HoldingSpaceItemView;
  22. class HoldingSpaceViewDelegate;
  23. // A section of holding space item views in a `HoldingSpaceTrayChildBubble`.
  24. class HoldingSpaceItemViewsSection : public views::View {
  25. public:
  26. HoldingSpaceItemViewsSection(HoldingSpaceViewDelegate* delegate,
  27. std::set<HoldingSpaceItem::Type> supported_types,
  28. const absl::optional<size_t>& max_count);
  29. HoldingSpaceItemViewsSection(const HoldingSpaceItemViewsSection& other) =
  30. delete;
  31. HoldingSpaceItemViewsSection& operator=(
  32. const HoldingSpaceItemViewsSection& other) = delete;
  33. ~HoldingSpaceItemViewsSection() override;
  34. // Initializes the section.
  35. void Init();
  36. // Resets the section. Called when the tray bubble starts closing to ensure
  37. // that no new items are created while the bubble widget is being
  38. // asynchronously closed.
  39. void Reset();
  40. // Returns all holding space item views in the section. Views are returned in
  41. // top-to-bottom, left-to-right order (or mirrored for RTL).
  42. std::vector<HoldingSpaceItemView*> GetHoldingSpaceItemViews();
  43. // views::View:
  44. void ChildPreferredSizeChanged(views::View* child) override;
  45. void ChildVisibilityChanged(views::View* child) override;
  46. void PreferredSizeChanged() override;
  47. void ViewHierarchyChanged(const views::ViewHierarchyChangedDetails&) override;
  48. // `HoldingSpaceModelObserver` events forwarded from the parent
  49. // `HoldingSpaceTrayChildBubble`. Note that events may be withheld from this
  50. // view if, for example, its parent is animating out.
  51. void OnHoldingSpaceItemsAdded(const std::vector<const HoldingSpaceItem*>&);
  52. void OnHoldingSpaceItemsRemoved(const std::vector<const HoldingSpaceItem*>&);
  53. void OnHoldingSpaceItemInitialized(const HoldingSpaceItem* item);
  54. // Removes all holding space item views from this section. This method is
  55. // expected to only be called:
  56. // * from the parent `HoldingSpaceTrayChildBubble` when this view is hidden.
  57. // * internally after having animated out the `container_` just prior to
  58. // swapping in new contents.
  59. void RemoveAllHoldingSpaceItemViews();
  60. // Returns whether this section has a placeholder to show in lieu of item
  61. // views when the model contains no initialized items of supported types.
  62. bool has_placeholder() const { return !!placeholder_; }
  63. // Returns the types of holding space items supported by this section.
  64. const std::set<HoldingSpaceItem::Type>& supported_types() const {
  65. return supported_types_;
  66. }
  67. protected:
  68. // Invoked to create the `header_` for this section.
  69. virtual std::unique_ptr<views::View> CreateHeader() = 0;
  70. // Invoked to create the `container_` for this section which parents its
  71. // holding space item views.
  72. virtual std::unique_ptr<views::View> CreateContainer() = 0;
  73. // Invoked to create the view for the specified holding space `item`. Note
  74. // that the created view will be parented by `container_`.
  75. virtual std::unique_ptr<HoldingSpaceItemView> CreateView(
  76. const HoldingSpaceItem* item) = 0;
  77. // Invoked to create the `placeholder_` for this section which shows when
  78. // `container_` is empty. The `placeholder_` can be destroyed via call to
  79. // `DestroyPlaceholder()` if it is no longer needed to exist.
  80. virtual std::unique_ptr<views::View> CreatePlaceholder();
  81. // Invoked to destroy `placeholder_`.
  82. void DestroyPlaceholder();
  83. HoldingSpaceViewDelegate* delegate() { return delegate_; }
  84. private:
  85. enum AnimationState : uint32_t {
  86. kNotAnimating = 0,
  87. kAnimatingIn = 1 << 1,
  88. kAnimatingOut = 1 << 2,
  89. };
  90. // Invoke to start animating in the contents of this section. No-ops if
  91. // animate in is already in progress.
  92. void MaybeAnimateIn();
  93. // Invoke to start animating out the contents of this section. No-ops if
  94. // animate out is already in progress.
  95. void MaybeAnimateOut();
  96. // Invoked to animate in the contents of this section. Any created animation
  97. // sequences must be observed by `observer`.
  98. void AnimateIn(ui::LayerAnimationObserver* observer);
  99. // Invoked to animate out the contents of this section. Any created animation
  100. // sequences must be observed by `observer`.
  101. void AnimateOut(ui::LayerAnimationObserver* observer);
  102. // Invoked when an animate in/out of the contents of this section has been
  103. // completed. Note that the provided observer will be deleted after returning.
  104. void OnAnimateInCompleted(const ui::CallbackLayerAnimationObserver&);
  105. void OnAnimateOutCompleted(const ui::CallbackLayerAnimationObserver&);
  106. HoldingSpaceViewDelegate* const delegate_;
  107. const std::set<HoldingSpaceItem::Type> supported_types_;
  108. const absl::optional<size_t> max_count_;
  109. // Owned by view hierarchy.
  110. views::View* header_ = nullptr;
  111. views::View* container_ = nullptr;
  112. views::View* placeholder_ = nullptr;
  113. views::ScrollView* scroll_view_ = nullptr;
  114. std::map<std::string, HoldingSpaceItemView*> views_by_item_id_;
  115. // Bit flag representation of current `AnimationState`. Note that it is
  116. // briefly possible to be both `kAnimatingIn` and `kAnimatingOut` when one
  117. // animation is preempting another.
  118. uint32_t animation_state_ = AnimationState::kNotAnimating;
  119. // Whether or not animations are disabled. Animations are only disabled during
  120. // initialization as holding space child bubbles are animated in instead.
  121. bool disable_animations_ = false;
  122. // Whether or not `PreferredSizeChanged()` is allowed to propagate up the
  123. // view hierarchy. This is disabled during batch child additions, removals,
  124. // and visibility change operations to reduce the number of layout events.
  125. bool disable_preferred_size_changed_ = false;
  126. base::WeakPtrFactory<HoldingSpaceItemViewsSection> weak_factory_{this};
  127. };
  128. } // namespace ash
  129. #endif // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEWS_SECTION_H_