home_button.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright 2014 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_SHELF_HOME_BUTTON_H_
  5. #define ASH_SHELF_HOME_BUTTON_H_
  6. #include <memory>
  7. #include "ash/app_list/app_list_metrics.h"
  8. #include "ash/ash_export.h"
  9. #include "ash/shelf/home_button_controller.h"
  10. #include "ash/shelf/shelf_button_delegate.h"
  11. #include "ash/shelf/shelf_control_button.h"
  12. #include "ui/gfx/geometry/rect.h"
  13. #include "ui/views/view_targeter_delegate.h"
  14. namespace views {
  15. class AnimationBuilder;
  16. class CircleLayerDelegate;
  17. class Label;
  18. } // namespace views
  19. namespace ui {
  20. class LayerOwner;
  21. }
  22. namespace ash {
  23. class Shelf;
  24. class ShelfButtonDelegate;
  25. class ShelfNavigationWidget;
  26. // Button used for the AppList icon on the shelf. It opens the app list (in
  27. // clamshell mode) or home screen (in tablet mode). Because the clamshell-mode
  28. // app list appears like a dismissable overlay, the button is highlighted while
  29. // the app list is open in clamshell mode.
  30. //
  31. // If Assistant is enabled, the button is filled in; long-pressing it will
  32. // launch Assistant.
  33. class ASH_EXPORT HomeButton : public ShelfControlButton,
  34. public ShelfButtonDelegate,
  35. public views::ViewTargeterDelegate {
  36. public:
  37. class ScopedNoClipRect {
  38. public:
  39. explicit ScopedNoClipRect(ShelfNavigationWidget* shelf_navigation_widget);
  40. ScopedNoClipRect(const ScopedNoClipRect&) = delete;
  41. ScopedNoClipRect& operator=(const ScopedNoClipRect&) = delete;
  42. ~ScopedNoClipRect();
  43. private:
  44. ShelfNavigationWidget* const shelf_navigation_widget_;
  45. const gfx::Rect clip_rect_;
  46. };
  47. // An observer that can be used to track the nudge animation state. Currently
  48. // used in testing.
  49. class NudgeAnimationObserver : public base::CheckedObserver {
  50. public:
  51. NudgeAnimationObserver() = default;
  52. NudgeAnimationObserver(const NudgeAnimationObserver&) = delete;
  53. NudgeAnimationObserver& operator=(const NudgeAnimationObserver&) = delete;
  54. ~NudgeAnimationObserver() override = default;
  55. // Called when the nudge animation is started/ended.
  56. virtual void NudgeAnimationStarted(HomeButton* home_button) = 0;
  57. virtual void NudgeAnimationEnded(HomeButton* home_button) = 0;
  58. // Called when the nudge label is animated to fully shown.
  59. virtual void NudgeLabelShown(HomeButton* home_button) = 0;
  60. };
  61. static const char kViewClassName[];
  62. explicit HomeButton(Shelf* shelf);
  63. HomeButton(const HomeButton&) = delete;
  64. HomeButton& operator=(const HomeButton&) = delete;
  65. ~HomeButton() override;
  66. // views::View:
  67. gfx::Size CalculatePreferredSize() const override;
  68. void Layout() override;
  69. // views::Button:
  70. void OnGestureEvent(ui::GestureEvent* event) override;
  71. const char* GetClassName() const override;
  72. std::u16string GetTooltipText(const gfx::Point& p) const override;
  73. // ShelfButtonDelegate:
  74. void OnShelfButtonAboutToRequestFocusFromTabTraversal(ShelfButton* button,
  75. bool reverse) override;
  76. void ButtonPressed(views::Button* sender,
  77. const ui::Event& event,
  78. views::InkDrop* ink_drop) override;
  79. // Called when the availability of a long-press gesture may have changed, e.g.
  80. // when Assistant becomes enabled.
  81. void OnAssistantAvailabilityChanged();
  82. // True if the app list is shown for the display containing this button.
  83. bool IsShowingAppList() const;
  84. // Called when a locale change is detected. Updates the button tooltip and
  85. // accessible name.
  86. void HandleLocaleChange();
  87. // Returns the display which contains this view.
  88. int64_t GetDisplayId() const;
  89. // Clip rect of this view's widget will be removed during the life time of the
  90. // returned ScopedNoClipRect.
  91. [[nodiscard]] std::unique_ptr<ScopedNoClipRect> CreateScopedNoClipRect();
  92. // Checks if the `nudge_label_` can be shown for the launcher nudge.
  93. // NOTE: This must be called after `CreateNudgeLabel()`, where the
  94. // `nudge_label_` is created. This is because whether the nudge can be shown
  95. // depends on nudge_label_'s preferred size.
  96. bool CanShowNudgeLabel() const;
  97. // Starts the launcher nudge animation.
  98. void StartNudgeAnimation();
  99. void AddNudgeAnimationObserverForTest(NudgeAnimationObserver* observer);
  100. void RemoveNudgeAnimationObserverForTest(NudgeAnimationObserver* observer);
  101. views::View* label_container_for_test() const { return label_container_; }
  102. protected:
  103. // views::Button:
  104. void PaintButtonContents(gfx::Canvas* canvas) override;
  105. void OnThemeChanged() override;
  106. private:
  107. // Creates `nudge_label_` for launcher nudge.
  108. void CreateNudgeLabel();
  109. // Animation functions for launcher nudge.
  110. void AnimateNudgeRipple(views::AnimationBuilder& builder);
  111. void AnimateNudgeBounce(views::AnimationBuilder& builder);
  112. void AnimateNudgeLabelSlideIn(views::AnimationBuilder& builder);
  113. void AnimateNudgeLabelSlideOut();
  114. void AnimateNudgeLabelFadeOut();
  115. // Callbacks for the nudge animation.
  116. void OnNudgeAnimationStarted();
  117. void OnNudgeAnimationEnded();
  118. void OnLabelSlideInAnimationEnded();
  119. void OnLabelFadeOutAnimationEnded();
  120. // Removes the nudge label from the view hierarchy.
  121. void RemoveNudgeLabel();
  122. // views::ViewTargeterDelegate:
  123. bool DoesIntersectRect(const views::View* target,
  124. const gfx::Rect& rect) const override;
  125. Shelf* const shelf_;
  126. // The controller used to determine the button's behavior.
  127. HomeButtonController controller_;
  128. // The ripple layer in the launcher nudge animation. Only exists during the
  129. // nudge animation.
  130. ui::LayerOwner nudge_ripple_layer_;
  131. // The label view and for launcher nudge animation.
  132. views::Label* nudge_label_ = nullptr;
  133. // The container of `nudge_label_`. This is also responsible for painting the
  134. // background of the label.
  135. views::View* label_container_ = nullptr;
  136. // The timer that counts down to hide the nudge_label_ from showing state.
  137. base::OneShotTimer label_nudge_timer_;
  138. // The delegate used by |nudge_ripple_layer_|. Only exists during the
  139. // nudge animation.
  140. std::unique_ptr<views::CircleLayerDelegate> ripple_layer_delegate_;
  141. std::unique_ptr<ScopedNoClipRect> scoped_no_clip_rect_;
  142. base::ObserverList<NudgeAnimationObserver> observers_;
  143. base::WeakPtrFactory<HomeButton> weak_ptr_factory_{this};
  144. };
  145. } // namespace ash
  146. #endif // ASH_SHELF_HOME_BUTTON_H_