widget_fade_animator.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. #include "ui/views/animation/widget_fade_animator.h"
  5. #include "ui/gfx/animation/linear_animation.h"
  6. #include "ui/views/widget/widget.h"
  7. namespace views {
  8. WidgetFadeAnimator::WidgetFadeAnimator(Widget* widget)
  9. : AnimationDelegateViews(widget->GetRootView()), widget_(widget) {
  10. widget_observation_.Observe(widget);
  11. }
  12. WidgetFadeAnimator::~WidgetFadeAnimator() = default;
  13. void WidgetFadeAnimator::FadeIn() {
  14. if (IsFadingIn())
  15. return;
  16. DCHECK(widget_);
  17. animation_type_ = FadeType::kFadeIn;
  18. fade_animation_.SetDuration(fade_in_duration_);
  19. // Widgets cannot be shown when visible and fully transparent.
  20. widget_->SetOpacity(0.01f);
  21. widget_->Show();
  22. fade_animation_.Start();
  23. }
  24. void WidgetFadeAnimator::CancelFadeIn() {
  25. if (!IsFadingIn())
  26. return;
  27. fade_animation_.Stop();
  28. animation_type_ = FadeType::kNone;
  29. }
  30. void WidgetFadeAnimator::FadeOut() {
  31. if (IsFadingOut() || !widget_)
  32. return;
  33. // If the widget is already hidden, then there is no current animation and
  34. // nothing to do. If the animation is close-on-hide, however, we should still
  35. // close the widget.
  36. if (!widget_->IsVisible()) {
  37. DCHECK(!IsFadingIn());
  38. if (close_on_hide_)
  39. widget_->Close();
  40. fade_complete_callbacks_.Notify(this, FadeType::kFadeOut);
  41. return;
  42. }
  43. animation_type_ = FadeType::kFadeOut;
  44. fade_animation_.SetDuration(fade_out_duration_);
  45. fade_animation_.Start();
  46. }
  47. void WidgetFadeAnimator::CancelFadeOut() {
  48. if (!IsFadingOut())
  49. return;
  50. fade_animation_.Stop();
  51. animation_type_ = FadeType::kNone;
  52. widget_->SetOpacity(1.0f);
  53. }
  54. base::CallbackListSubscription WidgetFadeAnimator::AddFadeCompleteCallback(
  55. FadeCompleteCallback callback) {
  56. return fade_complete_callbacks_.Add(callback);
  57. }
  58. void WidgetFadeAnimator::AnimationProgressed(const gfx::Animation* animation) {
  59. // Get the value of the animation with a material ease applied.
  60. double value =
  61. gfx::Tween::CalculateValue(tween_type_, animation->GetCurrentValue());
  62. float opacity = 0.0f;
  63. if (IsFadingOut())
  64. opacity = gfx::Tween::FloatValueBetween(value, 1.0f, 0.0f);
  65. else if (IsFadingIn())
  66. opacity = gfx::Tween::FloatValueBetween(value, 0.0f, 1.0f);
  67. if (IsFadingOut() && opacity == 0.0f) {
  68. if (close_on_hide_)
  69. widget_->Close();
  70. else
  71. widget_->Hide();
  72. } else {
  73. widget_->SetOpacity(opacity);
  74. }
  75. }
  76. void WidgetFadeAnimator::AnimationEnded(const gfx::Animation* animation) {
  77. const FadeType animation_type = animation_type_;
  78. AnimationProgressed(animation);
  79. animation_type_ = FadeType::kNone;
  80. fade_complete_callbacks_.Notify(this, animation_type);
  81. }
  82. void WidgetFadeAnimator::OnWidgetDestroying(Widget* widget) {
  83. widget_observation_.Reset();
  84. fade_animation_.End();
  85. animation_type_ = FadeType::kNone;
  86. widget_ = nullptr;
  87. }
  88. } // namespace views