123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef ASH_SYSTEM_PROGRESS_INDICATOR_PROGRESS_INDICATOR_H_
- #define ASH_SYSTEM_PROGRESS_INDICATOR_PROGRESS_INDICATOR_H_
- #include <memory>
- #include <vector>
- #include "ash/ash_export.h"
- #include "base/callback_list.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "ui/compositor/layer_delegate.h"
- #include "ui/compositor/layer_owner.h"
- namespace ash {
- class ProgressIconAnimation;
- class ProgressIndicatorAnimationRegistry;
- class ProgressRingAnimation;
- // A class owning a `ui::Layer` which paints indication of progress.
- // NOTE: The owned `layer()` is not painted if progress == `1.f`.
- class ASH_EXPORT ProgressIndicator : public ui::LayerOwner,
- public ui::LayerDelegate {
- public:
- static constexpr char kClassName[] = "ProgressIndicator";
- static constexpr float kProgressComplete = 1.f;
- ProgressIndicator(const ProgressIndicator&) = delete;
- ProgressIndicator& operator=(const ProgressIndicator&) = delete;
- ~ProgressIndicator() override;
- // Returns an instance which paints indication of progress returned by the
- // specified `progress_callback`. NOTE: This instance comes pre-wired with an
- // `animation_registry_` that will manage progress animations as needed.
- static std::unique_ptr<ProgressIndicator> CreateDefaultInstance(
- base::RepeatingCallback<absl::optional<float>()> progress_callback);
- // Adds the specified `callback` to be notified of `progress_` changes. The
- // `callback` will continue to receive events so long as both `this` and the
- // returned subscription exist.
- base::CallbackListSubscription AddProgressChangedCallback(
- base::RepeatingClosureList::CallbackType callback);
- // Creates and returns the `layer()` which is owned by this progress
- // indicator. Note that this may only be called if `layer()` does not exist.
- ui::Layer* CreateLayer();
- // Destroys the `layer()` which is owned by this progress indicator. Note that
- // this will no-op if `layer()` does not exist.
- void DestroyLayer();
- // Invoke to schedule repaint of the entire `layer()`.
- void InvalidateLayer();
- // Sets the visibility for this progress indicator's inner icon. Note that
- // the inner icon will only be painted while `progress_` is incomplete,
- // regardless of the value of `visible` provided.
- void SetInnerIconVisible(bool visible);
- bool inner_icon_visible() const { return inner_icon_visible_; }
- // Returns the underlying `animation_registry_` in which to look up animations
- // for the associated `animation_key_`. NOTE: This may return `nullptr`.
- ProgressIndicatorAnimationRegistry* animation_registry() {
- return animation_registry_;
- }
- // Returns the `animation_key_` for which to look up animations in the
- // underlying `animation_registry_`. NOTE: This may return `nullptr`.
- const void* animation_key() const { return animation_key_; }
- // Returns the underlying `progress_` for which to paint indication.
- // NOTE: If absent, progress is indeterminate.
- // NOTE: If present, progress must be >= `0.f` and <= `1.f`.
- const absl::optional<float>& progress() const { return progress_; }
- protected:
- // Each progress indicator is associated with an `animation_key_` which is
- // used to look up animations in the provided `animation_registry`. When an
- // animation exists, it will be painted in lieu of the determinate progress
- // indication that would otherwise be painted for the cached `progress_`.
- // NOTE: `animation_registry` may be `nullptr` if animations are not needed.
- ProgressIndicator(ProgressIndicatorAnimationRegistry* animation_registry,
- const void* animation_key);
- // Returns the calculated progress to paint to the owned `layer()`. This is
- // invoked during `UpdateVisualState()` just prior to painting.
- // NOTE: If absent, progress is indeterminate.
- // NOTE: If present, progress must be >= `0.f` and <= `1.f`.
- // NOTE: If progress == `1.f`, progress is complete and will not be painted.
- virtual absl::optional<float> CalculateProgress() const = 0;
- private:
- // ui::LayerDelegate:
- void OnDeviceScaleFactorChanged(float old_scale, float new_scale) override;
- void OnPaintLayer(const ui::PaintContext& context) override;
- void UpdateVisualState() override;
- // Invoked when the icon `animation` associated with this progress indicator's
- // `animation_key_` has changed in the `animation_registry_`.
- // NOTE: The specified `animation` may be `nullptr`.
- void OnProgressIconAnimationChanged(ProgressIconAnimation* animation);
- // Invoked when the ring `animation` associated with this progress indicator's
- // `animation_key_` has changed in the `animation_registry_`.
- // NOTE: The specified `animation` may be `nullptr`.
- void OnProgressRingAnimationChanged(ProgressRingAnimation* animation);
- // The animation registry in which to look up animations for the associated
- // `animation_key_`. When an animation exists, it will be painted in lieu of
- // the determinate progress indication that would otherwise be painted for the
- // cached `progress_`.
- ProgressIndicatorAnimationRegistry* const animation_registry_;
- // The key for which to look up animations in the `animation_registry_`.
- // When an animation exists, it will be painted in lieu of the determinate
- // progress indication that would otherwise be painted for the cached
- // `progress_`.
- const void* const animation_key_;
- // A subscription to receive events when the icon animation associated with
- // this progress indicator's `animation_key_` has changed in the
- // `animation_registry_`.
- base::CallbackListSubscription icon_animation_changed_subscription_;
- // A subscription to receive events on updates to the icon animation owned by
- // the `animation_registry_` which is associated with this progress
- // indicator's `animation_key_`. On icon animation update, the progress
- // indicator will `InvalidateLayer()` to trigger paint of the next animation
- // frame.
- base::CallbackListSubscription icon_animation_updated_subscription_;
- // A subscription to receive events when the ring animation associated with
- // this progress indicator's `animation_key_` has changed in the
- // `animation_registry_`.
- base::CallbackListSubscription ring_animation_changed_subscription_;
- // A subscription to receive events on updates to the ring animation owned by
- // the `animation_registry_` which is associated with this progress
- // indicator's `animation_key_`. On ring animation update, the progress
- // indicator will `InvalidateLayer()` to trigger paint of the next animation
- // frame.
- base::CallbackListSubscription ring_animation_updated_subscription_;
- // Cached progress returned from `CalculateProgress()` just prior to painting.
- // NOTE: If absent, progress is indeterminate.
- // NOTE: If present, progress must be >= `0.f` and <= `1.f`.
- absl::optional<float> progress_;
- // The list of callbacks for which to notify `progress_` changes.
- base::RepeatingClosureList progress_changed_callback_list_;
- // Whether this progress indicator's inner icon is visible. Note that the
- // inner icon will only be painted while `progress_` is incomplete, regardless
- // of this value.
- bool inner_icon_visible_ = true;
- };
- } // namespace ash
- #endif // ASH_SYSTEM_PROGRESS_INDICATOR_PROGRESS_INDICATOR_H_
|