holding_space_util.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright 2020 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. #include "ash/system/holding_space/holding_space_util.h"
  5. #include <memory>
  6. #include "third_party/abseil-cpp/absl/types/optional.h"
  7. #include "ui/compositor/layer.h"
  8. #include "ui/compositor/layer_animation_element.h"
  9. #include "ui/compositor/layer_animation_observer.h"
  10. #include "ui/compositor/layer_animation_sequence.h"
  11. #include "ui/compositor/layer_animator.h"
  12. #include "ui/gfx/canvas.h"
  13. #include "ui/views/background.h"
  14. #include "ui/views/painter.h"
  15. #include "ui/views/view.h"
  16. namespace ash {
  17. namespace holding_space_util {
  18. namespace {
  19. // CirclePainter ---------------------------------------------------------------
  20. class CirclePainter : public views::Painter {
  21. public:
  22. CirclePainter(SkColor color, size_t fixed_size)
  23. : color_(color), fixed_size_(fixed_size) {}
  24. CirclePainter(SkColor color, const gfx::InsetsF& insets)
  25. : color_(color), insets_(insets) {}
  26. CirclePainter(const CirclePainter&) = delete;
  27. CirclePainter& operator=(const CirclePainter&) = delete;
  28. ~CirclePainter() override = default;
  29. private:
  30. // views::Painter:
  31. gfx::Size GetMinimumSize() const override { return gfx::Size(); }
  32. void Paint(gfx::Canvas* canvas, const gfx::Size& size) override {
  33. gfx::RectF bounds{gfx::SizeF(size)};
  34. if (insets_.has_value())
  35. bounds.Inset(insets_.value());
  36. const float radius =
  37. fixed_size_.has_value()
  38. ? fixed_size_.value() / 2.f
  39. : std::min(bounds.size().width(), bounds.size().height()) / 2.f;
  40. cc::PaintFlags flags;
  41. flags.setAntiAlias(true);
  42. flags.setColor(color_);
  43. canvas->DrawCircle(bounds.CenterPoint(), radius, flags);
  44. }
  45. const SkColor color_;
  46. const absl::optional<size_t> fixed_size_;
  47. const absl::optional<gfx::InsetsF> insets_;
  48. };
  49. // Helpers ---------------------------------------------------------------------
  50. // Creates a `ui::LayerAnimationSequence` for the specified `element` with
  51. // optional `delay`, observed by the specified `observer`.
  52. std::unique_ptr<ui::LayerAnimationSequence> CreateObservedSequence(
  53. std::unique_ptr<ui::LayerAnimationElement> element,
  54. base::TimeDelta delay,
  55. ui::LayerAnimationObserver* observer) {
  56. auto sequence = std::make_unique<ui::LayerAnimationSequence>();
  57. if (!delay.is_zero()) {
  58. sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement(
  59. element->properties(), delay));
  60. }
  61. sequence->AddElement(std::move(element));
  62. sequence->AddObserver(observer);
  63. return sequence;
  64. }
  65. // Animates the specified `view` to a target `opacity` with the specified
  66. // `duration` and optional `delay`, associating `observer` with the created
  67. // animation sequences.
  68. void AnimateTo(views::View* view,
  69. float opacity,
  70. base::TimeDelta duration,
  71. base::TimeDelta delay,
  72. ui::LayerAnimationObserver* observer) {
  73. // Opacity animation.
  74. auto opacity_element =
  75. ui::LayerAnimationElement::CreateOpacityElement(opacity, duration);
  76. opacity_element->set_tween_type(gfx::Tween::Type::LINEAR);
  77. // Note that the `ui::LayerAnimator` takes ownership of any animation
  78. // sequences so they need to be released.
  79. view->layer()->GetAnimator()->StartAnimation(
  80. CreateObservedSequence(std::move(opacity_element), delay, observer)
  81. .release());
  82. }
  83. } // namespace
  84. // Animates in the specified `view` with the specified `duration` and optional
  85. // `delay`, associating `observer` with the created animation sequences.
  86. void AnimateIn(views::View* view,
  87. base::TimeDelta duration,
  88. base::TimeDelta delay,
  89. ui::LayerAnimationObserver* observer) {
  90. view->layer()->SetOpacity(0.f);
  91. AnimateTo(view, /*opacity=*/1.f, duration, delay, observer);
  92. }
  93. // Animates out the specified `view` with the specified `duration, associating
  94. // `observer` with the created animation sequences.
  95. void AnimateOut(views::View* view,
  96. base::TimeDelta duration,
  97. ui::LayerAnimationObserver* observer) {
  98. AnimateTo(view, /*opacity=*/0.f, duration, /*delay=*/base::TimeDelta(),
  99. observer);
  100. }
  101. std::unique_ptr<views::Background> CreateCircleBackground(SkColor color,
  102. size_t fixed_size) {
  103. return views::CreateBackgroundFromPainter(
  104. std::make_unique<CirclePainter>(color, fixed_size));
  105. }
  106. std::unique_ptr<views::Background> CreateCircleBackground(
  107. SkColor color,
  108. const gfx::InsetsF& insets) {
  109. return views::CreateBackgroundFromPainter(
  110. std::make_unique<CirclePainter>(color, insets));
  111. }
  112. } // namespace holding_space_util
  113. } // namespace ash