autozoom_toast_controller.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright 2022 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/camera/autozoom_toast_controller.h"
  5. #include "ash/accessibility/accessibility_controller_impl.h"
  6. #include "ash/shelf/shelf.h"
  7. #include "ash/shell.h"
  8. #include "ash/system/camera/autozoom_controller_impl.h"
  9. #include "ash/system/tray/tray_constants.h"
  10. #include "ash/system/tray/tray_utils.h"
  11. #include "ash/system/unified/unified_system_tray.h"
  12. #include "base/cxx17_backports.h"
  13. namespace ash {
  14. AutozoomToastController::Delegate::Delegate() = default;
  15. void AutozoomToastController::Delegate::AddAutozoomObserver(
  16. AutozoomObserver* observer) {
  17. Shell::Get()->autozoom_controller()->AddObserver(observer);
  18. }
  19. void AutozoomToastController::Delegate::RemoveAutozoomObserver(
  20. AutozoomObserver* observer) {
  21. Shell::Get()->autozoom_controller()->RemoveObserver(observer);
  22. }
  23. bool AutozoomToastController::Delegate::IsAutozoomEnabled() {
  24. return Shell::Get()->autozoom_controller()->GetState() !=
  25. cros::mojom::CameraAutoFramingState::OFF;
  26. }
  27. bool AutozoomToastController::Delegate::IsAutozoomControlEnabled() {
  28. return Shell::Get()->autozoom_controller()->IsAutozoomControlEnabled();
  29. }
  30. AutozoomToastController::AutozoomToastController(
  31. UnifiedSystemTray* tray,
  32. std::unique_ptr<Delegate> delegate)
  33. : tray_(tray), delegate_(std::move(delegate)) {
  34. delegate_->AddAutozoomObserver(this);
  35. }
  36. AutozoomToastController::~AutozoomToastController() {
  37. if (bubble_widget_ && !bubble_widget_->IsClosed())
  38. bubble_widget_->CloseNow();
  39. delegate_->RemoveAutozoomObserver(this);
  40. }
  41. void AutozoomToastController::ShowToast() {
  42. // If the bubble already exists, update the content of the bubble and extend
  43. // the autoclose timer.
  44. if (bubble_widget_) {
  45. UpdateToastView();
  46. if (!mouse_hovered_)
  47. StartAutoCloseTimer();
  48. return;
  49. }
  50. tray_->CloseSecondaryBubbles();
  51. TrayBubbleView::InitParams init_params;
  52. init_params.shelf_alignment = tray_->shelf()->alignment();
  53. init_params.preferred_width = kAutozoomToastMinWidth;
  54. init_params.delegate = GetWeakPtr();
  55. init_params.parent_window = tray_->GetBubbleWindowContainer();
  56. init_params.anchor_view = nullptr;
  57. init_params.anchor_mode = TrayBubbleView::AnchorMode::kRect;
  58. init_params.anchor_rect = tray_->shelf()->GetSystemTrayAnchorRect();
  59. // Decrease bottom and right insets to compensate for the adjustment of
  60. // the respective edges in Shelf::GetSystemTrayAnchorRect().
  61. init_params.insets = GetTrayBubbleInsets();
  62. init_params.translucent = true;
  63. auto bubble_view = std::make_unique<TrayBubbleView>(init_params);
  64. // bubble_view_ is owned by the view hierarchy and not by this class.
  65. bubble_view_ = bubble_view.get();
  66. toast_view_ =
  67. bubble_view->AddChildView(std::make_unique<AutozoomToastView>(this));
  68. bubble_widget_ =
  69. views::BubbleDialogDelegateView::CreateBubble(std::move(bubble_view));
  70. TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
  71. bubble_view_->InitializeAndShowBubble();
  72. StartAutoCloseTimer();
  73. UpdateToastView();
  74. tray_->SetTrayBubbleHeight(
  75. bubble_widget_->GetWindowBoundsInScreen().height());
  76. }
  77. void AutozoomToastController::HideToast() {
  78. close_timer_.Stop();
  79. if (!bubble_widget_ || bubble_widget_->IsClosed())
  80. return;
  81. bubble_widget_->Close();
  82. tray_->SetTrayBubbleHeight(0);
  83. }
  84. void AutozoomToastController::BubbleViewDestroyed() {
  85. close_timer_.Stop();
  86. bubble_view_ = nullptr;
  87. bubble_widget_ = nullptr;
  88. }
  89. void AutozoomToastController::OnMouseEnteredView() {
  90. close_timer_.Stop();
  91. mouse_hovered_ = true;
  92. }
  93. void AutozoomToastController::OnMouseExitedView() {
  94. StartAutoCloseTimer();
  95. mouse_hovered_ = false;
  96. }
  97. std::u16string AutozoomToastController::GetAccessibleNameForBubble() {
  98. if (!toast_view_)
  99. return std::u16string();
  100. return toast_view_->GetAccessibleName();
  101. }
  102. void AutozoomToastController::StartAutoCloseTimer() {
  103. close_timer_.Stop();
  104. // Don't start the timer if the toast is focused.
  105. if (toast_view_ && toast_view_->IsButtonFocused())
  106. return;
  107. int autoclose_delay = kTrayPopupAutoCloseDelayInSeconds;
  108. if (Shell::Get()->accessibility_controller()->spoken_feedback().enabled())
  109. autoclose_delay = kTrayPopupAutoCloseDelayInSecondsWithSpokenFeedback;
  110. close_timer_.Start(FROM_HERE, base::Seconds(autoclose_delay), this,
  111. &AutozoomToastController::HideToast);
  112. }
  113. void AutozoomToastController::OnAutozoomStateChanged(
  114. cros::mojom::CameraAutoFramingState state) {
  115. if (state == cros::mojom::CameraAutoFramingState::OFF) {
  116. // TODO(pihsun): Should we hide toast immediately when the autozoom is
  117. // toggled off while the toast is showing? Or should there be a "Autozoom
  118. // is off" toast?
  119. HideToast();
  120. }
  121. }
  122. void AutozoomToastController::UpdateToastView() {
  123. if (toast_view_) {
  124. toast_view_->SetAutozoomEnabled(/*enabled=*/delegate_->IsAutozoomEnabled());
  125. int width = base::clamp(toast_view_->GetPreferredSize().width(),
  126. kAutozoomToastMinWidth, kAutozoomToastMaxWidth);
  127. bubble_view_->SetPreferredWidth(width);
  128. }
  129. }
  130. void AutozoomToastController::StopAutocloseTimer() {
  131. close_timer_.Stop();
  132. }
  133. void AutozoomToastController::OnAutozoomControlEnabledChanged(bool enabled) {
  134. if (enabled) {
  135. if (delegate_->IsAutozoomEnabled()) {
  136. ShowToast();
  137. } else {
  138. HideToast();
  139. }
  140. }
  141. }
  142. } // namespace ash