holding_space_tray.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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_TRAY_H_
  5. #define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_TRAY_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "ash/ash_export.h"
  9. #include "ash/public/cpp/holding_space/holding_space_controller.h"
  10. #include "ash/public/cpp/holding_space/holding_space_controller_observer.h"
  11. #include "ash/public/cpp/holding_space/holding_space_model.h"
  12. #include "ash/public/cpp/holding_space/holding_space_model_observer.h"
  13. #include "ash/public/cpp/session/session_controller.h"
  14. #include "ash/public/cpp/session/session_observer.h"
  15. #include "ash/style/ash_color_provider.h"
  16. #include "ash/system/holding_space/holding_space_tray_bubble.h"
  17. #include "ash/system/tray/tray_background_view.h"
  18. #include "base/callback_list.h"
  19. #include "base/memory/weak_ptr.h"
  20. #include "base/scoped_observation.h"
  21. #include "base/timer/timer.h"
  22. #include "ui/base/metadata/metadata_header_macros.h"
  23. #include "ui/base/models/simple_menu_model.h"
  24. #include "ui/views/widget/widget.h"
  25. #include "ui/views/widget/widget_observer.h"
  26. class PrefChangeRegistrar;
  27. namespace aura {
  28. namespace client {
  29. class DragDropClientObserver;
  30. } // namespace client
  31. } // namespace aura
  32. namespace views {
  33. class ImageView;
  34. } // namespace views
  35. namespace ash {
  36. class HoldingSpaceTrayIcon;
  37. class ProgressIndicator;
  38. // The HoldingSpaceTray shows the tray button in the bottom area of the screen.
  39. // This class also controls the lifetime for all of the tools available in the
  40. // palette. HoldingSpaceTray has one instance per-display.
  41. class ASH_EXPORT HoldingSpaceTray : public TrayBackgroundView,
  42. public HoldingSpaceControllerObserver,
  43. public HoldingSpaceModelObserver,
  44. public SessionObserver,
  45. public ui::SimpleMenuModel::Delegate,
  46. public views::WidgetObserver {
  47. public:
  48. METADATA_HEADER(HoldingSpaceTray);
  49. explicit HoldingSpaceTray(Shelf* shelf);
  50. HoldingSpaceTray(const HoldingSpaceTray& other) = delete;
  51. HoldingSpaceTray& operator=(const HoldingSpaceTray& other) = delete;
  52. ~HoldingSpaceTray() override;
  53. // TrayBackgroundView:
  54. void Initialize() override;
  55. void ClickedOutsideBubble() override;
  56. std::u16string GetAccessibleNameForTray() override;
  57. views::View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
  58. std::u16string GetTooltipText(const gfx::Point& point) const override;
  59. void HandleLocaleChange() override;
  60. void HideBubbleWithView(const TrayBubbleView* bubble_view) override;
  61. void AnchorUpdated() override;
  62. void UpdateAfterLoginStatusChange() override;
  63. void CloseBubble() override;
  64. void ShowBubble() override;
  65. TrayBubbleView* GetBubbleView() override;
  66. views::Widget* GetBubbleWidget() const override;
  67. void SetVisiblePreferred(bool visible_preferred) override;
  68. bool GetDropFormats(int* formats,
  69. std::set<ui::ClipboardFormatType>* format_types) override;
  70. bool AreDropTypesRequired() override;
  71. bool CanDrop(const ui::OSExchangeData& data) override;
  72. int OnDragUpdated(const ui::DropTargetEvent& event) override;
  73. views::View::DropCallback GetDropCallback(
  74. const ui::DropTargetEvent& event) override;
  75. void Layout() override;
  76. void VisibilityChanged(views::View* starting_from, bool is_visible) override;
  77. void OnThemeChanged() override;
  78. void OnShouldShowAnimationChanged(bool should_animate) override;
  79. std::unique_ptr<ui::SimpleMenuModel> CreateContextMenuModel() override;
  80. // Invoke to cause the holding space tray to recalculate and update its
  81. // visibility. Note that this may or may not result in a visibility change
  82. // depending on state.
  83. void UpdateVisibility();
  84. // Returns the holding space tray bubble for testing.
  85. HoldingSpaceTrayBubble* bubble_for_testing() { return bubble_.get(); }
  86. // Previews are updated with delay to de-dupe against multiple updates
  87. // scheduled in quick succession. Invoke this method to cause scheduled
  88. // updates to be run immediately for testing.
  89. void FirePreviewsUpdateTimerIfRunningForTesting();
  90. // Previews are updated with delay to de-dupe against multiple updates
  91. // scheduled in quick success. This method allows updates to be scheduled with
  92. // zero delay, causing them to instead run immediately, for testing.
  93. void set_use_zero_previews_update_delay_for_testing(bool zero_delay) {
  94. use_zero_previews_update_delay_ = zero_delay;
  95. }
  96. private:
  97. // TrayBubbleView::Delegate:
  98. std::u16string GetAccessibleNameForBubble() override;
  99. bool ShouldEnableExtraKeyboardAccessibility() override;
  100. void HideBubble(const TrayBubbleView* bubble_view) override;
  101. // HoldingSpaceControllerObserver:
  102. void OnHoldingSpaceModelAttached(HoldingSpaceModel* model) override;
  103. void OnHoldingSpaceModelDetached(HoldingSpaceModel* model) override;
  104. // HoldingSpaceModelObserver:
  105. void OnHoldingSpaceItemsAdded(
  106. const std::vector<const HoldingSpaceItem*>& items) override;
  107. void OnHoldingSpaceItemsRemoved(
  108. const std::vector<const HoldingSpaceItem*>& items) override;
  109. void OnHoldingSpaceItemInitialized(const HoldingSpaceItem* item) override;
  110. // SessionObserver:
  111. void OnActiveUserPrefServiceChanged(PrefService* prefs) override;
  112. void OnSessionStateChanged(session_manager::SessionState state) override;
  113. // ui::SimpleMenuModel::Delegate:
  114. void ExecuteCommand(int command_id, int event_flags) override;
  115. // views::WidgetObserver:
  116. void OnWidgetDragWillStart(views::Widget* widget) override;
  117. void OnWidgetDestroying(views::Widget* widget) override;
  118. // Registers pref change registrars for preferences relevant to the holding
  119. // space tray state.
  120. void ObservePrefService(PrefService* prefs);
  121. // Called when the state reflected in the previews icon changes - it updates
  122. // the previews icon visibility and schedules the previews icon update.
  123. void UpdatePreviewsState();
  124. // Updates the visibility of the tray icon showing item previews.
  125. // If the previews are not enabled, or the holding space is empty, the default
  126. // holding space tray icon will be shown.
  127. void UpdatePreviewsVisibility();
  128. // Schedules a task to update the list of items shown in the previews tray
  129. // icon.
  130. void SchedulePreviewsIconUpdate();
  131. // Calculates the set of items that should be added to the holding space
  132. // preview icon, and updates the icon state. No-op if previews are not
  133. // enabled.
  134. void UpdatePreviewsIcon();
  135. // Whether previews icon is currently shown. Note that if the previews
  136. // feature is disabled, this will always be false. Otherwise, previews can be
  137. // enabled/ disabled by the user at runtime.
  138. bool PreviewsShown() const;
  139. // Updates the `default_tray_icon_` to account for potential overlap with the
  140. // inner icon of the `progress_indicator_` as both may occupy the same space.
  141. void UpdateDefaultTrayIcon();
  142. // Updates this view (and its children) to reflect state as a potential drop
  143. // target. If `event` is `nullptr`, this view is *not* a drop target.
  144. // Otherwise this view is a drop target if the `event` is located within
  145. // sufficient range of its bounds and contains pinnable files.
  146. void UpdateDropTargetState(const ui::DropTargetEvent* event);
  147. // Sets whether tray visibility and previews updates should be animated.
  148. void SetShouldAnimate(bool should_animate);
  149. // Pins the dropped files `unpinned_file_paths` to the tray.
  150. void PerformDrop(std::vector<base::FilePath> unpinned_file_paths,
  151. const ui::DropTargetEvent& event,
  152. ui::mojom::DragOperation& output_drag_op);
  153. std::unique_ptr<HoldingSpaceTrayBubble> bubble_;
  154. std::unique_ptr<aura::client::DragDropClientObserver> drag_drop_observer_;
  155. // Default tray icon shown when there are no previews available (or the
  156. // previews are disabled).
  157. // Owned by views hierarchy.
  158. views::ImageView* default_tray_icon_ = nullptr;
  159. // Content forward tray icon that contains holding space item previews.
  160. // Owned by views hierarchy.
  161. HoldingSpaceTrayIcon* previews_tray_icon_ = nullptr;
  162. // The view drawn on top of all other child views to indicate that this
  163. // view is a drop target capable of handling the current drag payload.
  164. views::View* drop_target_overlay_ = nullptr;
  165. // The icon parented by the `drop_target_overlay_` to indicate that this view
  166. // is a drop target capable of handling the current drag payload.
  167. views::ImageView* drop_target_icon_ = nullptr;
  168. // Owns the `ui::Layer` which paints indication of progress for all holding
  169. // space items in the model attached to the holding space controller.
  170. // NOTE: The `ui::Layer` is *not* painted if there are no items in progress.
  171. std::unique_ptr<ProgressIndicator> progress_indicator_;
  172. // Subscription to receive notification of changes to the
  173. // `progress_indicator_`'s underlying progress.
  174. base::RepeatingClosureList::Subscription
  175. progress_indicator_progress_changed_callback_list_subscription_;
  176. // When the holding space previews feature is enabled, the user can enable/
  177. // disable previews at runtime. This registrar is associated with the active
  178. // user pref service and notifies the holding space tray icon of changes to
  179. // the user's preference.
  180. std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
  181. // Timer for updating previews shown in the content forward tray icon.
  182. base::OneShotTimer previews_update_;
  183. // Used in tests to shorten the timeout for updating previews in the content
  184. // forward tray icon.
  185. bool use_zero_previews_update_delay_ = false;
  186. // Whether the user performed a drag-and-drop to pin action. Note that this
  187. // flag is set only within the scope of a drop release event sequence. It is
  188. // otherwise always set to `false`.
  189. bool did_drop_to_pin_ = false;
  190. base::ScopedObservation<HoldingSpaceController,
  191. HoldingSpaceControllerObserver>
  192. controller_observer_{this};
  193. base::ScopedObservation<HoldingSpaceModel, HoldingSpaceModelObserver>
  194. model_observer_{this};
  195. base::ScopedObservation<SessionController, SessionObserver> session_observer_{
  196. this};
  197. base::ScopedObservation<views::Widget, views::WidgetObserver>
  198. widget_observer_{this};
  199. // Animation will be disabled for the lifetime of this variable.
  200. std::unique_ptr<base::ScopedClosureRunner> animation_disabler_;
  201. base::WeakPtrFactory<HoldingSpaceTray> weak_factory_{this};
  202. };
  203. } // namespace ash
  204. #endif // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_TRAY_H_