shelf_app_button.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright 2013 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_SHELF_APP_BUTTON_H_
  5. #define ASH_SHELF_SHELF_APP_BUTTON_H_
  6. #include "ash/ash_export.h"
  7. #include "ash/public/cpp/shelf_types.h"
  8. #include "ash/shelf/shelf_button.h"
  9. #include "ash/shelf/shelf_button_delegate.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "base/timer/timer.h"
  12. #include "ui/compositor/layer_animation_observer.h"
  13. #include "ui/gfx/shadow_value.h"
  14. #include "ui/views/animation/ink_drop_observer.h"
  15. #include "ui/views/animation/ink_drop_state.h"
  16. namespace views {
  17. class ImageView;
  18. } // namespace views
  19. namespace ash {
  20. struct ShelfItem;
  21. class DotIndicator;
  22. class ShelfView;
  23. // Button used for app shortcuts on the shelf..
  24. class ASH_EXPORT ShelfAppButton : public ShelfButton,
  25. public views::InkDropObserver,
  26. public ui::ImplicitAnimationObserver {
  27. public:
  28. static const char kViewClassName[];
  29. // Used to indicate the current state of the button.
  30. enum State {
  31. // Nothing special. Usually represents an app shortcut item with no running
  32. // instance.
  33. STATE_NORMAL = 0,
  34. // Button has mouse hovering on it.
  35. STATE_HOVERED = 1 << 0,
  36. // Underlying ShelfItem has a running instance.
  37. STATE_RUNNING = 1 << 1,
  38. // Underlying ShelfItem needs user's attention.
  39. STATE_ATTENTION = 1 << 2,
  40. // Hide the status (temporarily for some animations).
  41. STATE_HIDDEN = 1 << 3,
  42. // Button is being dragged.
  43. STATE_DRAGGING = 1 << 4,
  44. // App has at least 1 notification.
  45. STATE_NOTIFICATION = 1 << 5,
  46. // Underlying ShelfItem owns the window that is currently active.
  47. STATE_ACTIVE = 1 << 6,
  48. };
  49. // Returns whether |event| should be handled by a ShelfAppButton if a context
  50. // menu for the view is shown. Note that the context menu controller will
  51. // redirect gesture events to the hotseat widget if the context menu was shown
  52. // for a ShelfAppButton). The hotseat widget uses this method to determine
  53. // whether such events can/should be dropped without handling.
  54. static bool ShouldHandleEventFromContextMenu(const ui::GestureEvent* event);
  55. ShelfAppButton(ShelfView* shelf_view,
  56. ShelfButtonDelegate* shelf_button_delegate);
  57. ShelfAppButton(const ShelfAppButton&) = delete;
  58. ShelfAppButton& operator=(const ShelfAppButton&) = delete;
  59. ~ShelfAppButton() override;
  60. // Sets the image to display for this entry.
  61. void SetImage(const gfx::ImageSkia& image);
  62. // Retrieve the image to show proxy operations.
  63. gfx::ImageSkia GetImage() const;
  64. // Gets the resized `icon_image_` without the shadow.
  65. gfx::ImageSkia GetIconImage() const;
  66. // |state| is or'd into the current state.
  67. void AddState(State state);
  68. void ClearState(State state);
  69. int state() const { return state_; }
  70. // Clears drag drag state that might have been set by gesture handling when a
  71. // gesture ends. No-op if the drag state has already been cleared.
  72. void ClearDragStateOnGestureEnd();
  73. // Returns the bounds of the icon.
  74. gfx::Rect GetIconBounds() const;
  75. // Returns the ideal icon bounds within the button view of the provided size,
  76. // and with the provided icon scale.
  77. gfx::Rect GetIdealIconBounds(const gfx::Size& button_size,
  78. float icon_scale) const;
  79. views::InkDrop* GetInkDropForTesting();
  80. // Called when user started dragging the shelf button.
  81. void OnDragStarted(const ui::LocatedEvent* event);
  82. // Callback used when a menu for this ShelfAppButton is closed.
  83. void OnMenuClosed();
  84. // views::Button overrides:
  85. void ShowContextMenu(const gfx::Point& p,
  86. ui::MenuSourceType source_type) override;
  87. void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  88. bool ShouldEnterPushedState(const ui::Event& event) override;
  89. // views::View overrides:
  90. const char* GetClassName() const override;
  91. bool OnMousePressed(const ui::MouseEvent& event) override;
  92. void OnMouseReleased(const ui::MouseEvent& event) override;
  93. void OnMouseCaptureLost() override;
  94. bool OnMouseDragged(const ui::MouseEvent& event) override;
  95. void Layout() override;
  96. void ChildPreferredSizeChanged(views::View* child) override;
  97. // Update button state from ShelfItem.
  98. void ReflectItemStatus(const ShelfItem& item);
  99. // Returns whether the icon size is up to date.
  100. bool IsIconSizeCurrent();
  101. // Called when the request for the context menu model is canceled.
  102. void OnContextMenuModelRequestCanceled();
  103. bool FireDragTimerForTest();
  104. void FireRippleActivationTimerForTest();
  105. // Return the bounds in the local coordinates enclosing the small ripple area.
  106. gfx::Rect CalculateSmallRippleArea() const;
  107. void SetNotificationBadgeColor(SkColor color);
  108. protected:
  109. // ui::EventHandler:
  110. void OnGestureEvent(ui::GestureEvent* event) override;
  111. // ui::ImplicitAnimationObserver:
  112. void OnImplicitAnimationsCompleted() override;
  113. // Sets the icon image with a shadow.
  114. void SetShadowedImage(const gfx::ImageSkia& bitmap);
  115. private:
  116. class AppNotificationIndicatorView;
  117. class AppStatusIndicatorView;
  118. // views::View:
  119. bool HandleAccessibleAction(const ui::AXActionData& action_data) override;
  120. // views::InkDropObserver:
  121. void InkDropAnimationStarted() override;
  122. void InkDropRippleAnimationEnded(views::InkDropState state) override;
  123. // Updates the parts of the button to reflect the current |state_| and
  124. // alignment. This may add or remove views, layout and paint.
  125. void UpdateState();
  126. // Invoked when |touch_drag_timer_| fires to show dragging UI.
  127. void OnTouchDragTimer();
  128. // Invoked when |ripple_activation_timer_| fires to activate the ink drop.
  129. void OnRippleTimer();
  130. // Calculates the preferred size of the icon.
  131. gfx::Size GetPreferredIconSize() const;
  132. // Scales up app icon if |scale_up| is true, otherwise scales it back to
  133. // normal size.
  134. void ScaleAppIcon(bool scale_up);
  135. // Calculates the icon bounds for an icon scaled by |icon_scale|.
  136. gfx::Rect GetIconViewBounds(const gfx::Rect& button_bounds,
  137. float icon_scale) const;
  138. // Calculates the notification indicator bounds when scaled by |scale|.
  139. gfx::Rect GetNotificationIndicatorBounds(float scale);
  140. // Calculates the transform between the icon scaled by |icon_scale| and the
  141. // normal size icon.
  142. gfx::Transform GetScaleTransform(float icon_scale);
  143. // Marks whether the ink drop animation has started or not.
  144. void SetInkDropAnimationStarted(bool started);
  145. // Maybe hides the ink drop at the end of gesture handling.
  146. void MaybeHideInkDropWhenGestureEnds();
  147. // The icon part of a button can be animated independently of the rest.
  148. views::ImageView* const icon_view_;
  149. // The ShelfView showing this ShelfAppButton. Owned by RootWindowController.
  150. ShelfView* const shelf_view_;
  151. // Draws an indicator underneath the image to represent the state of the
  152. // application.
  153. AppStatusIndicatorView* const indicator_;
  154. // Draws an indicator in the top right corner of the image to represent an
  155. // active notification.
  156. DotIndicator* notification_indicator_ = nullptr;
  157. // The current application state, a bitfield of State enum values.
  158. int state_ = STATE_NORMAL;
  159. gfx::ShadowValues icon_shadows_;
  160. // The bitmap image for this app button.
  161. gfx::ImageSkia icon_image_;
  162. // The scaling factor for displaying the app icon.
  163. float icon_scale_ = 1.0f;
  164. // App status.
  165. AppStatus app_status_ = AppStatus::kReady;
  166. // Indicates whether the ink drop animation starts.
  167. bool ink_drop_animation_started_ = false;
  168. // A timer to defer showing drag UI when the shelf button is pressed.
  169. base::OneShotTimer drag_timer_;
  170. // A timer to activate the ink drop ripple during a long press.
  171. base::OneShotTimer ripple_activation_timer_;
  172. // The target visibility of the shelf app's context menu.
  173. // NOTE: when `context_menu_target_visibility_` is true, the context menu may
  174. // not show yet due to the async request for the menu model.
  175. bool context_menu_target_visibility_ = false;
  176. std::unique_ptr<ShelfButtonDelegate::ScopedActiveInkDropCount>
  177. ink_drop_count_;
  178. // Used to track whether the menu was deleted while running. Must be last.
  179. base::WeakPtrFactory<ShelfAppButton> weak_factory_{this};
  180. };
  181. } // namespace ash
  182. #endif // ASH_SHELF_SHELF_APP_BUTTON_H_