blob: 6f1772e7458393f99d20ee3941edeb60b190ca2d [file] [log] [blame]
// Copyright 2020 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/accessibility/select_to_speak/select_to_speak_speed_bubble_controller.h"
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/bubble/bubble_constants.h"
#include "ash/public/cpp/accessibility_controller_enums.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h"
#include "ash/system/accessibility/floating_menu_utils.h"
#include "ash/system/accessibility/select_to_speak/select_to_speak_constants.h"
#include "ash/system/accessibility/select_to_speak/select_to_speak_speed_view.h"
#include "ash/system/tray/tray_background_view.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/unified/unified_system_tray_view.h"
#include "ui/compositor/layer.h"
#include "ui/wm/public/activation_client.h"
namespace ash {
namespace {
constexpr int kPreferredWidth = 150;
constexpr int kBubbleViewMargin = 2;
} // namespace
SelectToSpeakSpeedBubbleController::SelectToSpeakSpeedBubbleController(
SelectToSpeakSpeedView::Delegate* delegate)
: delegate_(delegate) {
Shell::Get()->activation_client()->AddObserver(this);
}
SelectToSpeakSpeedBubbleController::~SelectToSpeakSpeedBubbleController() {
Shell::Get()->activation_client()->RemoveObserver(this);
if (bubble_widget_ && !bubble_widget_->IsClosed())
bubble_widget_->CloseNow();
}
void SelectToSpeakSpeedBubbleController::Show(views::View* anchor_view,
double speech_rate) {
DCHECK(anchor_view);
if (!bubble_widget_) {
TrayBubbleView::InitParams init_params;
init_params.delegate = GetWeakPtr();
init_params.parent_window =
Shell::GetContainer(Shell::GetPrimaryRootWindow(),
kShellWindowId_AccessibilityBubbleContainer);
init_params.anchor_mode = TrayBubbleView::AnchorMode::kView;
init_params.anchor_view = anchor_view;
init_params.is_anchored_to_status_area = false;
init_params.margin = gfx::Insets::VH(kBubbleViewMargin, kBubbleViewMargin);
init_params.translucent = true;
init_params.close_on_deactivate = false;
init_params.preferred_width = kPreferredWidth;
bubble_view_ = new TrayBubbleView(init_params);
bubble_view_->SetArrow(views::BubbleBorder::BOTTOM_RIGHT);
bubble_view_->SetCanActivate(true);
bubble_view_->SetFocusBehavior(ActionableView::FocusBehavior::ALWAYS);
speed_view_ = new SelectToSpeakSpeedView(this, speech_rate);
bubble_view_->AddChildView(speed_view_);
// In dark light mode, we switch TrayBubbleView to use a textured layer
// instead of solid color layer, so no need to create an extra layer here.
if (!features::IsDarkLightModeEnabled()) {
speed_view_->SetPaintToLayer();
speed_view_->layer()->SetFillsBoundsOpaquely(false);
}
bubble_widget_ =
views::BubbleDialogDelegateView::CreateBubble(bubble_view_);
bubble_widget_->GetNativeView()->SetName(
kSelectToSpeakSpeedBubbleWindowName);
TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
bubble_view_->InitializeAndShowBubble();
} else {
speed_view_->SetInitialSpeechRate(speech_rate);
}
bubble_view_->ChangeAnchorView(anchor_view);
bubble_widget_->Show();
}
void SelectToSpeakSpeedBubbleController::Hide() {
if (!bubble_widget_)
return;
bubble_widget_->Hide();
}
bool SelectToSpeakSpeedBubbleController::IsVisible() const {
return bubble_widget_ && bubble_widget_->IsVisible();
}
void SelectToSpeakSpeedBubbleController::BubbleViewDestroyed() {
bubble_view_ = nullptr;
bubble_widget_ = nullptr;
}
void SelectToSpeakSpeedBubbleController::OnWindowActivated(
ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) {
if (!gained_active || !bubble_widget_ || !speed_view_)
return;
views::Widget* gained_widget =
views::Widget::GetWidgetForNativeView(gained_active);
if (gained_widget == bubble_widget_) {
speed_view_->SetInitialFocus();
}
}
void SelectToSpeakSpeedBubbleController::OnSpeechRateSelected(
double speech_rate) {
// Let parent handle this, so menu bubble controller can properly set speed
// button state.
delegate_->OnSpeechRateSelected(speech_rate);
}
} // namespace ash