progress_indicator.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright 2021 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_PROGRESS_INDICATOR_PROGRESS_INDICATOR_H_
  5. #define ASH_SYSTEM_PROGRESS_INDICATOR_PROGRESS_INDICATOR_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "ash/ash_export.h"
  9. #include "base/callback_list.h"
  10. #include "third_party/abseil-cpp/absl/types/optional.h"
  11. #include "ui/compositor/layer_delegate.h"
  12. #include "ui/compositor/layer_owner.h"
  13. namespace ash {
  14. class ProgressIconAnimation;
  15. class ProgressIndicatorAnimationRegistry;
  16. class ProgressRingAnimation;
  17. // A class owning a `ui::Layer` which paints indication of progress.
  18. // NOTE: The owned `layer()` is not painted if progress == `1.f`.
  19. class ASH_EXPORT ProgressIndicator : public ui::LayerOwner,
  20. public ui::LayerDelegate {
  21. public:
  22. static constexpr char kClassName[] = "ProgressIndicator";
  23. static constexpr float kProgressComplete = 1.f;
  24. ProgressIndicator(const ProgressIndicator&) = delete;
  25. ProgressIndicator& operator=(const ProgressIndicator&) = delete;
  26. ~ProgressIndicator() override;
  27. // Returns an instance which paints indication of progress returned by the
  28. // specified `progress_callback`. NOTE: This instance comes pre-wired with an
  29. // `animation_registry_` that will manage progress animations as needed.
  30. static std::unique_ptr<ProgressIndicator> CreateDefaultInstance(
  31. base::RepeatingCallback<absl::optional<float>()> progress_callback);
  32. // Adds the specified `callback` to be notified of `progress_` changes. The
  33. // `callback` will continue to receive events so long as both `this` and the
  34. // returned subscription exist.
  35. base::CallbackListSubscription AddProgressChangedCallback(
  36. base::RepeatingClosureList::CallbackType callback);
  37. // Creates and returns the `layer()` which is owned by this progress
  38. // indicator. Note that this may only be called if `layer()` does not exist.
  39. ui::Layer* CreateLayer();
  40. // Destroys the `layer()` which is owned by this progress indicator. Note that
  41. // this will no-op if `layer()` does not exist.
  42. void DestroyLayer();
  43. // Invoke to schedule repaint of the entire `layer()`.
  44. void InvalidateLayer();
  45. // Sets the visibility for this progress indicator's inner icon. Note that
  46. // the inner icon will only be painted while `progress_` is incomplete,
  47. // regardless of the value of `visible` provided.
  48. void SetInnerIconVisible(bool visible);
  49. bool inner_icon_visible() const { return inner_icon_visible_; }
  50. // Returns the underlying `animation_registry_` in which to look up animations
  51. // for the associated `animation_key_`. NOTE: This may return `nullptr`.
  52. ProgressIndicatorAnimationRegistry* animation_registry() {
  53. return animation_registry_;
  54. }
  55. // Returns the `animation_key_` for which to look up animations in the
  56. // underlying `animation_registry_`. NOTE: This may return `nullptr`.
  57. const void* animation_key() const { return animation_key_; }
  58. // Returns the underlying `progress_` for which to paint indication.
  59. // NOTE: If absent, progress is indeterminate.
  60. // NOTE: If present, progress must be >= `0.f` and <= `1.f`.
  61. const absl::optional<float>& progress() const { return progress_; }
  62. protected:
  63. // Each progress indicator is associated with an `animation_key_` which is
  64. // used to look up animations in the provided `animation_registry`. When an
  65. // animation exists, it will be painted in lieu of the determinate progress
  66. // indication that would otherwise be painted for the cached `progress_`.
  67. // NOTE: `animation_registry` may be `nullptr` if animations are not needed.
  68. ProgressIndicator(ProgressIndicatorAnimationRegistry* animation_registry,
  69. const void* animation_key);
  70. // Returns the calculated progress to paint to the owned `layer()`. This is
  71. // invoked during `UpdateVisualState()` just prior to painting.
  72. // NOTE: If absent, progress is indeterminate.
  73. // NOTE: If present, progress must be >= `0.f` and <= `1.f`.
  74. // NOTE: If progress == `1.f`, progress is complete and will not be painted.
  75. virtual absl::optional<float> CalculateProgress() const = 0;
  76. private:
  77. // ui::LayerDelegate:
  78. void OnDeviceScaleFactorChanged(float old_scale, float new_scale) override;
  79. void OnPaintLayer(const ui::PaintContext& context) override;
  80. void UpdateVisualState() override;
  81. // Invoked when the icon `animation` associated with this progress indicator's
  82. // `animation_key_` has changed in the `animation_registry_`.
  83. // NOTE: The specified `animation` may be `nullptr`.
  84. void OnProgressIconAnimationChanged(ProgressIconAnimation* animation);
  85. // Invoked when the ring `animation` associated with this progress indicator's
  86. // `animation_key_` has changed in the `animation_registry_`.
  87. // NOTE: The specified `animation` may be `nullptr`.
  88. void OnProgressRingAnimationChanged(ProgressRingAnimation* animation);
  89. // The animation registry in which to look up animations for the associated
  90. // `animation_key_`. When an animation exists, it will be painted in lieu of
  91. // the determinate progress indication that would otherwise be painted for the
  92. // cached `progress_`.
  93. ProgressIndicatorAnimationRegistry* const animation_registry_;
  94. // The key for which to look up animations in the `animation_registry_`.
  95. // When an animation exists, it will be painted in lieu of the determinate
  96. // progress indication that would otherwise be painted for the cached
  97. // `progress_`.
  98. const void* const animation_key_;
  99. // A subscription to receive events when the icon animation associated with
  100. // this progress indicator's `animation_key_` has changed in the
  101. // `animation_registry_`.
  102. base::CallbackListSubscription icon_animation_changed_subscription_;
  103. // A subscription to receive events on updates to the icon animation owned by
  104. // the `animation_registry_` which is associated with this progress
  105. // indicator's `animation_key_`. On icon animation update, the progress
  106. // indicator will `InvalidateLayer()` to trigger paint of the next animation
  107. // frame.
  108. base::CallbackListSubscription icon_animation_updated_subscription_;
  109. // A subscription to receive events when the ring animation associated with
  110. // this progress indicator's `animation_key_` has changed in the
  111. // `animation_registry_`.
  112. base::CallbackListSubscription ring_animation_changed_subscription_;
  113. // A subscription to receive events on updates to the ring animation owned by
  114. // the `animation_registry_` which is associated with this progress
  115. // indicator's `animation_key_`. On ring animation update, the progress
  116. // indicator will `InvalidateLayer()` to trigger paint of the next animation
  117. // frame.
  118. base::CallbackListSubscription ring_animation_updated_subscription_;
  119. // Cached progress returned from `CalculateProgress()` just prior to painting.
  120. // NOTE: If absent, progress is indeterminate.
  121. // NOTE: If present, progress must be >= `0.f` and <= `1.f`.
  122. absl::optional<float> progress_;
  123. // The list of callbacks for which to notify `progress_` changes.
  124. base::RepeatingClosureList progress_changed_callback_list_;
  125. // Whether this progress indicator's inner icon is visible. Note that the
  126. // inner icon will only be painted while `progress_` is incomplete, regardless
  127. // of this value.
  128. bool inner_icon_visible_ = true;
  129. };
  130. } // namespace ash
  131. #endif // ASH_SYSTEM_PROGRESS_INDICATOR_PROGRESS_INDICATOR_H_