123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- // Copyright 2022 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.
- #include "ash/system/holding_space/holding_space_progress_indicator_util.h"
- #include "ash/public/cpp/holding_space/holding_space_controller.h"
- #include "ash/public/cpp/holding_space/holding_space_controller_observer.h"
- #include "ash/public/cpp/holding_space/holding_space_item.h"
- #include "ash/public/cpp/holding_space/holding_space_model.h"
- #include "ash/public/cpp/holding_space/holding_space_model_observer.h"
- #include "ash/public/cpp/holding_space/holding_space_progress.h"
- #include "ash/system/holding_space/holding_space_animation_registry.h"
- #include "ash/system/progress_indicator/progress_indicator.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- namespace ash {
- namespace holding_space_util {
- namespace {
- // HoldingSpaceControllerProgressIndicator -------------------------------------
- // A class owning a `ui::Layer` which paints indication of progress for all
- // items in the model attached to its associated holding space `controller_`.
- // NOTE: The owned `layer()` is not painted if there are no items in progress.
- class HoldingSpaceControllerProgressIndicator
- : public ProgressIndicator,
- public HoldingSpaceControllerObserver,
- public HoldingSpaceModelObserver {
- public:
- explicit HoldingSpaceControllerProgressIndicator(
- HoldingSpaceController* controller)
- : ProgressIndicator(
- /*animation_registry=*/HoldingSpaceAnimationRegistry::GetInstance(),
- /*animation_key=*/controller),
- controller_(controller) {
- controller_observation_.Observe(controller_);
- if (controller_->model())
- OnHoldingSpaceModelAttached(controller_->model());
- }
- private:
- // ProgressIndicator:
- absl::optional<float> CalculateProgress() const override {
- // If there is no `model` attached, then there are no in-progress holding
- // space items. Do not paint the progress indication.
- const HoldingSpaceModel* model = controller_->model();
- if (!model)
- return kProgressComplete;
- HoldingSpaceProgress cumulative_progress;
- // Iterate over all holding space items.
- for (const auto& item : model->items()) {
- // Ignore any holding space items that are not yet initialized, since
- // they are not visible to the user, or items that are not visibly
- // in-progress, since they do not contribute to `cumulative_progress`.
- if (item->IsInitialized() && !item->progress().IsHidden() &&
- !item->progress().IsComplete()) {
- cumulative_progress += item->progress();
- }
- }
- return cumulative_progress.GetValue();
- }
- // HoldingSpaceControllerObserver:
- void OnHoldingSpaceModelAttached(HoldingSpaceModel* model) override {
- model_observation_.Observe(model);
- InvalidateLayer();
- }
- void OnHoldingSpaceModelDetached(HoldingSpaceModel* model) override {
- model_observation_.Reset();
- InvalidateLayer();
- }
- // HoldingSpaceModelObserver:
- void OnHoldingSpaceItemsAdded(
- const std::vector<const HoldingSpaceItem*>& items) override {
- for (const HoldingSpaceItem* item : items) {
- if (item->IsInitialized() && !item->progress().IsComplete()) {
- InvalidateLayer();
- return;
- }
- }
- }
- void OnHoldingSpaceItemsRemoved(
- const std::vector<const HoldingSpaceItem*>& items) override {
- for (const HoldingSpaceItem* item : items) {
- if (item->IsInitialized() && !item->progress().IsComplete()) {
- InvalidateLayer();
- return;
- }
- }
- }
- void OnHoldingSpaceItemUpdated(const HoldingSpaceItem* item,
- uint32_t updated_fields) override {
- if (item->IsInitialized() && (updated_fields & UpdatedField::kProgress))
- InvalidateLayer();
- }
- void OnHoldingSpaceItemInitialized(const HoldingSpaceItem* item) override {
- if (!item->progress().IsComplete())
- InvalidateLayer();
- }
- // The associated holding space `controller_` for which to indicate progress
- // of all holding space items in its attached model.
- HoldingSpaceController* const controller_;
- base::ScopedObservation<HoldingSpaceController,
- HoldingSpaceControllerObserver>
- controller_observation_{this};
- base::ScopedObservation<HoldingSpaceModel, HoldingSpaceModelObserver>
- model_observation_{this};
- };
- // HoldingSpaceItemProgressIndicator -------------------------------------------
- // A class owning a `ui::Layer` which paints indication of progress for its
- // associated holding space `item_`. NOTE: The owned `layer()` is not painted if
- // the associated `item_` is not in progress.
- class HoldingSpaceItemProgressIndicator : public ProgressIndicator,
- public HoldingSpaceModelObserver {
- public:
- explicit HoldingSpaceItemProgressIndicator(const HoldingSpaceItem* item)
- : ProgressIndicator(
- /*animation_registry=*/HoldingSpaceAnimationRegistry::GetInstance(),
- /*animation_key=*/item),
- item_(item) {
- model_observation_.Observe(HoldingSpaceController::Get()->model());
- }
- private:
- // ProgressIndicator:
- absl::optional<float> CalculateProgress() const override {
- // If `item_` is `nullptr` it is being destroyed. Ensure the progress
- // indication is not painted in this case. Similarly, ensure the progress
- // indication is not painted when progress is hidden.
- return item_ && !item_->progress().IsHidden() ? item_->progress().GetValue()
- : kProgressComplete;
- }
- // HoldingSpaceModelObserver:
- void OnHoldingSpaceItemUpdated(const HoldingSpaceItem* item,
- uint32_t updated_fields) override {
- if (item_ == item && (updated_fields & UpdatedField::kProgress))
- InvalidateLayer();
- }
- void OnHoldingSpaceItemsRemoved(
- const std::vector<const HoldingSpaceItem*>& items) override {
- for (const HoldingSpaceItem* item : items) {
- if (item_ == item) {
- item_ = nullptr;
- return;
- }
- }
- }
- // The associated holding space `item` for which to indicate progress.
- // NOTE: May temporarily be `nullptr` during the `item`s destruction sequence.
- const HoldingSpaceItem* item_ = nullptr;
- base::ScopedObservation<HoldingSpaceModel, HoldingSpaceModelObserver>
- model_observation_{this};
- };
- } // namespace
- // Utilities -------------------------------------------------------------------
- std::unique_ptr<ProgressIndicator> CreateProgressIndicatorForController(
- HoldingSpaceController* controller) {
- return std::make_unique<HoldingSpaceControllerProgressIndicator>(controller);
- }
- std::unique_ptr<ProgressIndicator> CreateProgressIndicatorForItem(
- const HoldingSpaceItem* item) {
- return std::make_unique<HoldingSpaceItemProgressIndicator>(item);
- }
- } // namespace holding_space_util
- } // namespace ash
|