tray_background_view.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. // Copyright (c) 2012 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_TRAY_TRAY_BACKGROUND_VIEW_H_
  5. #define ASH_SYSTEM_TRAY_TRAY_BACKGROUND_VIEW_H_
  6. #include <memory>
  7. #include "ash/ash_export.h"
  8. #include "ash/shelf/shelf_background_animator_observer.h"
  9. #include "ash/system/model/virtual_keyboard_model.h"
  10. #include "ash/system/tray/actionable_view.h"
  11. #include "ash/system/tray/tray_bubble_view.h"
  12. #include "ash/system/user/login_status.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "ui/gfx/geometry/insets.h"
  15. #include "ui/views/context_menu_controller.h"
  16. namespace ui {
  17. enum MenuSourceType;
  18. } // namespace ui
  19. namespace views {
  20. class MenuRunner;
  21. class View;
  22. } // namespace views
  23. namespace ash {
  24. class Shelf;
  25. class TrayContainer;
  26. class TrayEventFilter;
  27. // Base class for some children of StatusAreaWidget. This class handles setting
  28. // and animating the background when the Launcher is shown/hidden. It also
  29. // inherits from ActionableView so that the tray items can override
  30. // PerformAction when clicked on.
  31. class ASH_EXPORT TrayBackgroundView : public ActionableView,
  32. public views::ContextMenuController,
  33. public ShelfBackgroundAnimatorObserver,
  34. public TrayBubbleView::Delegate,
  35. public VirtualKeyboardModel::Observer {
  36. public:
  37. METADATA_HEADER(TrayBackgroundView);
  38. enum RoundedCornerBehavior {
  39. kNotRounded,
  40. kStartRounded,
  41. kEndRounded,
  42. kAllRounded
  43. };
  44. TrayBackgroundView(Shelf* shelf,
  45. RoundedCornerBehavior corner_behavior = kAllRounded);
  46. TrayBackgroundView(const TrayBackgroundView&) = delete;
  47. TrayBackgroundView& operator=(const TrayBackgroundView&) = delete;
  48. ~TrayBackgroundView() override;
  49. // Called after the tray has been added to the widget containing it.
  50. virtual void Initialize();
  51. // Initializes animations for the bubble. This contains only a fade out
  52. // animation that hides `bubble_widget` when it becomes invisible.
  53. static void InitializeBubbleAnimations(views::Widget* bubble_widget);
  54. // ActionableView:
  55. void OnThemeChanged() override;
  56. // VirtualKeyboardModel::Observer:
  57. void OnVirtualKeyboardVisibilityChanged() override;
  58. // Returns the associated tray bubble view, if one exists. Otherwise returns
  59. // nullptr.
  60. virtual TrayBubbleView* GetBubbleView();
  61. // Returns the associated tray bubble widget, if a bubble exists. Otherwise
  62. // returns nullptr.
  63. virtual views::Widget* GetBubbleWidget() const;
  64. // Returns a lock that prevents window activation from closing bubbles.
  65. [[nodiscard]] static base::ScopedClosureRunner
  66. DisableCloseBubbleOnWindowActivated();
  67. // Whether a window activation change should close bubbles.
  68. static bool ShouldCloseBubbleOnWindowActivated();
  69. // Closes the associated tray bubble view if it exists and is currently
  70. // showing.
  71. virtual void CloseBubble() {}
  72. // Shows the associated tray bubble if one exists. |show_by_click| indicates
  73. // whether the showing operation is initiated by mouse or gesture click.
  74. virtual void ShowBubble();
  75. // Calculates the ideal bounds that this view should have depending on the
  76. // constraints.
  77. virtual void CalculateTargetBounds();
  78. // Makes this view's bounds and layout match its calculated target bounds.
  79. virtual void UpdateLayout();
  80. // Called to update the tray button after the login status changes.
  81. virtual void UpdateAfterLoginStatusChange();
  82. // Called whenever the status area's collapse state changes.
  83. virtual void UpdateAfterStatusAreaCollapseChange();
  84. // Called when the anchor (tray or bubble) may have moved or changed.
  85. virtual void AnchorUpdated() {}
  86. // Called from GetAccessibleNodeData, must return a valid accessible name.
  87. virtual std::u16string GetAccessibleNameForTray() = 0;
  88. // Called when a locale change is detected. It should reload any strings the
  89. // view may be using. Note that the locale is not expected to change after the
  90. // user logs in.
  91. virtual void HandleLocaleChange() = 0;
  92. // Called when the bubble is resized.
  93. virtual void BubbleResized(const TrayBubbleView* bubble_view);
  94. // Updates this bubble about visibility change of *ANY* tray bubble
  95. // including itself.
  96. // `bubble_widget` is the bubble with visibility change. Please note that it
  97. // can be the current bubble as well.
  98. virtual void OnAnyBubbleVisibilityChanged(views::Widget* bubble_widget,
  99. bool visible);
  100. // Hides the bubble associated with |bubble_view|. Called when the widget
  101. // is closed.
  102. virtual void HideBubbleWithView(const TrayBubbleView* bubble_view) = 0;
  103. // Called by the bubble wrapper when a click event occurs outside the bubble.
  104. // May close the bubble.
  105. virtual void ClickedOutsideBubble() = 0;
  106. // Updates the background layer.
  107. virtual void UpdateBackground();
  108. void SetIsActive(bool is_active);
  109. bool is_active() const { return is_active_; }
  110. TrayContainer* tray_container() const { return tray_container_; }
  111. TrayEventFilter* tray_event_filter() { return tray_event_filter_.get(); }
  112. Shelf* shelf() { return shelf_; }
  113. // Updates the visibility of this tray's separator.
  114. void set_separator_visibility(bool visible) { separator_visible_ = visible; }
  115. // Sets whether to show the view when the status area is collapsed.
  116. void set_show_when_collapsed(bool show_when_collapsed) {
  117. show_when_collapsed_ = show_when_collapsed;
  118. }
  119. // Gets the anchor for bubbles, which is tray_container().
  120. views::View* GetBubbleAnchor() const;
  121. // Gets additional insets for positioning bubbles relative to
  122. // tray_container().
  123. gfx::Insets GetBubbleAnchorInsets() const;
  124. // Returns the container window for the bubble (on the proper display).
  125. aura::Window* GetBubbleWindowContainer();
  126. // Helper function that calculates background bounds relative to local bounds
  127. // based on background insets returned from GetBackgroundInsets().
  128. gfx::Rect GetBackgroundBounds() const;
  129. // ActionableView:
  130. bool PerformAction(const ui::Event& event) override;
  131. // Sets whether the tray item should be shown by default (e.g. it is
  132. // activated). The effective visibility of the tray item is determined by the
  133. // current state of the status tray (i.e. whether the virtual keyboard is
  134. // showing or if it is collapsed).
  135. virtual void SetVisiblePreferred(bool visible_preferred);
  136. bool visible_preferred() const { return visible_preferred_; }
  137. // Disables bounce in and fade in animation. The animation will remain
  138. // disabled until the returned scoped closure runner is run.
  139. [[nodiscard]] base::ScopedClosureRunner DisableShowAnimation();
  140. // Returns true if the view is showing a context menu.
  141. bool IsShowingMenu() const;
  142. // Set the rounded corner behavior for this tray item.
  143. void SetRoundedCornerBehavior(RoundedCornerBehavior corner_behavior);
  144. // Returns the corners based on the `corner_behavior_`;
  145. gfx::RoundedCornersF GetRoundedCorners();
  146. protected:
  147. // ActionableView:
  148. void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
  149. bool ShouldEnterPushedState(const ui::Event& event) override;
  150. void HandlePerformActionResult(bool action_performed,
  151. const ui::Event& event) override;
  152. views::PaintInfo::ScaleType GetPaintScaleType() const override;
  153. virtual void OnShouldShowAnimationChanged(bool should_animate) {}
  154. // Specifies the menu that appears when this tray is right-clicked if
  155. // `SetContextMenuEnabled(true)` has been called. Default implementation
  156. // returns a nullptr, in which case no context menu is shown.
  157. virtual std::unique_ptr<ui::SimpleMenuModel> CreateContextMenuModel();
  158. void SetContextMenuEnabled(bool should_enable_menu) {
  159. set_context_menu_controller(should_enable_menu ? this : nullptr);
  160. }
  161. void set_show_with_virtual_keyboard(bool show_with_virtual_keyboard) {
  162. show_with_virtual_keyboard_ = show_with_virtual_keyboard;
  163. }
  164. void set_use_bounce_in_animation(bool use_bounce_in_animation) {
  165. use_bounce_in_animation_ = use_bounce_in_animation;
  166. }
  167. private:
  168. class TrayWidgetObserver;
  169. class TrayBackgroundViewSessionChangeHandler;
  170. void StartVisibilityAnimation(bool visible);
  171. // Updates status area widget by calling `UpdateCollapseState()` and
  172. // `LogVisiblePodCountMetric()`.
  173. void UpdateStatusArea(bool should_log_visible_pod_count);
  174. // After hide animation is finished/aborted/removed, we will need to do an
  175. // update to the view's visibility and the view's status area widget state.
  176. void OnVisibilityAnimationFinished(bool should_log_visible_pod_count,
  177. bool aborted);
  178. // views::ContextMenuController:
  179. void ShowContextMenuForViewImpl(views::View* source,
  180. const gfx::Point& point,
  181. ui::MenuSourceType source_type) override;
  182. // views::View:
  183. void AboutToRequestFocusFromTabTraversal(bool reverse) override;
  184. void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  185. void ChildPreferredSizeChanged(views::View* child) override;
  186. // In some cases, we expect the layer's visibility to be set to false right
  187. // away when the layer is replaced. See
  188. // `OverviewButtonTrayTest.HideAnimationAlwaysCompletesOnDelete` test as an
  189. // example. We use `::wm::RecreateLayers(root_window)` to create fresh layers
  190. // for the window. If we don't override this method, the old layer and its
  191. // child layers will still be there until all the animation finished.
  192. std::unique_ptr<ui::Layer> RecreateLayer() override;
  193. // Callbacks for Animations
  194. void OnAnimationAborted();
  195. void OnAnimationEnded();
  196. // Applies transformations to the |layer()| to animate the view when
  197. // SetVisible(false) is called.
  198. void HideAnimation();
  199. void FadeInAnimation();
  200. void BounceInAnimation();
  201. // Helper function that calculates background insets relative to local bounds.
  202. gfx::Insets GetBackgroundInsets() const;
  203. // Returns the effective visibility of the tray item based on the current
  204. // state.
  205. bool GetEffectiveVisibility();
  206. // Checks if we should show bounce in or fade in animation.
  207. bool IsShowAnimationEnabled() const {
  208. return disable_show_animation_count_ == 0u;
  209. }
  210. // The shelf containing the system tray for this view.
  211. Shelf* shelf_;
  212. // Convenience pointer to the contents view.
  213. TrayContainer* tray_container_;
  214. // Determines if the view is active. This changes how the ink drop ripples
  215. // behave.
  216. bool is_active_;
  217. // Visibility of this tray's separator which is a line of 1x32px and 4px to
  218. // right of tray.
  219. bool separator_visible_;
  220. // During virtual keyboard is shown, visibility changes to TrayBackgroundView
  221. // are ignored. In such case, preferred visibility is reflected after the
  222. // virtual keyboard is hidden.
  223. bool visible_preferred_;
  224. // If true, the view always shows up when virtual keyboard is visible.
  225. bool show_with_virtual_keyboard_;
  226. // If true, the view is visible when the status area is collapsed.
  227. bool show_when_collapsed_;
  228. bool use_bounce_in_animation_ = true;
  229. bool is_starting_animation_ = false;
  230. // Number of active requests to disable the bounce-in and fade-in animation.
  231. size_t disable_show_animation_count_ = 0;
  232. // The shape of this tray which is only applied to the horizontal tray.
  233. // Defaults to `kAllRounded`.
  234. RoundedCornerBehavior corner_behavior_;
  235. std::unique_ptr<TrayWidgetObserver> widget_observer_;
  236. std::unique_ptr<TrayEventFilter> tray_event_filter_;
  237. std::unique_ptr<TrayBackgroundViewSessionChangeHandler> handler_;
  238. std::unique_ptr<ui::SimpleMenuModel> context_menu_model_;
  239. std::unique_ptr<views::MenuRunner> context_menu_runner_;
  240. base::WeakPtrFactory<TrayBackgroundView> weak_factory_{this};
  241. };
  242. } // namespace ash
  243. #endif // ASH_SYSTEM_TRAY_TRAY_BACKGROUND_VIEW_H_