1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/camera/autozoom_toast_controller.h"
#include <algorithm>
#include "ash/accessibility/accessibility_controller.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/system/camera/autozoom_controller_impl.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_utils.h"
#include "ash/system/unified/unified_system_tray.h"
namespace ash {
AutozoomToastController::Delegate::Delegate() = default;
void AutozoomToastController::Delegate::AddAutozoomObserver(
AutozoomObserver* observer) {
Shell::Get()->autozoom_controller()->AddObserver(observer);
}
void AutozoomToastController::Delegate::RemoveAutozoomObserver(
AutozoomObserver* observer) {
Shell::Get()->autozoom_controller()->RemoveObserver(observer);
}
bool AutozoomToastController::Delegate::IsAutozoomEnabled() {
return Shell::Get()->autozoom_controller()->GetState() !=
cros::mojom::CameraAutoFramingState::OFF;
}
bool AutozoomToastController::Delegate::IsAutozoomControlEnabled() {
return Shell::Get()->autozoom_controller()->IsAutozoomControlEnabled();
}
AutozoomToastController::AutozoomToastController(
UnifiedSystemTray* tray,
std::unique_ptr<Delegate> delegate)
: tray_(tray), delegate_(std::move(delegate)) {
delegate_->AddAutozoomObserver(this);
}
AutozoomToastController::~AutozoomToastController() {
if (bubble_widget_ && !bubble_widget_->IsClosed())
bubble_widget_->CloseNow();
delegate_->RemoveAutozoomObserver(this);
}
void AutozoomToastController::ShowToast() {
// If the bubble already exists, update the content of the bubble and extend
// the autoclose timer.
if (bubble_widget_) {
UpdateToastView();
if (!mouse_hovered_)
StartAutoCloseTimer();
return;
}
tray_->CloseSecondaryBubbles();
TrayBubbleView::InitParams init_params =
CreateInitParamsForTrayBubble(tray_, /*anchor_to_shelf_corner=*/true);
init_params.type = TrayBubbleView::TrayBubbleType::kSecondaryBubble;
init_params.preferred_width = kAutozoomToastMinWidth;
// Use this controller as the delegate rather than the tray.
init_params.delegate = GetWeakPtr();
auto bubble_view = std::make_unique<TrayBubbleView>(init_params);
// bubble_view_ is owned by the view hierarchy and not by this class.
bubble_view_ = bubble_view.get();
toast_view_ =
bubble_view->AddChildView(std::make_unique<AutozoomToastView>(this));
bubble_widget_ =
views::BubbleDialogDelegateView::CreateBubble(std::move(bubble_view));
TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
bubble_view_->InitializeAndShowBubble();
StartAutoCloseTimer();
UpdateToastView();
tray_->NotifySecondaryBubbleHeight(toast_view_->height());
}
void AutozoomToastController::HideToast() {
close_timer_.Stop();
if (!bubble_widget_ || bubble_widget_->IsClosed())
return;
bubble_widget_->Close();
tray_->NotifySecondaryBubbleHeight(0);
}
void AutozoomToastController::BubbleViewDestroyed() {
close_timer_.Stop();
bubble_view_ = nullptr;
bubble_widget_ = nullptr;
}
void AutozoomToastController::OnMouseEnteredView() {
close_timer_.Stop();
mouse_hovered_ = true;
}
void AutozoomToastController::OnMouseExitedView() {
StartAutoCloseTimer();
mouse_hovered_ = false;
}
std::u16string AutozoomToastController::GetAccessibleNameForBubble() {
if (!toast_view_)
return std::u16string();
return toast_view_->accessible_name();
}
void AutozoomToastController::HideBubble(const TrayBubbleView* bubble_view) {}
void AutozoomToastController::StartAutoCloseTimer() {
close_timer_.Stop();
// Don't start the timer if the toast is focused.
if (toast_view_ && toast_view_->IsButtonFocused())
return;
close_timer_.Start(
FROM_HERE,
Shell::Get()->accessibility_controller()->spoken_feedback().enabled()
? kSecondaryBubbleWithSpokenFeedbackDuration
: kSecondaryBubbleDuration,
this, &AutozoomToastController::HideToast);
}
void AutozoomToastController::OnAutozoomStateChanged(
cros::mojom::CameraAutoFramingState state) {
if (state == cros::mojom::CameraAutoFramingState::OFF) {
// TODO(pihsun): Should we hide toast immediately when the autozoom is
// toggled off while the toast is showing? Or should there be a "Autozoom
// is off" toast?
HideToast();
}
}
void AutozoomToastController::UpdateToastView() {
if (toast_view_) {
toast_view_->SetAutozoomEnabled(/*enabled=*/delegate_->IsAutozoomEnabled());
int width = std::clamp(toast_view_->GetPreferredSize().width(),
kAutozoomToastMinWidth, kAutozoomToastMaxWidth);
bubble_view_->SetPreferredWidth(width);
}
}
void AutozoomToastController::StopAutocloseTimer() {
close_timer_.Stop();
}
void AutozoomToastController::OnAutozoomControlEnabledChanged(bool enabled) {
if (enabled) {
if (delegate_->IsAutozoomEnabled()) {
ShowToast();
} else {
HideToast();
}
}
}
} // namespace ash
|