blob: 371e48121af21c4df90d3746ec0f104042f79e0f [file] [log] [blame]
// Copyright 2025 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/boca/on_task/on_task_pod_view.h"
#include <memory>
#include <string>
#include "ash/boca/on_task/on_task_pod_controller.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/style/icon_button.h"
#include "ash/style/tab_slider.h"
#include "ash/style/tab_slider_button.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/separator.h"
#include "ui/views/layout/box_layout.h"
namespace ash {
namespace {
// Parameters for the OnTask pod.
constexpr int kPodBorderRadius = 26;
constexpr int kPodVerticalPadding = 10;
constexpr int kPodHorizontalPadding = 12;
constexpr int kPodElementSpace = 8;
// Parameters for the separator in the OnTask pod.
constexpr int kSeparatorVerticalPadding = 0;
constexpr int kSeparatorHorizontalPadding = 4;
// Parameters for the label button in the OnTask pod.
constexpr int kLabelButtonRadius = 16;
constexpr int kLabelButtonTopPadding = 0;
constexpr int kLabelButtonLeftPadding = 12;
constexpr int kLabelButtonButtomPadding = 0;
constexpr int kLabelButtonRightPadding = 16;
constexpr int kLabelButtonHeight = 32;
constexpr int kLabelButtonWidth = 120;
constexpr int kLabelButtonIconTextSpace = 8;
std::unique_ptr<IconButton> CreateIconButton(base::RepeatingClosure callback,
const gfx::VectorIcon* icon,
int accessible_name_id,
bool is_togglable) {
auto button = std::make_unique<IconButton>(
std::move(callback), IconButton::Type::kMedium, icon, accessible_name_id,
is_togglable, /*has_border=*/false);
button->SetIconColor(cros_tokens::kCrosSysOnSurface);
button->SetBackgroundColor(SK_ColorTRANSPARENT);
return button;
}
std::unique_ptr<views::LabelButton> CreateLabelButton(
base::RepeatingClosure callback,
const std::u16string& text,
const gfx::VectorIcon* icon) {
auto button = std::make_unique<views::LabelButton>(std::move(callback), text);
button->SetImageModel(views::Button::STATE_NORMAL,
ui::ImageModel::FromVectorIcon(*icon, ui::kColorIcon));
button->SetBorder(views::CreateEmptyBorder(
gfx::Insets::TLBR(kLabelButtonTopPadding, kLabelButtonLeftPadding,
kLabelButtonButtomPadding, kLabelButtonRightPadding)));
button->SetHorizontalAlignment(gfx::ALIGN_CENTER);
button->SetImageLabelSpacing(kLabelButtonIconTextSpace);
button->SetBackground(views::CreateRoundedRectBackground(
cros_tokens::kCrosSysSystemOnBaseOpaque, kLabelButtonRadius));
return button;
}
} // namespace
OnTaskPodView::OnTaskPodView(OnTaskPodController* pod_controller)
: pod_controller_(pod_controller) {
SetOrientation(views::BoxLayout::Orientation::kHorizontal);
SetMainAxisAlignment(views::BoxLayout::MainAxisAlignment::kStart);
SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kStart);
SetBackground(views::CreateRoundedRectBackground(
cros_tokens::kCrosSysSystemBaseElevated, kPodBorderRadius));
SetInsideBorderInsets(
gfx::Insets::VH(kPodVerticalPadding, kPodHorizontalPadding));
SetBetweenChildSpacing(kPodElementSpace);
AddShortcutButtons();
}
OnTaskPodView::~OnTaskPodView() = default;
void OnTaskPodView::AddShortcutButtons() {
pod_position_slider_ = AddChildView(std::make_unique<TabSlider>(
/*max_tab_num=*/2,
TabSlider::InitParams{/*internal_border_padding=*/0,
/*between_child_spacing=*/0,
/*has_background=*/true,
/*has_selector_animation=*/true,
/*distribute_space_evenly=*/true}));
dock_left_button_ = pod_position_slider_->AddButton<IconSliderButton>(
base::BindRepeating(&OnTaskPodController::SetSnapLocation,
base::Unretained(pod_controller_),
OnTaskPodSnapLocation::kTopLeft),
&kKsvArrowLeftIcon,
l10n_util::GetStringUTF16(IDS_ON_TASK_MOVE_POD_TOP_LEFT_ACCESSIBLE_NAME));
dock_right_button_ = pod_position_slider_->AddButton<IconSliderButton>(
base::BindRepeating(&OnTaskPodController::SetSnapLocation,
base::Unretained(pod_controller_),
OnTaskPodSnapLocation::kTopRight),
&kKsvArrowRightIcon,
l10n_util::GetStringUTF16(
IDS_ON_TASK_MOVE_POD_TOP_RIGHT_ACCESSIBLE_NAME));
dock_left_button_->SetSelected(true);
left_separator_ = AddChildView(std::make_unique<views::Separator>());
left_separator_->SetBorder(views::CreateEmptyBorder(
gfx::Insets::VH(kSeparatorVerticalPadding, kSeparatorHorizontalPadding)));
left_separator_->SetColorId(cros_tokens::kCrosSysSeparator);
left_separator_->SetPreferredLength(kLabelButtonHeight);
back_button_ = AddChildView(CreateIconButton(
base::BindRepeating(&OnTaskPodController::MaybeNavigateToPreviousPage,
base::Unretained(pod_controller_)),
&kKsvBrowserBackIcon, IDS_ON_TASK_POD_NAVIGATE_BACK_ACCESSIBLE_NAME,
/*is_togglable=*/false));
forward_button_ = AddChildView(CreateIconButton(
base::BindRepeating(&OnTaskPodController::MaybeNavigateToNextPage,
base::Unretained(pod_controller_)),
&kKsvBrowserForwardIcon, IDS_ON_TASK_POD_NAVIGATE_FORWARD_ACCESSIBLE_NAME,
/*is_togglable=*/false));
reload_tab_button_ = AddChildView(CreateIconButton(
base::BindRepeating(&OnTaskPodController::ReloadCurrentPage,
base::Unretained(pod_controller_)),
&kKsvReloadIcon, IDS_ON_TASK_POD_RELOAD_ACCESSIBLE_NAME,
/*is_togglable=*/false));
right_separator_ = AddChildView(std::make_unique<views::Separator>());
right_separator_->SetBorder(views::CreateEmptyBorder(
gfx::Insets::VH(kSeparatorVerticalPadding, kSeparatorHorizontalPadding)));
right_separator_->SetColorId(cros_tokens::kCrosSysSeparator);
right_separator_->SetPreferredLength(kLabelButtonHeight);
pin_tab_strip_button_ = AddChildView(CreateLabelButton(
base::BindRepeating(&OnTaskPodView::UpdatePinTabStripButton,
base::Unretained(this)),
l10n_util::GetStringUTF16(IDS_ON_TASK_POD_PIN_TAP_STRIP_ACCESSIBLE_NAME),
&kUnpinnedIcon));
pin_tab_strip_button_->SetPreferredSize(
gfx::Size(kLabelButtonWidth, kLabelButtonHeight));
pin_tab_strip_button_->SetEnabled(
pod_controller_->CanToggleTabStripVisibility());
}
void OnTaskPodView::UpdatePinTabStripButton() {
should_show_tab_strip_ = !should_show_tab_strip_;
pod_controller_->ToggleTabStripVisibility(should_show_tab_strip_);
if (should_show_tab_strip_) {
// Button is "Hide tabs" when the tab strip is already shown.
pin_tab_strip_button_->SetText(l10n_util::GetStringUTF16(
IDS_ON_TASK_POD_UNPIN_TAP_STRIP_ACCESSIBLE_NAME));
pin_tab_strip_button_->SetBackground(views::CreateRoundedRectBackground(
cros_tokens::kCrosSysSystemPrimaryContainer, kLabelButtonRadius));
pin_tab_strip_button_->SetEnabledTextColors(
cros_tokens::kCrosSysSystemOnPrimaryContainer);
} else {
// Otherwise, button is "Show tabs" when the tab strip is already hidden.
pin_tab_strip_button_->SetText(l10n_util::GetStringUTF16(
IDS_ON_TASK_POD_PIN_TAP_STRIP_ACCESSIBLE_NAME));
pin_tab_strip_button_->SetBackground(views::CreateRoundedRectBackground(
cros_tokens::kCrosSysSystemOnBaseOpaque, kLabelButtonRadius));
pin_tab_strip_button_->SetEnabledTextColors(cros_tokens::kCrosSysOnSurface);
}
}
void OnTaskPodView::OnPageNavigationContextUpdate() {
back_button_->SetEnabled(pod_controller_->CanNavigateToPreviousPage());
if (!back_button_->GetEnabled()) {
back_button_->SetBackground(nullptr);
}
forward_button_->SetEnabled(pod_controller_->CanNavigateToNextPage());
if (!forward_button_->GetEnabled()) {
forward_button_->SetBackground(nullptr);
}
}
void OnTaskPodView::OnLockedModeUpdate() {
pin_tab_strip_button_->SetEnabled(
pod_controller_->CanToggleTabStripVisibility());
}
BEGIN_METADATA(OnTaskPodView)
END_METADATA
} // namespace ash